Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #include "L1Trigger/L1TGEM/interface/ME0TriggerPseudoBuilder.h"
0002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0003 #include "Geometry/Records/interface/MuonGeometryRecord.h"
0004 #include "Geometry/GEMGeometry/interface/ME0Geometry.h"
0005 
0006 #include <iostream>
0007 #include <cassert>
0008 
0009 const unsigned int ME0TriggerPseudoBuilder::ME0KeyLayer = 3;
0010 const int ME0TriggerPseudoBuilder::ME0TriggerCentralBX = 8;
0011 
0012 ME0TriggerPseudoBuilder::ME0TriggerPseudoBuilder(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 ME0TriggerPseudoBuilder::~ME0TriggerPseudoBuilder() {}
0019 
0020 void ME0TriggerPseudoBuilder::build(const ME0SegmentCollection* me0Segments, ME0TriggerDigiCollection& oc_trig) {
0021   if (info_ > 2)
0022     dumpAllME0Segments(*me0Segments);
0023 
0024   for (int endc = 0; endc < static_cast<int>(trig_me0s::MAX_ENDCAPS); endc++) {
0025     for (int cham = 0; cham < static_cast<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       ME0DetId detid(region, 0, cham + 1, 0);
0030 
0031       const auto& drange = me0Segments->get(detid);
0032       std::vector<ME0TriggerDigi> trigV;
0033       for (auto digiIt = drange.first; digiIt != drange.second; digiIt++) {
0034         if (info_ > 1)
0035           LogTrace("L1ME0Trigger") << "ME0TriggerPseudoBuilder id " << detid << " ME0 segment " << *digiIt
0036                                    << " to be converted into trigger digi\n";
0037         ME0TriggerDigi trig = segmentConversion(*digiIt);
0038         if (trig.isValid())
0039           trigV.push_back(trig);
0040         if (info_ > 1 and trig.isValid())
0041           LogTrace("L1ME0Trigger") << " ME0trigger " << trig << "\n";
0042         else if (info_ > 1)
0043           LogTrace("L1ME0Trigger") << " ME0trigger is not valid. Conversion failed \n";
0044       }
0045 
0046       if (!trigV.empty()) {
0047         LogTrace("L1ME0Trigger") << "ME0TriggerPseudoBuilder got results in " << detid << std::endl
0048                                  << "Put " << trigV.size() << " Trigger digi" << ((trigV.size() > 1) ? "s " : " ")
0049                                  << "in collection\n";
0050         oc_trig.put(std::make_pair(trigV.begin(), trigV.end()), detid);
0051       }
0052     }
0053   }
0054 }
0055 
0056 ME0TriggerDigi ME0TriggerPseudoBuilder::segmentConversion(const ME0Segment segment) {
0057   auto detid = segment.me0DetId();
0058   const ME0Chamber* chamber = me0_g->chamber(detid);
0059   const ME0Layer* keylayer = me0_g->chamber(detid)->layer(ME0TriggerPseudoBuilder::ME0KeyLayer);
0060   int chamberid = detid.chamber() % 2;
0061   int totRolls = keylayer->nEtaPartitions();
0062   float dphi = chamber->computeDeltaPhi(segment.localPosition(), segment.localDirection());
0063   float time = segment.time();
0064   int sign_time = (time > 0) ? 1 : -1;
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.me0Id().roll()) == rolls.end())
0069       rolls.push_back(rechit.me0Id().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   assert(rolls[0] >= 1);
0079   int partition = (rolls[0] - 1) << 1;  //roll from detid counts from 1
0080   if (rolls.size() == 2 and rolls[0] > rolls[1])
0081     partition = partition - 1;
0082   else if (rolls.size() == 2 and rolls[0] < rolls[1])
0083     partition = partition + 1;
0084 
0085   if (partition < 0 or partition >= 2 * totRolls) {
0086     LogTrace("L1ME0Trigger") << " ME0 segment rolls size of all hits " << rolls.size() << " rolls[0] " << rolls[0]
0087                              << " rolls.back() " << rolls.back() << " and ME0 trigger roll is " << partition
0088                              << " max expected " << 2 * totRolls - 1 << "\n";
0089     return ME0TriggerDigi();
0090   }
0091 
0092   //globalpoint from ME0 segment
0093   GlobalPoint gp = me0_g->idToDet(segment.me0DetId())->surface().toGlobal(segment.localPosition());
0094   const ME0EtaPartition* etapart = keylayer->etaPartition(rolls[0]);
0095   LocalPoint segment_lp = etapart->surface().toLocal(gp);  // convert segment gp into lp in etapartition coordinate
0096   float strippitch = etapart->localPitch(segment_lp);
0097   float strip = etapart->strip(segment_lp);
0098   int totstrip = etapart->nstrips();
0099   int istrip = static_cast<int>(strip);
0100   int phiposition = istrip;
0101   if (phiposition > totstrip)
0102     LogTrace("L1ME0Trigger") << " ME0 segment strip number is " << phiposition << " larger than nstrip " << totstrip
0103                              << " !!! \n";
0104   float phi_resolution = 0.5;                                                         //halfstrip
0105   int phiposition2 = (static_cast<int>((strip - phiposition) / phi_resolution) & 1);  // half-strip resolution
0106   phiposition = (phiposition << 1) | phiposition2;
0107 
0108   //gloablpoint from ME0 trigger digi
0109   float centreOfStrip = istrip + 0.25 + phiposition2 * 0.5;
0110   GlobalPoint gp_digi = etapart->toGlobal(etapart->centreOfStrip(centreOfStrip));
0111 
0112   float strippitch_rad = strippitch / gp.perp();  //unit in rad
0113 
0114   int idphi = static_cast<int>(fabs(dphi) / (strippitch_rad * dphiresolution_));
0115   const int max_idphi = 512;
0116   if (idphi >= max_idphi) {
0117     LogTrace("L1ME0Trigger") << " ME0 segment dphi " << dphi << " and int type: " << idphi
0118                              << " larger than max allowed: " << max_idphi << " !!! \n";
0119     idphi = max_idphi - 1;
0120   }
0121   int quality = nrechits;  // attention: not the same as discussed in meeting
0122   int BX = (static_cast<int>(fabs(time) / 25.0)) * sign_time + ME0TriggerPseudoBuilder::ME0TriggerCentralBX;
0123   int bend = (dphi > 0.0) ? 0 : 1;
0124   if (info_ > 2)
0125     LogTrace("L1ME0Trigger") << " ME0trigger in conversion function:\n"
0126                              << "\t chamber(1-18) " << detid.chamber() << " chamber id " << chamberid << " \n"
0127                              << "\t rolls size of all hits " << rolls.size() << " rolls[0] " << rolls[0]
0128                              << " rolls.back() " << rolls.back() << " roll " << partition << " \n"
0129                              << "\t nRechits " << nrechits << " quality " << quality << " \n"
0130                              << "\t strip(float) " << strip << " (int) " << istrip << " phiposition " << phiposition
0131                              << " resolution (in term of strip) " << phi_resolution << " \n"
0132                              << "\t deltaphi(float) " << dphi << " (int) " << idphi << " resolution "
0133                              << strippitch_rad * dphiresolution_ << " bend " << bend << " \n"
0134                              << "\t global point eta " << gp.eta() << " phi " << gp.phi() << " trigger digi eta "
0135                              << gp_digi.eta() << " phi " << gp_digi.phi() << " \n"
0136                              << "\t time (ns, float) " << time << " BX " << BX << " \n";
0137 
0138   ME0TriggerDigi result = ME0TriggerDigi(chamberid, quality, phiposition, partition, idphi, bend, BX);
0139   result.setStrip(istrip);
0140   return result;
0141 }
0142 
0143 void ME0TriggerPseudoBuilder::dumpAllME0Segments(const ME0SegmentCollection& segments) const {
0144   LogTrace("L1ME0Trigger") << "dumpt all ME0 Segments" << std::endl;
0145   for (auto iC = segments.id_begin(); iC != segments.id_end(); ++iC) {
0146     auto ch_segs = segments.get(*iC);
0147     for (auto iS = ch_segs.first; iS != ch_segs.second; ++iS) {
0148       GlobalPoint gp = me0_g->idToDet(iS->me0DetId())->surface().toGlobal(iS->localPosition());
0149       LogTrace("L1ME0Trigger") << "ME0Detid " << iS->me0DetId() << " segment " << *iS << " eta " << gp.eta() << " phi "
0150                                << gp.phi() << std::endl;
0151       auto recHits(iS->recHits());
0152       LogTrace("L1ME0Trigger") << "\t has " << recHits.size() << " me0 rechits" << std::endl;
0153       for (auto& rh : recHits) {
0154         const ME0RecHit* me0rh(dynamic_cast<const ME0RecHit*>(rh));
0155         LogTrace("L1ME0Trigger") << "\t  detid " << me0rh->me0Id() << " rechit " << *me0rh << std::endl;
0156       }
0157     }
0158   }
0159 }