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::ParameterSet& conf)
00009 : theDigiSimLinks(0),
00010 theWireDigiSimLinks(0),
00011 theSimHitMap(conf.getParameter<edm::InputTag>("CSCsimHitsXFTag")),
00012 simTracksXFTag(conf.getParameter<edm::InputTag>("simtracksXFTag")),
00013 linksTag(conf.getParameter<edm::InputTag>("CSClinksTag")),
00014 wireLinksTag(conf.getParameter<edm::InputTag>("CSCwireLinksTag"))
00015 {
00016 }
00017
00018 void MuonTruth::eventSetup(const edm::Event & event, const edm::EventSetup & setup)
00019 {
00020 edm::Handle<CrossingFrame<SimTrack> > xFrame;
00021 LogTrace("MuonTruth") <<"getting CrossingFrame<SimTrack> collection - "<<simTracksXFTag;
00022 event.getByLabel(simTracksXFTag,xFrame);
00023 std::auto_ptr<MixCollection<SimTrack> >
00024 theSimTracks( new MixCollection<SimTrack>(xFrame.product()) );
00025
00026 edm::Handle<DigiSimLinks> digiSimLinks;
00027 LogTrace("MuonTruth") <<"getting CSC Strip DigiSimLink collection - "<<linksTag;
00028 event.getByLabel(linksTag, digiSimLinks);
00029 theDigiSimLinks = digiSimLinks.product();
00030
00031 edm::Handle<DigiSimLinks> wireDigiSimLinks;
00032 LogTrace("MuonTruth") <<"getting CSC Wire DigiSimLink collection - "<<wireLinksTag;
00033 event.getByLabel(wireLinksTag, wireDigiSimLinks);
00034 theWireDigiSimLinks = wireDigiSimLinks.product();
00035
00036 theSimHitMap.fill(event);
00037
00038
00039 edm::ESHandle<CSCGeometry> mugeom;
00040 setup.get<MuonGeometryRecord>().get( mugeom );
00041 cscgeom = &*mugeom;
00042 }
00043
00044 float MuonTruth::muonFraction()
00045 {
00046 if(theChargeMap.size() == 0) return 0.;
00047
00048 float muonCharge = 0.;
00049 for(std::map<int, float>::const_iterator chargeMapItr = theChargeMap.begin();
00050 chargeMapItr != theChargeMap.end(); ++chargeMapItr)
00051 {
00052 if( abs(particleType(chargeMapItr->first)) == 13)
00053 {
00054 muonCharge += chargeMapItr->second;
00055 }
00056 }
00057
00058 return muonCharge / theTotalCharge;
00059 }
00060
00061
00062 std::vector<PSimHit> MuonTruth::simHits()
00063 {
00064 std::vector<PSimHit> result;
00065 for(std::map<int, float>::const_iterator chargeMapItr = theChargeMap.begin();
00066 chargeMapItr != theChargeMap.end(); ++chargeMapItr)
00067 {
00068 std::vector<PSimHit> trackHits = hitsFromSimTrack(chargeMapItr->first);
00069 result.insert(result.end(), trackHits.begin(), trackHits.end());
00070 }
00071
00072 return result;
00073 }
00074
00075
00076 std::vector<PSimHit> MuonTruth::muonHits()
00077 {
00078 std::vector<PSimHit> result;
00079 std::vector<PSimHit> allHits = simHits();
00080 std::vector<PSimHit>::const_iterator hitItr = allHits.begin(), lastHit = allHits.end();
00081
00082 for( ; hitItr != lastHit; ++hitItr)
00083 {
00084 if(abs((*hitItr).particleType()) == 13)
00085 {
00086 result.push_back(*hitItr);
00087 }
00088 }
00089 return result;
00090 }
00091
00092
00093 std::vector<MuonTruth::SimHitIdpr> MuonTruth::associateHitId(const TrackingRecHit & hit)
00094 {
00095 std::vector<SimHitIdpr> simtrackids;
00096 simtrackids.clear();
00097 const TrackingRecHit * hitp = &hit;
00098 const CSCRecHit2D * cscrechit = dynamic_cast<const CSCRecHit2D *>(hitp);
00099
00100 if (cscrechit) {
00101 analyze(*cscrechit);
00102 std::vector<PSimHit> matchedSimHits = simHits();
00103 for(std::vector<PSimHit>::const_iterator hIT=matchedSimHits.begin(); hIT != matchedSimHits.end(); hIT++) {
00104 SimHitIdpr currentId(hIT->trackId(), hIT->eventId());
00105 simtrackids.push_back(currentId);
00106 }
00107 } else {
00108 edm::LogWarning("MuonTruth")<<"WARNING in MuonTruth::associateHitId, null dynamic_cast !";
00109 }
00110 return simtrackids;
00111 }
00112
00113
00114 std::vector<PSimHit> MuonTruth::hitsFromSimTrack(int index)
00115 {
00116 std::vector<PSimHit> result;
00117 edm::PSimHitContainer hits = theSimHitMap.hits(theDetId);
00118 edm::PSimHitContainer::const_iterator hitItr = hits.begin(), lastHit = hits.end();
00119
00120 for( ; hitItr != lastHit; ++hitItr)
00121 {
00122 int hitTrack = hitItr->trackId();
00123 if(hitTrack == index)
00124 {
00125 result.push_back(*hitItr);
00126 }
00127 }
00128 return result;
00129 }
00130
00131
00132 int MuonTruth::particleType(int simTrack)
00133 {
00134 int result = 0;
00135 std::vector<PSimHit> hits = hitsFromSimTrack(simTrack);
00136 if(!hits.empty())
00137 {
00138 result = hits[0].particleType();
00139 }
00140 return result;
00141 }
00142
00143
00144 void MuonTruth::analyze(const CSCRecHit2D & recHit)
00145 {
00146 theChargeMap.clear();
00147 theTotalCharge = 0.;
00148 theDetId = recHit.geographicalId().rawId();
00149
00150 int nchannels = recHit.channels().size();
00151 CSCRecHit2D::ADCContainer adcContainer = recHit.adcs();
00152 const CSCLayerGeometry * laygeom = cscgeom->layer(recHit.cscDetId())->geometry();
00153
00154 for(int idigi = 0; idigi < nchannels; ++idigi)
00155 {
00156
00157 int istrip = recHit.channels()[idigi];
00158 int channel = laygeom->channel(istrip);
00159 float weight = adcContainer[idigi];
00160
00161 DigiSimLinks::const_iterator layerLinks = theDigiSimLinks->find(theDetId);
00162
00163 if(layerLinks != theDigiSimLinks->end())
00164 {
00165 addChannel(*layerLinks, channel, weight);
00166 }
00167 }
00168 }
00169
00170
00171 void MuonTruth::analyze(const CSCStripDigi & stripDigi, int rawDetIdCorrespondingToCSCLayer)
00172 {
00173 theDetId = rawDetIdCorrespondingToCSCLayer;
00174 theChargeMap.clear();
00175 theTotalCharge = 0.;
00176
00177 DigiSimLinks::const_iterator layerLinks = theDigiSimLinks->find(theDetId);
00178 if(layerLinks != theDigiSimLinks->end())
00179 {
00180 addChannel(*layerLinks, stripDigi.getStrip(), 1.);
00181 }
00182 }
00183
00184
00185 void MuonTruth::analyze(const CSCWireDigi & wireDigi, int rawDetIdCorrespondingToCSCLayer)
00186 {
00187 theDetId = rawDetIdCorrespondingToCSCLayer;
00188 theChargeMap.clear();
00189 theTotalCharge = 0.;
00190
00191 WireDigiSimLinks::const_iterator layerLinks = theWireDigiSimLinks->find(theDetId);
00192
00193 if(layerLinks != theDigiSimLinks->end())
00194 {
00195
00196 int wireDigiInSimulation = wireDigi.getWireGroup() + 100;
00197
00198 addChannel(*layerLinks, wireDigiInSimulation, 1.);
00199 }
00200 }
00201
00202
00203 void MuonTruth::addChannel(const LayerLinks &layerLinks, int channel, float weight)
00204 {
00205 LayerLinks::const_iterator linkItr = layerLinks.begin(),
00206 lastLayerLink = layerLinks.end();
00207
00208 for ( ; linkItr != lastLayerLink; ++linkItr)
00209 {
00210 int linkChannel = linkItr->channel();
00211 if(linkChannel == channel)
00212 {
00213 float charge = linkItr->fraction() * weight;
00214 theTotalCharge += charge;
00215
00216 int simTrack = linkItr->SimTrackId();
00217 std::map<int, float>::const_iterator chargeMapItr = theChargeMap.find( simTrack );
00218 if(chargeMapItr == theChargeMap.end())
00219 {
00220 theChargeMap[simTrack] = charge;
00221 }
00222 else
00223 {
00224 theChargeMap[simTrack] += charge;
00225 }
00226 }
00227 }
00228 }
00229
00230