Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-07 04:37:41

0001 /** 
0002  * \file GEMCSCSegmentBuilder.cc
0003  *
0004  */
0005 
0006 #include <RecoLocalMuon/GEMCSCSegment/plugins/GEMCSCSegmentBuilder.h>
0007 #include <RecoLocalMuon/GEMCSCSegment/plugins/GEMCSCSegmentAlgorithm.h>
0008 #include <RecoLocalMuon/GEMCSCSegment/plugins/GEMCSCSegmentBuilderPluginFactory.h>
0009 
0010 #include "FWCore/Framework/interface/ESHandle.h"
0011 #include <FWCore/Utilities/interface/Exception.h>
0012 #include <FWCore/MessageLogger/interface/MessageLogger.h>
0013 
0014 #include <Geometry/Records/interface/MuonGeometryRecord.h>
0015 #include <Geometry/CSCGeometry/interface/CSCChamberSpecs.h>
0016 #include <Geometry/CSCGeometry/interface/CSCLayer.h>
0017 #include <Geometry/CSCGeometry/interface/CSCGeometry.h>
0018 #include <Geometry/GEMGeometry/interface/GEMGeometry.h>
0019 #include <Geometry/GEMGeometry/interface/GEMEtaPartition.h>
0020 
0021 #include <DataFormats/MuonDetId/interface/CSCDetId.h>
0022 #include <DataFormats/MuonDetId/interface/GEMDetId.h>
0023 #include <DataFormats/CSCRecHit/interface/CSCRecHit2D.h>
0024 #include <DataFormats/CSCRecHit/interface/CSCRangeMapAccessor.h>
0025 #include <DataFormats/CSCRecHit/interface/CSCRecHit2DCollection.h>
0026 #include <DataFormats/CSCRecHit/interface/CSCSegmentCollection.h>
0027 #include <DataFormats/CSCRecHit/interface/CSCSegment.h>
0028 #include <DataFormats/GEMRecHit/interface/GEMRecHit.h>
0029 #include <DataFormats/GEMRecHit/interface/GEMRecHitCollection.h>
0030 
0031 GEMCSCSegmentBuilder::GEMCSCSegmentBuilder(const edm::ParameterSet& ps)
0032     :  // Ask factory to build this algorithm, giving it appropriate ParameterSet
0033       algo{GEMCSCSegmentBuilderPluginFactory::get()->create(ps.getParameter<std::string>("algo_name"),
0034                                                             ps.getParameter<edm::ParameterSet>("algo_psets"))},
0035       enable_me21_ge21_(ps.getParameter<bool>("enableME21GE21")),
0036       gemgeom_{nullptr},
0037       cscgeom_{nullptr} {
0038   edm::LogVerbatim("GEMCSCSegmentBuilder")
0039       << "[GEMCSCSegmentBuilder :: ctor] algorithm name: " << ps.getParameter<std::string>("algo_name");
0040 }
0041 
0042 GEMCSCSegmentBuilder::~GEMCSCSegmentBuilder() {
0043   edm::LogVerbatim("GEMCSCSegmentBuilder") << "[GEMCSCSegmentBuilder :: dstor] deleted the algorithm";
0044 }
0045 
0046 void GEMCSCSegmentBuilder::LinkGEMRollsToCSCChamberIndex(const GEMGeometry* gemGeo, const CSCGeometry* cscGeo) {
0047   for (TrackingGeometry::DetContainer::const_iterator it = gemGeo->dets().begin(); it < gemGeo->dets().end(); it++) {
0048     const GEMChamber* ch = dynamic_cast<const GEMChamber*>(*it);
0049     if (ch != nullptr) {
0050       std::vector<const GEMEtaPartition*> rolls = (ch->etaPartitions());
0051       for (std::vector<const GEMEtaPartition*>::const_iterator r = rolls.begin(); r != rolls.end(); ++r) {
0052         GEMDetId gemId = (*r)->id();
0053         int region = gemId.region();
0054         if (region != 0) {
0055           int station = gemId.station();
0056           int ring = gemId.ring();
0057           int gemchamber = gemId.chamber();
0058           int layer = gemId.layer();
0059           int cscring = ring;
0060           int cscstation = station;
0061           int cscchamber = gemchamber;
0062           int csclayer = layer;
0063           CSCStationIndex ind(region, cscstation, cscring, cscchamber, csclayer);
0064           std::set<GEMDetId> myrolls;
0065           if (rollstoreCSC.find(ind) != rollstoreCSC.end())
0066             myrolls = rollstoreCSC[ind];
0067           myrolls.insert(gemId);
0068           rollstoreCSC[ind] = myrolls;
0069         }
0070       }
0071     }
0072   }
0073 
0074   // edm::LogVerbatim to print details of std::map< CSCIndex, std::set<GEMRolls> >
0075   for (std::map<CSCStationIndex, std::set<GEMDetId> >::iterator mapit = rollstoreCSC.begin();
0076        mapit != rollstoreCSC.end();
0077        ++mapit) {
0078     CSCStationIndex map_first = mapit->first;
0079     std::set<GEMDetId> map_secnd = mapit->second;
0080     std::stringstream GEMRollsstream;
0081     for (std::set<GEMDetId>::iterator setit = map_secnd.begin(); setit != map_secnd.end(); ++setit) {
0082       GEMRollsstream << "[ GEM Id: " << setit->rawId() << " (" << *setit << ")"
0083                      << "]," << std::endl;
0084     }
0085     std::string GEMRollsstr = GEMRollsstream.str();
0086     edm::LogVerbatim("GEMCSCSegmentBuilder")
0087         << "[GEMCSCSegmentBuilder :: LinkGEMRollsToCSCChamberIndex] CSC Station Index :: [" << map_first.region() << ","
0088         << map_first.station() << "," << map_first.ring() << "," << map_first.chamber() << "," << map_first.layer()
0089         << "] has following GEM rolls: [" << GEMRollsstr << "]" << std::endl;
0090   }
0091 }
0092 
0093 void GEMCSCSegmentBuilder::build(const GEMRecHitCollection* recHits,
0094                                  const CSCSegmentCollection* cscsegments,
0095                                  GEMCSCSegmentCollection& oc) {
0096   edm::LogVerbatim("GEMCSCSegmentBuilder")
0097       << "[GEMCSCSegmentBuilder :: build] Total number of GEM rechits in this event: " << recHits->size()
0098       << " Total number of CSC segments in this event: " << cscsegments->size();
0099 
0100   // Structure of the build function:
0101   // --------------------------------
0102   // The build function is called once per Event
0103   // It loops over CSC Segment Collection and
0104   //   - identifies the CSC Chambers with segments
0105   //   - searches for rechits in GEM rolls associared
0106   //   - creates CSC segment collection with GEM RecHits associated (1)
0107   //   - creates CSC segment collection without GEM RecHits associated (2)
0108   // then
0109   //   - passes CSC segment collection (1) and GEM rechits to segment builder
0110   //   - makes a copy of CSC segment collection (2) and push it in the GEMCSC Segment collection
0111 
0112   // GEM Roll can contain more than one rechit     --> therefore create map <detId, vector<GEMRecHit> >
0113   // CSC Chamber can contain more than one segment --> therefore create map <detId, vector<CSCSegment> >
0114   std::map<uint32_t, std::vector<GEMRecHit*> > gemRecHitCollection;
0115   std::map<uint32_t, std::vector<const CSCSegment*> > cscSegColl_GEM11;
0116   std::map<uint32_t, std::vector<const CSCSegment*> > cscSegColl_noGEM;
0117 
0118   // === Loop over CSC Segment Collection ===
0119   // ========================================
0120   for (CSCSegmentCollection::const_iterator segmIt = cscsegments->begin(); segmIt != cscsegments->end(); ++segmIt) {
0121     CSCDetId CSCId = segmIt->cscDetId();
0122 
0123     // Search for Matches between GEM Roll and CSC Chamber
0124 
0125     // Case A :: ME1/1 and ME2/1 Segments can have GE1/1 and GE2/1 Rechits associated to them, respectively
0126     // ================================================================
0127     if (CSCId.isME11() or (enable_me21_ge21_ and CSCId.isME21())) {
0128       edm::LogVerbatim("GEMCSCSegmentBuilder")
0129           << "[GEMCSCSegmentBuilder :: build] Found " << (CSCId.isME11() ? "ME1/1" : "ME2/1") << " Segment in "
0130           << CSCId.rawId() << " = " << CSCId;
0131 
0132       // 1) Save the CSC Segment in CSC segment collection
0133       // -------------------------------------------------
0134       // get CSC segment vector associated to this CSCDetId
0135       // if no vector is associated yet to this CSCDetId, create empty vector
0136       // then add the segment to the vector
0137       // and assign the vector again to the CSCDetId
0138       std::vector<const CSCSegment*> cscsegmentvector = cscSegColl_GEM11[CSCId.rawId()];
0139       cscsegmentvector.push_back(segmIt->clone());
0140       cscSegColl_GEM11[CSCId.rawId()] = cscsegmentvector;
0141 
0142       // 2) Make a vector of GEM DetIds associated to this CSC chamber of the segment
0143       // ----------------------------------------------------------------------------
0144       std::vector<GEMDetId> rollsForThisCSCvector;
0145 
0146       int cscRegion = CSCId.endcap();
0147       int cscStation = CSCId.station();
0148       int cscChamber = CSCId.chamber();
0149       int gemRegion = 1;
0150       if (cscRegion == 2)
0151         gemRegion = -1;  // CSC Endcaps are numbered 1,2; GEM Endcaps are numbered +1, -1
0152       int gemRing = 1;   // this we can hardcode, only GEMs in Ring 1
0153       int gemStation = cscStation;
0154 
0155       int gem1stChamber = cscChamber;
0156       // Just adding also neighbouring chambers here is not enough to get the GEM-CSC segment looking at overlapping chambers
0157       // Need to disentangle the use of the CSC chamber and GEM roll in the GEMCSCSegFit class
0158       // For now just ignore the neighbouring chambers and keep code commented out ... at later point we will include it again
0159       // int gem2ndChamber = gem1stChamber+1; if(gem2ndChamber>36) gem2ndChamber-=36; // neighbouring GEM chamber X+1
0160       // int gem3rdChamber = gem1stChamber-1; if(gem2ndChamber<1)  gem2ndChamber+=36; // neighbouring GEM chamber X-1
0161 
0162       std::vector<CSCStationIndex> indexvector;
0163       CSCStationIndex index11(gemRegion, gemStation, gemRing, gem1stChamber, 1);  // GEM Chamber Layer 1
0164       CSCStationIndex index12(gemRegion, gemStation, gemRing, gem1stChamber, 2);  // GEM Chamber Layer 2
0165       indexvector.push_back(index11);
0166       indexvector.push_back(index12);
0167       // for now not inserting neighbouring chambers and keep code commented out ... at later point we will include it again
0168       // CSCStationIndex index21(gemRegion,gemStation,gemRing,gem2ndChamber,1);         CSCStationIndex index22(gemRegion,gemStation,gemRing,gem2ndChamber,2);
0169       // CSCStationIndex index31(gemRegion,gemStation,gemRing,gem3rdChamber,1);         CSCStationIndex index32(gemRegion,gemStation,gemRing,gem3rdChamber,2);
0170       // indexvector.push_back(index21); indexvector.push_back(index22);
0171       // indexvector.push_back(index31); indexvector.push_back(index32);
0172 
0173       for (std::vector<CSCStationIndex>::iterator cscIndexIt = indexvector.begin(); cscIndexIt != indexvector.end();
0174            ++cscIndexIt) {
0175         std::set<GEMDetId> rollsForThisCSC = rollstoreCSC[*cscIndexIt];
0176         for (std::set<GEMDetId>::iterator gemRollIt = rollsForThisCSC.begin(); gemRollIt != rollsForThisCSC.end();
0177              ++gemRollIt) {
0178           rollsForThisCSCvector.push_back(*gemRollIt);
0179         }
0180       }
0181 
0182       // 3) Loop over GEM Rechits
0183       // ------------------------
0184       edm::LogVerbatim("GEMCSCSegmentBuilder")
0185           << "[GEMCSCSegmentBuilder :: build] Start Loop over GEM Rechits :: size = " << recHits->size()
0186           << " and number of Rolls for this CSC :: " << rollsForThisCSCvector.size() << std::endl;
0187       for (GEMRecHitCollection::const_iterator hitIt = recHits->begin(); hitIt != recHits->end(); ++hitIt) {
0188         GEMDetId gemIdfromHit = hitIt->gemId();
0189 
0190         // Loop over GEM rolls being pointed by a CSC segment and look for a match
0191         for (std::vector<GEMDetId>::iterator gemRollIt = rollsForThisCSCvector.begin();
0192              gemRollIt != rollsForThisCSCvector.end();
0193              ++gemRollIt) {
0194           GEMDetId gemIdfromCSC(*gemRollIt);
0195           if (gemIdfromHit == GEMDetId(gemIdfromCSC.rawId())) {
0196             // get GEM RecHit vector associated to this CSC DetId
0197             // if no vector is associated yet to this CSC DetId, create empty vector
0198             // then add the rechits to the vector
0199             // and assign the vector again to the CSC DetId
0200             std::vector<GEMRecHit*> gemrechitvector = gemRecHitCollection[CSCId.rawId()];
0201             // check whether this hit was already filled in the gemrechit vector
0202             bool hitfound = false;
0203             for (std::vector<GEMRecHit*>::const_iterator it = gemrechitvector.begin(); it != gemrechitvector.end();
0204                  ++it) {
0205               if (hitIt->gemId() == (*it)->gemId() && hitIt->localPosition() == (*it)->localPosition())
0206                 hitfound = true;
0207             }
0208             if (!hitfound)
0209               gemrechitvector.push_back(hitIt->clone());
0210             gemRecHitCollection[CSCId.rawId()] = gemrechitvector;
0211             edm::LogVerbatim("GEMCSCSegmentBuilder")
0212                 << "[GEMCSCSegmentBuilder :: build] GEM Rechit in " << hitIt->gemId() << "[" << hitIt->gemId().rawId()
0213                 << "] added to CSC segment found in " << CSCId << " [" << CSCId.rawId() << "]" << std::endl;
0214           }
0215         }  // end Loop over GEM Rolls
0216       }  // end Loop over GEM RecHits
0217     }  // end requirement of CSC segment in ME1/1 or ME2/1
0218 
0219     // Case B :: all other CSC Chambers have no GEM Chamber associated
0220     // ===============================================================
0221     else {
0222       edm::LogVerbatim("GEMCSCSegmentBuilder")
0223           << "[GEMCSCSegmentBuilder :: build] Found a Segment in " << CSCId.rawId() << " = " << CSCId;
0224 
0225       // get CSC segment vector associated to this CSCDetId
0226       // if no vector is associated yet to this CSCDetId, create empty vector
0227       // then add the segment to the vector
0228       // and assign the vector again to the CSCDetId
0229       std::vector<const CSCSegment*> cscsegmentvector_noGEM = cscSegColl_noGEM[CSCId.rawId()];
0230       cscsegmentvector_noGEM.push_back(segmIt->clone());
0231       cscSegColl_noGEM[CSCId.rawId()] = cscsegmentvector_noGEM;
0232     }
0233   }  // end Loop over csc segments
0234 
0235   // === Now pass CSC Segments and GEM RecHits to the Segment Algorithm ===
0236   // ======================================================================
0237 
0238   // Here we do the first modification to the code of Raffaella
0239   //
0240   // Raffaella's code loops over the CSC Segments and assign GEM Rechits to them
0241   // Then it loops over the GemRechits and does the segmentbuilding using the
0242   // GEM Rechits and the assigned CSC segment. Now this relationship is not a one-to-one relationship (bijection)
0243   // In case there are more than 1 segment in the CSC, we have no control that the right supersegment is built
0244   //
0245   // Now we have a particular case where two muons passed through ME1/1,
0246   // resulting in 4 segments (2 real ones and 2 ghosts)
0247   // In this case the gemrechits are assigned to all 4 CSC segments
0248   // but the supersegment is only constructed once, instead of 4 trials,
0249   // resulting in 2 supersegments
0250   //
0251   // This is something I will change in the GEMCSCSegAlgoRR
0252   // In GEMCSCSegmentBuilder we just give all CSC segments and all GEM Rechits
0253   // belonging to one CSC chamber to the GEMCSC Segment Algo
0254 
0255   // case A :: Look for GEM Rechits associated to CSC Segments
0256   // =========================================================
0257   edm::LogVerbatim("GEMCSCSegmentBuilder")
0258       << "[GEMCSCSegmentBuilder :: build] Run over the gemRecHitCollection (size = " << gemRecHitCollection.size()
0259       << ") and build GEMCSC Segments";
0260   for (auto gemHitIt = gemRecHitCollection.begin(); gemHitIt != gemRecHitCollection.end(); ++gemHitIt) {
0261     CSCDetId cscId(gemHitIt->first);
0262 
0263     // hits
0264     std::vector<const CSCSegment*> cscSegments = cscSegColl_GEM11[cscId.rawId()];
0265     std::vector<const GEMRecHit*> gemRecHits;
0266     // dets
0267     std::map<uint32_t, const CSCLayer*> cscLayers;
0268     std::map<uint32_t, const GEMEtaPartition*> gemEtaPartitions;
0269 
0270     // fill dets for CSC
0271     std::vector<const CSCLayer*> cscLayerVector = cscgeom_->chamber(cscId.rawId())->layers();
0272     for (std::vector<const CSCLayer*>::const_iterator layIt = cscLayerVector.begin(); layIt != cscLayerVector.end();
0273          ++layIt) {
0274       cscLayers[(*layIt)->id()] = cscgeom_->layer((*layIt)->id());
0275     }
0276 
0277     // fill dets & hits for GEM
0278     for (auto rechit = gemHitIt->second.begin(); rechit != gemHitIt->second.end(); ++rechit) {
0279       GEMDetId gemid = (*rechit)->gemId();
0280       gemRecHits.push_back(*rechit);
0281       gemEtaPartitions[gemid.rawId()] = gemgeom_->etaPartition(gemid.rawId());
0282     }
0283 
0284     // LogDebug
0285     edm::LogVerbatim("GEMCSCSegmentBuilder")
0286         << "[GEMCSCSegmentBuilder :: build] ask SegmentAlgo to be run :: CSC DetId " << cscId.rawId() << " = " << cscId
0287         << " with " << cscSegments.size() << " CSC segments and " << gemRecHits.size() << " GEM rechits";
0288 
0289     // Ask the Segment Algorithm to build a GEMCSC Segment
0290     std::vector<GEMCSCSegment> segmentvector = algo->run(cscLayers, gemEtaPartitions, cscSegments, gemRecHits);
0291 
0292     // --- LogDebug --------------------------------------------------------
0293     edm::LogVerbatim("GEMCSCSegmentBuilder") << "[GEMCSCSegmentBuilder :: build] SegmentAlgo ran, now trying to add "
0294                                                 "the segments from the returned GEMCSCSegment vector (with size = "
0295                                              << segmentvector.size() << ") to the master collection";
0296     std::stringstream segmentvectorss;
0297     segmentvectorss << "[GEMCSCSegmentBuilder :: build] :: GEMCSC segmentvector :: elements [" << std::endl;
0298     for (std::vector<GEMCSCSegment>::const_iterator segIt = segmentvector.begin(); segIt != segmentvector.end();
0299          ++segIt) {
0300       segmentvectorss << "[GEMCSC Segment details: \n" << *segIt << "]," << std::endl;
0301     }
0302     segmentvectorss << "]";
0303     std::string segmentvectorstr = segmentvectorss.str();
0304     edm::LogVerbatim("GEMCSCSegmentBuilder") << segmentvectorstr;
0305     // --- End LogDebug ----------------------------------------------------
0306 
0307     // Add the segments to master collection
0308     edm::LogVerbatim("GEMCSCSegmentBuilder")
0309         << "[GEMCSCSegmentBuilder :: build] |--> GEMCSC Segments created, now try to add to the collection :: CSC "
0310            "DetId: "
0311         << cscId.rawId() << " = " << cscId << " added " << segmentvector.size() << " GEMCSC Segments";
0312     oc.put(cscId, segmentvector.begin(), segmentvector.end());
0313     edm::LogVerbatim("GEMCSCSegmentBuilder")
0314         << "[GEMCSCSegmentBuilder :: build] |--> GEMCSC Segments added to the collection";
0315   }
0316 
0317   // Case B :: push CSC segments without GEM rechits
0318   // associated to them into the GEMCSC Segment Collection
0319   // =====================================================
0320   // Also for the case where no GEM chamber is associated to the CSC chambers
0321   // fill also GEMCSC segment, but this is basically a copy of the CSC segment
0322   // this will allow us to use only the GEMCSC segment collection in STA Mu Reco
0323   edm::LogVerbatim("GEMCSCSegmentBuilder")
0324       << "[GEMCSCSegmentBuilder :: build] Run over the CSC Segment collection without GEM (size = "
0325       << cscSegColl_noGEM.size() << " CSC chambers with segments) and wrap GEMCSC Segments";
0326   for (auto cscSegIt = cscSegColl_noGEM.begin(); cscSegIt != cscSegColl_noGEM.end(); ++cscSegIt) {
0327     CSCDetId cscId(cscSegIt->first);
0328 
0329     std::vector<const GEMRecHit*> gemRecHits_noGEM;  // make empty gem rechits vector
0330     std::vector<const CSCSegment*> cscSegments_noGEM = cscSegColl_noGEM[cscSegIt->first];
0331     std::vector<GEMCSCSegment> segmentvector;
0332 
0333     edm::LogVerbatim("GEMCSCSegmentBuilder")
0334         << "[GEMCSCSegmentBuilder :: build] |--> Run over the CSC Segment vector without GEM (size = "
0335         << cscSegments_noGEM.size() << " CSC segments) and wrap GEMCSC Segments";
0336     for (std::vector<const CSCSegment*>::iterator it = cscSegments_noGEM.begin(); it != cscSegments_noGEM.end(); ++it) {
0337       // wrap the CSC segment in the GEMCSC segment class
0338       GEMCSCSegment tmp(*it,
0339                         gemRecHits_noGEM,
0340                         (*it)->localPosition(),
0341                         (*it)->localDirection(),
0342                         (*it)->parametersError(),
0343                         (*it)->chi2());
0344       segmentvector.push_back(tmp);
0345     }
0346 
0347     // add the segments to the master collection
0348     edm::LogVerbatim("GEMCSCSegmentBuilder")
0349         << "[GEMCSCSegmentBuilder :: build] |--> CSC Segments wrapped, now try to add to the collection :: CSC DetId: "
0350         << cscId.rawId() << " = " << cscId << " added " << segmentvector.size() << " GEMCSC Segments";
0351     oc.put(cscId, segmentvector.begin(), segmentvector.end());
0352     edm::LogVerbatim("GEMCSCSegmentBuilder")
0353         << "[GEMCSCSegmentBuilder :: build] |--> CSC Segments added to the collection";
0354   }
0355 
0356   edm::LogVerbatim("GEMCSCSegmentBuilder") << "[GEMCSCSegmentBuilder :: build] job done !!!";
0357 }
0358 
0359 void GEMCSCSegmentBuilder::setGeometry(const GEMGeometry* gemgeom, const CSCGeometry* cscgeom) {
0360   gemgeom_ = gemgeom;
0361   cscgeom_ = cscgeom;
0362 }