Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 /*!  \brief   Implementation of methods of TTClusterBuilder.h
0002  *  \details Here, in the source file, the methods which do depend
0003  *           on the specific type <T> that can fit the template.
0004  *
0005  * \author Andrew W. Rose
0006  * \author Nicola Pozzobon
0007  * \author Ivan Reid
0008  * \author Ian Tomalin
0009  * \date 2013 - 2020
0010  *
0011  */
0012 
0013 #include "L1Trigger/TrackTrigger/plugins/TTStubBuilder.h"
0014 
0015 /// Update output stubs with Refs to cluster collection that is associated to stubs.
0016 
0017 template <>
0018 void TTStubBuilder<Ref_Phase2TrackerDigi_>::updateStubs(
0019     const edm::OrphanHandle<edmNew::DetSetVector<TTCluster<Ref_Phase2TrackerDigi_>>>& clusterHandle,
0020     const edmNew::DetSetVector<TTStub<Ref_Phase2TrackerDigi_>>& inputEDstubs,
0021     edmNew::DetSetVector<TTStub<Ref_Phase2TrackerDigi_>>& outputEDstubs) const {
0022   /// Loop over tracker modules
0023   for (const auto& module : inputEDstubs) {
0024     /// Get the DetId and prepare the FastFiller
0025     DetId thisStackedDetId = module.id();
0026     typename edmNew::DetSetVector<TTStub<Ref_Phase2TrackerDigi_>>::FastFiller outputFiller(outputEDstubs,
0027                                                                                            thisStackedDetId);
0028 
0029     /// detid of the two components.
0030     ///This should be done via a TrackerTopology method that is not yet available.
0031     DetId lowerDetid = thisStackedDetId + 1;
0032     DetId upperDetid = thisStackedDetId + 2;
0033 
0034     /// Get the DetSets of the clusters
0035     edmNew::DetSet<TTCluster<Ref_Phase2TrackerDigi_>> lowerClusters = (*clusterHandle)[lowerDetid];
0036     edmNew::DetSet<TTCluster<Ref_Phase2TrackerDigi_>> upperClusters = (*clusterHandle)[upperDetid];
0037 
0038     /// Get the DetSet of the stubs
0039     edmNew::DetSet<TTStub<Ref_Phase2TrackerDigi_>> theseStubs = inputEDstubs[thisStackedDetId];
0040 
0041     /// Prepare the new DetSet to replace the current one
0042     /// Loop over the stubs in this module
0043     typename edmNew::DetSet<TTCluster<Ref_Phase2TrackerDigi_>>::const_iterator clusterIter;
0044     for (const auto& stub : theseStubs) {
0045       /// Create a temporary stub
0046       TTStub<Ref_Phase2TrackerDigi_> tempTTStub(stub.getDetId());
0047 
0048       /// Compare the clusters stored in the stub with the ones of this module
0049       const edm::Ref<edmNew::DetSetVector<TTCluster<Ref_Phase2TrackerDigi_>>, TTCluster<Ref_Phase2TrackerDigi_>>&
0050           lowerClusterToBeReplaced = stub.clusterRef(0);
0051       const edm::Ref<edmNew::DetSetVector<TTCluster<Ref_Phase2TrackerDigi_>>, TTCluster<Ref_Phase2TrackerDigi_>>&
0052           upperClusterToBeReplaced = stub.clusterRef(1);
0053 
0054       bool lowerOK = false;
0055       bool upperOK = false;
0056 
0057       for (clusterIter = lowerClusters.begin(); clusterIter != lowerClusters.end() && !lowerOK; ++clusterIter) {
0058         if (clusterIter->getHits() == lowerClusterToBeReplaced->getHits()) {
0059           tempTTStub.addClusterRef(edmNew::makeRefTo(clusterHandle, clusterIter));
0060           lowerOK = true;
0061         }
0062       }
0063 
0064       for (clusterIter = upperClusters.begin(); clusterIter != upperClusters.end() && !upperOK; ++clusterIter) {
0065         if (clusterIter->getHits() == upperClusterToBeReplaced->getHits()) {
0066           tempTTStub.addClusterRef(edmNew::makeRefTo(clusterHandle, clusterIter));
0067           upperOK = true;
0068         }
0069       }
0070 
0071       /// If no compatible clusters were found, skip to the next one
0072       if (!lowerOK || !upperOK)
0073         continue;
0074 
0075       /// getters for RawBend & BendOffset are in FULL-strip units, setters are in HALF-strip units
0076       tempTTStub.setRawBend(2. * stub.rawBend());
0077       tempTTStub.setBendOffset(2. * stub.bendOffset());
0078       tempTTStub.setBendBE(stub.bendBE());
0079       tempTTStub.setModuleTypePS(stub.moduleTypePS());
0080 
0081       outputFiller.push_back(tempTTStub);
0082 
0083     }  /// End of loop over stubs of this module
0084   }  /// End of loop over stub DetSetVector
0085 }
0086 
0087 /// Implement the producer
0088 
0089 template <>
0090 void TTStubBuilder<Ref_Phase2TrackerDigi_>::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0091   //Retrieve tracker topology from geometry
0092   edm::ESHandle<TrackerTopology> tTopoHandle = iSetup.getHandle(tTopoToken);
0093   const TrackerTopology* const tTopo = tTopoHandle.product();
0094   edm::ESHandle<TrackerGeometry> tGeomHandle = iSetup.getHandle(tGeomToken);
0095   const TrackerGeometry* const theTrackerGeom = tGeomHandle.product();
0096 
0097   /// -- Prepare output
0098   /// TTClusters associated to TTStubs
0099   auto ttClusterDSVForOutputAcc = std::make_unique<edmNew::DetSetVector<TTCluster<Ref_Phase2TrackerDigi_>>>();
0100   auto ttClusterDSVForOutputRej = std::make_unique<edmNew::DetSetVector<TTCluster<Ref_Phase2TrackerDigi_>>>();
0101   /// TTStubs with Refs to clusters pointing to collection of clusters in entire tracker.
0102   auto ttStubDSVForOutputAccTemp = std::make_unique<edmNew::DetSetVector<TTStub<Ref_Phase2TrackerDigi_>>>();
0103   auto ttStubDSVForOutputRejTemp = std::make_unique<edmNew::DetSetVector<TTStub<Ref_Phase2TrackerDigi_>>>();
0104   /// TTStubs with Refs to clusters pointing to collection of clusters associated to stubs.
0105   auto ttStubDSVForOutputAcc = std::make_unique<edmNew::DetSetVector<TTStub<Ref_Phase2TrackerDigi_>>>();
0106   auto ttStubDSVForOutputRej = std::make_unique<edmNew::DetSetVector<TTStub<Ref_Phase2TrackerDigi_>>>();
0107 
0108   /// Read the Clusters from the entire tracker.
0109   edm::Handle<edmNew::DetSetVector<TTCluster<Ref_Phase2TrackerDigi_>>> clusterHandle;
0110   iEvent.getByToken(clustersToken, clusterHandle);
0111 
0112   int nmod = -1;
0113 
0114   // Loop over all the tracker elements
0115 
0116   for (const auto& gd : theTrackerGeom->dets()) {
0117     DetId detid = (*gd).geographicalId();
0118     if (detid.subdetId() != StripSubdetector::TOB && detid.subdetId() != StripSubdetector::TID)
0119       continue;  // only run on OT
0120     if (!tTopo->isLower(detid))
0121       continue;  // loop on the stacks: choose the lower sensor
0122     DetId lowerDetid = detid;
0123     DetId upperDetid = tTopo->partnerDetId(detid);
0124     DetId stackDetid = tTopo->stack(detid);
0125     bool isPS = (theTrackerGeom->getDetectorType(stackDetid) == TrackerGeometry::ModuleType::Ph2PSP);
0126 
0127     bool is10G_PS = false;
0128 
0129     // Determine if this module is a 10G transmission scheme module
0130     //
0131     // TO FIX: take this info from Tracker -> DTC cabling map.
0132 
0133     if (detid.subdetId() == StripSubdetector::TOB) {
0134       if (tTopo->layer(detid) <= high_rate_max_layer)
0135         is10G_PS = true;
0136     } else if (detid.subdetId() == StripSubdetector::TID) {
0137       if (tTopo->tidRing(detid) <= high_rate_max_ring[tTopo->tidWheel(detid) - 1])
0138         is10G_PS = true;
0139     }
0140 
0141     ++nmod;
0142 
0143     unsigned int maxStubs;
0144     std::vector<std::pair<unsigned int, double>> bendMap;
0145 
0146     /// Go on only if both detectors have Clusters
0147     if (clusterHandle->find(lowerDetid) == clusterHandle->end() ||
0148         clusterHandle->find(upperDetid) == clusterHandle->end())
0149       continue;
0150 
0151     /// Get the DetSets of the Clusters
0152     edmNew::DetSet<TTCluster<Ref_Phase2TrackerDigi_>> lowerClusters = (*clusterHandle)[lowerDetid];
0153     edmNew::DetSet<TTCluster<Ref_Phase2TrackerDigi_>> upperClusters = (*clusterHandle)[upperDetid];
0154 
0155     /// If there are Clusters in both sensors, you can try and make a Stub
0156     /// This is ~redundant
0157     if (lowerClusters.empty() || upperClusters.empty())
0158       continue;
0159 
0160     /// Create the vectors of objects to be passed to the FastFillers
0161     std::vector<TTCluster<Ref_Phase2TrackerDigi_>> tempClusLowerAcc;
0162     std::vector<TTCluster<Ref_Phase2TrackerDigi_>> tempClusLowerRej;
0163     std::vector<TTCluster<Ref_Phase2TrackerDigi_>> tempClusUpperAcc;
0164     std::vector<TTCluster<Ref_Phase2TrackerDigi_>> tempClusUpperRej;
0165     std::vector<TTStub<Ref_Phase2TrackerDigi_>> tempStubAcc;
0166     std::vector<TTStub<Ref_Phase2TrackerDigi_>> tempStubRej;
0167     tempClusLowerAcc.clear();
0168     tempClusLowerRej.clear();
0169     tempClusUpperAcc.clear();
0170     tempClusUpperRej.clear();
0171     tempStubAcc.clear();
0172     tempStubRej.clear();
0173 
0174     /// Get chip size information
0175     /// FIX ME: Should take this from TrackerTopology, but it was buggy in 2017 (SV)
0176     const int chipSize = isPS ? 120 : 127;
0177     // No. of macro pixels along local y in each half of 2S module.
0178     constexpr int numMacroPixels = 16;
0179 
0180     /// Loop over pairs of Clusters
0181     for (auto lowerClusterIter = lowerClusters.begin(); lowerClusterIter != lowerClusters.end(); ++lowerClusterIter) {
0182       /// Temporary storage to allow only one stub per inner cluster, if requested in cfi
0183       std::vector<TTStub<Ref_Phase2TrackerDigi_>> tempOutput;
0184 
0185       for (auto upperClusterIter = upperClusters.begin(); upperClusterIter != upperClusters.end(); ++upperClusterIter) {
0186         /// Build a temporary Stub
0187         TTStub<Ref_Phase2TrackerDigi_> tempTTStub(stackDetid);
0188         tempTTStub.addClusterRef(edmNew::makeRefTo(clusterHandle, lowerClusterIter));
0189         tempTTStub.addClusterRef(edmNew::makeRefTo(clusterHandle, upperClusterIter));
0190         tempTTStub.setModuleTypePS(isPS);
0191 
0192         /// Check for compatibility of cluster pair
0193         bool thisConfirmation = false;
0194         int thisDisplacement = 999999;
0195         int thisOffset = 0;
0196         float thisHardBend = 0;
0197 
0198         theStubFindingAlgoHandle->PatternHitCorrelation(
0199             thisConfirmation, thisDisplacement, thisOffset, thisHardBend, tempTTStub);
0200         // Removed real offset.  Ivan Reid 10/2019
0201 
0202         /// If the Stub is above threshold
0203         if (thisConfirmation) {
0204           tempTTStub.setRawBend(thisDisplacement);
0205           tempTTStub.setBendOffset(thisOffset);
0206           tempTTStub.setBendBE(thisHardBend);
0207           tempOutput.push_back(tempTTStub);
0208         }  /// Stub accepted
0209       }  /// End of loop over upper clusters
0210 
0211       /// Here tempOutput stores all the stubs from this lower cluster
0212       /// Check if there is need to store only one or two (2S/PS modules cases) (if only one already, skip this step)
0213       if (ForbidMultipleStubs && tempOutput.size() > 1 + static_cast<unsigned int>(isPS)) {
0214         /// If so, sort the stubs by bend and keep only the first one (2S case) or the first pair (PS case) (smallest |bend|)
0215         std::sort(tempOutput.begin(), tempOutput.end(), TTStubBuilder<Ref_Phase2TrackerDigi_>::SortStubsBend);
0216 
0217         /// Get to the second element (the switch above ensures there are min 2)
0218         typename std::vector<TTStub<Ref_Phase2TrackerDigi_>>::iterator tempIter = tempOutput.begin();
0219         ++tempIter;
0220         if (isPS)
0221           ++tempIter;  // PS module case
0222         /// tempIter points now to the second or third element (2S/PS)
0223 
0224         /// Delete all-but-the first one from tempOutput
0225         tempOutput.erase(tempIter, tempOutput.end());
0226       }
0227 
0228       /// Here, tempOutput is either of size 1 (if ForbidMultupleStubs = true),
0229       /// or of size N with all the valid combinations ...
0230 
0231       /// Now loop over the accepted stubs (1 or N) for this lower cluster
0232 
0233       for (auto& tempTTStub : tempOutput) {
0234         /// Put in the output
0235         if (not applyFE)  // No dynamic inefficiencies
0236         {
0237           /// This means that ALL stubs go into the output
0238           tempClusLowerAcc.push_back(*(tempTTStub.clusterRef(0)));
0239           tempClusUpperAcc.push_back(*(tempTTStub.clusterRef(1)));
0240           tempStubAcc.push_back(tempTTStub);
0241         } else {
0242           bool FEreject = false;
0243 
0244           /// This means that only some stubs go to the output
0245           MeasurementPoint mp0 = tempTTStub.clusterRef(0)->findAverageLocalCoordinates();
0246           int seg = static_cast<int>(mp0.y());  // Identifies which half of module
0247           if (isPS)
0248             seg = seg / numMacroPixels;
0249           /// Find out which MPA/CBC ASIC
0250           int chip = 1000 * nmod + 10 * int(tempTTStub.innerClusterPosition() / chipSize) + seg;
0251           /// Find out which CIC ASIC
0252           int CIC_chip = 10 * nmod + seg;
0253 
0254           // First look is the stub is passing trough the very front end (CBC/MPA)
0255           maxStubs = isPS ? maxStubs_PS : maxStubs_2S;
0256 
0257           if (isPS)  // MPA
0258           {
0259             if (moduleStubs_MPA[chip] < int(maxStubs)) {
0260               moduleStubs_MPA[chip]++;
0261             } else {
0262               FEreject = true;
0263             }
0264           } else  // CBC
0265           {
0266             if (moduleStubs_CBC[chip] < int(maxStubs)) {
0267               moduleStubs_CBC[chip]++;
0268             } else {
0269               FEreject = true;
0270             }
0271           }
0272 
0273           // End of the MPA/CBC loop
0274 
0275           // If the stub has been already thrown out, there is no reason to include it into the CIC stream
0276           // We put it in the rejected container, flagged with offset to indicate reason.
0277 
0278           if (FEreject) {
0279             tempTTStub.setRawBend(CBCFailOffset + 2. * tempTTStub.rawBend());
0280             tempTTStub.setBendOffset(CBCFailOffset + 2. * tempTTStub.bendOffset());
0281             tempClusLowerRej.push_back(*(tempTTStub.clusterRef(0)));
0282             tempClusUpperRej.push_back(*(tempTTStub.clusterRef(1)));
0283             tempStubRej.push_back(tempTTStub);
0284             continue;
0285           }
0286 
0287           maxStubs = isPS ? maxStubs_PS_CIC_5 : maxStubs_2S_CIC_5;
0288 
0289           if (is10G_PS)
0290             maxStubs = maxStubs_PS_CIC_10;
0291 
0292           bool CIC_reject = true;
0293 
0294           moduleStubs_CIC[CIC_chip].push_back(tempTTStub);  //We temporarily add the new stub
0295 
0296           if (moduleStubs_CIC[CIC_chip].size() <= maxStubs) {
0297             tempClusLowerAcc.push_back(*(tempTTStub.clusterRef(0)));
0298             tempClusUpperAcc.push_back(*(tempTTStub.clusterRef(1)));
0299             tempStubAcc.push_back(tempTTStub);  // The stub is kept
0300 
0301           } else {
0302             /// TO FIX: The maxStub stubs with lowest |bend| are retained. This algo considers all stubs
0303             /// since the last multiple of 8 events, (i.e. in 1-8 events), whereas true CIC chip considers
0304             /// all stubs in current block of 8 events (i.e. always in 8 events). So may be optimistic.
0305 
0306             /// Sort stubs by |bend|.
0307             bendMap.clear();
0308             bendMap.reserve(moduleStubs_CIC[CIC_chip].size());
0309 
0310             for (unsigned int i = 0; i < moduleStubs_CIC[CIC_chip].size(); ++i) {
0311               bendMap.emplace_back(i, moduleStubs_CIC[CIC_chip].at(i).bendFE());
0312             }
0313 
0314             std::sort(bendMap.begin(), bendMap.end(), TTStubBuilder<Ref_Phase2TrackerDigi_>::SortStubBendPairs);
0315 
0316             // bendMap contains link over all the stubs included in moduleStubs_CIC[CIC_chip]
0317 
0318             for (unsigned int i = 0; i < maxStubs; ++i) {
0319               // The stub we have just added is amongst those with smallest |bend| so keep it.
0320               if (bendMap[i].first == moduleStubs_CIC[CIC_chip].size() - 1) {
0321                 CIC_reject = false;
0322               }
0323             }
0324 
0325             if (CIC_reject)  // The stub added does not pass the cut
0326             {
0327               tempTTStub.setRawBend(CICFailOffset + 2. * tempTTStub.rawBend());
0328               tempTTStub.setBendOffset(CICFailOffset + 2. * tempTTStub.bendOffset());
0329               tempClusLowerRej.push_back(*(tempTTStub.clusterRef(0)));
0330               tempClusUpperRej.push_back(*(tempTTStub.clusterRef(1)));
0331               tempStubRej.push_back(tempTTStub);
0332             } else {
0333               tempClusLowerAcc.push_back(*(tempTTStub.clusterRef(0)));
0334               tempClusUpperAcc.push_back(*(tempTTStub.clusterRef(1)));
0335               tempStubAcc.push_back(tempTTStub);  // The stub is added
0336             }
0337           }
0338         }  /// End of check on max number of stubs per module
0339       }  /// End of nested loop
0340     }  /// End of loop over pairs of Clusters
0341 
0342     /// Fill output collections
0343     if (not tempClusLowerAcc.empty())
0344       this->fill(*ttClusterDSVForOutputAcc, lowerDetid, tempClusLowerAcc);
0345     if (not tempClusLowerRej.empty())
0346       this->fill(*ttClusterDSVForOutputRej, lowerDetid, tempClusLowerRej);
0347     if (not tempClusUpperAcc.empty())
0348       this->fill(*ttClusterDSVForOutputAcc, upperDetid, tempClusUpperAcc);
0349     if (not tempClusUpperRej.empty())
0350       this->fill(*ttClusterDSVForOutputRej, upperDetid, tempClusUpperRej);
0351     if (not tempStubAcc.empty())
0352       this->fill(*ttStubDSVForOutputAccTemp, stackDetid, tempStubAcc);
0353     if (not tempStubRej.empty())
0354       this->fill(*ttStubDSVForOutputRejTemp, stackDetid, tempStubRej);
0355 
0356   }  /// End of loop over detector elements
0357 
0358   // Store the subset of clusters associated to stubs.
0359 
0360   edm::OrphanHandle<edmNew::DetSetVector<TTCluster<Ref_Phase2TrackerDigi_>>> ttClusterAccHandle =
0361       iEvent.put(std::move(ttClusterDSVForOutputAcc), "ClusterAccepted");
0362   edm::OrphanHandle<edmNew::DetSetVector<TTCluster<Ref_Phase2TrackerDigi_>>> ttClusterRejHandle =
0363       iEvent.put(std::move(ttClusterDSVForOutputRej), "ClusterRejected");
0364 
0365   /// The TTStubs created above contain Refs to the ClusterInclusive collection (all clusters in Tracker).
0366   /// Replace them with new TTStubs with Refs to ClusterAccepted collection (only clusters in Stubs),
0367   /// so big ClusterInclusive collection can be dropped.
0368 
0369   this->updateStubs(ttClusterAccHandle, *ttStubDSVForOutputAccTemp, *ttStubDSVForOutputAcc);
0370   this->updateStubs(ttClusterRejHandle, *ttStubDSVForOutputRejTemp, *ttStubDSVForOutputRej);
0371 
0372   /// Put output in the event (2)
0373   iEvent.put(std::move(ttStubDSVForOutputAcc), "StubAccepted");
0374   iEvent.put(std::move(ttStubDSVForOutputRej), "StubRejected");
0375 
0376   ++ievt;
0377   if (ievt % 8 == 0)
0378     moduleStubs_CIC.clear();  // Everything is cleared up after 8BX
0379   if (ievt % 2 == 0)
0380     moduleStubs_MPA.clear();  // Everything is cleared up after 2BX
0381   moduleStubs_CBC.clear();    // Everything is cleared up after everyBX
0382 }