CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/SimMuon/MCTruth/src/DTHitAssociator.cc

Go to the documentation of this file.
00001 #include "SimMuon/MCTruth/interface/DTHitAssociator.h"
00002 #include "SimDataFormats/CrossingFrame/interface/CrossingFrame.h"
00003 #include "SimDataFormats/CrossingFrame/interface/MixCollection.h"
00004 #include "DataFormats/DetId/interface/DetId.h"
00005 #include "DataFormats/MuonDetId/interface/MuonSubdetId.h"
00006 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00007 #include "Geometry/Records/interface/MuonGeometryRecord.h"
00008 #include "Geometry/DTGeometry/interface/DTLayer.h"
00009 #include "Geometry/DTGeometry/interface/DTTopology.h"
00010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00011 #include <string>
00012 #include <sstream>
00013 
00014 using namespace std;
00015 
00016 // Constructor
00017 DTHitAssociator::DTHitAssociator(const edm::Event& iEvent, const edm::EventSetup& iSetup, const edm::ParameterSet& conf, bool printRtS):
00018 
00019   // input collection labels
00020   DTsimhitsTag(conf.getParameter<edm::InputTag>("DTsimhitsTag")),
00021   DTsimhitsXFTag(conf.getParameter<edm::InputTag>("DTsimhitsXFTag")),
00022   DTdigiTag(conf.getParameter<edm::InputTag>("DTdigiTag")),
00023   DTdigisimlinkTag(conf.getParameter<edm::InputTag>("DTdigisimlinkTag")),
00024   DTrechitTag(conf.getParameter<edm::InputTag>("DTrechitTag")),
00025 
00026   // nice printout of DT hits
00027   dumpDT(conf.getParameter<bool>("dumpDT")),
00028   // CrossingFrame used or not ?
00029   crossingframe(conf.getParameter<bool>("crossingframe")),
00030   // Event contain the DTDigiSimLink collection ?
00031   links_exist(conf.getParameter<bool>("links_exist")),
00032   // associatorByWire links to a RecHit all the "valid" SimHits on the same DT wire
00033   associatorByWire(conf.getParameter<bool>("associatorByWire")),
00034 
00035   printRtS(true)
00036   
00037 {  
00038   LogTrace("DTHitAssociator") <<"DTHitAssociator constructor: dumpDT = "<<dumpDT
00039                               <<", crossingframe = "<<crossingframe<<", links_exist = "<<links_exist
00040                               <<", associatorByWire = "<<associatorByWire;
00041   
00042   if (!links_exist && !associatorByWire) {
00043     edm::LogWarning("DTHitAssociator")<<"*** WARNING in DTHitAssociator::DTHitAssociator: associatorByWire reset to TRUE !"
00044                                       <<"    \t (missing DTDigiSimLinkCollection ?)";
00045     associatorByWire = true;
00046   }
00047   
00048   // need DT Geometry to discard hits for which the drift time parametrisation is not applicable
00049   edm::ESHandle<DTGeometry> muonGeom;
00050   iSetup.get<MuonGeometryRecord>().get(muonGeom);
00051   
00052   // Get the DT SimHits from the event and map PSimHit by DTWireId
00053   mapOfSimHit.clear();
00054   bool takeHit(true);
00055  
00056   if (crossingframe) {
00057     edm::Handle<CrossingFrame<PSimHit> > xFrame;
00058     LogTrace("DTHitAssociator") <<"getting CrossingFrame<PSimHit> collection - "<<DTsimhitsXFTag;
00059     iEvent.getByLabel(DTsimhitsXFTag,xFrame);
00060     auto_ptr<MixCollection<PSimHit> > 
00061       DTsimhits( new MixCollection<PSimHit>(xFrame.product()) );
00062     LogTrace("DTHitAssociator") <<"... size = "<<DTsimhits->size();
00063     MixCollection<PSimHit>::MixItr isimhit;
00064     for (isimhit=DTsimhits->begin(); isimhit!= DTsimhits->end(); isimhit++) {
00065       DTWireId wireid((*isimhit).detUnitId());
00066       takeHit = SimHitOK(muonGeom, *isimhit);
00067       mapOfSimHit[wireid].push_back(make_pair(*isimhit,takeHit));
00068     }
00069   }
00070   else if (!DTsimhitsTag.label().empty()) {
00071     edm::Handle<edm::PSimHitContainer> DTsimhits;
00072     LogTrace("DTHitAssociator") <<"getting PSimHit collection - "<<DTsimhitsTag;
00073     iEvent.getByLabel(DTsimhitsTag,DTsimhits);    
00074     LogTrace("DTHitAssociator") <<"... size = "<<DTsimhits->size();
00075     edm::PSimHitContainer::const_iterator isimhit;
00076     for (isimhit=DTsimhits->begin(); isimhit!= DTsimhits->end(); isimhit++) {
00077       DTWireId wireid((*isimhit).detUnitId());
00078       takeHit = SimHitOK(muonGeom, *isimhit);
00079       mapOfSimHit[wireid].push_back(make_pair(*isimhit,takeHit));
00080     }    
00081   }
00082 
00083   // Get the DT Digi collection from the event
00084   mapOfDigi.clear();
00085   edm::Handle<DTDigiCollection> digis;
00086   LogTrace("DTHitAssociator") <<"getting DTDigi collection - "<<DTdigiTag;
00087   iEvent.getByLabel(DTdigiTag,digis);
00088   
00089   if (digis.isValid()) {
00090     // Map DTDigi by DTWireId
00091     for (DTDigiCollection::DigiRangeIterator detUnit=digis->begin(); detUnit !=digis->end(); ++detUnit) {
00092       const DTLayerId& layerid = (*detUnit).first;
00093       const DTDigiCollection::Range& range = (*detUnit).second;
00094       
00095       DTDigiCollection::const_iterator digi;
00096       for (digi = range.first; digi != range.second; ++digi){
00097         DTWireId wireid(layerid,(*digi).wire());
00098         mapOfDigi[wireid].push_back(*digi);
00099       }
00100     }
00101   } else {
00102     LogTrace("DTHitAssociator") <<"... NO DTDigi collection found !";
00103   }
00104   
00105   mapOfLinks.clear();
00106   if (links_exist) {
00107   // Get the DT DigiSimLink collection from the event and map DTDigiSimLink by DTWireId
00108     edm::Handle<DTDigiSimLinkCollection> digisimlinks;
00109     LogTrace("DTHitAssociator") <<"getting DTDigiSimLink collection - "<<DTdigisimlinkTag;
00110     iEvent.getByLabel(DTdigisimlinkTag,digisimlinks);
00111     
00112     for (DTDigiSimLinkCollection::DigiRangeIterator detUnit=digisimlinks->begin(); 
00113          detUnit !=digisimlinks->end(); 
00114          ++detUnit) {
00115       const DTLayerId& layerid = (*detUnit).first;
00116       const DTDigiSimLinkCollection::Range& range = (*detUnit).second;
00117       
00118       DTDigiSimLinkCollection::const_iterator link;
00119       for (link=range.first; link!=range.second; ++link){
00120         DTWireId wireid(layerid,(*link).wire());
00121         mapOfLinks[wireid].push_back(*link);
00122       }
00123     }
00124   }
00125 
00126   if(dumpDT && printRtS) {
00127     
00128     // Get the DT rechits from the event
00129     edm::Handle<DTRecHitCollection> DTrechits; 
00130     LogTrace("DTHitAssociator") <<"getting DTRecHit1DPair collection - "<<DTrechitTag;
00131     iEvent.getByLabel(DTrechitTag,DTrechits);
00132     LogTrace("DTHitAssociator") <<"... size = "<<DTrechits->size();
00133     
00134     // map DTRecHit1DPair by DTWireId
00135     mapOfRecHit.clear();
00136     DTRecHitCollection::const_iterator rechit;
00137     for(rechit=DTrechits->begin(); rechit!=DTrechits->end(); ++rechit) {
00138       DTWireId wireid = (*rechit).wireId();
00139       mapOfRecHit[wireid].push_back(*rechit);
00140     }
00141     
00142     if (mapOfSimHit.end() != mapOfSimHit.begin()) {
00143       edm::LogVerbatim("DTHitAssociator")<<"\n *** Dump DT PSimHit's ***";
00144       
00145       int jwire = 0;
00146       int ihit = 0;
00147       
00148       for(SimHitMap::const_iterator mapIT=mapOfSimHit.begin();
00149           mapIT!=mapOfSimHit.end();
00150           ++mapIT , jwire++) {
00151         
00152         DTWireId wireid = (*mapIT).first;
00153         for (vector<PSimHit_withFlag>::const_iterator hitIT = mapOfSimHit[wireid].begin(); 
00154              hitIT != mapOfSimHit[wireid].end(); 
00155              hitIT++ , ihit++) {
00156           PSimHit hit = hitIT->first;
00157           edm::LogVerbatim("DTHitAssociator")
00158             <<"PSimHit "<<ihit <<", wire "<<wireid //<<", detID = "<<hit.detUnitId()
00159             <<", SimTrack Id:"<<hit.trackId()<<"/Evt:(" <<hit.eventId().event()<<","<<hit.eventId().bunchCrossing()<<") "
00160             <<", pdg = "<<hit.particleType()<<", procs = "<<hit.processType();
00161         }       
00162       } 
00163     } else {
00164       edm::LogVerbatim("DTHitAssociator")<<"\n *** There are NO DT PSimHit's ***";
00165     }
00166 
00167     if(mapOfDigi.end() != mapOfDigi.begin()) {
00168       
00169       int jwire = 0;
00170       int ihit = 0;
00171       
00172       for(DigiMap::const_iterator mapIT=mapOfDigi.begin(); mapIT!=mapOfDigi.end(); ++mapIT , jwire++) {
00173         edm::LogVerbatim("DTHitAssociator")<<"\n *** Dump DT digis ***";
00174 
00175         DTWireId wireid = (*mapIT).first;
00176         for (vector<DTDigi>::const_iterator hitIT = mapOfDigi[wireid].begin(); 
00177              hitIT != mapOfDigi[wireid].end(); 
00178              hitIT++ , ihit++) {
00179           edm::LogVerbatim("DTHitAssociator")
00180             <<"DTDigi "<<ihit<<", wire "<<wireid<<", number = "<<hitIT->number()<<", TDC counts = "<<hitIT->countsTDC();
00181         }       
00182       }
00183     } else {
00184       LogTrace("DTHitAssociator")<<"\n *** There are NO DTDigi's ***";
00185     }
00186     
00187     if (mapOfRecHit.end() != mapOfRecHit.begin()) 
00188       edm::LogVerbatim("DTHitAssociator")<<"\n *** Analyze DTRecHitCollection by DTWireId ***";
00189     
00190     int iwire = 0;
00191     for(RecHitMap::const_iterator mapIT=mapOfRecHit.begin(); 
00192         mapIT!=mapOfRecHit.end(); 
00193         ++mapIT , iwire++) {
00194       
00195       DTWireId wireid = (*mapIT).first;
00196       edm::LogVerbatim("DTHitAssociator")<<"\n==================================================================="; 
00197       edm::LogVerbatim("DTHitAssociator")<<"wire index = "<<iwire<<"  *** DTWireId = "<<" ("<<wireid<<")";
00198       
00199       if(mapOfSimHit.find(wireid) != mapOfSimHit.end()) {
00200         edm::LogVerbatim("DTHitAssociator")<<"\n"<<mapOfSimHit[wireid].size()<<" SimHits (PSimHit):";
00201         
00202         for (vector<PSimHit_withFlag>::const_iterator hitIT = mapOfSimHit[wireid].begin(); 
00203              hitIT != mapOfSimHit[wireid].end(); 
00204              ++hitIT) {
00205           stringstream tId;
00206           tId << (hitIT->first).trackId();
00207           string simhitlog = "\t SimTrack Id = "+tId.str();
00208           if (hitIT->second) simhitlog = simhitlog + "\t -VALID HIT-";
00209           else simhitlog = simhitlog + "\t -not valid hit-";
00210           edm::LogVerbatim("DTHitAssociator")<<simhitlog;
00211         }
00212       }
00213       
00214       if(mapOfLinks.find(wireid) != mapOfLinks.end()) {
00215         edm::LogVerbatim("DTHitAssociator")<<"\n"<<mapOfLinks[wireid].size()<<" Links (DTDigiSimLink):";
00216         
00217         for (vector<DTDigiSimLink>::const_iterator hitIT = mapOfLinks[wireid].begin(); 
00218              hitIT != mapOfLinks[wireid].end(); 
00219              ++hitIT) {
00220           edm::LogVerbatim("DTHitAssociator")
00221             <<"\t digi number = "<<hitIT->number()<<", time = "<<hitIT->time()<<", SimTrackId = "<<hitIT->SimTrackId();
00222         }
00223       }
00224       
00225       if(mapOfDigi.find(wireid) != mapOfDigi.end()) {
00226         edm::LogVerbatim("DTHitAssociator")<<"\n"<<mapOfDigi[wireid].size()<<" Digis (DTDigi):";
00227         for (vector<DTDigi>::const_iterator hitIT = mapOfDigi[wireid].begin(); 
00228              hitIT != mapOfDigi[wireid].end(); 
00229              ++hitIT) {
00230           edm::LogVerbatim("DTHitAssociator")<<"\t digi number = "<<hitIT->number()<<", time = "<<hitIT->time();
00231         }
00232       }
00233       
00234       edm::LogVerbatim("DTHitAssociator")<<"\n"<<(*mapIT).second.size()<<" RecHits (DTRecHit1DPair):";    
00235       for(vector<DTRecHit1DPair>::const_iterator vIT =(*mapIT).second.begin(); 
00236           vIT !=(*mapIT).second.end(); 
00237           ++vIT) {
00238         edm::LogVerbatim("DTHitAssociator")<<"\t digi time = "<<vIT->digiTime();
00239       }
00240     }
00241   }
00242 }
00243 // end of constructor
00244 
00245 std::vector<DTHitAssociator::SimHitIdpr> DTHitAssociator::associateHitId(const TrackingRecHit & hit) {
00246   
00247   std::vector<SimHitIdpr> simtrackids;
00248   const TrackingRecHit * hitp = &hit;
00249   const DTRecHit1D * dtrechit = dynamic_cast<const DTRecHit1D *>(hitp);
00250   
00251   if (dtrechit) {
00252     simtrackids = associateDTHitId(dtrechit);
00253   } else {
00254     edm::LogWarning("DTHitAssociator")<<"*** WARNING in DTHitAssociator::associateHitId, null dynamic_cast !";
00255   }
00256   return simtrackids;
00257 }
00258 
00259 std::vector<DTHitAssociator::SimHitIdpr> DTHitAssociator::associateDTHitId(const DTRecHit1D * dtrechit) {
00260   
00261   std::vector<SimHitIdpr> matched; 
00262 
00263   DTWireId wireid = dtrechit->wireId();
00264   
00265   if(associatorByWire) {
00266     // matching based on DTWireId : take only "valid" SimHits on that wire
00267 
00268     if(mapOfSimHit.find(wireid) != mapOfSimHit.end()) { 
00269       for (vector<PSimHit_withFlag>::const_iterator hitIT = mapOfSimHit[wireid].begin(); 
00270            hitIT != mapOfSimHit[wireid].end(); 
00271            ++hitIT) {
00272         
00273         bool valid_hit = hitIT->second;
00274         PSimHit this_hit = hitIT->first;
00275 
00276         if (valid_hit) {
00277           SimHitIdpr currentId(this_hit.trackId(), this_hit.eventId());
00278           matched.push_back(currentId);
00279         }
00280       }
00281     }
00282   }
00283 
00284   else {
00285     // matching based on DTDigiSimLink
00286     
00287     float theTime = dtrechit->digiTime();
00288     int theNumber(-1);
00289 
00290     if (mapOfLinks.find(wireid) != mapOfLinks.end()) {
00291       // DTDigiSimLink::time() is set equal to DTDigi::time() only for the DTDigiSimLink corresponding to the digitizied PSimHit
00292       // other DTDigiSimLinks associated to the same DTDigi are identified by having the same DTDigiSimLink::number()
00293       
00294       // first find the associated digi Number
00295       for (vector<DTDigiSimLink>::const_iterator linkIT = mapOfLinks[wireid].begin(); 
00296            linkIT != mapOfLinks[wireid].end(); 
00297            ++linkIT ) {
00298         float digitime = linkIT->time();
00299         if (fabs(digitime-theTime)<0.1) {
00300           theNumber = linkIT->number();
00301         }       
00302       }
00303       
00304       // then get all the DTDigiSimLinks with that digi Number (corresponding to valid SimHits  
00305       //  within a time window of the order of the time resolution, specified in the DTDigitizer)
00306       for (vector<DTDigiSimLink>::const_iterator linkIT = mapOfLinks[wireid].begin(); 
00307            linkIT != mapOfLinks[wireid].end(); 
00308            ++linkIT ) {
00309         
00310         int digiNr = linkIT->number();
00311         if (digiNr == theNumber) {
00312           SimHitIdpr currentId(linkIT->SimTrackId(), linkIT->eventId());
00313           matched.push_back(currentId);
00314         }
00315       }
00316 
00317     } else {
00318       edm::LogError("DTHitAssociator")<<"*** ERROR in DTHitAssociator::associateDTHitId - DTRecHit1D: "
00319                                       <<*dtrechit<<" has no associated DTDigiSimLink !"<<endl;
00320       return matched; 
00321     }
00322   }
00323   
00324   return matched;
00325 }
00326 
00327 std::vector<PSimHit> DTHitAssociator::associateHit(const TrackingRecHit & hit) {
00328   
00329   std::vector<PSimHit> simhits;  
00330   std::vector<SimHitIdpr> simtrackids;
00331 
00332   const TrackingRecHit * hitp = &hit;
00333   const DTRecHit1D * dtrechit = dynamic_cast<const DTRecHit1D *>(hitp);
00334 
00335   if (dtrechit) {
00336     DTWireId wireid = dtrechit->wireId();
00337     
00338     if (associatorByWire) {
00339     // matching based on DTWireId : take only "valid" SimHits on that wire
00340 
00341       if(mapOfSimHit.find(wireid) != mapOfSimHit.end()) {       
00342         for (vector<PSimHit_withFlag>::const_iterator hitIT = mapOfSimHit[wireid].begin(); 
00343              hitIT != mapOfSimHit[wireid].end(); 
00344              ++hitIT) {
00345           
00346           bool valid_hit = hitIT->second;
00347           if (valid_hit) simhits.push_back(hitIT->first);
00348         }
00349       }
00350     }
00351     else {
00352       // matching based on DTDigiSimLink
00353 
00354       simtrackids = associateDTHitId(dtrechit);
00355 
00356       for (vector<SimHitIdpr>::const_iterator idIT =  simtrackids.begin(); idIT != simtrackids.end(); ++idIT) {
00357         uint32_t trId = idIT->first;
00358         EncodedEventId evId = idIT->second;
00359         
00360         if(mapOfSimHit.find(wireid) != mapOfSimHit.end()) {     
00361           for (vector<PSimHit_withFlag>::const_iterator hitIT = mapOfSimHit[wireid].begin(); 
00362                hitIT != mapOfSimHit[wireid].end(); 
00363                ++hitIT) {
00364             
00365             if (hitIT->first.trackId() == trId  && 
00366                 hitIT->first.eventId() == evId) 
00367               simhits.push_back(hitIT->first);      
00368           }
00369         }       
00370       }
00371     }
00372 
00373   } else {
00374     edm::LogWarning("DTHitAssociator")<<"*** WARNING in DTHitAssociator::associateHit, null dynamic_cast !";
00375   }
00376   return simhits;
00377 }
00378 
00379 bool DTHitAssociator::SimHitOK(const edm::ESHandle<DTGeometry> & muongeom, 
00380                                const PSimHit & simhit) {
00381   bool result = true;
00382   
00383   DTWireId wireid(simhit.detUnitId());
00384   const DTLayer* dtlayer = muongeom->layer(wireid.layerId()); 
00385   LocalPoint entryP = simhit.entryPoint();
00386   LocalPoint exitP = simhit.exitPoint();
00387   const DTTopology &topo = dtlayer->specificTopology();
00388   float xwire = topo.wirePosition(wireid.wire()); 
00389   float xEntry = entryP.x() - xwire;
00390   float xExit  = exitP.x() - xwire;
00391   DTTopology::Side entrySide = topo.onWhichBorder(xEntry,entryP.y(),entryP.z());
00392   DTTopology::Side exitSide  = topo.onWhichBorder(xExit,exitP.y(),exitP.z());
00393   
00394   bool noParametrisation = 
00395     (( entrySide == DTTopology::none || exitSide == DTTopology::none ) ||
00396      (entrySide == exitSide) ||
00397      ((entrySide == DTTopology::xMin && exitSide == DTTopology::xMax) || 
00398       (entrySide == DTTopology::xMax && exitSide == DTTopology::xMin))   );
00399 
00400   // discard hits where parametrization can not be used
00401   if (noParametrisation) 
00402     {
00403       result = false;
00404       return result;
00405     }  
00406     
00407   float x;
00408   LocalPoint hitPos = simhit.localPosition(); 
00409   
00410   if(fabs(hitPos.z()) < 0.002) {
00411     // hit center within 20 um from z=0, no need to extrapolate.
00412     x = hitPos.x() - xwire;
00413   } else {
00414     x = xEntry - (entryP.z()*(xExit-xEntry))/(exitP.z()-entryP.z());
00415   }
00416   
00417   // discard hits where x is out of range of the parametrization (|x|>2.1 cm)
00418   x *= 10.;  //cm -> mm 
00419   if (fabs(x) > 21.) 
00420     result = false;
00421   
00422   return result;
00423 }