CMS 3D CMS Logo

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")<<"DTHitAssociator: WARNING: 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 {
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   // Get the DT rechits from the event
00127   edm::Handle<DTRecHitCollection> DTrechits; 
00128   LogTrace("DTHitAssociator") <<"getting DTRecHit1DPair collection - "<<DTrechitTag;
00129   iEvent.getByLabel(DTrechitTag,DTrechits);
00130   LogTrace("DTHitAssociator") <<"... size = "<<DTrechits->size();
00131   
00132   // map DTRecHit1DPair by DTWireId
00133   mapOfRecHit.clear();
00134   DTRecHitCollection::const_iterator rechit;
00135   for(rechit=DTrechits->begin(); rechit!=DTrechits->end(); ++rechit) {
00136     DTWireId wireid = (*rechit).wireId();
00137     mapOfRecHit[wireid].push_back(*rechit);
00138   }
00139   
00140   if(dumpDT && printRtS) {
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           DTDigi digi = *hitIT;
00180           edm::LogVerbatim("DTHitAssociator")
00181             <<"DTDigi "<<ihit<<", wire "<<wireid<<", number = "<<hitIT->number()<<", TDC counts = "<<hitIT->countsTDC();
00182         }       
00183       }
00184     } else {
00185       LogTrace("DTHitAssociator")<<"\n *** There are NO DTDigi's ***";
00186     }
00187     
00188     if (mapOfRecHit.end() != mapOfRecHit.begin()) 
00189       edm::LogVerbatim("DTHitAssociator")<<"\n *** Analyze DTRecHitCollection by DTWireId ***";
00190     
00191     int iwire = 0;
00192     for(RecHitMap::const_iterator mapIT=mapOfRecHit.begin(); 
00193         mapIT!=mapOfRecHit.end(); 
00194         ++mapIT , iwire++) {
00195       
00196       DTWireId wireid = (*mapIT).first;
00197       edm::LogVerbatim("DTHitAssociator")<<"\n==================================================================="; 
00198       edm::LogVerbatim("DTHitAssociator")<<"wire index = "<<iwire<<"  *** DTWireId = "<<" ("<<wireid<<")";
00199       
00200       if(mapOfSimHit.find(wireid) != mapOfSimHit.end()) {
00201         edm::LogVerbatim("DTHitAssociator")<<"\n"<<mapOfSimHit[wireid].size()<<" SimHits (PSimHit):";
00202         
00203         for (vector<PSimHit_withFlag>::const_iterator hitIT = mapOfSimHit[wireid].begin(); 
00204              hitIT != mapOfSimHit[wireid].end(); 
00205              ++hitIT) {
00206           stringstream tId;
00207           tId << (hitIT->first).trackId();
00208           string simhitlog = "\t SimTrack Id = "+tId.str();
00209           if (hitIT->second) simhitlog = simhitlog + "\t -VALID HIT-";
00210           else simhitlog = simhitlog + "\t -not valid hit-";
00211           edm::LogVerbatim("DTHitAssociator")<<simhitlog;
00212         }
00213       }
00214       
00215       if(mapOfLinks.find(wireid) != mapOfLinks.end()) {
00216         edm::LogVerbatim("DTHitAssociator")<<"\n"<<mapOfLinks[wireid].size()<<" Links (DTDigiSimLink):";
00217         
00218         for (vector<DTDigiSimLink>::const_iterator hitIT = mapOfLinks[wireid].begin(); 
00219              hitIT != mapOfLinks[wireid].end(); 
00220              ++hitIT) {
00221           edm::LogVerbatim("DTHitAssociator")
00222             <<"\t digi number = "<<hitIT->number()<<", time = "<<hitIT->time()<<", SimTrackId = "<<hitIT->SimTrackId();
00223         }
00224       }
00225       
00226       if(mapOfDigi.find(wireid) != mapOfDigi.end()) {
00227         edm::LogVerbatim("DTHitAssociator")<<"\n"<<mapOfDigi[wireid].size()<<" Digis (DTDigi):";
00228         for (vector<DTDigi>::const_iterator hitIT = mapOfDigi[wireid].begin(); 
00229              hitIT != mapOfDigi[wireid].end(); 
00230              ++hitIT) {
00231           edm::LogVerbatim("DTHitAssociator")<<"\t digi number = "<<hitIT->number()<<", time = "<<hitIT->time();
00232         }
00233       }
00234       
00235       edm::LogVerbatim("DTHitAssociator")<<"\n"<<(*mapIT).second.size()<<" RecHits (DTRecHit1DPair):";    
00236       for(vector<DTRecHit1DPair>::const_iterator vIT =(*mapIT).second.begin(); 
00237           vIT !=(*mapIT).second.end(); 
00238           ++vIT) {
00239         edm::LogVerbatim("DTHitAssociator")<<"\t digi time = "<<vIT->digiTime();
00240       }
00241     }
00242   }
00243 }
00244 // end of constructor
00245 
00246 std::vector<DTHitAssociator::SimHitIdpr> DTHitAssociator::associateHitId(const TrackingRecHit & hit) {
00247   
00248   std::vector<SimHitIdpr> simtrackids;
00249   const TrackingRecHit * hitp = &hit;
00250   const DTRecHit1D * dtrechit = dynamic_cast<const DTRecHit1D *>(hitp);
00251   
00252   if (dtrechit) {
00253     simtrackids = associateDTHitId(dtrechit);
00254   } else {
00255     edm::LogWarning("DTHitAssociator")<<"*** WARNING in DTHitAssociator::associateHitId, null dynamic_cast !";
00256   }
00257   return simtrackids;
00258 }
00259 
00260 std::vector<DTHitAssociator::SimHitIdpr> DTHitAssociator::associateDTHitId(const DTRecHit1D * dtrechit) {
00261   
00262   std::vector<SimHitIdpr> matched; 
00263 
00264   DTWireId wireid = dtrechit->wireId();
00265   
00266   if(associatorByWire) {
00267     // matching based on DTWireId : take only "valid" SimHits on that wire
00268 
00269     if(mapOfSimHit.find(wireid) != mapOfSimHit.end()) { 
00270       for (vector<PSimHit_withFlag>::const_iterator hitIT = mapOfSimHit[wireid].begin(); 
00271            hitIT != mapOfSimHit[wireid].end(); 
00272            ++hitIT) {
00273         
00274         bool valid_hit = hitIT->second;
00275         PSimHit this_hit = hitIT->first;
00276 
00277         if (valid_hit) {
00278           SimHitIdpr currentId(this_hit.trackId(), this_hit.eventId());
00279           matched.push_back(currentId);
00280         }
00281       }
00282     }
00283   }
00284 
00285   else {
00286     // matching based on DTDigiSimLink
00287     
00288     float theTime = dtrechit->digiTime();
00289     int theNumber(-1);
00290 
00291     if (mapOfLinks.find(wireid) != mapOfLinks.end()) {
00292       // DTDigiSimLink::time() is set equal to DTDigi::time() only for the DTDigiSimLink corresponding to the digitizied PSimHit
00293       // other DTDigiSimLinks associated to the same DTDigi are identified by having the same DTDigiSimLink::number()
00294       
00295       // first find the associated digi Number
00296       for (vector<DTDigiSimLink>::const_iterator linkIT = mapOfLinks[wireid].begin(); 
00297            linkIT != mapOfLinks[wireid].end(); 
00298            ++linkIT ) {
00299         float digitime = linkIT->time();
00300         if (fabs(digitime-theTime)<0.1) {
00301           theNumber = linkIT->number();
00302         }       
00303       }
00304       
00305       // then get all the DTDigiSimLinks with that digi Number (corresponding to valid SimHits  
00306       //  within a time window of the order of the time resolution, specified in the DTDigitizer)
00307       for (vector<DTDigiSimLink>::const_iterator linkIT = mapOfLinks[wireid].begin(); 
00308            linkIT != mapOfLinks[wireid].end(); 
00309            ++linkIT ) {
00310         
00311         int digiNr = linkIT->number();
00312         if (digiNr == theNumber) {
00313           SimHitIdpr currentId(linkIT->SimTrackId(), linkIT->eventId());
00314           matched.push_back(currentId);
00315         }
00316       }
00317 
00318     } else {
00319       edm::LogError("DTHitAssociator")<<"ERROR in DTHitAssociator::associateDTHitId - DTRecHit1D: "
00320                                       <<*dtrechit<<" has no associated DTDigiSimLink !"<<endl;
00321       return matched; 
00322     }
00323   }
00324   
00325   return matched;
00326 }
00327 
00328 std::vector<PSimHit> DTHitAssociator::associateHit(const TrackingRecHit & hit) {
00329   
00330   std::vector<PSimHit> simhits;  
00331   std::vector<SimHitIdpr> simtrackids;
00332 
00333   const TrackingRecHit * hitp = &hit;
00334   const DTRecHit1D * dtrechit = dynamic_cast<const DTRecHit1D *>(hitp);
00335 
00336   if (dtrechit) {
00337     DTWireId wireid = dtrechit->wireId();
00338     
00339     if (associatorByWire) {
00340     // matching based on DTWireId : take only "valid" SimHits on that wire
00341 
00342       if(mapOfSimHit.find(wireid) != mapOfSimHit.end()) {       
00343         for (vector<PSimHit_withFlag>::const_iterator hitIT = mapOfSimHit[wireid].begin(); 
00344              hitIT != mapOfSimHit[wireid].end(); 
00345              ++hitIT) {
00346           
00347           bool valid_hit = hitIT->second;
00348           if (valid_hit) simhits.push_back(hitIT->first);
00349         }
00350       }
00351     }
00352     else {
00353       // matching based on DTDigiSimLink
00354 
00355       simtrackids = associateDTHitId(dtrechit);
00356 
00357       for (vector<SimHitIdpr>::const_iterator idIT =  simtrackids.begin(); idIT != simtrackids.end(); ++idIT) {
00358         uint32_t trId = idIT->first;
00359         EncodedEventId evId = idIT->second;
00360         
00361         if(mapOfSimHit.find(wireid) != mapOfSimHit.end()) {     
00362           for (vector<PSimHit_withFlag>::const_iterator hitIT = mapOfSimHit[wireid].begin(); 
00363                hitIT != mapOfSimHit[wireid].end(); 
00364                ++hitIT) {
00365             
00366             if (hitIT->first.trackId() == trId  && 
00367                 hitIT->first.eventId() == evId) 
00368               simhits.push_back(hitIT->first);      
00369           }
00370         }       
00371       }
00372     }
00373 
00374   } else {
00375     edm::LogWarning("DTHitAssociator")<<"*** WARNING in DTHitAssociator::associateHit, null dynamic_cast !";
00376   }
00377   return simhits;
00378 }
00379 
00380 bool DTHitAssociator::SimHitOK(const edm::ESHandle<DTGeometry> & muongeom, 
00381                                const PSimHit & simhit) {
00382   bool result = true;
00383   
00384   DTWireId wireid(simhit.detUnitId());
00385   const DTLayer* dtlayer = muongeom->layer(wireid.layerId()); 
00386   LocalPoint entryP = simhit.entryPoint();
00387   LocalPoint exitP = simhit.exitPoint();
00388   const DTTopology &topo = dtlayer->specificTopology();
00389   float xwire = topo.wirePosition(wireid.wire()); 
00390   float xEntry = entryP.x() - xwire;
00391   float xExit  = exitP.x() - xwire;
00392   DTTopology::Side entrySide = topo.onWhichBorder(xEntry,entryP.y(),entryP.z());
00393   DTTopology::Side exitSide  = topo.onWhichBorder(xExit,exitP.y(),exitP.z());
00394   
00395   bool noParametrisation = 
00396     (( entrySide == DTTopology::none || exitSide == DTTopology::none ) ||
00397      (entrySide == exitSide) ||
00398      ((entrySide == DTTopology::xMin && exitSide == DTTopology::xMax) || 
00399       (entrySide == DTTopology::xMax && exitSide == DTTopology::xMin))   );
00400 
00401   // discard hits where parametrization can not be used
00402   if (noParametrisation) 
00403     {
00404       result = false;
00405       return result;
00406     }  
00407     
00408   float x;
00409   LocalPoint hitPos = simhit.localPosition(); 
00410   
00411   if(fabs(hitPos.z()) < 0.002) {
00412     // hit center within 20 um from z=0, no need to extrapolate.
00413     x = hitPos.x() - xwire;
00414   } else {
00415     x = xEntry - (entryP.z()*(xExit-xEntry))/(exitP.z()-entryP.z());
00416   }
00417   
00418   // discard hits where x is out of range of the parametrization (|x|>2.1 cm)
00419   x *= 10.;  //cm -> mm 
00420   if (fabs(x) > 21.) 
00421     result = false;
00422   
00423   return result;
00424 }

Generated on Tue Jun 9 17:47:35 2009 for CMSSW by  doxygen 1.5.4