Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-04-15 22:41:37

0001 #include "L1Trigger/DTTriggerPhase2/interface/MPThetaMatching.h"
0002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0003 #include "L1Trigger/DTTriggerPhase2/interface/constants.h"
0004 
0005 using namespace cmsdt;
0006 
0007 namespace {
0008   struct {
0009     bool operator()(const metaPrimitive &mp1, const metaPrimitive &mp2) const {
0010       DTChamberId chId1(mp1.rawId);
0011 
0012       int sector1 = chId1.sector();
0013       int wheel1 = chId1.wheel();
0014       int station1 = chId1.station();
0015 
0016       DTChamberId chId2(mp2.rawId);
0017       DTSuperLayerId slId2(mp2.rawId);
0018 
0019       int sector2 = chId2.sector();
0020       int wheel2 = chId2.wheel();
0021       int station2 = chId2.station();
0022 
0023       // First, compare by chamber
0024       if (sector1 != sector2)
0025         return sector1 < sector2;
0026       if (wheel1 != wheel2)
0027         return wheel1 < wheel2;
0028       if (station1 != station2)
0029         return station1 < station2;
0030 
0031       // If they are in the same category, sort by the value (4th index)
0032       return mp1.quality > mp2.quality;
0033     }
0034   } const compareMPs;
0035 }  //namespace
0036 
0037 // ============================================================================
0038 // Constructors and destructor
0039 // ============================================================================
0040 MPThetaMatching::MPThetaMatching(const edm::ParameterSet &pset)
0041     : MPFilter(pset),
0042       debug_(pset.getUntrackedParameter<bool>("debug")),
0043       th_option_(pset.getParameter<int>("th_option")),
0044       th_quality_(pset.getParameter<int>("th_quality")),
0045       scenario_(pset.getParameter<int>("scenario")) {}
0046 
0047 MPThetaMatching::~MPThetaMatching() { finish(); }
0048 
0049 // ============================================================================
0050 // Main methods (initialise, run, finish)
0051 // ============================================================================
0052 void MPThetaMatching::initialise(const edm::EventSetup &iEventSetup) {}
0053 
0054 void MPThetaMatching::run(edm::Event &iEvent,
0055                           const edm::EventSetup &iEventSetup,
0056                           std::vector<metaPrimitive> &inMPaths,
0057                           std::vector<metaPrimitive> &outMPaths) {
0058   if (debug_)
0059     LogDebug("MPThetaMatching") << "MPThetaMatching: run";
0060 
0061   //static const double shift_back;  // Needed for t0 (TDC) calculation, taken from main algo
0062   double temp_shift = 0;
0063   if (scenario_ == MC)
0064     temp_shift = 400;  // value used in standard CMSSW simulation
0065   else if (scenario_ == DATA)
0066     temp_shift = 0;
0067   else if (scenario_ == SLICE_TEST)
0068     temp_shift = 400;  // slice test mimics simulation
0069 
0070   static const double shift_back = temp_shift;  // Needed for t0 (TDC) calculation, taken from main algo
0071 
0072   if (th_option_ > 0) {
0073     auto filteredMPs = filter(inMPaths, shift_back);
0074     for (auto &mp : filteredMPs)
0075       outMPaths.push_back(mp);
0076   } else {
0077     if (th_option_ < 0)
0078       LogDebug("MPThetaMatching")
0079           << "MPThetaMatching: th_option can NOT be negative!!! Check settings. Saving all MPs for the moment"
0080           << std::endl;
0081     outMPaths = inMPaths;  //no filter at all
0082   }
0083 }
0084 
0085 void MPThetaMatching::finish() {};
0086 
0087 ///////////////////////////
0088 ///  OTHER METHODS
0089 
0090 std::vector<metaPrimitive> MPThetaMatching::filter(std::vector<metaPrimitive> inMPs, double shift_back) {
0091   std::vector<metaPrimitive> outMPs;
0092   std::vector<metaPrimitive> thetaMPs;
0093   std::vector<metaPrimitive> phiMPs;
0094 
0095   //survey theta and phi MPs
0096   for (auto &mp : inMPs) {
0097     DTChamberId chId(mp.rawId);
0098     DTSuperLayerId slId(mp.rawId);
0099 
0100     if (slId.superLayer() == 2)
0101       thetaMPs.push_back(mp);
0102     else if (chId.station() == 4)  //No theta matching for MB4, save MP
0103       outMPs.push_back(mp);
0104     else if (mp.quality > th_quality_)  //don't do theta matching for q > X, save
0105     {
0106       outMPs.push_back(mp);
0107       phiMPs.push_back(mp);  //keep them in the loop to filter in Theta for cases where there are no other phiMPs
0108     } else
0109       phiMPs.push_back(mp);
0110   }
0111 
0112   //Order Theta MPs by quality
0113   std::sort(thetaMPs.begin(), thetaMPs.end(), compareMPs);
0114 
0115   //Use only best quality theta MP in chamber
0116   thetaMPs = getBestThetaMPInChamber(thetaMPs);
0117 
0118   // Loop on phi, save those at chamber without Theta MPs
0119   for (auto &mp : phiMPs) {
0120     DTChamberId chId(mp.rawId);
0121     DTSuperLayerId slId(mp.rawId);
0122 
0123     int sector = chId.sector();
0124     int wheel = chId.wheel();
0125     int station = chId.station();
0126 
0127     if (!isThereThetaMPInChamber(sector, wheel, station, thetaMPs)) {
0128       if (mp.quality <= th_quality_)  //Has it been saved already?
0129         outMPs.push_back(mp);         // No theta MPs in chamber to match, save MP
0130     }
0131   }
0132 
0133   // Loop on theta (already ordered)
0134   int oldSector = 0;
0135   int oldStation = 0;
0136   int oldWheel = -999;
0137   // container to decide which theta-phi pair to save
0138   std::vector<std::tuple<metaPrimitive, metaPrimitive, float>>
0139       deltaTimePosPhiCands;  //thetaMP, phiMP, difference in TimePosition
0140   std::vector<metaPrimitive> savedThetaMPs;
0141 
0142   for (metaPrimitive &mpTheta : thetaMPs) {
0143     DTChamberId chId(mpTheta.rawId);
0144     DTSuperLayerId slId(mpTheta.rawId);
0145 
0146     int sector = chId.sector();
0147     int wheel = chId.wheel();
0148     int station = chId.station();
0149 
0150     if (station == 4) {  //not possible
0151       LogDebug("MPThetaMatching") << "MPThetaMatching: station 4 does NOT have Theta SL 2";
0152       continue;
0153     }
0154 
0155     if (sector != oldSector || wheel != oldWheel || station != oldStation) {  //new chamber
0156       if (!deltaTimePosPhiCands.empty())
0157         orderAndSave(deltaTimePosPhiCands, &outMPs, &savedThetaMPs);
0158 
0159       deltaTimePosPhiCands.clear();
0160       oldSector = sector;
0161       oldWheel = wheel;
0162       oldStation = station;
0163     }
0164 
0165     float t0 = ((int)round(mpTheta.t0 / (float)LHC_CLK_FREQ)) - shift_back;
0166     float posRefZ = zFE[wheel + 2];
0167 
0168     if (wheel == 0 && (sector == 1 || sector == 4 || sector == 5 || sector == 8 || sector == 9 || sector == 12))
0169       posRefZ = -posRefZ;
0170     float posZ = abs(mpTheta.phi);
0171 
0172     // Loop in Phis
0173     for (metaPrimitive &mpPhi : phiMPs) {
0174       DTChamberId chId2(mpPhi.rawId);
0175       DTSuperLayerId slId2(mpPhi.rawId);
0176 
0177       int sector2 = chId2.sector();
0178       int wheel2 = chId2.wheel();
0179       int station2 = chId2.station();
0180 
0181       if (station2 != station || sector2 != sector || wheel2 != wheel)
0182         continue;
0183 
0184       float t02 = ((int)round(mpPhi.t0 / (float)LHC_CLK_FREQ)) - shift_back;
0185 
0186       float tphi = t02 - abs(posZ / ZRES_CONV - posRefZ) / vwire;
0187 
0188       int LR = -1;
0189       if (wheel == 0 && (sector == 3 || sector == 4 || sector == 7 || sector == 8 || sector == 11 || sector == 12))
0190         LR = +1;
0191       else if (wheel > 0)
0192         LR = pow(-1, wheel + sector + 1);
0193       else if (wheel < 0)
0194         LR = pow(-1, -wheel + sector);
0195 
0196       float posRefX = LR * xFE[station - 1];
0197       float ttheta = t0 - (mpPhi.x / 1000 - posRefX) / vwire;
0198 
0199       deltaTimePosPhiCands.push_back({mpTheta, mpPhi, abs(tphi - ttheta)});
0200     }  //loop in phis
0201 
0202     if (deltaTimePosPhiCands.empty()) {
0203       outMPs.push_back(mpTheta);  //save ThetaMP when there is no phi TPs
0204       savedThetaMPs.push_back(mpTheta);
0205     }
0206   }  // loop in thetas
0207 
0208   if (!deltaTimePosPhiCands.empty())
0209     orderAndSave(deltaTimePosPhiCands, &outMPs, &savedThetaMPs);  //do once more for last theta TP in loop
0210 
0211   return outMPs;
0212 };
0213 
0214 bool MPThetaMatching::isThereThetaMPInChamber(int sector2,
0215                                               int wheel2,
0216                                               int station2,
0217                                               std::vector<metaPrimitive> thetaMPs) {
0218   for (auto &mp1 : thetaMPs) {
0219     DTChamberId chId(mp1.rawId);
0220     DTSuperLayerId slId(mp1.rawId);
0221 
0222     int sector = chId.sector();
0223     int wheel = chId.wheel();
0224     int station = chId.station();
0225     if (sector == sector2 && wheel == wheel2 && station == station2)
0226       return true;
0227   }
0228   return false;
0229 };
0230 
0231 std::vector<metaPrimitive> MPThetaMatching::getBestThetaMPInChamber(std::vector<metaPrimitive> thetaMPs) {
0232   std::vector<metaPrimitive> bestThetaMPs;
0233   for (const auto &mp1 : thetaMPs) {
0234     DTChamberId chId1(mp1.rawId);
0235 
0236     //if there are more than 1 theta TPs in chamber, use and save only the one with highest quality
0237     int sector1 = chId1.sector();
0238     int wheel1 = chId1.wheel();
0239     if (wheel1 == 0) {  //Exception for Wheel 0 ONLY, to take into account background in other chambers
0240       int station1 = chId1.station();
0241       // Theta TPs (SL2) can be only q=1 (3hits) or q=3 (4 hits)
0242       if (mp1.quality > 1) {
0243         bestThetaMPs.push_back(mp1);
0244         continue;
0245       }
0246 
0247       int nTPs = 0;
0248       bool saved = false;
0249       // if q=1
0250       for (const auto &mp2 : thetaMPs) {
0251         DTChamberId chId2(mp2.rawId);
0252         DTSuperLayerId slId2(mp2.rawId);
0253 
0254         int sector2 = chId2.sector();
0255         int wheel2 = chId2.wheel();
0256         int station2 = chId2.station();
0257 
0258         if (sector1 == sector2 && wheel1 == wheel2 && station1 == station2) {
0259           if (mp2.quality > mp1.quality && wheel1 == 0) {
0260             saved = true;
0261             break;  //there is a q=3 and it was already saved
0262           } else if (mp2.quality == mp1.quality && mp2.t0 != mp1.t0) {
0263             saved = true;
0264             bestThetaMPs.push_back(mp1);
0265             break;  //if there are more than 1 with same q=1, save both
0266           } else if (abs(wheel1) == 2 && station1 < 3) {
0267             saved = true;
0268             bestThetaMPs.push_back(mp1);
0269             break;
0270           }
0271 
0272           nTPs++;
0273         }
0274       }
0275       if (nTPs == 1 && !saved)
0276         bestThetaMPs.push_back(mp1);  //only one Theta TP in chamber and it is q=1
0277     }  //wheel ==0
0278 
0279     else
0280       bestThetaMPs.push_back(mp1);
0281   }  // loop in thetaMPs
0282 
0283   return bestThetaMPs;
0284 };
0285 
0286 void MPThetaMatching::orderAndSave(std::vector<std::tuple<metaPrimitive, metaPrimitive, float>> deltaTimePosPhiCands,
0287                                    std::vector<metaPrimitive> *outMPs,
0288                                    std::vector<metaPrimitive> *savedThetaMPs) {
0289   //reorder deltaTimePosPhiCands according to tphi-ttheta distance
0290   std::sort(deltaTimePosPhiCands.begin(), deltaTimePosPhiCands.end(), comparePairs);
0291   int count = 0;
0292 
0293   for (std::tuple<metaPrimitive, metaPrimitive, float> &p :
0294        deltaTimePosPhiCands) {  //save up to nth nearest Theta-Phi pair candidate
0295     if (std::get<1>(p).quality > th_quality_)
0296       continue;
0297     DTChamberId chId(std::get<1>(p).rawId);
0298 
0299     if ((abs(chId.wheel()) == 2 && chId.station() < 3 && count < th_option_ + 1) ||  //save an extra pair for WH+-2MB1/2
0300         count < th_option_) {
0301       std::get<0>(p).t0 = std::get<1>(p).t0;     //replace t0 by associated phi t0
0302       outMPs->push_back(std::get<1>(p));         //add PhiMP
0303       outMPs->push_back(std::get<0>(p));         //add ThetaMP
0304       savedThetaMPs->push_back(std::get<0>(p));  //for accounting
0305       count++;
0306     } else
0307       break;  //avoid Theta duplicates when saving more than one pair
0308   }
0309 
0310   for (std::tuple<metaPrimitive, metaPrimitive, float> &p :
0311        deltaTimePosPhiCands) {  // save theta TP when paired Phi was above th_quality_
0312     DTChamberId chId(std::get<1>(p).rawId);
0313     if (count < th_option_ || (abs(chId.wheel()) == 2 && chId.station() < 3 && count < (th_option_ + 1))) {
0314       if (std::get<1>(p).quality > th_quality_) {
0315         //if (abs(chId.wheel())!=0)
0316         std::get<0>(p).t0 = std::get<1>(p).t0;  //replace t0 by associated phi t0
0317         outMPs->push_back(std::get<0>(p));      //add ThetaMP
0318         savedThetaMPs->push_back(std::get<0>(p));
0319         count++;
0320       }
0321     } else
0322       break;
0323   }
0324 }