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
0027
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
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;
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
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);
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;
0105 int phiposition2 = (static_cast<int>((strip - phiposition) / phi_resolution) & 1);
0106 phiposition = (phiposition << 1) | phiposition2;
0107
0108
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();
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;
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 }