File indexing completed on 2025-04-09 02:02:06
0001 #include "L1Trigger/L1TTrackMatch/interface/DisplacedVertexProducer.h"
0002 #include "L1TrackUnpacker.h"
0003
0004 using namespace l1trackunpacker;
0005
0006 double DisplacedVertexProducer::FloatPtFromBits(const L1TTTrackType& track) const {
0007 ap_uint<14> ptEmulationBits = track.getTrackWord()(TTTrack_TrackWord::TrackBitLocations::kRinvMSB - 1,
0008 TTTrack_TrackWord::TrackBitLocations::kRinvLSB);
0009 ap_ufixed<14, 9> ptEmulation;
0010 ptEmulation.V = (ptEmulationBits.range());
0011 return ptEmulation.to_double();
0012 }
0013
0014 double DisplacedVertexProducer::FloatEtaFromBits(const L1TTTrackType& track) const {
0015 TTTrack_TrackWord::tanl_t etaBits = track.getTanlWord();
0016 glbeta_intern digieta;
0017 digieta.V = etaBits.range();
0018 return (double)digieta;
0019 }
0020
0021 double DisplacedVertexProducer::FloatPhiFromBits(const L1TTTrackType& track) const {
0022 int Sector = track.phiSector();
0023 double sector_phi_value = 0;
0024 if (Sector < 5) {
0025 sector_phi_value = 2.0 * M_PI * Sector / 9.0;
0026 } else {
0027 sector_phi_value = (-1.0 * M_PI + M_PI / 9.0 + (Sector - 5) * 2.0 * M_PI / 9.0);
0028 }
0029 glbphi_intern trkphiSector = DoubleToBit(
0030 sector_phi_value, TTTrack_TrackWord::TrackBitWidths::kPhiSize + kExtraGlobalPhiBit, TTTrack_TrackWord::stepPhi0);
0031 glbphi_intern local_phiBits = 0;
0032 local_phiBits.V = track.getPhiWord();
0033
0034 glbphi_intern local_phi =
0035 DoubleToBit(BitToDouble(local_phiBits, TTTrack_TrackWord::TrackBitWidths::kPhiSize, TTTrack_TrackWord::stepPhi0),
0036 TTTrack_TrackWord::TrackBitWidths::kPhiSize + kExtraGlobalPhiBit,
0037 TTTrack_TrackWord::stepPhi0);
0038 glbphi_intern digiphi = local_phi + trkphiSector;
0039 return BitToDouble(
0040 digiphi, TTTrack_TrackWord::TrackBitWidths::kPhiSize + kExtraGlobalPhiBit, TTTrack_TrackWord::stepPhi0);
0041 }
0042
0043 int DisplacedVertexProducer::ChargeFromBits(const L1TTTrackType& track) const {
0044 ap_uint<1> chargeBit = track.getTrackWord()[TTTrack_TrackWord::TrackBitLocations::kRinvMSB];
0045 return 1 - (2 * chargeBit.to_uint());
0046 }
0047
0048 double convertPtToR(double pt) {
0049 return 100.0 * (1.0 / (0.3 * 3.8)) * pt;
0050 }
0051
0052 bool ComparePtTrack(std::pair<Track_Parameters, edm::Ptr<TrackingParticle>> a,
0053 std::pair<Track_Parameters, edm::Ptr<TrackingParticle>> b) {
0054 return a.first.pt > b.first.pt;
0055 }
0056
0057 Double_t dist(Double_t x1, Double_t y1, Double_t x2 = 0, Double_t y2 = 0) {
0058 return (std::sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)));
0059 }
0060
0061 Double_t dist_TPs(Track_Parameters a, Track_Parameters b) {
0062 float x1 = a.x0;
0063 float y1 = a.y0;
0064 float x2 = b.x0;
0065 float y2 = b.y0;
0066 float R1 = a.rho;
0067 float R2 = b.rho;
0068 float R = dist(x1, y1, x2, y2);
0069 if ((R >= fabs(R1 - R2)) && (R <= (R1 + R2))) {
0070 return (0);
0071 } else if (R == 0) {
0072 return (-99999.0);
0073 } else {
0074 return (R - R1 - R2);
0075 }
0076 }
0077
0078 Int_t calcVertex(Track_Parameters a, Track_Parameters b, Double_t& x_vtx, Double_t& y_vtx, Double_t& z_vtx) {
0079 float x1 = a.x0;
0080 float y1 = a.y0;
0081 float x2 = b.x0;
0082 float y2 = b.y0;
0083 float R1 = a.rho;
0084 float R2 = b.rho;
0085 float R = dist(x1, y1, x2, y2);
0086 if (R == 0)
0087 return -1;
0088 float co1 = (pow(R1, 2) - pow(R2, 2)) / (2 * pow(R, 2));
0089 float radicand = (2 / pow(R, 2)) * (pow(R1, 2) + pow(R2, 2)) - (pow(pow(R1, 2) - pow(R2, 2), 2) / pow(R, 4)) - 1;
0090 float co2 = 0;
0091 if (radicand > 0)
0092 co2 = 0.5 * std::sqrt(radicand);
0093 float ix1_x = 0.5 * (x1 + x2) + co1 * (x2 - x1) + co2 * (y2 - y1);
0094 float ix2_x = 0.5 * (x1 + x2) + co1 * (x2 - x1) - co2 * (y2 - y1);
0095 float ix1_y = 0.5 * (y1 + y2) + co1 * (y2 - y1) + co2 * (x1 - x2);
0096 float ix2_y = 0.5 * (y1 + y2) + co1 * (y2 - y1) - co2 * (x1 - x2);
0097 float ix1_z1 = a.trackZAtVertex(ix1_x, ix1_y);
0098 float ix1_z2 = b.trackZAtVertex(ix1_x, ix1_y);
0099 float ix1_delz = fabs(ix1_z1 - ix1_z2);
0100 float ix2_z1 = a.trackZAtVertex(ix2_x, ix2_y);
0101 float ix2_z2 = b.trackZAtVertex(ix2_x, ix2_y);
0102 float ix2_delz = fabs(ix2_z1 - ix2_z2);
0103 float trk1_POCA[2] = {a.d0 * std::sin(a.phi), -1 * a.d0 * std::cos(a.phi)};
0104 float trk2_POCA[2] = {b.d0 * std::sin(b.phi), -1 * b.d0 * std::cos(b.phi)};
0105 float trk1_ix1_delxy[2] = {ix1_x - trk1_POCA[0], ix1_y - trk1_POCA[1]};
0106 float trk1_ix2_delxy[2] = {ix2_x - trk1_POCA[0], ix2_y - trk1_POCA[1]};
0107 float trk2_ix1_delxy[2] = {ix1_x - trk2_POCA[0], ix1_y - trk2_POCA[1]};
0108 float trk2_ix2_delxy[2] = {ix2_x - trk2_POCA[0], ix2_y - trk2_POCA[1]};
0109 float trk1_traj[2] = {std::cos(a.phi), std::sin(a.phi)};
0110 float trk2_traj[2] = {std::cos(b.phi), std::sin(b.phi)};
0111 bool trk1_ix1_inTraj = ((trk1_ix1_delxy[0] * trk1_traj[0] + trk1_ix1_delxy[1] * trk1_traj[1]) > 0) ? true : false;
0112 bool trk1_ix2_inTraj = ((trk1_ix2_delxy[0] * trk1_traj[0] + trk1_ix2_delxy[1] * trk1_traj[1]) > 0) ? true : false;
0113 bool trk2_ix1_inTraj = ((trk2_ix1_delxy[0] * trk2_traj[0] + trk2_ix1_delxy[1] * trk2_traj[1]) > 0) ? true : false;
0114 bool trk2_ix2_inTraj = ((trk2_ix2_delxy[0] * trk2_traj[0] + trk2_ix2_delxy[1] * trk2_traj[1]) > 0) ? true : false;
0115 if (trk1_ix1_inTraj && trk2_ix1_inTraj && trk1_ix2_inTraj && trk2_ix2_inTraj) {
0116 if (ix1_delz < ix2_delz) {
0117 x_vtx = ix1_x;
0118 y_vtx = ix1_y;
0119 z_vtx = (ix1_z1 + ix1_z2) / 2;
0120 return 0;
0121 } else {
0122 x_vtx = ix2_x;
0123 y_vtx = ix2_y;
0124 z_vtx = (ix2_z1 + ix2_z2) / 2;
0125 return 0;
0126 }
0127 }
0128 if (trk1_ix1_inTraj && trk2_ix1_inTraj) {
0129 x_vtx = ix1_x;
0130 y_vtx = ix1_y;
0131 z_vtx = (ix1_z1 + ix1_z2) / 2;
0132 return 1;
0133 }
0134 if (trk1_ix2_inTraj && trk2_ix2_inTraj) {
0135 x_vtx = ix2_x;
0136 y_vtx = ix2_y;
0137 z_vtx = (ix2_z1 + ix2_z2) / 2;
0138 return 2;
0139 } else {
0140 if (ix1_delz < ix2_delz) {
0141 x_vtx = ix1_x;
0142 y_vtx = ix1_y;
0143 z_vtx = (ix1_z1 + ix1_z2) / 2;
0144 return 3;
0145 } else {
0146 x_vtx = ix2_x;
0147 y_vtx = ix2_y;
0148 z_vtx = (ix2_z1 + ix2_z2) / 2;
0149 return 3;
0150 }
0151 }
0152 return 4;
0153 }
0154
0155 DisplacedVertexProducer::DisplacedVertexProducer(const edm::ParameterSet& iConfig)
0156 : ttTrackMCTruthToken_(consumes<TTTrackAssociationMap<Ref_Phase2TrackerDigi_>>(
0157 iConfig.getParameter<edm::InputTag>("mcTruthTrackInputTag"))),
0158 trackToken_(consumes<std::vector<TTTrack<Ref_Phase2TrackerDigi_>>>(
0159 iConfig.getParameter<edm::InputTag>("l1TracksInputTag"))),
0160 trackGTTToken_(consumes<std::vector<TTTrack<Ref_Phase2TrackerDigi_>>>(
0161 iConfig.getParameter<edm::InputTag>("l1TracksGTTInputTag"))),
0162 outputVertexCollectionName_(iConfig.getParameter<std::string>("l1TrackVertexCollectionName")),
0163 model_(iConfig.getParameter<edm::FileInPath>("model")),
0164 runEmulation_(iConfig.getParameter<bool>("runEmulation")),
0165 cutSet_(iConfig.getParameter<edm::ParameterSet>("cutSet")),
0166 chi2rzMax_(cutSet_.getParameter<double>("chi2rzMax")),
0167 promptMVAMin_(cutSet_.getParameter<double>("promptMVAMin")),
0168 ptMin_(cutSet_.getParameter<double>("ptMin")),
0169 etaMax_(cutSet_.getParameter<double>("etaMax")),
0170 dispD0Min_(cutSet_.getParameter<double>("dispD0Min")),
0171 promptMVADispTrackMin_(cutSet_.getParameter<double>("promptMVADispTrackMin")),
0172 overlapEtaMin_(cutSet_.getParameter<double>("overlapEtaMin")),
0173 overlapEtaMax_(cutSet_.getParameter<double>("overlapEtaMax")),
0174 overlapNStubsMin_(cutSet_.getParameter<int>("overlapNStubsMin")),
0175 diskEtaMin_(cutSet_.getParameter<double>("diskEtaMin")),
0176 diskD0Min_(cutSet_.getParameter<double>("diskD0Min")),
0177 barrelD0Min_(cutSet_.getParameter<double>("barrelD0Min")),
0178 RTMin_(cutSet_.getParameter<double>("RTMin")),
0179 RTMax_(cutSet_.getParameter<double>("RTMax")) {
0180
0181 produces<l1t::DisplacedTrackVertexCollection>(outputVertexCollectionName_);
0182 }
0183
0184 void DisplacedVertexProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const {
0185 edm::Handle<TTTrackAssociationMap<Ref_Phase2TrackerDigi_>> MCTruthTTTrackHandle;
0186 iEvent.getByToken(ttTrackMCTruthToken_, MCTruthTTTrackHandle);
0187 edm::Handle<std::vector<TTTrack<Ref_Phase2TrackerDigi_>>> TTTrackHandle;
0188 iEvent.getByToken(trackToken_, TTTrackHandle);
0189 edm::Handle<std::vector<TTTrack<Ref_Phase2TrackerDigi_>>> TTTrackGTTHandle;
0190 iEvent.getByToken(trackGTTToken_, TTTrackGTTHandle);
0191 std::vector<TTTrack<Ref_Phase2TrackerDigi_>>::const_iterator iterL1Track;
0192 int this_l1track = 0;
0193 std::vector<std::pair<Track_Parameters, edm::Ptr<TrackingParticle>>> selectedTracksWithTruth;
0194
0195
0196 for (iterL1Track = TTTrackHandle->begin(); iterL1Track != TTTrackHandle->end(); iterL1Track++) {
0197 edm::Ptr<TTTrack<Ref_Phase2TrackerDigi_>> l1track_ptr(TTTrackHandle, this_l1track);
0198 edm::Ptr<TTTrack<Ref_Phase2TrackerDigi_>> gtttrack_ptr(TTTrackGTTHandle, this_l1track);
0199 this_l1track++;
0200
0201 float pt, eta, phi, z0, d0, rho, chi2rphi, chi2rz, bendchi2, MVA1;
0202 int nstub;
0203
0204 if (runEmulation_) {
0205 pt = FloatPtFromBits(*gtttrack_ptr);
0206 eta = FloatEtaFromBits(*gtttrack_ptr);
0207 phi = FloatPhiFromBits(*gtttrack_ptr);
0208 z0 = gtttrack_ptr->getZ0();
0209 d0 = gtttrack_ptr->getD0();
0210 int charge = ChargeFromBits(*gtttrack_ptr);
0211 rho = charge * convertPtToR(pt);
0212 chi2rphi = gtttrack_ptr->getChi2RPhi();
0213 chi2rz = gtttrack_ptr->getChi2RZ();
0214 bendchi2 = gtttrack_ptr->getBendChi2();
0215 MVA1 = gtttrack_ptr->getMVAQuality();
0216 nstub = gtttrack_ptr->getNStubs();
0217 } else {
0218 pt = l1track_ptr->momentum().perp();
0219 eta = l1track_ptr->momentum().eta();
0220 phi = l1track_ptr->momentum().phi();
0221 z0 = l1track_ptr->z0();
0222 float x0 = l1track_ptr->POCA().x();
0223 float y0 = l1track_ptr->POCA().y();
0224 d0 = x0 * std::sin(phi) - y0 * std::cos(phi);
0225 rho = 1 / l1track_ptr->rInv();
0226 chi2rphi = l1track_ptr->chi2XYRed();
0227 chi2rz = l1track_ptr->chi2ZRed();
0228 bendchi2 = l1track_ptr->stubPtConsistency();
0229 MVA1 = l1track_ptr->trkMVA1();
0230 std::vector<edm::Ref<edmNew::DetSetVector<TTStub<Ref_Phase2TrackerDigi_>>, TTStub<Ref_Phase2TrackerDigi_>>>
0231 stubRefs = l1track_ptr->getStubRefs();
0232 nstub = (int)stubRefs.size();
0233 }
0234
0235 if (chi2rz < chi2rzMax_ && MVA1 > promptMVAMin_ && pt > ptMin_ && fabs(eta) < etaMax_) {
0236 if (fabs(d0) > dispD0Min_) {
0237 if (MVA1 <= promptMVADispTrackMin_)
0238 continue;
0239 }
0240 if (fabs(eta) > overlapEtaMin_ && fabs(eta) < overlapEtaMax_) {
0241 if (nstub <= overlapNStubsMin_)
0242 continue;
0243 }
0244 if (fabs(eta) > diskEtaMin_) {
0245 if (fabs(d0) <= diskD0Min_)
0246 continue;
0247 }
0248 if (fabs(eta) <= diskEtaMin_) {
0249 if (fabs(d0) <= barrelD0Min_)
0250 continue;
0251 }
0252
0253 Track_Parameters track =
0254 Track_Parameters(pt, d0, z0, eta, phi, rho, (this_l1track - 1), nstub, chi2rphi, chi2rz, bendchi2, MVA1);
0255
0256 edm::Ptr<TrackingParticle> my_tp = MCTruthTTTrackHandle->findTrackingParticlePtr(l1track_ptr);
0257 selectedTracksWithTruth.push_back(std::make_pair(track, my_tp));
0258 }
0259 }
0260
0261
0262 std::unique_ptr<l1t::DisplacedTrackVertexCollection> product(new std::vector<l1t::DisplacedTrackVertex>());
0263 for (int i = 0; i < int(selectedTracksWithTruth.size() - 1); i++) {
0264 for (int j = i + 1; j < int(selectedTracksWithTruth.size()); j++) {
0265 if (dist_TPs(selectedTracksWithTruth[i].first, selectedTracksWithTruth[j].first) != 0)
0266 continue;
0267 Double_t x_dv_trk = -9999.0;
0268 Double_t y_dv_trk = -9999.0;
0269 Double_t z_dv_trk = -9999.0;
0270 edm::Ptr<TrackingParticle> tp_i = selectedTracksWithTruth[i].second;
0271 edm::Ptr<TrackingParticle> tp_j = selectedTracksWithTruth[j].second;
0272 bool isReal = false;
0273 if (!tp_i.isNull() && !tp_j.isNull()) {
0274 bool isHard_i = false;
0275 bool isHard_j = false;
0276 if (!tp_i->genParticles().empty() && !tp_j->genParticles().empty()) {
0277 isHard_i = tp_i->genParticles()[0]->isHardProcess() || tp_i->genParticles()[0]->fromHardProcessFinalState();
0278 isHard_j = tp_j->genParticles()[0]->isHardProcess() || tp_j->genParticles()[0]->fromHardProcessFinalState();
0279 }
0280
0281 if (tp_i->eventId().event() == 0 && tp_j->eventId().event() == 0 && fabs(tp_i->vx() - tp_j->vx()) < 0.0001 &&
0282 fabs(tp_i->vy() - tp_j->vy()) < 0.0001 && fabs(tp_i->vz() - tp_j->vz()) < 0.0001 && isHard_i && isHard_j &&
0283 ((tp_i->charge() + tp_j->charge()) == 0)) {
0284 isReal = true;
0285 }
0286 }
0287
0288 int inTraj =
0289 calcVertex(selectedTracksWithTruth[i].first, selectedTracksWithTruth[j].first, x_dv_trk, y_dv_trk, z_dv_trk);
0290 Vertex_Parameters vertex = Vertex_Parameters(
0291 x_dv_trk, y_dv_trk, z_dv_trk, selectedTracksWithTruth[i].first, selectedTracksWithTruth[j].first);
0292
0293 if (vertex.R_T > RTMax_)
0294 continue;
0295 if (vertex.R_T < RTMin_)
0296 continue;
0297
0298 l1t::DisplacedTrackVertex outputVertex = l1t::DisplacedTrackVertex(selectedTracksWithTruth[i].first.index,
0299 selectedTracksWithTruth[j].first.index,
0300 inTraj,
0301 vertex.d_T,
0302 vertex.R_T,
0303 vertex.cos_T,
0304 vertex.delta_z,
0305 vertex.x_dv,
0306 vertex.y_dv,
0307 vertex.z_dv,
0308 vertex.openingAngle,
0309 vertex.p_mag,
0310 isReal);
0311
0312
0313 float ptRescaling = 0.25;
0314 float deltaZRescaling = 0.125;
0315 if (runEmulation_) {
0316 std::vector<ap_fixed<13, 8, AP_RND_CONV, AP_SAT>> Transformed_features = {
0317 selectedTracksWithTruth[i].first.pt * ptRescaling,
0318 selectedTracksWithTruth[j].first.pt * ptRescaling,
0319 selectedTracksWithTruth[i].first.eta,
0320 selectedTracksWithTruth[j].first.eta,
0321 selectedTracksWithTruth[i].first.phi,
0322 selectedTracksWithTruth[j].first.phi,
0323 selectedTracksWithTruth[i].first.d0,
0324 selectedTracksWithTruth[j].first.d0,
0325 selectedTracksWithTruth[i].first.z0,
0326 selectedTracksWithTruth[j].first.z0,
0327 selectedTracksWithTruth[i].first.chi2rz,
0328 selectedTracksWithTruth[j].first.chi2rz,
0329 selectedTracksWithTruth[i].first.bendchi2,
0330 selectedTracksWithTruth[j].first.bendchi2,
0331 selectedTracksWithTruth[i].first.MVA1,
0332 selectedTracksWithTruth[j].first.MVA1,
0333 vertex.d_T,
0334 vertex.R_T,
0335 vertex.cos_T,
0336 vertex.delta_z * deltaZRescaling};
0337 conifer::BDT<ap_fixed<13, 8, AP_RND_CONV, AP_SAT>, ap_fixed<13, 8, AP_RND_CONV, AP_SAT>> bdt(
0338 this->model_.fullPath());
0339 std::vector<ap_fixed<13, 8, AP_RND_CONV, AP_SAT>> output = bdt.decision_function(Transformed_features);
0340 outputVertex.setScore(output.at(0).to_float());
0341 } else {
0342 std::vector<float> Transformed_features = {float(selectedTracksWithTruth[i].first.pt * ptRescaling),
0343 float(selectedTracksWithTruth[j].first.pt * ptRescaling),
0344 selectedTracksWithTruth[i].first.eta,
0345 selectedTracksWithTruth[j].first.eta,
0346 selectedTracksWithTruth[i].first.phi,
0347 selectedTracksWithTruth[j].first.phi,
0348 selectedTracksWithTruth[i].first.d0,
0349 selectedTracksWithTruth[j].first.d0,
0350 selectedTracksWithTruth[i].first.z0,
0351 selectedTracksWithTruth[j].first.z0,
0352 float(selectedTracksWithTruth[i].first.chi2rz),
0353 float(selectedTracksWithTruth[j].first.chi2rz),
0354 float(selectedTracksWithTruth[i].first.bendchi2),
0355 float(selectedTracksWithTruth[j].first.bendchi2),
0356 float(selectedTracksWithTruth[i].first.MVA1),
0357 float(selectedTracksWithTruth[j].first.MVA1),
0358 vertex.d_T,
0359 vertex.R_T,
0360 vertex.cos_T,
0361 float(vertex.delta_z * deltaZRescaling)};
0362 conifer::BDT<float, float> bdt(this->model_.fullPath());
0363 std::vector<float> output = bdt.decision_function(Transformed_features);
0364 outputVertex.setScore(output.at(0));
0365 }
0366
0367 product->emplace_back(outputVertex);
0368 }
0369 }
0370
0371
0372 iEvent.put(std::move(product), outputVertexCollectionName_);
0373 }
0374
0375 DEFINE_FWK_MODULE(DisplacedVertexProducer);