Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:20:29

0001 #include "L1Trigger/L1TGEM/interface/GE0TriggerPseudoBuilder.h"
0002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0003 #include "Geometry/Records/interface/MuonGeometryRecord.h"
0004 #include "Geometry/GEMGeometry/interface/GEMGeometry.h"
0005 
0006 #include <iostream>
0007 #include <cassert>
0008 
0009 const unsigned int GE0TriggerPseudoBuilder::ME0KeyLayer = 3;
0010 const int GE0TriggerPseudoBuilder::ME0TriggerCentralBX = 8;
0011 
0012 GE0TriggerPseudoBuilder::GE0TriggerPseudoBuilder(const edm::ParameterSet& conf) {
0013   config_ = conf;
0014   info_ = config_.getUntrackedParameter<int>("info", 0);
0015   dphiresolution_ = config_.getUntrackedParameter<double>("DeltaPhiResolution", 0.25);
0016 }
0017 
0018 GE0TriggerPseudoBuilder::~GE0TriggerPseudoBuilder() {}
0019 
0020 void GE0TriggerPseudoBuilder::build(const GEMSegmentCollection& me0Segments, GE0TriggerDigiCollection& oc_trig) {
0021   if (info_ > 2)
0022     dumpAllME0Segments(me0Segments);
0023 
0024   for (unsigned int endc = 0; endc < static_cast<unsigned int>(trig_me0s::MAX_ENDCAPS); endc++) {
0025     for (unsigned int cham = 0; cham < static_cast<unsigned int>(trig_me0s::MAX_CHAMBERS); cham++) {
0026       // 0th layer means whole chamber.
0027       // chamber counts from 1 to 18 in ME0ID
0028       const int region(endc == 0 ? -1 : 1);
0029       //  constexpr GEMDetId(int region, int ring, int station, int layer, int chamber, int ieta)
0030       GEMDetId detid(region, 1, 0, 0, cham + 1, 0);
0031 
0032       const auto& drange = me0Segments.get(detid);
0033       std::vector<ME0TriggerDigi> trigV;
0034       for (auto digiIt = drange.first; digiIt != drange.second; digiIt++) {
0035         if (info_ > 1)
0036           LogTrace("L1ME0Trigger") << "GE0TriggerPseudoBuilder id " << detid << " ME0 segment " << *digiIt
0037                                    << " to be converted into trigger digi\n";
0038         ME0TriggerDigi trig = segmentConversion(*digiIt);
0039         if (trig.isValid())
0040           trigV.push_back(trig);
0041         if (info_ > 1 and trig.isValid())
0042           LogTrace("L1ME0Trigger") << " ME0trigger " << trig << "\n";
0043         else if (info_ > 1)
0044           LogTrace("L1ME0Trigger") << " ME0trigger is not valid. Conversion failed \n";
0045       }
0046 
0047       if (!trigV.empty()) {
0048         LogTrace("L1ME0Trigger") << "GE0TriggerPseudoBuilder got results in " << detid << std::endl
0049                                  << "Put " << trigV.size() << " Trigger digi" << ((trigV.size() > 1) ? "s " : " ")
0050                                  << "in collection\n";
0051         oc_trig.put(std::make_pair(trigV.begin(), trigV.end()), detid);
0052       }
0053     }
0054   }
0055 }
0056 
0057 ME0TriggerDigi GE0TriggerPseudoBuilder::segmentConversion(const GEMSegment segment) {
0058   auto detid = segment.gemDetId();
0059   const GEMSuperChamber* chamber = me0_g->superChamber(detid);
0060   const GEMChamber* keylayer = chamber->chamber(GE0TriggerPseudoBuilder::ME0KeyLayer);
0061   int chamberid = detid.superChamberId() % 2;
0062   int totRolls = keylayer->nEtaPartitions();
0063   float dphi = chamber->computeDeltaPhi(segment.localPosition(), segment.localDirection());
0064 
0065   int nrechits = segment.nRecHits();
0066   std::vector<int> rolls;
0067   for (const auto& rechit : segment.specificRecHits()) {
0068     if (std::find(rolls.begin(), rolls.end(), rechit.gemId().roll()) == rolls.end())
0069       rolls.push_back(rechit.gemId().roll());
0070   }
0071   if (rolls.size() > 2 or rolls.empty())
0072     LogTrace("L1ME0Trigger") << " ME0 segment is crossing " << rolls.size() << " roll !!! \n";
0073   //assert(rolls.size() <= 2);   // we did found very few ME0 segments crossing 3 rolls!!! this cut is applied offline
0074   if (rolls.empty())
0075     return ME0TriggerDigi();
0076   if (rolls[0] < 1) {
0077     LogTrace("L1ME0Trigger") << " ME0 segment has wrong roll number " << rolls[0] << " which should be >= 1 \n !!!";
0078     throw edm::Exception(edm::errors::LogicError, "ME0 should have at least one roll");
0079   }
0080   int partition = (rolls[0] - 1) << 1;  //roll from detid counts from 1
0081   if (rolls.size() == 2 and rolls[0] > rolls[1])
0082     partition = partition - 1;
0083   else if (rolls.size() == 2 and rolls[0] < rolls[1])
0084     partition = partition + 1;
0085 
0086   if (partition < 0 or partition >= 2 * totRolls) {
0087     LogTrace("L1ME0Trigger") << " ME0 segment rolls size of all hits " << rolls.size() << " rolls[0] " << rolls[0]
0088                              << " rolls.back() " << rolls.back() << " and ME0 trigger roll is " << partition
0089                              << " max expected " << 2 * totRolls - 1 << "\n";
0090     return ME0TriggerDigi();
0091   }
0092 
0093   //globalpoint from ME0 segment
0094   GlobalPoint gp = me0_g->idToDet(segment.gemDetId())->surface().toGlobal(segment.localPosition());
0095   const GEMEtaPartition* etapart = keylayer->etaPartition(rolls[0]);
0096   LocalPoint segment_lp = etapart->surface().toLocal(gp);  // convert segment gp into lp in etapartition coordinate
0097   float strippitch = etapart->localPitch(segment_lp);
0098   float strip = etapart->strip(segment_lp);
0099   int totstrip = etapart->nstrips();
0100   int istrip = static_cast<int>(strip);
0101   int phiposition = istrip;
0102   if (phiposition > totstrip)
0103     LogTrace("L1ME0Trigger") << " ME0 segment strip number is " << phiposition << " larger than nstrip " << totstrip
0104                              << " !!! \n";
0105   constexpr float phi_resolution = 0.5;                                               //halfstrip
0106   int phiposition2 = (static_cast<int>((strip - phiposition) / phi_resolution) & 1);  // half-strip resolution
0107   phiposition = (phiposition << 1) | phiposition2;
0108 
0109   //gloablpoint from ME0 trigger digi
0110   float centreOfStrip = istrip + 0.25 + phiposition2 * 0.5;
0111   GlobalPoint gp_digi = etapart->toGlobal(etapart->centreOfStrip(centreOfStrip));
0112 
0113   float strippitch_rad = strippitch / gp.perp();  //unit in rad
0114 
0115   int idphi = static_cast<int>(fabs(dphi) / (strippitch_rad * dphiresolution_));
0116   const int max_idphi = 512;
0117   if (idphi >= max_idphi) {
0118     LogTrace("L1ME0Trigger") << " ME0 segment dphi " << dphi << " and int type: " << idphi
0119                              << " larger than max allowed: " << max_idphi << " !!! \n";
0120     idphi = max_idphi - 1;
0121   }
0122   int quality = nrechits;  // attention: not the same as discussed in meeting
0123   // !!!!TODO!!!! int BX = (static_cast<int>(fabs(time) / 25.0)) * sign_time + GE0TriggerPseudoBuilder::ME0TriggerCentralBX;
0124   int BX = GE0TriggerPseudoBuilder::ME0TriggerCentralBX;
0125   int bend = (dphi > 0.0) ? 0 : 1;
0126   if (info_ > 2)
0127     LogTrace("L1ME0Trigger") << " ME0trigger in conversion function:\n"
0128                              << "\t chamber(1-18) " << detid.chamber() << " chamber id " << chamberid << " \n"
0129                              << "\t rolls size of all hits " << rolls.size() << " rolls[0] " << rolls[0]
0130                              << " rolls.back() " << rolls.back() << " roll " << partition << " \n"
0131                              << "\t nRechits " << nrechits << " quality " << quality << " \n"
0132                              << "\t strip(float) " << strip << " (int) " << istrip << " phiposition " << phiposition
0133                              << " resolution (in term of strip) " << phi_resolution << " \n"
0134                              << "\t deltaphi(float) " << dphi << " (int) " << idphi << " resolution "
0135                              << strippitch_rad * dphiresolution_ << " bend " << bend << " \n"
0136                              << "\t global point eta " << gp.eta() << " phi " << gp.phi() << " trigger digi eta "
0137                              << gp_digi.eta() << " phi " << gp_digi.phi() << " \n"
0138         // << "\t time (ns, float) " << time << " BX " << BX << " \n"
0139         ;
0140 
0141   ME0TriggerDigi result = ME0TriggerDigi(chamberid, quality, phiposition, partition, idphi, bend, BX);
0142   result.setStrip(istrip);
0143   return result;
0144 
0145   return ME0TriggerDigi();
0146 }
0147 
0148 void GE0TriggerPseudoBuilder::dumpAllME0Segments(const GEMSegmentCollection& segments) const {
0149   LogTrace("L1GE0Trigger") << "dumpt all ME0 Segments" << std::endl;
0150   for (auto iC = segments.id_begin(); iC != segments.id_end(); ++iC) {
0151     auto ch_segs = segments.get(*iC);
0152     for (auto iS = ch_segs.first; iS != ch_segs.second; ++iS) {
0153       if (iS->gemDetId().station() != 0)  // only dump GE0 segments
0154         continue;
0155       GlobalPoint gp = me0_g->idToDet(iS->gemDetId())->surface().toGlobal(iS->localPosition());
0156       LogTrace("L1ME0Trigger") << "ME0Detid " << iS->gemDetId() << " segment " << *iS << " eta " << gp.eta() << " phi "
0157                                << gp.phi() << std::endl;
0158       auto recHits(iS->recHits());
0159       LogTrace("L1GE0Trigger") << "\t has " << recHits.size() << " me0 rechits" << std::endl;
0160       for (auto& rh : recHits) {
0161         const GEMRecHit* me0rh(dynamic_cast<const GEMRecHit*>(rh));
0162         LogTrace("L1GEMTrigger") << "\t  detid " << me0rh->gemId() << " rechit " << *me0rh << std::endl;
0163       }
0164     }
0165   }
0166 }