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
0027
0028 const int region(endc == 0 ? -1 : 1);
0029
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
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;
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
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);
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;
0106 int phiposition2 = (static_cast<int>((strip - phiposition) / phi_resolution) & 1);
0107 phiposition = (phiposition << 1) | phiposition2;
0108
0109
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();
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;
0123
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
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)
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 }