CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/CommonTools/RecoAlgos/src/ClusterStorer.cc

Go to the documentation of this file.
00001 #include "CommonTools/RecoAlgos/interface/ClusterStorer.h"
00002 
00003 #include "FWCore/Utilities/interface/Exception.h"
00004 
00005 #include "DataFormats/TrackingRecHit/interface/TrackingRecHit.h"
00006 #include "DataFormats/TrackerRecHit2D/interface/SiPixelRecHit.h"
00007 #include "DataFormats/TrackerRecHit2D/interface/SiStripRecHit1D.h"
00008 #include "DataFormats/TrackerRecHit2D/interface/SiStripRecHit2D.h"
00009 #include "DataFormats/TrackerRecHit2D/interface/ProjectedSiStripRecHit2D.h"
00010 #include "DataFormats/TrackerRecHit2D/interface/SiStripMatchedRecHit2D.h"
00011 // FastSim hits:
00012 #include "DataFormats/TrackerRecHit2D/interface/SiTrackerGSRecHit2D.h"
00013 #include "DataFormats/TrackerRecHit2D/interface/SiTrackerGSMatchedRecHit2D.h"
00014 
00015 
00016 #include "DataFormats/SiStripDetId/interface/SiStripDetId.h"
00017 
00018 namespace helper {
00019 
00020   // -------------------------------------------------------------
00021   //FIXME (push cluster pointers...)
00022   void ClusterStorer::addCluster(TrackingRecHitCollection &hits, size_t index)
00023   {
00024     TrackingRecHit &newHit = hits[index];
00025     const std::type_info &hit_type = typeid(newHit);
00026     if (hit_type == typeid(SiPixelRecHit)) {
00027       //std::cout << "|  It is a Pixel hit !!" << std::endl;
00028       pixelClusterRecords_.push_back(PixelClusterHitRecord(static_cast<SiPixelRecHit&>(newHit),
00029                                                            hits, index));
00030     } else if (hit_type == typeid(SiStripRecHit1D)) {
00031       //std::cout << "|   It is a SiStripRecHit1D hit !!" << std::endl;
00032       stripClusterRecords_.push_back(StripClusterHitRecord(static_cast<SiStripRecHit1D&>(newHit),
00033                                                            hits, index));
00034     } else if (hit_type == typeid(SiStripRecHit2D)) {
00035       //std::cout << "|   It is a SiStripRecHit2D hit !!" << std::endl;
00036       stripClusterRecords_.push_back(StripClusterHitRecord(static_cast<SiStripRecHit2D&>(newHit),
00037                                                            hits, index));
00038     } else if (hit_type == typeid(SiStripMatchedRecHit2D)) {      
00039       //std::cout << "|   It is a SiStripMatchedRecHit2D hit !!" << std::endl;
00040       SiStripMatchedRecHit2D &mhit = static_cast<SiStripMatchedRecHit2D&>(newHit);
00041       stripClusterRecords_.push_back(StripClusterHitRecord(mhit.monoHit(), hits, index));
00042       stripClusterRecords_.push_back(StripClusterHitRecord(mhit.stereoHit(), hits, index));
00043     } else if (hit_type == typeid(ProjectedSiStripRecHit2D)) {
00044       //std::cout << "|   It is a ProjectedSiStripRecHit2D hit !!" << std::endl;
00045       ProjectedSiStripRecHit2D &phit = static_cast<ProjectedSiStripRecHit2D&>(newHit);
00046       stripClusterRecords_.push_back(StripClusterHitRecord(phit.originalHit(), hits, index));
00047     } else {
00048       if (hit_type == typeid(SiTrackerGSMatchedRecHit2D)
00049           || hit_type == typeid(SiTrackerGSRecHit2D)) {
00050         //std::cout << "|   It is a " << hit_type.name() << " hit !!" << std::endl;
00051         // FastSim hits: Do nothing instead of caring about FastSim clusters, 
00052         //               not even sure whether these really exist.
00053         //               At least predecessor code in TrackSelector and MuonSelector
00054         //               did not treat them.
00055       } else {
00056         // through for unknown types
00057         throw cms::Exception("UnknownHitType") << "helper::ClusterStorer::addCluster: "
00058                                                << "Unknown hit type " << hit_type.name()
00059                                                << ".\n";
00060       }
00061     } // end 'switch' on hit type
00062     
00063   }
00064   
00065   // -------------------------------------------------------------
00066   void ClusterStorer::clear()
00067   {
00068     pixelClusterRecords_.clear();
00069     stripClusterRecords_.clear();
00070   }
00071   
00072   // -------------------------------------------------------------
00073   void ClusterStorer::
00074   processAllClusters(edmNew::DetSetVector<SiPixelCluster> &pixelDsvToFill,
00075                      edm::RefProd<edmNew::DetSetVector<SiPixelCluster> > refPixelClusters,
00076                      edmNew::DetSetVector<SiStripCluster> &stripDsvToFill,
00077                      edm::RefProd<edmNew::DetSetVector<SiStripCluster> > refStripClusters)
00078   {
00079     if (!pixelClusterRecords_.empty()) {
00080       this->processClusters<SiPixelRecHit, SiPixelCluster>
00081         (pixelClusterRecords_, pixelDsvToFill, refPixelClusters);
00082     }
00083     if (!stripClusterRecords_.empty()) {
00084       // All we need from the HitType 'SiStripRecHit2D' is the
00085       // typedef for 'SiStripRecHit2D::ClusterRef'.
00086       // The fact that rekey<SiStripRecHit2D> is called is irrelevant since
00087       // ClusterHitRecord<typename SiStripRecHit2D::ClusterRef>::rekey<RecHitType>
00088       // is specialised such that 'RecHitType' is not used...
00089       this->processClusters<SiStripRecHit2D, SiStripCluster>
00090         (stripClusterRecords_, stripDsvToFill, refStripClusters);
00091     }
00092   }
00093   
00094   //-------------------------------------------------------------
00095   template<typename HitType, typename ClusterType>
00096   void ClusterStorer::
00097   processClusters(std::vector<ClusterHitRecord<typename HitType::ClusterRef> > &clusterRecords,
00098                   edmNew::DetSetVector<ClusterType>                            &dsvToFill,
00099                   edm::RefProd< edmNew::DetSetVector<ClusterType> >            &refprod)
00100   {
00101     std::sort(clusterRecords.begin(), clusterRecords.end()); // this sorts them by detid 
00102     typedef
00103       typename std::vector<ClusterHitRecord<typename HitType::ClusterRef> >::const_iterator
00104       RIT;
00105     RIT it = clusterRecords.begin(), end = clusterRecords.end();
00106     size_t clusters = 0;
00107     while (it != end) {
00108       RIT it2 = it;
00109       uint32_t detid = it->detid();
00110       
00111       // first isolate all clusters on the same detid
00112       while ( (it2 != end) && (it2->detid() == detid)) {  ++it2; }
00113       // now [it, it2] bracket one detid
00114       
00115       // then prepare to copy the clusters
00116       typename edmNew::DetSetVector<ClusterType>::FastFiller filler(dsvToFill, detid);
00117       typename HitType::ClusterRef lastRef, newRef;
00118       for ( ; it != it2; ++it) { // loop on the detid
00119         // first check if we need to clone the hit
00120         if (it->clusterRef() != lastRef) { 
00121           lastRef = it->clusterRef();
00122           // clone cluster
00123           filler.push_back( *lastRef );  
00124           // make new ref
00125           newRef = typename HitType::ClusterRef( refprod, clusters++ );
00126         } 
00127         it->template rekey<HitType>(newRef);
00128       } // end of the loop on a single detid
00129       
00130     } // end of the loop on all clusters
00131   }
00132   
00133   //-------------------------------------------------------------
00134   // helper classes  
00135   //-------------------------------------------------------------
00136   // FIXME (migrate to new RTTI and interface)
00137   // generic rekey (in practise for pixel only...)
00138   template<typename ClusterRefType> // template for class
00139   template<typename RecHitType>     // template for member function
00140   void ClusterStorer::ClusterHitRecord<ClusterRefType>::
00141   rekey(const ClusterRefType &newRef) const
00142   {
00143     TrackingRecHit & genericHit = (*hits_)[index_]; 
00144     RecHitType *hit = 0;
00145     if (genericHit.geographicalId().rawId() == detid_) { // a hit on this det, so it's simple
00146       hit = dynamic_cast<RecHitType *>(&genericHit); //static_cast<RecHitType *>(&genericHit);
00147     }
00148     assert (hit != 0);
00149     assert (hit->cluster() == ref_); // otherwise something went wrong
00150     hit->setClusterRef(newRef);
00151   }
00152   
00153   // -------------------------------------------------------------
00154   // Specific rekey for class template ClusterRefType = SiStripRecHit2D::ClusterRef,
00155   // RecHitType is not used.
00156   template<>
00157   template<typename RecHitType> // or template<> to specialise also here?
00158   void ClusterStorer::ClusterHitRecord<SiStripRecHit2D::ClusterRef>::
00159   //  rekey<SiStripRecHit2D>(const SiStripRecHit2D::ClusterRef &newRef) const
00160   rekey(const SiStripRecHit2D::ClusterRef &newRef) const
00161   {
00162     TrackingRecHit &genericHit = (*hits_)[index_];
00163     const std::type_info &hit_type = typeid(genericHit);
00164 
00165     OmniClusterRef * cluRef=0;
00166     if (typeid(SiStripRecHit1D) == hit_type) {
00167       cluRef = &static_cast<SiStripRecHit1D&>(genericHit).omniCluster();
00168      } else if (typeid(SiStripRecHit2D) == hit_type) {
00169       cluRef = &static_cast<SiStripRecHit2D&>(genericHit).omniCluster();
00170     } else if (typeid(SiStripMatchedRecHit2D) == hit_type) {
00171         SiStripMatchedRecHit2D &mhit = static_cast<SiStripMatchedRecHit2D&>(genericHit);
00172          cluRef = (SiStripDetId(detid_).stereo() ? &mhit.stereoClusterRef() : &mhit.monoClusterRef());
00173     } else if (typeid(ProjectedSiStripRecHit2D) == hit_type) {
00174       cluRef = &static_cast<ProjectedSiStripRecHit2D&>(genericHit).originalHit().omniCluster();
00175     }
00176   
00177     assert(cluRef != 0); // to catch missing RecHit types
00178     assert(cluRef->key() == ref_.key()); // otherwise something went wrong
00179     (*cluRef) = OmniClusterRef(newRef);
00180   }
00181   
00182 } // end namespace 'helper'