CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/SimMuon/MCTruth/src/MuonTruth.cc

Go to the documentation of this file.
00001 #include "SimMuon/MCTruth/interface/MuonTruth.h"
00002 #include "FWCore/Framework/interface/ESHandle.h"
00003 #include "DataFormats/Common/interface/DetSetVector.h"
00004 #include "SimDataFormats/TrackerDigiSimLink/interface/StripDigiSimLink.h"
00005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00006 #include "Geometry/Records/interface/MuonGeometryRecord.h"
00007 
00008 MuonTruth::MuonTruth(const edm::Event& event, const edm::EventSetup& setup, const edm::ParameterSet& conf): 
00009   theDigiSimLinks(0),
00010   theWireDigiSimLinks(0),
00011   linksTag(conf.getParameter<edm::InputTag>("CSClinksTag")),
00012   wireLinksTag(conf.getParameter<edm::InputTag>("CSCwireLinksTag")),
00013   // CrossingFrame used or not ?
00014   crossingframe(conf.getParameter<bool>("crossingframe")),
00015   CSCsimHitsTag(conf.getParameter<edm::InputTag>("CSCsimHitsTag")),
00016   CSCsimHitsXFTag(conf.getParameter<edm::InputTag>("CSCsimHitsXFTag"))
00017 
00018 {
00019   edm::Handle<DigiSimLinks> digiSimLinks;
00020   LogTrace("MuonTruth") <<"getting CSC Strip DigiSimLink collection - "<<linksTag;
00021   event.getByLabel(linksTag, digiSimLinks);
00022   theDigiSimLinks = digiSimLinks.product();
00023 
00024   edm::Handle<DigiSimLinks> wireDigiSimLinks;
00025   LogTrace("MuonTruth") <<"getting CSC Wire DigiSimLink collection - "<<wireLinksTag;
00026   event.getByLabel(wireLinksTag, wireDigiSimLinks);
00027   theWireDigiSimLinks = wireDigiSimLinks.product();
00028 
00029   // get CSC Geometry to use CSCLayer methods
00030   edm::ESHandle<CSCGeometry> mugeom;
00031   setup.get<MuonGeometryRecord>().get( mugeom );
00032   cscgeom = &*mugeom;
00033 
00034   // get CSC Bad Chambers (ME4/2)
00035   edm::ESHandle<CSCBadChambers> badChambers;
00036   setup.get<CSCBadChambersRcd>().get(badChambers);
00037   cscBadChambers = badChambers.product();
00038 
00039   theSimHitMap.clear();
00040 
00041   if (crossingframe) {
00042     
00043     edm::Handle<CrossingFrame<PSimHit> > cf;
00044     LogTrace("MuonTruth") <<"getting CrossingFrame<PSimHit> collection - "<<CSCsimHitsXFTag;
00045     event.getByLabel(CSCsimHitsXFTag, cf);
00046     
00047     std::auto_ptr<MixCollection<PSimHit> > 
00048       CSCsimhits( new MixCollection<PSimHit>(cf.product()) );
00049     LogTrace("MuonTruth") <<"... size = "<<CSCsimhits->size();
00050 
00051     for(MixCollection<PSimHit>::MixItr hitItr = CSCsimhits->begin();
00052         hitItr != CSCsimhits->end(); ++hitItr) 
00053       {
00054         theSimHitMap[hitItr->detUnitId()].push_back(*hitItr);
00055       }
00056     
00057   } else if (!CSCsimHitsTag.label().empty()){
00058 
00059     edm::Handle<edm::PSimHitContainer> CSCsimhits;
00060     LogTrace("MuonTruth") <<"getting PSimHit collection - "<<CSCsimHitsTag;
00061     event.getByLabel(CSCsimHitsTag, CSCsimhits);    
00062     LogTrace("MuonTruth") <<"... size = "<<CSCsimhits->size();
00063     
00064     for(edm::PSimHitContainer::const_iterator hitItr = CSCsimhits->begin();
00065         hitItr != CSCsimhits->end(); ++hitItr)
00066       {
00067         theSimHitMap[hitItr->detUnitId()].push_back(*hitItr);
00068       }
00069   }
00070 }
00071 
00072 float MuonTruth::muonFraction()
00073 {
00074   if(theChargeMap.size() == 0) return 0.;
00075 
00076   float muonCharge = 0.;
00077   for(std::map<SimHitIdpr, float>::const_iterator chargeMapItr = theChargeMap.begin();
00078       chargeMapItr != theChargeMap.end(); ++chargeMapItr)
00079   {
00080     if( abs(particleType(chargeMapItr->first)) == 13)
00081     {
00082       muonCharge += chargeMapItr->second;
00083     }
00084   }
00085 
00086   return muonCharge / theTotalCharge;
00087 }
00088 
00089 
00090 std::vector<PSimHit> MuonTruth::simHits()
00091 {
00092   std::vector<PSimHit> result;
00093   for(std::map<SimHitIdpr, float>::const_iterator chargeMapItr = theChargeMap.begin();
00094       chargeMapItr != theChargeMap.end(); ++chargeMapItr)
00095   {
00096     std::vector<PSimHit> trackHits = hitsFromSimTrack(chargeMapItr->first);
00097     result.insert(result.end(), trackHits.begin(), trackHits.end());
00098   }
00099   
00100   return result;
00101 }
00102 
00103 
00104 std::vector<PSimHit> MuonTruth::muonHits()
00105 {
00106   std::vector<PSimHit> result;
00107   std::vector<PSimHit> allHits = simHits();
00108   std::vector<PSimHit>::const_iterator hitItr = allHits.begin(), lastHit = allHits.end();
00109 
00110   for( ; hitItr != lastHit; ++hitItr)
00111   {
00112     if(abs((*hitItr).particleType()) == 13)
00113     {
00114       result.push_back(*hitItr);
00115     }
00116   }
00117   return result;
00118 }
00119 
00120 
00121 std::vector<MuonTruth::SimHitIdpr> MuonTruth::associateCSCHitId(const CSCRecHit2D * cscrechit) {
00122   std::vector<SimHitIdpr> simtrackids;
00123   
00124   theDetId = cscrechit->geographicalId().rawId();
00125   int nchannels = cscrechit->nStrips();
00126   const CSCLayerGeometry * laygeom = cscgeom->layer(cscrechit->cscDetId())->geometry();
00127   
00128   DigiSimLinks::const_iterator layerLinks = theDigiSimLinks->find(theDetId);    
00129   
00130   if (layerLinks != theDigiSimLinks->end()) {
00131     
00132     for(int idigi = 0; idigi < nchannels; ++idigi) {
00133       // strip and readout channel numbers may differ in ME1/1A
00134       int istrip = cscrechit->channels(idigi);
00135       int channel = laygeom->channel(istrip);
00136       
00137       for (LayerLinks::const_iterator link=layerLinks->begin(); link!=layerLinks->end(); ++link) {
00138         int ch = static_cast<int>(link->channel());
00139         if (ch == channel) {
00140           SimHitIdpr currentId(link->SimTrackId(), link->eventId());
00141           if (find(simtrackids.begin(), simtrackids.end(), currentId) == simtrackids.end())
00142             simtrackids.push_back(currentId);
00143         }
00144       }
00145     }
00146     
00147   } else edm::LogWarning("MuonTruth")
00148     <<"*** WARNING in MuonTruth::associateCSCHitId - CSC layer "<<theDetId<<" has no DigiSimLinks !"<<std::endl;   
00149   
00150   return simtrackids;
00151 }
00152 
00153 
00154 std::vector<MuonTruth::SimHitIdpr> MuonTruth::associateHitId(const TrackingRecHit & hit)
00155 {
00156   std::vector<SimHitIdpr> simtrackids;
00157   
00158   const TrackingRecHit * hitp = &hit;
00159   const CSCRecHit2D * cscrechit = dynamic_cast<const CSCRecHit2D *>(hitp);
00160 
00161   if (cscrechit) {
00162     
00163     theDetId = cscrechit->geographicalId().rawId();
00164     int nchannels = cscrechit->nStrips();
00165     const CSCLayerGeometry * laygeom = cscgeom->layer(cscrechit->cscDetId())->geometry();
00166 
00167     DigiSimLinks::const_iterator layerLinks = theDigiSimLinks->find(theDetId);    
00168 
00169     if (layerLinks != theDigiSimLinks->end()) {
00170       
00171       for(int idigi = 0; idigi < nchannels; ++idigi) {
00172         // strip and readout channel numbers may differ in ME1/1A
00173         int istrip = cscrechit->channels(idigi);
00174         int channel = laygeom->channel(istrip);
00175         
00176         for (LayerLinks::const_iterator link=layerLinks->begin(); link!=layerLinks->end(); ++link) {
00177           int ch = static_cast<int>(link->channel());
00178           if (ch == channel) {
00179             SimHitIdpr currentId(link->SimTrackId(), link->eventId());
00180             if (find(simtrackids.begin(), simtrackids.end(), currentId) == simtrackids.end())
00181               simtrackids.push_back(currentId);
00182           }
00183         }
00184       }
00185       
00186     } else edm::LogWarning("MuonTruth")
00187       <<"*** WARNING in MuonTruth::associateHitId - CSC layer "<<theDetId<<" has no DigiSimLinks !"<<std::endl;   
00188     
00189   } else edm::LogWarning("MuonTruth")<<"*** WARNING in MuonTruth::associateHitId, null dynamic_cast !";
00190   
00191   return simtrackids;
00192 }
00193 
00194 
00195 std::vector<PSimHit> MuonTruth::hitsFromSimTrack(MuonTruth::SimHitIdpr truthId)
00196 {
00197   std::vector<PSimHit> result;
00198   edm::PSimHitContainer hits;
00199   
00200   if (theSimHitMap.find(theDetId) != theSimHitMap.end()) 
00201     hits = theSimHitMap[theDetId];
00202 
00203   edm::PSimHitContainer::const_iterator hitItr = hits.begin(), lastHit = hits.end();
00204 
00205   for( ; hitItr != lastHit; ++hitItr)
00206   {
00207     unsigned int hitTrack = hitItr->trackId();
00208     EncodedEventId hitEvId = hitItr->eventId();
00209 
00210     if(hitTrack == truthId.first && hitEvId == truthId.second) 
00211     {
00212       result.push_back(*hitItr);
00213     }
00214   }
00215   return result;
00216 }
00217 
00218 
00219 int MuonTruth::particleType(MuonTruth::SimHitIdpr truthId)
00220 {
00221   int result = 0;
00222   std::vector<PSimHit> hits = hitsFromSimTrack(truthId);
00223   if(!hits.empty())
00224   {
00225     result = hits[0].particleType();
00226   }
00227   return result;
00228 }
00229 
00230 
00231 void MuonTruth::analyze(const CSCRecHit2D & recHit)
00232 {
00233   theChargeMap.clear();
00234   theTotalCharge = 0.;
00235   theDetId = recHit.geographicalId().rawId();
00236 
00237   int nchannels = recHit.nStrips();
00238   const CSCLayerGeometry * laygeom = cscgeom->layer(recHit.cscDetId())->geometry();
00239 
00240   for(int idigi = 0; idigi < nchannels; ++idigi)
00241   {
00242     // strip and readout channel numbers may differ in ME1/1A
00243     int istrip = recHit.channels(idigi);
00244     int channel = laygeom->channel(istrip);
00245     float weight = recHit.adcs(idigi,0);//DL: I think this is wrong before and after...seems to assume one time binadcContainer[idigi];
00246 
00247     DigiSimLinks::const_iterator layerLinks = theDigiSimLinks->find(theDetId);
00248 
00249     if(layerLinks != theDigiSimLinks->end())
00250     {
00251       addChannel(*layerLinks, channel, weight);
00252     }
00253   }
00254 }
00255 
00256 
00257 void MuonTruth::analyze(const CSCStripDigi & stripDigi, int rawDetIdCorrespondingToCSCLayer)
00258 {
00259   theDetId = rawDetIdCorrespondingToCSCLayer;
00260   theChargeMap.clear();
00261   theTotalCharge = 0.;
00262 
00263   DigiSimLinks::const_iterator layerLinks = theDigiSimLinks->find(theDetId);
00264   if(layerLinks != theDigiSimLinks->end())
00265   {
00266     addChannel(*layerLinks, stripDigi.getStrip(), 1.);
00267   }
00268 }
00269 
00270 
00271 void MuonTruth::analyze(const CSCWireDigi & wireDigi, int rawDetIdCorrespondingToCSCLayer) 
00272 {
00273   theDetId = rawDetIdCorrespondingToCSCLayer;
00274   theChargeMap.clear();
00275   theTotalCharge = 0.;
00276 
00277   WireDigiSimLinks::const_iterator layerLinks = theWireDigiSimLinks->find(theDetId);
00278 
00279   if(layerLinks != theDigiSimLinks->end()) 
00280   {
00281     // In the simulation digis, the channel labels for wires and strips must be distinct, therefore:
00282     int wireDigiInSimulation = wireDigi.getWireGroup() + 100;
00283     //
00284     addChannel(*layerLinks, wireDigiInSimulation, 1.);
00285   }
00286 }
00287 
00288 
00289 void MuonTruth::addChannel(const LayerLinks &layerLinks, int channel, float weight)
00290 {
00291   LayerLinks::const_iterator linkItr = layerLinks.begin(), 
00292                              lastLayerLink = layerLinks.end();
00293 
00294   for ( ; linkItr != lastLayerLink; ++linkItr)
00295   {
00296     int linkChannel = linkItr->channel();
00297     if(linkChannel == channel)
00298     {
00299       float charge = linkItr->fraction() * weight;
00300       theTotalCharge += charge;
00301       // see if it's in the map
00302       SimHitIdpr truthId(linkItr->SimTrackId(),linkItr->eventId());
00303       std::map<SimHitIdpr, float>::const_iterator chargeMapItr = theChargeMap.find(truthId);
00304       if(chargeMapItr == theChargeMap.end())
00305       {
00306         theChargeMap[truthId] = charge;
00307       }
00308       else
00309       {
00310         theChargeMap[truthId] += charge;
00311       }
00312     }
00313   }
00314 }
00315     
00316