From e7b2f37dde4f8d77aa8641bdb068c8ecf35c6845 Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Thu, 13 Nov 2025 20:17:14 +0100 Subject: [PATCH 01/61] Add Phase2 OT efficiency client to standalone harvesting sequence --- .../test/harvestingstep_phase2tk_cfg.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/DQM/SiTrackerPhase2/test/harvestingstep_phase2tk_cfg.py b/DQM/SiTrackerPhase2/test/harvestingstep_phase2tk_cfg.py index 56950a5497d67..63acf9b4ca5a7 100644 --- a/DQM/SiTrackerPhase2/test/harvestingstep_phase2tk_cfg.py +++ b/DQM/SiTrackerPhase2/test/harvestingstep_phase2tk_cfg.py @@ -27,6 +27,7 @@ process.load('Configuration.StandardSequences.DQMSaverAtRunEnd_cff') process.load('Configuration.StandardSequences.Harvesting_cff') process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') +process.load('Validation.SiTrackerPhase2V.Phase2OTEffClient_cff') process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(8000), @@ -81,11 +82,18 @@ from Configuration.AlCa.GlobalTag import GlobalTag process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase2_realistic_T21', '') +# Load your sidecar client +process.load('Validation.SiTrackerPhase2V.Phase2OTEffClient_cff') + +# Add the client into the standalone harvesting sequence +process.trackerphase2ValidationHarvesting_standalone += process.phase2OTEffClientSeq + # Path and EndPath definitions process.trackerphase2ValidationHarvesting_step = cms.Path(process.trackerphase2ValidationHarvesting_standalone) -##default path in production -#process.trackerphase2ValidationHarvesting_step = cms.Path(process.trackerphase2ValidationHarvesting) +## default path in production +# process.trackerphase2ValidationHarvesting_step = cms.Path(process.trackerphase2ValidationHarvesting) + process.dqmsave_step = cms.Path(process.DQMSaver) # Schedule definition -process.schedule = cms.Schedule(process.trackerphase2ValidationHarvesting_step,process.dqmsave_step) \ No newline at end of file +process.schedule = cms.Schedule(process.trackerphase2ValidationHarvesting_step, process.dqmsave_step) \ No newline at end of file From 1c9bd03bec195ad4c1fc52b242c9aef94ed4c631 Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Thu, 13 Nov 2025 20:22:14 +0100 Subject: [PATCH 02/61] use DQMGenericClient for Phase2OT track efficiencies; drop manual code --- .../plugins/Phase2OTHarvestTracks.cc | 526 +----------------- 1 file changed, 2 insertions(+), 524 deletions(-) diff --git a/Validation/SiTrackerPhase2V/plugins/Phase2OTHarvestTracks.cc b/Validation/SiTrackerPhase2V/plugins/Phase2OTHarvestTracks.cc index 9809843c8ecaf..4e108499cc5f3 100644 --- a/Validation/SiTrackerPhase2V/plugins/Phase2OTHarvestTracks.cc +++ b/Validation/SiTrackerPhase2V/plugins/Phase2OTHarvestTracks.cc @@ -27,7 +27,6 @@ #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/ServiceRegistry/interface/Service.h" -#include "Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h" class Phase2OTHarvestTracks : public DQMEDHarvester { public: @@ -54,58 +53,6 @@ void Phase2OTHarvestTracks::dqmEndJob(DQMStore::IBooker &ibooker, DQMStore::IGet float eta_bins[] = {0.0, 0.7, 1.0, 1.2, 1.6, 2.0, 2.4}; int eta_binnum = 6; - // Find all monitor elements for histograms - MonitorElement *meN_eta = igetter.get(topFolderName_ + "/Nominal_L1TF/EfficiencyIngredients/match_tp_eta"); - MonitorElement *meD_eta = igetter.get(topFolderName_ + "/Nominal_L1TF/EfficiencyIngredients/tp_eta"); - MonitorElement *meN_pt = igetter.get(topFolderName_ + "/Nominal_L1TF/EfficiencyIngredients/match_tp_pt"); - MonitorElement *meD_pt = igetter.get(topFolderName_ + "/Nominal_L1TF/EfficiencyIngredients/tp_pt"); - MonitorElement *meN_pt_zoom = igetter.get(topFolderName_ + "/Nominal_L1TF/EfficiencyIngredients/match_tp_pt_zoom"); - MonitorElement *meD_pt_zoom = igetter.get(topFolderName_ + "/Nominal_L1TF/EfficiencyIngredients/tp_pt_zoom"); - MonitorElement *meN_d0 = igetter.get(topFolderName_ + "/Nominal_L1TF/EfficiencyIngredients/match_tp_d0"); - MonitorElement *meD_d0 = igetter.get(topFolderName_ + "/Nominal_L1TF/EfficiencyIngredients/tp_d0"); - MonitorElement *meN_Lxy = igetter.get(topFolderName_ + "/Nominal_L1TF/EfficiencyIngredients/match_tp_Lxy"); - MonitorElement *meD_Lxy = igetter.get(topFolderName_ + "/Nominal_L1TF/EfficiencyIngredients/tp_Lxy"); - MonitorElement *meN_z0 = igetter.get(topFolderName_ + "/Nominal_L1TF/EfficiencyIngredients/match_tp_z0"); - MonitorElement *meD_z0 = igetter.get(topFolderName_ + "/Nominal_L1TF/EfficiencyIngredients/tp_z0"); - - // Extended collection - MonitorElement *meN_prompt_eta = - igetter.get(topFolderName_ + "/Extended_L1TF/Prompt/EfficiencyIngredients/match_prompt_tp_eta"); - MonitorElement *meN_prompt_pt = - igetter.get(topFolderName_ + "/Extended_L1TF/Prompt/EfficiencyIngredients/match_prompt_tp_pt"); - MonitorElement *meN_prompt_pt_zoom = - igetter.get(topFolderName_ + "/Extended_L1TF/Prompt/EfficiencyIngredients/match_prompt_tp_pt_zoom"); - MonitorElement *meN_prompt_d0 = - igetter.get(topFolderName_ + "/Extended_L1TF/Prompt/EfficiencyIngredients/match_prompt_tp_d0"); - MonitorElement *meN_prompt_Lxy = - igetter.get(topFolderName_ + "/Extended_L1TF/Prompt/EfficiencyIngredients/match_prompt_tp_Lxy"); - MonitorElement *meN_prompt_z0 = - igetter.get(topFolderName_ + "/Extended_L1TF/Prompt/EfficiencyIngredients/match_prompt_tp_z0"); - - MonitorElement *meN_displaced_eta = - igetter.get(topFolderName_ + "/Extended_L1TF/Displaced/EfficiencyIngredients/match_displaced_tp_eta"); - MonitorElement *meD_displaced_eta = - igetter.get(topFolderName_ + "/Extended_L1TF/Displaced/EfficiencyIngredients/tp_eta_for_dis"); - MonitorElement *meN_displaced_pt = - igetter.get(topFolderName_ + "/Extended_L1TF/Displaced/EfficiencyIngredients/match_displaced_tp_pt"); - MonitorElement *meD_displaced_pt = - igetter.get(topFolderName_ + "/Extended_L1TF/Displaced/EfficiencyIngredients/tp_pt_for_dis"); - MonitorElement *meN_displaced_pt_zoom = igetter.get(topFolderName_ + - "/Extended_L1TF/Displaced/EfficiencyIngredients/" - "match_displaced_tp_pt_zoom"); - MonitorElement *meD_displaced_pt_zoom = - igetter.get(topFolderName_ + "/Extended_L1TF/Displaced/EfficiencyIngredients/tp_pt_zoom_for_dis"); - MonitorElement *meN_displaced_d0 = - igetter.get(topFolderName_ + "/Extended_L1TF/Displaced/EfficiencyIngredients/match_displaced_tp_d0"); - MonitorElement *meD_displaced_d0 = - igetter.get(topFolderName_ + "/Extended_L1TF/Displaced/EfficiencyIngredients/tp_d0_for_dis"); - MonitorElement *meN_displaced_Lxy = - igetter.get(topFolderName_ + "/Extended_L1TF/Displaced/EfficiencyIngredients/match_displaced_tp_Lxy"); - MonitorElement *meN_displaced_z0 = - igetter.get(topFolderName_ + "/Extended_L1TF/Displaced/EfficiencyIngredients/match_displaced_tp_z0"); - MonitorElement *meD_displaced_z0 = - igetter.get(topFolderName_ + "/Extended_L1TF/Displaced/EfficiencyIngredients/tp_z0_for_dis"); - std::string eta_ranges[6] = {"eta0to0p7", "eta0p7to1", "eta1to1p2", "eta1p2to1p6", "eta1p6to2", "eta2to2p4"}; // nominal collection std::vector respt_pt2to3 = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; @@ -179,477 +126,7 @@ void Phase2OTHarvestTracks::dqmEndJob(DQMStore::IBooker &ibooker, DQMStore::IGet igetter.get(topFolderName_ + "/Extended_L1TF/Displaced/ResolutionIngredients/resd0_displaced_" + eta_ranges[i]); } - // nominal collection - if (meN_eta && meD_eta) { - // Get the numerator and denominator histograms - TH1F *numerator = meN_eta->getTH1F(); - TH1F *denominator = meD_eta->getTH1F(); - numerator->Sumw2(); - denominator->Sumw2(); - - // Set the current directory - igetter.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/FinalEfficiency"); - - // Book the new histogram to contain the results - MonitorElement *me_effic_eta = ibooker.book1D("EtaEfficiency", - "#eta efficiency", - numerator->GetNbinsX(), - numerator->GetXaxis()->GetXmin(), - numerator->GetXaxis()->GetXmax()); - - // Calculate the efficiency - phase2tkutil::makeEfficiencyME(numerator, denominator, me_effic_eta, "tracking particle #eta"); - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for eta efficiency cannot be found!\n"; - } - - // extended collection - if (meN_prompt_eta && meD_eta) { - // Get the numerator and denominator histograms - TH1F *numerator = meN_prompt_eta->getTH1F(); - TH1F *denominator = meD_eta->getTH1F(); - numerator->Sumw2(); - if (!denominator->GetSumw2N()) { - denominator->Sumw2(); - } - - // Set the current directory - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Prompt/FinalEfficiency"); - - // Book the new histogram to contain the results - MonitorElement *me_effic_eta = ibooker.book1D("EtaEfficiency", - "Prompt #eta efficiency", - numerator->GetNbinsX(), - numerator->GetXaxis()->GetXmin(), - numerator->GetXaxis()->GetXmax()); - - // Calculate the efficiency - phase2tkutil::makeEfficiencyME(numerator, denominator, me_effic_eta, "tracking particle #eta"); - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for extended prompt " - "eta efficiency cannot be found!\n"; - } - - if (meN_displaced_eta && meD_displaced_eta) { - // Get the numerator and denominator histograms - TH1F *numerator = meN_displaced_eta->getTH1F(); - TH1F *denominator = meD_displaced_eta->getTH1F(); - numerator->Sumw2(); - denominator->Sumw2(); - - // Set the current directory - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Displaced/FinalEfficiency"); - - // Book the new histogram to contain the results - MonitorElement *me_effic_eta = ibooker.book1D("EtaEfficiency", - "Displaced #eta efficiency", - numerator->GetNbinsX(), - numerator->GetXaxis()->GetXmin(), - numerator->GetXaxis()->GetXmax()); - - // Calculate the efficiency - phase2tkutil::makeEfficiencyME(numerator, denominator, me_effic_eta, "tracking particle #eta"); - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for extended displaced eta efficiency cannot be " - "found!\n"; - } - - // nominal collection - if (meN_pt && meD_pt) { - // Get the numerator and denominator histograms - TH1F *numerator = meN_pt->getTH1F(); - TH1F *denominator = meD_pt->getTH1F(); - numerator->Sumw2(); - denominator->Sumw2(); - - // Set the current directory - igetter.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/FinalEfficiency"); - - // Book the new histogram to contain the results - MonitorElement *me_effic_pt = ibooker.book1D("PtEfficiency", - "p_{T} efficiency", - numerator->GetNbinsX(), - numerator->GetXaxis()->GetXmin(), - numerator->GetXaxis()->GetXmax()); - - // Calculate the efficiency - phase2tkutil::makeEfficiencyME(numerator, denominator, me_effic_pt, "Tracking particle p_{T} [GeV]"); - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for pT efficiency cannot be found!\n"; - } - - // extended collection - if (meN_prompt_pt && meD_pt) { - // Get the numerator and denominator histograms - TH1F *numerator = meN_prompt_pt->getTH1F(); - TH1F *denominator = meD_pt->getTH1F(); - numerator->Sumw2(); - if (!denominator->GetSumw2N()) { - denominator->Sumw2(); - } - - // Set the current directory - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Prompt/FinalEfficiency"); - - // Book the new histogram to contain the results - MonitorElement *me_effic_pt = ibooker.book1D("PtEfficiency", - "Prompt p_{T} efficiency", - numerator->GetNbinsX(), - numerator->GetXaxis()->GetXmin(), - numerator->GetXaxis()->GetXmax()); - - // Calculate the efficiency - phase2tkutil::makeEfficiencyME(numerator, denominator, me_effic_pt, "Tracking particle p_{T} [GeV]"); - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for extended prompt " - "pT efficiency cannot be found!\n"; - } - - if (meN_displaced_pt && meD_displaced_pt) { - // Get the numerator and denominator histograms - TH1F *numerator = meN_displaced_pt->getTH1F(); - TH1F *denominator = meD_displaced_pt->getTH1F(); - numerator->Sumw2(); - denominator->Sumw2(); - - // Set the current directory - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Displaced/FinalEfficiency"); - - // Book the new histogram to contain the results - MonitorElement *me_effic_pt = ibooker.book1D("PtEfficiency", - "Displaced p_{T} efficiency", - numerator->GetNbinsX(), - numerator->GetXaxis()->GetXmin(), - numerator->GetXaxis()->GetXmax()); - - // Calculate the efficiency - phase2tkutil::makeEfficiencyME(numerator, denominator, me_effic_pt, "Tracking particle p_{T} [GeV]"); - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for extended displaced pT efficiency cannot be " - "found!\n"; - } - - // nominal collection - if (meN_pt_zoom && meD_pt_zoom) { - // Get the numerator and denominator histograms - TH1F *numerator_zoom = meN_pt_zoom->getTH1F(); - TH1F *denominator_zoom = meD_pt_zoom->getTH1F(); - numerator_zoom->Sumw2(); - denominator_zoom->Sumw2(); - - // Set the current directory - igetter.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/FinalEfficiency"); - - // Book the new histogram to contain the results - MonitorElement *me_effic_pt_zoom = ibooker.book1D("PtEfficiency_zoom", - "p_{T} efficiency", - numerator_zoom->GetNbinsX(), - numerator_zoom->GetXaxis()->GetXmin(), - numerator_zoom->GetXaxis()->GetXmax()); - - // Calculate the efficiency - phase2tkutil::makeEfficiencyME(numerator_zoom, denominator_zoom, me_effic_pt_zoom, "Tracking particle p_{T} [GeV]"); - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for zoom pT efficiency cannot be found!\n"; - } - - // extended collection - if (meN_prompt_pt_zoom && meD_pt_zoom) { - // Get the numerator and denominator histograms - TH1F *numerator_zoom = meN_prompt_pt_zoom->getTH1F(); - TH1F *denominator_zoom = meD_pt_zoom->getTH1F(); - numerator_zoom->Sumw2(); - if (!denominator_zoom->GetSumw2N()) { - denominator_zoom->Sumw2(); - } - - // Set the current directory - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Prompt/FinalEfficiency"); - - // Book the new histogram to contain the results - MonitorElement *me_effic_pt_zoom = ibooker.book1D("PtEfficiency_zoom", - "Prompt p_{T} efficiency", - numerator_zoom->GetNbinsX(), - numerator_zoom->GetXaxis()->GetXmin(), - numerator_zoom->GetXaxis()->GetXmax()); - - // Calculate the efficiency - phase2tkutil::makeEfficiencyME(numerator_zoom, denominator_zoom, me_effic_pt_zoom, "Tracking particle p_{T} [GeV]"); - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for extended prompt " - "zoom pT efficiency cannot be found!\n"; - } - - if (meN_displaced_pt_zoom && meD_displaced_pt_zoom) { - // Get the numerator and denominator histograms - TH1F *numerator_zoom = meN_displaced_pt_zoom->getTH1F(); - TH1F *denominator_zoom = meD_displaced_pt_zoom->getTH1F(); - numerator_zoom->Sumw2(); - denominator_zoom->Sumw2(); - - // Set the current directory - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Displaced/FinalEfficiency"); - - // Book the new histogram to contain the results - MonitorElement *me_effic_pt_zoom = ibooker.book1D("PtEfficiency_zoom", - "Displaced p_{T} efficiency", - numerator_zoom->GetNbinsX(), - numerator_zoom->GetXaxis()->GetXmin(), - numerator_zoom->GetXaxis()->GetXmax()); - - // Calculate the efficiency - phase2tkutil::makeEfficiencyME(numerator_zoom, denominator_zoom, me_effic_pt_zoom, "Tracking particle p_{T} [GeV]"); - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for extended displaced zoom pT efficiency cannot " - "be found!\n"; - } - - // nominal collection - if (meN_d0 && meD_d0) { - // Get the numerator and denominator histograms - TH1F *numerator = meN_d0->getTH1F(); - TH1F *denominator = meD_d0->getTH1F(); - numerator->Sumw2(); - denominator->Sumw2(); - - // Set the current directory - igetter.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/FinalEfficiency"); - - // Book the new histogram to contain the results - MonitorElement *me_effic_d0 = ibooker.book1D("d0Efficiency", - "d_{0} efficiency", - numerator->GetNbinsX(), - numerator->GetXaxis()->GetXmin(), - numerator->GetXaxis()->GetXmax()); - - // Calculate the efficiency - phase2tkutil::makeEfficiencyME(numerator, denominator, me_effic_d0, "Tracking particle d_{0} [cm]"); - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for d0 efficiency cannot be found!\n"; - } - - // extended collection - if (meN_prompt_d0 && meD_d0) { - // Get the numerator and denominator histograms - TH1F *numerator = meN_prompt_d0->getTH1F(); - TH1F *denominator = meD_d0->getTH1F(); - numerator->Sumw2(); - if (!denominator->GetSumw2N()) { - denominator->Sumw2(); - } - - // Set the current directory - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Prompt/FinalEfficiency"); - - // Book the new histogram to contain the results - MonitorElement *me_effic_d0 = ibooker.book1D("d0Efficiency", - "Prompt d_{0} efficiency", - numerator->GetNbinsX(), - numerator->GetXaxis()->GetXmin(), - numerator->GetXaxis()->GetXmax()); - - // Calculate the efficiency - phase2tkutil::makeEfficiencyME(numerator, denominator, me_effic_d0, "Tracking particle d_{0} [cm]"); - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for extended prompt " - "d0 efficiency cannot be found!\n"; - } - - if (meN_displaced_d0 && meD_displaced_d0) { - // Get the numerator and denominator histograms - TH1F *numerator = meN_displaced_d0->getTH1F(); - TH1F *denominator = meD_displaced_d0->getTH1F(); - numerator->Sumw2(); - denominator->Sumw2(); - - // Set the current directory - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Displaced/FinalEfficiency"); - - // Book the new histogram to contain the results - MonitorElement *me_effic_d0 = ibooker.book1D("d0Efficiency", - "Displaced d_{0} efficiency", - numerator->GetNbinsX(), - numerator->GetXaxis()->GetXmin(), - numerator->GetXaxis()->GetXmax()); - - // Calculate the efficiency - phase2tkutil::makeEfficiencyME(numerator, denominator, me_effic_d0, "Tracking particle d_{0} [cm]"); - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for extended displaced d0 efficiency cannot be " - "found!\n"; - } - - // nominal collection - if (meN_Lxy && meD_Lxy) { - // Get the numerator and denominator histograms - TH1F *numerator = meN_Lxy->getTH1F(); - TH1F *denominator = meD_Lxy->getTH1F(); - numerator->Sumw2(); - denominator->Sumw2(); - - // Set the current directory - igetter.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/FinalEfficiency"); - - // Book the new histogram to contain the results - MonitorElement *me_effic_Lxy = ibooker.book1D("LxyEfficiency", - "Lxy efficiency", - numerator->GetNbinsX(), - numerator->GetXaxis()->GetXmin(), - numerator->GetXaxis()->GetXmax()); - - // Calculate the efficiency - phase2tkutil::makeEfficiencyME(numerator, denominator, me_effic_Lxy, "Tracking particle Lxy [cm]"); - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for Lxy efficiency cannot be found!\n"; - } - - // extended collecion - if (meN_prompt_Lxy && meD_Lxy) { - // Get the numerator and denominator histograms - TH1F *numerator = meN_prompt_Lxy->getTH1F(); - TH1F *denominator = meD_Lxy->getTH1F(); - numerator->Sumw2(); - if (!denominator->GetSumw2N()) { - denominator->Sumw2(); - } - - // Set the current directory - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Prompt/FinalEfficiency"); - - // Book the new histogram to contain the results - MonitorElement *me_effic_Lxy = ibooker.book1D("LxyEfficiency", - "Prompt Lxy efficiency", - numerator->GetNbinsX(), - numerator->GetXaxis()->GetXmin(), - numerator->GetXaxis()->GetXmax()); - - // Calculate the efficiency - phase2tkutil::makeEfficiencyME(numerator, denominator, me_effic_Lxy, "Tracking particle Lxy [cm]"); - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for extended prompt " - "Lxy efficiency cannot be found!\n"; - } - - if (meN_displaced_Lxy && meD_Lxy) { - // Get the numerator and denominator histograms - TH1F *numerator = meN_displaced_Lxy->getTH1F(); - TH1F *denominator = meD_Lxy->getTH1F(); - numerator->Sumw2(); - if (!denominator->GetSumw2N()) { - denominator->Sumw2(); - } - - // Set the current directory - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Displaced/FinalEfficiency"); - - // Book the new histogram to contain the results - MonitorElement *me_effic_Lxy = ibooker.book1D("LxyEfficiency", - "Displaced Lxy efficiency", - numerator->GetNbinsX(), - numerator->GetXaxis()->GetXmin(), - numerator->GetXaxis()->GetXmax()); - - // Calculate the efficiency - phase2tkutil::makeEfficiencyME(numerator, denominator, me_effic_Lxy, "Tracking particle Lxy [cm]"); - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for extended displaced Lxy efficiency cannot be " - "found!\n"; - } - - // nominal collection - if (meN_z0 && meD_z0) { - // Get the numerator and denominator histograms - TH1F *numerator = meN_z0->getTH1F(); - TH1F *denominator = meD_z0->getTH1F(); - numerator->Sumw2(); - denominator->Sumw2(); - - // Set the current directory - igetter.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/FinalEfficiency"); - - // Book the new histogram to contain the results - MonitorElement *me_effic_z0 = ibooker.book1D("z0Efficiency", - "z0 efficiency", - numerator->GetNbinsX(), - numerator->GetXaxis()->GetXmin(), - numerator->GetXaxis()->GetXmax()); - - // Calculate the efficiency - phase2tkutil::makeEfficiencyME(numerator, denominator, me_effic_z0, "Tracking particle z0 [cm]"); - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for z0 efficiency cannot be found!\n"; - } - - // extended collection - if (meN_prompt_z0 && meD_z0) { - // Get the numerator and denominator histograms - TH1F *numerator = meN_prompt_z0->getTH1F(); - TH1F *denominator = meD_z0->getTH1F(); - numerator->Sumw2(); - if (!denominator->GetSumw2N()) { - denominator->Sumw2(); - } - - // Set the current directory - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Prompt/FinalEfficiency"); - - // Book the new histogram to contain the results - MonitorElement *me_effic_z0 = ibooker.book1D("z0Efficiency", - "Prompt z0 efficiency", - numerator->GetNbinsX(), - numerator->GetXaxis()->GetXmin(), - numerator->GetXaxis()->GetXmax()); - - // Calculate the efficiency - phase2tkutil::makeEfficiencyME(numerator, denominator, me_effic_z0, "Tracking particle z0 [cm]"); - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for extended prompt " - "d0 efficiency cannot be found!\n"; - } - - if (meN_displaced_z0 && meD_displaced_z0) { - // Get the numerator and denominator histograms - TH1F *numerator = meN_displaced_z0->getTH1F(); - TH1F *denominator = meD_displaced_z0->getTH1F(); - numerator->Sumw2(); - denominator->Sumw2(); - - // Set the current directory - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Displaced/FinalEfficiency"); - - // Book the new histogram to contain the results - MonitorElement *me_effic_z0 = ibooker.book1D("z0Efficiency", - "Displaced z0 efficiency", - numerator->GetNbinsX(), - numerator->GetXaxis()->GetXmin(), - numerator->GetXaxis()->GetXmax()); - - // Calculate the efficiency - phase2tkutil::makeEfficiencyME(numerator, denominator, me_effic_z0, "Tracking particle z0 [cm]"); - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for extended displaced z0 efficiency cannot be " - "found!\n"; - } - - // nominal collection +// nominal collection if (std::find(respt_pt2to3.begin(), respt_pt2to3.end(), nullptr) == respt_pt2to3.end()) { // Set the current directoy igetter.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/FinalResolution"); @@ -1266,6 +743,7 @@ void Phase2OTHarvestTracks::dqmEndJob(DQMStore::IBooker &ibooker, DQMStore::IGet } } // end dqmEndJob + #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" #include "FWCore/ParameterSet/interface/ParameterSetDescription.h" void Phase2OTHarvestTracks::fillDescriptions(edm::ConfigurationDescriptions &descriptions) { From 5cdca81e90570bcc42c0afce75080191067a8fc7 Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Thu, 13 Nov 2025 20:23:06 +0100 Subject: [PATCH 03/61] added helper functions for booking histograms --- .../interface/TrackerPhase2HistUtil.h | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h b/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h index fa89b22fa0f62..5fa3baf80d4e6 100644 --- a/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h +++ b/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h @@ -11,11 +11,15 @@ #define Validation_SiTrackerPhase2V_TrackerPhase2HistUtil_h #include +#include +#include +#include "FWCore/ParameterSet/interface/ParameterSet.h" #include "DQMServices/Core/interface/DQMStore.h" #include "TH1.h" namespace phase2tkutil { + inline void makeEfficiencyME(TH1* numerator, TH1* denominator, dqm::legacy::MonitorElement* me, @@ -29,5 +33,44 @@ namespace phase2tkutil { efficiency->GetYaxis()->SetTitle("Efficiency"); } + using ME = dqm::legacy::MonitorElement; + + inline ME* book1DFromPS(DQMStore::IBooker& iBooker, + const std::string& name, + const edm::ParameterSet& ps, + const char* xaxis, + const char* yaxis) { + auto h = iBooker.book1D(name, name, + ps.getParameter("Nbinsx"), + ps.getParameter("xmin"), + ps.getParameter("xmax")); + h->setAxisTitle(xaxis, 1); + h->setAxisTitle(yaxis, 2); + return h; + } + + inline void bookDenNum(DQMStore::IBooker& iBooker, + const std::string& base, + ME*& den, ME*& num, + const edm::ParameterSet& ps, + const char* xaxis, + const char* denY = "# tracking particles", + const char* numY = "# matched tracking particles", + const std::string& denPrefix = "tp_", + const std::string& numPrefix = "match_tp_") { + den = book1DFromPS(iBooker, denPrefix + base, ps, xaxis, denY); + num = book1DFromPS(iBooker, numPrefix + base, ps, xaxis, numY); + } + + inline void bookIntoVec(DQMStore::IBooker& iBooker, + std::vector& vec, + int i, + const std::string& name, + const edm::ParameterSet& ps, + const char* xaxis, + const char* yaxis = "# tracking particles") { + if ((int)vec.size() <= i) vec.resize(i + 1, nullptr); + vec[i] = book1DFromPS(iBooker, name, ps, xaxis, yaxis); + } } // namespace phase2tkutil #endif From 378849faa54e3166a3c8b5cc398075defb4d0b80 Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Thu, 13 Nov 2025 20:24:26 +0100 Subject: [PATCH 04/61] code using DQMGenericClient for Phase2OT track efficiencies --- .../python/Phase2OTEffClient_cff.py | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 Validation/SiTrackerPhase2V/python/Phase2OTEffClient_cff.py diff --git a/Validation/SiTrackerPhase2V/python/Phase2OTEffClient_cff.py b/Validation/SiTrackerPhase2V/python/Phase2OTEffClient_cff.py new file mode 100644 index 0000000000000..d447e10894335 --- /dev/null +++ b/Validation/SiTrackerPhase2V/python/Phase2OTEffClient_cff.py @@ -0,0 +1,49 @@ +import FWCore.ParameterSet.Config as cms + +# Must match your C++ TopFolderName default/value +_topFolder = "TrackerPhase2OTL1TrackV" + +# Keep outputs names unique so we never collide with anything else +# (prefix with "ClientTest_") +phase2OTEffClient = cms.EDProducer( + "DQMGenericClient", + subDirs=cms.untracked.vstring( + f"{_topFolder}/Nominal_L1TF/FinalEfficiency", + f"{_topFolder}/Extended_L1TF/Prompt/FinalEfficiency", + f"{_topFolder}/Extended_L1TF/Displaced/FinalEfficiency", + ), + # Format per entry: + # " '' " + efficiency=cms.vstring( + # Nominal + "EtaEfficiency '#eta efficiency;tracking particle #eta;Efficiency' ../EfficiencyIngredients/match_tp_eta ../EfficiencyIngredients/tp_eta", + "PtEfficiency 'p_{T} efficiency;p_{T} [GeV];Efficiency' ../EfficiencyIngredients/match_tp_pt ../EfficiencyIngredients/tp_pt", + "PtEfficiencyZoom 'p_{T} efficiency;p_{T} [GeV];Efficiency' ../EfficiencyIngredients/match_tp_pt_zoom ../EfficiencyIngredients/tp_pt_zoom", + "d0Efficiency 'd_{0} efficiency;d_{0} [cm];Efficiency' ../EfficiencyIngredients/match_tp_d0 ../EfficiencyIngredients/tp_d0", + "LxyEfficiency 'L_{xy} efficiency;L_{xy} [cm];Efficiency' ../EfficiencyIngredients/match_tp_Lxy ../EfficiencyIngredients/tp_Lxy", + "z0Efficiency 'z_{0} efficiency;z_{0} [cm];Efficiency' ../EfficiencyIngredients/match_tp_z0 ../EfficiencyIngredients/tp_z0", + + # Prompt (Extended) + # (denominators are nominal tp_*) + "EtaEfficiency '#eta efficiency;tracking particle #eta;Efficiency' ../EfficiencyIngredients/match_prompt_tp_eta ../EfficiencyIngredients/tp_eta", + "PtEfficiency 'p_{T} efficiency;p_{T} [GeV];Efficiency' ../EfficiencyIngredients/match_prompt_tp_pt ../EfficiencyIngredients/tp_pt", + "PtEfficiencyZoom 'p_{T} efficiency;p_{T} [GeV];Efficiency' ../EfficiencyIngredients/match_prompt_tp_pt_zoom ../EfficiencyIngredients/tp_pt_zoom", + "d0Efficiency 'd_{0} efficiency;d_{0} [cm];Efficiency' ../EfficiencyIngredients/match_prompt_tp_d0 ../EfficiencyIngredients/tp_d0", + "LxyEfficiency 'L_{xy} efficiency;L_{xy} [cm];Efficiency' ../EfficiencyIngredients/match_prompt_tp_Lxy ../EfficiencyIngredients/tp_Lxy", + "z0Efficiency 'z_{0} efficiency;z_{0} [cm];Efficiency' ../EfficiencyIngredients/match_prompt_tp_z0 ../EfficiencyIngredients/tp_z0", + + # Displaced + "EtaEfficiency '#eta efficiency;tracking particle #eta;Efficiency' ../EfficiencyIngredients/match_displaced_tp_eta ../EfficiencyIngredients/tp_eta_for_dis", + "PtEfficiency 'p_{T} efficiency;p_{T} [GeV];Efficiency' ../EfficiencyIngredients/match_displaced_tp_pt ../EfficiencyIngredients/tp_pt_for_dis", + "PtEfficiencyZoom 'p_{T} efficiency;p_{T} [GeV];Efficiency' ../EfficiencyIngredients/match_displaced_tp_pt_zoom ../EfficiencyIngredients/tp_pt_zoom_for_dis", + "d0Efficiency 'd_{0} efficiency;d_{0} [cm];Efficiency' ../EfficiencyIngredients/match_displaced_tp_d0 ../EfficiencyIngredients/tp_d0_for_dis", + "LxyEfficiency 'L_{xy} efficiency;L_{xy} [cm];Efficiency' ../EfficiencyIngredients/match_displaced_tp_Lxy ../EfficiencyIngredients/tp_Lxy_for_dis", + "z0Efficiency 'z_{0} efficiency;z_{0} [cm];Efficiency' ../EfficiencyIngredients/match_displaced_tp_z0 ../EfficiencyIngredients/tp_z0_for_dis", + ), + resolution=cms.vstring(), + efficiencyProfile=cms.untracked.vstring(), + verbose=cms.untracked.uint32(0) +) + +# Expose as a Sequence so you can append with one line +phase2OTEffClientSeq = cms.Sequence(phase2OTEffClient) \ No newline at end of file From 405d956d6006f61a2acf484090e9bb1c8d6a9a35 Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Thu, 13 Nov 2025 20:25:17 +0100 Subject: [PATCH 05/61] reduced many lines of code by use of helper functions --- .../plugins/Phase2OTValidateTracks.cc | 722 ++---------------- 1 file changed, 77 insertions(+), 645 deletions(-) diff --git a/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateTracks.cc b/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateTracks.cc index 2b2477f66e028..34a6af2839caf 100644 --- a/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateTracks.cc +++ b/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateTracks.cc @@ -55,6 +55,7 @@ #include "SimDataFormats/Associations/interface/TTStubAssociationMap.h" #include "SimDataFormats/Associations/interface/TTTrackAssociationMap.h" #include "SimDataFormats/TrackingAnalysis/interface/TrackingParticle.h" +#include "Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h" #include "Validation/SiTrackerPhase2V/interface/TrackerPhase2ValidationUtil.h" class Phase2OTValidateTracks : public DQMEDAnalyzer { @@ -212,7 +213,6 @@ Phase2OTValidateTracks::Phase2OTValidateTracks(const edm::ParameterSet &iConfig) // particle TP_minNLayersStub = conf_.getParameter("TP_minNLayersStub"); // Minimum number of layers with stubs for the // tracking particle to be considered for matching - TP_minNLayersStub = conf_.getParameter("TP_minNLayersStub"); TP_minPt = conf_.getParameter("TP_minPt"); // min pT to consider matching TP_maxEta = conf_.getParameter("TP_maxEta"); // max eta to consider matching TP_maxZ0 = conf_.getParameter("TP_maxZ0"); // max vertZ (or z0) to consider matching @@ -644,669 +644,101 @@ void Phase2OTValidateTracks::bookHistograms(DQMStore::IBooker &iBooker, edm::ParameterSet psRes_z0 = conf_.getParameter("TH1Res_z0"); edm::ParameterSet psRes_d0 = conf_.getParameter("TH1Res_d0"); edm::ParameterSet psRes_displaced_d0 = conf_.getParameter("TH1Resdisplaced_d0"); + + static const std::string ranges[6] = {"eta0to0p7", "eta0p7to1", "eta1to1p2", "eta1p2to1p6", "eta1p6to2", "eta2to2p4"}; + using namespace phase2tkutil; + // Histogram setup and definitions - std::string HistoName; + // ================== trackParticles (sample) ================== iBooker.setCurrentFolder(topFolderName_ + "/trackParticles"); + trackParts_Pt = book1DFromPS(iBooker, "trackParts_Pt", psTrackParts_Pt, "p_{T} [GeV]", "# tracking particles"); + trackParts_Eta = book1DFromPS(iBooker, "trackParts_Eta", psTrackParts_Eta, "#eta", "# tracking particles"); + trackParts_Phi = book1DFromPS(iBooker, "trackParts_Phi", psTrackParts_Phi, "#phi", "# tracking particles"); - // 1D: pT - HistoName = "trackParts_Pt"; - trackParts_Pt = iBooker.book1D(HistoName, - HistoName, - psTrackParts_Pt.getParameter("Nbinsx"), - psTrackParts_Pt.getParameter("xmin"), - psTrackParts_Pt.getParameter("xmax")); - trackParts_Pt->setAxisTitle("p_{T} [GeV]", 1); - trackParts_Pt->setAxisTitle("# tracking particles", 2); - - // 1D: eta - HistoName = "trackParts_Eta"; - trackParts_Eta = iBooker.book1D(HistoName, - HistoName, - psTrackParts_Eta.getParameter("Nbinsx"), - psTrackParts_Eta.getParameter("xmin"), - psTrackParts_Eta.getParameter("xmax")); - trackParts_Eta->setAxisTitle("#eta", 1); - trackParts_Eta->setAxisTitle("# tracking particles", 2); - - // 1D: phi - HistoName = "trackParts_Phi"; - trackParts_Phi = iBooker.book1D(HistoName, - HistoName, - psTrackParts_Phi.getParameter("Nbinsx"), - psTrackParts_Phi.getParameter("xmin"), - psTrackParts_Phi.getParameter("xmax")); - trackParts_Phi->setAxisTitle("#phi", 1); - trackParts_Phi->setAxisTitle("# tracking particles", 2); - - // 1D plots for nominal collection efficiency - iBooker.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/EfficiencyIngredients"); - // pT - HistoName = "tp_pt"; - tp_pt = iBooker.book1D(HistoName, - HistoName, - psEffic_pt.getParameter("Nbinsx"), - psEffic_pt.getParameter("xmin"), - psEffic_pt.getParameter("xmax")); - tp_pt->setAxisTitle("p_{T} [GeV]", 1); - tp_pt->setAxisTitle("# tracking particles", 2); - - // Matched TP's pT - HistoName = "match_tp_pt"; - match_tp_pt = iBooker.book1D(HistoName, - HistoName, - psEffic_pt.getParameter("Nbinsx"), - psEffic_pt.getParameter("xmin"), - psEffic_pt.getParameter("xmax")); - match_tp_pt->setAxisTitle("p_{T} [GeV]", 1); - match_tp_pt->setAxisTitle("# matched tracking particles", 2); - - // pT zoom (0-10 GeV) - HistoName = "tp_pt_zoom"; - tp_pt_zoom = iBooker.book1D(HistoName, - HistoName, - psEffic_pt_zoom.getParameter("Nbinsx"), - psEffic_pt_zoom.getParameter("xmin"), - psEffic_pt_zoom.getParameter("xmax")); - tp_pt_zoom->setAxisTitle("p_{T} [GeV]", 1); - tp_pt_zoom->setAxisTitle("# tracking particles", 2); - - // Matched pT zoom (0-10 GeV) - HistoName = "match_tp_pt_zoom"; - match_tp_pt_zoom = iBooker.book1D(HistoName, - HistoName, - psEffic_pt_zoom.getParameter("Nbinsx"), - psEffic_pt_zoom.getParameter("xmin"), - psEffic_pt_zoom.getParameter("xmax")); - match_tp_pt_zoom->setAxisTitle("p_{T} [GeV]", 1); - match_tp_pt_zoom->setAxisTitle("# matched tracking particles", 2); - - // eta - HistoName = "tp_eta"; - tp_eta = iBooker.book1D(HistoName, - HistoName, - psEffic_eta.getParameter("Nbinsx"), - psEffic_eta.getParameter("xmin"), - psEffic_eta.getParameter("xmax")); - tp_eta->setAxisTitle("#eta", 1); - tp_eta->setAxisTitle("# tracking particles", 2); - - // Matched eta - HistoName = "match_tp_eta"; - match_tp_eta = iBooker.book1D(HistoName, - HistoName, - psEffic_eta.getParameter("Nbinsx"), - psEffic_eta.getParameter("xmin"), - psEffic_eta.getParameter("xmax")); - match_tp_eta->setAxisTitle("#eta", 1); - match_tp_eta->setAxisTitle("# matched tracking particles", 2); - - // d0 - HistoName = "tp_d0"; - tp_d0 = iBooker.book1D(HistoName, - HistoName, - psEffic_d0.getParameter("Nbinsx"), - psEffic_d0.getParameter("xmin"), - psEffic_d0.getParameter("xmax")); - tp_d0->setAxisTitle("d_{0} [cm]", 1); - tp_d0->setAxisTitle("# tracking particles", 2); - - // Matched d0 - HistoName = "match_tp_d0"; - match_tp_d0 = iBooker.book1D(HistoName, - HistoName, - psEffic_d0.getParameter("Nbinsx"), - psEffic_d0.getParameter("xmin"), - psEffic_d0.getParameter("xmax")); - match_tp_d0->setAxisTitle("d_{0} [cm]", 1); - match_tp_d0->setAxisTitle("# matched tracking particles", 2); - - // Lxy (also known as vxy) - HistoName = "tp_Lxy"; - tp_Lxy = iBooker.book1D(HistoName, - HistoName, - psEffic_Lxy.getParameter("Nbinsx"), - psEffic_Lxy.getParameter("xmin"), - psEffic_Lxy.getParameter("xmax")); - tp_Lxy->setAxisTitle("L_{xy} [cm]", 1); - tp_Lxy->setAxisTitle("# tracking particles", 2); - - // Matched Lxy - HistoName = "match_tp_Lxy"; - match_tp_Lxy = iBooker.book1D(HistoName, - HistoName, - psEffic_Lxy.getParameter("Nbinsx"), - psEffic_Lxy.getParameter("xmin"), - psEffic_Lxy.getParameter("xmax")); - match_tp_Lxy->setAxisTitle("L_{xy} [cm]", 1); - match_tp_Lxy->setAxisTitle("# matched tracking particles", 2); - - // z0 - HistoName = "tp_z0"; - tp_z0 = iBooker.book1D(HistoName, - HistoName, - psEffic_z0.getParameter("Nbinsx"), - psEffic_z0.getParameter("xmin"), - psEffic_z0.getParameter("xmax")); - tp_z0->setAxisTitle("z_{0} [cm]", 1); - tp_z0->setAxisTitle("# tracking particles", 2); - - // Matched d0 - HistoName = "match_tp_z0"; - match_tp_z0 = iBooker.book1D(HistoName, - HistoName, - psEffic_z0.getParameter("Nbinsx"), - psEffic_z0.getParameter("xmin"), - psEffic_z0.getParameter("xmax")); - match_tp_z0->setAxisTitle("z_{0} [cm]", 1); - match_tp_z0->setAxisTitle("# matched tracking particles", 2); - - // 1D plots for residual + // ================== Nominal_L1TF / Residual ================== iBooker.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/Residual"); - // full pT - HistoName = "res_pt"; - res_pt = iBooker.book1D(HistoName, - HistoName, - psRes_pt.getParameter("Nbinsx"), - psRes_pt.getParameter("xmin"), - psRes_pt.getParameter("xmax")); - res_pt->setAxisTitle("p_{T} [GeV]", 1); - res_pt->setAxisTitle("# tracking particles", 2); - - // Full eta - HistoName = "res_eta"; - res_eta = iBooker.book1D(HistoName, - HistoName, - psRes_eta.getParameter("Nbinsx"), - psRes_eta.getParameter("xmin"), - psRes_eta.getParameter("xmax")); - res_eta->setAxisTitle("#eta", 1); - res_eta->setAxisTitle("# tracking particles", 2); - - // Relative pT - HistoName = "res_ptRel"; - res_ptRel = iBooker.book1D(HistoName, - HistoName, - psRes_ptRel.getParameter("Nbinsx"), - psRes_ptRel.getParameter("xmin"), - psRes_ptRel.getParameter("xmax")); - res_ptRel->setAxisTitle("Relative p_{T} [GeV]", 1); - res_ptRel->setAxisTitle("# tracking particles", 2); - - HistoName = "res_d0"; - d0_res_hist = iBooker.book1D(HistoName, - HistoName, - psRes_d0.getParameter("Nbinsx"), - psRes_d0.getParameter("xmin"), - psRes_d0.getParameter("xmax")); - d0_res_hist->setAxisTitle("trk d_{0} - tp d_{0} [cm]", 1); - d0_res_hist->setAxisTitle("# tracking particles", 2); + res_pt = book1DFromPS(iBooker, "res_pt", psRes_pt, "p_{T} [GeV]", "# tracking particles"); + res_eta = book1DFromPS(iBooker, "res_eta", psRes_eta, "#eta", "# tracking particles"); + res_ptRel = book1DFromPS(iBooker, "res_ptRel", psRes_ptRel, "Relative p_{T} [GeV]", "# tracking particles"); + d0_res_hist = book1DFromPS(iBooker, "res_d0", psRes_d0, "trk d_{0} - tp d_{0} [cm]","# tracking particles"); + // ===== Nominal_L1TF / ResolutionIngredients (eta-sliced) ===== iBooker.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/ResolutionIngredients"); - std::string ranges[6] = {"eta0to0p7", "eta0p7to1", "eta1to1p2", "eta1p2to1p6", "eta1p6to2", "eta2to2p4"}; - for (int i = 0; i < 6; i++) { - // Eta parts (for resolution) - HistoName = "reseta_" + ranges[i]; - reseta_vect[i] = iBooker.book1D(HistoName, - HistoName, - psRes_eta.getParameter("Nbinsx"), - psRes_eta.getParameter("xmin"), - psRes_eta.getParameter("xmax")); - reseta_vect[i]->setAxisTitle("#eta_{trk} - #eta_{tp}", 1); - reseta_vect[i]->setAxisTitle("# tracking particles", 2); - - // pT parts for resolution (pT res vs eta) - // pT a (2 to 3 GeV) - HistoName = "respt_" + ranges[i] + "_pt2to3"; - respt_pt2to3[i] = iBooker.book1D(HistoName, - HistoName, - psRes_pt.getParameter("Nbinsx"), - psRes_pt.getParameter("xmin"), - psRes_pt.getParameter("xmax")); - respt_pt2to3[i]->setAxisTitle("(p_{T}(trk) - p_{T}(tp))/p_{T}(tp)", 1); - respt_pt2to3[i]->setAxisTitle("# tracking particles", 2); - - // pT b (3 to 8 GeV) - HistoName = "respt_" + ranges[i] + "_pt3to8"; - respt_pt3to8[i] = iBooker.book1D(HistoName, - HistoName, - psRes_pt.getParameter("Nbinsx"), - psRes_pt.getParameter("xmin"), - psRes_pt.getParameter("xmax")); - respt_pt3to8[i]->setAxisTitle("(p_{T}(trk) - p_{T}(tp))/p_{T}(tp)", 1); - respt_pt3to8[i]->setAxisTitle("# tracking particles", 2); - - // pT c (>8 GeV) - HistoName = "respt_" + ranges[i] + "_pt8toInf"; - respt_pt8toInf[i] = iBooker.book1D(HistoName, - HistoName, - psRes_pt.getParameter("Nbinsx"), - psRes_pt.getParameter("xmin"), - psRes_pt.getParameter("xmax")); - respt_pt8toInf[i]->setAxisTitle("(p_{T}(trk) - p_{T}(tp))/p_{T}(tp)", 1); - respt_pt8toInf[i]->setAxisTitle("# tracking particles", 2); - - // Phi parts (for resolution) - HistoName = "resphi_" + ranges[i]; - resphi_vect[i] = iBooker.book1D(HistoName, - HistoName, - psRes_phi.getParameter("Nbinsx"), - psRes_phi.getParameter("xmin"), - psRes_phi.getParameter("xmax")); - resphi_vect[i]->setAxisTitle("#phi_{trk} - #phi_{tp}", 1); - resphi_vect[i]->setAxisTitle("# tracking particles", 2); - - // z0 parts (for resolution) - HistoName = "resz0_" + ranges[i]; - resz0_vect[i] = iBooker.book1D(HistoName, - HistoName, - psRes_z0.getParameter("Nbinsx"), - psRes_z0.getParameter("xmin"), - psRes_z0.getParameter("xmax")); - resz0_vect[i]->setAxisTitle("z0_{trk} - z0_{tp} [cm]", 1); - resz0_vect[i]->setAxisTitle("# tracking particles", 2); - - // d0 parts (for resolution) - HistoName = "resd0_" + ranges[i]; - resd0_vect[i] = iBooker.book1D(HistoName, - HistoName, - psRes_d0.getParameter("Nbinsx"), - psRes_d0.getParameter("xmin"), - psRes_d0.getParameter("xmax")); - resd0_vect[i]->setAxisTitle("d0_{trk} - d0_{tp} [cm]", 1); - resd0_vect[i]->setAxisTitle("# tracking particles", 2); + for (int i = 0; i < 6; ++i) { + bookIntoVec(iBooker, reseta_vect, i, "reseta_" + ranges[i], psRes_eta, "#eta_{trk} - #eta_{tp}"); + bookIntoVec(iBooker, resphi_vect, i, "resphi_" + ranges[i], psRes_phi, "#phi_{trk} - #phi_{tp}"); + bookIntoVec(iBooker, resz0_vect, i, "resz0_" + ranges[i], psRes_z0, "z0_{trk} - z0_{tp} [cm]"); + bookIntoVec(iBooker, resd0_vect, i, "resd0_" + ranges[i], psRes_d0, "d0_{trk} - d0_{tp} [cm]"); + + respt_pt2to3[i] = book1DFromPS(iBooker, "respt_" + ranges[i] + "_pt2to3", psRes_pt, " (p_{T}(trk) - p_{T}(tp))/p_{T}(tp)", "# tracking particles"); + respt_pt3to8[i] = book1DFromPS(iBooker, "respt_" + ranges[i] + "_pt3to8", psRes_pt, " (p_{T}(trk) - p_{T}(tp))/p_{T}(tp)", "# tracking particles"); + respt_pt8toInf[i] = book1DFromPS(iBooker,"respt_" + ranges[i] + "_pt8toInf",psRes_pt, " (p_{T}(trk) - p_{T}(tp))/p_{T}(tp)", "# tracking particles"); } + // =========== Extended_L1TF / Displaced / Efficiency =========== iBooker.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Displaced/EfficiencyIngredients"); - // tp pt for denom for displaced tracks - HistoName = "tp_pt_for_dis"; - tp_pt_for_dis = iBooker.book1D(HistoName, - HistoName, - psEffic_pt.getParameter("Nbinsx"), - psEffic_pt.getParameter("xmin"), - psEffic_pt.getParameter("xmax")); - tp_pt_for_dis->setAxisTitle("p_{T} [GeV]", 1); - tp_pt_for_dis->setAxisTitle("# tracking particles", 2); - - // Matched Extended TP's pt - HistoName = "match_displaced_tp_pt"; - match_displaced_tp_pt = iBooker.book1D(HistoName, - HistoName, - psEffic_pt.getParameter("Nbinsx"), - psEffic_pt.getParameter("xmin"), - psEffic_pt.getParameter("xmax")); - match_displaced_tp_pt->setAxisTitle("p_{T} [GeV]", 1); - match_displaced_tp_pt->setAxisTitle("# matched extended tracking particles", 2); - - // Zoom version - HistoName = "tp_pt_zoom_for_dis"; - tp_pt_zoom_for_dis = iBooker.book1D(HistoName, - HistoName, - psEffic_pt_zoom.getParameter("Nbinsx"), - psEffic_pt_zoom.getParameter("xmin"), - psEffic_pt_zoom.getParameter("xmax")); - tp_pt_zoom_for_dis->setAxisTitle("p_{T} [GeV]", 1); - tp_pt_zoom_for_dis->setAxisTitle("# tracking particles", 2); - - // Zoom version - HistoName = "match_displaced_tp_pt_zoom"; - match_displaced_tp_pt_zoom = iBooker.book1D(HistoName, - HistoName, - psEffic_pt_zoom.getParameter("Nbinsx"), - psEffic_pt_zoom.getParameter("xmin"), - psEffic_pt_zoom.getParameter("xmax")); - match_displaced_tp_pt_zoom->setAxisTitle("p_{T} [GeV]", 1); - match_displaced_tp_pt_zoom->setAxisTitle("# matched extended tracking particles", 2); - - // TP's eta for denom for displaced tracks - HistoName = "tp_eta_for_dis"; - tp_eta_for_dis = iBooker.book1D(HistoName, - HistoName, - psEffic_eta.getParameter("Nbinsx"), - psEffic_eta.getParameter("xmin"), - psEffic_eta.getParameter("xmax")); - tp_eta_for_dis->setAxisTitle("#eta", 1); - tp_eta_for_dis->setAxisTitle("# tracking particles", 2); - - // Matched Extended TP's eta - HistoName = "match_displaced_tp_eta"; - match_displaced_tp_eta = iBooker.book1D(HistoName, - HistoName, - psEffic_eta.getParameter("Nbinsx"), - psEffic_eta.getParameter("xmin"), - psEffic_eta.getParameter("xmax")); - match_displaced_tp_eta->setAxisTitle("#eta", 1); - match_displaced_tp_eta->setAxisTitle("# matched extended tracking particles", 2); - - // TP's d0 for denom for displaced tracks - HistoName = "tp_d0_for_dis"; - tp_d0_for_dis = iBooker.book1D(HistoName, - HistoName, - psDisEffic_d0.getParameter("Nbinsx"), - psDisEffic_d0.getParameter("xmin"), - psDisEffic_d0.getParameter("xmax")); - tp_d0_for_dis->setAxisTitle("d_{0} [cm]", 1); - tp_d0_for_dis->setAxisTitle("# tracking particles", 2); - - // Matched Extended TP's d0 - HistoName = "match_displaced_tp_d0"; - match_displaced_tp_d0 = iBooker.book1D(HistoName, - HistoName, - psDisEffic_d0.getParameter("Nbinsx"), - psDisEffic_d0.getParameter("xmin"), - psDisEffic_d0.getParameter("xmax")); - match_displaced_tp_d0->setAxisTitle("d_{0} [cm]", 1); - match_displaced_tp_d0->setAxisTitle("# matched extended tracking particles", 2); - - // Matched Extended TP's Lxy - HistoName = "match_displaced_tp_Lxy"; - match_displaced_tp_Lxy = iBooker.book1D(HistoName, - HistoName, - psEffic_Lxy.getParameter("Nbinsx"), - psEffic_Lxy.getParameter("xmin"), - psEffic_Lxy.getParameter("xmax")); - match_displaced_tp_Lxy->setAxisTitle("L_{xy} [cm]", 1); - match_displaced_tp_Lxy->setAxisTitle("# matched extended tracking particles", 2); - - // TP's z0 for denom for displaced tracks - HistoName = "tp_z0_for_dis"; - tp_z0_for_dis = iBooker.book1D(HistoName, - HistoName, - psEffic_z0.getParameter("Nbinsx"), - psEffic_z0.getParameter("xmin"), - psEffic_z0.getParameter("xmax")); - tp_z0_for_dis->setAxisTitle("z_{0} [cm]", 1); - tp_z0_for_dis->setAxisTitle("# tracking particles", 2); - - // Matched Extended TP's z0 - HistoName = "match_displaced_tp_z0"; - match_displaced_tp_z0 = iBooker.book1D(HistoName, - HistoName, - psEffic_z0.getParameter("Nbinsx"), - psEffic_z0.getParameter("xmin"), - psEffic_z0.getParameter("xmax")); - match_displaced_tp_z0->setAxisTitle("z_{0} [cm]", 1); - match_displaced_tp_z0->setAxisTitle("# matched extended tracking particles", 2); - + tp_pt_for_dis = book1DFromPS(iBooker, "tp_pt_for_dis", psEffic_pt, "p_{T} [GeV]", "# tracking particles"); + tp_pt_zoom_for_dis = book1DFromPS(iBooker, "tp_pt_zoom_for_dis", psEffic_pt_zoom, "p_{T} [GeV]", "# tracking particles"); + tp_eta_for_dis = book1DFromPS(iBooker, "tp_eta_for_dis", psEffic_eta, "#eta", "# tracking particles"); + tp_d0_for_dis = book1DFromPS(iBooker, "tp_d0_for_dis", psDisEffic_d0, "d_{0} [cm]", "# tracking particles"); + tp_z0_for_dis = book1DFromPS(iBooker, "tp_z0_for_dis", psEffic_z0, "z_{0} [cm]", "# tracking particles"); + + match_displaced_tp_pt = book1DFromPS(iBooker, "match_displaced_tp_pt", psEffic_pt, "p_{T} [GeV]", "# matched extended tracking particles"); + match_displaced_tp_pt_zoom = book1DFromPS(iBooker, "match_displaced_tp_pt_zoom", psEffic_pt_zoom, "p_{T} [GeV]", "# matched extended tracking particles"); + match_displaced_tp_eta = book1DFromPS(iBooker, "match_displaced_tp_eta", psEffic_eta, "#eta", "# matched extended tracking particles"); + match_displaced_tp_d0 = book1DFromPS(iBooker, "match_displaced_tp_d0", psDisEffic_d0, "d_{0} [cm]", "# matched extended tracking particles"); + match_displaced_tp_Lxy = book1DFromPS(iBooker, "match_displaced_tp_Lxy", psEffic_Lxy, "L_{xy} [cm]", "# matched extended tracking particles"); + match_displaced_tp_z0 = book1DFromPS(iBooker, "match_displaced_tp_z0", psEffic_z0, "z_{0} [cm]", "# matched extended tracking particles"); + + // =========== Extended_L1TF / Displaced / Residual =========== iBooker.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Displaced/Residual"); + res_displaced_d0 = book1DFromPS(iBooker, "res_displaced_d0", psRes_displaced_d0, "trk d_{0} - tp d_{0} [cm]", "# displaced tracks"); + res_displaced_eta = book1DFromPS(iBooker, "res_displaced_eta", psRes_eta, "#eta_{trk} - #eta_{tp}", "# tracking particles"); + res_displaced_pt = book1DFromPS(iBooker, "res_displaced_pt", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); + res_displaced_ptRel = book1DFromPS(iBooker, "res_displaced_ptRel", psRes_ptRel, "Relative p_{T} [GeV]", "# tracking particles"); - HistoName = "res_displaced_d0"; - res_displaced_d0 = iBooker.book1D(HistoName, - HistoName, - psRes_displaced_d0.getParameter("Nbinsx"), - psRes_displaced_d0.getParameter("xmin"), - psRes_displaced_d0.getParameter("xmax")); - res_displaced_d0->setAxisTitle("trk d_{0} - tp d_{0} [cm]", 1); - res_displaced_d0->setAxisTitle("# displaced tracks", 2); - - HistoName = "res_displaced_eta"; - res_displaced_eta = iBooker.book1D(HistoName, - HistoName, - psRes_eta.getParameter("Nbinsx"), - psRes_eta.getParameter("xmin"), - psRes_eta.getParameter("xmax")); - res_displaced_eta->setAxisTitle("#eta_{trk} - #eta_{tp}", 1); - res_displaced_eta->setAxisTitle("# tracking particles", 2); - - HistoName = "res_displaced_pt"; - res_displaced_pt = iBooker.book1D(HistoName, - HistoName, - psRes_pt.getParameter("Nbinsx"), - psRes_pt.getParameter("xmin"), - psRes_pt.getParameter("xmax")); - res_displaced_pt->setAxisTitle("p_{T}(trk)-p_{T}(tp)", 1); - res_displaced_pt->setAxisTitle("# tracking particles", 2); - - HistoName = "res_displaced_ptRel"; - res_displaced_ptRel = iBooker.book1D(HistoName, - HistoName, - psRes_ptRel.getParameter("Nbinsx"), - psRes_ptRel.getParameter("xmin"), - psRes_ptRel.getParameter("xmax")); - res_displaced_ptRel->setAxisTitle("Relative p_{T} [GeV]", 1); - res_displaced_ptRel->setAxisTitle("# tracking particles", 2); - + // ===== Extended_L1TF / Displaced / ResolutionIngredients ===== iBooker.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Displaced/ResolutionIngredients"); - - for (int i = 0; i < 6; i++) { - // reseta_displaced_vect[i] - HistoName = "reseta_displaced_" + ranges[i]; - reseta_displaced_vect[i] = iBooker.book1D(HistoName, - HistoName, - psRes_eta.getParameter("Nbinsx"), - psRes_eta.getParameter("xmin"), - psRes_eta.getParameter("xmax")); - reseta_displaced_vect[i]->setAxisTitle("#eta_{trk} - #eta_{tp}", 1); - reseta_displaced_vect[i]->setAxisTitle("# tracking particles", 2); - - // resphi_displaced_vect[i] - HistoName = "resphi_displaced_" + ranges[i]; - resphi_displaced_vect[i] = iBooker.book1D(HistoName, - HistoName, - psRes_phi.getParameter("Nbinsx"), - psRes_phi.getParameter("xmin"), - psRes_phi.getParameter("xmax")); - resphi_displaced_vect[i]->setAxisTitle("#phi_{trk} - #phi_{tp}", 1); - resphi_displaced_vect[i]->setAxisTitle("# tracking particles", 2); - - // resd0_displaced_vect[i] - HistoName = "resd0_displaced_" + ranges[i]; - resd0_displaced_vect[i] = iBooker.book1D(HistoName, - HistoName, - psRes_displaced_d0.getParameter("Nbinsx"), - psRes_displaced_d0.getParameter("xmin"), - psRes_displaced_d0.getParameter("xmax")); - resd0_displaced_vect[i]->setAxisTitle("d0_{trk} - d0_{tp} [cm]", 1); - resd0_displaced_vect[i]->setAxisTitle("# tracking particles", 2); - - HistoName = "resz0_displaced_" + ranges[i]; - resz0_displaced_vect[i] = iBooker.book1D(HistoName, - HistoName, - psRes_z0.getParameter("Nbinsx"), - psRes_z0.getParameter("xmin"), - psRes_z0.getParameter("xmax")); - resz0_displaced_vect[i]->setAxisTitle("z0_{trk} - z0_{tp} [cm]", 1); - resz0_displaced_vect[i]->setAxisTitle("# tracking particles", 2); - - // pT resolution in bins (2‐3, 3‐8, >8 GeV) - HistoName = "respt_displaced_" + ranges[i] + "_pt2to3"; - respt_displaced_pt2to3[i] = iBooker.book1D(HistoName, - HistoName, - psRes_pt.getParameter("Nbinsx"), - psRes_pt.getParameter("xmin"), - psRes_pt.getParameter("xmax")); - respt_displaced_pt2to3[i]->setAxisTitle("p_{T}(trk)-p_{T}(tp)", 1); - respt_displaced_pt2to3[i]->setAxisTitle("# tracking particles", 2); - - HistoName = "respt_displaced_" + ranges[i] + "_pt3to8"; - respt_displaced_pt3to8[i] = iBooker.book1D(HistoName, - HistoName, - psRes_pt.getParameter("Nbinsx"), - psRes_pt.getParameter("xmin"), - psRes_pt.getParameter("xmax")); - respt_displaced_pt3to8[i]->setAxisTitle("p_{T}(trk)-p_{T}(tp)", 1); - respt_displaced_pt3to8[i]->setAxisTitle("# tracking particles", 2); - - HistoName = "respt_displaced_" + ranges[i] + "_pt8toInf"; - respt_displaced_pt8toInf[i] = iBooker.book1D(HistoName, - HistoName, - psRes_pt.getParameter("Nbinsx"), - psRes_pt.getParameter("xmin"), - psRes_pt.getParameter("xmax")); - respt_displaced_pt8toInf[i]->setAxisTitle("p_{T}(trk)-p_{T}(tp)", 1); - respt_displaced_pt8toInf[i]->setAxisTitle("# tracking particles", 2); + for (int i = 0; i < 6; ++i) { + bookIntoVec(iBooker, reseta_displaced_vect, i, "reseta_displaced_" + ranges[i], psRes_eta, "#eta_{trk} - #eta_{tp}"); + bookIntoVec(iBooker, resphi_displaced_vect, i, "resphi_displaced_" + ranges[i], psRes_phi, "#phi_{trk} - #phi_{tp}"); + // displaced d0 uses displaced-d0 PSet + bookIntoVec(iBooker, resd0_displaced_vect, i, "resd0_displaced_" + ranges[i], psRes_displaced_d0, "d0_{trk} - d0_{tp} [cm]"); + bookIntoVec(iBooker, resz0_displaced_vect, i, "resz0_displaced_" + ranges[i], psRes_z0, "z0_{trk} - z0_{tp} [cm]"); + + respt_displaced_pt2to3[i] = book1DFromPS(iBooker, "respt_displaced_" + ranges[i] + "_pt2to3", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); + respt_displaced_pt3to8[i] = book1DFromPS(iBooker, "respt_displaced_" + ranges[i] + "_pt3to8", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); + respt_displaced_pt8toInf[i] = book1DFromPS(iBooker,"respt_displaced_" + ranges[i] + "_pt8toInf",psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); } + // =========== Extended_L1TF / Prompt / Efficiency =========== iBooker.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Prompt/EfficiencyIngredients"); - - // Matched prompt TPs that come from the extended collection - HistoName = "match_prompt_tp_pt"; - match_prompt_tp_pt = iBooker.book1D(HistoName, - HistoName, - psEffic_pt.getParameter("Nbinsx"), - psEffic_pt.getParameter("xmin"), - psEffic_pt.getParameter("xmax")); - match_prompt_tp_pt->setAxisTitle("p_{T} [GeV]", 1); - match_prompt_tp_pt->setAxisTitle("# matched tracking particles", 2); - - // Zoom version - HistoName = "match_prompt_tp_pt_zoom"; - match_prompt_tp_pt_zoom = iBooker.book1D(HistoName, - HistoName, - psEffic_pt_zoom.getParameter("Nbinsx"), - psEffic_pt_zoom.getParameter("xmin"), - psEffic_pt_zoom.getParameter("xmax")); - match_prompt_tp_pt_zoom->setAxisTitle("p_{T} [GeV]", 1); - match_prompt_tp_pt_zoom->setAxisTitle("# matched tracking particles", 2); - - // Matched Extended TP's eta - HistoName = "match_prompt_tp_eta"; - match_prompt_tp_eta = iBooker.book1D(HistoName, - HistoName, - psEffic_eta.getParameter("Nbinsx"), - psEffic_eta.getParameter("xmin"), - psEffic_eta.getParameter("xmax")); - match_prompt_tp_eta->setAxisTitle("#eta", 1); - match_prompt_tp_eta->setAxisTitle("# matched tracking particles", 2); - - // Matched Extended TP's d0 - HistoName = "match_prompt_tp_d0"; - match_prompt_tp_d0 = iBooker.book1D(HistoName, - HistoName, - psEffic_d0.getParameter("Nbinsx"), - psEffic_d0.getParameter("xmin"), - psEffic_d0.getParameter("xmax")); - match_prompt_tp_d0->setAxisTitle("d_{0} [cm]", 1); - match_prompt_tp_d0->setAxisTitle("# matched tracking particles", 2); - - // Matched Extended TP's Lxy - HistoName = "match_prompt_tp_Lxy"; - match_prompt_tp_Lxy = iBooker.book1D(HistoName, - HistoName, - psEffic_Lxy.getParameter("Nbinsx"), - psEffic_Lxy.getParameter("xmin"), - psEffic_Lxy.getParameter("xmax")); - match_prompt_tp_Lxy->setAxisTitle("L_{xy} [cm]", 1); - match_prompt_tp_Lxy->setAxisTitle("# matched tracking particles", 2); - - // Matched Extended TP's z0 - HistoName = "match_prompt_tp_z0"; - match_prompt_tp_z0 = iBooker.book1D(HistoName, - HistoName, - psEffic_z0.getParameter("Nbinsx"), - psEffic_z0.getParameter("xmin"), - psEffic_z0.getParameter("xmax")); - match_prompt_tp_z0->setAxisTitle("z_{0} [cm]", 1); - match_prompt_tp_z0->setAxisTitle("# matched tracking particles", 2); - + match_prompt_tp_pt = book1DFromPS(iBooker, "match_prompt_tp_pt", psEffic_pt, "p_{T} [GeV]", "# matched tracking particles"); + match_prompt_tp_pt_zoom = book1DFromPS(iBooker, "match_prompt_tp_pt_zoom", psEffic_pt_zoom, "p_{T} [GeV]", "# matched tracking particles"); + match_prompt_tp_eta = book1DFromPS(iBooker, "match_prompt_tp_eta", psEffic_eta, "#eta", "# matched tracking particles"); + match_prompt_tp_d0 = book1DFromPS(iBooker, "match_prompt_tp_d0", psEffic_d0, "d_{0} [cm]", "# matched tracking particles"); + match_prompt_tp_Lxy = book1DFromPS(iBooker, "match_prompt_tp_Lxy", psEffic_Lxy, "L_{xy} [cm]", "# matched tracking particles"); + match_prompt_tp_z0 = book1DFromPS(iBooker, "match_prompt_tp_z0", psEffic_z0, "z_{0} [cm]", "# matched tracking particles"); + + // =========== Extended_L1TF / Prompt / Residual =========== iBooker.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Prompt/Residual"); + res_prompt_d0 = book1DFromPS(iBooker, "res_prompt_d0", psRes_d0, "trk d_{0} - tp d_{0} [cm]", "# tracking particles"); + res_prompt_eta = book1DFromPS(iBooker, "res_prompt_eta", psRes_eta, "#eta_{trk} - #eta_{tp}", "# tracking particles"); + res_prompt_pt = book1DFromPS(iBooker, "res_prompt_pt", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); + res_prompt_ptRel = book1DFromPS(iBooker, "res_prompt_ptRel", psRes_ptRel, "Relative p_{T} [GeV]", "# tracking particles"); - HistoName = "res_prompt_d0"; - res_prompt_d0 = iBooker.book1D(HistoName, - HistoName, - psRes_d0.getParameter("Nbinsx"), - psRes_d0.getParameter("xmin"), - psRes_d0.getParameter("xmax")); - res_prompt_d0->setAxisTitle("trk d_{0} - tp d_{0} [cm]", 1); - res_prompt_d0->setAxisTitle("# tracking particles", 2); - - HistoName = "res_prompt_eta"; - res_prompt_eta = iBooker.book1D(HistoName, - HistoName, - psRes_eta.getParameter("Nbinsx"), - psRes_eta.getParameter("xmin"), - psRes_eta.getParameter("xmax")); - res_prompt_eta->setAxisTitle("#eta_{trk} - #eta_{tp}", 1); - res_prompt_eta->setAxisTitle("# tracking particles", 2); - - HistoName = "res_prompt_pt"; - res_prompt_pt = iBooker.book1D(HistoName, - HistoName, - psRes_pt.getParameter("Nbinsx"), - psRes_pt.getParameter("xmin"), - psRes_pt.getParameter("xmax")); - res_prompt_pt->setAxisTitle("p_{T}(trk)-p_{T}(tp)", 1); - res_prompt_pt->setAxisTitle("# tracking particles", 2); - - HistoName = "res_prompt_ptRel"; - res_prompt_ptRel = iBooker.book1D(HistoName, - HistoName, - psRes_ptRel.getParameter("Nbinsx"), - psRes_ptRel.getParameter("xmin"), - psRes_ptRel.getParameter("xmax")); - res_prompt_ptRel->setAxisTitle("Relative p_{T} [GeV]", 1); - res_prompt_ptRel->setAxisTitle("# tracking particles", 2); - + // ===== Extended_L1TF / Prompt / ResolutionIngredients ===== iBooker.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Prompt/ResolutionIngredients"); - - for (int i = 0; i < 6; i++) { - // reseta_prompt_vect[i] - HistoName = "reseta_prompt_" + ranges[i]; - reseta_prompt_vect[i] = iBooker.book1D(HistoName, - HistoName, - psRes_eta.getParameter("Nbinsx"), - psRes_eta.getParameter("xmin"), - psRes_eta.getParameter("xmax")); - reseta_prompt_vect[i]->setAxisTitle("#eta_{trk} - #eta_{tp}", 1); - reseta_prompt_vect[i]->setAxisTitle("# tracking particles", 2); - - // resphi_prompt_vect[i] - HistoName = "resphi_prompt_" + ranges[i]; - resphi_prompt_vect[i] = iBooker.book1D(HistoName, - HistoName, - psRes_phi.getParameter("Nbinsx"), - psRes_phi.getParameter("xmin"), - psRes_phi.getParameter("xmax")); - resphi_prompt_vect[i]->setAxisTitle("#phi_{trk} - #phi_{tp}", 1); - resphi_prompt_vect[i]->setAxisTitle("# tracking particles", 2); - - // resd0_prompt_vect[i] - HistoName = "resd0_prompt_" + ranges[i]; - resd0_prompt_vect[i] = iBooker.book1D(HistoName, - HistoName, - psRes_d0.getParameter("Nbinsx"), - psRes_d0.getParameter("xmin"), - psRes_d0.getParameter("xmax")); - resd0_prompt_vect[i]->setAxisTitle("d0_{trk} - d0_{tp} [cm]", 1); - resd0_prompt_vect[i]->setAxisTitle("# tracking particles", 2); - - HistoName = "resz0_prompt_" + ranges[i]; - resz0_prompt_vect[i] = iBooker.book1D(HistoName, - HistoName, - psRes_z0.getParameter("Nbinsx"), - psRes_z0.getParameter("xmin"), - psRes_z0.getParameter("xmax")); - resz0_prompt_vect[i]->setAxisTitle("z0_{trk} - z0_{tp} [cm]", 1); - resz0_prompt_vect[i]->setAxisTitle("# tracking particles", 2); - - // pT resolution in bins (2‐3, 3‐8, >8 GeV) - HistoName = "respt_prompt_" + ranges[i] + "_pt2to3"; - respt_prompt_pt2to3[i] = iBooker.book1D(HistoName, - HistoName, - psRes_pt.getParameter("Nbinsx"), - psRes_pt.getParameter("xmin"), - psRes_pt.getParameter("xmax")); - respt_prompt_pt2to3[i]->setAxisTitle("p_{T}(trk)-p_{T}(tp)", 1); - respt_prompt_pt2to3[i]->setAxisTitle("# tracking particles", 2); - - HistoName = "respt_prompt_" + ranges[i] + "_pt3to8"; - respt_prompt_pt3to8[i] = iBooker.book1D(HistoName, - HistoName, - psRes_pt.getParameter("Nbinsx"), - psRes_pt.getParameter("xmin"), - psRes_pt.getParameter("xmax")); - respt_prompt_pt3to8[i]->setAxisTitle("p_{T}(trk)-p_{T}(tp)", 1); - respt_prompt_pt3to8[i]->setAxisTitle("# tracking particles", 2); - - HistoName = "respt_prompt_" + ranges[i] + "_pt8toInf"; - respt_prompt_pt8toInf[i] = iBooker.book1D(HistoName, - HistoName, - psRes_pt.getParameter("Nbinsx"), - psRes_pt.getParameter("xmin"), - psRes_pt.getParameter("xmax")); - respt_prompt_pt8toInf[i]->setAxisTitle("p_{T}(trk)-p_{T}(tp)", 1); - respt_prompt_pt8toInf[i]->setAxisTitle("# tracking particles", 2); + for (int i = 0; i < 6; ++i) { + bookIntoVec(iBooker, reseta_prompt_vect, i, "reseta_prompt_" + ranges[i], psRes_eta, "#eta_{trk} - #eta_{tp}"); + bookIntoVec(iBooker, resphi_prompt_vect, i, "resphi_prompt_" + ranges[i], psRes_phi, "#phi_{trk} - #phi_{tp}"); + bookIntoVec(iBooker, resd0_prompt_vect, i, "resd0_prompt_" + ranges[i], psRes_d0, "d0_{trk} - d0_{tp} [cm]"); + bookIntoVec(iBooker, resz0_prompt_vect, i, "resz0_prompt_" + ranges[i], psRes_z0, "z0_{trk} - z0_{tp} [cm]"); + + respt_prompt_pt2to3[i] = book1DFromPS(iBooker, "respt_prompt_" + ranges[i] + "_pt2to3", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); + respt_prompt_pt3to8[i] = book1DFromPS(iBooker, "respt_prompt_" + ranges[i] + "_pt3to8", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); + respt_prompt_pt8toInf[i] = book1DFromPS(iBooker,"respt_prompt_" + ranges[i] + "_pt8toInf",psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); } - } // end of method #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" From 290ca3a77c08466f57c0d6d91b193b265db88de5 Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Fri, 14 Nov 2025 19:36:36 +0100 Subject: [PATCH 06/61] fixed error causing compile issues --- .../interface/TrackerPhase2HistUtil.h | 39 +++++++++++-------- .../plugins/Phase2OTValidateTracks.cc | 9 +++-- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h b/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h index 5fa3baf80d4e6..7da54aef6a96c 100644 --- a/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h +++ b/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h @@ -14,8 +14,9 @@ #include #include -#include "FWCore/ParameterSet/interface/ParameterSet.h" #include "DQMServices/Core/interface/DQMStore.h" +#include "DQMServices/Core/interface/MonitorElement.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" #include "TH1.h" namespace phase2tkutil { @@ -33,13 +34,12 @@ namespace phase2tkutil { efficiency->GetYaxis()->SetTitle("Efficiency"); } - using ME = dqm::legacy::MonitorElement; - - inline ME* book1DFromPS(DQMStore::IBooker& iBooker, - const std::string& name, - const edm::ParameterSet& ps, - const char* xaxis, - const char* yaxis) { + inline dqm::legacy::MonitorElement* book1DFromPS( + dqm::legacy::DQMStore::IBooker& iBooker, + const std::string& name, + const edm::ParameterSet& ps, + const char* xaxis, + const char* yaxis) { auto h = iBooker.book1D(name, name, ps.getParameter("Nbinsx"), ps.getParameter("xmin"), @@ -49,28 +49,35 @@ namespace phase2tkutil { return h; } - inline void bookDenNum(DQMStore::IBooker& iBooker, + template + inline void bookDenNum(dqm::legacy::DQMStore::IBooker& iBooker, const std::string& base, - ME*& den, ME*& num, + Ptr& den, Ptr& num, const edm::ParameterSet& ps, const char* xaxis, const char* denY = "# tracking particles", const char* numY = "# matched tracking particles", const std::string& denPrefix = "tp_", const std::string& numPrefix = "match_tp_") { - den = book1DFromPS(iBooker, denPrefix + base, ps, xaxis, denY); - num = book1DFromPS(iBooker, numPrefix + base, ps, xaxis, numY); + auto* denME = book1DFromPS(iBooker, denPrefix + base, ps, xaxis, denY); + auto* numME = book1DFromPS(iBooker, numPrefix + base, ps, xaxis, numY); + den = denME; + num = numME; } - inline void bookIntoVec(DQMStore::IBooker& iBooker, - std::vector& vec, + template + inline void bookIntoVec(dqm::legacy::DQMStore::IBooker& iBooker, + Vec& vec, int i, const std::string& name, const edm::ParameterSet& ps, const char* xaxis, const char* yaxis = "# tracking particles") { - if ((int)vec.size() <= i) vec.resize(i + 1, nullptr); - vec[i] = book1DFromPS(iBooker, name, ps, xaxis, yaxis); + if ((int)vec.size() <= i) + vec.resize(i + 1, nullptr); + + auto* me = book1DFromPS(iBooker, name, ps, xaxis, yaxis); + vec[i] = me; } } // namespace phase2tkutil #endif diff --git a/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateTracks.cc b/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateTracks.cc index 34a6af2839caf..abe2bbc08779e 100644 --- a/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateTracks.cc +++ b/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateTracks.cc @@ -646,8 +646,10 @@ void Phase2OTValidateTracks::bookHistograms(DQMStore::IBooker &iBooker, edm::ParameterSet psRes_displaced_d0 = conf_.getParameter("TH1Resdisplaced_d0"); static const std::string ranges[6] = {"eta0to0p7", "eta0p7to1", "eta1to1p2", "eta1p2to1p6", "eta1p6to2", "eta2to2p4"}; - using namespace phase2tkutil; - + using phase2tkutil::book1DFromPS; + using phase2tkutil::bookIntoVec; + using phase2tkutil::bookDenNum; + // Histogram setup and definitions // ================== trackParticles (sample) ================== iBooker.setCurrentFolder(topFolderName_ + "/trackParticles"); @@ -702,7 +704,6 @@ void Phase2OTValidateTracks::bookHistograms(DQMStore::IBooker &iBooker, for (int i = 0; i < 6; ++i) { bookIntoVec(iBooker, reseta_displaced_vect, i, "reseta_displaced_" + ranges[i], psRes_eta, "#eta_{trk} - #eta_{tp}"); bookIntoVec(iBooker, resphi_displaced_vect, i, "resphi_displaced_" + ranges[i], psRes_phi, "#phi_{trk} - #phi_{tp}"); - // displaced d0 uses displaced-d0 PSet bookIntoVec(iBooker, resd0_displaced_vect, i, "resd0_displaced_" + ranges[i], psRes_displaced_d0, "d0_{trk} - d0_{tp} [cm]"); bookIntoVec(iBooker, resz0_displaced_vect, i, "resz0_displaced_" + ranges[i], psRes_z0, "z0_{trk} - z0_{tp} [cm]"); @@ -887,4 +888,4 @@ void Phase2OTValidateTracks::fillDescriptions(edm::ConfigurationDescriptions &de // descriptions.addWithDefaultLabel(desc); } -DEFINE_FWK_MODULE(Phase2OTValidateTracks); +DEFINE_FWK_MODULE(Phase2OTValidateTracks); \ No newline at end of file From 18190eb75204b3494e802b8772aadb16979bfb74 Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Tue, 18 Nov 2025 19:57:55 +0100 Subject: [PATCH 07/61] got rid of unnecessary helper function calls and added histograms deleted in error --- .../plugins/Phase2OTValidateTracks.cc | 142 ++++++++++-------- 1 file changed, 79 insertions(+), 63 deletions(-) diff --git a/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateTracks.cc b/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateTracks.cc index abe2bbc08779e..49637b4cf0ef4 100644 --- a/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateTracks.cc +++ b/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateTracks.cc @@ -645,74 +645,91 @@ void Phase2OTValidateTracks::bookHistograms(DQMStore::IBooker &iBooker, edm::ParameterSet psRes_d0 = conf_.getParameter("TH1Res_d0"); edm::ParameterSet psRes_displaced_d0 = conf_.getParameter("TH1Resdisplaced_d0"); - static const std::string ranges[6] = {"eta0to0p7", "eta0p7to1", "eta1to1p2", "eta1p2to1p6", "eta1p6to2", "eta2to2p4"}; using phase2tkutil::book1DFromPS; - using phase2tkutil::bookIntoVec; - using phase2tkutil::bookDenNum; - - // Histogram setup and definitions - // ================== trackParticles (sample) ================== + + // |eta| bin labels for resolution ingredients + std::string ranges[6] = { "eta0to0p7", "eta0p7to1", "eta1to1p2", "eta1p2to1p6", "eta1p6to2", "eta2to2p4" }; + + // Tracking particle kinematics iBooker.setCurrentFolder(topFolderName_ + "/trackParticles"); trackParts_Pt = book1DFromPS(iBooker, "trackParts_Pt", psTrackParts_Pt, "p_{T} [GeV]", "# tracking particles"); trackParts_Eta = book1DFromPS(iBooker, "trackParts_Eta", psTrackParts_Eta, "#eta", "# tracking particles"); - trackParts_Phi = book1DFromPS(iBooker, "trackParts_Phi", psTrackParts_Phi, "#phi", "# tracking particles"); - - // ================== Nominal_L1TF / Residual ================== + trackParts_Phi = book1DFromPS(iBooker, "trackParts_Phi", psTrackParts_Phi, "#phi", "# tracking particles"); + + // Nominal L1TF: efficiency ingredients (denominator + matched numerator) + iBooker.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/EfficiencyIngredients"); + // Denominator: all selected TPs + tp_pt = book1DFromPS(iBooker, "tp_pt", psEffic_pt, "p_{T} [GeV]", "# tracking particles"); + tp_pt_zoom = book1DFromPS(iBooker, "tp_pt_zoom", psEffic_pt_zoom, "p_{T} [GeV]", "# tracking particles"); + tp_eta = book1DFromPS(iBooker, "tp_eta", psEffic_eta, "#eta", "# tracking particles"); + tp_d0 = book1DFromPS(iBooker, "tp_d0", psEffic_d0, "d_{0} [cm]", "# tracking particles"); + tp_Lxy = book1DFromPS(iBooker, "tp_Lxy", psEffic_Lxy, "L_{xy} [cm]", "# tracking particles"); + tp_z0 = book1DFromPS(iBooker, "tp_z0", psEffic_z0, "z_{0} [cm]", "# tracking particles"); + + // Numerator: matched TPs + match_tp_pt = book1DFromPS(iBooker, "match_tp_pt", psEffic_pt, "p_{T} [GeV]", "# matched tracking particles"); + match_tp_pt_zoom = book1DFromPS(iBooker, "match_tp_pt_zoom", psEffic_pt_zoom, "p_{T} [GeV]", "# matched tracking particles"); + match_tp_eta = book1DFromPS(iBooker, "match_tp_eta", psEffic_eta, "#eta", "# matched tracking particles"); + match_tp_d0 = book1DFromPS(iBooker, "match_tp_d0", psEffic_d0, "d_{0} [cm]", "# matched tracking particles"); + match_tp_Lxy = book1DFromPS(iBooker, "match_tp_Lxy", psEffic_Lxy, "L_{xy} [cm]", "# matched tracking particles"); + match_tp_z0 = book1DFromPS(iBooker, "match_tp_z0", psEffic_z0, "z_{0} [cm]", "# matched tracking particles"); + + // Nominal L1TF: residual distributions iBooker.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/Residual"); - res_pt = book1DFromPS(iBooker, "res_pt", psRes_pt, "p_{T} [GeV]", "# tracking particles"); - res_eta = book1DFromPS(iBooker, "res_eta", psRes_eta, "#eta", "# tracking particles"); - res_ptRel = book1DFromPS(iBooker, "res_ptRel", psRes_ptRel, "Relative p_{T} [GeV]", "# tracking particles"); - d0_res_hist = book1DFromPS(iBooker, "res_d0", psRes_d0, "trk d_{0} - tp d_{0} [cm]","# tracking particles"); - - // ===== Nominal_L1TF / ResolutionIngredients (eta-sliced) ===== + res_pt = book1DFromPS(iBooker, "res_pt", psRes_pt, "p_{T} [GeV]", "# tracking particles"); + res_eta = book1DFromPS(iBooker, "res_eta", psRes_eta, "#eta", "# tracking particles"); + res_ptRel = book1DFromPS(iBooker, "res_ptRel", psRes_ptRel, "Relative p_{T} [GeV]", "# tracking particles"); + d0_res_hist = book1DFromPS(iBooker, "res_d0", psRes_d0, "trk d_{0} - tp d_{0} [cm]","# tracking particles"); + + // Nominal L1TF: resolution vs eta and pT slices iBooker.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/ResolutionIngredients"); - for (int i = 0; i < 6; ++i) { - bookIntoVec(iBooker, reseta_vect, i, "reseta_" + ranges[i], psRes_eta, "#eta_{trk} - #eta_{tp}"); - bookIntoVec(iBooker, resphi_vect, i, "resphi_" + ranges[i], psRes_phi, "#phi_{trk} - #phi_{tp}"); - bookIntoVec(iBooker, resz0_vect, i, "resz0_" + ranges[i], psRes_z0, "z0_{trk} - z0_{tp} [cm]"); - bookIntoVec(iBooker, resd0_vect, i, "resd0_" + ranges[i], psRes_d0, "d0_{trk} - d0_{tp} [cm]"); - - respt_pt2to3[i] = book1DFromPS(iBooker, "respt_" + ranges[i] + "_pt2to3", psRes_pt, " (p_{T}(trk) - p_{T}(tp))/p_{T}(tp)", "# tracking particles"); - respt_pt3to8[i] = book1DFromPS(iBooker, "respt_" + ranges[i] + "_pt3to8", psRes_pt, " (p_{T}(trk) - p_{T}(tp))/p_{T}(tp)", "# tracking particles"); - respt_pt8toInf[i] = book1DFromPS(iBooker,"respt_" + ranges[i] + "_pt8toInf",psRes_pt, " (p_{T}(trk) - p_{T}(tp))/p_{T}(tp)", "# tracking particles"); + for (int i = 0; i < 6; i++) { + reseta_vect[i] = book1DFromPS(iBooker, "reseta_" + ranges[i], psRes_eta, "#eta_{trk} - #eta_{tp}", "# tracking particles"); + resphi_vect[i] = book1DFromPS(iBooker, "resphi_" + ranges[i], psRes_phi, "#phi_{trk} - #phi_{tp}", "# tracking particles"); + resz0_vect[i] = book1DFromPS(iBooker, "resz0_" + ranges[i], psRes_z0, "z0_{trk} - z0_{tp} [cm]", "# tracking particles"); + resd0_vect[i] = book1DFromPS(iBooker, "resd0_" + ranges[i], psRes_d0, "d0_{trk} - d0_{tp} [cm]", "# tracking particles"); + respt_pt2to3[i] = book1DFromPS(iBooker, "respt_" + ranges[i] + "_pt2to3", psRes_pt, "(p_{T}(trk) - p_{T}(tp))/p_{T}(tp)", "# tracking particles"); + respt_pt3to8[i] = book1DFromPS(iBooker, "respt_" + ranges[i] + "_pt3to8", psRes_pt, "(p_{T}(trk) - p_{T}(tp))/p_{T}(tp)", "# tracking particles"); + respt_pt8toInf[i] = book1DFromPS(iBooker, "respt_" + ranges[i] + "_pt8toInf", psRes_pt, "(p_{T}(trk) - p_{T}(tp))/p_{T}(tp)", "# tracking particles"); } - - // =========== Extended_L1TF / Displaced / Efficiency =========== + + // Extended L1TF (Displaced): efficiency ingredients iBooker.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Displaced/EfficiencyIngredients"); - tp_pt_for_dis = book1DFromPS(iBooker, "tp_pt_for_dis", psEffic_pt, "p_{T} [GeV]", "# tracking particles"); - tp_pt_zoom_for_dis = book1DFromPS(iBooker, "tp_pt_zoom_for_dis", psEffic_pt_zoom, "p_{T} [GeV]", "# tracking particles"); - tp_eta_for_dis = book1DFromPS(iBooker, "tp_eta_for_dis", psEffic_eta, "#eta", "# tracking particles"); - tp_d0_for_dis = book1DFromPS(iBooker, "tp_d0_for_dis", psDisEffic_d0, "d_{0} [cm]", "# tracking particles"); - tp_z0_for_dis = book1DFromPS(iBooker, "tp_z0_for_dis", psEffic_z0, "z_{0} [cm]", "# tracking particles"); - - match_displaced_tp_pt = book1DFromPS(iBooker, "match_displaced_tp_pt", psEffic_pt, "p_{T} [GeV]", "# matched extended tracking particles"); - match_displaced_tp_pt_zoom = book1DFromPS(iBooker, "match_displaced_tp_pt_zoom", psEffic_pt_zoom, "p_{T} [GeV]", "# matched extended tracking particles"); - match_displaced_tp_eta = book1DFromPS(iBooker, "match_displaced_tp_eta", psEffic_eta, "#eta", "# matched extended tracking particles"); - match_displaced_tp_d0 = book1DFromPS(iBooker, "match_displaced_tp_d0", psDisEffic_d0, "d_{0} [cm]", "# matched extended tracking particles"); - match_displaced_tp_Lxy = book1DFromPS(iBooker, "match_displaced_tp_Lxy", psEffic_Lxy, "L_{xy} [cm]", "# matched extended tracking particles"); - match_displaced_tp_z0 = book1DFromPS(iBooker, "match_displaced_tp_z0", psEffic_z0, "z_{0} [cm]", "# matched extended tracking particles"); - - // =========== Extended_L1TF / Displaced / Residual =========== + // Denominator: displaced TP selection + tp_pt_for_dis = book1DFromPS(iBooker, "tp_pt_for_dis", psEffic_pt, "p_{T} [GeV]", "# tracking particles"); + tp_pt_zoom_for_dis = book1DFromPS(iBooker, "tp_pt_zoom_for_dis", psEffic_pt_zoom, "p_{T} [GeV]", "# tracking particles"); + tp_eta_for_dis = book1DFromPS(iBooker, "tp_eta_for_dis", psEffic_eta, "#eta", "# tracking particles"); + tp_d0_for_dis = book1DFromPS(iBooker, "tp_d0_for_dis", psDisEffic_d0, "d_{0} [cm]", "# tracking particles"); + tp_z0_for_dis = book1DFromPS(iBooker, "tp_z0_for_dis", psEffic_z0, "z_{0} [cm]", "# tracking particles"); + + // Numerator: matched displaced TPs + match_displaced_tp_pt = book1DFromPS(iBooker, "match_displaced_tp_pt", psEffic_pt, "p_{T} [GeV]", "# matched extended tracking particles"); + match_displaced_tp_pt_zoom = book1DFromPS(iBooker, "match_displaced_tp_pt_zoom", psEffic_pt_zoom, "p_{T} [GeV]", "# matched extended tracking particles"); + match_displaced_tp_eta = book1DFromPS(iBooker, "match_displaced_tp_eta", psEffic_eta, "#eta", "# matched extended tracking particles"); + match_displaced_tp_d0 = book1DFromPS(iBooker, "match_displaced_tp_d0", psDisEffic_d0, "d_{0} [cm]", "# matched extended tracking particles"); + match_displaced_tp_Lxy = book1DFromPS(iBooker, "match_displaced_tp_Lxy", psEffic_Lxy, "L_{xy} [cm]", "# matched extended tracking particles"); + match_displaced_tp_z0 = book1DFromPS(iBooker, "match_displaced_tp_z0", psEffic_z0, "z_{0} [cm]", "# matched extended tracking particles"); + + // Extended L1TF (Displaced): residual distributions iBooker.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Displaced/Residual"); res_displaced_d0 = book1DFromPS(iBooker, "res_displaced_d0", psRes_displaced_d0, "trk d_{0} - tp d_{0} [cm]", "# displaced tracks"); res_displaced_eta = book1DFromPS(iBooker, "res_displaced_eta", psRes_eta, "#eta_{trk} - #eta_{tp}", "# tracking particles"); res_displaced_pt = book1DFromPS(iBooker, "res_displaced_pt", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); res_displaced_ptRel = book1DFromPS(iBooker, "res_displaced_ptRel", psRes_ptRel, "Relative p_{T} [GeV]", "# tracking particles"); - // ===== Extended_L1TF / Displaced / ResolutionIngredients ===== + // Extended L1TF (Displaced): resolution vs eta and pT slices iBooker.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Displaced/ResolutionIngredients"); - for (int i = 0; i < 6; ++i) { - bookIntoVec(iBooker, reseta_displaced_vect, i, "reseta_displaced_" + ranges[i], psRes_eta, "#eta_{trk} - #eta_{tp}"); - bookIntoVec(iBooker, resphi_displaced_vect, i, "resphi_displaced_" + ranges[i], psRes_phi, "#phi_{trk} - #phi_{tp}"); - bookIntoVec(iBooker, resd0_displaced_vect, i, "resd0_displaced_" + ranges[i], psRes_displaced_d0, "d0_{trk} - d0_{tp} [cm]"); - bookIntoVec(iBooker, resz0_displaced_vect, i, "resz0_displaced_" + ranges[i], psRes_z0, "z0_{trk} - z0_{tp} [cm]"); - - respt_displaced_pt2to3[i] = book1DFromPS(iBooker, "respt_displaced_" + ranges[i] + "_pt2to3", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); - respt_displaced_pt3to8[i] = book1DFromPS(iBooker, "respt_displaced_" + ranges[i] + "_pt3to8", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); - respt_displaced_pt8toInf[i] = book1DFromPS(iBooker,"respt_displaced_" + ranges[i] + "_pt8toInf",psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); + for (int i = 0; i < 6; i++) { + reseta_displaced_vect[i] = book1DFromPS(iBooker, "reseta_displaced_" + ranges[i], psRes_eta, "#eta_{trk} - #eta_{tp}", "# tracking particles"); + resphi_displaced_vect[i] = book1DFromPS(iBooker, "resphi_displaced_" + ranges[i], psRes_phi, "#phi_{trk} - #phi_{tp}", "# tracking particles"); + resd0_displaced_vect[i] = book1DFromPS(iBooker, "resd0_displaced_" + ranges[i], psRes_displaced_d0, "d0_{trk} - d0_{tp} [cm]", "# tracking particles"); + resz0_displaced_vect[i] = book1DFromPS(iBooker, "resz0_displaced_" + ranges[i], psRes_z0, "z0_{trk} - z0_{tp} [cm]", "# tracking particles"); + respt_displaced_pt2to3[i] = book1DFromPS(iBooker, "respt_displaced_" + ranges[i] + "_pt2to3", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); + respt_displaced_pt3to8[i] = book1DFromPS(iBooker, "respt_displaced_" + ranges[i] + "_pt3to8", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); + respt_displaced_pt8toInf[i] = book1DFromPS(iBooker, "respt_displaced_" + ranges[i] + "_pt8toInf", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); } - // =========== Extended_L1TF / Prompt / Efficiency =========== + // Extended L1TF (Prompt): efficiency ingredients (matched prompt TPs) iBooker.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Prompt/EfficiencyIngredients"); match_prompt_tp_pt = book1DFromPS(iBooker, "match_prompt_tp_pt", psEffic_pt, "p_{T} [GeV]", "# matched tracking particles"); match_prompt_tp_pt_zoom = book1DFromPS(iBooker, "match_prompt_tp_pt_zoom", psEffic_pt_zoom, "p_{T} [GeV]", "# matched tracking particles"); @@ -720,25 +737,24 @@ void Phase2OTValidateTracks::bookHistograms(DQMStore::IBooker &iBooker, match_prompt_tp_d0 = book1DFromPS(iBooker, "match_prompt_tp_d0", psEffic_d0, "d_{0} [cm]", "# matched tracking particles"); match_prompt_tp_Lxy = book1DFromPS(iBooker, "match_prompt_tp_Lxy", psEffic_Lxy, "L_{xy} [cm]", "# matched tracking particles"); match_prompt_tp_z0 = book1DFromPS(iBooker, "match_prompt_tp_z0", psEffic_z0, "z_{0} [cm]", "# matched tracking particles"); - - // =========== Extended_L1TF / Prompt / Residual =========== + + // Extended L1TF (Prompt): residual distributions iBooker.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Prompt/Residual"); res_prompt_d0 = book1DFromPS(iBooker, "res_prompt_d0", psRes_d0, "trk d_{0} - tp d_{0} [cm]", "# tracking particles"); res_prompt_eta = book1DFromPS(iBooker, "res_prompt_eta", psRes_eta, "#eta_{trk} - #eta_{tp}", "# tracking particles"); res_prompt_pt = book1DFromPS(iBooker, "res_prompt_pt", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); res_prompt_ptRel = book1DFromPS(iBooker, "res_prompt_ptRel", psRes_ptRel, "Relative p_{T} [GeV]", "# tracking particles"); - // ===== Extended_L1TF / Prompt / ResolutionIngredients ===== + // Extended L1TF (Prompt): resolution vs eta and pT slices iBooker.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Prompt/ResolutionIngredients"); - for (int i = 0; i < 6; ++i) { - bookIntoVec(iBooker, reseta_prompt_vect, i, "reseta_prompt_" + ranges[i], psRes_eta, "#eta_{trk} - #eta_{tp}"); - bookIntoVec(iBooker, resphi_prompt_vect, i, "resphi_prompt_" + ranges[i], psRes_phi, "#phi_{trk} - #phi_{tp}"); - bookIntoVec(iBooker, resd0_prompt_vect, i, "resd0_prompt_" + ranges[i], psRes_d0, "d0_{trk} - d0_{tp} [cm]"); - bookIntoVec(iBooker, resz0_prompt_vect, i, "resz0_prompt_" + ranges[i], psRes_z0, "z0_{trk} - z0_{tp} [cm]"); - - respt_prompt_pt2to3[i] = book1DFromPS(iBooker, "respt_prompt_" + ranges[i] + "_pt2to3", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); - respt_prompt_pt3to8[i] = book1DFromPS(iBooker, "respt_prompt_" + ranges[i] + "_pt3to8", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); - respt_prompt_pt8toInf[i] = book1DFromPS(iBooker,"respt_prompt_" + ranges[i] + "_pt8toInf",psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); + for (int i = 0; i < 6; i++) { + reseta_prompt_vect[i] = book1DFromPS(iBooker, "reseta_prompt_" + ranges[i], psRes_eta, "#eta_{trk} - #eta_{tp}", "# tracking particles"); + resphi_prompt_vect[i] = book1DFromPS(iBooker, "resphi_prompt_" + ranges[i], psRes_phi, "#phi_{trk} - #phi_{tp}", "# tracking particles"); + resd0_prompt_vect[i] = book1DFromPS(iBooker, "resd0_prompt_" + ranges[i], psRes_d0, "d0_{trk} - d0_{tp} [cm]", "# tracking particles"); + resz0_prompt_vect[i] = book1DFromPS(iBooker, "resz0_prompt_" + ranges[i], psRes_z0, "z0_{trk} - z0_{tp} [cm]", "# tracking particles"); + respt_prompt_pt2to3[i] = book1DFromPS(iBooker, "respt_prompt_" + ranges[i] + "_pt2to3", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); + respt_prompt_pt3to8[i] = book1DFromPS(iBooker, "respt_prompt_" + ranges[i] + "_pt3to8", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); + respt_prompt_pt8toInf[i] = book1DFromPS(iBooker, "respt_prompt_" + ranges[i] + "_pt8toInf", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); } } // end of method From ccc774f3c1ef961d319195053664dcf39de5e5f2 Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Tue, 18 Nov 2025 19:58:55 +0100 Subject: [PATCH 08/61] got rid of unnecessary helper functions --- .../interface/TrackerPhase2HistUtil.h | 31 ------------------- 1 file changed, 31 deletions(-) diff --git a/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h b/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h index 7da54aef6a96c..f84e3278dac6a 100644 --- a/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h +++ b/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h @@ -48,36 +48,5 @@ namespace phase2tkutil { h->setAxisTitle(yaxis, 2); return h; } - - template - inline void bookDenNum(dqm::legacy::DQMStore::IBooker& iBooker, - const std::string& base, - Ptr& den, Ptr& num, - const edm::ParameterSet& ps, - const char* xaxis, - const char* denY = "# tracking particles", - const char* numY = "# matched tracking particles", - const std::string& denPrefix = "tp_", - const std::string& numPrefix = "match_tp_") { - auto* denME = book1DFromPS(iBooker, denPrefix + base, ps, xaxis, denY); - auto* numME = book1DFromPS(iBooker, numPrefix + base, ps, xaxis, numY); - den = denME; - num = numME; - } - - template - inline void bookIntoVec(dqm::legacy::DQMStore::IBooker& iBooker, - Vec& vec, - int i, - const std::string& name, - const edm::ParameterSet& ps, - const char* xaxis, - const char* yaxis = "# tracking particles") { - if ((int)vec.size() <= i) - vec.resize(i + 1, nullptr); - - auto* me = book1DFromPS(iBooker, name, ps, xaxis, yaxis); - vec[i] = me; - } } // namespace phase2tkutil #endif From 5571675fa88332a0f62d0d8f4d281cfc6c9252cc Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Tue, 18 Nov 2025 22:44:15 +0100 Subject: [PATCH 09/61] added code to calculate stub efficiencies --- .../python/Phase2OTEffClient_cff.py | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/Validation/SiTrackerPhase2V/python/Phase2OTEffClient_cff.py b/Validation/SiTrackerPhase2V/python/Phase2OTEffClient_cff.py index d447e10894335..c498fcb186faa 100644 --- a/Validation/SiTrackerPhase2V/python/Phase2OTEffClient_cff.py +++ b/Validation/SiTrackerPhase2V/python/Phase2OTEffClient_cff.py @@ -45,5 +45,27 @@ verbose=cms.untracked.uint32(0) ) +_topFolderStubs = "TrackerPhase2OTStubV" + +phase2OTStubEffClient = cms.EDProducer( + "DQMGenericClient", + subDirs=cms.untracked.vstring( + f"{_topFolderStubs}/FinalEfficiency", + ), + # " '' " + efficiency=cms.vstring( + "StubEfficiencyBarrel 'Stub Efficiency Barrel;tracking particle p_{T} [GeV];Efficiency' ../EfficiencyIngredients/gen_clusters_if_stub_barrel ../EfficiencyIngredients/gen_clusters_barrel", + "StubEfficiencyZoomBarrel 'Stub Efficiency Zoom Barrel;tracking particle p_{T} [GeV];Efficiency' ../EfficiencyIngredients/gen_clusters_if_stub_zoom_barrel ../EfficiencyIngredients/gen_clusters_zoom_barrel", + "StubEfficiencyEndcaps 'Stub Efficiency Endcaps;tracking particle p_{T} [GeV];Efficiency' ../EfficiencyIngredients/gen_clusters_if_stub_endcaps ../EfficiencyIngredients/gen_clusters_endcaps", + "StubEfficiencyZoomEndcaps 'Stub Efficiency Zoom Endcaps;tracking particle p_{T} [GeV];Efficiency' ../EfficiencyIngredients/gen_clusters_if_stub_zoom_endcaps ../EfficiencyIngredients/gen_clusters_zoom_endcaps", + ), + resolution=cms.vstring(), + efficiencyProfile=cms.untracked.vstring(), + verbose=cms.untracked.uint32(0) +) + # Expose as a Sequence so you can append with one line -phase2OTEffClientSeq = cms.Sequence(phase2OTEffClient) \ No newline at end of file +phase2OTEffClientSeq = cms.Sequence( + phase2OTEffClient # tracks + + phase2OTStubEffClient # stubs +) \ No newline at end of file From bf2dc78123e8d300f7077810c1465ad6c32c7360 Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Tue, 18 Nov 2025 22:50:50 +0100 Subject: [PATCH 10/61] removed Phase2OTHarvestStub.cc as efficiency calculations are now done in Phase2OTEffClient_cff.py --- .../plugins/Phase2OTHarvestStub.cc | 176 ------------------ 1 file changed, 176 deletions(-) delete mode 100644 Validation/SiTrackerPhase2V/plugins/Phase2OTHarvestStub.cc diff --git a/Validation/SiTrackerPhase2V/plugins/Phase2OTHarvestStub.cc b/Validation/SiTrackerPhase2V/plugins/Phase2OTHarvestStub.cc deleted file mode 100644 index 795ca3916e94f..0000000000000 --- a/Validation/SiTrackerPhase2V/plugins/Phase2OTHarvestStub.cc +++ /dev/null @@ -1,176 +0,0 @@ - -// Package: Validation/SiTrackerPhase2V -// Class: Phase2OTHarvestStub - -/** - * This class is part of the Phase 2 Tracker validation framework and performs - * the harvesting step for stub validation. It processes histograms - * created during the earlier validation steps to calculate efficiencies and - * resolutions for stub reconstruction. - * - * Usage: - * To generate histograms from this code, run the test configuration files - * provided in the DQM/SiTrackerPhase2/test directory. The generated histograms - * can then be analyzed or visualized. - */ - -// Created by: Brandi Skipworth, 2025 - -#include - -#include "DQMServices/Core/interface/DQMEDHarvester.h" -#include "DQMServices/Core/interface/DQMStore.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/ServiceRegistry/interface/Service.h" -#include "Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h" - -class Phase2OTHarvestStub : public DQMEDHarvester { -public: - explicit Phase2OTHarvestStub(const edm::ParameterSet &); - ~Phase2OTHarvestStub() override; - void dqmEndJob(DQMStore::IBooker &ibooker, DQMStore::IGetter &igetter) override; - static void fillDescriptions(edm::ConfigurationDescriptions &descriptions); - -private: - // ----------member data --------------------------- - std::string topFolderName_; -}; - -Phase2OTHarvestStub::Phase2OTHarvestStub(const edm::ParameterSet &iConfig) - : topFolderName_(iConfig.getParameter("TopFolderName")) {} - -Phase2OTHarvestStub::~Phase2OTHarvestStub() {} - -// ------------ method called once each job just after ending the event loop -// ------------ -void Phase2OTHarvestStub::dqmEndJob(DQMStore::IBooker &ibooker, DQMStore::IGetter &igetter) { - using namespace edm; - - // Find all monitor elements for histograms - MonitorElement *meN_clus_barrel = igetter.get(topFolderName_ + "/EfficiencyIngredients/gen_clusters_if_stub_barrel"); - MonitorElement *meD_clus_barrel = igetter.get(topFolderName_ + "/EfficiencyIngredients/gen_clusters_barrel"); - MonitorElement *meN_clus_zoom_barrel = - igetter.get(topFolderName_ + "/EfficiencyIngredients/gen_clusters_if_stub_zoom_barrel"); - MonitorElement *meD_clus_zoom_barrel = - igetter.get(topFolderName_ + "/EfficiencyIngredients/gen_clusters_zoom_barrel"); - MonitorElement *meN_clus_endcaps = - igetter.get(topFolderName_ + "/EfficiencyIngredients/gen_clusters_if_stub_endcaps"); - MonitorElement *meD_clus_endcaps = igetter.get(topFolderName_ + "/EfficiencyIngredients/gen_clusters_endcaps"); - MonitorElement *meN_clus_zoom_endcaps = - igetter.get(topFolderName_ + "/EfficiencyIngredients/gen_clusters_if_stub_zoom_endcaps"); - MonitorElement *meD_clus_zoom_endcaps = - igetter.get(topFolderName_ + "/EfficiencyIngredients/gen_clusters_zoom_endcaps"); - - if (meN_clus_barrel && meD_clus_barrel) { - // Get the numerator and denominator histograms - TH1F *numerator = meN_clus_barrel->getTH1F(); - TH1F *denominator = meD_clus_barrel->getTH1F(); - numerator->Sumw2(); - denominator->Sumw2(); - - // Set the current directory - igetter.setCurrentFolder(topFolderName_ + "/FinalEfficiency"); - - // Book the new histogram to contain the results - MonitorElement *me_effic_clus_barrel = ibooker.book1D("StubEfficiencyBarrel", - "Stub Efficiency Barrel", - numerator->GetNbinsX(), - numerator->GetXaxis()->GetXmin(), - numerator->GetXaxis()->GetXmax()); - - // Calculate the efficiency - phase2tkutil::makeEfficiencyME(numerator, denominator, me_effic_clus_barrel, "tracking particle pT [GeV]"); - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for stub efficiency barrel cannot be found!\n"; - } - - if (meN_clus_zoom_barrel && meD_clus_zoom_barrel) { - // Get the numerator and denominator histograms - TH1F *numerator_zoom = meN_clus_zoom_barrel->getTH1F(); - TH1F *denominator_zoom = meD_clus_zoom_barrel->getTH1F(); - numerator_zoom->Sumw2(); - denominator_zoom->Sumw2(); - - // Set the current directory - igetter.setCurrentFolder(topFolderName_ + "/FinalEfficiency"); - - // Book the new histogram to contain the results - MonitorElement *me_effic_clus_zoom_barrel = ibooker.book1D("StubEfficiencyZoomBarrel", - "Stub Efficiency Zoom Barrel", - numerator_zoom->GetNbinsX(), - numerator_zoom->GetXaxis()->GetXmin(), - numerator_zoom->GetXaxis()->GetXmax()); - - // Calculate the efficiency - phase2tkutil::makeEfficiencyME( - numerator_zoom, denominator_zoom, me_effic_clus_zoom_barrel, "tracking particle pT [GeV]"); - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for stub zoom barrel " - "efficiency cannot be found!\n"; - } - - if (meN_clus_endcaps && meD_clus_endcaps) { - // Get the numerator and denominator histograms - TH1F *numerator = meN_clus_endcaps->getTH1F(); - TH1F *denominator = meD_clus_endcaps->getTH1F(); - numerator->Sumw2(); - denominator->Sumw2(); - - // Set the current directory - igetter.setCurrentFolder(topFolderName_ + "/FinalEfficiency"); - - // Book the new histogram to contain the results - MonitorElement *me_effic_clus_endcaps = ibooker.book1D("StubEfficiencyEndcaps", - "Stub Efficiency Endcaps", - numerator->GetNbinsX(), - numerator->GetXaxis()->GetXmin(), - numerator->GetXaxis()->GetXmax()); - - // Calculate the efficiency - phase2tkutil::makeEfficiencyME(numerator, denominator, me_effic_clus_endcaps, "tracking particle pT [GeV]"); - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for stub efficiency endcaps cannot be found!\n"; - } - - if (meN_clus_zoom_endcaps && meD_clus_zoom_endcaps) { - // Get the numerator and denominator histograms - TH1F *numerator_zoom = meN_clus_zoom_endcaps->getTH1F(); - TH1F *denominator_zoom = meD_clus_zoom_endcaps->getTH1F(); - numerator_zoom->Sumw2(); - denominator_zoom->Sumw2(); - - // Set the current directory - igetter.setCurrentFolder(topFolderName_ + "/FinalEfficiency"); - - // Book the new histogram to contain the results - MonitorElement *me_effic_clus_zoom_endcaps = ibooker.book1D("StubEfficiencyZoomEndcaps", - "Stub Efficiency Zoom Endcaps", - numerator_zoom->GetNbinsX(), - numerator_zoom->GetXaxis()->GetXmin(), - numerator_zoom->GetXaxis()->GetXmax()); - - // Calculate the efficiency - phase2tkutil::makeEfficiencyME( - numerator_zoom, denominator_zoom, me_effic_clus_zoom_endcaps, "tracking particle pT [GeV]"); - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for stub zoom endcaps " - "efficiency cannot be found!\n"; - } -} // end dqmEndJob - -#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" -#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" -void Phase2OTHarvestStub::fillDescriptions(edm::ConfigurationDescriptions &descriptions) { - edm::ParameterSetDescription desc; - desc.add("TopFolderName", "TrackerPhase2OTStubV"); - descriptions.add("Phase2OTHarvestStub", desc); -} -DEFINE_FWK_MODULE(Phase2OTHarvestStub); From 0f11897938e058fc73c84a12809354eeeb03f183 Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Tue, 6 Jan 2026 21:40:41 +0100 Subject: [PATCH 11/61] add helper function for resolution hists --- .../interface/TrackerPhase2HistUtil.h | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h b/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h index f84e3278dac6a..0edb53c3e8dfa 100644 --- a/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h +++ b/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h @@ -13,10 +13,12 @@ #include #include #include +#include #include "DQMServices/Core/interface/DQMStore.h" #include "DQMServices/Core/interface/MonitorElement.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" #include "TH1.h" namespace phase2tkutil { @@ -34,6 +36,30 @@ namespace phase2tkutil { efficiency->GetYaxis()->SetTitle("Efficiency"); } + inline void fillResolutionFromVec(const std::vector& srcVec, + dqm::legacy::MonitorElement* destME, + const std::string& yAxisTitle) { + if (!destME) return; + + // Check if any source elements are missing + if (std::find(srcVec.begin(), srcVec.end(), nullptr) != srcVec.end()) { + edm::LogWarning("TrackerPhase2HistUtil") << "Missing source ME for resolution: " << destME->getName(); + return; + } + + TH1* hDest = destME->getTH1(); + hDest->SetMinimum(0.0); + hDest->SetStats(false); + hDest->GetYaxis()->SetTitle(yAxisTitle.c_str()); + + for (size_t i = 0; i < srcVec.size(); ++i) { + TH1* hSrc = srcVec[i]->getTH1(); + // Bin 1 in destination corresponds to index 0 in vector + hDest->SetBinContent(i + 1, hSrc->GetStdDev()); + hDest->SetBinError(i + 1, hSrc->GetStdDevError()); + } + } + inline dqm::legacy::MonitorElement* book1DFromPS( dqm::legacy::DQMStore::IBooker& iBooker, const std::string& name, From e21bd8816a809aa2847968dcd18df6aa54ad42f0 Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Tue, 6 Jan 2026 21:41:20 +0100 Subject: [PATCH 12/61] reduced several hundred lines of code by use of helper function --- .../plugins/Phase2OTHarvestTracks.cc | 754 ++---------------- 1 file changed, 67 insertions(+), 687 deletions(-) diff --git a/Validation/SiTrackerPhase2V/plugins/Phase2OTHarvestTracks.cc b/Validation/SiTrackerPhase2V/plugins/Phase2OTHarvestTracks.cc index 4e108499cc5f3..c820cfea56565 100644 --- a/Validation/SiTrackerPhase2V/plugins/Phase2OTHarvestTracks.cc +++ b/Validation/SiTrackerPhase2V/plugins/Phase2OTHarvestTracks.cc @@ -18,15 +18,15 @@ // Updated by: Brandi Skipworth, 2025 #include +#include +#include #include "DQMServices/Core/interface/DQMEDHarvester.h" #include "DQMServices/Core/interface/DQMStore.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/Frameworkfwd.h" #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/ServiceRegistry/interface/Service.h" +#include "Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h" class Phase2OTHarvestTracks : public DQMEDHarvester { public: @@ -52,698 +52,78 @@ void Phase2OTHarvestTracks::dqmEndJob(DQMStore::IBooker &ibooker, DQMStore::IGet float eta_bins[] = {0.0, 0.7, 1.0, 1.2, 1.6, 2.0, 2.4}; int eta_binnum = 6; - std::string eta_ranges[6] = {"eta0to0p7", "eta0p7to1", "eta1to1p2", "eta1p2to1p6", "eta1p6to2", "eta2to2p4"}; + // nominal collection - std::vector respt_pt2to3 = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - std::vector respt_pt3to8 = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - std::vector respt_pt8toInf = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - std::vector mereseta_vect = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - std::vector meresphi_vect = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - std::vector meresz0_vect = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - std::vector meresd0_vect = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; + std::vector respt_pt2to3(6, nullptr), respt_pt3to8(6, nullptr), respt_pt8toInf(6, nullptr); + std::vector mereseta_vect(6, nullptr), meresphi_vect(6, nullptr), meresz0_vect(6, nullptr), meresd0_vect(6, nullptr); - // extended collection - std::vector prompt_respt_pt2to3 = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - std::vector prompt_respt_pt3to8 = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - std::vector prompt_respt_pt8toInf = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - std::vector prompt_mereseta_vect = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - std::vector prompt_meresphi_vect = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - std::vector prompt_meresz0_vect = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - std::vector prompt_meresd0_vect = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; + std::vector prompt_respt_pt2to3(6, nullptr), prompt_respt_pt3to8(6, nullptr), prompt_respt_pt8toInf(6, nullptr); + std::vector prompt_mereseta_vect(6, nullptr), prompt_meresphi_vect(6, nullptr), prompt_meresz0_vect(6, nullptr), prompt_meresd0_vect(6, nullptr); - std::vector displaced_respt_pt2to3 = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - std::vector displaced_respt_pt3to8 = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - std::vector displaced_respt_pt8toInf = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - std::vector displaced_mereseta_vect = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - std::vector displaced_meresphi_vect = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - std::vector displaced_meresz0_vect = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - std::vector displaced_meresd0_vect = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; + std::vector displaced_respt_pt2to3(6, nullptr), displaced_respt_pt3to8(6, nullptr), displaced_respt_pt8toInf(6, nullptr); + std::vector displaced_mereseta_vect(6, nullptr), displaced_meresphi_vect(6, nullptr), displaced_meresz0_vect(6, nullptr), displaced_meresd0_vect(6, nullptr); for (int i = 0; i < 6; i++) { - // nominal collection - respt_pt2to3[i] = - igetter.get(topFolderName_ + "/Nominal_L1TF/ResolutionIngredients/respt_" + eta_ranges[i] + "_pt2to3"); - respt_pt3to8[i] = - igetter.get(topFolderName_ + "/Nominal_L1TF/ResolutionIngredients/respt_" + eta_ranges[i] + "_pt3to8"); - respt_pt8toInf[i] = - igetter.get(topFolderName_ + "/Nominal_L1TF/ResolutionIngredients/respt_" + eta_ranges[i] + "_pt8toInf"); - mereseta_vect[i] = igetter.get(topFolderName_ + "/Nominal_L1TF/ResolutionIngredients/reseta_" + eta_ranges[i]); - meresphi_vect[i] = igetter.get(topFolderName_ + "/Nominal_L1TF/ResolutionIngredients/resphi_" + eta_ranges[i]); - meresz0_vect[i] = igetter.get(topFolderName_ + "/Nominal_L1TF/ResolutionIngredients/resz0_" + eta_ranges[i]); - meresd0_vect[i] = igetter.get(topFolderName_ + "/Nominal_L1TF/ResolutionIngredients/resd0_" + eta_ranges[i]); - - // extended collection - prompt_respt_pt2to3[i] = igetter.get(topFolderName_ + "/Extended_L1TF/Prompt/ResolutionIngredients/respt_prompt_" + - eta_ranges[i] + "_pt2to3"); - prompt_respt_pt3to8[i] = igetter.get(topFolderName_ + "/Extended_L1TF/Prompt/ResolutionIngredients/respt_prompt_" + - eta_ranges[i] + "_pt3to8"); - prompt_respt_pt8toInf[i] = igetter.get( - topFolderName_ + "/Extended_L1TF/Prompt/ResolutionIngredients/respt_prompt_" + eta_ranges[i] + "_pt8toInf"); - prompt_mereseta_vect[i] = - igetter.get(topFolderName_ + "/Extended_L1TF/Prompt/ResolutionIngredients/reseta_prompt_" + eta_ranges[i]); - prompt_meresphi_vect[i] = - igetter.get(topFolderName_ + "/Extended_L1TF/Prompt/ResolutionIngredients/resphi_prompt_" + eta_ranges[i]); - prompt_meresz0_vect[i] = - igetter.get(topFolderName_ + "/Extended_L1TF/Prompt/ResolutionIngredients/resz0_prompt_" + eta_ranges[i]); - prompt_meresd0_vect[i] = - igetter.get(topFolderName_ + "/Extended_L1TF/Prompt/ResolutionIngredients/resd0_prompt_" + eta_ranges[i]); - - displaced_respt_pt2to3[i] = igetter.get( - topFolderName_ + "/Extended_L1TF/Displaced/ResolutionIngredients/respt_displaced_" + eta_ranges[i] + "_pt2to3"); - displaced_respt_pt3to8[i] = igetter.get( - topFolderName_ + "/Extended_L1TF/Displaced/ResolutionIngredients/respt_displaced_" + eta_ranges[i] + "_pt3to8"); - displaced_respt_pt8toInf[i] = - igetter.get(topFolderName_ + "/Extended_L1TF/Displaced/ResolutionIngredients/respt_displaced_" + eta_ranges[i] + - "_pt8toInf"); - displaced_mereseta_vect[i] = igetter.get( - topFolderName_ + "/Extended_L1TF/Displaced/ResolutionIngredients/reseta_displaced_" + eta_ranges[i]); - displaced_meresphi_vect[i] = igetter.get( - topFolderName_ + "/Extended_L1TF/Displaced/ResolutionIngredients/resphi_displaced_" + eta_ranges[i]); - displaced_meresz0_vect[i] = - igetter.get(topFolderName_ + "/Extended_L1TF/Displaced/ResolutionIngredients/resz0_displaced_" + eta_ranges[i]); - displaced_meresd0_vect[i] = - igetter.get(topFolderName_ + "/Extended_L1TF/Displaced/ResolutionIngredients/resd0_displaced_" + eta_ranges[i]); - } - -// nominal collection - if (std::find(respt_pt2to3.begin(), respt_pt2to3.end(), nullptr) == respt_pt2to3.end()) { - // Set the current directoy - igetter.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/FinalResolution"); - - // Grab the histograms - std::vector vResPt1 = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - for (int i = 0; i < 6; i++) { - vResPt1[i] = respt_pt2to3[i]->getTH1F(); - } - - // Book the new histogram to contain the results - MonitorElement *me_res_pt1 = - ibooker.book1D("pTResVsEta_2-3", "p_{T} resolution vs |#eta|, for p_{T}: 2-3 GeV", eta_binnum, eta_bins); - TH1F *resPt1 = me_res_pt1->getTH1F(); - resPt1->GetXaxis()->SetTitle("tracking particle |#eta|"); - resPt1->GetYaxis()->SetTitle("#sigma(#Delta p_{T}/p_{T})"); - resPt1->SetMinimum(0.0); - resPt1->SetStats(false); - - for (int i = 0; i < 6; i++) { - resPt1->SetBinContent(i + 1, vResPt1[i]->GetStdDev()); - resPt1->SetBinError(i + 1, vResPt1[i]->GetStdDevError()); - } - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for pT resolution (2-3) cannot be found!\n"; - } - - // extended collection - if (std::find(prompt_respt_pt2to3.begin(), prompt_respt_pt2to3.end(), nullptr) == prompt_respt_pt2to3.end()) { - // Set the current directoy - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Prompt/FinalResolution"); - - // Grab the histograms - std::vector vResPt1 = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - for (int i = 0; i < 6; i++) { - vResPt1[i] = prompt_respt_pt2to3[i]->getTH1F(); - } - - // Book the new histogram to contain the results - MonitorElement *me_res_pt1 = - ibooker.book1D("pTResVsEta_2-3_prompt", "p_{T} resolution vs |#eta|, for p_{T}: 2-3 GeV", eta_binnum, eta_bins); - TH1F *resPt1 = me_res_pt1->getTH1F(); - resPt1->GetXaxis()->SetTitle("tracking particle |#eta|"); - resPt1->GetYaxis()->SetTitle("#sigma(#Delta p_{T}/p_{T})"); - resPt1->SetMinimum(0.0); - resPt1->SetStats(false); - - for (int i = 0; i < 6; i++) { - resPt1->SetBinContent(i + 1, vResPt1[i]->GetStdDev()); - resPt1->SetBinError(i + 1, vResPt1[i]->GetStdDevError()); - } - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for extended prompt " - "pT resolution (2-3) cannot be found!\n"; - } - - if (std::find(displaced_respt_pt2to3.begin(), displaced_respt_pt2to3.end(), nullptr) == - displaced_respt_pt2to3.end()) { - // Set the current directoy - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Displaced/FinalResolution"); - - // Grab the histograms - std::vector vResPt1 = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - for (int i = 0; i < 6; i++) { - vResPt1[i] = displaced_respt_pt2to3[i]->getTH1F(); - } - - // Book the new histogram to contain the results - MonitorElement *me_res_pt1 = ibooker.book1D( - "pTResVsEta_2-3_displaced", "p_{T} resolution vs |#eta|, for p_{T}: 2-3 GeV", eta_binnum, eta_bins); - TH1F *resPt1 = me_res_pt1->getTH1F(); - resPt1->GetXaxis()->SetTitle("tracking particle |#eta|"); - resPt1->GetYaxis()->SetTitle("#sigma(#Delta p_{T}/p_{T})"); - resPt1->SetMinimum(0.0); - resPt1->SetStats(false); - - for (int i = 0; i < 6; i++) { - resPt1->SetBinContent(i + 1, vResPt1[i]->GetStdDev()); - resPt1->SetBinError(i + 1, vResPt1[i]->GetStdDevError()); - } - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for extended displaced pT resolution (2-3) cannot " - "be found!\n"; - } - - // nominal collection - if (std::find(respt_pt3to8.begin(), respt_pt3to8.end(), nullptr) == respt_pt3to8.end()) { - // Set the current directoy - igetter.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/FinalResolution"); - - // Grab the histograms - std::vector vResPt2 = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - for (int i = 0; i < 6; i++) { - vResPt2[i] = respt_pt3to8[i]->getTH1F(); - } - - // Book the new histogram to contain the results - MonitorElement *me_res_pt2 = - ibooker.book1D("pTResVsEta_3-8", "p_{T} resolution vs |#eta|, for p_{T}: 3-8 GeV", eta_binnum, eta_bins); - TH1F *resPt2 = me_res_pt2->getTH1F(); - resPt2->GetXaxis()->SetTitle("tracking particle |#eta|"); - resPt2->GetYaxis()->SetTitle("#sigma(#Deltap_{T}/p_{T})"); - resPt2->SetMinimum(0.0); - resPt2->SetStats(false); - - for (int i = 0; i < 6; i++) { - resPt2->SetBinContent(i + 1, vResPt2[i]->GetStdDev()); - resPt2->SetBinError(i + 1, vResPt2[i]->GetStdDevError()); - } - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for pT resolution (3-8) cannot be found!\n"; - } - - // extended collection - // prompt - if (std::find(prompt_respt_pt3to8.begin(), prompt_respt_pt3to8.end(), nullptr) == prompt_respt_pt3to8.end()) { - // Set the current directoy - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Prompt/FinalResolution"); - - // Grab the histograms - std::vector vResPt2 = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - for (int i = 0; i < 6; i++) { - vResPt2[i] = prompt_respt_pt3to8[i]->getTH1F(); - } - - // Book the new histogram to contain the results - MonitorElement *me_res_pt2 = - ibooker.book1D("pTResVsEta_3-8_prompt", "p_{T} resolution vs |#eta|, for p_{T}: 3-8 GeV", eta_binnum, eta_bins); - TH1F *resPt2 = me_res_pt2->getTH1F(); - resPt2->GetXaxis()->SetTitle("tracking particle |#eta|"); - resPt2->GetYaxis()->SetTitle("#sigma(#Deltap_{T}/p_{T})"); - resPt2->SetMinimum(0.0); - resPt2->SetStats(false); - - for (int i = 0; i < 6; i++) { - resPt2->SetBinContent(i + 1, vResPt2[i]->GetStdDev()); - resPt2->SetBinError(i + 1, vResPt2[i]->GetStdDevError()); - } - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for pT resolution " - "(3-8) (prompt) cannot be found!\n"; - } - - // displaced - if (std::find(displaced_respt_pt3to8.begin(), displaced_respt_pt3to8.end(), nullptr) == - displaced_respt_pt3to8.end()) { - // Set the current directoy - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Displaced/FinalResolution"); - - // Grab the histograms - std::vector vResPt2 = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - for (int i = 0; i < 6; i++) { - vResPt2[i] = displaced_respt_pt3to8[i]->getTH1F(); - } - - // Book the new histogram to contain the results - MonitorElement *me_res_pt2 = ibooker.book1D( - "pTResVsEta_3-8_displaced", "p_{T} resolution vs |#eta|, for p_{T}: 3-8 GeV", eta_binnum, eta_bins); - TH1F *resPt2 = me_res_pt2->getTH1F(); - resPt2->GetXaxis()->SetTitle("tracking particle |#eta|"); - resPt2->GetYaxis()->SetTitle("#sigma(#Deltap_{T}/p_{T})"); - resPt2->SetMinimum(0.0); - resPt2->SetStats(false); - - for (int i = 0; i < 6; i++) { - resPt2->SetBinContent(i + 1, vResPt2[i]->GetStdDev()); - resPt2->SetBinError(i + 1, vResPt2[i]->GetStdDevError()); - } - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for pT resolution " - "(3-8) (displaced) cannot be found!\n"; - } - - // nominal collection - if (std::find(respt_pt8toInf.begin(), respt_pt8toInf.end(), nullptr) == respt_pt8toInf.end()) { - // Set the current directoy - igetter.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/FinalResolution"); - - // Grab the histograms - std::vector vResPt3 = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - for (int i = 0; i < 6; i++) { - vResPt3[i] = respt_pt8toInf[i]->getTH1F(); - } - - // Book the new histogram to contain the results - MonitorElement *me_res_pt3 = - ibooker.book1D("pTResVsEta_8-inf", "p_{T} resolution vs |#eta|, for p_{T}: >8 GeV", eta_binnum, eta_bins); - TH1F *resPt3 = me_res_pt3->getTH1F(); - resPt3->GetXaxis()->SetTitle("tracking particle |#eta|"); - resPt3->GetYaxis()->SetTitle("#sigma(#Deltap_{T}/p_{T})"); - resPt3->SetMinimum(0.0); - resPt3->SetStats(false); - - for (int i = 0; i < 6; i++) { - resPt3->SetBinContent(i + 1, vResPt3[i]->GetStdDev()); - resPt3->SetBinError(i + 1, vResPt3[i]->GetStdDevError()); - } - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for pT resolution (8-inf) cannot be found!\n"; - } - - // extended collection - // prompt - if (std::find(prompt_respt_pt8toInf.begin(), prompt_respt_pt8toInf.end(), nullptr) == prompt_respt_pt8toInf.end()) { - // Set the current directoy - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Prompt/FinalResolution"); - - // Grab the histograms - std::vector vResPt3 = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - for (int i = 0; i < 6; i++) { - vResPt3[i] = prompt_respt_pt8toInf[i]->getTH1F(); - } - - // Book the new histogram to contain the results - MonitorElement *me_res_pt3 = ibooker.book1D( - "pTResVsEta_8-inf_prompt", "p_{T} resolution vs |#eta|, for p_{T}: >8 GeV", eta_binnum, eta_bins); - TH1F *resPt3 = me_res_pt3->getTH1F(); - resPt3->GetXaxis()->SetTitle("tracking particle |#eta|"); - resPt3->GetYaxis()->SetTitle("#sigma(#Deltap_{T}/p_{T})"); - resPt3->SetMinimum(0.0); - resPt3->SetStats(false); - - for (int i = 0; i < 6; i++) { - resPt3->SetBinContent(i + 1, vResPt3[i]->GetStdDev()); - resPt3->SetBinError(i + 1, vResPt3[i]->GetStdDevError()); - } - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for pT resolution " - "(8-inf) (prompt) cannot be found!\n"; - } - - // displaced - if (std::find(displaced_respt_pt8toInf.begin(), displaced_respt_pt8toInf.end(), nullptr) == - displaced_respt_pt8toInf.end()) { - // Set the current directoy - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Displaced/FinalResolution"); - - // Grab the histograms - std::vector vResPt3 = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - for (int i = 0; i < 6; i++) { - vResPt3[i] = displaced_respt_pt8toInf[i]->getTH1F(); - } - - // Book the new histogram to contain the results - MonitorElement *me_res_pt3 = ibooker.book1D( - "pTResVsEta_8-inf_displaced", "p_{T} resolution vs |#eta|, for p_{T}: >8 GeV", eta_binnum, eta_bins); - TH1F *resPt3 = me_res_pt3->getTH1F(); - resPt3->GetXaxis()->SetTitle("tracking particle |#eta|"); - resPt3->GetYaxis()->SetTitle("#sigma(#Deltap_{T}/p_{T})"); - resPt3->SetMinimum(0.0); - resPt3->SetStats(false); - - for (int i = 0; i < 6; i++) { - resPt3->SetBinContent(i + 1, vResPt3[i]->GetStdDev()); - resPt3->SetBinError(i + 1, vResPt3[i]->GetStdDevError()); - } - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for pT resolution " - "(8-inf) (displaced) cannot be found!\n"; - } - - // nominal collection eta resolution - if (std::find(mereseta_vect.begin(), mereseta_vect.end(), nullptr) == mereseta_vect.end()) { - // Set the current directoy - igetter.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/FinalResolution"); - - // Grab the histograms - std::vector vResEta = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - for (int i = 0; i < 6; i++) { - vResEta[i] = mereseta_vect[i]->getTH1F(); - } - - // Book the new histogram to contain the results - MonitorElement *me_res_eta = ibooker.book1D("EtaResolution", "#eta resolution vs |#eta|", eta_binnum, eta_bins); - TH1F *resEta = me_res_eta->getTH1F(); - resEta->GetXaxis()->SetTitle("tracking particle |#eta|"); - resEta->GetYaxis()->SetTitle("#sigma(#Delta#eta)"); - resEta->SetMinimum(0.0); - resEta->SetStats(false); - - for (int i = 0; i < 6; i++) { - resEta->SetBinContent(i + 1, vResEta[i]->GetStdDev()); - resEta->SetBinError(i + 1, vResEta[i]->GetStdDevError()); - } - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for eta resolution cannot be found!\n"; - } - - // extended collection eta resolution - // prompt - if (std::find(prompt_mereseta_vect.begin(), prompt_mereseta_vect.end(), nullptr) == prompt_mereseta_vect.end()) { - // Set the current director - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Prompt/FinalResolution"); - std::vector vResEta(6, nullptr); - for (int i = 0; i < 6; i++) { - vResEta[i] = prompt_mereseta_vect[i]->getTH1F(); - } - - // Book the new histogram to contain the results - MonitorElement *me_res_eta = - ibooker.book1D("EtaResolution_prompt", "#eta resolution vs |#eta|", eta_binnum, eta_bins); - TH1F *resEta = me_res_eta->getTH1F(); - resEta->GetXaxis()->SetTitle("tracking particle |#eta|"); - resEta->GetYaxis()->SetTitle("#sigma(#Delta#eta)"); - resEta->SetMinimum(0.0); - resEta->SetStats(false); - - for (int i = 0; i < 6; i++) { - resEta->SetBinContent(i + 1, vResEta[i]->GetStdDev()); - resEta->SetBinError(i + 1, vResEta[i]->GetStdDevError()); - } - } else { - edm::LogWarning("DataNotFound") << "Monitor elements for eta resolution (prompt) cannot be found!"; - } - - // displaced - if (std::find(displaced_mereseta_vect.begin(), displaced_mereseta_vect.end(), nullptr) == - displaced_mereseta_vect.end()) { - // Set the current director - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Displaced/FinalResolution"); - std::vector vResEta(6, nullptr); - for (int i = 0; i < 6; i++) { - vResEta[i] = displaced_mereseta_vect[i]->getTH1F(); - } - - // Book the new histogram to contain the results - MonitorElement *me_res_eta = - ibooker.book1D("EtaResolution_displaced", "#eta resolution vs |#eta|", eta_binnum, eta_bins); - TH1F *resEta = me_res_eta->getTH1F(); - resEta->GetXaxis()->SetTitle("tracking particle |#eta|"); - resEta->GetYaxis()->SetTitle("#sigma(#Delta#eta)"); - resEta->SetMinimum(0.0); - resEta->SetStats(false); - - for (int i = 0; i < 6; i++) { - resEta->SetBinContent(i + 1, vResEta[i]->GetStdDev()); - resEta->SetBinError(i + 1, vResEta[i]->GetStdDevError()); - } - } else { - edm::LogWarning("DataNotFound") << "Monitor elements for eta resolution (displaced) cannot be found!"; - } - - // nominal collection phi resolution - if (std::find(meresphi_vect.begin(), meresphi_vect.end(), nullptr) == meresphi_vect.end()) { - // Set the current directoy - igetter.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/FinalResolution"); - - // Grab the histograms - std::vector vResPhi = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - for (int i = 0; i < 6; i++) { - vResPhi[i] = meresphi_vect[i]->getTH1F(); - } - - // Book the new histogram to contain the results - MonitorElement *me_res_phi = ibooker.book1D("PhiResolution", "#phi resolution vs |#eta|", eta_binnum, eta_bins); - TH1F *resPhi = me_res_phi->getTH1F(); - resPhi->GetXaxis()->SetTitle("tracking particle |#eta|"); - resPhi->GetYaxis()->SetTitle("#sigma(#Delta#phi)"); - resPhi->SetMinimum(0.0); - resPhi->SetStats(false); - - for (int i = 0; i < 6; i++) { - resPhi->SetBinContent(i + 1, vResPhi[i]->GetStdDev()); - resPhi->SetBinError(i + 1, vResPhi[i]->GetStdDevError()); - } - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for phi resolution cannot be found!\n"; - } - - // extended collection phi resolution - // prompt - if (std::find(prompt_meresphi_vect.begin(), prompt_meresphi_vect.end(), nullptr) == prompt_meresphi_vect.end()) { - // Set the current directoy - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Prompt/FinalResolution"); - - // Grab the histograms - std::vector vResPhi = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - for (int i = 0; i < 6; i++) { - vResPhi[i] = prompt_meresphi_vect[i]->getTH1F(); - } - - // Book the new histogram to contain the results - MonitorElement *me_res_phi = - ibooker.book1D("PhiResolution_prompt", "#phi resolution vs |#eta|", eta_binnum, eta_bins); - TH1F *resPhi = me_res_phi->getTH1F(); - resPhi->GetXaxis()->SetTitle("tracking particle |#eta|"); - resPhi->GetYaxis()->SetTitle("#sigma(#Delta#phi)"); - resPhi->SetMinimum(0.0); - resPhi->SetStats(false); - - for (int i = 0; i < 6; i++) { - resPhi->SetBinContent(i + 1, vResPhi[i]->GetStdDev()); - resPhi->SetBinError(i + 1, vResPhi[i]->GetStdDevError()); - } - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for phi resolution (prompt) cannot be found!\n"; - } - - // displaced - if (std::find(displaced_meresphi_vect.begin(), displaced_meresphi_vect.end(), nullptr) == - displaced_meresphi_vect.end()) { - // Set the current directoy - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Displaced/FinalResolution"); - - // Grab the histograms - std::vector vResPhi = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - for (int i = 0; i < 6; i++) { - vResPhi[i] = displaced_meresphi_vect[i]->getTH1F(); - } - - // Book the new histogram to contain the results - MonitorElement *me_res_phi = - ibooker.book1D("PhiResolution_displaced", "#phi resolution vs |#eta|", eta_binnum, eta_bins); - TH1F *resPhi = me_res_phi->getTH1F(); - resPhi->GetXaxis()->SetTitle("tracking particle |#eta|"); - resPhi->GetYaxis()->SetTitle("#sigma(#Delta#phi)"); - resPhi->SetMinimum(0.0); - resPhi->SetStats(false); - - for (int i = 0; i < 6; i++) { - resPhi->SetBinContent(i + 1, vResPhi[i]->GetStdDev()); - resPhi->SetBinError(i + 1, vResPhi[i]->GetStdDevError()); - } - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for phi resolution (displaced) cannot be found!\n"; - } - - // nominal collection z0 resolution - if (std::find(meresz0_vect.begin(), meresz0_vect.end(), nullptr) == meresz0_vect.end()) { - // Set the current directoy - igetter.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/FinalResolution"); - - // Grab the histograms - std::vector vResz0 = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - for (int i = 0; i < 6; i++) { - vResz0[i] = meresz0_vect[i]->getTH1F(); - } - - // Book the new histogram to contain the results - MonitorElement *me_res_z0 = ibooker.book1D("z0Resolution", "z0 resolution vs |#eta|", eta_binnum, eta_bins); - TH1F *resz0 = me_res_z0->getTH1F(); - resz0->GetXaxis()->SetTitle("tracking particle |#eta|"); - resz0->GetYaxis()->SetTitle("#sigma(#Deltaz0) [cm]"); - resz0->SetMinimum(0.0); - resz0->SetStats(false); - - for (int i = 0; i < 6; i++) { - resz0->SetBinContent(i + 1, vResz0[i]->GetStdDev()); - resz0->SetBinError(i + 1, vResz0[i]->GetStdDevError()); - } - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for z0 resolution cannot be found!\n"; - } - - // extended collection z0 resolution - // prompt - if (std::find(prompt_meresz0_vect.begin(), prompt_meresz0_vect.end(), nullptr) == prompt_meresz0_vect.end()) { - // Set the current directoy - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Prompt/FinalResolution"); - - // Grab the histograms - std::vector vResz0 = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - for (int i = 0; i < 6; i++) { - vResz0[i] = prompt_meresz0_vect[i]->getTH1F(); - } - - // Book the new histogram to contain the results - MonitorElement *me_res_z0 = ibooker.book1D("z0Resolution_prompt", "z0 resolution vs |#eta|", eta_binnum, eta_bins); - TH1F *resz0 = me_res_z0->getTH1F(); - resz0->GetXaxis()->SetTitle("tracking particle |#eta|"); - resz0->GetYaxis()->SetTitle("#sigma(#Deltaz0) [cm]"); - resz0->SetMinimum(0.0); - resz0->SetStats(false); - - for (int i = 0; i < 6; i++) { - resz0->SetBinContent(i + 1, vResz0[i]->GetStdDev()); - resz0->SetBinError(i + 1, vResz0[i]->GetStdDevError()); - } - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for z0 resolution (prompt) cannot be found!\n"; - } - - // displaced - if (std::find(displaced_meresz0_vect.begin(), displaced_meresz0_vect.end(), nullptr) == - displaced_meresz0_vect.end()) { - // Set the current directoy - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Displaced/FinalResolution"); - - // Grab the histograms - std::vector vResz0 = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - for (int i = 0; i < 6; i++) { - vResz0[i] = displaced_meresz0_vect[i]->getTH1F(); - } - - // Book the new histogram to contain the results - MonitorElement *me_res_z0 = - ibooker.book1D("z0Resolution_displaced", "z0 resolution vs |#eta|", eta_binnum, eta_bins); - TH1F *resz0 = me_res_z0->getTH1F(); - resz0->GetXaxis()->SetTitle("tracking particle |#eta|"); - resz0->GetYaxis()->SetTitle("#sigma(#Deltaz0) [cm]"); - resz0->SetMinimum(0.0); - resz0->SetStats(false); - - for (int i = 0; i < 6; i++) { - resz0->SetBinContent(i + 1, vResz0[i]->GetStdDev()); - resz0->SetBinError(i + 1, vResz0[i]->GetStdDevError()); - } - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for z0 resolution (displaced) cannot be found!\n"; - } - - // nominal collection d0 resolution - if (std::find(meresd0_vect.begin(), meresd0_vect.end(), nullptr) == meresd0_vect.end()) { - // Set the current directoy - igetter.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/FinalResolution"); - - // Grab the histograms - std::vector vResD0 = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - for (int i = 0; i < 6; i++) { - vResD0[i] = meresd0_vect[i]->getTH1F(); - } - - // Book the new histogram to contain the results - MonitorElement *me_res_d0 = ibooker.book1D("d0Resolution", "d_{0} resolution vs |#eta|", eta_binnum, eta_bins); - TH1F *resd0 = me_res_d0->getTH1F(); - resd0->GetXaxis()->SetTitle("tracking particle |#eta|"); - resd0->GetYaxis()->SetTitle("#sigma(#Deltad_{0}) [cm]"); - resd0->SetMinimum(0.0); - resd0->SetStats(false); - - for (int i = 0; i < 6; i++) { - resd0->SetBinContent(i + 1, vResD0[i]->GetStdDev()); - resd0->SetBinError(i + 1, vResD0[i]->GetStdDevError()); - } - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for d0 resolution cannot be found!\n"; - } - - // extended collection d0 resolution - // prompt - if (std::find(prompt_meresd0_vect.begin(), prompt_meresd0_vect.end(), nullptr) == prompt_meresd0_vect.end()) { - // Set the current directoy - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Prompt/FinalResolution"); - - // Grab the histograms - std::vector vResD0 = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - for (int i = 0; i < 6; i++) { - vResD0[i] = prompt_meresd0_vect[i]->getTH1F(); - } - - // Book the new histogram to contain the results - MonitorElement *me_res_d0 = - ibooker.book1D("d0Resolution_prompt", "d_{0} resolution vs |#eta|", eta_binnum, eta_bins); - TH1F *resd0 = me_res_d0->getTH1F(); - resd0->GetXaxis()->SetTitle("tracking particle |#eta|"); - resd0->GetYaxis()->SetTitle("#sigma(#Deltad_{0}) [cm]"); - resd0->SetMinimum(0.0); - resd0->SetStats(false); - - for (int i = 0; i < 6; i++) { - resd0->SetBinContent(i + 1, vResD0[i]->GetStdDev()); - resd0->SetBinError(i + 1, vResD0[i]->GetStdDevError()); - } - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for d0 resolution (prompt) cannot be found!\n"; - } - - // displaced - if (std::find(displaced_meresd0_vect.begin(), displaced_meresd0_vect.end(), nullptr) == - displaced_meresd0_vect.end()) { - // Set the current directoy - igetter.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Displaced/FinalResolution"); - - // Grab the histograms - std::vector vResD0 = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; - for (int i = 0; i < 6; i++) { - vResD0[i] = displaced_meresd0_vect[i]->getTH1F(); - } - - // Book the new histogram to contain the results - MonitorElement *me_res_d0 = - ibooker.book1D("d0Resolution_displaced", "d_{0} resolution vs |#eta|", eta_binnum, eta_bins); - TH1F *resd0 = me_res_d0->getTH1F(); - resd0->GetXaxis()->SetTitle("tracking particle |#eta|"); - resd0->GetYaxis()->SetTitle("#sigma(#Deltad_{0}) [cm]"); - resd0->SetMinimum(0.0); - resd0->SetStats(false); - - for (int i = 0; i < 6; i++) { - resd0->SetBinContent(i + 1, vResD0[i]->GetStdDev()); - resd0->SetBinError(i + 1, vResD0[i]->GetStdDevError()); - } - } // if ME found - else { - edm::LogWarning("DataNotFound") << "Monitor elements for d0 resolution (displaced) cannot be found!\n"; - } + std::string resIng = topFolderName_ + "/Nominal_L1TF/ResolutionIngredients/"; + respt_pt2to3[i] = igetter.get(resIng + "respt_" + eta_ranges[i] + "_pt2to3"); + respt_pt3to8[i] = igetter.get(resIng + "respt_" + eta_ranges[i] + "_pt3to8"); + respt_pt8toInf[i] = igetter.get(resIng + "respt_" + eta_ranges[i] + "_pt8toInf"); + mereseta_vect[i] = igetter.get(resIng + "reseta_" + eta_ranges[i]); + meresphi_vect[i] = igetter.get(resIng + "resphi_" + eta_ranges[i]); + meresz0_vect[i] = igetter.get(resIng + "resz0_" + eta_ranges[i]); + meresd0_vect[i] = igetter.get(resIng + "resd0_" + eta_ranges[i]); + + std::string promptIng = topFolderName_ + "/Extended_L1TF/Prompt/ResolutionIngredients/"; + prompt_respt_pt2to3[i] = igetter.get(promptIng + "respt_prompt_" + eta_ranges[i] + "_pt2to3"); + prompt_respt_pt3to8[i] = igetter.get(promptIng + "respt_prompt_" + eta_ranges[i] + "_pt3to8"); + prompt_respt_pt8toInf[i] = igetter.get(promptIng + "respt_prompt_" + eta_ranges[i] + "_pt8toInf"); + prompt_mereseta_vect[i] = igetter.get(promptIng + "reseta_prompt_" + eta_ranges[i]); + prompt_meresphi_vect[i] = igetter.get(promptIng + "resphi_prompt_" + eta_ranges[i]); + prompt_meresz0_vect[i] = igetter.get(promptIng + "resz0_prompt_" + eta_ranges[i]); + prompt_meresd0_vect[i] = igetter.get(promptIng + "resd0_prompt_" + eta_ranges[i]); + + std::string dispIng = topFolderName_ + "/Extended_L1TF/Displaced/ResolutionIngredients/"; + displaced_respt_pt2to3[i] = igetter.get(dispIng + "respt_displaced_" + eta_ranges[i] + "_pt2to3"); + displaced_respt_pt3to8[i] = igetter.get(dispIng + "respt_displaced_" + eta_ranges[i] + "_pt3to8"); + displaced_respt_pt8toInf[i] = igetter.get(dispIng + "respt_displaced_" + eta_ranges[i] + "_pt8toInf"); + displaced_mereseta_vect[i] = igetter.get(dispIng + "reseta_displaced_" + eta_ranges[i]); + displaced_meresphi_vect[i] = igetter.get(dispIng + "resphi_displaced_" + eta_ranges[i]); + displaced_meresz0_vect[i] = igetter.get(dispIng + "resz0_displaced_" + eta_ranges[i]); + displaced_meresd0_vect[i] = igetter.get(dispIng + "resd0_displaced_" + eta_ranges[i]); + } + + // Final Resolutions - Nominal + ibooker.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/FinalResolution"); + phase2tkutil::fillResolutionFromVec(respt_pt2to3, ibooker.book1D("pTResVsEta_2-3", ";|#eta|;#sigma(#Delta p_{T}/p_{T})", eta_binnum, eta_bins), ""); + phase2tkutil::fillResolutionFromVec(respt_pt3to8, ibooker.book1D("pTResVsEta_3-8", ";|#eta|;#sigma(#Delta p_{T}/p_{T})", eta_binnum, eta_bins), ""); + phase2tkutil::fillResolutionFromVec(respt_pt8toInf, ibooker.book1D("pTResVsEta_8-inf", ";|#eta|;#sigma(#Delta p_{T}/p_{T})", eta_binnum, eta_bins), ""); + phase2tkutil::fillResolutionFromVec(mereseta_vect, ibooker.book1D("EtaResolution", ";|#eta|;#sigma(#Delta#eta)", eta_binnum, eta_bins), ""); + phase2tkutil::fillResolutionFromVec(meresphi_vect, ibooker.book1D("PhiResolution", ";|#eta|;#sigma(#Delta#phi)", eta_binnum, eta_bins), ""); + phase2tkutil::fillResolutionFromVec(meresz0_vect, ibooker.book1D("z0Resolution", ";|#eta|;#sigma(#Deltaz0) [cm]", eta_binnum, eta_bins), ""); + phase2tkutil::fillResolutionFromVec(meresd0_vect, ibooker.book1D("d0Resolution", ";|#eta|;#sigma(#Deltad_{0}) [cm]", eta_binnum, eta_bins), ""); + + // Final Resolutions - Prompt + ibooker.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Prompt/FinalResolution"); + phase2tkutil::fillResolutionFromVec(prompt_respt_pt2to3, ibooker.book1D("pTResVsEta_2-3_prompt", ";|#eta|;#sigma(#Delta p_{T}/p_{T})", eta_binnum, eta_bins), ""); + phase2tkutil::fillResolutionFromVec(prompt_respt_pt3to8, ibooker.book1D("pTResVsEta_3-8_prompt", ";|#eta|;#sigma(#Delta p_{T}/p_{T})", eta_binnum, eta_bins), ""); + phase2tkutil::fillResolutionFromVec(prompt_respt_pt8toInf, ibooker.book1D("pTResVsEta_8-inf_prompt", ";|#eta|;#sigma(#Delta p_{T}/p_{T})", eta_binnum, eta_bins), ""); + phase2tkutil::fillResolutionFromVec(prompt_mereseta_vect, ibooker.book1D("EtaResolution_prompt", ";|#eta|;#sigma(#Delta#eta)", eta_binnum, eta_bins), ""); + phase2tkutil::fillResolutionFromVec(prompt_meresphi_vect, ibooker.book1D("PhiResolution_prompt", ";|#eta|;#sigma(#Delta#phi)", eta_binnum, eta_bins), ""); + phase2tkutil::fillResolutionFromVec(prompt_meresz0_vect, ibooker.book1D("z0Resolution_prompt", ";|#eta|;#sigma(#Deltaz0) [cm]", eta_binnum, eta_bins), ""); + phase2tkutil::fillResolutionFromVec(prompt_meresd0_vect, ibooker.book1D("d0Resolution_prompt", ";|#eta|;#sigma(#Deltad_{0}) [cm]", eta_binnum, eta_bins), ""); + + // Final Resolutions - Displaced + ibooker.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Displaced/FinalResolution"); + phase2tkutil::fillResolutionFromVec(displaced_respt_pt2to3, ibooker.book1D("pTResVsEta_2-3_displaced", ";|#eta|;#sigma(#Delta p_{T}/p_{T})", eta_binnum, eta_bins), ""); + phase2tkutil::fillResolutionFromVec(displaced_respt_pt3to8, ibooker.book1D("pTResVsEta_3-8_displaced", ";|#eta|;#sigma(#Delta p_{T}/p_{T})", eta_binnum, eta_bins), ""); + phase2tkutil::fillResolutionFromVec(displaced_respt_pt8toInf, ibooker.book1D("pTResVsEta_8-inf_displaced", ";|#eta|;#sigma(#Delta p_{T}/p_{T})", eta_binnum, eta_bins), ""); + phase2tkutil::fillResolutionFromVec(displaced_mereseta_vect, ibooker.book1D("EtaResolution_displaced", ";|#eta|;#sigma(#Delta#eta)", eta_binnum, eta_bins), ""); + phase2tkutil::fillResolutionFromVec(displaced_meresphi_vect, ibooker.book1D("PhiResolution_displaced", ";|#eta|;#sigma(#Delta#phi)", eta_binnum, eta_bins), ""); + phase2tkutil::fillResolutionFromVec(displaced_meresz0_vect, ibooker.book1D("z0Resolution_displaced", ";|#eta|;#sigma(#Deltaz0) [cm]", eta_binnum, eta_bins), ""); + phase2tkutil::fillResolutionFromVec(displaced_meresd0_vect, ibooker.book1D("d0Resolution_displaced", ";|#eta|;#sigma(#Deltad_{0}) [cm]", eta_binnum, eta_bins), ""); } // end dqmEndJob - #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" #include "FWCore/ParameterSet/interface/ParameterSetDescription.h" void Phase2OTHarvestTracks::fillDescriptions(edm::ConfigurationDescriptions &descriptions) { From 39e20926024aa9865602d782f1e7223e75cf818a Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Wed, 21 Jan 2026 23:15:45 +0100 Subject: [PATCH 13/61] add detailed hists to sub-folder and reduce range for deltaPhi hists --- .../plugins/Phase2OTValidateStub.cc | 500 +++++++----------- 1 file changed, 202 insertions(+), 298 deletions(-) diff --git a/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateStub.cc b/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateStub.cc index 6fd174e1b5704..2fc464b4142c9 100644 --- a/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateStub.cc +++ b/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateStub.cc @@ -51,6 +51,7 @@ #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" #include "L1Trigger/TrackFindingTracklet/interface/Settings.h" #include "SimDataFormats/Associations/interface/TTStubAssociationMap.h" +#include "Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h" #include "Validation/SiTrackerPhase2V/interface/TrackerPhase2ValidationUtil.h" class Phase2OTValidateStub : public DQMEDAnalyzer { @@ -76,33 +77,47 @@ class Phase2OTValidateStub : public DQMEDAnalyzer { // Global position of the stubs MonitorElement* Stub_RZ = nullptr; // TTStub #rho vs. z - // delta_z hists + // delta_z hists barrel MonitorElement* z_res_isPS_barrel = nullptr; MonitorElement* z_res_is2S_barrel = nullptr; - // delta_r hists + // delta_r hists endcaps + MonitorElement* r_res_isPS_endcap = nullptr; + MonitorElement* r_res_is2S_endcap = nullptr; + + // delta_r hists (Split into FW/BW) MonitorElement* r_res_isPS_fw_endcap = nullptr; MonitorElement* r_res_is2S_fw_endcap = nullptr; MonitorElement* r_res_isPS_bw_endcap = nullptr; MonitorElement* r_res_is2S_bw_endcap = nullptr; - - // delta_phi hists + + // delta_phi hists (PS / 2S, barrel vs endcap) MonitorElement* phi_res_isPS_barrel = nullptr; MonitorElement* phi_res_is2S_barrel = nullptr; + MonitorElement* phi_res_isPS_endcap = nullptr; // FW + BW combined + MonitorElement* phi_res_is2S_endcap = nullptr; // FW + BW combined + + // delta_phi hists (Specific FW/BW and Barrel layers) MonitorElement* phi_res_fw_endcap = nullptr; MonitorElement* phi_res_bw_endcap = nullptr; std::vector phi_res_barrel_layers; std::vector phi_res_fw_endcap_discs; std::vector phi_res_bw_endcap_discs; - // delta_bend hists + // delta_bend hists (PS / 2S, barrel vs endcap) + MonitorElement* bend_res_isPS_barrel = nullptr; + MonitorElement* bend_res_is2S_barrel = nullptr; + MonitorElement* bend_res_isPS_endcap = nullptr; // FW + BW combined + MonitorElement* bend_res_is2S_endcap = nullptr; // FW + BW combined + + // delta_bend hists (General barrel/endcap and Barrel layers) MonitorElement* bend_res_fw_endcap = nullptr; MonitorElement* bend_res_bw_endcap = nullptr; - MonitorElement* bend_res_barrel = nullptr; std::vector bend_res_barrel_layers; std::vector bend_res_fw_endcap_discs; std::vector bend_res_bw_endcap_discs; + // Helper vectors std::vector* phi_res_vec = nullptr; std::vector* bend_res_vec = nullptr; @@ -171,22 +186,6 @@ Phase2OTValidateStub::~Phase2OTValidateStub() { void Phase2OTValidateStub::dqmBeginRun(const edm::Run& iRun, const edm::EventSetup& iSetup) { tkGeom_ = &(iSetup.getData(geomToken_)); tTopo_ = &(iSetup.getData(topoToken_)); - - // Clear existing histograms - phi_res_barrel_layers.clear(); - bend_res_barrel_layers.clear(); - phi_res_fw_endcap_discs.clear(); - bend_res_fw_endcap_discs.clear(); - phi_res_bw_endcap_discs.clear(); - bend_res_bw_endcap_discs.clear(); - - // Resize vectors and set elements to nullptr - phi_res_barrel_layers.resize(trklet::N_LAYER, nullptr); - bend_res_barrel_layers.resize(trklet::N_LAYER, nullptr); - phi_res_fw_endcap_discs.resize(trklet::N_DISK, nullptr); - bend_res_fw_endcap_discs.resize(trklet::N_DISK, nullptr); - phi_res_bw_endcap_discs.resize(trklet::N_DISK, nullptr); - bend_res_bw_endcap_discs.resize(trklet::N_DISK, nullptr); } // member functions @@ -283,7 +282,7 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet double c_ = settings.c(); // Geometries - const TrackerGeometry* theTrackerGeom = tkGeom_; + //const TrackerGeometry* theTrackerGeom = tkGeom_; const TrackerTopology* tTopo = tTopo_; /// Loop over input Stubs for basic histogram filling (e.g., Stub_RZ) @@ -466,25 +465,59 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet float phiRes = tp_phi - stub_phi; float rRes = tp_r - stub_r; - // Histograms for z_res, phi_res, and r_res based on module type and - // location + // Histograms for z_res, phi_res, bend_res, and r_res based on module type and location if (isBarrel == 1) { - bend_res_barrel->Fill(bendRes); + // --- BARREL LOGIC --- + phi_res_vec = &phi_res_barrel_layers; + bend_res_vec = &bend_res_barrel_layers; + if (isPSmodule) { z_res_isPS_barrel->Fill(zRes); phi_res_isPS_barrel->Fill(phiRes); + bend_res_isPS_barrel->Fill(bendRes); } else { z_res_is2S_barrel->Fill(zRes); phi_res_is2S_barrel->Fill(phiRes); + bend_res_is2S_barrel->Fill(bendRes); } } else { + // --- ENDCAP LOGIC --- + + // Fill Summary Endcap plots + if (isPSmodule) { + r_res_isPS_endcap->Fill(rRes); + phi_res_isPS_endcap->Fill(phiRes); + bend_res_isPS_endcap->Fill(bendRes); + } else { + r_res_is2S_endcap->Fill(rRes); + phi_res_is2S_endcap->Fill(phiRes); + bend_res_is2S_endcap->Fill(bendRes); + } + + // Specific FW/BW Logic (ONLY runs if NOT Barrel) if (stub_maxZ > 0) { + // Forward Endcap + bend_res_fw_endcap->Fill(bendRes); + phi_res_fw_endcap->Fill(phiRes); + + // Set pointers to FW vectors + phi_res_vec = &phi_res_fw_endcap_discs; + bend_res_vec = &bend_res_fw_endcap_discs; + if (isPSmodule) { r_res_isPS_fw_endcap->Fill(rRes); } else { r_res_is2S_fw_endcap->Fill(rRes); } } else { + // Backward Endcap + bend_res_bw_endcap->Fill(bendRes); + phi_res_bw_endcap->Fill(phiRes); + + // Set pointers to BW vectors + phi_res_vec = &phi_res_bw_endcap_discs; + bend_res_vec = &bend_res_bw_endcap_discs; + if (isPSmodule) { r_res_isPS_bw_endcap->Fill(rRes); } else { @@ -493,30 +526,21 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet } } - // Ensure that the vectors are correctly assigned before use - if (isBarrel == 1) { - phi_res_vec = &phi_res_barrel_layers; - bend_res_vec = &bend_res_barrel_layers; + // --- SAFE FILLING --- + // Now we fill the vector. Because of the logic above, + // phi_res_vec is guaranteed to match the isBarrel state. + + if (isBarrel) { + if (layer >= 1 && layer <= trklet::N_LAYER) { + (*bend_res_vec)[layer - 1]->Fill(bendRes); + (*phi_res_vec)[layer - 1]->Fill(phiRes); + } } else { - if (stub_maxZ > 0) { - // Forward endcap - bend_res_fw_endcap->Fill(bendRes); - phi_res_fw_endcap->Fill(phiRes); - phi_res_vec = &phi_res_fw_endcap_discs; - bend_res_vec = &bend_res_fw_endcap_discs; - } else { - // Backward endcap - bend_res_bw_endcap->Fill(bendRes); - phi_res_bw_endcap->Fill(phiRes); - phi_res_vec = &phi_res_bw_endcap_discs; - bend_res_vec = &bend_res_bw_endcap_discs; + if (layer >= 1 && layer <= trklet::N_DISK) { + (*bend_res_vec)[layer - 1]->Fill(bendRes); + (*phi_res_vec)[layer - 1]->Fill(phiRes); } } - // Fill the appropriate histogram based on layer/disc - if (layer >= 1 && layer <= trklet::N_LAYER) { - (*bend_res_vec)[layer - 1]->Fill(bendRes); - (*phi_res_vec)[layer - 1]->Fill(phiRes); - } } // end loop over input stubs } // end loop over geometric detectors @@ -577,7 +601,7 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet if (nStubTP < TP_minNStub || nStubLayerTP < TP_minNLayersStub) continue; - // Find all clusters that can be associated to a tracking particle with at + /*// Find all clusters that can be associated to a tracking particle with at // least one hit std::vector>, TTCluster>> associatedClusters = MCTruthTTClusterHandle->findTTClusterRefs(tp_ptr); @@ -664,7 +688,70 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet } // end if stub cluster coords.x matches associated cluster coords.x } // end loop over stubs on the same detid as associated clusters } // end if stubs on same detid - } // end loop over associated clusters + } // end loop over associated clusters*/ + + // -------------------------------------------------------------------------------- + // NEW LOGIC: "Flag Method" (One entry per TP) + // -------------------------------------------------------------------------------- + + // 1. Check for Clusters (Denominator Flags) + bool hasBarrelCluster = false; + bool hasEndcapCluster = false; + + if (MCTruthTTClusterHandle.isValid()) { + auto associatedClusters = MCTruthTTClusterHandle->findTTClusterRefs(tp_ptr); + for (const auto& clus : associatedClusters) { + if (!MCTruthTTClusterHandle->isGenuine(clus)) continue; + + DetId detid = clus->getDetId(); + if (detid.subdetId() == StripSubdetector::TOB) hasBarrelCluster = true; + else if (detid.subdetId() == StripSubdetector::TID) hasEndcapCluster = true; + + if (hasBarrelCluster && hasEndcapCluster) break; // Optimization + } + } + + // 2. Check for Stubs (Numerator Flags) + // Using direct reference matching (Safe & Fast) + bool hasBarrelStub = false; + bool hasEndcapStub = false; + + if (MCTruthTTStubHandle.isValid()) { + // We can re-use 'theStubRefs' calculated at the top of the loop + for (const auto& stub : theStubRefs) { + if (!MCTruthTTStubHandle->isGenuine(stub)) continue; + + DetId detid = stub->getDetId(); + if (detid.subdetId() == StripSubdetector::TOB) hasBarrelStub = true; + else if (detid.subdetId() == StripSubdetector::TID) hasEndcapStub = true; + + if (hasBarrelStub && hasEndcapStub) break; // Optimization + } + } + + // 3. Fill Histograms (Once per TP) + + // Barrel Region + if (hasBarrelCluster) { + gen_clusters_barrel->Fill(tmp_tp_pt); + gen_clusters_zoom_barrel->Fill(tmp_tp_pt); + + if (hasBarrelStub) { + gen_clusters_if_stub_barrel->Fill(tmp_tp_pt); + gen_clusters_if_stub_zoom_barrel->Fill(tmp_tp_pt); + } + } + + // Endcap Region + if (hasEndcapCluster) { + gen_clusters_endcaps->Fill(tmp_tp_pt); + gen_clusters_zoom_endcaps->Fill(tmp_tp_pt); + + if (hasEndcapStub) { + gen_clusters_if_stub_endcaps->Fill(tmp_tp_pt); + gen_clusters_if_stub_zoom_endcaps->Fill(tmp_tp_pt); + } + } } // end loop over tracking particles } // end of method @@ -677,6 +764,15 @@ void Phase2OTValidateStub::bookHistograms(DQMStore::IBooker& iBooker, edm::Run c edm::ParameterSet psBend_Res = conf_.getParameter("TH1Bend_Res"); edm::ParameterSet psEffic_pt = conf_.getParameter("TH1Effic_pt"); edm::ParameterSet psEffic_pt_zoom = conf_.getParameter("TH1Effic_pt_zoom"); + using phase2tkutil::book1DFromPS; + + phi_res_barrel_layers.assign(trklet::N_LAYER, nullptr); + bend_res_barrel_layers.assign(trklet::N_LAYER, nullptr); + phi_res_fw_endcap_discs.assign(trklet::N_DISK, nullptr); + bend_res_fw_endcap_discs.assign(trklet::N_DISK, nullptr); + phi_res_bw_endcap_discs.assign(trklet::N_DISK, nullptr); + bend_res_bw_endcap_discs.assign(trklet::N_DISK, nullptr); + std::string HistoName; iBooker.setCurrentFolder(topFolderName_); // 2D histogram for stub_RZ @@ -691,260 +787,68 @@ void Phase2OTValidateStub::bookHistograms(DQMStore::IBooker& iBooker, edm::Run c psTTStub_RZ.getParameter("ymax")); iBooker.setCurrentFolder(topFolderName_ + "/Residual"); - // z-res for PS modules - HistoName = "#Delta z Barrel PS modules"; - z_res_isPS_barrel = iBooker.book1D(HistoName, - HistoName, - ps_PS_Res.getParameter("Nbinsx"), - ps_PS_Res.getParameter("xmin"), - ps_PS_Res.getParameter("xmax")); - z_res_isPS_barrel->setAxisTitle("tp_z - stub_z", 1); - z_res_isPS_barrel->setAxisTitle("events ", 2); - - // z-res for 2S modules - HistoName = "#Delta z Barrel 2S modules"; - z_res_is2S_barrel = iBooker.book1D(HistoName, - HistoName, - ps_2S_Res.getParameter("Nbinsx"), - ps_2S_Res.getParameter("xmin"), - ps_2S_Res.getParameter("xmax")); - z_res_is2S_barrel->setAxisTitle("tp_z - stub_z [cm]", 1); - z_res_is2S_barrel->setAxisTitle("events ", 2); - - // r-res for fw endcap PS modules - HistoName = "#Delta r FW Endcap PS modules"; - r_res_isPS_fw_endcap = iBooker.book1D(HistoName, - HistoName, - ps_PS_Res.getParameter("Nbinsx"), - ps_PS_Res.getParameter("xmin"), - ps_PS_Res.getParameter("xmax")); - r_res_isPS_fw_endcap->setAxisTitle("tp_r - stub_r [cm]", 1); - r_res_isPS_fw_endcap->setAxisTitle("events ", 2); - - // r-res for fw endcap 2S modules - HistoName = "#Delta r FW Endcap 2S modules"; - r_res_is2S_fw_endcap = iBooker.book1D(HistoName, - HistoName, - ps_2S_Res.getParameter("Nbinsx"), - ps_2S_Res.getParameter("xmin"), - ps_2S_Res.getParameter("xmax")); - r_res_is2S_fw_endcap->setAxisTitle("tp_r - stub_r [cm]", 1); - r_res_is2S_fw_endcap->setAxisTitle("events ", 2); - - // r-res for bw endcap PS modules - HistoName = "#Delta r BW Endcap PS modules"; - r_res_isPS_bw_endcap = iBooker.book1D(HistoName, - HistoName, - ps_PS_Res.getParameter("Nbinsx"), - ps_PS_Res.getParameter("xmin"), - ps_PS_Res.getParameter("xmax")); - r_res_isPS_bw_endcap->setAxisTitle("tp_r - stub_r [cm]", 1); - r_res_isPS_bw_endcap->setAxisTitle("events ", 2); - - // r-res for bw endcap 2S modules - HistoName = "#Delta r BW Endcap 2S modules"; - r_res_is2S_bw_endcap = iBooker.book1D(HistoName, - HistoName, - ps_2S_Res.getParameter("Nbinsx"), - ps_2S_Res.getParameter("xmin"), - ps_2S_Res.getParameter("xmax")); - r_res_is2S_bw_endcap->setAxisTitle("tp_r - stub_r [cm]", 1); - r_res_is2S_bw_endcap->setAxisTitle("events ", 2); - - // histograms for phi_res and bend_res - HistoName = "#Delta #phi Barrel PS modules"; - phi_res_isPS_barrel = iBooker.book1D(HistoName, - HistoName, - psPhi_Res.getParameter("Nbinsx"), - psPhi_Res.getParameter("xmin"), - psPhi_Res.getParameter("xmax")); - phi_res_isPS_barrel->setAxisTitle("tp_phi - stub_phi", 1); - phi_res_isPS_barrel->setAxisTitle("events", 2); - - HistoName = "#Delta #phi Barrel 2S modules"; - phi_res_is2S_barrel = iBooker.book1D(HistoName, - HistoName, - psPhi_Res.getParameter("Nbinsx"), - psPhi_Res.getParameter("xmin"), - psPhi_Res.getParameter("xmax")); - - HistoName = "#Delta #phi FW Endcap"; - phi_res_fw_endcap = iBooker.book1D(HistoName, - HistoName, - psPhi_Res.getParameter("Nbinsx"), - psPhi_Res.getParameter("xmin"), - psPhi_Res.getParameter("xmax")); - - HistoName = "#Delta #phi BW Endcap"; - phi_res_bw_endcap = iBooker.book1D(HistoName, - HistoName, - psPhi_Res.getParameter("Nbinsx"), - psPhi_Res.getParameter("xmin"), - psPhi_Res.getParameter("xmax")); - - HistoName = "#Delta bend FW Endcap"; - bend_res_fw_endcap = iBooker.book1D(HistoName, - HistoName, - psBend_Res.getParameter("Nbinsx"), - psBend_Res.getParameter("xmin"), - psBend_Res.getParameter("xmax")); - - HistoName = "#Delta bend BW Endcap"; - bend_res_bw_endcap = iBooker.book1D(HistoName, - HistoName, - psBend_Res.getParameter("Nbinsx"), - psBend_Res.getParameter("xmin"), - psBend_Res.getParameter("xmax")); - - HistoName = "#Delta bend Barrel"; - bend_res_barrel = iBooker.book1D(HistoName, - HistoName, - psBend_Res.getParameter("Nbinsx"), - psBend_Res.getParameter("xmin"), - psBend_Res.getParameter("xmax")); - - // barrel layers + // z residuals barrel (Summary) + z_res_isPS_barrel = book1DFromPS(iBooker, "#Delta z Barrel PS modules", ps_PS_Res, "tp_z - stub_z", "events"); + z_res_is2S_barrel = book1DFromPS(iBooker, "#Delta z Barrel 2S modules", ps_2S_Res, "tp_z - stub_z [cm]", "events"); + + // r residuals endcaps (Summary) + r_res_isPS_endcap = book1DFromPS(iBooker, "#Delta r Endcaps PS modules", ps_PS_Res, "tp_r - stub_r [cm]", "events"); + r_res_is2S_endcap = book1DFromPS(iBooker, "#Delta r Endcaps 2S modules", ps_2S_Res, "tp_r - stub_r [cm]", "events"); + + // phi residuals (PS / 2S, barrel vs endcaps) (Summary) + phi_res_isPS_barrel = book1DFromPS(iBooker, "#Delta #phi Barrel PS modules", psPhi_Res, "tp_phi - stub_phi", "events"); + phi_res_is2S_barrel = book1DFromPS(iBooker, "#Delta #phi Barrel 2S modules", psPhi_Res, "tp_phi - stub_phi", "events"); + phi_res_isPS_endcap = book1DFromPS(iBooker, "#Delta #phi Endcaps PS modules", psPhi_Res, "tp_phi - stub_phi", "events"); + phi_res_is2S_endcap = book1DFromPS(iBooker, "#Delta #phi Endcaps 2S modules", psPhi_Res, "tp_phi - stub_phi", "events"); + + // bend residuals (PS / 2S, barrel vs endcaps) (Summary) + bend_res_isPS_barrel = book1DFromPS(iBooker, "#Delta bend Barrel PS modules", psBend_Res, "tp_bend - stub_bend", "events"); + bend_res_is2S_barrel = book1DFromPS(iBooker, "#Delta bend Barrel 2S modules", psBend_Res, "tp_bend - stub_bend", "events"); + bend_res_isPS_endcap = book1DFromPS(iBooker, "#Delta bend Endcaps PS modules", psBend_Res, "tp_bend - stub_bend", "events"); + bend_res_is2S_endcap = book1DFromPS(iBooker, "#Delta bend Endcaps 2S modules", psBend_Res, "tp_bend - stub_bend", "events"); + + iBooker.setCurrentFolder(topFolderName_ + "/Residual/Detailed"); + + // Detailed Endcap R-Residuals (Split by FW/BW) + r_res_isPS_fw_endcap = book1DFromPS(iBooker, "#Delta r FW Endcap PS modules", ps_PS_Res, "tp_r - stub_r [cm]", "events"); + r_res_is2S_fw_endcap = book1DFromPS(iBooker, "#Delta r FW Endcap 2S modules", ps_2S_Res, "tp_r - stub_r [cm]", "events"); + r_res_isPS_bw_endcap = book1DFromPS(iBooker, "#Delta r BW Endcap PS modules", ps_PS_Res, "tp_r - stub_r [cm]", "events"); + r_res_is2S_bw_endcap = book1DFromPS(iBooker, "#Delta r BW Endcap 2S modules", ps_2S_Res, "tp_r - stub_r [cm]", "events"); + + // Detailed Endcap Phi/Bend (Split by FW/BW) + phi_res_fw_endcap = book1DFromPS(iBooker, "#Delta #phi FW Endcap", psPhi_Res, "tp_phi - stub_phi", "events"); + phi_res_bw_endcap = book1DFromPS(iBooker, "#Delta #phi BW Endcap", psPhi_Res, "tp_phi - stub_phi", "events"); + bend_res_fw_endcap = book1DFromPS(iBooker, "#Delta bend FW Endcap", psBend_Res, "tp_bend - stub_bend", "events"); + bend_res_bw_endcap = book1DFromPS(iBooker, "#Delta bend BW Endcap", psBend_Res, "tp_bend - stub_bend", "events"); + + // Barrel Layers (Per Layer) for (int i = 0; i < trklet::N_LAYER; ++i) { - std::string HistoName = "#Delta #phi Barrel L" + std::to_string(i + 1); - phi_res_barrel_layers[i] = iBooker.book1D(HistoName, - HistoName, - psPhi_Res.getParameter("Nbinsx"), - psPhi_Res.getParameter("xmin"), - psPhi_Res.getParameter("xmax")); - phi_res_barrel_layers[i]->setAxisTitle("tp_phi - stub_phi", 1); - phi_res_barrel_layers[i]->setAxisTitle("events", 2); - - HistoName = "#Delta bend Barrel L" + std::to_string(i + 1); - bend_res_barrel_layers[i] = iBooker.book1D(HistoName, - HistoName, - psBend_Res.getParameter("Nbinsx"), - psBend_Res.getParameter("xmin"), - psBend_Res.getParameter("xmax")); - bend_res_barrel_layers[i]->setAxisTitle("tp_bend - stub_bend", 1); - bend_res_barrel_layers[i]->setAxisTitle("events", 2); + std::string layerParams = "L" + std::to_string(i + 1); + phi_res_barrel_layers[i] = book1DFromPS(iBooker, "#Delta #phi Barrel " + layerParams, psPhi_Res, "tp_phi - stub_phi", "events"); + bend_res_barrel_layers[i] = book1DFromPS(iBooker, "#Delta bend Barrel " + layerParams, psBend_Res, "tp_bend - stub_bend", "events"); } - // endcap discs + // Endcap Disks (Per Disk, Split FW/BW) for (int i = 0; i < trklet::N_DISK; ++i) { - std::string HistoName = "#Delta #phi FW Endcap D" + std::to_string(i + 1); - phi_res_fw_endcap_discs[i] = iBooker.book1D(HistoName, - HistoName, - psPhi_Res.getParameter("Nbinsx"), - psPhi_Res.getParameter("xmin"), - psPhi_Res.getParameter("xmax")); - phi_res_fw_endcap_discs[i]->setAxisTitle("tp_phi - stub_phi", 1); - phi_res_fw_endcap_discs[i]->setAxisTitle("events", 2); - - HistoName = "#Delta bend FW Endcap D" + std::to_string(i + 1); - bend_res_fw_endcap_discs[i] = iBooker.book1D(HistoName, - HistoName, - psBend_Res.getParameter("Nbinsx"), - psBend_Res.getParameter("xmin"), - psBend_Res.getParameter("xmax")); - bend_res_fw_endcap_discs[i]->setAxisTitle("tp_bend - stub_bend", 1); - bend_res_fw_endcap_discs[i]->setAxisTitle("events", 2); - - HistoName = "#Delta #phi BW Endcap D" + std::to_string(i + 1); - phi_res_bw_endcap_discs[i] = iBooker.book1D(HistoName, - HistoName, - psPhi_Res.getParameter("Nbinsx"), - psPhi_Res.getParameter("xmin"), - psPhi_Res.getParameter("xmax")); - phi_res_bw_endcap_discs[i]->setAxisTitle("tp_phi - stub_phi", 1); - phi_res_bw_endcap_discs[i]->setAxisTitle("events", 2); - - HistoName = "#Delta bend BW Endcap D" + std::to_string(i + 1); - bend_res_bw_endcap_discs[i] = iBooker.book1D(HistoName, - HistoName, - psBend_Res.getParameter("Nbinsx"), - psBend_Res.getParameter("xmin"), - psBend_Res.getParameter("xmax")); - bend_res_bw_endcap_discs[i]->setAxisTitle("tp_bend - stub_bend", 1); - bend_res_bw_endcap_discs[i]->setAxisTitle("events", 2); + std::string diskParams = "D" + std::to_string(i + 1); + phi_res_fw_endcap_discs[i] = book1DFromPS(iBooker, "#Delta #phi FW Endcap " + diskParams, psPhi_Res, "tp_phi - stub_phi", "events"); + bend_res_fw_endcap_discs[i] = book1DFromPS(iBooker, "#Delta bend FW Endcap " + diskParams, psBend_Res, "tp_bend - stub_bend", "events"); + phi_res_bw_endcap_discs[i] = book1DFromPS(iBooker, "#Delta #phi BW Endcap " + diskParams, psPhi_Res, "tp_phi - stub_phi", "events"); + bend_res_bw_endcap_discs[i] = book1DFromPS(iBooker, "#Delta bend BW Endcap " + diskParams, psBend_Res, "tp_bend - stub_bend", "events"); } - // 1D plots for efficiency + // 1D plots for stub efficiency vs pT iBooker.setCurrentFolder(topFolderName_ + "/EfficiencyIngredients"); - // Gen clusters barrel - HistoName = "gen_clusters_barrel"; - gen_clusters_barrel = iBooker.book1D(HistoName, - HistoName, - psEffic_pt.getParameter("Nbinsx"), - psEffic_pt.getParameter("xmin"), - psEffic_pt.getParameter("xmax")); - gen_clusters_barrel->setAxisTitle("p_{T} [GeV]", 1); - gen_clusters_barrel->setAxisTitle("# tracking particles", 2); - - // Gen clusters if stub barrel - HistoName = "gen_clusters_if_stub_barrel"; - gen_clusters_if_stub_barrel = iBooker.book1D(HistoName, - HistoName, - psEffic_pt.getParameter("Nbinsx"), - psEffic_pt.getParameter("xmin"), - psEffic_pt.getParameter("xmax")); - gen_clusters_if_stub_barrel->setAxisTitle("p_{T} [GeV]", 1); - gen_clusters_if_stub_barrel->setAxisTitle("# tracking particles", 2); - - // Gen clusters endcaps - HistoName = "gen_clusters_endcaps"; - gen_clusters_endcaps = iBooker.book1D(HistoName, - HistoName, - psEffic_pt.getParameter("Nbinsx"), - psEffic_pt.getParameter("xmin"), - psEffic_pt.getParameter("xmax")); - gen_clusters_endcaps->setAxisTitle("p_{T} [GeV]", 1); - gen_clusters_endcaps->setAxisTitle("# tracking particles", 2); - - // Gen clusters if stub endcaps - HistoName = "gen_clusters_if_stub_endcaps"; - gen_clusters_if_stub_endcaps = iBooker.book1D(HistoName, - HistoName, - psEffic_pt.getParameter("Nbinsx"), - psEffic_pt.getParameter("xmin"), - psEffic_pt.getParameter("xmax")); - gen_clusters_if_stub_endcaps->setAxisTitle("p_{T} [GeV]", 1); - gen_clusters_if_stub_endcaps->setAxisTitle("# tracking particles", 2); - - // Gen clusters pT zoom (0-10 GeV) barrel - HistoName = "gen_clusters_zoom_barrel"; - gen_clusters_zoom_barrel = iBooker.book1D(HistoName, - HistoName, - psEffic_pt_zoom.getParameter("Nbinsx"), - psEffic_pt_zoom.getParameter("xmin"), - psEffic_pt_zoom.getParameter("xmax")); - gen_clusters_zoom_barrel->setAxisTitle("p_{T} [GeV]", 1); - gen_clusters_zoom_barrel->setAxisTitle("# tracking particles", 2); - - // Gen cluters if stub pT zoom (0-10 GeV) barrel - HistoName = "gen_clusters_if_stub_zoom_barrel"; - gen_clusters_if_stub_zoom_barrel = iBooker.book1D(HistoName, - HistoName, - psEffic_pt_zoom.getParameter("Nbinsx"), - psEffic_pt_zoom.getParameter("xmin"), - psEffic_pt_zoom.getParameter("xmax")); - gen_clusters_if_stub_zoom_barrel->setAxisTitle("p_{T} [GeV]", 1); - gen_clusters_if_stub_zoom_barrel->setAxisTitle("# tracking particles", 2); - - // Gen clusters pT zoom (0-10 GeV) endcaps - HistoName = "gen_clusters_zoom_endcaps"; - gen_clusters_zoom_endcaps = iBooker.book1D(HistoName, - HistoName, - psEffic_pt_zoom.getParameter("Nbinsx"), - psEffic_pt_zoom.getParameter("xmin"), - psEffic_pt_zoom.getParameter("xmax")); - gen_clusters_zoom_endcaps->setAxisTitle("p_{T} [GeV]", 1); - gen_clusters_zoom_endcaps->setAxisTitle("# tracking particles", 2); - - // Gen cluters if stub pT zoom (0-10 GeV) endcaps - HistoName = "gen_clusters_if_stub_zoom_endcaps"; - gen_clusters_if_stub_zoom_endcaps = iBooker.book1D(HistoName, - HistoName, - psEffic_pt_zoom.getParameter("Nbinsx"), - psEffic_pt_zoom.getParameter("xmin"), - psEffic_pt_zoom.getParameter("xmax")); - gen_clusters_if_stub_zoom_endcaps->setAxisTitle("p_{T} [GeV]", 1); - gen_clusters_if_stub_zoom_endcaps->setAxisTitle("# tracking particles", 2); + gen_clusters_barrel = book1DFromPS(iBooker, "gen_clusters_barrel", psEffic_pt, "p_{T} [GeV]", "# tracking particles"); + gen_clusters_if_stub_barrel = book1DFromPS(iBooker, "gen_clusters_if_stub_barrel", psEffic_pt, "p_{T} [GeV]", "# tracking particles"); + gen_clusters_endcaps = book1DFromPS(iBooker, "gen_clusters_endcaps", psEffic_pt, "p_{T} [GeV]", "# tracking particles"); + gen_clusters_if_stub_endcaps = book1DFromPS(iBooker, "gen_clusters_if_stub_endcaps", psEffic_pt, "p_{T} [GeV]", "# tracking particles"); + + gen_clusters_zoom_barrel = book1DFromPS(iBooker, "gen_clusters_zoom_barrel", psEffic_pt_zoom, "p_{T} [GeV]", "# tracking particles"); + gen_clusters_if_stub_zoom_barrel = book1DFromPS(iBooker, "gen_clusters_if_stub_zoom_barrel", psEffic_pt_zoom, "p_{T} [GeV]", "# tracking particles"); + gen_clusters_zoom_endcaps = book1DFromPS(iBooker, "gen_clusters_zoom_endcaps", psEffic_pt_zoom, "p_{T} [GeV]", "# tracking particles"); + gen_clusters_if_stub_zoom_endcaps= book1DFromPS(iBooker, "gen_clusters_if_stub_zoom_endcaps",psEffic_pt_zoom, "p_{T} [GeV]", "# tracking particles"); } void Phase2OTValidateStub::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { @@ -976,9 +880,9 @@ void Phase2OTValidateStub::fillDescriptions(edm::ConfigurationDescriptions& desc } { edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 599); - psd0.add("xmax", 0.1); - psd0.add("xmin", -0.1); + psd0.add("Nbinsx", 100); + psd0.add("xmax", 0.025); + psd0.add("xmin", -0.025); desc.add("TH1Phi_Res", psd0); } { From f73480f31338c63b5e5aaeffdf8de3fe345359d3 Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Wed, 21 Jan 2026 23:18:53 +0100 Subject: [PATCH 14/61] edit comments --- .../plugins/Phase2OTValidateStub.cc | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateStub.cc b/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateStub.cc index 2fc464b4142c9..87b24ed625677 100644 --- a/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateStub.cc +++ b/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateStub.cc @@ -481,7 +481,6 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet bend_res_is2S_barrel->Fill(bendRes); } } else { - // --- ENDCAP LOGIC --- // Fill Summary Endcap plots if (isPSmodule) { @@ -525,10 +524,6 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet } } } - - // --- SAFE FILLING --- - // Now we fill the vector. Because of the logic above, - // phi_res_vec is guaranteed to match the isBarrel state. if (isBarrel) { if (layer >= 1 && layer <= trklet::N_LAYER) { @@ -694,7 +689,7 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet // NEW LOGIC: "Flag Method" (One entry per TP) // -------------------------------------------------------------------------------- - // 1. Check for Clusters (Denominator Flags) + // Check for Clusters (Denominator Flags) bool hasBarrelCluster = false; bool hasEndcapCluster = false; @@ -711,8 +706,8 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet } } - // 2. Check for Stubs (Numerator Flags) - // Using direct reference matching (Safe & Fast) + // Check for Stubs (Numerator Flags) + // Using direct reference matching bool hasBarrelStub = false; bool hasEndcapStub = false; @@ -729,7 +724,7 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet } } - // 3. Fill Histograms (Once per TP) + // Fill Histograms (Once per TP) // Barrel Region if (hasBarrelCluster) { From 1c8648feb5843a557d6f69f68466907aa8d2e849 Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Mon, 26 Jan 2026 19:25:27 +0100 Subject: [PATCH 15/61] add weights for stub efficiency hists --- .../plugins/Phase2OTValidateStub.cc | 110 ++++++------------ 1 file changed, 36 insertions(+), 74 deletions(-) diff --git a/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateStub.cc b/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateStub.cc index 87b24ed625677..b0b85ff92cfe4 100644 --- a/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateStub.cc +++ b/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateStub.cc @@ -282,7 +282,7 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet double c_ = settings.c(); // Geometries - //const TrackerGeometry* theTrackerGeom = tkGeom_; + const TrackerGeometry* theTrackerGeom = tkGeom_; const TrackerTopology* tTopo = tTopo_; /// Loop over input Stubs for basic histogram filling (e.g., Stub_RZ) @@ -560,6 +560,10 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet layer = static_cast(tTopo->layer(detid)) + 5; // fill in array as entries 6-10 // treat genuine stubs separately (==2 is genuine, ==1 is not) + // Prioritize "Genuine" stubs (value 2) over "Combinatorial/Unknown" stubs (value 1) + // Check if the stub is NOT genuine (findTrackingParticlePtr is null) + // If it is NOT genuine, only record it as '1' if we haven't already found a genuine stub (value < 2) in this layer + // Otherwise (the stub IS genuine), strictly mark the layer as '2', overwriting any previous '1' if (MCTruthTTStubHandle->findTrackingParticlePtr(theStubRefs.at(is)).isNull() && hasStubInLayer[layer] < 2) hasStubInLayer[layer] = 1; else @@ -596,11 +600,26 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet if (nStubTP < TP_minNStub || nStubLayerTP < TP_minNLayersStub) continue; - /*// Find all clusters that can be associated to a tracking particle with at + // Find all clusters that can be associated to a tracking particle with at // least one hit std::vector>, TTCluster>> associatedClusters = MCTruthTTClusterHandle->findTTClusterRefs(tp_ptr); + int nValidClustersBarrel = 0; + int nValidClustersEndcap = 0; + + // Count genuine clusters first + for (const auto& clus : associatedClusters) { + if (!MCTruthTTClusterHandle->isGenuine(clus)) continue; + DetId detid = clus->getDetId(); + if (detid.subdetId() == StripSubdetector::TOB) nValidClustersBarrel++; + else if (detid.subdetId() == StripSubdetector::TID) nValidClustersEndcap++; + } + + // Define weights (1.0 / N) + float weightBarrel = (nValidClustersBarrel > 0) ? 1.0f / nValidClustersBarrel : 0.0f; + float weightEndcap = (nValidClustersEndcap > 0) ? 1.0f / nValidClustersEndcap : 0.0f; + // Loop through associated clusters for (std::size_t k = 0; k < associatedClusters.size(); ++k) { auto clusA = associatedClusters[k]; @@ -614,6 +633,10 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet if (!isGenuine) continue; + // apply weight + bool isBarrelBool = (clusdetid.subdetId() == StripSubdetector::TOB); + float currentWeight = isBarrelBool ? weightBarrel : weightEndcap; + DetId detidA = tTopo->stack(clusdetid); const GeomDetUnit* detA = theTrackerGeom->idToDetUnit(clusdetid); const PixelGeomDetUnit* theGeomDetA = dynamic_cast(detA); @@ -630,12 +653,13 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet edm::LogVerbatim("Tracklet") << "WARNING -- neither TOB or TID stub, shouldn't happen..."; } + // modified for weights if (isBarrel == 1) { - gen_clusters_barrel->Fill(tmp_tp_pt); - gen_clusters_zoom_barrel->Fill(tmp_tp_pt); + gen_clusters_barrel->Fill(tmp_tp_pt, currentWeight); + gen_clusters_zoom_barrel->Fill(tmp_tp_pt, currentWeight); } else { - gen_clusters_endcaps->Fill(tmp_tp_pt); - gen_clusters_zoom_endcaps->Fill(tmp_tp_pt); + gen_clusters_endcaps->Fill(tmp_tp_pt, currentWeight); + gen_clusters_zoom_endcaps->Fill(tmp_tp_pt, currentWeight); } // If there are stubs on the same detid, loop on those stubs @@ -671,82 +695,20 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet continue; float stub_tp_pt = stubTP->pt(); if (stub_tp_pt == tmp_tp_pt) { + // modified for weights if (isBarrel == 1) { - gen_clusters_if_stub_barrel->Fill(tmp_tp_pt); - gen_clusters_if_stub_zoom_barrel->Fill(tmp_tp_pt); + gen_clusters_if_stub_barrel->Fill(tmp_tp_pt, currentWeight); + gen_clusters_if_stub_zoom_barrel->Fill(tmp_tp_pt, currentWeight); } else { - gen_clusters_if_stub_endcaps->Fill(tmp_tp_pt); - gen_clusters_if_stub_zoom_endcaps->Fill(tmp_tp_pt); + gen_clusters_if_stub_endcaps->Fill(tmp_tp_pt, currentWeight); + gen_clusters_if_stub_zoom_endcaps->Fill(tmp_tp_pt, currentWeight); } break; } } // end if stub cluster coords.x matches associated cluster coords.x } // end loop over stubs on the same detid as associated clusters } // end if stubs on same detid - } // end loop over associated clusters*/ - - // -------------------------------------------------------------------------------- - // NEW LOGIC: "Flag Method" (One entry per TP) - // -------------------------------------------------------------------------------- - - // Check for Clusters (Denominator Flags) - bool hasBarrelCluster = false; - bool hasEndcapCluster = false; - - if (MCTruthTTClusterHandle.isValid()) { - auto associatedClusters = MCTruthTTClusterHandle->findTTClusterRefs(tp_ptr); - for (const auto& clus : associatedClusters) { - if (!MCTruthTTClusterHandle->isGenuine(clus)) continue; - - DetId detid = clus->getDetId(); - if (detid.subdetId() == StripSubdetector::TOB) hasBarrelCluster = true; - else if (detid.subdetId() == StripSubdetector::TID) hasEndcapCluster = true; - - if (hasBarrelCluster && hasEndcapCluster) break; // Optimization - } - } - - // Check for Stubs (Numerator Flags) - // Using direct reference matching - bool hasBarrelStub = false; - bool hasEndcapStub = false; - - if (MCTruthTTStubHandle.isValid()) { - // We can re-use 'theStubRefs' calculated at the top of the loop - for (const auto& stub : theStubRefs) { - if (!MCTruthTTStubHandle->isGenuine(stub)) continue; - - DetId detid = stub->getDetId(); - if (detid.subdetId() == StripSubdetector::TOB) hasBarrelStub = true; - else if (detid.subdetId() == StripSubdetector::TID) hasEndcapStub = true; - - if (hasBarrelStub && hasEndcapStub) break; // Optimization - } - } - - // Fill Histograms (Once per TP) - - // Barrel Region - if (hasBarrelCluster) { - gen_clusters_barrel->Fill(tmp_tp_pt); - gen_clusters_zoom_barrel->Fill(tmp_tp_pt); - - if (hasBarrelStub) { - gen_clusters_if_stub_barrel->Fill(tmp_tp_pt); - gen_clusters_if_stub_zoom_barrel->Fill(tmp_tp_pt); - } - } - - // Endcap Region - if (hasEndcapCluster) { - gen_clusters_endcaps->Fill(tmp_tp_pt); - gen_clusters_zoom_endcaps->Fill(tmp_tp_pt); - - if (hasEndcapStub) { - gen_clusters_if_stub_endcaps->Fill(tmp_tp_pt); - gen_clusters_if_stub_zoom_endcaps->Fill(tmp_tp_pt); - } - } + } // end loop over associated clusters } // end loop over tracking particles } // end of method From 4cf52e5da07caea8bad82c2c9a74c127d8efe96e Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Mon, 26 Jan 2026 23:05:32 +0100 Subject: [PATCH 16/61] add code to make number of stubs per event hist --- .../plugins/Phase2OTValidateStub.cc | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateStub.cc b/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateStub.cc index b0b85ff92cfe4..75c76d3676967 100644 --- a/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateStub.cc +++ b/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateStub.cc @@ -77,6 +77,9 @@ class Phase2OTValidateStub : public DQMEDAnalyzer { // Global position of the stubs MonitorElement* Stub_RZ = nullptr; // TTStub #rho vs. z + // Number of stubs per event + MonitorElement* number_of_stubs = nullptr; + // delta_z hists barrel MonitorElement* z_res_isPS_barrel = nullptr; MonitorElement* z_res_is2S_barrel = nullptr; @@ -294,6 +297,12 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet return; } + int nStubs = 0; + for (auto const& detSet : *Phase2TrackerDigiTTStubHandle) { + nStubs += detSet.size(); + } + number_of_stubs->Fill(nStubs); + for (inputIter = Phase2TrackerDigiTTStubHandle->begin(); inputIter != Phase2TrackerDigiTTStubHandle->end(); ++inputIter) { for (contentIter = inputIter->begin(); contentIter != inputIter->end(); ++contentIter) { @@ -715,6 +724,7 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet // ------------ method called when starting to processes a run ------------ void Phase2OTValidateStub::bookHistograms(DQMStore::IBooker& iBooker, edm::Run const& run, edm::EventSetup const& es) { edm::ParameterSet psTTStub_RZ = conf_.getParameter("TH2TTStub_RZ"); + edm::ParameterSet psNStubs = conf_.getParameter("TH1NStubs"); edm::ParameterSet ps_2S_Res = conf_.getParameter("TH1_2S_Res"); edm::ParameterSet ps_PS_Res = conf_.getParameter("TH1_PS_Res"); edm::ParameterSet psPhi_Res = conf_.getParameter("TH1Phi_Res"); @@ -743,6 +753,9 @@ void Phase2OTValidateStub::bookHistograms(DQMStore::IBooker& iBooker, edm::Run c psTTStub_RZ.getParameter("ymin"), psTTStub_RZ.getParameter("ymax")); + // number of stubs histogram + number_of_stubs = book1DFromPS(iBooker, "number_of_stubs", psNStubs, "# stubs", "events"); + iBooker.setCurrentFolder(topFolderName_ + "/Residual"); // z residuals barrel (Summary) z_res_isPS_barrel = book1DFromPS(iBooker, "#Delta z Barrel PS modules", ps_PS_Res, "tp_z - stub_z", "events"); @@ -821,6 +834,13 @@ void Phase2OTValidateStub::fillDescriptions(edm::ConfigurationDescriptions& desc psd0.add("ymin", 0); desc.add("TH2TTStub_RZ", psd0); } + { + edm::ParameterSetDescription psd0; + psd0.add("Nbinsx", 100); + psd0.add("xmax", 25000); + psd0.add("xmin", 0); + desc.add("TH1NStubs", psd0); + } { edm::ParameterSetDescription psd0; psd0.add("Nbinsx", 99); From 6401193916ee6ddef9416d0e2bfd5ec2f07f4912 Mon Sep 17 00:00:00 2001 From: Havyn Ancelin Date: Thu, 11 Dec 2025 17:44:41 -0600 Subject: [PATCH 17/61] updated phi matching for very low pt, particularly for bending angles --- .../L1TMuonPhase2/interface/Constants.h | 8 +- .../L1TMuonPhase2/interface/MuonStub.h | 5 + DataFormats/L1TMuonPhase2/src/MuonStub.cc | 49 +++++ .../Phase2L1GMT/interface/ConvertedTTTrack.h | 61 ++++-- .../interface/PreTrackMatchedMuon.h | 131 ++++++++++-- .../Phase2L1GMT/interface/TPSAlgorithm.h | 16 +- .../Phase2L1GMT/interface/TrackConverter.h | 8 +- .../plugins/Phase2L1TGMTStubProducer.cc | 6 +- .../src/L1TPhase2GMTBarrelStubProcessor.cc | 5 +- L1Trigger/Phase2L1GMT/src/TPS.cc | 71 +++++-- L1Trigger/Phase2L1GMT/src/TPSAlgorithm.cc | 200 ++++++++++++++++-- L1Trigger/Phase2L1GMT/src/TrackConverter.cc | 11 +- 12 files changed, 473 insertions(+), 98 deletions(-) diff --git a/DataFormats/L1TMuonPhase2/interface/Constants.h b/DataFormats/L1TMuonPhase2/interface/Constants.h index 89859db2d1c43..539cb47ca7bbf 100644 --- a/DataFormats/L1TMuonPhase2/interface/Constants.h +++ b/DataFormats/L1TMuonPhase2/interface/Constants.h @@ -31,11 +31,11 @@ namespace Phase2L1GMT { const int BITSSTUBCOORD = 10; const int BITSSTUBETA = 8; const int BITSSTUBID = 12; - const int BITSSTUBPHIQUALITY = 4; - const int BITSSTUBETAQUALITY = 4; - const int BITSSTUBTIME = 8; + const int BITSSTUBPHIQUALITY = 2; + const int BITSSTUBETAQUALITY = 2; + const int BITSSTUBTIME = 5; const int BITSSTAMUONQUALITY = 6; - const int BITSMUONBX = 4; + const int BITSMUONBX = 3; //PreTrackMatherdMuon const int BITSMATCHQUALITY = 9; diff --git a/DataFormats/L1TMuonPhase2/interface/MuonStub.h b/DataFormats/L1TMuonPhase2/interface/MuonStub.h index 70902648a96b0..6e09e4a4af6fd 100644 --- a/DataFormats/L1TMuonPhase2/interface/MuonStub.h +++ b/DataFormats/L1TMuonPhase2/interface/MuonStub.h @@ -29,6 +29,7 @@ //#include "DataFormats/L1TMuon/interface/BMTF/L1MuBMTrackSegLoc.h" #include "DataFormats/L1Trigger/interface/BXVector.h" #include "DataFormats/Common/interface/Ref.h" +#include "DataFormats/L1TMuonPhase2/interface/Constants.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" // --------------------- @@ -140,6 +141,10 @@ namespace l1t { void print() const; + const Phase2L1GMT::wordtype hybridStubWord() const; + void printHybridStub(std::string module, uint spaces, bool label) const; + void printHybridStubWord(std::string module, uint spaces, bool label) const; + private: int etaRegion_; //In the barrel this is wheel. In the endcap it is 6-ring int phiRegion_; //In the barrel it is sector. In the endcap it is chamber diff --git a/DataFormats/L1TMuonPhase2/src/MuonStub.cc b/DataFormats/L1TMuonPhase2/src/MuonStub.cc index 779da226920b6..9c1785ca9c0ca 100644 --- a/DataFormats/L1TMuonPhase2/src/MuonStub.cc +++ b/DataFormats/L1TMuonPhase2/src/MuonStub.cc @@ -87,3 +87,52 @@ void MuonStub::print() const { << " quality=" << quality_ << " eta1=" << eta1_ << " eta2=" << eta2_ << " etaQuality=" << etaQuality_ << " type=" << type_; } + +const Phase2L1GMT::wordtype MuonStub::hybridStubWord() const { + Phase2L1GMT::wordtype w = 0; + int bstart = 0; + bstart = Phase2L1GMT::wordconcat(w, bstart, 1, 1); //valid bit is always on in emulator because invalid stubs are never created + bstart = Phase2L1GMT::wordconcat(w, bstart, quality_, Phase2L1GMT::BITSSTUBPHIQUALITY); + bstart = Phase2L1GMT::wordconcat(w, bstart, etaQuality_, Phase2L1GMT::BITSSTUBETAQUALITY); + bstart = Phase2L1GMT::wordconcat(w, bstart, bxNum_, Phase2L1GMT::BITSMUONBX); + bstart = Phase2L1GMT::wordconcat(w, bstart, coord1_, Phase2L1GMT::BITSSTUBCOORD); + bstart = Phase2L1GMT::wordconcat(w, bstart, coord2_, Phase2L1GMT::BITSSTUBCOORD); + bstart = Phase2L1GMT::wordconcat(w, bstart, eta1_, Phase2L1GMT::BITSSTUBETA); + bstart = Phase2L1GMT::wordconcat(w, bstart, eta2_, Phase2L1GMT::BITSSTUBETA); + bstart = Phase2L1GMT::wordconcat(w, bstart, 0, Phase2L1GMT::BITSSTUBTIME); //placeholder for time + int addr = address(); + bstart = Phase2L1GMT::wordconcat(w, bstart, addr, Phase2L1GMT::BITSSTUBID); + bstart = Phase2L1GMT::wordconcat(w, bstart, tfLayer_, 3); + return w; +} + +void MuonStub::printHybridStub(std::string module="MuonStub", uint spaces=0, bool label=true) const { + std::string lab = ""; + lab.append(spaces, ' '); + if (label) + lab.append("hybrid stub: "); + int addr = address(); + edm::LogInfo(module) << lab + << "quality = " << quality_ << ", " + << "etaQuality = " << etaQuality_ << ", " + << "bxNum = " << bxNum_ << ", " + << "coord1 = " << offline_coord1_ << " (" << coord1_ << ")" << ", " + << "coord2 = " << offline_coord2_ << " (" << coord2_ << ")" << ", " + << "eta1 = " << offline_eta1_ << " (" << eta1_ << ")" << ", " + << "eta2 = " << offline_eta2_ << " (" << eta2_ << ")" << "," + << "\n" << std::setfill(' ') << std::setw(lab.length()) << " " + << "time = " << 0 << ", " //placeholder for time + << "address = " << addr << " (id = " << id_ << ")" << ", " + << "tfLayer = " << tfLayer_ + << std::flush; +} + +void MuonStub::printHybridStubWord(std::string module="MuonStub", uint spaces=0, bool label=true) const { + std::string lab = ""; + lab.append(spaces, ' '); + if (label) + lab.append("hybrid stub word = "); + Phase2L1GMT::wordtype w = MuonStub::hybridStubWord(); + edm::LogInfo(module) << lab << std::setfill('0') << std::setw(16) << std::hex << w.to_uint64() << std::flush; +} + diff --git a/L1Trigger/Phase2L1GMT/interface/ConvertedTTTrack.h b/L1Trigger/Phase2L1GMT/interface/ConvertedTTTrack.h index af1e253f037b2..098a08bad18ff 100644 --- a/L1Trigger/Phase2L1GMT/interface/ConvertedTTTrack.h +++ b/L1Trigger/Phase2L1GMT/interface/ConvertedTTTrack.h @@ -17,8 +17,7 @@ namespace Phase2L1GMT { const ap_int& phi, const ap_int& z0, const ap_int& d0, - const ap_uint<1>& quality, - const ap_uint<96>& word) + const ap_uint<1>& quality) : charge_(charge), curvature_(curvature), abseta_(abseta), @@ -27,8 +26,7 @@ namespace Phase2L1GMT { phi_(phi), z0_(z0), d0_(d0), - quality_(quality), - word_(word) {} + quality_(quality) {} const ap_uint<1> charge() const { return charge_; } @@ -49,25 +47,55 @@ namespace Phase2L1GMT { const float offline_eta() const { return offline_eta_; } const float offline_phi() const { return offline_phi_; } - const ap_uint<96>& word() const { return word_; } + const ap_uint<67> word() const { + ap_uint<67> w = 0; + int bstart = 0; + bstart = wordconcat>(w, bstart, 1, 1); //valid bit is always on in emulator because invalid tracks are never created + bstart = wordconcat>(w, bstart, charge_, 1); + bstart = wordconcat>(w, bstart, pt_, BITSPT); + bstart = wordconcat>(w, bstart, phi_, BITSPHI); + bstart = wordconcat>(w, bstart, eta_, BITSETA); + bstart = wordconcat>(w, bstart, z0_, BITSZ0); + bstart = wordconcat>(w, bstart, d0_, BITSD0); + bstart = wordconcat>(w, bstart, quality_, 1); + return w; + } + void setOfflineQuantities(float pt, float eta, float phi) { offline_pt_ = pt; offline_eta_ = eta; offline_phi_ = phi; } - void print() const { - LogDebug("ConvertedTTTrack") << "converted track : charge=" << charge_ << " curvature=" << curvature_ - << " pt=" << offline_pt_ << "," << pt_ << " eta=" << offline_eta_ << "," << eta_ - << " phi=" << offline_phi_ << "," << phi_ << " z0=" << z0_ << " d0=" << d0_ - << " quality=" << quality_; + void print(std::string module="ConvertedTTTrack", uint spaces=0, bool label=true) const { + std::string lab = ""; + lab.append(spaces, ' '); + if (label) + lab.append("converted track: "); + std::string chargeSign = (charge_ == 0) ? "+1" : "-1"; + edm::LogInfo(module) << lab + << "charge = " << chargeSign << " (" << charge_ << ")" << ", " + << "pt = " << offline_pt_ << " (" << pt_ << ")" << ", " + << "phi = " << offline_phi_ << " (" << phi_ << ")" << ", " + << "eta = " << offline_eta_ << " (" << eta_ << ")" << "," + << "\n" << std::setfill(' ') << std::setw(lab.length()) << " " + << "z0 = " << z0_ << ", " + << "d0 = " << d0_ << ", " + << "quality = " << quality_ << ", " + << "(curvature = " << curvature_ << ")" + << std::flush; } - - void printWord() const { - LogDebug("ConvertedTTTrack") << "converted track : word=" << std::setfill('0') << std::setw(8) << std::hex - << (long long unsigned int)((word_ >> 64).to_uint64()) << std::setfill('0') - << std::setw(16) << std::hex - << (long long unsigned int)((word_ & 0xffffffffffffffff).to_uint64()); + + void printWord(std::string module="ConvertedTTTrack", uint spaces=0, bool label=true) const { + std::string lab = ""; + lab.append(spaces, ' '); + if (label) + lab.append("converted track word = "); + ap_uint<67> w = word(); + edm::LogInfo(module) << lab + << std::setfill('0') << std::setw(1) << std::hex << (long long unsigned int)((w >> 64).to_uint64()) + << std::setfill('0') << std::setw(16) << std::hex << (long long unsigned int)((w & 0xffffffffffffffff).to_uint64()) + << std::flush; } void setTrkPtr(const edm::Ptr >& trkPtr) { trkPtr_ = trkPtr; } @@ -87,7 +115,6 @@ namespace Phase2L1GMT { float offline_pt_; float offline_eta_; float offline_phi_; - ap_uint<96> word_; edm::Ptr > trkPtr_; }; diff --git a/L1Trigger/Phase2L1GMT/interface/PreTrackMatchedMuon.h b/L1Trigger/Phase2L1GMT/interface/PreTrackMatchedMuon.h index 641fee944b797..c6890bb6161bc 100644 --- a/L1Trigger/Phase2L1GMT/interface/PreTrackMatchedMuon.h +++ b/L1Trigger/Phase2L1GMT/interface/PreTrackMatchedMuon.h @@ -34,6 +34,11 @@ namespace Phase2L1GMT { d0_(d0), beta_(beta), isGlobal_(false), + quality0_(0), + quality1_(0), + quality2_(0), + quality3_(0), + quality4_(0), quality_(0), stubID0_(4095), stubID1_(4095), @@ -52,6 +57,11 @@ namespace Phase2L1GMT { const uint beta() const { return beta_; } bool isGlobalMuon() const { return isGlobal_; } + const int quality0() const { return quality0_; } + const int quality1() const { return quality1_; } + const int quality2() const { return quality2_; } + const int quality3() const { return quality3_; } + const int quality4() const { return quality4_; } const int quality() const { return quality_; } const int offline_pt() const { return offline_pt_; } const float offline_eta() const { return offline_eta_; } @@ -65,7 +75,11 @@ namespace Phase2L1GMT { const uint matchMask() const { return matchMask_; } bool valid() const { return valid_; } - + void setQuality0(uint quality0) { quality0_ = quality0; } + void setQuality1(uint quality1) { quality1_ = quality1; } + void setQuality2(uint quality2) { quality2_ = quality2; } + void setQuality3(uint quality3) { quality3_ = quality3; } + void setQuality4(uint quality4) { quality4_ = quality4; } void setQuality(uint quality) { quality_ = quality; } void setValid(bool v) { valid_ = v; } @@ -80,25 +94,33 @@ namespace Phase2L1GMT { void resetGlobal() { isGlobal_ = false; } const l1t::SAMuonRefVector& muonRef() const { return muRef_; } - void addStub(const l1t::MuonStubRef& stub, uint mask) { + void addStub(const l1t::MuonStubRef& stub, uint mask, uint quality) { stubs_.push_back(stub); if (stub->tfLayer() == 0) { stubID0_ = stub->address(); matchMask_ = matchMask_ | (mask); + quality0_ = quality; } else if (stub->tfLayer() == 1) { stubID1_ = stub->address(); matchMask_ = matchMask_ | (mask << 2); + quality1_ = quality; } else if (stub->tfLayer() == 2) { stubID2_ = stub->address(); matchMask_ = matchMask_ | (mask << 4); + quality2_ = quality; } else if (stub->tfLayer() == 3) { stubID3_ = stub->address(); matchMask_ = matchMask_ | (mask << 6); + quality3_ = quality; } else if (stub->tfLayer() == 4) { stubID4_ = stub->address(); matchMask_ = matchMask_ | (mask << 8); + quality4_ = quality; } } + + void setCleanMask(const uint cleanMask) { cleanMask_ = cleanMask; } + const uint cleanMask() const { return cleanMask_; } const l1t::MuonStubRefVector& stubs() const { return stubs_; } @@ -106,13 +128,13 @@ namespace Phase2L1GMT { const edm::Ptr > trkPtr() const { return trkPtr_; } - void print() const { - LogDebug("PreTrackMatchedMuon") << "preconstructed muon : charge=" << charge_ << " pt=" << offline_pt_ << "," - << pt_ << " eta=" << offline_eta_ << "," << eta_ << " phi=" << offline_phi_ << "," - << phi_ << " z0=" << z0_ << " d0=" << d0_ << " quality=" << quality_ - << " isGlobal=" << isGlobal_ << " valid=" << valid_ << " stubs: " << stubID0_ - << " " << stubID1_ << " " << stubID2_ << " " << stubID3_ << " " << stubID4_; - } + // void print() const { + // LogDebug("PreTrackMatchedMuon") << "preconstructed muon : charge=" << charge_ << " pt=" << offline_pt_ << "," + // << pt_ << " eta=" << offline_eta_ << "," << eta_ << " phi=" << offline_phi_ << "," + // << phi_ << " z0=" << z0_ << " d0=" << d0_ << " quality=" << quality_ + // << " isGlobal=" << isGlobal_ << " valid=" << valid_ << " stubs: " << stubID0_ + // << " " << stubID1_ << " " << stubID2_ << " " << stubID3_ << " " << stubID4_; + //} uint64_t lsb() const { wordtype w = 0; @@ -142,11 +164,86 @@ namespace Phase2L1GMT { return w2.to_int(); } - void printWord() const { - LogDebug("PreTrackMatchedMuon") << "PreTrackMatchedMuon : word=" << std::setfill('0') << std::setw(16) << std::hex - << (long long unsigned int)(msb() >> 2) << std::setfill('0') << std::setw(16) - << std::hex - << (long long unsigned int)((lsb() | (msb() << 62)) & 0xffffffffffffffff); + const ap_uint<182> word() const { + ap_uint<182> w = 0; + int bstart = 0; + bstart = wordconcat>(w, bstart, valid_, 1); + bstart = wordconcat>(w, bstart, charge_, 1); + bstart = wordconcat>(w, bstart, pt_, BITSPT); + bstart = wordconcat>(w, bstart, phi_, BITSPHI); + bstart = wordconcat>(w, bstart, eta_, BITSETA); + bstart = wordconcat>(w, bstart, z0_, BITSZ0); + bstart = wordconcat>(w, bstart, d0_, BITSD0); + bstart = wordconcat>(w, bstart, isGlobal_, 1); + bstart = wordconcat>(w, bstart, beta_, BITSMUONBETA); + bstart = wordconcat>(w, bstart, quality0_, BITSMATCHQUALITY-2); + bstart = wordconcat>(w, bstart, stubID0_, BITSSTUBID); + bstart = wordconcat>(w, bstart, ((matchMask_)&0b11), 2); + bstart = wordconcat>(w, bstart, quality1_, BITSMATCHQUALITY-2); + bstart = wordconcat>(w, bstart, stubID1_, BITSSTUBID); + bstart = wordconcat>(w, bstart, ((matchMask_>>2)&0b11), 2); + bstart = wordconcat>(w, bstart, quality2_, BITSMATCHQUALITY-2); + bstart = wordconcat>(w, bstart, stubID2_, BITSSTUBID); + bstart = wordconcat>(w, bstart, ((matchMask_>>4)&0b11), 2); + bstart = wordconcat>(w, bstart, quality3_, BITSMATCHQUALITY-2); + bstart = wordconcat>(w, bstart, stubID3_, BITSSTUBID); + bstart = wordconcat>(w, bstart, ((matchMask_>>6)&0b11), 2); + bstart = wordconcat>(w, bstart, quality4_, BITSMATCHQUALITY-2); + bstart = wordconcat>(w, bstart, stubID4_, BITSSTUBID); + bstart = wordconcat>(w, bstart, ((matchMask_>>8)&0b11), 2); + bstart = wordconcat>(w, bstart, quality_, BITSMATCHQUALITY); + + return w; + } + + void print(std::string module="PreTrackMatchedMuon", uint spaces=0, bool label=true) const { + std::string lab = ""; + lab.append(spaces, ' '); + if (label) + lab.append("TPS premuon: "); + std::string chargeSign = (charge_ == 0) ? "+1" : "-1"; + edm::LogInfo(module) << lab + << "charge = " << chargeSign << " (" << charge_ << ")" << ", " + << "pt = " << offline_pt_ << " (" << pt_ << ")" << ", " + << "phi = " << offline_phi_ << " (" << phi_ << ")" << ", " + << "eta = " << offline_eta_ << " (" << eta_ << ")" << "," + << "\n" << std::setfill(' ') << std::setw(lab.length()) << " " + << "z0 = " << z0_ << ", " + << "d0 = " << d0_ << ", " + << "isGlobal = " << isGlobal_ << ", " + << "beta = " << beta_ << "," + << "\n" << std::setfill(' ') << std::setw(lab.length()) << " " + << "stubID0 = " << stubID0_ << ", " + << "stubID1 = " << stubID1_ << ", " + << "stubID2 = " << stubID2_ << ", " + << "stubID3 = " << stubID3_ << ", " + << "stubID4 = " << stubID4_ << "," + << "\n" << std::setfill(' ') << std::setw(lab.length()) << " " + << "quality = " << quality_ << ", " + << "quality0 = " << quality0_ << ", " + << "quality1 = " << quality1_ << ", " + << "quality2 = " << quality2_ << ", " + << "quality3 = " << quality3_ << ", " + << "quality4 = " << quality4_ + << "\n" << std::setfill(' ') << std::setw(spaces+4) << " " << "Stubs: " + << std::flush; + for (const auto& stub : stubs_) { + stub->printHybridStub(module, spaces+8, false); + stub->printHybridStubWord(module, spaces+12, true); + } + } + + void printWord(std::string module="PreTrackMatchedMuon", uint spaces=0, bool label=true) const { + std::string lab = ""; + lab.append(spaces, ' '); + if (label) + lab.append("TPS premuon word = "); + ap_uint<182> w = word(); + edm::LogInfo(module) << lab + << std::setfill('0') << std::setw(14) << std::hex << (long long unsigned int)((w >> 128).to_uint64()) + << std::setfill('0') << std::setw(16) << std::hex << (long long unsigned int)((w >> 64).to_uint64()) + << std::setfill('0') << std::setw(16) << std::hex << (long long unsigned int)((w & 0xffffffffffffffff).to_uint64()) + << std::flush; } private: @@ -158,6 +255,11 @@ namespace Phase2L1GMT { int d0_; uint beta_; bool isGlobal_; + uint quality0_; //qualities of the matches in the individual tf layers + uint quality1_; + uint quality2_; + uint quality3_; + uint quality4_; uint quality_; float offline_pt_; float offline_eta_; @@ -168,6 +270,7 @@ namespace Phase2L1GMT { uint stubID3_; uint stubID4_; uint matchMask_; + uint cleanMask_; bool valid_; l1t::MuonStubRefVector stubs_; diff --git a/L1Trigger/Phase2L1GMT/interface/TPSAlgorithm.h b/L1Trigger/Phase2L1GMT/interface/TPSAlgorithm.h index c637184fa5f70..db40d5ec58639 100644 --- a/L1Trigger/Phase2L1GMT/interface/TPSAlgorithm.h +++ b/L1Trigger/Phase2L1GMT/interface/TPSAlgorithm.h @@ -25,9 +25,8 @@ namespace Phase2L1GMT { const unsigned int BITSHIFTPROP2C2 = 24; const unsigned int BITSHIFTPROP3C2 = 19; const unsigned int BITSHIFTRES1 = 11; - //for comparison with absK to see which functional form to propagate phi according to - //coord1 k cutoff: 4096 - //coord2 k cutoffs: 1024, 7168, 4096, 2048, 4096 + //curvscale for coord1 is 4096 + //curvscales for coord2 are 1024, 7168, 4096, 2048, 4096 const unsigned int BITSHIFTCURVSCALEC1 = 12; const unsigned int BITSHIFTCURVSCALEC2LEADS[5] = {10, 13, 12, 11, 12}; const unsigned int BITSHIFTCURVSCALEC2CORRS[5] = {0, 10, 0, 0, 0}; @@ -70,11 +69,12 @@ namespace Phase2L1GMT { std::vector cleanNeighbor(const std::vector& muons, const std::vector& muonsPrevious, const std::vector& muonsNext, - bool equality) const; - std::vector convert(const std::vector& muons, uint maximum) const; - bool outputGT(std::vector& muons) const; - void SetQualityBits(std::vector& muons) const; - std::vector sort(std::vector& muons, uint maximum) const; + bool equality); + std::vector cleanAll(std::vector& muons); + std::vector convert(std::vector& muons, uint maximum); + bool outputGT(std::vector& muons); + void SetQualityBits(std::vector& muons); + std::vector sort(std::vector& muons, uint maximum); private: int verbose_; diff --git a/L1Trigger/Phase2L1GMT/interface/TrackConverter.h b/L1Trigger/Phase2L1GMT/interface/TrackConverter.h index a12a2a5ed213f..1c68c06cd3370 100644 --- a/L1Trigger/Phase2L1GMT/interface/TrackConverter.h +++ b/L1Trigger/Phase2L1GMT/interface/TrackConverter.h @@ -19,7 +19,13 @@ namespace Phase2L1GMT { int verbose_; typedef ap_uint<96> wordtype; - uint generateQuality(const edm::Ptr >& track) { return 1; } + uint generateQuality(const edm::Ptr >& track) { + uint chi2Cut = 0xf; + if ((track->getChi2RPhiBits() <= chi2Cut) && (track->getChi2RPhiBits() <= chi2Cut)) + return 1; + else + return 0; + } uint ptLookup(uint absCurv) { for (auto i : ptShifts) { diff --git a/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc b/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc index 26f995f14c839..8cbe0c69f3563 100644 --- a/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc +++ b/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc @@ -167,19 +167,19 @@ void Phase2L1TGMTStubProducer::fillDescriptions(edm::ConfigurationDescriptions& "eta_1", { -46, -45, -43, -41, -39, -37, -35, -30, -28, -26, -23, -20, -18, -15, -9, -6, -3, -1, - 1, 3, 6, 9, 15, 18, 20, 23, 26, 28, 30, 35, 37, 39, 41, 43, 45, 1503, + 1, 3, 6, 9, 15, 18, 20, 23, 26, 28, 30, 35, 37, 39, 41, 43, 45, 46, //1503 I think the large entries at the end here were a mistake }); psd0.add>( "eta_2", { -41, -39, -38, -36, -34, -32, -30, -26, -24, -22, -20, -18, -15, -13, -8, -5, -3, -1, - 1, 3, 5, 8, 13, 15, 18, 20, 22, 24, 26, 30, 32, 34, 36, 38, 39, 1334, + 1, 3, 5, 8, 13, 15, 18, 20, 22, 24, 26, 30, 32, 34, 36, 38, 39, 41, //1334 }); psd0.add>( "eta_3", { -35, -34, -32, -31, -29, -27, -26, -22, -20, -19, -17, -15, -13, -11, -6, -4, -2, -1, - 1, 2, 4, 6, 11, 13, 15, 17, 19, 20, 22, 26, 27, 29, 31, 32, 34, 1148, + 1, 2, 4, 6, 11, 13, 15, 17, 19, 20, 22, 26, 27, 29, 31, 32, 34, 35, //1148 }); psd0.add>("coarseEta_1", { diff --git a/L1Trigger/Phase2L1GMT/src/L1TPhase2GMTBarrelStubProcessor.cc b/L1Trigger/Phase2L1GMT/src/L1TPhase2GMTBarrelStubProcessor.cc index 44c04b7875748..4fb7dc83402ce 100644 --- a/L1Trigger/Phase2L1GMT/src/L1TPhase2GMTBarrelStubProcessor.cc +++ b/L1Trigger/Phase2L1GMT/src/L1TPhase2GMTBarrelStubProcessor.cc @@ -31,6 +31,8 @@ l1t::MuonStub L1TPhase2GMTBarrelStubProcessor::buildStub(const L1Phase2MuDTPhDig const L1MuDTChambThDigi* etaS) { l1t::MuonStub stub = buildStubNoEta(phiS); + //we do not yet have the full eta information in phase 2, so we will just use coarse eta for now + /* //Now full eta int qeta1 = -16384; int qeta2 = -16384; @@ -66,7 +68,7 @@ l1t::MuonStub L1TPhase2GMTBarrelStubProcessor::buildStub(const L1Phase2MuDTPhDig stub.setEta(eta1, 0, 1); stub.setOfflineQuantities(stub.offline_coord1(), stub.offline_coord2(), eta1 * etaLSB_, 0.0); } - + */ return stub; } @@ -147,6 +149,7 @@ l1t::MuonStubCollection L1TPhase2GMTBarrelStubProcessor::makeStubs(const L1Phase sN = sN | (wr1 << 30); sN = sN | (wq << 51); sN = sN | (wr2 << 55); + unsigned int index = (station - 1) * 4 + phiDigi.index(); os << std::setw(0) << std::dec << sector << " " << wheel << " " << station << " "; os << std::uppercase << std::setfill('0') << std::setw(16) << std::hex << uint64_t(sN) << " "; } diff --git a/L1Trigger/Phase2L1GMT/src/TPS.cc b/L1Trigger/Phase2L1GMT/src/TPS.cc index 023c4ca0a167d..30497c2afff94 100644 --- a/L1Trigger/Phase2L1GMT/src/TPS.cc +++ b/L1Trigger/Phase2L1GMT/src/TPS.cc @@ -12,6 +12,7 @@ TPS::TPS(const edm::ParameterSet& iConfig) std::vector TPS::processEvent(const std::vector >& tracks, const l1t::MuonStubRefVector& muonStubs) { + //Split tracks to the links as they come std::array >, 9> loctracks; for (unsigned i = 0; i < 9; ++i) @@ -26,29 +27,61 @@ std::vector TPS::processEvent(const std::vector stubs; for (int i = 0; i < 9; ++i) stubs[i] = associateStubsWithNonant(muonStubs, i); - + + //print all tracks and stubs for an event + if (verbose_ == 1) { + for (unsigned i = 0; i < 9; ++i) { + edm::LogInfo("TPS") << "Sector " << i << ":\n" + << " L1 Tracks:"; + for (const auto& t : loctracks[i]) { + edm::LogInfo("TPS") << " RinvBits = " << ap_int(t->getRinvBits()) << ", eta = " << t->eta() << ", phi = " << t->phi() << std::flush; + edm::LogInfo("TPS") << " l1track word = " << std::setfill('0') << std::setw(8) << std::hex << ((t->getTrackWord())>>64).to_uint64() << std::setw(16) << (t->getTrackWord()).to_uint64() << std::dec << std::flush; + } + edm::LogInfo("TPS") << " Converted Tracks:"; + for (const auto& track : convertedTracks[i]) { + track.print("TPS", 8, false); + track.printWord("TPS", 12, true); + } + edm::LogInfo("TPS") << " Stubs:"; + for (const auto& stub : stubs[i]) { + stub->printHybridStub("TPS", 8, false); + stub->printHybridStubWord("TPS", 12, true); + + } + } + } + //run track - muon matching per nonant std::array, 9> mus; for (int i = 0; i < 9; ++i) mus[i] = tps_->processNonant(convertedTracks.at(i), stubs.at(i)); - //clean neighboring nonants - std::vector > muCleaneds; - muCleaneds.push_back(tps_->cleanNeighbor(mus[0], mus[8], mus[1], true)); - muCleaneds.push_back(tps_->cleanNeighbor(mus[1], mus[0], mus[2], false)); - muCleaneds.push_back(tps_->cleanNeighbor(mus[2], mus[1], mus[3], true)); - muCleaneds.push_back(tps_->cleanNeighbor(mus[3], mus[2], mus[4], false)); - muCleaneds.push_back(tps_->cleanNeighbor(mus[4], mus[3], mus[5], true)); - muCleaneds.push_back(tps_->cleanNeighbor(mus[5], mus[4], mus[6], false)); - muCleaneds.push_back(tps_->cleanNeighbor(mus[6], mus[5], mus[7], true)); - muCleaneds.push_back(tps_->cleanNeighbor(mus[7], mus[6], mus[8], false)); - //ARGH! 9 sectors - so some duplicates very rarely - muCleaneds.push_back(tps_->cleanNeighbor(mus[8], mus[7], mus[0], false)); - - //merge all the collections - std::vector mergedCleaned; - for (auto&& v : muCleaneds) { - mergedCleaned.insert(mergedCleaned.end(), v.begin(), v.end()); + //examine match and overall muon qualities pre and post cleaning + if (verbose_ == 1) { + edm::LogInfo("TPS") << "Before cleaning premuons:"; + for (unsigned i = 0; i < 9; ++i) { + std::vector sector_mus = mus[i]; + for (const auto& sector_mu : sector_mus) { + edm::LogInfo("TPS") << " (Sector " << i << ")" << std::flush; + sector_mu.print("TPS", 4, false); + sector_mu.printWord("TPS", 8, true); + } + } + } + + //clean all of the nonants at once + std::vector mergedPrecleaned; + for (auto&& v : mus) { + mergedPrecleaned.insert(mergedPrecleaned.end(), v.begin(), v.end()); + } + std::vector mergedCleaned = tps_->cleanAll(mergedPrecleaned); + + if (verbose_ == 1) { + edm::LogInfo("TPS") << "After cleaning premuons:"; + for (const auto& cleaned_mu : mergedCleaned) { + cleaned_mu.print("TPS", 4, false); + cleaned_mu.printWord("TPS", 8, true); + } } std::vector trackMatchedMuonsNoIso = tps_->convert(mergedCleaned, 32); @@ -115,7 +148,7 @@ l1t::MuonStubRefVector TPS::associateStubsWithNonant(const l1t::MuonStubRefVecto ap_int deltaPhi = phi - center; ap_uint absDeltaPhi = (deltaPhi < 0) ? ap_uint(-deltaPhi) : ap_uint(deltaPhi); - if (absDeltaPhi < 284) //important to see pt = 3 to 4 //was 168 //was 42 + if (absDeltaPhi < 284) //was 284 //was 168 //was 42 out.push_back(s); } return out; diff --git a/L1Trigger/Phase2L1GMT/src/TPSAlgorithm.cc b/L1Trigger/Phase2L1GMT/src/TPSAlgorithm.cc index 9977aa2c947d5..0a138b84d3161 100644 --- a/L1Trigger/Phase2L1GMT/src/TPSAlgorithm.cc +++ b/L1Trigger/Phase2L1GMT/src/TPSAlgorithm.cc @@ -12,8 +12,7 @@ std::vector TPSAlgorithm::processNonant(const std::vector cleanedMuons = clean(preMuons); - return cleanedMuons; + return preMuons; } std::vector TPSAlgorithm::cleanNeighbor(const std::vector& muons, @@ -53,22 +52,96 @@ std::vector TPSAlgorithm::cleanNeighbor(const std::vector

TPSAlgorithm::convert(const std::vector& muons, uint maximum) const { +std::vector TPSAlgorithm::cleanAll(std::vector& muons) { + std::vector out; + + if (muons.empty()) + return out; + + if (verbose_ == 1) { + edm::LogInfo("TPSAlgo") << "-----Cleaning Up Muons in all regions"; + edm::LogInfo("TPSAlgo") << "Before:"; + } + + for (uint i = 0; i < muons.size(); ++i) { + if (verbose_ == 1) { + muons[i].print(); + } + ap_uint<5> mask = 0x1f; + for (uint j = 0; j < muons.size(); ++j) { + if (i == j) + continue; + bool muons_equal = ((muons[i].charge() == muons[j].charge()) && (muons[i].pt() == muons[j].pt()) && (muons[i].phi() == muons[j].phi()) + && (muons[i].eta() == muons[j].eta()) && (muons[i].z0() == muons[j].z0()) && (muons[i].d0() == muons[j].d0()) + && (muons[i].beta() == muons[j].beta()) && (muons[i].isGlobalMuon() == muons[j].isGlobalMuon()) && (muons[i].stubID0() == muons[j].stubID0()) + && (muons[i].stubID1() == muons[j].stubID1()) && (muons[i].stubID2() == muons[j].stubID2()) && (muons[i].stubID3() == muons[j].stubID3()) + && (muons[i].stubID4() == muons[j].stubID4())); + bool equality = (muons_equal && (i < j)); + mask = mask & cleanMuon(muons[i], muons[j], equality); //only the first duplicate survives + } + muons[i].setCleanMask(mask); + if (mask) { + if (verbose_ == 1) + edm::LogInfo("TPSAlgo") << "kept"; + out.push_back(muons[i]); + } else { + if (verbose_ == 1) + edm::LogInfo("TPSAlgo") << "discarded"; + } + } + return out; +} + + +std::vector TPSAlgorithm::convert(std::vector& muons, uint maximum) { std::vector out; for (const auto& mu : muons) { if (out.size() == maximum) break; l1t::TrackerMuon muon(mu.trkPtr(), mu.charge(), mu.pt(), mu.eta(), mu.phi(), mu.z0(), mu.d0(), mu.quality()); muon.setMuonRef(mu.muonRef()); - for (const auto& stub : mu.stubs()) - muon.addStub(stub); + for (const auto& stub : mu.stubs()) { + if (mu.cleanMask() & (1 << stub->tfLayer())) + muon.addStub(stub); + } - uint matches = 0; - uint mask = mu.matchMask(); + if (verbose_ == 1) { + edm::LogInfo("TPSAlgo") << "PreTrackMatchedMuon: " << "\n" + << " charge = " << mu.charge() << "\n" + << " stub ids: " << "\n" + << " id0 = " << mu.stubID0() << "\n" + << " id1 = " << mu.stubID1() << "\n" + << " id2 = " << mu.stubID2() << "\n" + << " id3 = " << mu.stubID3() << "\n" + << " id4 = " << mu.stubID4() << "\n" + << " stub addresses: " << "\n" + << std::flush; + for (const auto& stub : mu.stubs()) + edm::LogInfo("TPSAlgo") << " " << stub->address() << "\n" << std::flush; + edm::LogInfo("TPSAlgo") << "\n" + << "TrackerMuon: " << "\n" + << " charge = " << muon.charge() << "\n" + << " hwCharge = " << muon.hwCharge() << "\n" + << " stub addresses: " << "\n" + << std::flush + << std::hex << muon.word()[1] << "\n" + << std::hex << muon.word()[0] << std::flush; + for (const auto& stub : muon.stubs()) + edm::LogInfo("TPSAlgo") << " " << stub->address() << "\n" << std::flush; + edm::LogInfo("TPSAlgo") << "\n\n\n" << std::flush; + } - for (uint i = 0; i < 10; i = i + 1) { - if (mask & (1 << i)) - matches++; + uint matches = 0; + uint matchMask = mu.matchMask(); + uint cleanMask = mu.cleanMask(); + + for (uint i = 0; i < 5; i = i + 1) { + if (cleanMask & (1 << i)) { + for (uint j = 2*i; j < 2*i + 2; j = j + 1) { + if (matchMask & (1 << j)) + matches++; + } + } } muon.setNumberOfMatches(matches); out.push_back(muon); @@ -324,14 +397,13 @@ propagation_t TPSAlgorithm::propagate(const ConvertedTTTrack& track, uint layer) ap_int eta = track.eta(); out.eta = eta / ETADIVIDER; - //out.eta = eta >> ETASHIFT; - + ap_uint resetak = (res1_eta * k2) >> 23; ap_ufixed sigma_eta1 = res0_eta1 + resetak; out.sigma_eta1 = ap_uint(sigma_eta1); ap_ufixed sigma_eta2 = res0_eta2 + resetak; out.sigma_eta2 = ap_uint(sigma_eta2); - + out.valid = 1; out.is_barrel = is_barrel; @@ -420,7 +492,7 @@ match_t TPSAlgorithm::match(const propagation_t prop, const l1t::MuonStubRef& st eta1Matched = 1; else eta1Matched = 0; - + if (verbose_ == 1) edm::LogInfo("TPSAlgo") << "eta1 matched=" << eta1Matched.to_int() << " delta=" << deltaEta1.to_int() << " res=" << prop_sigma_eta1.to_int(); @@ -435,7 +507,8 @@ match_t TPSAlgorithm::match(const propagation_t prop, const l1t::MuonStubRef& st else eta2Matched = 0; match_t out; - out.id = trackID; + //out.id = trackID; //dont think we ever use track ID in tps + out.id = stub->address(); if (verbose_ == 1) edm::LogInfo("TPSAlgo") << "eta2 matched=" << eta2Matched.to_int() << " delta=" << deltaEta2.to_int() @@ -449,7 +522,7 @@ match_t TPSAlgorithm::match(const propagation_t prop, const l1t::MuonStubRef& st if (out.valid == 0) { out.quality = 0; } else { - out.quality = 32 - deltaCoord1 / 4; + out.quality = 32 - deltaCoord1 / 4; //do we really need to divide by 4? if (coord2Matched == 1) { out.quality += 32 - deltaCoord2 / 4; out.valid = 3; @@ -492,7 +565,7 @@ match_t TPSAlgorithm::propagateAndMatch(const ConvertedTTTrack& track, match_t TPSAlgorithm::getBest(const std::vector& matches) const { match_t best = matches[0]; for (const auto& m : matches) { - if (m.quality > best.quality) + if ((m.quality > best.quality) || ((m.quality == best.quality) && (m.id > best.id))) //implement well-ordered tie breaker best = m; } @@ -505,7 +578,7 @@ void TPSAlgorithm::matchingInfos(const std::vector& matchInfo, if (!matchInfo.empty()) { match_t b = getBest(matchInfo); if (b.valid != 0) { - muon.addStub(b.stubRef, b.valid); + muon.addStub(b.stubRef, b.valid, b.quality); if (b.isGlobal) muon.addMuonRef(b.muRef); quality += b.quality; @@ -576,6 +649,75 @@ PreTrackMatchedMuon TPSAlgorithm::processTrack(const ConvertedTTTrack& track, edm::LogInfo("TPSAlgo") << std::endl; } + //printouts + if (verbose_ == 1) { + + edm::LogInfo("TPSAlgo") << "Input converted track: " << std::flush; + //q, pt, phi, eta, z0, d0, quality + edm::LogInfo("TPSAlgo") << " " + << "q=" + to_string(ap_uint<1>(track.charge())) + ", " + << "pt=" + to_string(ap_uint(track.pt())) + ", " + << "phi=" + to_string(ap_int(track.phi())) + ", " + << "eta=" + to_string(ap_int(track.eta())) + ", " + << "z0=" + to_string(ap_int(track.z0())) + ", " + << "d0=" + to_string(ap_int(track.d0())) + ", " + << "quality=" + to_string(ap_uint<1>(track.quality())) + ", " + << "\n" + << std::flush; + + edm::LogInfo("TPSAlgo") << "Input stubs:" << std::flush; + + for (const auto& stub : stubs) { + edm::LogInfo("TPSAlgo") << " " + << "layer=" + to_string(stub->tfLayer()) + ", " + << "coord1=" + to_string(stub->coord1()) + ", " + << "coord2=" + to_string(stub->coord2()) + ", " + << "eta1=" + to_string(stub->eta1()) + ", " + << "eta2=" + to_string(stub->eta2()) + ", " + << "quality=" + to_string(stub->quality()) + ", " + << "etaQuality=" + to_string(stub->etaQuality()) + ", " + << "id=" + to_string(stub->address()) + ", " + << std::flush; + } + + edm::LogInfo("TPSAlgo") << "End stubs\n" << std::flush; + + edm::LogInfo("TPSAlgo") << "Output PreTrackMatchedMuon: " + << "valid=" + to_string(muon.valid()) + ", " + << "q=" + to_string(muon.charge()) + ", " + << "pt=" + to_string(muon.pt()) + ", " + << "phi=" + to_string(muon.phi()) + ", " + << "eta=" + to_string(muon.eta()) + ", " + << "z0=" + to_string(muon.z0()) + ", " + << "d0=" + to_string(muon.d0()) + ", " + << "isGlobalMuon=" + to_string(muon.isGlobalMuon()) + ", " + << "beta=" + to_string(muon.beta()) + ", " + << "quality=" + to_string(muon.quality()) + ", " + << "\n" + << std::flush; + + edm::LogInfo("TPSAlgo") << "Output PreTrackMatchedMuon matched stubs:" << std::flush; + + for (const auto& stub : muon.stubs()) { + match_t tempmatch = propagateAndMatch(track, stub, 0); //want to verify details of match as well as stub + edm::LogInfo("TPSAlgo") << " " + << "layer=" + to_string(stub->tfLayer()) + ", " + << "coord1=" + to_string(stub->coord1()) + ", " + << "coord2=" + to_string(stub->coord2()) + ", " + << "eta1=" + to_string(stub->eta1()) + ", " + << "eta2=" + to_string(stub->eta2()) + ", " + << "phiQuality=" + to_string(stub->quality()) + ", " + << "etaQuality=" + to_string(stub->etaQuality()) + ", " + << "id=" + to_string(stub->address()) + ", " + << "quality=" + to_string(tempmatch.quality) + ", " + << "valid=" + to_string(tempmatch.valid) + ", " + << std::flush; + } + + edm::LogInfo("TPSAlgo") << "End stubs\n\n" << std::flush; + + } + return muon; } @@ -609,10 +751,26 @@ ap_uint<5> TPSAlgorithm::cleanMuon(const PreTrackMatchedMuon& mu, const PreTrack overlap = overlap | 0x10; } - if (((mu.quality() < other.quality()) && (!eq)) || ((mu.quality() <= other.quality()) && (eq))) - return valid & (~overlap); - else + if (verbose_ == 1) { + edm::LogInfo("TPSAlgo") << "source ID0: " << mu.stubID0() << "\n" + << "source ID1: " << mu.stubID1() << "\n" + << "source ID2: " << mu.stubID2() << "\n" + << "source ID3: " << mu.stubID3() << "\n" + << "source ID4: " << mu.stubID4() << "\n" + << "other ID0: " << other.stubID0() << "\n" + << "other ID1: " << other.stubID1() << "\n" + << "other ID2: " << other.stubID2() << "\n" + << "other ID3: " << other.stubID3() << "\n" + << "other ID4: " << other.stubID4() << "\n" + << "valid: " << valid << "\n" + << "overlap: " << overlap << "\n" + << std::endl; + } + + if ((eq && (mu.quality() >= other.quality())) || ((!eq) && (mu.quality() > other.quality()))) return valid; + else + return valid & (~overlap); } std::vector TPSAlgorithm::clean(const std::vector& muons) const { diff --git a/L1Trigger/Phase2L1GMT/src/TrackConverter.cc b/L1Trigger/Phase2L1GMT/src/TrackConverter.cc index 1582f03487294..6fa0c81cdbb58 100644 --- a/L1Trigger/Phase2L1GMT/src/TrackConverter.cc +++ b/L1Trigger/Phase2L1GMT/src/TrackConverter.cc @@ -32,16 +32,7 @@ ConvertedTTTrack TrackConverter::convert(const edm::Ptr phi = ap_int(phisec + track->phiSector() * 910); - wordtype word = 0; - int bstart = 0; - bstart = wordconcat(word, bstart, curvature, BITSTTCURV); - bstart = wordconcat(word, bstart, phi, BITSPHI); //was phiSec - bstart = wordconcat(word, bstart, tanLambda, BITSTTTANL); - bstart = wordconcat(word, bstart, z0, BITSZ0); - bstart = wordconcat(word, bstart, d0, BITSD0); - wordconcat(word, bstart, uint(track->chi2()), 4); - - ConvertedTTTrack convertedTrack(charge, curvature, absEta, pt, eta, phi, z0, d0, quality, word); + ConvertedTTTrack convertedTrack(charge, curvature, absEta, pt, eta, phi, z0, d0, quality); convertedTrack.setOfflineQuantities(LSBpt * pt, LSBeta * eta, LSBphi * phi); if (verbose_) convertedTrack.print(); From fe094813d425d567e4c5e6d21da9e1853404f52a Mon Sep 17 00:00:00 2001 From: Havyn Ancelin Date: Thu, 11 Dec 2025 17:44:41 -0600 Subject: [PATCH 18/61] updated TPS data formats, cleaning, logs, and other misc things --- DataFormats/L1TMuonPhase2/interface/Constants.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DataFormats/L1TMuonPhase2/interface/Constants.h b/DataFormats/L1TMuonPhase2/interface/Constants.h index 539cb47ca7bbf..520ee87cec2d6 100644 --- a/DataFormats/L1TMuonPhase2/interface/Constants.h +++ b/DataFormats/L1TMuonPhase2/interface/Constants.h @@ -44,7 +44,7 @@ namespace Phase2L1GMT { //Track Muon Match const int BITSSIGMAETA = 4; const int BITSSIGMACOORD = 4; - const int BITSPROPCOORD = 6; //lowered this to make room for another prop coefficient + const int BITSPROPCOORD = 6; const int BITSPROPSIGMACOORD_A = 6; const int BITSPROPSIGMACOORD_B = 6; const int BITSPROPSIGMAETA_A = 5; From 540f010d81aeef154aca96346a108e513ede9222 Mon Sep 17 00:00:00 2001 From: Zhenbin Wu Date: Wed, 28 Jan 2026 13:16:07 -0600 Subject: [PATCH 19/61] Code clean and format --- DataFormats/L1TMuonPhase2/src/MuonStub.cc | 37 +++-- .../Phase2L1GMT/interface/ConvertedTTTrack.h | 45 +++--- .../interface/PreTrackMatchedMuon.h | 152 +++++++++--------- .../Phase2L1GMT/interface/TPSAlgorithm.h | 12 +- .../Phase2L1GMT/interface/TrackConverter.h | 4 +- .../plugins/Phase2L1TGMTStubProducer.cc | 16 +- L1Trigger/Phase2L1GMT/src/TPS.cc | 35 ++-- L1Trigger/Phase2L1GMT/src/TPSAlgorithm.cc | 89 +++++----- 8 files changed, 204 insertions(+), 186 deletions(-) diff --git a/DataFormats/L1TMuonPhase2/src/MuonStub.cc b/DataFormats/L1TMuonPhase2/src/MuonStub.cc index 9c1785ca9c0ca..d3df0fb5c8aaf 100644 --- a/DataFormats/L1TMuonPhase2/src/MuonStub.cc +++ b/DataFormats/L1TMuonPhase2/src/MuonStub.cc @@ -91,7 +91,8 @@ void MuonStub::print() const { const Phase2L1GMT::wordtype MuonStub::hybridStubWord() const { Phase2L1GMT::wordtype w = 0; int bstart = 0; - bstart = Phase2L1GMT::wordconcat(w, bstart, 1, 1); //valid bit is always on in emulator because invalid stubs are never created + //valid bit is always on in emulator because invalid stubs are never created + bstart = Phase2L1GMT::wordconcat(w, bstart, 1, 1); bstart = Phase2L1GMT::wordconcat(w, bstart, quality_, Phase2L1GMT::BITSSTUBPHIQUALITY); bstart = Phase2L1GMT::wordconcat(w, bstart, etaQuality_, Phase2L1GMT::BITSSTUBETAQUALITY); bstart = Phase2L1GMT::wordconcat(w, bstart, bxNum_, Phase2L1GMT::BITSMUONBX); @@ -99,35 +100,40 @@ const Phase2L1GMT::wordtype MuonStub::hybridStubWord() const { bstart = Phase2L1GMT::wordconcat(w, bstart, coord2_, Phase2L1GMT::BITSSTUBCOORD); bstart = Phase2L1GMT::wordconcat(w, bstart, eta1_, Phase2L1GMT::BITSSTUBETA); bstart = Phase2L1GMT::wordconcat(w, bstart, eta2_, Phase2L1GMT::BITSSTUBETA); - bstart = Phase2L1GMT::wordconcat(w, bstart, 0, Phase2L1GMT::BITSSTUBTIME); //placeholder for time + bstart = + Phase2L1GMT::wordconcat(w, bstart, 0, Phase2L1GMT::BITSSTUBTIME); //placeholder for time int addr = address(); bstart = Phase2L1GMT::wordconcat(w, bstart, addr, Phase2L1GMT::BITSSTUBID); bstart = Phase2L1GMT::wordconcat(w, bstart, tfLayer_, 3); return w; } -void MuonStub::printHybridStub(std::string module="MuonStub", uint spaces=0, bool label=true) const { +void MuonStub::printHybridStub(std::string module = "MuonStub", uint spaces = 0, bool label = true) const { std::string lab = ""; lab.append(spaces, ' '); if (label) lab.append("hybrid stub: "); int addr = address(); - edm::LogInfo(module) << lab - << "quality = " << quality_ << ", " + edm::LogInfo(module) << lab << "quality = " << quality_ << ", " << "etaQuality = " << etaQuality_ << ", " << "bxNum = " << bxNum_ << ", " - << "coord1 = " << offline_coord1_ << " (" << coord1_ << ")" << ", " - << "coord2 = " << offline_coord2_ << " (" << coord2_ << ")" << ", " - << "eta1 = " << offline_eta1_ << " (" << eta1_ << ")" << ", " - << "eta2 = " << offline_eta2_ << " (" << eta2_ << ")" << "," - << "\n" << std::setfill(' ') << std::setw(lab.length()) << " " - << "time = " << 0 << ", " //placeholder for time - << "address = " << addr << " (id = " << id_ << ")" << ", " - << "tfLayer = " << tfLayer_ - << std::flush; + << "coord1 = " << offline_coord1_ << " (" << coord1_ << ")" + << ", " + << "coord2 = " << offline_coord2_ << " (" << coord2_ << ")" + << ", " + << "eta1 = " << offline_eta1_ << " (" << eta1_ << ")" + << ", " + << "eta2 = " << offline_eta2_ << " (" << eta2_ << ")" + << "," + << "\n" + << std::setfill(' ') << std::setw(lab.length()) << " " + << "time = " << 0 << ", " //placeholder for time + << "address = " << addr << " (id = " << id_ << ")" + << ", " + << "tfLayer = " << tfLayer_ << std::flush; } -void MuonStub::printHybridStubWord(std::string module="MuonStub", uint spaces=0, bool label=true) const { +void MuonStub::printHybridStubWord(std::string module = "MuonStub", uint spaces = 0, bool label = true) const { std::string lab = ""; lab.append(spaces, ' '); if (label) @@ -135,4 +141,3 @@ void MuonStub::printHybridStubWord(std::string module="MuonStub", uint spaces=0, Phase2L1GMT::wordtype w = MuonStub::hybridStubWord(); edm::LogInfo(module) << lab << std::setfill('0') << std::setw(16) << std::hex << w.to_uint64() << std::flush; } - diff --git a/L1Trigger/Phase2L1GMT/interface/ConvertedTTTrack.h b/L1Trigger/Phase2L1GMT/interface/ConvertedTTTrack.h index 098a08bad18ff..40939e0d90631 100644 --- a/L1Trigger/Phase2L1GMT/interface/ConvertedTTTrack.h +++ b/L1Trigger/Phase2L1GMT/interface/ConvertedTTTrack.h @@ -50,7 +50,8 @@ namespace Phase2L1GMT { const ap_uint<67> word() const { ap_uint<67> w = 0; int bstart = 0; - bstart = wordconcat>(w, bstart, 1, 1); //valid bit is always on in emulator because invalid tracks are never created + //valid bit is always on in emulator because invalid tracks are never created + bstart = wordconcat>(w, bstart, 1, 1); bstart = wordconcat>(w, bstart, charge_, 1); bstart = wordconcat>(w, bstart, pt_, BITSPT); bstart = wordconcat>(w, bstart, phi_, BITSPHI); @@ -67,40 +68,42 @@ namespace Phase2L1GMT { offline_phi_ = phi; } - void print(std::string module="ConvertedTTTrack", uint spaces=0, bool label=true) const { + void print(std::string module = "ConvertedTTTrack", uint spaces = 0, bool label = true) const { std::string lab = ""; lab.append(spaces, ' '); if (label) lab.append("converted track: "); std::string chargeSign = (charge_ == 0) ? "+1" : "-1"; - edm::LogInfo(module) << lab - << "charge = " << chargeSign << " (" << charge_ << ")" << ", " - << "pt = " << offline_pt_ << " (" << pt_ << ")" << ", " - << "phi = " << offline_phi_ << " (" << phi_ << ")" << ", " - << "eta = " << offline_eta_ << " (" << eta_ << ")" << "," - << "\n" << std::setfill(' ') << std::setw(lab.length()) << " " - << "z0 = " << z0_ << ", " - << "d0 = " << d0_ << ", " + edm::LogInfo(module) << lab << "charge = " << chargeSign << " (" << charge_ << ")" + << ", " + << "pt = " << offline_pt_ << " (" << pt_ << ")" + << ", " + << "phi = " << offline_phi_ << " (" << phi_ << ")" + << ", " + << "eta = " << offline_eta_ << " (" << eta_ << ")" + << "," + << "\n" + << std::setfill(' ') << std::setw(lab.length()) << " " + << "z0 = " << z0_ << ", " + << "d0 = " << d0_ << ", " << "quality = " << quality_ << ", " - << "(curvature = " << curvature_ << ")" - << std::flush; + << "(curvature = " << curvature_ << ")" << std::flush; } - - void printWord(std::string module="ConvertedTTTrack", uint spaces=0, bool label=true) const { + + void printWord(std::string module = "ConvertedTTTrack", uint spaces = 0, bool label = true) const { std::string lab = ""; lab.append(spaces, ' '); if (label) lab.append("converted track word = "); ap_uint<67> w = word(); - edm::LogInfo(module) << lab - << std::setfill('0') << std::setw(1) << std::hex << (long long unsigned int)((w >> 64).to_uint64()) - << std::setfill('0') << std::setw(16) << std::hex << (long long unsigned int)((w & 0xffffffffffffffff).to_uint64()) - << std::flush; + edm::LogInfo(module) << lab << std::setfill('0') << std::setw(1) << std::hex + << (long long unsigned int)((w >> 64).to_uint64()) << std::setfill('0') << std::setw(16) + << std::hex << (long long unsigned int)((w & 0xffffffffffffffff).to_uint64()) << std::flush; } - void setTrkPtr(const edm::Ptr >& trkPtr) { trkPtr_ = trkPtr; } + void setTrkPtr(const edm::Ptr>& trkPtr) { trkPtr_ = trkPtr; } - const edm::Ptr > trkPtr() const { return trkPtr_; } + const edm::Ptr> trkPtr() const { return trkPtr_; } private: ap_uint<1> charge_; @@ -116,7 +119,7 @@ namespace Phase2L1GMT { float offline_eta_; float offline_phi_; - edm::Ptr > trkPtr_; + edm::Ptr> trkPtr_; }; } // namespace Phase2L1GMT diff --git a/L1Trigger/Phase2L1GMT/interface/PreTrackMatchedMuon.h b/L1Trigger/Phase2L1GMT/interface/PreTrackMatchedMuon.h index c6890bb6161bc..2b6b5454602c9 100644 --- a/L1Trigger/Phase2L1GMT/interface/PreTrackMatchedMuon.h +++ b/L1Trigger/Phase2L1GMT/interface/PreTrackMatchedMuon.h @@ -34,11 +34,11 @@ namespace Phase2L1GMT { d0_(d0), beta_(beta), isGlobal_(false), - quality0_(0), - quality1_(0), - quality2_(0), - quality3_(0), - quality4_(0), + quality0_(0), + quality1_(0), + quality2_(0), + quality3_(0), + quality4_(0), quality_(0), stubID0_(4095), stubID1_(4095), @@ -99,34 +99,34 @@ namespace Phase2L1GMT { if (stub->tfLayer() == 0) { stubID0_ = stub->address(); matchMask_ = matchMask_ | (mask); - quality0_ = quality; + quality0_ = quality; } else if (stub->tfLayer() == 1) { stubID1_ = stub->address(); matchMask_ = matchMask_ | (mask << 2); - quality1_ = quality; + quality1_ = quality; } else if (stub->tfLayer() == 2) { stubID2_ = stub->address(); matchMask_ = matchMask_ | (mask << 4); - quality2_ = quality; + quality2_ = quality; } else if (stub->tfLayer() == 3) { stubID3_ = stub->address(); matchMask_ = matchMask_ | (mask << 6); - quality3_ = quality; + quality3_ = quality; } else if (stub->tfLayer() == 4) { stubID4_ = stub->address(); matchMask_ = matchMask_ | (mask << 8); - quality4_ = quality; + quality4_ = quality; } } - + void setCleanMask(const uint cleanMask) { cleanMask_ = cleanMask; } const uint cleanMask() const { return cleanMask_; } const l1t::MuonStubRefVector& stubs() const { return stubs_; } - void setTrkPtr(const edm::Ptr >& trkPtr) { trkPtr_ = trkPtr; } + void setTrkPtr(const edm::Ptr>& trkPtr) { trkPtr_ = trkPtr; } - const edm::Ptr > trkPtr() const { return trkPtr_; } + const edm::Ptr> trkPtr() const { return trkPtr_; } // void print() const { // LogDebug("PreTrackMatchedMuon") << "preconstructed muon : charge=" << charge_ << " pt=" << offline_pt_ << "," @@ -165,85 +165,91 @@ namespace Phase2L1GMT { } const ap_uint<182> word() const { - ap_uint<182> w = 0; - int bstart = 0; - bstart = wordconcat>(w, bstart, valid_, 1); - bstart = wordconcat>(w, bstart, charge_, 1); - bstart = wordconcat>(w, bstart, pt_, BITSPT); - bstart = wordconcat>(w, bstart, phi_, BITSPHI); - bstart = wordconcat>(w, bstart, eta_, BITSETA); - bstart = wordconcat>(w, bstart, z0_, BITSZ0); - bstart = wordconcat>(w, bstart, d0_, BITSD0); - bstart = wordconcat>(w, bstart, isGlobal_, 1); - bstart = wordconcat>(w, bstart, beta_, BITSMUONBETA); - bstart = wordconcat>(w, bstart, quality0_, BITSMATCHQUALITY-2); - bstart = wordconcat>(w, bstart, stubID0_, BITSSTUBID); - bstart = wordconcat>(w, bstart, ((matchMask_)&0b11), 2); - bstart = wordconcat>(w, bstart, quality1_, BITSMATCHQUALITY-2); - bstart = wordconcat>(w, bstart, stubID1_, BITSSTUBID); - bstart = wordconcat>(w, bstart, ((matchMask_>>2)&0b11), 2); - bstart = wordconcat>(w, bstart, quality2_, BITSMATCHQUALITY-2); - bstart = wordconcat>(w, bstart, stubID2_, BITSSTUBID); - bstart = wordconcat>(w, bstart, ((matchMask_>>4)&0b11), 2); - bstart = wordconcat>(w, bstart, quality3_, BITSMATCHQUALITY-2); - bstart = wordconcat>(w, bstart, stubID3_, BITSSTUBID); - bstart = wordconcat>(w, bstart, ((matchMask_>>6)&0b11), 2); - bstart = wordconcat>(w, bstart, quality4_, BITSMATCHQUALITY-2); - bstart = wordconcat>(w, bstart, stubID4_, BITSSTUBID); - bstart = wordconcat>(w, bstart, ((matchMask_>>8)&0b11), 2); - bstart = wordconcat>(w, bstart, quality_, BITSMATCHQUALITY); + ap_uint<182> w = 0; + int bstart = 0; + bstart = wordconcat>(w, bstart, valid_, 1); + bstart = wordconcat>(w, bstart, charge_, 1); + bstart = wordconcat>(w, bstart, pt_, BITSPT); + bstart = wordconcat>(w, bstart, phi_, BITSPHI); + bstart = wordconcat>(w, bstart, eta_, BITSETA); + bstart = wordconcat>(w, bstart, z0_, BITSZ0); + bstart = wordconcat>(w, bstart, d0_, BITSD0); + bstart = wordconcat>(w, bstart, isGlobal_, 1); + bstart = wordconcat>(w, bstart, beta_, BITSMUONBETA); + bstart = wordconcat>(w, bstart, quality0_, BITSMATCHQUALITY - 2); + bstart = wordconcat>(w, bstart, stubID0_, BITSSTUBID); + bstart = wordconcat>(w, bstart, ((matchMask_) & 0b11), 2); + bstart = wordconcat>(w, bstart, quality1_, BITSMATCHQUALITY - 2); + bstart = wordconcat>(w, bstart, stubID1_, BITSSTUBID); + bstart = wordconcat>(w, bstart, ((matchMask_ >> 2) & 0b11), 2); + bstart = wordconcat>(w, bstart, quality2_, BITSMATCHQUALITY - 2); + bstart = wordconcat>(w, bstart, stubID2_, BITSSTUBID); + bstart = wordconcat>(w, bstart, ((matchMask_ >> 4) & 0b11), 2); + bstart = wordconcat>(w, bstart, quality3_, BITSMATCHQUALITY - 2); + bstart = wordconcat>(w, bstart, stubID3_, BITSSTUBID); + bstart = wordconcat>(w, bstart, ((matchMask_ >> 6) & 0b11), 2); + bstart = wordconcat>(w, bstart, quality4_, BITSMATCHQUALITY - 2); + bstart = wordconcat>(w, bstart, stubID4_, BITSSTUBID); + bstart = wordconcat>(w, bstart, ((matchMask_ >> 8) & 0b11), 2); + bstart = wordconcat>(w, bstart, quality_, BITSMATCHQUALITY); - return w; + return w; } - void print(std::string module="PreTrackMatchedMuon", uint spaces=0, bool label=true) const { + void print(std::string module = "PreTrackMatchedMuon", uint spaces = 0, bool label = true) const { std::string lab = ""; lab.append(spaces, ' '); if (label) lab.append("TPS premuon: "); std::string chargeSign = (charge_ == 0) ? "+1" : "-1"; - edm::LogInfo(module) << lab - << "charge = " << chargeSign << " (" << charge_ << ")" << ", " - << "pt = " << offline_pt_ << " (" << pt_ << ")" << ", " - << "phi = " << offline_phi_ << " (" << phi_ << ")" << ", " - << "eta = " << offline_eta_ << " (" << eta_ << ")" << "," - << "\n" << std::setfill(' ') << std::setw(lab.length()) << " " - << "z0 = " << z0_ << ", " + edm::LogInfo(module) << lab << "charge = " << chargeSign << " (" << charge_ << ")" + << ", " + << "pt = " << offline_pt_ << " (" << pt_ << ")" + << ", " + << "phi = " << offline_phi_ << " (" << phi_ << ")" + << ", " + << "eta = " << offline_eta_ << " (" << eta_ << ")" + << "," + << "\n" + << std::setfill(' ') << std::setw(lab.length()) << " " + << "z0 = " << z0_ << ", " << "d0 = " << d0_ << ", " - << "isGlobal = " << isGlobal_ << ", " + << "isGlobal = " << isGlobal_ << ", " << "beta = " << beta_ << "," - << "\n" << std::setfill(' ') << std::setw(lab.length()) << " " - << "stubID0 = " << stubID0_ << ", " - << "stubID1 = " << stubID1_ << ", " - << "stubID2 = " << stubID2_ << ", " - << "stubID3 = " << stubID3_ << ", " - << "stubID4 = " << stubID4_ << "," - << "\n" << std::setfill(' ') << std::setw(lab.length()) << " " + << "\n" + << std::setfill(' ') << std::setw(lab.length()) << " " + << "stubID0 = " << stubID0_ << ", " + << "stubID1 = " << stubID1_ << ", " + << "stubID2 = " << stubID2_ << ", " + << "stubID3 = " << stubID3_ << ", " + << "stubID4 = " << stubID4_ << "," + << "\n" + << std::setfill(' ') << std::setw(lab.length()) << " " << "quality = " << quality_ << ", " << "quality0 = " << quality0_ << ", " - << "quality1 = " << quality1_ << ", " - << "quality2 = " << quality2_ << ", " - << "quality3 = " << quality3_ << ", " - << "quality4 = " << quality4_ - << "\n" << std::setfill(' ') << std::setw(spaces+4) << " " << "Stubs: " - << std::flush; + << "quality1 = " << quality1_ << ", " + << "quality2 = " << quality2_ << ", " + << "quality3 = " << quality3_ << ", " + << "quality4 = " << quality4_ << "\n" + << std::setfill(' ') << std::setw(spaces + 4) << " " + << "Stubs: " << std::flush; for (const auto& stub : stubs_) { - stub->printHybridStub(module, spaces+8, false); - stub->printHybridStubWord(module, spaces+12, true); + stub->printHybridStub(module, spaces + 8, false); + stub->printHybridStubWord(module, spaces + 12, true); } } - void printWord(std::string module="PreTrackMatchedMuon", uint spaces=0, bool label=true) const { + void printWord(std::string module = "PreTrackMatchedMuon", uint spaces = 0, bool label = true) const { std::string lab = ""; lab.append(spaces, ' '); if (label) lab.append("TPS premuon word = "); ap_uint<182> w = word(); - edm::LogInfo(module) << lab - << std::setfill('0') << std::setw(14) << std::hex << (long long unsigned int)((w >> 128).to_uint64()) - << std::setfill('0') << std::setw(16) << std::hex << (long long unsigned int)((w >> 64).to_uint64()) - << std::setfill('0') << std::setw(16) << std::hex << (long long unsigned int)((w & 0xffffffffffffffff).to_uint64()) - << std::flush; + edm::LogInfo(module) << lab << std::setfill('0') << std::setw(14) << std::hex + << (long long unsigned int)((w >> 128).to_uint64()) << std::setfill('0') << std::setw(16) + << std::hex << (long long unsigned int)((w >> 64).to_uint64()) << std::setfill('0') + << std::setw(16) << std::hex + << (long long unsigned int)((w & 0xffffffffffffffff).to_uint64()) << std::flush; } private: @@ -255,7 +261,7 @@ namespace Phase2L1GMT { int d0_; uint beta_; bool isGlobal_; - uint quality0_; //qualities of the matches in the individual tf layers + uint quality0_; //qualities of the matches in the individual tf layers uint quality1_; uint quality2_; uint quality3_; @@ -275,7 +281,7 @@ namespace Phase2L1GMT { bool valid_; l1t::MuonStubRefVector stubs_; l1t::SAMuonRefVector muRef_; - edm::Ptr > trkPtr_; + edm::Ptr> trkPtr_; }; } // namespace Phase2L1GMT diff --git a/L1Trigger/Phase2L1GMT/interface/TPSAlgorithm.h b/L1Trigger/Phase2L1GMT/interface/TPSAlgorithm.h index db40d5ec58639..78d483c30d7e5 100644 --- a/L1Trigger/Phase2L1GMT/interface/TPSAlgorithm.h +++ b/L1Trigger/Phase2L1GMT/interface/TPSAlgorithm.h @@ -69,12 +69,12 @@ namespace Phase2L1GMT { std::vector cleanNeighbor(const std::vector& muons, const std::vector& muonsPrevious, const std::vector& muonsNext, - bool equality); - std::vector cleanAll(std::vector& muons); - std::vector convert(std::vector& muons, uint maximum); - bool outputGT(std::vector& muons); - void SetQualityBits(std::vector& muons); - std::vector sort(std::vector& muons, uint maximum); + bool equality) const; + std::vector cleanAll(std::vector& muons) const; + std::vector convert(std::vector& muons, uint maximum) const; + bool outputGT(std::vector& muons) const; + void SetQualityBits(std::vector& muons) const; + std::vector sort(std::vector& muons, uint maximum) const; private: int verbose_; diff --git a/L1Trigger/Phase2L1GMT/interface/TrackConverter.h b/L1Trigger/Phase2L1GMT/interface/TrackConverter.h index 1c68c06cd3370..b6862e31dbbed 100644 --- a/L1Trigger/Phase2L1GMT/interface/TrackConverter.h +++ b/L1Trigger/Phase2L1GMT/interface/TrackConverter.h @@ -22,9 +22,9 @@ namespace Phase2L1GMT { uint generateQuality(const edm::Ptr >& track) { uint chi2Cut = 0xf; if ((track->getChi2RPhiBits() <= chi2Cut) && (track->getChi2RPhiBits() <= chi2Cut)) - return 1; + return 1; else - return 0; + return 0; } uint ptLookup(uint absCurv) { diff --git a/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc b/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc index 8cbe0c69f3563..3c45cc004435a 100644 --- a/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc +++ b/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc @@ -163,23 +163,23 @@ void Phase2L1TGMTStubProducer::fillDescriptions(edm::ConfigurationDescriptions& psd0.add("phiLSB", 0.02453124992); psd0.add("phiBDivider", 16); psd0.add("etaLSB", 0.024586688); - psd0.add>( - "eta_1", - { - -46, -45, -43, -41, -39, -37, -35, -30, -28, -26, -23, -20, -18, -15, -9, -6, -3, -1, - 1, 3, 6, 9, 15, 18, 20, 23, 26, 28, 30, 35, 37, 39, 41, 43, 45, 46, //1503 I think the large entries at the end here were a mistake - }); + psd0.add>("eta_1", + { + -46, -45, -43, -41, -39, -37, -35, -30, -28, -26, -23, -20, -18, + -15, -9, -6, -3, -1, 1, 3, 6, 9, 15, 18, 20, 23, + 26, 28, 30, 35, 37, 39, 41, 43, 45, 46, //1503 I think the large entries at the end here were a mistake + }); psd0.add>( "eta_2", { -41, -39, -38, -36, -34, -32, -30, -26, -24, -22, -20, -18, -15, -13, -8, -5, -3, -1, - 1, 3, 5, 8, 13, 15, 18, 20, 22, 24, 26, 30, 32, 34, 36, 38, 39, 41, //1334 + 1, 3, 5, 8, 13, 15, 18, 20, 22, 24, 26, 30, 32, 34, 36, 38, 39, 41, //1334 }); psd0.add>( "eta_3", { -35, -34, -32, -31, -29, -27, -26, -22, -20, -19, -17, -15, -13, -11, -6, -4, -2, -1, - 1, 2, 4, 6, 11, 13, 15, 17, 19, 20, 22, 26, 27, 29, 31, 32, 34, 35, //1148 + 1, 2, 4, 6, 11, 13, 15, 17, 19, 20, 22, 26, 27, 29, 31, 32, 34, 35, //1148 }); psd0.add>("coarseEta_1", { diff --git a/L1Trigger/Phase2L1GMT/src/TPS.cc b/L1Trigger/Phase2L1GMT/src/TPS.cc index 30497c2afff94..ea66dc8ccc542 100644 --- a/L1Trigger/Phase2L1GMT/src/TPS.cc +++ b/L1Trigger/Phase2L1GMT/src/TPS.cc @@ -12,7 +12,6 @@ TPS::TPS(const edm::ParameterSet& iConfig) std::vector TPS::processEvent(const std::vector >& tracks, const l1t::MuonStubRefVector& muonStubs) { - //Split tracks to the links as they come std::array >, 9> loctracks; for (unsigned i = 0; i < 9; ++i) @@ -27,30 +26,32 @@ std::vector TPS::processEvent(const std::vector stubs; for (int i = 0; i < 9; ++i) stubs[i] = associateStubsWithNonant(muonStubs, i); - + //print all tracks and stubs for an event if (verbose_ == 1) { for (unsigned i = 0; i < 9; ++i) { edm::LogInfo("TPS") << "Sector " << i << ":\n" - << " L1 Tracks:"; + << " L1 Tracks:"; for (const auto& t : loctracks[i]) { - edm::LogInfo("TPS") << " RinvBits = " << ap_int(t->getRinvBits()) << ", eta = " << t->eta() << ", phi = " << t->phi() << std::flush; - edm::LogInfo("TPS") << " l1track word = " << std::setfill('0') << std::setw(8) << std::hex << ((t->getTrackWord())>>64).to_uint64() << std::setw(16) << (t->getTrackWord()).to_uint64() << std::dec << std::flush; + edm::LogInfo("TPS") << " RinvBits = " << ap_int(t->getRinvBits()) << ", eta = " << t->eta() + << ", phi = " << t->phi() << std::flush; + edm::LogInfo("TPS") << " l1track word = " << std::setfill('0') << std::setw(8) << std::hex + << ((t->getTrackWord()) >> 64).to_uint64() << std::setw(16) + << (t->getTrackWord()).to_uint64() << std::dec << std::flush; } edm::LogInfo("TPS") << " Converted Tracks:"; for (const auto& track : convertedTracks[i]) { - track.print("TPS", 8, false); - track.printWord("TPS", 12, true); + track.print("TPS", 8, false); + track.printWord("TPS", 12, true); } edm::LogInfo("TPS") << " Stubs:"; for (const auto& stub : stubs[i]) { - stub->printHybridStub("TPS", 8, false); - stub->printHybridStubWord("TPS", 12, true); - + stub->printHybridStub("TPS", 8, false); + stub->printHybridStubWord("TPS", 12, true); } } } - + //run track - muon matching per nonant std::array, 9> mus; for (int i = 0; i < 9; ++i) @@ -62,20 +63,20 @@ std::vector TPS::processEvent(const std::vector sector_mus = mus[i]; for (const auto& sector_mu : sector_mus) { - edm::LogInfo("TPS") << " (Sector " << i << ")" << std::flush; - sector_mu.print("TPS", 4, false); - sector_mu.printWord("TPS", 8, true); + edm::LogInfo("TPS") << " (Sector " << i << ")" << std::flush; + sector_mu.print("TPS", 4, false); + sector_mu.printWord("TPS", 8, true); } } } - + //clean all of the nonants at once std::vector mergedPrecleaned; for (auto&& v : mus) { mergedPrecleaned.insert(mergedPrecleaned.end(), v.begin(), v.end()); } std::vector mergedCleaned = tps_->cleanAll(mergedPrecleaned); - + if (verbose_ == 1) { edm::LogInfo("TPS") << "After cleaning premuons:"; for (const auto& cleaned_mu : mergedCleaned) { @@ -148,7 +149,7 @@ l1t::MuonStubRefVector TPS::associateStubsWithNonant(const l1t::MuonStubRefVecto ap_int deltaPhi = phi - center; ap_uint absDeltaPhi = (deltaPhi < 0) ? ap_uint(-deltaPhi) : ap_uint(deltaPhi); - if (absDeltaPhi < 284) //was 284 //was 168 //was 42 + if (absDeltaPhi < 284) //was 284 //was 168 //was 42 out.push_back(s); } return out; diff --git a/L1Trigger/Phase2L1GMT/src/TPSAlgorithm.cc b/L1Trigger/Phase2L1GMT/src/TPSAlgorithm.cc index 0a138b84d3161..a0ae987f783f8 100644 --- a/L1Trigger/Phase2L1GMT/src/TPSAlgorithm.cc +++ b/L1Trigger/Phase2L1GMT/src/TPSAlgorithm.cc @@ -52,7 +52,7 @@ std::vector TPSAlgorithm::cleanNeighbor(const std::vector

TPSAlgorithm::cleanAll(std::vector& muons) { +std::vector TPSAlgorithm::cleanAll(std::vector& muons) const { std::vector out; if (muons.empty()) @@ -71,13 +71,16 @@ std::vector TPSAlgorithm::cleanAll(std::vector TPSAlgorithm::cleanAll(std::vector TPSAlgorithm::convert(std::vector& muons, uint maximum) { +std::vector TPSAlgorithm::convert(std::vector& muons, uint maximum) const { std::vector out; for (const auto& mu : muons) { if (out.size() == maximum) @@ -106,29 +108,33 @@ std::vector TPSAlgorithm::convert(std::vectoraddress() << "\n" << std::flush; edm::LogInfo("TPSAlgo") << "\n" - << "TrackerMuon: " << "\n" + << "TrackerMuon: " + << "\n" << " charge = " << muon.charge() << "\n" << " hwCharge = " << muon.hwCharge() << "\n" - << " stub addresses: " << "\n" - << std::flush - << std::hex << muon.word()[1] << "\n" - << std::hex << muon.word()[0] << std::flush; - for (const auto& stub : muon.stubs()) - edm::LogInfo("TPSAlgo") << " " << stub->address() << "\n" << std::flush; - edm::LogInfo("TPSAlgo") << "\n\n\n" << std::flush; + << " stub addresses: " + << "\n" + << std::flush << std::hex << muon.word()[1] << "\n" + << std::hex << muon.word()[0] << std::flush; + for (const auto& stub : muon.stubs()) + edm::LogInfo("TPSAlgo") << " " << stub->address() << "\n" << std::flush; + edm::LogInfo("TPSAlgo") << "\n\n\n" << std::flush; } uint matches = 0; @@ -137,7 +143,7 @@ std::vector TPSAlgorithm::convert(std::vector eta = track.eta(); out.eta = eta / ETADIVIDER; - + ap_uint resetak = (res1_eta * k2) >> 23; ap_ufixed sigma_eta1 = res0_eta1 + resetak; out.sigma_eta1 = ap_uint(sigma_eta1); ap_ufixed sigma_eta2 = res0_eta2 + resetak; out.sigma_eta2 = ap_uint(sigma_eta2); - + out.valid = 1; out.is_barrel = is_barrel; @@ -492,7 +498,7 @@ match_t TPSAlgorithm::match(const propagation_t prop, const l1t::MuonStubRef& st eta1Matched = 1; else eta1Matched = 0; - + if (verbose_ == 1) edm::LogInfo("TPSAlgo") << "eta1 matched=" << eta1Matched.to_int() << " delta=" << deltaEta1.to_int() << " res=" << prop_sigma_eta1.to_int(); @@ -522,7 +528,7 @@ match_t TPSAlgorithm::match(const propagation_t prop, const l1t::MuonStubRef& st if (out.valid == 0) { out.quality = 0; } else { - out.quality = 32 - deltaCoord1 / 4; //do we really need to divide by 4? + out.quality = 32 - deltaCoord1 / 4; //do we really need to divide by 4? if (coord2Matched == 1) { out.quality += 32 - deltaCoord2 / 4; out.valid = 3; @@ -565,7 +571,8 @@ match_t TPSAlgorithm::propagateAndMatch(const ConvertedTTTrack& track, match_t TPSAlgorithm::getBest(const std::vector& matches) const { match_t best = matches[0]; for (const auto& m : matches) { - if ((m.quality > best.quality) || ((m.quality == best.quality) && (m.id > best.id))) //implement well-ordered tie breaker + if ((m.quality > best.quality) || + ((m.quality == best.quality) && (m.id > best.id))) //implement well-ordered tie breaker best = m; } @@ -651,11 +658,10 @@ PreTrackMatchedMuon TPSAlgorithm::processTrack(const ConvertedTTTrack& track, //printouts if (verbose_ == 1) { - edm::LogInfo("TPSAlgo") << "Input converted track: " << std::flush; //q, pt, phi, eta, z0, d0, quality edm::LogInfo("TPSAlgo") << " " - << "q=" + to_string(ap_uint<1>(track.charge())) + ", " + << "q=" + to_string(ap_uint<1>(track.charge())) + ", " << "pt=" + to_string(ap_uint(track.pt())) + ", " << "phi=" + to_string(ap_int(track.phi())) + ", " << "eta=" + to_string(ap_int(track.eta())) + ", " @@ -663,10 +669,10 @@ PreTrackMatchedMuon TPSAlgorithm::processTrack(const ConvertedTTTrack& track, << "d0=" + to_string(ap_int(track.d0())) + ", " << "quality=" + to_string(ap_uint<1>(track.quality())) + ", " << "\n" - << std::flush; + << std::flush; edm::LogInfo("TPSAlgo") << "Input stubs:" << std::flush; - + for (const auto& stub : stubs) { edm::LogInfo("TPSAlgo") << " " << "layer=" + to_string(stub->tfLayer()) + ", " @@ -676,12 +682,11 @@ PreTrackMatchedMuon TPSAlgorithm::processTrack(const ConvertedTTTrack& track, << "eta2=" + to_string(stub->eta2()) + ", " << "quality=" + to_string(stub->quality()) + ", " << "etaQuality=" + to_string(stub->etaQuality()) + ", " - << "id=" + to_string(stub->address()) + ", " - << std::flush; + << "id=" + to_string(stub->address()) + ", " << std::flush; } edm::LogInfo("TPSAlgo") << "End stubs\n" << std::flush; - + edm::LogInfo("TPSAlgo") << "Output PreTrackMatchedMuon: " << "valid=" + to_string(muon.valid()) + ", " << "q=" + to_string(muon.charge()) + ", " @@ -693,13 +698,13 @@ PreTrackMatchedMuon TPSAlgorithm::processTrack(const ConvertedTTTrack& track, << "isGlobalMuon=" + to_string(muon.isGlobalMuon()) + ", " << "beta=" + to_string(muon.beta()) + ", " << "quality=" + to_string(muon.quality()) + ", " - << "\n" - << std::flush; + << "\n" + << std::flush; edm::LogInfo("TPSAlgo") << "Output PreTrackMatchedMuon matched stubs:" << std::flush; - + for (const auto& stub : muon.stubs()) { - match_t tempmatch = propagateAndMatch(track, stub, 0); //want to verify details of match as well as stub + match_t tempmatch = propagateAndMatch(track, stub, 0); //want to verify details of match as well as stub edm::LogInfo("TPSAlgo") << " " << "layer=" + to_string(stub->tfLayer()) + ", " << "coord1=" + to_string(stub->coord1()) + ", " @@ -710,12 +715,10 @@ PreTrackMatchedMuon TPSAlgorithm::processTrack(const ConvertedTTTrack& track, << "etaQuality=" + to_string(stub->etaQuality()) + ", " << "id=" + to_string(stub->address()) + ", " << "quality=" + to_string(tempmatch.quality) + ", " - << "valid=" + to_string(tempmatch.valid) + ", " - << std::flush; + << "valid=" + to_string(tempmatch.valid) + ", " << std::flush; } - edm::LogInfo("TPSAlgo") << "End stubs\n\n" << std::flush; - + edm::LogInfo("TPSAlgo") << "End stubs\n\n" << std::flush; } return muon; From 8901e721728c21b112d5c01e207adb7d4590f88b Mon Sep 17 00:00:00 2001 From: Lovisa Date: Mon, 8 Dec 2025 14:46:53 +0100 Subject: [PATCH 20/61] Including EXOnanoAODv1 custom constent --- .../PyReleaseValidation/python/relval_nano.py | 12 + .../NanoAOD/interface/DisTauTagScaling.h | 191 ++++ PhysicsTools/NanoAOD/plugins/BuildFile.xml | 10 + .../NanoAOD/plugins/DSAMuonTableProducer.cc | 318 +++++++ PhysicsTools/NanoAOD/plugins/DisTauTag.cc | 338 +++++++ .../NanoAOD/plugins/DispJetTableProducer.cc | 491 ++++++++++ .../plugins/ElectronExtendedTableProducer.cc | 295 ++++++ .../plugins/ElectronVertexTableProducer.cc | 468 ++++++++++ .../NanoAOD/plugins/JetImpactParameters.cc | 140 +++ .../plugins/MuonExtendedTableProducer.cc | 338 +++++++ .../plugins/MuonVertexTableProducer.cc | 874 ++++++++++++++++++ .../plugins/cscMDSshowerTableProducer.cc | 390 ++++++++ .../plugins/dtMDSshowerTableProducer.cc | 339 +++++++ PhysicsTools/NanoAOD/python/autoNANO.py | 3 + .../NanoAOD/python/custom_displacedtau_cff.py | 157 ++++ PhysicsTools/NanoAOD/python/custom_exo_cff.py | 315 +++++++ PhysicsTools/NanoAOD/test/test-exoNano.sh | 1 + 17 files changed, 4680 insertions(+) create mode 100644 PhysicsTools/NanoAOD/interface/DisTauTagScaling.h create mode 100644 PhysicsTools/NanoAOD/plugins/DSAMuonTableProducer.cc create mode 100644 PhysicsTools/NanoAOD/plugins/DisTauTag.cc create mode 100644 PhysicsTools/NanoAOD/plugins/DispJetTableProducer.cc create mode 100644 PhysicsTools/NanoAOD/plugins/ElectronExtendedTableProducer.cc create mode 100644 PhysicsTools/NanoAOD/plugins/ElectronVertexTableProducer.cc create mode 100644 PhysicsTools/NanoAOD/plugins/JetImpactParameters.cc create mode 100644 PhysicsTools/NanoAOD/plugins/MuonExtendedTableProducer.cc create mode 100644 PhysicsTools/NanoAOD/plugins/MuonVertexTableProducer.cc create mode 100644 PhysicsTools/NanoAOD/plugins/cscMDSshowerTableProducer.cc create mode 100644 PhysicsTools/NanoAOD/plugins/dtMDSshowerTableProducer.cc create mode 100644 PhysicsTools/NanoAOD/python/custom_displacedtau_cff.py create mode 100644 PhysicsTools/NanoAOD/python/custom_exo_cff.py create mode 100755 PhysicsTools/NanoAOD/test/test-exoNano.sh diff --git a/Configuration/PyReleaseValidation/python/relval_nano.py b/Configuration/PyReleaseValidation/python/relval_nano.py index 476ab6a6333c8..c25931b6d2a12 100644 --- a/Configuration/PyReleaseValidation/python/relval_nano.py +++ b/Configuration/PyReleaseValidation/python/relval_nano.py @@ -306,6 +306,9 @@ def subnext(self): steps['BTVNANO_mc15.0'] = merge([{'-s': 'NANO:@BTV,DQM:@nanoAODDQM', '-n': '1000'}, steps['NANO_mc15.0']]) +steps['EXONANO_mc15.0'] = merge([{'-s': 'PAT,NANO:@EXO', '-n': '1000'}, + steps['NANO_mc15.0']]) + steps['lepTrackInfoNANO_mc15.0'] = merge([{'-s': 'NANO:@LepTrackInfo,DQM:@nanoAODDQM', '-n': '1000'}, steps['NANO_mc15.0']]) @@ -323,10 +326,14 @@ def subnext(self): # ====== DATA ====== lumis_Run2025C = {392175: [[95, 542]]} +lumis_Run2025C_Muon0 = {392997: [[146, 202]]} steps['JetMET1_Run2025C_MINIAOD_150X'] = {'INPUT': InputInfo( location='STD', ls=lumis_Run2025C, dataSet='/JetMET1/Run2025C-PromptReco-v1/MINIAOD')} +steps['Muon0_Run2025C_AOD_150X'] = {'INPUT': InputInfo( + location='STD',ls=lumis_Run2025C_Muon0, dataSet='/Muon0/Run2025C-PromptReco-v1/AOD')} + steps['ScoutingPFRun3_Run2025C_HLTSCOUT_150X'] = {'INPUT': InputInfo(location='STD', ls=lumis_Run2025C, dataSet='/ScoutingPFRun3/Run2025C-v1/HLTSCOUT')} @@ -350,6 +357,9 @@ def subnext(self): steps['BTVNANO_data15.0'] = merge([{'-s': 'NANO:@BTV,DQM:@nanoAODDQM', '-n': '1000'}, steps['NANO_data15.0']]) +steps['EXONANO_data15.0'] = merge([{'-s': 'PAT,NANO:@EXO', '-n': '1000'}, + steps['NANO_data15.0']]) + steps['lepTrackInfoNANO_data15.0'] = merge([{'-s': 'NANO:@LepTrackInfo,DQM:@nanoAODDQM', '-n': '1000'}, steps['NANO_data15.0']]) @@ -495,6 +505,7 @@ def subnext(self): workflows[_wfn()] = ['ScoutingNANOmc150X', ['TTbar_13p6_Summer24_MINIAOD_150X', 'scoutingNANO_mc15.0']] workflows[_wfn()] = ['ScoutingNANOwithPromptmc150X', ['TTbar_13p6_Summer24_MINIAOD_150X', 'scoutingNANO_withPrompt_mc15.0']] workflows[_wfn()] = ['BPHNANOmc150X', ['TTbar_13p6_Summer24_MINIAOD_150X', 'BPHNANO_mc15.0']] +workflows[_wfn()] = ['EXONANOmc150X', ['TTbar_13p6_Summer24_AOD_140X', 'EXONANO_mc15.0']] # POG/PAG custom NANOs, data _wfn.subnext() @@ -507,6 +518,7 @@ def subnext(self): workflows[_wfn()] = ['ScoutingNANOdata150Xrun3', ['ScoutingPFRun3_Run2025C_HLTSCOUT_150X', 'scoutingNANO_data15.0']] workflows[_wfn()] = ['ScoutingNANOwithPromptdata150Xrun3', ['ScoutingPFMonitor_Run2025C_MINIAOD_150X', 'scoutingNANO_withPrompt_data15.0']] # noqa workflows[_wfn()] = ['BPHNANOdata150Xrun3', ['JetMET1_Run2025C_MINIAOD_150X', 'BPHNANO_data15.0']] +workflows[_wfn()] = ['EXONANOdata150Xrun3', ['Muon0_Run2025C_AOD_150X', 'EXONANO_data15.0']] # DPG custom NANOs, data _wfn.subnext() diff --git a/PhysicsTools/NanoAOD/interface/DisTauTagScaling.h b/PhysicsTools/NanoAOD/interface/DisTauTagScaling.h new file mode 100644 index 0000000000000..8027dc6a679a9 --- /dev/null +++ b/PhysicsTools/NanoAOD/interface/DisTauTagScaling.h @@ -0,0 +1,191 @@ +namespace scaling { + struct PfCand { + inline static const std::vector> mean = {{0, 0}, + {50.0, 50.0}, + {0.0, 0.0}, + {0.0, 0.0}, + {0.09469, 0.09469}, + {0, 0}, + {0, 0}, + {0, 0}, + {5.0, 5.0}, + {5.0, 5.0}, + {6.442, 6.442}, + {0, 0}, + {-0.01635, -0.01635}, + {0.02704, 0.02704}, + {-0.01443, -0.01443}, + {0.05551, 0.05551}, + {11.16, 11.16}, + {13.53, 13.53}, + {0.5, 0.5}, + {0.5, 0.5}, + {1.3, 1.3}, + {0.5, 0.5}, + {0, 0}, + {0, 0}}; + inline static const std::vector> std = {{1, 1}, {50.0, 50.0}, + {3.0, 3.0}, {3.141592653589793, 3.141592653589793}, + {0.0651, 0.0651}, {1, 1}, + {1, 1}, {1, 1}, + {5.0, 5.0}, {5.0, 5.0}, + {8.344, 8.344}, {1, 1}, + {2.4, 2.4}, {0.08913, 0.08913}, + {7.444, 7.444}, {0.5998, 0.5998}, + {60.39, 60.39}, {6.44, 6.44}, + {0.5, 0.5}, {0.5, 0.5}, + {1.3, 1.3}, {0.5, 0.5}, + {1, 1}, {1, 1}}; + inline static const std::vector> lim_min = { + {-std::numeric_limits::infinity(), -std::numeric_limits::infinity()}, + {-1.0, -1.0}, + {-1.0, -1.0}, + {-1.0, -1.0}, + {-5, -5}, + {-std::numeric_limits::infinity(), -std::numeric_limits::infinity()}, + {-std::numeric_limits::infinity(), -std::numeric_limits::infinity()}, + {-std::numeric_limits::infinity(), -std::numeric_limits::infinity()}, + {-1.0, -1.0}, + {-1.0, -1.0}, + {-5, -5}, + {-std::numeric_limits::infinity(), -std::numeric_limits::infinity()}, + {-5, -5}, + {-5, -5}, + {-5, -5}, + {-5, -5}, + {-5, -5}, + {-5, -5}, + {-1.0, -1.0}, + {-1.0, -1.0}, + {-1.0, -1.0}, + {-1.0, -1.0}, + {-std::numeric_limits::infinity(), -std::numeric_limits::infinity()}, + {-std::numeric_limits::infinity(), -std::numeric_limits::infinity()}}; + inline static const std::vector> lim_max = { + {std::numeric_limits::infinity(), std::numeric_limits::infinity()}, + {1.0, 1.0}, + {1.0, 1.0}, + {1.0, 1.0}, + {5, 5}, + {std::numeric_limits::infinity(), std::numeric_limits::infinity()}, + {std::numeric_limits::infinity(), std::numeric_limits::infinity()}, + {std::numeric_limits::infinity(), std::numeric_limits::infinity()}, + {1.0, 1.0}, + {1.0, 1.0}, + {5, 5}, + {std::numeric_limits::infinity(), std::numeric_limits::infinity()}, + {5, 5}, + {5, 5}, + {5, 5}, + {5, 5}, + {5, 5}, + {5, 5}, + {1.0, 1.0}, + {1.0, 1.0}, + {1.0, 1.0}, + {1.0, 1.0}, + {std::numeric_limits::infinity(), std::numeric_limits::infinity()}, + {std::numeric_limits::infinity(), std::numeric_limits::infinity()}}; + }; + struct PfCandCategorical { + inline static const std::vector> mean = {{0, 0}, {0, 0}, {0, 0}}; + inline static const std::vector> std = {{1, 1}, {1, 1}, {1, 1}}; + inline static const std::vector> lim_min = { + {-std::numeric_limits::infinity(), -std::numeric_limits::infinity()}, + {-std::numeric_limits::infinity(), -std::numeric_limits::infinity()}, + {-std::numeric_limits::infinity(), -std::numeric_limits::infinity()}}; + inline static const std::vector> lim_max = { + {std::numeric_limits::infinity(), std::numeric_limits::infinity()}, + {std::numeric_limits::infinity(), std::numeric_limits::infinity()}, + {std::numeric_limits::infinity(), std::numeric_limits::infinity()}}; + }; +}; // namespace scaling + +namespace setupSizes { + const inline long int output_classes = 2; + const inline size_t n_Global = 5; + const inline size_t n_PfCand = 24; + const inline size_t nSeq_PfCand = 50; + const inline size_t n_PfCandCategorical = 3; + const inline size_t nSeq_PfCandCategorical = 50; + const inline std::vector CellObjectTypes{"PfCand", "PfCandCategorical"}; +}; // namespace setupSizes + +enum class Global_Features { jet_pt = 0, jet_eta = 1, Lxy = 2, Lz = 3, Lrel = 4 }; + +enum class PfCand_Features { + pfCand_valid = 0, + pfCand_pt = 1, + pfCand_eta = 2, + pfCand_phi = 3, + pfCand_mass = 4, + pfCand_charge = 5, + pfCand_puppiWeight = 6, + pfCand_puppiWeightNoLep = 7, + pfCand_lostInnerHits = 8, + pfCand_nPixelHits = 9, + pfCand_nHits = 10, + pfCand_hasTrackDetails = 11, + pfCand_dxy = 12, + pfCand_dxy_error = 13, + pfCand_dz = 14, + pfCand_dz_error = 15, + pfCand_track_chi2 = 16, + pfCand_track_ndof = 17, + pfCand_caloFraction = 18, + pfCand_hcalFraction = 19, + pfCand_rawCaloFraction = 20, + pfCand_rawHcalFraction = 21, + pfCand_deta = 22, + pfCand_dphi = 23 +}; + +enum class PfCandCategorical_Features { pfCand_particleType = 0, pfCand_pvAssociationQuality = 1, pfCand_fromPV = 2 }; + +enum class CellObjectType { PfCand, PfCandCategorical }; + +template +struct FeaturesHelper; + +template <> +struct FeaturesHelper { + static constexpr CellObjectType object_type = CellObjectType::PfCand; + static constexpr size_t size = 24; + static constexpr size_t length = 50; + using scaler_type = scaling::PfCand; +}; + +template <> +struct FeaturesHelper { + static constexpr CellObjectType object_type = CellObjectType::PfCandCategorical; + static constexpr size_t size = 3; + static constexpr size_t length = 50; + using scaler_type = scaling::PfCandCategorical; +}; + +using FeatureTuple = std::tuple; + +enum class PFParticleType { + Undefined = 0, // undefined + h = 1, // charged hadron + e = 2, // electron + mu = 3, // muon + gamma = 4, // photon + h0 = 5, // neutral hadron + h_HF = 6, // HF tower identified as a hadron + egamma_HF = 7, // HF tower identified as an EM particle +}; + +inline PFParticleType TranslatePdgIdToPFParticleType(int pdgId) { + static const std::map type_map = { + {11, PFParticleType::e}, + {13, PFParticleType::mu}, + {22, PFParticleType::gamma}, + {211, PFParticleType::h}, + {130, PFParticleType::h0}, + {1, PFParticleType::h_HF}, + {2, PFParticleType::egamma_HF}, + }; + auto iter = type_map.find(std::abs(pdgId)); + return iter == type_map.end() ? PFParticleType::Undefined : iter->second; +} diff --git a/PhysicsTools/NanoAOD/plugins/BuildFile.xml b/PhysicsTools/NanoAOD/plugins/BuildFile.xml index bbe8818cfa63a..003e5b6107791 100644 --- a/PhysicsTools/NanoAOD/plugins/BuildFile.xml +++ b/PhysicsTools/NanoAOD/plugins/BuildFile.xml @@ -22,8 +22,17 @@ + + + + + + + + + @@ -34,6 +43,7 @@ + diff --git a/PhysicsTools/NanoAOD/plugins/DSAMuonTableProducer.cc b/PhysicsTools/NanoAOD/plugins/DSAMuonTableProducer.cc new file mode 100644 index 0000000000000..974522e02a33d --- /dev/null +++ b/PhysicsTools/NanoAOD/plugins/DSAMuonTableProducer.cc @@ -0,0 +1,318 @@ +// system include files +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/global/EDProducer.h" + +#include "FWCore/Framework/interface/Event.h" + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" + +#include "DataFormats/PatCandidates/interface/Muon.h" +#include "DataFormats/MuonReco/interface/MuonSelectors.h" +#include "DataFormats/NanoAOD/interface/FlatTable.h" + +#include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h" +#include "TrackingTools/Records/interface/TransientTrackRecord.h" +#include "TrackingTools/IPTools/interface/IPTools.h" +#include "DataFormats/TrackReco/interface/Track.h" +#include "DataFormats/VertexReco/interface/VertexFwd.h" +#include "DataFormats/VertexReco/interface/Vertex.h" + +class DSAMuonTableProducer : public edm::global::EDProducer<> { +public: + DSAMuonTableProducer(const edm::ParameterSet& iConfig) + : name_(iConfig.getParameter("name")), + dsaMuonTag_(consumes>(iConfig.getParameter("dsaMuons"))), + muonTag_(consumes>(iConfig.getParameter("muons"))), + vtxTag_(consumes(iConfig.getParameter("primaryVertex"))), + bsTag_(consumes(iConfig.getParameter("beamspot"))), + transientTrackBuilderToken_(esConsumes(edm::ESInputTag("", "TransientTrackBuilder"))) { + produces(); + } + + ~DSAMuonTableProducer() override {} + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("name")->setComment("name of the muon nanoaod::FlatTable"); + desc.add("dsaMuons")->setComment("input displaced standalone muon collection"); + desc.add("muons")->setComment("input muon collection"); + desc.add("primaryVertex")->setComment("input primary vertex collection"); + desc.add("beamspot")->setComment("input beamspot collection"); + descriptions.add("DSAMuonTable", desc); + } + +private: + void produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const override; + + bool passesDisplacedID(const reco::Track& dsaMuon) const; + std::tuple getMatches(const pat::Muon& muon, + const reco::Track& dsaMuon, + float minPositionDiff = 1e-6) const; + std::tuple getSegments(const reco::Track& dsaMuon) const; + + std::string name_; + edm::EDGetTokenT> dsaMuonTag_; + edm::EDGetTokenT> muonTag_; + edm::EDGetTokenT vtxTag_; + edm::EDGetTokenT bsTag_; + edm::ESGetToken transientTrackBuilderToken_; +}; + +void DSAMuonTableProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const { + float minPositionDiffForMatching = 1e-6; + + const std::vector& dsaMuons = iEvent.get(dsaMuonTag_); + const std::vector& patMuons = iEvent.get(muonTag_); + + const reco::VertexCollection& primaryVertices = iEvent.get(vtxTag_); + const auto& pv = primaryVertices.at(0); + GlobalPoint primaryVertex(pv.x(), pv.y(), pv.z()); + + const reco::BeamSpot& beamSpotInput = iEvent.get(bsTag_); + const auto& bs = beamSpotInput.position(); + GlobalPoint beamSpot(bs.x(), bs.y(), bs.z()); + reco::Vertex beamSpotVertex(beamSpotInput.position(), beamSpotInput.covariance3D()); + + const TransientTrackBuilder& builder = iSetup.getData(transientTrackBuilderToken_); + + unsigned int nDSAMuons = dsaMuons.size(); + unsigned int nMuons = patMuons.size(); + + std::vector idx, trkNumPlanes, trkNumHits, trkNumDTHits, trkNumCSCHits, outerEta, outerPhi; + + std::vector dzPV, dzPVErr, dxyPVTraj, dxyPVTrajErr, dxyPVSigned, dxyPVSignedErr, ip3DPVSigned, ip3DPVSignedErr; + + std::vector displacedId; + std::vector> nMatchesPerMuon; + std::vector muonMatch1, muonMatch1idx, muonMatch2, muonMatch2idx, muonMatch3, muonMatch3idx, muonMatch4, + muonMatch4idx, muonMatch5, muonMatch5idx; + std::vector muonDTMatch1, muonDTMatch1idx, muonDTMatch2, muonDTMatch2idx, muonDTMatch3, muonDTMatch3idx; + std::vector muonCSCMatch1, muonCSCMatch1idx, muonCSCMatch2, muonCSCMatch2idx, muonCSCMatch3, muonCSCMatch3idx; + std::vector nSegments, nDTSegments, nCSCSegments; + + std::vector totPATmatches, totPATmatchesOS, totPATmatchesDisplID, totPATmatchesDisplIDOS, + totLoosePATmatchesDisplID, totLoosePATmatchesDisplIDOS; + std::vector LoosePATmatchesDisplIDOSpt, LoosePATmatchesDisplIDOSdsaDetID1, LoosePATmatchesDisplIDOSdsaDetID2, + LoosePATmatchesDisplIDOSdsaDetID3; + + for (unsigned int i = 0; i < nDSAMuons; i++) { + const reco::Track& dsaMuon = dsaMuons[i]; + idx.push_back(i); + + trkNumPlanes.push_back(dsaMuon.hitPattern().muonStationsWithValidHits()); + trkNumHits.push_back(dsaMuon.hitPattern().numberOfValidMuonHits()); + trkNumDTHits.push_back(dsaMuon.hitPattern().numberOfValidMuonDTHits()); + trkNumCSCHits.push_back(dsaMuon.hitPattern().numberOfValidMuonCSCHits()); + + outerEta.push_back(dsaMuon.extra().isNonnull() && dsaMuon.extra().isAvailable() ? dsaMuon.outerEta() : -999); + outerPhi.push_back(dsaMuon.extra().isNonnull() && dsaMuon.extra().isAvailable() ? dsaMuon.outerPhi() : -999); + + dzPV.push_back(dsaMuon.dz(pv.position())); + dzPVErr.push_back(std::hypot(dsaMuon.dzError(), pv.zError())); + reco::TransientTrack transientTrack = builder.build(dsaMuon); + TrajectoryStateClosestToPoint trajectoryPV = transientTrack.trajectoryStateClosestToPoint(primaryVertex); + dxyPVTraj.push_back(trajectoryPV.perigeeParameters().transverseImpactParameter()); + dxyPVTrajErr.push_back(trajectoryPV.perigeeError().transverseImpactParameterError()); + GlobalVector muonRefTrackDir(dsaMuon.px(), dsaMuon.py(), dsaMuon.pz()); + dxyPVSigned.push_back(IPTools::signedTransverseImpactParameter(transientTrack, muonRefTrackDir, pv).second.value()); + dxyPVSignedErr.push_back( + IPTools::signedTransverseImpactParameter(transientTrack, muonRefTrackDir, pv).second.error()); + + ip3DPVSigned.push_back(IPTools::signedImpactParameter3D(transientTrack, muonRefTrackDir, pv).second.value()); + ip3DPVSignedErr.push_back(IPTools::signedImpactParameter3D(transientTrack, muonRefTrackDir, pv).second.error()); + + float passesDisplacedId = 0; + if (passesDisplacedID(dsaMuon)) + passesDisplacedId = 1; + displacedId.push_back(passesDisplacedId); + + // Assigning 5 best matches and corresponding muon indices + std::vector> muonMatches(5, std::make_pair(-1.0, -1.0)); + std::vector> muonDTMatches(5, std::make_pair(-1.0, -1.0)); + std::vector> muonCSCMatches(5, std::make_pair(-1.0, -1.0)); + std::vector nMuonMatches; + std::vector nMuonDTMatches; + std::vector nMuonCSCMatches; + for (unsigned int j = 0; j < nMuons; j++) { + if (j > 4) + break; + const pat::Muon& muon = patMuons[j]; + // Muon-DSA Matches Table + auto [nDTMatches, nCSCMatches] = getMatches(muon, dsaMuon, minPositionDiffForMatching); + int nMatches = nDTMatches + nCSCMatches; + muonMatches[j] = std::make_pair(nMatches, j); + muonDTMatches[j] = std::make_pair(nDTMatches, j); + muonCSCMatches[j] = std::make_pair(nCSCMatches, j); + nMuonMatches.push_back(nMatches); + nMuonDTMatches.push_back(nDTMatches); + nMuonCSCMatches.push_back(nCSCMatches); + } + nMatchesPerMuon.push_back(nMuonMatches); + nMatchesPerMuon.push_back(nMuonDTMatches); + nMatchesPerMuon.push_back(nMuonCSCMatches); + std::sort(muonMatches.rbegin(), muonMatches.rend()); + std::sort(muonDTMatches.rbegin(), muonDTMatches.rend()); + std::sort(muonCSCMatches.rbegin(), muonCSCMatches.rend()); + muonMatch1.push_back(muonMatches[0].first); + muonMatch1idx.push_back(muonMatches[0].second); + muonMatch2.push_back(muonMatches[1].first); + muonMatch2idx.push_back(muonMatches[1].second); + muonMatch3.push_back(muonMatches[2].first); + muonMatch3idx.push_back(muonMatches[2].second); + muonMatch4.push_back(muonMatches[3].first); + muonMatch4idx.push_back(muonMatches[3].second); + muonMatch5.push_back(muonMatches[4].first); + muonMatch5idx.push_back(muonMatches[4].second); + + muonDTMatch1.push_back(muonDTMatches[0].first); + muonDTMatch1idx.push_back(muonDTMatches[0].second); + muonDTMatch2.push_back(muonDTMatches[1].first); + muonDTMatch2idx.push_back(muonDTMatches[1].second); + muonDTMatch3.push_back(muonDTMatches[2].first); + muonDTMatch3idx.push_back(muonDTMatches[2].second); + muonCSCMatch1.push_back(muonCSCMatches[0].first); + muonCSCMatch1idx.push_back(muonCSCMatches[0].second); + muonCSCMatch2.push_back(muonCSCMatches[1].first); + muonCSCMatch2idx.push_back(muonCSCMatches[1].second); + muonCSCMatch3.push_back(muonCSCMatches[2].first); + muonCSCMatch3idx.push_back(muonCSCMatches[2].second); + + auto [nDTSegments_, nCSCSegments_] = getSegments(dsaMuon); + nSegments.push_back(nDTSegments_ + nCSCSegments_); + nDTSegments.push_back(nDTSegments_); + nCSCSegments.push_back(nCSCSegments_); + } + + auto dsaMuonTab = std::make_unique(dsaMuons.size(), name_, false, true); + + dsaMuonTab->addColumn("idx", idx, ""); + dsaMuonTab->addColumn("trkNumPlanes", trkNumPlanes, ""); + dsaMuonTab->addColumn("trkNumHits", trkNumHits, ""); + dsaMuonTab->addColumn("trkNumDTHits", trkNumDTHits, ""); + dsaMuonTab->addColumn("trkNumCSCHits", trkNumCSCHits, ""); + + dsaMuonTab->addColumn("outerEta", outerEta, ""); + dsaMuonTab->addColumn("outerPhi", outerPhi, ""); + + dsaMuonTab->addColumn("dzPV", dzPV, ""); + dsaMuonTab->addColumn("dzPVErr", dzPVErr, ""); + dsaMuonTab->addColumn("dxyPVTraj", dxyPVTraj, ""); + dsaMuonTab->addColumn("dxyPVTrajErr", dxyPVTrajErr, ""); + dsaMuonTab->addColumn("dxyPVSigned", dxyPVSigned, ""); + dsaMuonTab->addColumn("dxyPVSignedErr", dxyPVSignedErr, ""); + dsaMuonTab->addColumn("ip3DPVSigned", ip3DPVSigned, ""); + dsaMuonTab->addColumn("ip3DPVSignedErr", ip3DPVSignedErr, ""); + + dsaMuonTab->addColumn("displacedID", displacedId, ""); + + dsaMuonTab->addColumn("muonMatch1", muonMatch1, ""); + dsaMuonTab->addColumn("muonMatch1idx", muonMatch1idx, ""); + dsaMuonTab->addColumn("muonMatch2", muonMatch2, ""); + dsaMuonTab->addColumn("muonMatch2idx", muonMatch2idx, ""); + dsaMuonTab->addColumn("muonMatch3", muonMatch3, ""); + dsaMuonTab->addColumn("muonMatch3idx", muonMatch3idx, ""); + dsaMuonTab->addColumn("muonMatch4", muonMatch4, ""); + dsaMuonTab->addColumn("muonMatch4idx", muonMatch4idx, ""); + dsaMuonTab->addColumn("muonMatch5", muonMatch5, ""); + dsaMuonTab->addColumn("muonMatch5idx", muonMatch5idx, ""); + + dsaMuonTab->addColumn("muonDTMatch1", muonDTMatch1, ""); + dsaMuonTab->addColumn("muonDTMatch1idx", muonDTMatch1idx, ""); + dsaMuonTab->addColumn("muonDTMatch2", muonDTMatch2, ""); + dsaMuonTab->addColumn("muonDTMatch2idx", muonDTMatch2idx, ""); + dsaMuonTab->addColumn("muonDTMatch3", muonDTMatch3, ""); + dsaMuonTab->addColumn("muonDTMatch3idx", muonDTMatch3idx, ""); + + dsaMuonTab->addColumn("muonCSCMatch1", muonCSCMatch1, ""); + dsaMuonTab->addColumn("muonCSCMatch1idx", muonCSCMatch1idx, ""); + dsaMuonTab->addColumn("muonCSCMatch2", muonCSCMatch2, ""); + dsaMuonTab->addColumn("muonCSCMatch2idx", muonCSCMatch2idx, ""); + dsaMuonTab->addColumn("muonCSCMatch3", muonCSCMatch3, ""); + dsaMuonTab->addColumn("muonCSCMatch3idx", muonCSCMatch3idx, ""); + + dsaMuonTab->addColumn("nSegments", nSegments, ""); + dsaMuonTab->addColumn("nDTSegments", nDTSegments, ""); + dsaMuonTab->addColumn("nCSCSegments", nCSCSegments, ""); + + iEvent.put(std::move(dsaMuonTab)); +} + +bool DSAMuonTableProducer::passesDisplacedID(const reco::Track& dsaMuon) const { + // displaced muon Id as recommended by Muon POG + float validHits = dsaMuon.hitPattern().numberOfValidMuonCSCHits() + dsaMuon.hitPattern().numberOfValidMuonDTHits(); + if (validHits > 12) { + if (dsaMuon.hitPattern().numberOfValidMuonCSCHits() != 0 || + (dsaMuon.hitPattern().numberOfValidMuonCSCHits() == 0 && dsaMuon.hitPattern().numberOfValidMuonDTHits() > 18)) { + if (dsaMuon.normalizedChi2() < 2.5) { + if (dsaMuon.ptError() / dsaMuon.pt() < 1) { + return true; + } + } + } + } + return false; +} + +// Returns number of DT and CSC segments of the DSA muon are associated to the PAT muon +std::tuple DSAMuonTableProducer::getMatches(const pat::Muon& muon, + const reco::Track& dsaMuon, + float minPositionDiff) const { + int nMatchesDT = 0; + int nMatchesCSC = 0; + + if (dsaMuon.extra().isNonnull() && dsaMuon.extra().isAvailable()) { + for (auto& hit : dsaMuon.recHits()) { + if (!hit->isValid()) + continue; + DetId id = hit->geographicalId(); + if (id.det() != DetId::Muon) + continue; + + if (id.subdetId() == MuonSubdetId::DT || id.subdetId() == MuonSubdetId::CSC) { + for (auto& chamber : muon.matches()) { + if (chamber.id.rawId() != id.rawId()) + continue; + + for (auto& segment : chamber.segmentMatches) { + if (fabs(segment.x - hit->localPosition().x()) < minPositionDiff && + fabs(segment.y - hit->localPosition().y()) < minPositionDiff) { + if (id.subdetId() == MuonSubdetId::DT) + nMatchesDT++; + else + nMatchesCSC++; + break; + } + } + } + } + } + } + return {nMatchesDT, nMatchesCSC}; +} + +std::tuple DSAMuonTableProducer::getSegments(const reco::Track& dsaMuon) const { + int nHitsDT = 0; + int nHitsCSC = 0; + if (dsaMuon.extra().isNonnull() && dsaMuon.extra().isAvailable()) { + for (auto& hit : dsaMuon.recHits()) { + if (!hit->isValid()) + continue; + DetId id = hit->geographicalId(); + if (id.det() != DetId::Muon) + continue; + if (id.subdetId() == MuonSubdetId::DT) + nHitsDT++; + if (id.subdetId() == MuonSubdetId::DT) + nHitsCSC++; + } + } + return {nHitsDT, nHitsCSC}; +} + +#include "FWCore/Framework/interface/MakerMacros.h" +DEFINE_FWK_MODULE(DSAMuonTableProducer); diff --git a/PhysicsTools/NanoAOD/plugins/DisTauTag.cc b/PhysicsTools/NanoAOD/plugins/DisTauTag.cc new file mode 100644 index 0000000000000..f8a27692b6b96 --- /dev/null +++ b/PhysicsTools/NanoAOD/plugins/DisTauTag.cc @@ -0,0 +1,338 @@ + +/* + +///////////////////////////////////// + +// Displaced tau training features with multi-threading : Mykyta Shchedrolosiev , Pritam Palit, created on 01/09/2025 + +///////////////////////////////////// + +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "DataFormats/PatCandidates/interface/Jet.h" +#include "DataFormats/PatCandidates/interface/PackedCandidate.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/FileInPath.h" +#include "FWCore/Utilities/interface/StreamID.h" +#include "PhysicsTools/TensorFlow/interface/TensorFlow.h" + +#include "PhysicsTools/NanoAOD/interface/DisTauTagScaling.h" + +void test_vector(std::vector& values) { + for (auto& value : values) { + if (std::isnan(value)) { + throw std::runtime_error("DisTauTag score output: NaN detected."); + } else if (std::isinf(value)) { + throw std::runtime_error("DisTauTag score output: Infinity detected."); + } else if (!std::isfinite(value)) { + throw std::runtime_error("DisTauTag score output: Non-standard value detected."); + } + } +} + +class DisTauTag : public edm::global::EDProducer<> { +public: + explicit DisTauTag(const edm::ParameterSet&); + ~DisTauTag() override; + + template + static Scalar getDeltaPhi(Scalar phi1, Scalar phi2); + + static void fill_zero(tensorflow::Tensor&); + +private: + void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; + + template + float Scale(const Int_t, const Float_t, const bool) const; + void saveInputs(const tensorflow::Tensor& tensor, + const std::string& block_name, + const edm::EventID& eventId, + size_t jetIndex) const; + + void initializeTensorFlow(); + + const edm::FileInPath graphPath_; + const edm::EDGetTokenT jets_token; + const bool save_inputs_; + const unsigned batch_size_; + + // TensorFlow resources for threading + tensorflow::GraphDef* graphDef_; + tensorflow::Session* session_; +}; + +DisTauTag::~DisTauTag() { + if (session_) { + tensorflow::closeSession(session_); + } + delete graphDef_; +} + +DisTauTag::DisTauTag(const edm::ParameterSet& config) + : graphPath_(config.getParameter("graphPath")), + jets_token(consumes(config.getParameter("jets"))), + save_inputs_(config.getParameter("save_inputs")), + batch_size_(config.getParameter("batchSize")), + graphDef_(nullptr), + session_(nullptr) { + produces>("score0"); + produces>("score1"); + initializeTensorFlow(); +} + +void DisTauTag::initializeTensorFlow() { + if (!session_) { + const std::string graphFile = graphPath_.fullPath(); + graphDef_ = tensorflow::loadGraphDef(graphFile); + session_ = tensorflow::createSession(graphDef_); + } +} + +template +Scalar DisTauTag::getDeltaPhi(Scalar phi1, Scalar phi2) { + static constexpr Scalar pi = boost::math::constants::pi(); + Scalar dphi = phi1 - phi2; + if (dphi > pi) + dphi -= 2 * pi; + else if (dphi <= -pi) + dphi += 2 * pi; + return dphi; +} + +void DisTauTag::fill_zero(tensorflow::Tensor& tensor) { + size_t size_ = 1; + int num_dimensions = tensor.shape().dims(); + for (int ii_dim = 0; ii_dim < num_dimensions; ii_dim++) + size_ = size_ * tensor.shape().dim_size(ii_dim); + + for (size_t ii = 0; ii < size_; ii++) + tensor.flat()(ii) = 0.0; +} + +template +float DisTauTag::Scale(const Int_t idx, const Float_t value, const bool inner) const { + return std::clamp((value - FeatureT::mean.at(idx).at(inner)) / FeatureT::std.at(idx).at(inner), + FeatureT::lim_min.at(idx).at(inner), + FeatureT::lim_max.at(idx).at(inner)); +} + +void DisTauTag::saveInputs(const tensorflow::Tensor& tensor, + const std::string& block_name, + const edm::EventID& eventId, + size_t jetIndex) const { + const int tau_n = tensor.shape().dim_size(0); + const int pf_n = tensor.shape().dim_size(1); + const int ftr_n = tensor.shape().dim_size(2); + + std::string json_file_name = "distag_" + std::to_string(eventId.run()) + "_" + + std::to_string(eventId.luminosityBlock()) + "_" + std::to_string(eventId.event()) + "_" + + "jet_" + std::to_string(jetIndex) + ".json"; + + std::ofstream json_file(json_file_name.data()); + if (!json_file.is_open()) { + edm::LogError("DisTauTag") << "Failed to open file for saving inputs: " << json_file_name; + return; + } + + json_file << "{\"" << block_name << "\":["; + for (int tau_idx = 0; tau_idx < tau_n; tau_idx++) { + json_file << "["; + for (int pf_idx = 0; pf_idx < pf_n; pf_idx++) { + json_file << "["; + for (int ftr_idx = 0; ftr_idx < ftr_n; ftr_idx++) { + json_file << std::setprecision(7) << std::fixed << tensor.tensor()(tau_idx, pf_idx, ftr_idx); + if (ftr_idx < ftr_n - 1) + json_file << ", "; + } + json_file << "]"; + if (pf_idx < pf_n - 1) + json_file << ", "; + } + json_file << "]"; + if (tau_idx < tau_n - 1) + json_file << ", "; + } + json_file << "]}"; +} + +void DisTauTag::produce(edm::StreamID, edm::Event& event, const edm::EventSetup& setup) const { + auto jets = event.getHandle(jets_token); + + const size_t jets_size = jets->size(); + + std::vector v_score0(jets_size, -9); + std::vector v_score1(jets_size, -9); + + // Processing jets in batches + const size_t n_batches = (jets_size + batch_size_ - 1) / batch_size_; + + for (size_t batch_idx = 0; batch_idx < n_batches; ++batch_idx) { + const size_t jet_start = batch_idx * batch_size_; + const size_t jet_end = std::min((batch_idx + 1) * batch_size_, jets_size); + const size_t current_batch_size = jet_end - jet_start; + + // batched inputs + tensorflow::Tensor input_1(tensorflow::DT_FLOAT, + {static_cast(current_batch_size), setupSizes::nSeq_PfCand, setupSizes::n_PfCand}); + tensorflow::Tensor input_2( + tensorflow::DT_FLOAT, + {static_cast(current_batch_size), setupSizes::nSeq_PfCand, setupSizes::n_PfCandCategorical}); + fill_zero(input_1); + fill_zero(input_2); + + // Filling the batches + for (size_t batch_jet_idx = 0; batch_jet_idx < current_batch_size; ++batch_jet_idx) { + const size_t jetIndex = jet_start + batch_jet_idx; + const auto& jet = jets->at(jetIndex); + const auto& jet_p4 = jet.polarP4(); + + // Get jet daughters and sort by pt + const size_t nDaughters = jet.numberOfDaughters(); + std::vector indices(nDaughters); + std::iota(indices.begin(), indices.end(), 0); + std::sort(indices.begin(), indices.end(), [&](size_t a, size_t b) { + const auto& daughter_1 = jet.daughterPtr(a); + const auto& daughter_2 = jet.daughterPtr(b); + return daughter_1->polarP4().pt() > daughter_2->polarP4().pt(); + }); + + size_t daughter_idx = 0; + size_t tensor_idx = 0; + + while (tensor_idx < static_cast(setupSizes::nSeq_PfCand) && daughter_idx < nDaughters) { + const auto& jet_daughter = jet.daughterPtr(indices.at(daughter_idx)); + const auto daughter = dynamic_cast(jet_daughter.get()); + ++daughter_idx; + + if (!daughter) + continue; + + auto getVecRef = [&](tensorflow::Tensor& tensor, auto _fe, Float_t value) { + const int _feature_idx = static_cast(_fe); + if (_feature_idx < 0) + return; + tensor.tensor()(batch_jet_idx, tensor_idx, _feature_idx) = + Scale::scaler_type>(_feature_idx, value, false); + }; + + { // General features + typedef PfCand_Features Br; + getVecRef(input_1, Br::pfCand_valid, 1.0); + getVecRef(input_1, Br::pfCand_pt, static_cast(daughter->polarP4().pt())); + getVecRef(input_1, Br::pfCand_eta, static_cast(daughter->polarP4().eta())); + getVecRef(input_1, Br::pfCand_phi, static_cast(daughter->polarP4().phi())); + getVecRef(input_1, Br::pfCand_mass, static_cast(daughter->polarP4().mass())); + getVecRef(input_1, Br::pfCand_charge, static_cast(daughter->charge())); + getVecRef(input_1, Br::pfCand_puppiWeight, static_cast(daughter->puppiWeight())); + getVecRef(input_1, Br::pfCand_puppiWeightNoLep, static_cast(daughter->puppiWeightNoLep())); + getVecRef(input_1, Br::pfCand_lostInnerHits, static_cast(daughter->lostInnerHits())); + getVecRef(input_1, Br::pfCand_nPixelHits, static_cast(daughter->numberOfPixelHits())); + getVecRef(input_1, Br::pfCand_nHits, static_cast(daughter->numberOfHits())); + getVecRef(input_1, Br::pfCand_caloFraction, static_cast(daughter->caloFraction())); + getVecRef(input_1, Br::pfCand_hcalFraction, static_cast(daughter->hcalFraction())); + getVecRef(input_1, Br::pfCand_rawCaloFraction, static_cast(daughter->rawCaloFraction())); + getVecRef(input_1, Br::pfCand_rawHcalFraction, static_cast(daughter->rawHcalFraction())); + + getVecRef(input_1, Br::pfCand_hasTrackDetails, static_cast(daughter->hasTrackDetails())); + + if (daughter->hasTrackDetails()) { + if (std::isfinite(daughter->dz())) + getVecRef(input_1, Br::pfCand_dz, static_cast(daughter->dz())); + if (std::isfinite(daughter->dzError())) + getVecRef(input_1, Br::pfCand_dz_error, static_cast(daughter->dzError())); + if (std::isfinite(daughter->dxyError())) + getVecRef(input_1, Br::pfCand_dxy_error, static_cast(daughter->dxyError())); + + getVecRef(input_1, Br::pfCand_dxy, static_cast(daughter->dxy())); + getVecRef(input_1, Br::pfCand_track_chi2, static_cast(daughter->bestTrack()->chi2())); + getVecRef(input_1, Br::pfCand_track_ndof, static_cast(daughter->bestTrack()->ndof())); + } + + Float_t jet_eta = jet_p4.eta(); + Float_t jet_phi = jet_p4.phi(); + getVecRef(input_1, PfCand_Features::pfCand_deta, static_cast(daughter->polarP4().eta()) - jet_eta); + getVecRef(input_1, + PfCand_Features::pfCand_dphi, + getDeltaPhi(static_cast(daughter->polarP4().phi()), jet_phi)); + } + + { // Categorical features + typedef PfCandCategorical_Features Br; + getVecRef( + input_2, Br::pfCand_particleType, static_cast(TranslatePdgIdToPFParticleType(daughter->pdgId()))); + getVecRef(input_2, Br::pfCand_pvAssociationQuality, static_cast(daughter->pvAssociationQuality())); + getVecRef(input_2, Br::pfCand_fromPV, static_cast(daughter->fromPV())); + } + + ++tensor_idx; + } + } + + // Running inference on batch + std::vector outputs; + { tensorflow::run(session_, {{"input_1", input_1}, {"input_2", input_2}}, {"final_out"}, &outputs); } + + // Storing results + for (size_t batch_jet_idx = 0; batch_jet_idx < current_batch_size; ++batch_jet_idx) { + const size_t jetIndex = jet_start + batch_jet_idx; + v_score0[jetIndex] = outputs[0].matrix()(batch_jet_idx, 0); + v_score1[jetIndex] = outputs[0].matrix()(batch_jet_idx, 1); + } + + // Save inputs if requested (for debugging) + if (save_inputs_) { + for (size_t batch_jet_idx = 0; batch_jet_idx < current_batch_size; ++batch_jet_idx) { + const size_t jetIndex = jet_start + batch_jet_idx; + + // Extract single jet inputs from the batch + tensorflow::Tensor single_input_1(tensorflow::DT_FLOAT, {1, setupSizes::nSeq_PfCand, setupSizes::n_PfCand}); + tensorflow::Tensor single_input_2(tensorflow::DT_FLOAT, + {1, setupSizes::nSeq_PfCand, setupSizes::n_PfCandCategorical}); + + for (size_t i = 0; i < static_cast(setupSizes::nSeq_PfCand); ++i) { + for (size_t j = 0; j < static_cast(setupSizes::n_PfCand); ++j) { + single_input_1.tensor()(0, i, j) = input_1.tensor()(batch_jet_idx, i, j); + } + for (size_t j = 0; j < static_cast(setupSizes::n_PfCandCategorical); ++j) { + single_input_2.tensor()(0, i, j) = input_2.tensor()(batch_jet_idx, i, j); + } + } + + saveInputs(single_input_1, "PfCand", event.id(), jetIndex); + saveInputs(single_input_2, "PfCandCategorical", event.id(), jetIndex); + } + } + } + + test_vector(v_score0); + test_vector(v_score1); + + std::unique_ptr> vm_score0(new edm::ValueMap()); + edm::ValueMap::Filler filler_score0(*vm_score0); + filler_score0.insert(jets, v_score0.begin(), v_score0.end()); + filler_score0.fill(); + event.put(std::move(vm_score0), "score0"); + + std::unique_ptr> vm_score1(new edm::ValueMap()); + edm::ValueMap::Filler filler_score1(*vm_score1); + filler_score1.insert(jets, v_score1.begin(), v_score1.end()); + filler_score1.fill(); + event.put(std::move(vm_score1), "score1"); +} + +DEFINE_FWK_MODULE(DisTauTag); diff --git a/PhysicsTools/NanoAOD/plugins/DispJetTableProducer.cc b/PhysicsTools/NanoAOD/plugins/DispJetTableProducer.cc new file mode 100644 index 0000000000000..07972b6548991 --- /dev/null +++ b/PhysicsTools/NanoAOD/plugins/DispJetTableProducer.cc @@ -0,0 +1,491 @@ +// -*- C++ -*- +// +// Package: PhysicsTools/EXOnanoAOD +// Class: DispJetTableProducer +// +/**\class DispJetTableProducer + + Description: Additional variables for displaced vertices involving at least one lepton and other tracks + +*/ +// +// Original Author: Kirill Skovpen +// Created: Sat, 1 Mar 2025 08:37:01 GMT +// + +// system include files +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/StreamID.h" + +#include "DataFormats/PatCandidates/interface/Electron.h" +#include "DataFormats/PatCandidates/interface/Muon.h" +#include "DataFormats/PatCandidates/interface/Jet.h" +#include "DataFormats/MuonReco/interface/MuonSelectors.h" + +// nanoAOD include files +#include "DataFormats/NanoAOD/interface/FlatTable.h" + +// object specific include files +#include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h" +#include "TrackingTools/Records/interface/TransientTrackRecord.h" +#include "TrackingTools/IPTools/interface/IPTools.h" +#include "DataFormats/TrackReco/interface/Track.h" +#include "DataFormats/VertexReco/interface/VertexFwd.h" +#include "DataFormats/VertexReco/interface/Vertex.h" + +class DispJetTableProducer : public edm::stream::EDProducer<> { +protected: + edm::ESGetToken ttbToken_; + edm::EDGetTokenT> electronTag_; + edm::EDGetTokenT> muonTag_; + edm::EDGetTokenT vtxTag_; + edm::EDGetTokenT secVtxTag_; + +public: + DispJetTableProducer(edm::ParameterSet const& params) + : ttbToken_(esConsumes(edm::ESInputTag("", "TransientTrackBuilder"))), + electronTag_(consumes>(params.getParameter("electrons"))), + muonTag_(consumes>(params.getParameter("muons"))), + vtxTag_(consumes(params.getParameter("primaryVertex"))), + secVtxTag_(consumes(params.getParameter("secondaryVertex"))) { + produces("DispJetElectron"); + produces("DispJetElectronVtx"); + produces("DispJetElectronTrk"); + produces("DispJetMuon"); + produces("DispJetMuonVtx"); + produces("DispJetMuonTrk"); + } + + ~DispJetTableProducer() override {} + + void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override { + const TransientTrackBuilder* theB = &iSetup.getData(ttbToken_); + + const std::vector& electrons = iEvent.get(electronTag_); + const std::vector& muons = iEvent.get(muonTag_); + const reco::VertexCollection& primaryVertices = iEvent.get(vtxTag_); + const reco::VertexCollection& secVertices = iEvent.get(secVtxTag_); + const auto& pv = primaryVertices.at(0); + GlobalPoint primaryVertex(pv.x(), pv.y(), pv.z()); + + unsigned int nElectrons = electrons.size(); + unsigned int nMuons = muons.size(); + + std::vector el_idx; + std::vector el_lIVF_match; + std::vector el_IVF_df, el_IVF_ntracks, el_IVF_elid; + std::vector el_IVF_x, el_IVF_y, el_IVF_z, el_IVF_cx, el_IVF_cy, el_IVF_cz, el_IVF_chi2, el_IVF_pt, + el_IVF_eta, el_IVF_phi, el_IVF_E, el_IVF_mass; + std::vector el_IVF_trackcharge, el_IVF_trackelid, el_IVF_trackvtxid; + std::vector el_IVF_trackpt, el_IVF_tracketa, el_IVF_trackphi, el_IVF_trackE, el_IVF_trackdxy, el_IVF_trackdz; + std::vector el_IVF_tracksignedIP2D, el_IVF_tracksignedIP3D, el_IVF_tracksignedIP2Dsig, + el_IVF_tracksignedIP3Dsig; + std::vector el_IVF_signedIP2D, el_IVF_signedIP3D, el_IVF_signedIP2Dsig, el_IVF_signedIP3Dsig; + + std::vector mu_idx; + std::vector mu_lIVF_match; + std::vector mu_IVF_df, mu_IVF_ntracks, mu_IVF_muid; + std::vector mu_IVF_x, mu_IVF_y, mu_IVF_z, mu_IVF_cx, mu_IVF_cy, mu_IVF_cz, mu_IVF_chi2, mu_IVF_pt, + mu_IVF_eta, mu_IVF_phi, mu_IVF_E, mu_IVF_mass; + std::vector mu_IVF_trackcharge, mu_IVF_trackmuid, mu_IVF_trackvtxid; + std::vector mu_IVF_trackpt, mu_IVF_tracketa, mu_IVF_trackphi, mu_IVF_trackE, mu_IVF_trackdxy, mu_IVF_trackdz; + std::vector mu_IVF_tracksignedIP2D, mu_IVF_tracksignedIP3D, mu_IVF_tracksignedIP2Dsig, + mu_IVF_tracksignedIP3Dsig; + std::vector mu_IVF_signedIP2D, mu_IVF_signedIP3D, mu_IVF_signedIP2Dsig, mu_IVF_signedIP3Dsig; + + el_idx.clear(); + el_lIVF_match.clear(); + el_IVF_df.clear(); + el_IVF_ntracks.clear(); + el_IVF_elid.clear(); + el_IVF_x.clear(); + el_IVF_y.clear(); + el_IVF_z.clear(); + el_IVF_cx.clear(); + el_IVF_cy.clear(); + el_IVF_cz.clear(); + el_IVF_chi2.clear(); + el_IVF_pt.clear(); + el_IVF_eta.clear(); + el_IVF_phi.clear(); + el_IVF_E.clear(); + el_IVF_mass.clear(); + el_IVF_trackcharge.clear(); + el_IVF_trackelid.clear(); + el_IVF_trackvtxid.clear(); + el_IVF_trackpt.clear(); + el_IVF_tracketa.clear(); + el_IVF_trackphi.clear(); + el_IVF_trackE.clear(); + el_IVF_trackdxy.clear(); + el_IVF_trackdz.clear(); + el_IVF_tracksignedIP2D.clear(); + el_IVF_tracksignedIP2Dsig.clear(); + el_IVF_tracksignedIP3D.clear(); + el_IVF_tracksignedIP3Dsig.clear(); + + el_IVF_signedIP2D.clear(); + el_IVF_signedIP2Dsig.clear(); + el_IVF_signedIP3D.clear(); + el_IVF_signedIP3Dsig.clear(); + + mu_idx.clear(); + mu_lIVF_match.clear(); + mu_IVF_df.clear(); + mu_IVF_ntracks.clear(); + mu_IVF_muid.clear(); + mu_IVF_x.clear(); + mu_IVF_y.clear(); + mu_IVF_z.clear(); + mu_IVF_cx.clear(); + mu_IVF_cy.clear(); + mu_IVF_cz.clear(); + mu_IVF_chi2.clear(); + mu_IVF_pt.clear(); + mu_IVF_eta.clear(); + mu_IVF_phi.clear(); + mu_IVF_E.clear(); + mu_IVF_mass.clear(); + mu_IVF_trackcharge.clear(); + mu_IVF_trackmuid.clear(); + mu_IVF_trackvtxid.clear(); + mu_IVF_trackpt.clear(); + mu_IVF_tracketa.clear(); + mu_IVF_trackphi.clear(); + mu_IVF_trackE.clear(); + mu_IVF_trackdxy.clear(); + mu_IVF_trackdz.clear(); + mu_IVF_tracksignedIP2D.clear(); + mu_IVF_tracksignedIP2Dsig.clear(); + mu_IVF_tracksignedIP3D.clear(); + mu_IVF_tracksignedIP3Dsig.clear(); + + mu_IVF_signedIP2D.clear(); + mu_IVF_signedIP2Dsig.clear(); + mu_IVF_signedIP3D.clear(); + mu_IVF_signedIP3Dsig.clear(); + + int ntrack_max = 100; + int nElectronsSel = 0; + int nMuonsSel = 0; + + for (unsigned int i = 0; i < nElectrons; i++) { + const pat::Electron& el = electrons[i]; + + if (el.gsfTrack().isNull()) + continue; + if (el.pt() < 7) + continue; + if (fabs(el.eta()) > 2.5) + continue; + + el_idx.push_back(i); + el_lIVF_match.push_back(false); + + bool new_vtx = false; + double dR, deta, normchi2; + double mindR = 20, minnormchi2 = 10000; + int nVtx = 0; + reco::Vertex* vtxDisp = nullptr; + for (const reco::Vertex& vtx : secVertices) { + for (reco::Vertex::trackRef_iterator vtxTrackref = vtx.tracks_begin(); vtxTrackref != vtx.tracks_end(); + vtxTrackref++) { + reco::TrackRef vtxTrack = vtxTrackref->castTo(); + for (edm::Ref cand : el.associatedPackedPFCandidates()) { + dR = reco::deltaR(cand->eta(), cand->phi(), vtxTrack->eta(), vtxTrack->phi()); + deta = fabs(cand->eta() - vtxTrack->eta()); + normchi2 = fabs(vtx.chi2() / vtx.ndof()); + + if ((dR < 0.05 or (dR < 0.1 and deta < 0.03)) and + (dR < mindR or (dR == mindR and normchi2 < minnormchi2))) { + new_vtx = true; + vtxDisp = const_cast(&vtx); + el_lIVF_match[nElectronsSel] = true; + mindR = dR; + minnormchi2 = normchi2; + } + } + } + + if (new_vtx) { + el_IVF_x.push_back(vtx.x()); + el_IVF_y.push_back(vtx.y()); + el_IVF_z.push_back(vtx.z()); + el_IVF_cx.push_back(vtx.xError()); + el_IVF_cy.push_back(vtx.yError()); + el_IVF_cz.push_back(vtx.zError()); + el_IVF_df.push_back(vtx.ndof()); + el_IVF_chi2.push_back(vtx.chi2()); + el_IVF_pt.push_back(vtx.p4().pt()); + el_IVF_eta.push_back(vtx.p4().eta()); + el_IVF_phi.push_back(vtx.p4().phi()); + el_IVF_E.push_back(vtx.p4().energy()); + el_IVF_mass.push_back(vtx.p4().mass()); + el_IVF_elid.push_back(nElectronsSel); + + el_IVF_ntracks.push_back(0); + for (reco::Vertex::trackRef_iterator vtxTrackref = vtx.tracks_begin(); vtxTrackref != vtx.tracks_end(); + vtxTrackref++) { + if (el_IVF_ntracks.back() == ntrack_max) + break; + reco::TrackRef vtxTrack = vtxTrackref->castTo(); + const auto& trk = theB->build(vtxTrack); + Global3DVector dir(vtxTrack->px(), vtxTrack->py(), vtxTrack->pz()); + const auto& ip2d = IPTools::signedTransverseImpactParameter(trk, dir, *vtxDisp); + const auto& ip3d = IPTools::signedImpactParameter3D(trk, dir, *vtxDisp); + el_IVF_tracksignedIP2D.push_back(ip2d.second.value()); + el_IVF_tracksignedIP3D.push_back(ip3d.second.value()); + el_IVF_tracksignedIP2Dsig.push_back(ip2d.second.significance()); + el_IVF_tracksignedIP3Dsig.push_back(ip3d.second.significance()); + el_IVF_trackpt.push_back(vtxTrack->pt()); + el_IVF_tracketa.push_back(vtxTrack->eta()); + el_IVF_trackphi.push_back(vtxTrack->phi()); + el_IVF_trackE.push_back(vtxTrack->p()); + el_IVF_trackcharge.push_back(vtxTrack->charge()); + el_IVF_trackdxy.push_back(std::abs(vtxTrack->dxy(pv.position()))); + el_IVF_trackdz.push_back(std::abs(vtxTrack->dz(pv.position()))); + el_IVF_trackelid.push_back(nElectronsSel); + el_IVF_trackvtxid.push_back(nVtx); + el_IVF_ntracks.back()++; + } + nVtx++; + new_vtx = false; + + auto track = el.gsfTrack(); + if (track.isNonnull()) { + const auto& trk = theB->build(track); + Global3DVector dir(track->px(), track->py(), track->pz()); + const auto& ip2d = IPTools::signedTransverseImpactParameter(trk, dir, *vtxDisp); + const auto& ip3d = IPTools::signedImpactParameter3D(trk, dir, *vtxDisp); + el_IVF_signedIP2D.push_back(ip2d.second.value()); + el_IVF_signedIP3D.push_back(ip3d.second.value()); + el_IVF_signedIP2Dsig.push_back(ip2d.second.significance()); + el_IVF_signedIP3Dsig.push_back(ip3d.second.significance()); + } else { + el_IVF_signedIP2D.push_back(-999); + el_IVF_signedIP3D.push_back(-999); + el_IVF_signedIP2Dsig.push_back(-999); + el_IVF_signedIP3Dsig.push_back(-999); + } + } + } + nElectronsSel += 1; + } + + for (unsigned int i = 0; i < nMuons; i++) { + const pat::Muon& mu = muons[i]; + + if (mu.innerTrack().isNull()) + continue; + if (mu.pt() < 5) + continue; + if (fabs(mu.eta()) > 2.4) + continue; + if (!mu.isPFMuon()) + continue; + if (!(mu.isTrackerMuon() || mu.isGlobalMuon())) + continue; + + mu_idx.push_back(i); + mu_lIVF_match.push_back(false); + + bool new_vtx = false; + double ptdiff, normchi2; + double minptdiff = 10, minnormchi2 = 10000; + int nVtx = 0; + reco::Vertex* vtxDisp = nullptr; + for (const reco::Vertex& vtx : secVertices) { + for (reco::Vertex::trackRef_iterator vtxTrackref = vtx.tracks_begin(); vtxTrackref != vtx.tracks_end(); + vtxTrackref++) { + reco::TrackRef vtxTrack = vtxTrackref->castTo(); + for (size_t iCand = 0; iCand < mu.numberOfSourceCandidatePtrs(); ++iCand) { + if (!(mu.sourceCandidatePtr(iCand).isNonnull() and mu.sourceCandidatePtr(iCand).isAvailable())) + continue; + ptdiff = fabs(mu.sourceCandidatePtr(iCand)->pt() - vtxTrack->pt()); + normchi2 = fabs(vtx.chi2() / vtx.ndof()); + + if (ptdiff < 0.001 and (ptdiff < minptdiff or (ptdiff == minptdiff and normchi2 < minnormchi2))) { + new_vtx = true; + vtxDisp = const_cast(&vtx); + mu_lIVF_match[nMuonsSel] = true; + minptdiff = ptdiff; + minnormchi2 = normchi2; + } + } + } + if (new_vtx) { + mu_IVF_x.push_back(vtx.x()); + mu_IVF_y.push_back(vtx.y()); + mu_IVF_z.push_back(vtx.z()); + mu_IVF_cx.push_back(vtx.xError()); + mu_IVF_cy.push_back(vtx.yError()); + mu_IVF_cz.push_back(vtx.zError()); + mu_IVF_df.push_back(vtx.ndof()); + mu_IVF_chi2.push_back(vtx.chi2()); + mu_IVF_pt.push_back(vtx.p4().pt()); + mu_IVF_eta.push_back(vtx.p4().eta()); + mu_IVF_phi.push_back(vtx.p4().phi()); + mu_IVF_E.push_back(vtx.p4().energy()); + mu_IVF_mass.push_back(vtx.p4().mass()); + mu_IVF_muid.push_back(nMuonsSel); + + mu_IVF_ntracks.push_back(0); + for (reco::Vertex::trackRef_iterator vtxTrackref = vtx.tracks_begin(); vtxTrackref != vtx.tracks_end(); + vtxTrackref++) { + if (mu_IVF_ntracks.back() == ntrack_max) + break; + reco::TrackRef vtxTrack = vtxTrackref->castTo(); + const auto& trk = theB->build(vtxTrack); + Global3DVector dir(vtxTrack->px(), vtxTrack->py(), vtxTrack->pz()); + const auto& ip2d = IPTools::signedTransverseImpactParameter(trk, dir, *vtxDisp); + const auto& ip3d = IPTools::signedImpactParameter3D(trk, dir, *vtxDisp); + mu_IVF_tracksignedIP2D.push_back(ip2d.second.value()); + mu_IVF_tracksignedIP3D.push_back(ip3d.second.value()); + mu_IVF_tracksignedIP2Dsig.push_back(ip2d.second.significance()); + mu_IVF_tracksignedIP3Dsig.push_back(ip3d.second.significance()); + mu_IVF_trackpt.push_back(vtxTrack->pt()); + mu_IVF_tracketa.push_back(vtxTrack->eta()); + mu_IVF_trackphi.push_back(vtxTrack->phi()); + mu_IVF_trackE.push_back(vtxTrack->p()); + mu_IVF_trackcharge.push_back(vtxTrack->charge()); + mu_IVF_trackdxy.push_back(std::abs(vtxTrack->dxy(pv.position()))); + mu_IVF_trackdz.push_back(std::abs(vtxTrack->dz(pv.position()))); + mu_IVF_trackmuid.push_back(nMuonsSel); + mu_IVF_trackvtxid.push_back(nVtx); + mu_IVF_ntracks.back()++; + } + nVtx++; + new_vtx = false; + + auto track = mu.innerTrack(); + if (track.isNonnull()) { + const auto& trk = theB->build(track); + Global3DVector dir(track->px(), track->py(), track->pz()); + const auto& ip2d = IPTools::signedTransverseImpactParameter(trk, dir, *vtxDisp); + const auto& ip3d = IPTools::signedImpactParameter3D(trk, dir, *vtxDisp); + mu_IVF_signedIP2D.push_back(ip2d.second.value()); + mu_IVF_signedIP3D.push_back(ip3d.second.value()); + mu_IVF_signedIP2Dsig.push_back(ip2d.second.significance()); + mu_IVF_signedIP3Dsig.push_back(ip3d.second.significance()); + } else { + mu_IVF_signedIP2D.push_back(-999); + mu_IVF_signedIP3D.push_back(-999); + mu_IVF_signedIP2Dsig.push_back(-999); + mu_IVF_signedIP3Dsig.push_back(-999); + } + } + } + nMuonsSel += 1; + } + + auto dispJetElectronTab = std::make_unique(nElectronsSel, "DispJetElectron", false, false); + auto dispJetMuonTab = std::make_unique(nMuonsSel, "DispJetMuon", false, false); + + dispJetElectronTab->addColumn("idx", el_idx, ""); + dispJetElectronTab->addColumn("lIVF_match", el_lIVF_match, ""); + + auto dispJetElectronVtxTab = + std::make_unique(el_IVF_x.size(), "DispJetElectronVtx", false, false); + dispJetElectronVtxTab->addColumn("IVF_df", el_IVF_df, ""); + dispJetElectronVtxTab->addColumn("IVF_ntracks", el_IVF_ntracks, ""); + dispJetElectronVtxTab->addColumn("IVF_elid", el_IVF_elid, ""); + dispJetElectronVtxTab->addColumn("IVF_x", el_IVF_x, ""); + dispJetElectronVtxTab->addColumn("IVF_y", el_IVF_y, ""); + dispJetElectronVtxTab->addColumn("IVF_z", el_IVF_z, ""); + dispJetElectronVtxTab->addColumn("IVF_cx", el_IVF_cx, ""); + dispJetElectronVtxTab->addColumn("IVF_cy", el_IVF_cy, ""); + dispJetElectronVtxTab->addColumn("IVF_cz", el_IVF_cz, ""); + dispJetElectronVtxTab->addColumn("IVF_chi2", el_IVF_chi2, ""); + dispJetElectronVtxTab->addColumn("IVF_pt", el_IVF_pt, ""); + dispJetElectronVtxTab->addColumn("IVF_eta", el_IVF_eta, ""); + dispJetElectronVtxTab->addColumn("IVF_phi", el_IVF_phi, ""); + dispJetElectronVtxTab->addColumn("IVF_E", el_IVF_E, ""); + dispJetElectronVtxTab->addColumn("IVF_mass", el_IVF_mass, ""); + dispJetElectronVtxTab->addColumn("IVF_signedIP2D", el_IVF_signedIP2D, ""); + dispJetElectronVtxTab->addColumn("IVF_signedIP2Dsig", el_IVF_signedIP2Dsig, ""); + dispJetElectronVtxTab->addColumn("IVF_signedIP3D", el_IVF_signedIP3D, ""); + dispJetElectronVtxTab->addColumn("IVF_signedIP3Dsig", el_IVF_signedIP3Dsig, ""); + + int nTracksElectron = 0; + for (unsigned int iv = 0; iv < el_IVF_ntracks.size(); iv++) { + nTracksElectron += std::min(el_IVF_ntracks[iv], ntrack_max); + } + auto dispJetElectronTrkTab = + std::make_unique(nTracksElectron, "DispJetElectronTrk", false, false); + dispJetElectronTrkTab->addColumn("IVF_trackcharge", el_IVF_trackcharge, ""); + dispJetElectronTrkTab->addColumn("IVF_trackpt", el_IVF_trackpt, ""); + dispJetElectronTrkTab->addColumn("IVF_tracketa", el_IVF_tracketa, ""); + dispJetElectronTrkTab->addColumn("IVF_trackphi", el_IVF_trackphi, ""); + dispJetElectronTrkTab->addColumn("IVF_trackE", el_IVF_trackE, ""); + dispJetElectronTrkTab->addColumn("IVF_trackdxy", el_IVF_trackdxy, ""); + dispJetElectronTrkTab->addColumn("IVF_trackdz", el_IVF_trackdz, ""); + dispJetElectronTrkTab->addColumn("IVF_trackelid", el_IVF_trackelid, ""); + dispJetElectronTrkTab->addColumn("IVF_trackvtxid", el_IVF_trackvtxid, ""); + dispJetElectronTrkTab->addColumn("IVF_tracksignedIP2D", el_IVF_tracksignedIP2D, ""); + dispJetElectronTrkTab->addColumn("IVF_tracksignedIP2Dsig", el_IVF_tracksignedIP2Dsig, ""); + dispJetElectronTrkTab->addColumn("IVF_tracksignedIP3D", el_IVF_tracksignedIP3D, ""); + dispJetElectronTrkTab->addColumn("IVF_tracksignedIP3Dsig", el_IVF_tracksignedIP3Dsig, ""); + + dispJetMuonTab->addColumn("idx", mu_idx, ""); + dispJetMuonTab->addColumn("lIVF_match", mu_lIVF_match, ""); + + auto dispJetMuonVtxTab = std::make_unique(mu_IVF_x.size(), "DispJetMuonVtx", false, false); + dispJetMuonVtxTab->addColumn("IVF_df", mu_IVF_df, ""); + dispJetMuonVtxTab->addColumn("IVF_ntracks", mu_IVF_ntracks, ""); + dispJetMuonVtxTab->addColumn("IVF_muid", mu_IVF_muid, ""); + dispJetMuonVtxTab->addColumn("IVF_x", mu_IVF_x, ""); + dispJetMuonVtxTab->addColumn("IVF_y", mu_IVF_y, ""); + dispJetMuonVtxTab->addColumn("IVF_z", mu_IVF_z, ""); + dispJetMuonVtxTab->addColumn("IVF_cx", mu_IVF_cx, ""); + dispJetMuonVtxTab->addColumn("IVF_cy", mu_IVF_cy, ""); + dispJetMuonVtxTab->addColumn("IVF_cz", mu_IVF_cz, ""); + dispJetMuonVtxTab->addColumn("IVF_chi2", mu_IVF_chi2, ""); + dispJetMuonVtxTab->addColumn("IVF_pt", mu_IVF_pt, ""); + dispJetMuonVtxTab->addColumn("IVF_eta", mu_IVF_eta, ""); + dispJetMuonVtxTab->addColumn("IVF_phi", mu_IVF_phi, ""); + dispJetMuonVtxTab->addColumn("IVF_E", mu_IVF_E, ""); + dispJetMuonVtxTab->addColumn("IVF_mass", mu_IVF_mass, ""); + dispJetMuonVtxTab->addColumn("IVF_signedIP2D", mu_IVF_signedIP2D, ""); + dispJetMuonVtxTab->addColumn("IVF_signedIP2Dsig", mu_IVF_signedIP2Dsig, ""); + dispJetMuonVtxTab->addColumn("IVF_signedIP3D", mu_IVF_signedIP3D, ""); + dispJetMuonVtxTab->addColumn("IVF_signedIP3Dsig", mu_IVF_signedIP3Dsig, ""); + + int nTracksMuon = 0; + for (unsigned int iv = 0; iv < mu_IVF_ntracks.size(); iv++) { + nTracksMuon += std::min(mu_IVF_ntracks[iv], ntrack_max); + } + auto dispJetMuonTrkTab = std::make_unique(nTracksMuon, "DispJetMuonTrk", false, false); + dispJetMuonTrkTab->addColumn("IVF_trackcharge", mu_IVF_trackcharge, ""); + dispJetMuonTrkTab->addColumn("IVF_trackpt", mu_IVF_trackpt, ""); + dispJetMuonTrkTab->addColumn("IVF_tracketa", mu_IVF_tracketa, ""); + dispJetMuonTrkTab->addColumn("IVF_trackphi", mu_IVF_trackphi, ""); + dispJetMuonTrkTab->addColumn("IVF_trackE", mu_IVF_trackE, ""); + dispJetMuonTrkTab->addColumn("IVF_trackdxy", mu_IVF_trackdxy, ""); + dispJetMuonTrkTab->addColumn("IVF_trackdz", mu_IVF_trackdz, ""); + dispJetMuonTrkTab->addColumn("IVF_trackmuid", mu_IVF_trackmuid, ""); + dispJetMuonTrkTab->addColumn("IVF_trackvtxid", mu_IVF_trackvtxid, ""); + dispJetMuonTrkTab->addColumn("IVF_tracksignedIP2D", mu_IVF_tracksignedIP2D, ""); + dispJetMuonTrkTab->addColumn("IVF_tracksignedIP2Dsig", mu_IVF_tracksignedIP2Dsig, ""); + dispJetMuonTrkTab->addColumn("IVF_tracksignedIP3D", mu_IVF_tracksignedIP3D, ""); + dispJetMuonTrkTab->addColumn("IVF_tracksignedIP3Dsig", mu_IVF_tracksignedIP3Dsig, ""); + + iEvent.put(std::move(dispJetElectronTab), "DispJetElectron"); + iEvent.put(std::move(dispJetElectronVtxTab), "DispJetElectronVtx"); + iEvent.put(std::move(dispJetElectronTrkTab), "DispJetElectronTrk"); + iEvent.put(std::move(dispJetMuonTab), "DispJetMuon"); + iEvent.put(std::move(dispJetMuonVtxTab), "DispJetMuonVtx"); + iEvent.put(std::move(dispJetMuonTrkTab), "DispJetMuonTrk"); + } +}; + +#include "FWCore/Framework/interface/MakerMacros.h" +DEFINE_FWK_MODULE(DispJetTableProducer); diff --git a/PhysicsTools/NanoAOD/plugins/ElectronExtendedTableProducer.cc b/PhysicsTools/NanoAOD/plugins/ElectronExtendedTableProducer.cc new file mode 100644 index 0000000000000..61ee491eb4a77 --- /dev/null +++ b/PhysicsTools/NanoAOD/plugins/ElectronExtendedTableProducer.cc @@ -0,0 +1,295 @@ +// system include files +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/global/EDProducer.h" + +#include "FWCore/Framework/interface/Event.h" + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" + +#include "DataFormats/PatCandidates/interface/Electron.h" +#include "DataFormats/PatCandidates/interface/Jet.h" +#include "DataFormats/NanoAOD/interface/FlatTable.h" +#include "DataFormats/PatCandidates/interface/PackedCandidate.h" + +#include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h" +#include "TrackingTools/Records/interface/TransientTrackRecord.h" +#include "TrackingTools/IPTools/interface/IPTools.h" +#include "DataFormats/TrackReco/interface/Track.h" +#include "DataFormats/VertexReco/interface/VertexFwd.h" +#include "DataFormats/VertexReco/interface/Vertex.h" + +class ElectronExtendedTableProducer : public edm::global::EDProducer<> { +public: + explicit ElectronExtendedTableProducer(const edm::ParameterSet& iConfig) + : name_(iConfig.getParameter("name")), + rhoTag_(consumes(iConfig.getParameter("rho"))), + electronTag_(consumes>(iConfig.getParameter("electrons"))), + vtxTag_(consumes(iConfig.getParameter("primaryVertex"))), + jetTag_(consumes>(iConfig.getParameter("jets"))), + jetFatTag_(consumes>(iConfig.getParameter("jetsFat"))), + jetSubTag_(consumes>(iConfig.getParameter("jetsSub"))) { + produces(); + } + + ~ElectronExtendedTableProducer() override {}; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("rho")->setComment("input rho parameter"); + desc.add("electrons")->setComment("input electron collection"); + desc.add("primaryVertex")->setComment("input primary vertex collection"); + desc.add("jets")->setComment("input jet collection"); + desc.add("jetsFat")->setComment("input fat jet collection"); + desc.add("jetsSub")->setComment("input sub jet collection"); + desc.add("name")->setComment("name of the electron nanoaod::FlatTable we are extending"); + descriptions.add("electronTable", desc); + } + +private: + void produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const override; + + float GetDEtaInSeed(const pat::Electron* el) const; + float getPFIso(const pat::Electron& electron) const; + int findMatchedJet(const reco::Candidate& lepton, const std::vector& jets) const; + void fillLeptonJetVariables(const reco::GsfElectron* el, + const std::vector& jets, + const reco::Vertex& vertex, + const double rho, + std::vector* jetIdx, + std::vector relIso0p4, + std::vector* jetPtRatio, + std::vector* jetPtRel, + std::vector* jrtSelectedChargedMultiplicity) const; + + std::string name_; + edm::EDGetTokenT rhoTag_; + edm::EDGetTokenT> electronTag_; + edm::EDGetTokenT vtxTag_; + edm::EDGetTokenT> jetTag_; + edm::EDGetTokenT> jetFatTag_; + edm::EDGetTokenT> jetSubTag_; +}; + +void ElectronExtendedTableProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const { + const double rho = iEvent.get(rhoTag_); + const std::vector& electrons = iEvent.get(electronTag_); + const reco::VertexCollection& primaryVertices = iEvent.get(vtxTag_); + const std::vector& jets = iEvent.get(jetTag_); + const std::vector& jetFat = iEvent.get(jetFatTag_); + const std::vector& jetSub = iEvent.get(jetSubTag_); + + const auto& pv = primaryVertices.at(0); + GlobalPoint primaryVertex(pv.x(), pv.y(), pv.z()); + + unsigned int nElectrons = electrons.size(); + + std::vector idx, charge; + + std::vector relIso0p4; + std::vector jetPtRatio, jetPtRel; + std::vector jetIdx; + std::vector jetFatIdx, jetSubIdx; + std::vector jetSelectedChargedMultiplicity; + std::vector dxy, dz, IP3d, IP3dSig; + + std::vector isEB, isEE; + std::vector superClusterOverP, ecalEnergy, dEtaInSeed; + std::vector numberInnerHitsMissing, numberOfValidPixelHits, numberOfValidTrackerHits; + std::vector sigmaIetaIeta, deltaPhiSuperClusterTrack, deltaEtaSuperClusterTrack, eInvMinusPInv, hOverE; + + for (unsigned int i = 0; i < nElectrons; i++) { + const pat::Electron& electron = electrons[i]; + + idx.push_back(i); + + charge.push_back(electron.charge()); + + isEB.push_back(electron.isEB()); + isEE.push_back(electron.isEE()); + superClusterOverP.push_back(electron.eSuperClusterOverP()); + ecalEnergy.push_back(electron.ecalEnergy()); + dEtaInSeed.push_back(std::abs(GetDEtaInSeed(&electron))); + numberInnerHitsMissing.push_back( + electron.gsfTrack()->hitPattern().numberOfLostHits(reco::HitPattern::MISSING_INNER_HITS)); + numberOfValidPixelHits.push_back( + (!electron.gsfTrack().isNull()) ? electron.gsfTrack()->hitPattern().numberOfValidPixelHits() : 0); + numberOfValidTrackerHits.push_back( + (!electron.gsfTrack().isNull()) ? electron.gsfTrack()->hitPattern().numberOfValidTrackerHits() : 0); + + sigmaIetaIeta.push_back(electron.full5x5_sigmaIetaIeta()); + deltaPhiSuperClusterTrack.push_back(fabs(electron.deltaPhiSuperClusterTrackAtVtx())); + deltaEtaSuperClusterTrack.push_back(fabs(electron.deltaEtaSuperClusterTrackAtVtx())); + eInvMinusPInv.push_back((1.0 - electron.eSuperClusterOverP()) / electron.correctedEcalEnergy()); + hOverE.push_back(electron.hadronicOverEm()); + + dxy.push_back(electron.dB(pat::Electron::PV2D)); + dz.push_back(electron.dB(pat::Electron::PVDZ)); + IP3d.push_back(electron.dB(pat::Electron::PV3D)); + IP3dSig.push_back(fabs(electron.dB(pat::Electron::PV3D) / electron.edB(pat::Electron::PV3D))); + + relIso0p4.push_back(getPFIso(electron)); + + fillLeptonJetVariables( + &electron, jets, pv, rho, &jetIdx, relIso0p4, &jetPtRatio, &jetPtRel, &jetSelectedChargedMultiplicity); + + const reco::Candidate* el_cand = dynamic_cast(&electron); + jetFatIdx.push_back(findMatchedJet(*el_cand, jetFat)); + jetSubIdx.push_back(findMatchedJet(*el_cand, jetSub)); + } + + auto tab = std::make_unique(nElectrons, name_, false, true); + tab->addColumn("idx", idx, "LLPnanoAOD electron index"); + + tab->addColumn("dxy", dxy, ""); + tab->addColumn("dz", dz, ""); + tab->addColumn("IP3d", IP3d, ""); + tab->addColumn("IP3dSig", IP3dSig, ""); + + tab->addColumn("relIso0p4", relIso0p4, ""); + tab->addColumn("jetPtRatio", jetPtRatio, ""); + tab->addColumn("jetPtRel", jetPtRel, ""); + tab->addColumn("jetSelectedChargedMultiplicity", jetSelectedChargedMultiplicity, ""); + tab->addColumn("jetIdx", jetIdx, ""); + tab->addColumn("jetFatIdx", jetFatIdx, ""); + tab->addColumn("jetSubIdx", jetSubIdx, ""); + + tab->addColumn("isEB", isEB, ""); + tab->addColumn("isEE", isEE, ""); + tab->addColumn("superClusterOverP", superClusterOverP, ""); + tab->addColumn("ecalEnergy", ecalEnergy, ""); + tab->addColumn("dEtaInSeed", dEtaInSeed, ""); + tab->addColumn("numberInnerHitsMissing", numberInnerHitsMissing, ""); + tab->addColumn("numberOfValidPixelHits", numberOfValidPixelHits, ""); + tab->addColumn("numberOfValidTrackerHits", numberOfValidTrackerHits, ""); + tab->addColumn("sigmaIetaIeta", sigmaIetaIeta, ""); + tab->addColumn("deltaPhiSuperClusterTrack", deltaPhiSuperClusterTrack, ""); + tab->addColumn("deltaEtaSuperClusterTrack", deltaEtaSuperClusterTrack, ""); + tab->addColumn("eInvMinusPInv", eInvMinusPInv, ""); + tab->addColumn("hOverE", hOverE, ""); + + iEvent.put(std::move(tab)); +} + +float ElectronExtendedTableProducer::GetDEtaInSeed(const pat::Electron* el) const { + if (el->superCluster().isNonnull() and el->superCluster()->seed().isNonnull()) + return el->deltaEtaSuperClusterTrackAtVtx() - el->superCluster()->eta() + el->superCluster()->seed()->eta(); + else + return std::numeric_limits::max(); +} + +template +bool isSourceCandidatePtrMatch(const T1& lhs, const T2& rhs) { + for (size_t lhsIndex = 0; lhsIndex < lhs.numberOfSourceCandidatePtrs(); ++lhsIndex) { + auto lhsSourcePtr = lhs.sourceCandidatePtr(lhsIndex); + for (size_t rhsIndex = 0; rhsIndex < rhs.numberOfSourceCandidatePtrs(); ++rhsIndex) { + auto rhsSourcePtr = rhs.sourceCandidatePtr(rhsIndex); + if (lhsSourcePtr == rhsSourcePtr) { + return true; + } + } + } + + return false; +} + +int ElectronExtendedTableProducer::findMatchedJet(const reco::Candidate& lepton, + const std::vector& jets) const { + int iJet = -1; + + unsigned int nJets = jets.size(); + + for (unsigned int i = 0; i < nJets; i++) { + const pat::Jet& jet = jets[i]; + if (isSourceCandidatePtrMatch(lepton, jet)) { + return i; + } + } + + return iJet; +} + +void ElectronExtendedTableProducer::fillLeptonJetVariables(const reco::GsfElectron* el, + const std::vector& jets, + const reco::Vertex& vertex, + const double rho, + std::vector* jetIdx, + std::vector relIso0p4, + std::vector* jetPtRatio, + std::vector* jetPtRel, + std::vector* jetSelectedChargedMultiplicity) const { + const reco::Candidate* cand = dynamic_cast(el); + int matchedJetIdx = findMatchedJet(*cand, jets); + + jetIdx->push_back(matchedJetIdx); + + if (matchedJetIdx < 0) { + float ptRatio = (1. / (1. + relIso0p4.back())); + jetPtRatio->push_back(ptRatio); + jetPtRel->push_back(0); + jetSelectedChargedMultiplicity->push_back(0); + } else { + const pat::Jet& jet = jets[matchedJetIdx]; + auto rawJetP4 = jet.correctedP4("Uncorrected"); + auto leptonP4 = cand->p4(); + + bool leptonEqualsJet = ((rawJetP4 - leptonP4).P() < 1e-4); + + if (leptonEqualsJet) { + jetPtRatio->push_back(1); + jetPtRel->push_back(0); + jetSelectedChargedMultiplicity->push_back(0); + } else { + auto L1JetP4 = jet.correctedP4("L1FastJet"); + double L2L3JEC = jet.pt() / L1JetP4.pt(); + auto lepAwareJetP4 = (L1JetP4 - leptonP4) * L2L3JEC + leptonP4; + + float ptRatio = cand->pt() / lepAwareJetP4.pt(); + float ptRel = leptonP4.Vect().Cross((lepAwareJetP4 - leptonP4).Vect().Unit()).R(); + jetPtRatio->push_back(ptRatio); + jetPtRel->push_back(ptRel); + jetSelectedChargedMultiplicity->push_back(0); + + for (const auto& daughterPtr : jet.daughterPtrVector()) { + const pat::PackedCandidate& daughter = *((const pat::PackedCandidate*)daughterPtr.get()); + + if (daughter.charge() == 0) + continue; + if (daughter.fromPV() < 2) + continue; + if (reco::deltaR(daughter, *cand) > 0.4) + continue; + if (!daughter.hasTrackDetails()) + continue; + + auto daughterTrack = daughter.pseudoTrack(); + + if (daughterTrack.pt() <= 1) + continue; + if (daughterTrack.hitPattern().numberOfValidHits() < 8) + continue; + if (daughterTrack.hitPattern().numberOfValidPixelHits() < 2) + continue; + if (daughterTrack.normalizedChi2() >= 5) + continue; + if (std::abs(daughterTrack.dz(vertex.position())) >= 17) + continue; + if (std::abs(daughterTrack.dxy(vertex.position())) >= 0.2) + continue; + ++jetSelectedChargedMultiplicity->back(); + } + } + } +} + +float ElectronExtendedTableProducer::getPFIso(const pat::Electron& electron) const { + return electron.userFloat("PFIsoAll04") / electron.pt(); +} + +#include "FWCore/Framework/interface/MakerMacros.h" +//define this as a plug-in +DEFINE_FWK_MODULE(ElectronExtendedTableProducer); diff --git a/PhysicsTools/NanoAOD/plugins/ElectronVertexTableProducer.cc b/PhysicsTools/NanoAOD/plugins/ElectronVertexTableProducer.cc new file mode 100644 index 0000000000000..a194366fcf7d0 --- /dev/null +++ b/PhysicsTools/NanoAOD/plugins/ElectronVertexTableProducer.cc @@ -0,0 +1,468 @@ +#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "FWCore/Utilities/interface/transform.h" +#include "DataFormats/NanoAOD/interface/FlatTable.h" + +#include "DataFormats/TrackReco/interface/Track.h" +#include "DataFormats/GsfTrackReco/interface/GsfTrack.h" +#include "DataFormats/VertexReco/interface/VertexFwd.h" +#include "DataFormats/VertexReco/interface/Vertex.h" +#include "TLorentzVector.h" +#include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h" +#include "TrackingTools/Records/interface/TransientTrackRecord.h" +#include "DataFormats/BeamSpot/interface/BeamSpot.h" +#include "DataFormats/PatCandidates/interface/Electron.h" + +#include "DataFormats/Math/interface/deltaR.h" + +#include "RecoVertex/VertexPrimitives/interface/TransientVertex.h" +#include "RecoVertex/KalmanVertexFit/interface/KalmanVertexFitter.h" + +#include "RecoVertex/KinematicFitPrimitives/interface/ParticleMass.h" +#include "RecoVertex/KinematicFitPrimitives/interface/MultiTrackKinematicConstraint.h" +#include "RecoVertex/KinematicFitPrimitives/interface/KinematicParticleFactoryFromTransientTrack.h" +#include "RecoVertex/KinematicFit/interface/KinematicConstrainedVertexFitter.h" +#include "RecoVertex/KinematicFit/interface/TwoTrackMassKinematicConstraint.h" +#include "RecoVertex/KinematicFit/interface/KinematicParticleVertexFitter.h" +#include "RecoVertex/KinematicFit/interface/KinematicParticleFitter.h" +#include "RecoVertex/KinematicFit/interface/MassKinematicConstraint.h" + +#include "TrackingTools/Records/interface/TrackingComponentsRecord.h" +#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" +#include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h" + +#include "TrackingTools/PatternTools/interface/TwoTrackMinimumDistance.h" +#include "PhysicsTools/RecoUtils/interface/CheckHitPattern.h" +#include "DataFormats/TrackerCommon/interface/TrackerTopology.h" +#include "Geometry/Records/interface/TrackerTopologyRcd.h" +#include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" +#include "Geometry/CommonDetUnit/interface/TrackingGeometry.h" +#include "Geometry/Records/interface/TrackerDigiGeometryRecord.h" + +#include "TrackingTools/IPTools/interface/IPTools.h" + +#include +#include + +class ElectronVertexTableProducer : public edm::global::EDProducer<> { +public: + explicit ElectronVertexTableProducer(const edm::ParameterSet& iConfig) + : electronTag_(consumes>(iConfig.getParameter("electrons"))), + bsTag_(consumes(iConfig.getParameter("beamspot"))), + pvTag_(consumes(iConfig.getParameter("primaryVertex"))), + magneticFieldToken_(esConsumes()), + tkerGeomToken_(esConsumes()), + tkerTopoToken_(esConsumes()), + transientTrackBuilderToken_(esConsumes(edm::ESInputTag("", "TransientTrackBuilder"))) { + produces("ElectronVertex"); + produces("ElectronVertexRefittedTracks"); + } + + ~ElectronVertexTableProducer() override {} + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("electrons")->setComment("input pat electrons collection"); + desc.add("beamspot")->setComment("input beamspot collection"); + desc.add("primaryVertex")->setComment("input primaryVertex collection"); + descriptions.add("electronVertexTables", desc); + } + +private: + void produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const override; + + std::pair getVxy(const reco::Vertex electronVertex) const; + std::pair getVxyz(const reco::Vertex electronVertex) const; + + std::tuple getDistanceBetweenElectronTracks( + const reco::Track& track1, const reco::Track& track2, const edm::ESHandle& magneticField) const; + + const edm::EDGetTokenT> electronTag_; + const edm::EDGetTokenT bsTag_; + const edm::EDGetTokenT pvTag_; + const edm::ESGetToken magneticFieldToken_; + const edm::ESGetToken tkerGeomToken_; + const edm::ESGetToken tkerTopoToken_; + const edm::ESGetToken transientTrackBuilderToken_; +}; + +void ElectronVertexTableProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const { + const std::vector& electrons = iEvent.get(electronTag_); + + const reco::BeamSpot& beamSpotInput = iEvent.get(bsTag_); + const auto& bs = beamSpotInput.position(); + GlobalPoint beamSpot(bs.x(), bs.y(), bs.z()); + reco::Vertex beamSpotVertex(beamSpotInput.position(), beamSpotInput.covariance3D()); + + const reco::VertexCollection& primaryVertices = iEvent.get(pvTag_); + const auto& pv = primaryVertices.at(0); + GlobalPoint primaryVertex(pv.x(), pv.y(), pv.z()); + + auto const& magneticField = &iSetup.getData(magneticFieldToken_); + + auto const& tkerGeom = &iSetup.getData(tkerGeomToken_); + auto const& tkerTopo = &iSetup.getData(tkerTopoToken_); + const TransientTrackBuilder& builder = iSetup.getData(transientTrackBuilderToken_); + + KalmanVertexFitter vertexFitter(true, true); + + int nElectronVertices = 0; + int refittedTrackIdx_counter = 0; + + std::vector vertexIsValid; + std::vector vxy, vxyz, vx, vy, vz, t, vxySigma, vxyzSigma, vxErr, vyErr, vzErr, tErr; + std::vector chi2, ndof, normChi2, dR, originalElectronIdx1, originalElectronIdx2, refittedTrackIdx1, + refittedTrackIdx2; + std::vector DCA, DCAstatus, DCAx, DCAy, DCAz; + std::vector hitsInFrontOfVert1, missHitsAfterVert1, hitsInFrontOfVert2, missHitsAfterVert2; + + std::vector refittedTrackIdx, refittedTrackOriginalIdx, refittedTrackPt, refittedTrackPtErr, refittedTrackPx, + refittedTrackPy, refittedTrackPz; + std::vector refittedTrackEta, refittedTrackEtaErr, refittedTrackPhi, refittedTrackPhiErr, refittedTrackCharge, + refittedTrackNormChi2, refittedTrackNdof, refittedTrackChi2; + std::vector refittedTrackDzPV, refittedTrackDzPVErr, refittedTrackDxyPVTraj, refittedTrackDxyPVTrajErr, + refittedTrackDxyPVSigned, refittedTrackDxyPVSignedErr, refittedTrackIp3DPVSigned, refittedTrackIp3DPVSignedErr; + std::vector refittedTrackDxyBS, refittedTrackDxyBSErr, refittedTrackDzBS, refittedTrackDzBSErr, + refittedTrackDxyBSTraj, refittedTrackDxyBSTrajErr, refittedTrackDxyBSSigned, refittedTrackDxyBSSignedErr, + refittedTrackIp3DBSSigned, refittedTrackIp3DBSSignedErr; + std::vector refittedVertMass, refittedVertPt, refittedVertEta, refittedVertPhi; + // pat electrons + for (size_t i = 0; i < electrons.size(); i++) { + const pat::Electron& electron_i = electrons.at(i); + + reco::GsfTrackRef trackRef_i = electron_i.gsfTrack(); + + const auto& electronTrack_i = trackRef_i.get(); + reco::TransientTrack electronTransientTrack_i = builder.build(electronTrack_i); + + // pat-pat electron vertex + for (size_t j = i + 1; j < electrons.size(); j++) { + const pat::Electron& electron_j = electrons.at(j); + + reco::GsfTrackRef trackRef_j = electron_j.gsfTrack(); + + const auto& electronTrack_j = trackRef_j.get(); + reco::TransientTrack electronTransientTrack_j = builder.build(electronTrack_j); + + std::vector electronTransientTracks{}; + electronTransientTracks.push_back(electronTransientTrack_i); + electronTransientTracks.push_back(electronTransientTrack_j); + + TransientVertex transientElectronVertex = vertexFitter.vertex(electronTransientTracks); + reco::Vertex electronVertex = reco::Vertex(transientElectronVertex); + + if (!transientElectronVertex.isValid()) + continue; + std::tuple distanceTuple = + getDistanceBetweenElectronTracks(*electronTrack_i, *electronTrack_j, magneticField); + // if dca status is good but dca is more than 15 cm + if (std::get<1>(distanceTuple) && std::get<0>(distanceTuple) > 15) + continue; + + nElectronVertices++; + + vertexIsValid.push_back(transientElectronVertex.isValid()); + std::pair vxy_ = getVxy(electronVertex); + vxy.push_back(vxy_.first); + vxySigma.push_back(vxy_.second); + std::pair vxyz_ = getVxyz(electronVertex); + vxyz.push_back(vxyz_.first); + vxyzSigma.push_back(vxyz_.second); + ndof.push_back(electronVertex.ndof()); + normChi2.push_back(electronVertex.normalizedChi2()); + chi2.push_back(electronVertex.chi2()); + vx.push_back(electronVertex.x()); + vy.push_back(electronVertex.y()); + vz.push_back(electronVertex.z()); + t.push_back(electronVertex.t()); + vxErr.push_back(electronVertex.xError()); + vyErr.push_back(electronVertex.yError()); + vzErr.push_back(electronVertex.zError()); + tErr.push_back(electronVertex.tError()); + + dR.push_back(reco::deltaR(electron_i, electron_j)); + originalElectronIdx1.push_back(i); + originalElectronIdx2.push_back(j); + + DCA.push_back(std::get<0>(distanceTuple)); + DCAstatus.push_back(std::get<1>(distanceTuple)); + DCAx.push_back(std::get<2>(distanceTuple).x()); + DCAy.push_back(std::get<2>(distanceTuple).y()); + DCAz.push_back(std::get<2>(distanceTuple).z()); + + CheckHitPattern checkHitPattern; + checkHitPattern.init(tkerTopo, *tkerGeom, builder); + CheckHitPattern::Result hitPattern_i = checkHitPattern(*electronTrack_i, transientElectronVertex.vertexState()); + hitsInFrontOfVert1.push_back(hitPattern_i.hitsInFrontOfVert); + missHitsAfterVert1.push_back(hitPattern_i.missHitsAfterVert); + + CheckHitPattern::Result hitPattern_j = checkHitPattern(*electronTrack_j, transientElectronVertex.vertexState()); + hitsInFrontOfVert2.push_back(hitPattern_j.hitsInFrontOfVert); + missHitsAfterVert2.push_back(hitPattern_j.missHitsAfterVert); + + reco::TransientTrack refittedTrack_i = transientElectronVertex.refittedTrack(electronTransientTrack_i); + reco::TransientTrack refittedTrack_j = transientElectronVertex.refittedTrack(electronTransientTrack_j); + refittedTrackOriginalIdx.push_back(i); + refittedTrackPt.push_back(refittedTrack_i.track().pt()); + refittedTrackPtErr.push_back(refittedTrack_i.track().ptError()); + refittedTrackPx.push_back(refittedTrack_i.track().px()); + refittedTrackPy.push_back(refittedTrack_i.track().py()); + refittedTrackPz.push_back(refittedTrack_i.track().pz()); + refittedTrackEta.push_back(refittedTrack_i.track().eta()); + refittedTrackEtaErr.push_back(refittedTrack_i.track().etaError()); + refittedTrackPhi.push_back(refittedTrack_i.track().phi()); + refittedTrackPhiErr.push_back(refittedTrack_i.track().phiError()); + refittedTrackCharge.push_back(refittedTrack_i.track().charge()); + refittedTrackNormChi2.push_back(refittedTrack_i.normalizedChi2()); + refittedTrackNdof.push_back(refittedTrack_i.ndof()); + refittedTrackChi2.push_back(refittedTrack_i.chi2()); + + refittedTrackDzPV.push_back(refittedTrack_i.track().dz(pv.position())); + refittedTrackDzPVErr.push_back(std::hypot(refittedTrack_i.track().dzError(), pv.zError())); + TrajectoryStateClosestToPoint trajectoryPV_i = refittedTrack_i.trajectoryStateClosestToPoint(primaryVertex); + refittedTrackDxyPVTraj.push_back(trajectoryPV_i.perigeeParameters().transverseImpactParameter()); + refittedTrackDxyPVTrajErr.push_back(trajectoryPV_i.perigeeError().transverseImpactParameterError()); + GlobalVector electronRefTrackDir_i( + refittedTrack_i.track().px(), refittedTrack_i.track().py(), refittedTrack_i.track().pz()); + refittedTrackDxyPVSigned.push_back( + IPTools::signedTransverseImpactParameter(refittedTrack_i, electronRefTrackDir_i, pv).second.value()); + refittedTrackDxyPVSignedErr.push_back( + IPTools::signedTransverseImpactParameter(refittedTrack_i, electronRefTrackDir_i, pv).second.error()); + refittedTrackIp3DPVSigned.push_back( + IPTools::signedImpactParameter3D(refittedTrack_i, electronRefTrackDir_i, pv).second.value()); + refittedTrackIp3DPVSignedErr.push_back( + IPTools::signedImpactParameter3D(refittedTrack_i, electronRefTrackDir_i, pv).second.error()); + refittedTrackDxyBS.push_back(refittedTrack_i.track().dxy(bs)); + refittedTrackDxyBSErr.push_back(std::hypot(refittedTrack_i.track().dxyError(), beamSpotVertex.zError())); + refittedTrackDzBS.push_back(refittedTrack_i.track().dz(bs)); + refittedTrackDzBSErr.push_back(std::hypot(refittedTrack_i.track().dzError(), beamSpotVertex.zError())); + TrajectoryStateClosestToBeamLine trajectoryBS_i = refittedTrack_i.stateAtBeamLine(); + refittedTrackDxyBSTraj.push_back(trajectoryBS_i.transverseImpactParameter().value()); + refittedTrackDxyBSTrajErr.push_back(trajectoryBS_i.transverseImpactParameter().error()); + refittedTrackDxyBSSigned.push_back( + IPTools::signedTransverseImpactParameter(refittedTrack_i, electronRefTrackDir_i, beamSpotVertex) + .second.value()); + refittedTrackDxyBSSignedErr.push_back( + IPTools::signedTransverseImpactParameter(refittedTrack_i, electronRefTrackDir_i, beamSpotVertex) + .second.error()); + refittedTrackIp3DBSSigned.push_back( + IPTools::signedImpactParameter3D(refittedTrack_i, electronRefTrackDir_i, beamSpotVertex).second.value()); + refittedTrackIp3DBSSignedErr.push_back( + IPTools::signedImpactParameter3D(refittedTrack_i, electronRefTrackDir_i, beamSpotVertex).second.error()); + refittedTrackIdx.push_back(refittedTrackIdx_counter); + refittedTrackIdx1.push_back(refittedTrackIdx_counter); + refittedTrackIdx_counter++; + + refittedTrackOriginalIdx.push_back(j); + refittedTrackPt.push_back(refittedTrack_j.track().pt()); + refittedTrackPtErr.push_back(refittedTrack_j.track().ptError()); + refittedTrackPx.push_back(refittedTrack_j.track().px()); + refittedTrackPy.push_back(refittedTrack_j.track().py()); + refittedTrackPz.push_back(refittedTrack_j.track().pz()); + refittedTrackEta.push_back(refittedTrack_j.track().eta()); + refittedTrackEtaErr.push_back(refittedTrack_j.track().etaError()); + refittedTrackPhi.push_back(refittedTrack_j.track().phi()); + refittedTrackPhiErr.push_back(refittedTrack_j.track().phiError()); + refittedTrackCharge.push_back(refittedTrack_j.track().charge()); + refittedTrackNormChi2.push_back(refittedTrack_j.normalizedChi2()); + refittedTrackNdof.push_back(refittedTrack_j.ndof()); + refittedTrackChi2.push_back(refittedTrack_j.chi2()); + + refittedTrackDzPV.push_back(refittedTrack_j.track().dz(pv.position())); + refittedTrackDzPVErr.push_back(std::hypot(refittedTrack_j.track().dzError(), pv.zError())); + TrajectoryStateClosestToPoint trajectoryPV_j = refittedTrack_j.trajectoryStateClosestToPoint(primaryVertex); + refittedTrackDxyPVTraj.push_back(trajectoryPV_j.perigeeParameters().transverseImpactParameter()); + refittedTrackDxyPVTrajErr.push_back(trajectoryPV_j.perigeeError().transverseImpactParameterError()); + GlobalVector electronRefTrackDir_j( + refittedTrack_j.track().px(), refittedTrack_j.track().py(), refittedTrack_j.track().pz()); + refittedTrackDxyPVSigned.push_back( + IPTools::signedTransverseImpactParameter(refittedTrack_j, electronRefTrackDir_j, pv).second.value()); + refittedTrackDxyPVSignedErr.push_back( + IPTools::signedTransverseImpactParameter(refittedTrack_j, electronRefTrackDir_j, pv).second.error()); + refittedTrackIp3DPVSigned.push_back( + IPTools::signedImpactParameter3D(refittedTrack_j, electronRefTrackDir_j, pv).second.value()); + refittedTrackIp3DPVSignedErr.push_back( + IPTools::signedImpactParameter3D(refittedTrack_j, electronRefTrackDir_j, pv).second.error()); + refittedTrackDxyBS.push_back(refittedTrack_j.track().dxy(bs)); + refittedTrackDxyBSErr.push_back(std::hypot(refittedTrack_j.track().dxyError(), beamSpotVertex.zError())); + refittedTrackDzBS.push_back(refittedTrack_j.track().dz(bs)); + refittedTrackDzBSErr.push_back(std::hypot(refittedTrack_j.track().dzError(), beamSpotVertex.zError())); + TrajectoryStateClosestToBeamLine trajectoryBS_j = refittedTrack_j.stateAtBeamLine(); + refittedTrackDxyBSTraj.push_back(trajectoryBS_j.transverseImpactParameter().value()); + refittedTrackDxyBSTrajErr.push_back(trajectoryBS_j.transverseImpactParameter().error()); + refittedTrackDxyBSSigned.push_back( + IPTools::signedTransverseImpactParameter(refittedTrack_j, electronRefTrackDir_j, beamSpotVertex) + .second.value()); + refittedTrackDxyBSSignedErr.push_back( + IPTools::signedTransverseImpactParameter(refittedTrack_j, electronRefTrackDir_j, beamSpotVertex) + .second.error()); + refittedTrackIp3DBSSigned.push_back( + IPTools::signedImpactParameter3D(refittedTrack_j, electronRefTrackDir_j, beamSpotVertex).second.value()); + refittedTrackIp3DBSSignedErr.push_back( + IPTools::signedImpactParameter3D(refittedTrack_j, electronRefTrackDir_j, beamSpotVertex).second.error()); + refittedTrackIdx.push_back(refittedTrackIdx_counter); + refittedTrackIdx2.push_back(refittedTrackIdx_counter); + refittedTrackIdx_counter++; + + // Perform kinematic fit to re-compute dielectron four-momentum (especially for better mass resolution) + KinematicParticleFactoryFromTransientTrack pFactory; + ParticleMass e_mass = 0.000511; + float e_sigma = 0.00000001; + float chi = 0.; + float ndf = 0.; + std::vector eleParticles; + eleParticles.push_back(pFactory.particle(electronTransientTracks[0], e_mass, chi, ndf, e_sigma)); + eleParticles.push_back(pFactory.particle(electronTransientTracks[1], e_mass, chi, ndf, e_sigma)); + KinematicParticleVertexFitter fitter; + try { + RefCountedKinematicTree vertexFitTree = fitter.fit(eleParticles); + if (vertexFitTree->isValid()) { + vertexFitTree->movePointerToTheTop(); + auto diele_part = vertexFitTree->currentParticle(); + auto diele_state = diele_part->currentState(); + auto daughters = vertexFitTree->daughterParticles(); + refittedVertMass.push_back(diele_state.mass()); + refittedVertPt.push_back(diele_state.globalMomentum().transverse()); + refittedVertEta.push_back(diele_state.globalMomentum().eta()); + refittedVertPhi.push_back(diele_state.globalMomentum().phi()); + } else { + refittedVertMass.push_back(-999.); + refittedVertPt.push_back(-999.); + refittedVertEta.push_back(-999.); + refittedVertPhi.push_back(-999.); + } + } catch (std::exception& ex) { + std::cout << "kinematic vertex fit failed!" << std::endl; + refittedVertMass.push_back(-999.); + refittedVertPt.push_back(-999.); + refittedVertEta.push_back(-999.); + refittedVertPhi.push_back(-999.); + } + } + } + + auto vertexTab = std::make_unique(nElectronVertices, "ElectronVertex", false, false); + auto refittedTracksTab = + std::make_unique(nElectronVertices * 2, "ElectronVertexRefittedTracks", false, false); + + vertexTab->addColumn("isValid", vertexIsValid, ""); + vertexTab->addColumn("vxy", vxy, ""); + vertexTab->addColumn("vxySigma", vxySigma, ""); + vertexTab->addColumn("vxyz", vxyz, ""); + vertexTab->addColumn("vxyzSigma", vxyzSigma, ""); + vertexTab->addColumn("chi2", chi2, ""); + vertexTab->addColumn("ndof", ndof, ""); + vertexTab->addColumn("normChi2", normChi2, ""); + vertexTab->addColumn("vx", vx, ""); + vertexTab->addColumn("vy", vy, ""); + vertexTab->addColumn("vz", vz, ""); + vertexTab->addColumn("t", t, ""); + vertexTab->addColumn("vxErr", vxErr, ""); + vertexTab->addColumn("vyErr", vyErr, ""); + vertexTab->addColumn("vzErr", vzErr, ""); + vertexTab->addColumn("tErr", tErr, ""); + vertexTab->addColumn("dR", dR, ""); + vertexTab->addColumn("originalElectronIdx1", originalElectronIdx1, ""); + vertexTab->addColumn("originalElectronIdx2", originalElectronIdx2, ""); + vertexTab->addColumn("dca", DCA, ""); + vertexTab->addColumn("dcaStatus", DCAstatus, ""); + vertexTab->addColumn("dcax", DCAx, ""); + vertexTab->addColumn("dcay", DCAy, ""); + vertexTab->addColumn("dcaz", DCAz, ""); + vertexTab->addColumn("hitsInFrontOfVert1", hitsInFrontOfVert1, ""); + vertexTab->addColumn("hitsInFrontOfVert2", hitsInFrontOfVert2, ""); + vertexTab->addColumn("missHitsAfterVert1", missHitsAfterVert1, ""); + vertexTab->addColumn("missHitsAfterVert2", missHitsAfterVert2, ""); + vertexTab->addColumn("refittedTrackIdx1", refittedTrackIdx1, ""); + vertexTab->addColumn("refittedTrackIdx2", refittedTrackIdx2, ""); + vertexTab->addColumn("massRefit", refittedVertMass, ""); + vertexTab->addColumn("ptRefit", refittedVertPt, ""); + vertexTab->addColumn("etaRefit", refittedVertEta, ""); + vertexTab->addColumn("phiRefit", refittedVertPhi, ""); + + iEvent.put(std::move(vertexTab), "ElectronVertex"); + + refittedTracksTab->addColumn("idx", refittedTrackIdx, ""); + refittedTracksTab->addColumn("originalElectronIdx", refittedTrackOriginalIdx, ""); + refittedTracksTab->addColumn("pt", refittedTrackPt, ""); + refittedTracksTab->addColumn("ptErr", refittedTrackPtErr, ""); + refittedTracksTab->addColumn("px", refittedTrackPx, ""); + refittedTracksTab->addColumn("py", refittedTrackPy, ""); + refittedTracksTab->addColumn("pz", refittedTrackPz, ""); + refittedTracksTab->addColumn("eta", refittedTrackEta, ""); + refittedTracksTab->addColumn("etaErr", refittedTrackEtaErr, ""); + refittedTracksTab->addColumn("phi", refittedTrackPhi, ""); + refittedTracksTab->addColumn("phiErr", refittedTrackPhiErr, ""); + refittedTracksTab->addColumn("charge", refittedTrackCharge, ""); + refittedTracksTab->addColumn("normChi2", refittedTrackNormChi2, ""); + refittedTracksTab->addColumn("ndof", refittedTrackNdof, ""); + refittedTracksTab->addColumn("chi2", refittedTrackChi2, ""); + refittedTracksTab->addColumn("dzPV", refittedTrackDzPV, ""); + refittedTracksTab->addColumn("dzPVErr", refittedTrackDzPVErr, ""); + refittedTracksTab->addColumn("dxyPVTraj", refittedTrackDxyPVTraj, ""); + refittedTracksTab->addColumn("dxyPVTrajErr", refittedTrackDxyPVTrajErr, ""); + refittedTracksTab->addColumn("dxyPVSigned", refittedTrackDxyPVSigned, ""); + refittedTracksTab->addColumn("dxyPVSignedErr", refittedTrackDxyPVSignedErr, ""); + refittedTracksTab->addColumn("ip3DPVSigned", refittedTrackIp3DPVSigned, ""); + refittedTracksTab->addColumn("ip3DPVSignedErr", refittedTrackIp3DPVSignedErr, ""); + refittedTracksTab->addColumn("dxyBS", refittedTrackDxyBS, ""); + refittedTracksTab->addColumn("dxyBSErr", refittedTrackDxyBSErr, ""); + refittedTracksTab->addColumn("dzBS", refittedTrackDzBS, ""); + refittedTracksTab->addColumn("dzBSErr", refittedTrackDzBSErr, ""); + refittedTracksTab->addColumn("dxyBSTraj", refittedTrackDxyBSTraj, ""); + refittedTracksTab->addColumn("dxyBSTrajErr", refittedTrackDxyBSTrajErr, ""); + refittedTracksTab->addColumn("dxyBSSigned", refittedTrackDxyBSSigned, ""); + refittedTracksTab->addColumn("dxyBSSignedErr", refittedTrackDxyBSSignedErr, ""); + refittedTracksTab->addColumn("ip3DBSSigned", refittedTrackIp3DBSSigned, ""); + refittedTracksTab->addColumn("ip3DBSSignedErr", refittedTrackIp3DBSSignedErr, ""); + + iEvent.put(std::move(refittedTracksTab), "ElectronVertexRefittedTracks"); +} + +std::pair ElectronVertexTableProducer::getVxy(const reco::Vertex electronVertex) const { + float vxy = sqrt(electronVertex.x() * electronVertex.x() + electronVertex.y() * electronVertex.y()); + float vxySigma = + (1 / vxy) * sqrt(electronVertex.x() * electronVertex.x() * electronVertex.xError() * electronVertex.xError() + + electronVertex.y() * electronVertex.y() * electronVertex.yError() * electronVertex.yError()); + return std::make_pair(vxy, vxySigma); +} + +std::pair ElectronVertexTableProducer::getVxyz(const reco::Vertex electronVertex) const { + float vxyz = sqrt(electronVertex.x() * electronVertex.x() + electronVertex.y() * electronVertex.y() + + electronVertex.z() * electronVertex.z()); + float vxyzSigma = + (1 / vxyz) * sqrt(electronVertex.x() * electronVertex.x() * electronVertex.xError() * electronVertex.xError() + + electronVertex.y() * electronVertex.y() * electronVertex.yError() * electronVertex.yError() + + electronVertex.z() * electronVertex.z() * electronVertex.zError() * electronVertex.zError()); + return std::make_pair(vxyz, vxyzSigma); +} + +/** +* Proximity between the electrons based on EXO-23-010 +* Getting Distance of Closest Approach between electron tracks using TwoTrackMinimumDistance +* Returns tuple of distance (float), error of distance (float) and crossing point (GlobalPoint) +**/ +std::tuple ElectronVertexTableProducer::getDistanceBetweenElectronTracks( + const reco::Track& track1, const reco::Track& track2, const edm::ESHandle& magneticField) const { + TwoTrackMinimumDistance ttmd; + FreeTrajectoryState fts1(GlobalPoint(track1.vx(), track1.vy(), track1.vz()), + GlobalVector(track1.px(), track1.py(), track1.pz()), + track1.charge(), + magneticField.product()); + FreeTrajectoryState fts2(GlobalPoint(track2.vx(), track2.vy(), track2.vz()), + GlobalVector(track2.px(), track2.py(), track2.pz()), + track2.charge(), + magneticField.product()); + bool status = ttmd.calculate(fts1, fts2); + if (!status) + return std::tuple(-999.f, status, GlobalPoint(-999.f, -999.f, -999.f)); + return std::make_tuple(ttmd.distance(), status, ttmd.crossingPoint()); +} + +#include "FWCore/Framework/interface/MakerMacros.h" +DEFINE_FWK_MODULE(ElectronVertexTableProducer); diff --git a/PhysicsTools/NanoAOD/plugins/JetImpactParameters.cc b/PhysicsTools/NanoAOD/plugins/JetImpactParameters.cc new file mode 100644 index 0000000000000..b5e081cc85ec3 --- /dev/null +++ b/PhysicsTools/NanoAOD/plugins/JetImpactParameters.cc @@ -0,0 +1,140 @@ +/* +//////////////////////////////////////////////// + +Jet Impact parameter information for displaced tau collection : Pritam Palit, created on 01/09/2025 + +////////////////////////////////////////////////// + */ + +#include +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/StreamID.h" +#include "DataFormats/PatCandidates/interface/Jet.h" +#include "DataFormats/PatCandidates/interface/PackedCandidate.h" +#include "FWCore/Framework/interface/MakerMacros.h" + +void vector_test(std::vector& values) { + for (auto& value : values) { + if (std::isnan(value)) { + throw std::runtime_error("Jet IP output: NaN detected."); + } else if (std::isinf(value)) { + throw std::runtime_error("Jet IP output: Infinity detected."); + } else if (!std::isfinite(value)) { + throw std::runtime_error("Jet IP output: Non-standard value detected."); + } + } +} + +class JetImpactParameters : public edm::stream::EDProducer<> { +public: + explicit JetImpactParameters(const edm::ParameterSet&); + ~JetImpactParameters() override = default; + +private: + void produce(edm::Event&, const edm::EventSetup&) override; + + edm::EDGetTokenT jetsToken_; + edm::EDGetTokenT pfCandidatesToken_; + const double deltaRMax_; +}; + +JetImpactParameters::JetImpactParameters(const edm::ParameterSet& config) + : jetsToken_(consumes(config.getParameter("jets"))), + pfCandidatesToken_(consumes(config.getParameter("pfCandidates"))), + deltaRMax_(config.getParameter("deltaRMax")) { + produces>("jetDxy"); + produces>("jetDz"); + produces>("jetDxyError"); + produces>("jetDzError"); + produces>("jetCharge"); +} + +void JetImpactParameters::produce(edm::Event& event, const edm::EventSetup& setup) { + // Get jets and PFCandidates + auto jets = event.getHandle(jetsToken_); + + std::vector v_jetDxy(jets->size(), -1.0); + std::vector v_jetDz(jets->size(), -1.0); + std::vector v_jetDxyError(jets->size(), -1.0); + std::vector v_jetDzError(jets->size(), -1.0); + std::vector v_jetCharge(jets->size(), -1.0); + + // Loop over jets + for (size_t jetIndex = 0; jetIndex < jets->size(); ++jetIndex) { + const auto& jet = jets->at(jetIndex); + const auto& jetP4 = jet.polarP4(); + + // Find the leading charged PFCandidate within deltaR < 0.4 + const pat::PackedCandidate* leadingChargedPFCandidate = nullptr; + Float_t leadingPt = -1.0; + + // Loop over jet daughters + const size_t nDaughters = jet.numberOfDaughters(); + for (size_t i = 0; i < nDaughters; ++i) { + const auto& daughterPtr = jet.daughterPtr(i); + const auto* daughter = dynamic_cast(daughterPtr.get()); + + // Skip if not a charged candidate or doesn't have track details + if (!daughter || daughter->charge() == 0 || !daughter->hasTrackDetails()) + continue; + + Float_t deltaR = reco::deltaR(daughter->polarP4(), jetP4); + if (deltaR > deltaRMax_) + continue; + + if (daughter->pt() > leadingPt) { + leadingPt = daughter->pt(); + leadingChargedPFCandidate = daughter; + } + } + + if (leadingChargedPFCandidate) { + v_jetDxy.at(jetIndex) = leadingChargedPFCandidate->dxy(); + v_jetDz.at(jetIndex) = leadingChargedPFCandidate->dz(); + v_jetDxyError.at(jetIndex) = leadingChargedPFCandidate->dxyError(); + v_jetDzError.at(jetIndex) = leadingChargedPFCandidate->dzError(); + v_jetCharge.at(jetIndex) = leadingChargedPFCandidate->charge(); + } + } + + vector_test(v_jetDxy); + vector_test(v_jetDz); + vector_test(v_jetDxyError); + vector_test(v_jetDzError); + vector_test(v_jetCharge); + + auto vm_jetDxy = std::make_unique>(); + edm::ValueMap::Filler filler_jetDxy(*vm_jetDxy); + filler_jetDxy.insert(jets, v_jetDxy.begin(), v_jetDxy.end()); + filler_jetDxy.fill(); + event.put(std::move(vm_jetDxy), "jetDxy"); + + auto vm_jetDz = std::make_unique>(); + edm::ValueMap::Filler filler_jetDz(*vm_jetDz); + filler_jetDz.insert(jets, v_jetDz.begin(), v_jetDz.end()); + filler_jetDz.fill(); + event.put(std::move(vm_jetDz), "jetDz"); + + auto vm_jetDxyError = std::make_unique>(); + edm::ValueMap::Filler filler_jetDxyError(*vm_jetDxyError); + filler_jetDxyError.insert(jets, v_jetDxyError.begin(), v_jetDxyError.end()); + filler_jetDxyError.fill(); + event.put(std::move(vm_jetDxyError), "jetDxyError"); + + auto vm_jetDzError = std::make_unique>(); + edm::ValueMap::Filler filler_jetDzError(*vm_jetDzError); + filler_jetDzError.insert(jets, v_jetDzError.begin(), v_jetDzError.end()); + filler_jetDzError.fill(); + event.put(std::move(vm_jetDzError), "jetDzError"); + + auto vm_jetCharge = std::make_unique>(); + edm::ValueMap::Filler filler_jetCharge(*vm_jetCharge); + filler_jetCharge.insert(jets, v_jetCharge.begin(), v_jetCharge.end()); + filler_jetCharge.fill(); + event.put(std::move(vm_jetCharge), "jetCharge"); +} + +DEFINE_FWK_MODULE(JetImpactParameters); diff --git a/PhysicsTools/NanoAOD/plugins/MuonExtendedTableProducer.cc b/PhysicsTools/NanoAOD/plugins/MuonExtendedTableProducer.cc new file mode 100644 index 0000000000000..18d12db42cb74 --- /dev/null +++ b/PhysicsTools/NanoAOD/plugins/MuonExtendedTableProducer.cc @@ -0,0 +1,338 @@ +// system include files +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/global/EDProducer.h" + +#include "FWCore/Framework/interface/Event.h" + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" + +#include "DataFormats/PatCandidates/interface/Muon.h" +#include "DataFormats/MuonReco/interface/MuonSelectors.h" +#include "DataFormats/PatCandidates/interface/Jet.h" +#include "DataFormats/NanoAOD/interface/FlatTable.h" +#include "DataFormats/PatCandidates/interface/PackedCandidate.h" + +#include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h" +#include "TrackingTools/Records/interface/TransientTrackRecord.h" +#include "TrackingTools/IPTools/interface/IPTools.h" +#include "DataFormats/TrackReco/interface/Track.h" +#include "DataFormats/VertexReco/interface/VertexFwd.h" +#include "DataFormats/VertexReco/interface/Vertex.h" + +class MuonExtendedTableProducer : public edm::global::EDProducer<> { +public: + explicit MuonExtendedTableProducer(const edm::ParameterSet& iConfig) + : name_(iConfig.getParameter("name")), + rhoTag_(consumes(iConfig.getParameter("rho"))), + muonTag_(consumes>(iConfig.getParameter("muons"))), + vtxTag_(consumes(iConfig.getParameter("primaryVertex"))), + bsTag_(consumes(iConfig.getParameter("beamspot"))), + jetTag_(consumes>(iConfig.getParameter("jets"))), + jetFatTag_(consumes>(iConfig.getParameter("jetsFat"))), + jetSubTag_(consumes>(iConfig.getParameter("jetsSub"))), + transientTrackBuilderToken_(esConsumes(edm::ESInputTag("", "TransientTrackBuilder"))) { + produces(); + } + + ~MuonExtendedTableProducer() override {}; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("rho")->setComment("input rho parameter"); + desc.add("muons")->setComment("input muon collection"); + desc.add("primaryVertex")->setComment("input primary vertex collection"); + desc.add("beamspot")->setComment("input beamspot collection"); + desc.add("jets")->setComment("input jet collection"); + desc.add("jetsFat")->setComment("input fat jet collection"); + desc.add("jetsSub")->setComment("input sub jet collection"); + desc.add("name")->setComment("name of the muon nanoaod::FlatTable we are extending"); + descriptions.add("muonTable", desc); + } + +private: + void produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const override; + + float getPFIso(const pat::Muon& muon) const; + int findMatchedJet(const reco::Candidate& lepton, const std::vector& jets) const; + void fillLeptonJetVariables(const reco::Muon* mu, + const std::vector& jets, + const reco::Vertex& vertex, + const double rho, + std::vector* jetIdx, + std::vector relIso0p4, + std::vector* jetPtRatio, + std::vector* jetPtRel, + std::vector* jetSelectedChargedMultiplicity) const; + + std::string name_; + edm::EDGetTokenT rhoTag_; + edm::EDGetTokenT> muonTag_; + edm::EDGetTokenT vtxTag_; + edm::EDGetTokenT bsTag_; + edm::EDGetTokenT> generalTrackTag_; + edm::EDGetTokenT> jetTag_; + edm::EDGetTokenT> jetFatTag_; + edm::EDGetTokenT> jetSubTag_; + edm::ESGetToken transientTrackBuilderToken_; +}; + +void MuonExtendedTableProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const { + const double& rho = iEvent.get(rhoTag_); + edm::Handle> muonHandle; + iEvent.getByToken(muonTag_, muonHandle); + const auto& muons = *muonHandle; + const reco::VertexCollection& primaryVertices = iEvent.get(vtxTag_); + const reco::BeamSpot& beamspots = iEvent.get(bsTag_); + const std::vector& jets = iEvent.get(jetTag_); + const std::vector& jetFat = iEvent.get(jetFatTag_); + const std::vector& jetSub = iEvent.get(jetSubTag_); + + const auto& pv = primaryVertices.at(0); + GlobalPoint primaryVertex(pv.x(), pv.y(), pv.z()); + + const auto& bs = beamspots.position(); + GlobalPoint beamSpot(bs.x(), bs.y(), bs.z()); + reco::Vertex beamSpotVertex(beamspots.position(), beamspots.covariance3D()); + + const TransientTrackBuilder& builder = iSetup.getData(transientTrackBuilderToken_); + + unsigned int nMuons = muons.size(); + + std::vector idx, charge, trkPt, trkPtErr; + std::vector numberInnerHitsMissing; + std::vector relIso0p4; + std::vector jetPtRatio, jetPtRel; + std::vector jetIdx; + std::vector jetFatIdx, jetSubIdx; + std::vector jetSelectedChargedMultiplicity; + + std::vector dzPV, dzPVErr, dxyPVTraj, dxyPVTrajErr, dxyPVSigned, dxyPVSignedErr, ip3DPVSigned, ip3DPVSignedErr; + + std::vector trkNumPlanes, trkNumHits, trkNumDTHits, trkNumCSCHits, trkNumPixelHits(nMuons, -1), + trkNumTrkLayers(nMuons, -1), normChi2; + std::vector outerEta(nMuons, -5), outerPhi(nMuons, -5); + + for (unsigned int i = 0; i < nMuons; i++) { + const pat::Muon& muon = muons[i]; + const pat::MuonRef muonRef(muonHandle, i); + + reco::TrackRef trackRef; + + if (muon.isGlobalMuon()) { + trackRef = muon.combinedMuon(); + } else if (muon.isStandAloneMuon()) { + trackRef = muon.standAloneMuon(); + } else { + trackRef = muon.tunePMuonBestTrack(); + } + + idx.push_back(i); + + const auto& track = trackRef.get(); + reco::TransientTrack transientTrack = builder.build(track); + + charge.push_back(muon.charge()); + + trkPt.push_back(track->pt()); + trkPtErr.push_back(track->ptError()); + + relIso0p4.push_back(getPFIso(muon)); + + fillLeptonJetVariables( + &muon, jets, pv, rho, &jetIdx, relIso0p4, &jetPtRatio, &jetPtRel, &jetSelectedChargedMultiplicity); + + const reco::Candidate* mu_cand = dynamic_cast(&muon); + jetFatIdx.push_back(findMatchedJet(*mu_cand, jetFat)); + jetSubIdx.push_back(findMatchedJet(*mu_cand, jetSub)); + + numberInnerHitsMissing.push_back(!muon.innerTrack().isNull() ? muon.innerTrack()->hitPattern().numberOfLostHits( + reco::HitPattern::MISSING_INNER_HITS) + : 0); + + dzPV.push_back(track->dz(pv.position())); + dzPVErr.push_back(std::hypot(track->dzError(), pv.zError())); + TrajectoryStateClosestToPoint trajectoryPV = transientTrack.trajectoryStateClosestToPoint(primaryVertex); + dxyPVTraj.push_back(trajectoryPV.perigeeParameters().transverseImpactParameter()); + dxyPVTrajErr.push_back(trajectoryPV.perigeeError().transverseImpactParameterError()); + GlobalVector muonRefTrackDir(muon.px(), muon.py(), muon.pz()); + dxyPVSigned.push_back(IPTools::signedTransverseImpactParameter(transientTrack, muonRefTrackDir, pv).second.value()); + dxyPVSignedErr.push_back( + IPTools::signedTransverseImpactParameter(transientTrack, muonRefTrackDir, pv).second.error()); + + ip3DPVSigned.push_back( + IPTools::signedImpactParameter3D(transientTrack, muonRefTrackDir, beamSpotVertex).second.value()); + ip3DPVSignedErr.push_back( + IPTools::signedImpactParameter3D(transientTrack, muonRefTrackDir, beamSpotVertex).second.error()); + + trkNumPlanes.push_back(track->hitPattern().muonStationsWithValidHits()); + trkNumHits.push_back(track->hitPattern().numberOfValidMuonHits()); + trkNumDTHits.push_back(track->hitPattern().numberOfValidMuonDTHits()); + trkNumCSCHits.push_back(track->hitPattern().numberOfValidMuonCSCHits()); + + normChi2.push_back(track->normalizedChi2()); + + // Cannot get outer track for tracker muons + if (track->extra().isNonnull() && track->extra().isAvailable() && track->outerOk()) { + outerEta[i] = track->outerEta(); + outerPhi[i] = track->outerPhi(); + } + } + + auto tab = std::make_unique(nMuons, name_, false, true); + tab->addColumn("idx", idx, "EXOnanoAOD muon index"); + + tab->addColumn("trkPt", trkPt, ""); + tab->addColumn("trkPtErr", trkPtErr, ""); + + tab->addColumn("relIso0p4", relIso0p4, ""); + tab->addColumn("jetPtRatio", jetPtRatio, ""); + tab->addColumn("jetPtRel", jetPtRel, ""); + tab->addColumn("jetSelectedChargedMultiplicity", jetSelectedChargedMultiplicity, ""); + tab->addColumn("jetIdx", jetIdx, ""); + tab->addColumn("jetFatIdx", jetFatIdx, ""); + tab->addColumn("jetSubIdx", jetSubIdx, ""); + + tab->addColumn("numberInnerHitsMissing", numberInnerHitsMissing, ""); + + tab->addColumn("dzPV", dzPV, ""); + tab->addColumn("dzPVErr", dzPVErr, ""); + tab->addColumn("dxyPVTraj", dxyPVTraj, ""); + tab->addColumn("dxyPVTrajErr", dxyPVTrajErr, ""); + tab->addColumn("dxyPVSigned", dxyPVSigned, ""); + tab->addColumn("dxyPVSignedErr", dxyPVSignedErr, ""); + tab->addColumn("ip3DPVSigned", ip3DPVSigned, ""); + tab->addColumn("ip3DPVSignedErr", ip3DPVSignedErr, ""); + + tab->addColumn("trkNumPlanes", trkNumPlanes, ""); + tab->addColumn("trkNumHits", trkNumHits, ""); + tab->addColumn("trkNumDTHits", trkNumDTHits, ""); + tab->addColumn("trkNumCSCHits", trkNumCSCHits, ""); + tab->addColumn("normChi2", normChi2, ""); + tab->addColumn("trkNumPixelHits", trkNumPixelHits, ""); + tab->addColumn("trkNumTrkLayers", trkNumTrkLayers, ""); + + tab->addColumn("outerEta", outerEta, ""); + tab->addColumn("outerPhi", outerPhi, ""); + + iEvent.put(std::move(tab)); +} + +float MuonExtendedTableProducer::getPFIso(const pat::Muon& muon) const { + return (muon.pfIsolationR04().sumChargedHadronPt + + std::max(0., + muon.pfIsolationR04().sumNeutralHadronEt + muon.pfIsolationR04().sumPhotonEt - + 0.5 * muon.pfIsolationR04().sumPUPt)) / + muon.pt(); +} + +template +bool isSourceCandidatePtrMatch(const T1& lhs, const T2& rhs) { + for (size_t lhsIndex = 0; lhsIndex < lhs.numberOfSourceCandidatePtrs(); ++lhsIndex) { + auto lhsSourcePtr = lhs.sourceCandidatePtr(lhsIndex); + for (size_t rhsIndex = 0; rhsIndex < rhs.numberOfSourceCandidatePtrs(); ++rhsIndex) { + auto rhsSourcePtr = rhs.sourceCandidatePtr(rhsIndex); + if (lhsSourcePtr == rhsSourcePtr) { + return true; + } + } + } + + return false; +} + +int MuonExtendedTableProducer::findMatchedJet(const reco::Candidate& lepton, const std::vector& jets) const { + int iJet = -1; + + unsigned int nJets = jets.size(); + + for (unsigned int i = 0; i < nJets; i++) { + const pat::Jet& jet = jets[i]; + if (isSourceCandidatePtrMatch(lepton, jet)) { + return i; + } + } + + return iJet; +} + +void MuonExtendedTableProducer::fillLeptonJetVariables(const reco::Muon* mu, + const std::vector& jets, + const reco::Vertex& vertex, + const double rho, + std::vector* jetIdx, + std::vector relIso0p4, + std::vector* jetPtRatio, + std::vector* jetPtRel, + std::vector* jetSelectedChargedMultiplicity) const { + const reco::Candidate* cand = dynamic_cast(mu); + int matchedJetIdx = findMatchedJet(*cand, jets); + + jetIdx->push_back(matchedJetIdx); + + if (matchedJetIdx < 0) { + float ptRatio = (1. / (1. + relIso0p4.back())); + jetPtRatio->push_back(ptRatio); + jetPtRel->push_back(0); + jetSelectedChargedMultiplicity->push_back(0); + } else { + const pat::Jet& jet = jets[matchedJetIdx]; + auto rawJetP4 = jet.correctedP4("Uncorrected"); + auto leptonP4 = cand->p4(); + + bool leptonEqualsJet = ((rawJetP4 - leptonP4).P() < 1e-4); + + if (leptonEqualsJet) { + jetPtRatio->push_back(1); + jetPtRel->push_back(0); + jetSelectedChargedMultiplicity->push_back(0); + } else { + auto L1JetP4 = jet.correctedP4("L1FastJet"); + double L2L3JEC = jet.pt() / L1JetP4.pt(); + auto lepAwareJetP4 = (L1JetP4 - leptonP4) * L2L3JEC + leptonP4; + + float ptRatio = cand->pt() / lepAwareJetP4.pt(); + float ptRel = leptonP4.Vect().Cross((lepAwareJetP4 - leptonP4).Vect().Unit()).R(); + jetPtRatio->push_back(ptRatio); + jetPtRel->push_back(ptRel); + jetSelectedChargedMultiplicity->push_back(0); + + for (const auto& daughterPtr : jet.daughterPtrVector()) { + const pat::PackedCandidate& daughter = *((const pat::PackedCandidate*)daughterPtr.get()); + + if (daughter.charge() == 0) + continue; + if (daughter.fromPV() < 2) + continue; + if (reco::deltaR(daughter, *cand) > 0.4) + continue; + if (!daughter.hasTrackDetails()) + continue; + + auto daughterTrack = daughter.pseudoTrack(); + + if (daughterTrack.pt() <= 1) + continue; + if (daughterTrack.hitPattern().numberOfValidHits() < 8) + continue; + if (daughterTrack.hitPattern().numberOfValidPixelHits() < 2) + continue; + if (daughterTrack.normalizedChi2() >= 5) + continue; + if (std::abs(daughterTrack.dz(vertex.position())) >= 17) + continue; + if (std::abs(daughterTrack.dxy(vertex.position())) >= 0.2) + continue; + ++jetSelectedChargedMultiplicity->back(); + } + } + } +} + +#include "FWCore/Framework/interface/MakerMacros.h" +//define this as a plug-in +DEFINE_FWK_MODULE(MuonExtendedTableProducer); diff --git a/PhysicsTools/NanoAOD/plugins/MuonVertexTableProducer.cc b/PhysicsTools/NanoAOD/plugins/MuonVertexTableProducer.cc new file mode 100644 index 0000000000000..c945e9e733b7f --- /dev/null +++ b/PhysicsTools/NanoAOD/plugins/MuonVertexTableProducer.cc @@ -0,0 +1,874 @@ +#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "FWCore/Utilities/interface/transform.h" +#include "DataFormats/NanoAOD/interface/FlatTable.h" + +#include "DataFormats/TrackReco/interface/Track.h" +#include "DataFormats/VertexReco/interface/VertexFwd.h" +#include "DataFormats/VertexReco/interface/Vertex.h" +#include "TLorentzVector.h" +#include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h" +#include "TrackingTools/Records/interface/TransientTrackRecord.h" +#include "DataFormats/BeamSpot/interface/BeamSpot.h" +#include "DataFormats/PatCandidates/interface/Muon.h" + +#include "DataFormats/Math/interface/deltaR.h" + +#include "RecoVertex/VertexPrimitives/interface/TransientVertex.h" +#include "RecoVertex/KalmanVertexFit/interface/KalmanVertexFitter.h" + +#include "TrackingTools/Records/interface/TrackingComponentsRecord.h" +#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" +#include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h" +#include "TrackingTools/GeomPropagators/interface/Propagator.h" + +#include "TrackingTools/PatternTools/interface/TwoTrackMinimumDistance.h" +#include "PhysicsTools/RecoUtils/interface/CheckHitPattern.h" +#include "DataFormats/TrackerCommon/interface/TrackerTopology.h" +#include "Geometry/Records/interface/TrackerTopologyRcd.h" +#include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" +#include "Geometry/CommonDetUnit/interface/TrackingGeometry.h" +#include "Geometry/Records/interface/TrackerDigiGeometryRecord.h" + +#include "TrackingTools/IPTools/interface/IPTools.h" + +#include +#include + +class MuonVertexTableProducer : public edm::global::EDProducer<> { +public: + explicit MuonVertexTableProducer(const edm::ParameterSet& iConfig) + : dsaMuonTag_(consumes>(iConfig.getParameter("dsaMuons"))), + patMuonTag_(consumes>(iConfig.getParameter("patMuons"))), + bsTag_(consumes(iConfig.getParameter("beamspot"))), + pvTag_(consumes(iConfig.getParameter("primaryVertex"))), + generalTrackTag_(consumes>(iConfig.getParameter("generalTracks"))), + propagatorToken_(esConsumes(edm::ESInputTag("", "SteppingHelixPropagatorAny"))), + magneticFieldToken_(esConsumes()), + tkerGeomToken_(esConsumes()), + tkerTopoToken_(esConsumes()), + transientTrackBuilderToken_(esConsumes(edm::ESInputTag("", "TransientTrackBuilder"))) { + produces("PatMuonVertex"); + produces("PatDSAMuonVertex"); + produces("DSAMuonVertex"); + produces("PatMuonVertexRefittedTracks"); + produces("PatDSAMuonVertexRefittedTracks"); + produces("DSAMuonVertexRefittedTracks"); + } + + ~MuonVertexTableProducer() override {} + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("patMuons")->setComment("input pat muon collection"); + desc.add("dsaMuons")->setComment("input displaced standalone muon collection"); + desc.add("beamspot")->setComment("input beamspot collection"); + desc.add("primaryVertex")->setComment("input primaryVertex collection"); + desc.add("generalTracks")->setComment("input generalTracks collection"); + descriptions.add("muonVertexTables", desc); + } + +private: + void produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const override; + + std::pair getVxy(const reco::Vertex muonVertex) const; + std::pair getVxyz(const reco::Vertex muonVertex) const; + + template + float getDisplacedTrackerIsolation(const std::vector& generalTracks, + const MuonType1& muon_1, + const reco::Vertex muonVertex, + const reco::BeamSpot& beamspot, + const MuonType2* muon_2 = nullptr, + float maxDR = 0.3, + float minDR = 0.01, + float maxDz = 0.5, + float maxDxy = 0.2) const; + + template + float getProximityDeltaR(const MuonType& track, + const MuonType& trackRef, + const edm::ESHandle& magneticField, + const edm::ESHandle& propagator) const; + + std::tuple getDistanceBetweenMuonTracks( + const reco::Track& track1, const reco::Track& track2, const edm::ESHandle& magneticField) const; + + const edm::EDGetTokenT> dsaMuonTag_; + const edm::EDGetTokenT> patMuonTag_; + const edm::EDGetTokenT bsTag_; + const edm::EDGetTokenT pvTag_; + const edm::EDGetTokenT> generalTrackTag_; + const edm::ESGetToken propagatorToken_; + const edm::ESGetToken magneticFieldToken_; + const edm::ESGetToken tkerGeomToken_; + const edm::ESGetToken tkerTopoToken_; + const edm::ESGetToken transientTrackBuilderToken_; +}; + +void MuonVertexTableProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const { + const std::vector& dsaMuons = iEvent.get(dsaMuonTag_); + const std::vector& patMuons = iEvent.get(patMuonTag_); + + const reco::BeamSpot& beamSpotInput = iEvent.get(bsTag_); + const auto& bs = beamSpotInput.position(); + GlobalPoint beamSpot(bs.x(), bs.y(), bs.z()); + reco::Vertex beamSpotVertex(beamSpotInput.position(), beamSpotInput.covariance3D()); + + const reco::VertexCollection& primaryVertices = iEvent.get(pvTag_); + const auto& pv = primaryVertices.at(0); + GlobalPoint primaryVertex(pv.x(), pv.y(), pv.z()); + + const std::vector& generalTracks = iEvent.get(generalTrackTag_); + + auto const& propagator = &iSetup.getData(propagatorToken_); + auto const& magneticField = &iSetup.getData(magneticFieldToken_); + + auto const& tkerGeom = &iSetup.getData(tkerGeomToken_); + auto const& tkerTopo = &iSetup.getData(tkerTopoToken_); + const TransientTrackBuilder& builder = iSetup.getData(transientTrackBuilderToken_); + + KalmanVertexFitter vertexFitter(true, true); + + int nPatPatVertices = 0; + int nPatDSAVertices = 0; + int nDSADSAVertices = 0; + int ppRefittedTrackIdx_counter = 0; + int pdRefittedTrackIdx_counter = 0; + int ddRefittedTrackIdx_counter = 0; + + std::map> vertexIsValid; + std::map> vxy, vxyz, vx, vy, vz, t, vxySigma, vxyzSigma, vxErr, vyErr, vzErr, tErr; + std::map> chi2, ndof, normChi2, dR, originalMuonIdx1, originalMuonIdx2, + refittedTrackIdx1, refittedTrackIdx2, isDSAMuon1, isDSAMuon2; + std::map> displacedTrackIso03Dimuon1, displacedTrackIso03Dimuon2, + displacedTrackIso04Dimuon1, displacedTrackIso04Dimuon2; + std::map> displacedTrackIso03Muon1, displacedTrackIso03Muon2, + displacedTrackIso04Muon1, displacedTrackIso04Muon2, proxDeltaR; + std::map> DCA, DCAstatus, DCAx, DCAy, DCAz; + std::map> hitsInFrontOfVert1, missHitsAfterVert1, hitsInFrontOfVert2, + missHitsAfterVert2; + + std::map> refittedTrackIdx, refittedTrackIsDSAMuon, refittedTrackOriginalIdx, + refittedTrackPt, refittedTrackPtErr, refittedTrackPx, refittedTrackPy, refittedTrackPz; + std::map> refittedTrackEta, refittedTrackEtaErr, refittedTrackPhi, + refittedTrackPhiErr, refittedTrackCharge, refittedTrackNormChi2, refittedTrackNdof, refittedTrackChi2; + std::map> refittedTrackDzPV, refittedTrackDzPVErr, refittedTrackDxyPVTraj, + refittedTrackDxyPVTrajErr, refittedTrackDxyPVSigned, refittedTrackDxyPVSignedErr, refittedTrackIp3DPVSigned, + refittedTrackIp3DPVSignedErr; + std::map> refittedTrackIso03Dimuon1, refittedTrackIso03Dimuon2, + refittedTrackIso04Dimuon1, refittedTrackIso04Dimuon2, refittedTrackIso03Muon1, refittedTrackIso03Muon2, + refittedTrackIso04Muon1, refittedTrackIso04Muon2; + + // pat muons + for (size_t i = 0; i < patMuons.size(); i++) { + const pat::Muon& muon_i = patMuons.at(i); + + reco::TrackRef trackRef_i; + if (muon_i.isGlobalMuon()) + trackRef_i = muon_i.combinedMuon(); + else if (muon_i.isStandAloneMuon()) + trackRef_i = muon_i.standAloneMuon(); + else + trackRef_i = muon_i.tunePMuonBestTrack(); + + const auto& muonTrack_i = trackRef_i.get(); + reco::TransientTrack muonTransientTrack_i = builder.build(muonTrack_i); + + // pat-pat muon vertex + for (size_t j = i + 1; j < patMuons.size(); j++) { + const pat::Muon& muon_j = patMuons.at(j); + + reco::TrackRef trackRef_j; + if (muon_j.isGlobalMuon()) + trackRef_j = muon_j.combinedMuon(); + else if (muon_j.isStandAloneMuon()) + trackRef_j = muon_j.standAloneMuon(); + else + trackRef_j = muon_j.tunePMuonBestTrack(); + + const auto& muonTrack_j = trackRef_j.get(); + reco::TransientTrack muonTransientTrack_j = builder.build(muonTrack_j); + + std::vector muonTransientTracks{}; + muonTransientTracks.push_back(muonTransientTrack_i); + muonTransientTracks.push_back(muonTransientTrack_j); + + TransientVertex transientMuonVertex = vertexFitter.vertex(muonTransientTracks); + reco::Vertex muonVertex = reco::Vertex(transientMuonVertex); + + if (!transientMuonVertex.isValid()) + continue; + std::tuple distanceTuple = + getDistanceBetweenMuonTracks(*muonTrack_i, *muonTrack_j, magneticField); + // if dca status is good but dca is more than 15 cm + if (std::get<1>(distanceTuple) && std::get<0>(distanceTuple) > 15) + continue; + + nPatPatVertices++; + + vertexIsValid["PATPAT"].push_back(transientMuonVertex.isValid()); + std::pair vxy_ = getVxy(muonVertex); + vxy["PATPAT"].push_back(vxy_.first); + vxySigma["PATPAT"].push_back(vxy_.second); + std::pair vxyz_ = getVxyz(muonVertex); + vxyz["PATPAT"].push_back(vxyz_.first); + vxyzSigma["PATPAT"].push_back(vxyz_.second); + chi2["PATPAT"].push_back(muonVertex.chi2()); + ndof["PATPAT"].push_back(muonVertex.ndof()); + normChi2["PATPAT"].push_back(muonVertex.normalizedChi2()); + vx["PATPAT"].push_back(muonVertex.x()); + vy["PATPAT"].push_back(muonVertex.y()); + vz["PATPAT"].push_back(muonVertex.z()); + t["PATPAT"].push_back(muonVertex.t()); + vxErr["PATPAT"].push_back(muonVertex.xError()); + vyErr["PATPAT"].push_back(muonVertex.yError()); + vzErr["PATPAT"].push_back(muonVertex.zError()); + tErr["PATPAT"].push_back(muonVertex.tError()); + + dR["PATPAT"].push_back(reco::deltaR(muon_i, muon_j)); + originalMuonIdx1["PATPAT"].push_back(i); + originalMuonIdx2["PATPAT"].push_back(j); + isDSAMuon1["PATPAT"].push_back(0); + isDSAMuon2["PATPAT"].push_back(0); + + displacedTrackIso03Dimuon1["PATPAT"].push_back(getDisplacedTrackerIsolation( + generalTracks, muon_i, muonVertex, beamSpotInput, &muon_j, 0.3)); + displacedTrackIso04Dimuon1["PATPAT"].push_back(getDisplacedTrackerIsolation( + generalTracks, muon_i, muonVertex, beamSpotInput, &muon_j, 0.4)); + displacedTrackIso03Dimuon2["PATPAT"].push_back(getDisplacedTrackerIsolation( + generalTracks, muon_j, muonVertex, beamSpotInput, &muon_i, 0.3)); + displacedTrackIso04Dimuon2["PATPAT"].push_back(getDisplacedTrackerIsolation( + generalTracks, muon_j, muonVertex, beamSpotInput, &muon_i, 0.4)); + displacedTrackIso03Muon1["PATPAT"].push_back(getDisplacedTrackerIsolation( + generalTracks, muon_i, muonVertex, beamSpotInput, nullptr, 0.3)); + displacedTrackIso04Muon1["PATPAT"].push_back(getDisplacedTrackerIsolation( + generalTracks, muon_i, muonVertex, beamSpotInput, nullptr, 0.4)); + displacedTrackIso03Muon2["PATPAT"].push_back(getDisplacedTrackerIsolation( + generalTracks, muon_j, muonVertex, beamSpotInput, nullptr, 0.3)); + displacedTrackIso04Muon2["PATPAT"].push_back(getDisplacedTrackerIsolation( + generalTracks, muon_j, muonVertex, beamSpotInput, nullptr, 0.4)); + + // PAT muons cannot be only tracker muons for proximity deltaR calculations + if ((muon_i.isGlobalMuon() || muon_i.isStandAloneMuon()) && + (muon_j.isGlobalMuon() || muon_j.isStandAloneMuon())) { + proxDeltaR["PATPAT"].push_back(getProximityDeltaR(*muonTrack_i, *muonTrack_j, magneticField, propagator)); + } else + proxDeltaR["PATPAT"].push_back(-1); + + DCA["PATPAT"].push_back(std::get<0>(distanceTuple)); + DCAstatus["PATPAT"].push_back(std::get<1>(distanceTuple)); + DCAx["PATPAT"].push_back(std::get<2>(distanceTuple).x()); + DCAy["PATPAT"].push_back(std::get<2>(distanceTuple).y()); + DCAz["PATPAT"].push_back(std::get<2>(distanceTuple).z()); + + CheckHitPattern checkHitPattern; + checkHitPattern.init(tkerTopo, *tkerGeom, builder); + if (muon_i.isTrackerMuon()) { + CheckHitPattern::Result hitPattern_i = checkHitPattern(*muonTrack_i, transientMuonVertex.vertexState()); + hitsInFrontOfVert1["PATPAT"].push_back(hitPattern_i.hitsInFrontOfVert); + missHitsAfterVert1["PATPAT"].push_back(hitPattern_i.missHitsAfterVert); + } else { + hitsInFrontOfVert1["PATPAT"].push_back(-1); + missHitsAfterVert1["PATPAT"].push_back(-1); + } + if (muon_j.isTrackerMuon()) { + CheckHitPattern::Result hitPattern_j = checkHitPattern(*muonTrack_j, transientMuonVertex.vertexState()); + hitsInFrontOfVert2["PATPAT"].push_back(hitPattern_j.hitsInFrontOfVert); + missHitsAfterVert2["PATPAT"].push_back(hitPattern_j.missHitsAfterVert); + } else { + hitsInFrontOfVert2["PATPAT"].push_back(-1); + missHitsAfterVert2["PATPAT"].push_back(-1); + } + + reco::TransientTrack refittedTrack_i = transientMuonVertex.refittedTrack(muonTransientTrack_i); + reco::TransientTrack refittedTrack_j = transientMuonVertex.refittedTrack(muonTransientTrack_j); + std::vector refittedTracks = {refittedTrack_i, refittedTrack_j}; + for (size_t k = 0; k < refittedTracks.size(); ++k) { + const auto& refittedTrack = refittedTracks[k]; + refittedTrackIsDSAMuon["PATPAT"].push_back(0); + refittedTrackOriginalIdx["PATPAT"].push_back(i); + refittedTrackPt["PATPAT"].push_back(refittedTrack.track().pt()); + refittedTrackPtErr["PATPAT"].push_back(refittedTrack.track().ptError()); + refittedTrackPx["PATPAT"].push_back(refittedTrack.track().px()); + refittedTrackPy["PATPAT"].push_back(refittedTrack.track().py()); + refittedTrackPz["PATPAT"].push_back(refittedTrack.track().pz()); + refittedTrackEta["PATPAT"].push_back(refittedTrack.track().eta()); + refittedTrackEtaErr["PATPAT"].push_back(refittedTrack.track().etaError()); + refittedTrackPhi["PATPAT"].push_back(refittedTrack.track().phi()); + refittedTrackPhiErr["PATPAT"].push_back(refittedTrack.track().phiError()); + refittedTrackCharge["PATPAT"].push_back(refittedTrack.track().charge()); + refittedTrackNormChi2["PATPAT"].push_back(refittedTrack.normalizedChi2()); + refittedTrackNdof["PATPAT"].push_back(refittedTrack.ndof()); + refittedTrackChi2["PATPAT"].push_back(refittedTrack.chi2()); + + refittedTrackDzPV["PATPAT"].push_back(refittedTrack.track().dz(pv.position())); + refittedTrackDzPVErr["PATPAT"].push_back(std::hypot(refittedTrack.track().dzError(), pv.zError())); + TrajectoryStateClosestToPoint trajectoryPV_i = refittedTrack.trajectoryStateClosestToPoint(primaryVertex); + refittedTrackDxyPVTraj["PATPAT"].push_back(trajectoryPV_i.perigeeParameters().transverseImpactParameter()); + refittedTrackDxyPVTrajErr["PATPAT"].push_back(trajectoryPV_i.perigeeError().transverseImpactParameterError()); + GlobalVector muonRefTrackDir_i( + refittedTrack.track().px(), refittedTrack.track().py(), refittedTrack.track().pz()); + refittedTrackDxyPVSigned["PATPAT"].push_back( + IPTools::signedTransverseImpactParameter(refittedTrack, muonRefTrackDir_i, pv).second.value()); + refittedTrackDxyPVSignedErr["PATPAT"].push_back( + IPTools::signedTransverseImpactParameter(refittedTrack, muonRefTrackDir_i, pv).second.error()); + refittedTrackIp3DPVSigned["PATPAT"].push_back( + IPTools::signedImpactParameter3D(refittedTrack, muonRefTrackDir_i, pv).second.value()); + refittedTrackIp3DPVSignedErr["PATPAT"].push_back( + IPTools::signedImpactParameter3D(refittedTrack, muonRefTrackDir_i, pv).second.error()); + + refittedTrackIdx["PATPAT"].push_back(ppRefittedTrackIdx_counter); + if (k == 0) + refittedTrackIdx1["PATPAT"].push_back(ppRefittedTrackIdx_counter); + if (k == 1) + refittedTrackIdx2["PATPAT"].push_back(ppRefittedTrackIdx_counter); + ppRefittedTrackIdx_counter++; + } + + refittedTrackIso03Dimuon1["PATPAT"].push_back(getDisplacedTrackerIsolation( + generalTracks, refittedTrack_i.track(), muonVertex, beamSpotInput, &refittedTrack_j.track(), 0.3)); + refittedTrackIso04Dimuon1["PATPAT"].push_back(getDisplacedTrackerIsolation( + generalTracks, refittedTrack_i.track(), muonVertex, beamSpotInput, &refittedTrack_j.track(), 0.4)); + refittedTrackIso03Dimuon2["PATPAT"].push_back(getDisplacedTrackerIsolation( + generalTracks, refittedTrack_j.track(), muonVertex, beamSpotInput, &refittedTrack_i.track(), 0.3)); + refittedTrackIso04Dimuon2["PATPAT"].push_back(getDisplacedTrackerIsolation( + generalTracks, refittedTrack_j.track(), muonVertex, beamSpotInput, &refittedTrack_i.track(), 0.4)); + refittedTrackIso03Muon1["PATPAT"].push_back(getDisplacedTrackerIsolation( + generalTracks, refittedTrack_i.track(), muonVertex, beamSpotInput, nullptr, 0.3)); + refittedTrackIso04Muon1["PATPAT"].push_back(getDisplacedTrackerIsolation( + generalTracks, refittedTrack_i.track(), muonVertex, beamSpotInput, nullptr, 0.4)); + refittedTrackIso03Muon2["PATPAT"].push_back(getDisplacedTrackerIsolation( + generalTracks, refittedTrack_j.track(), muonVertex, beamSpotInput, nullptr, 0.3)); + refittedTrackIso04Muon2["PATPAT"].push_back(getDisplacedTrackerIsolation( + generalTracks, refittedTrack_j.track(), muonVertex, beamSpotInput, nullptr, 0.4)); + } + + // pat-dsa muon vertex + for (size_t j = 0; j < dsaMuons.size(); j++) { + const auto& muonTrack_j = dsaMuons.at(j); + reco::TransientTrack muonTransientTrack_j = builder.build(muonTrack_j); + + std::vector muonTransientTracks{}; + muonTransientTracks.push_back(muonTransientTrack_i); + muonTransientTracks.push_back(muonTransientTrack_j); + + TransientVertex transientMuonVertex = vertexFitter.vertex(muonTransientTracks); + reco::Vertex muonVertex = reco::Vertex(transientMuonVertex); + + if (!transientMuonVertex.isValid()) + continue; + std::tuple distanceTuple = + getDistanceBetweenMuonTracks(*muonTrack_i, muonTrack_j, magneticField); + // if dca status is good but dca is more than 15 cm + if (std::get<1>(distanceTuple) && std::get<0>(distanceTuple) > 15) + continue; + + nPatDSAVertices++; + + vertexIsValid["PATDSA"].push_back(transientMuonVertex.isValid()); + std::pair vxy_ = getVxy(muonVertex); + vxy["PATDSA"].push_back(vxy_.first); + vxySigma["PATDSA"].push_back(vxy_.second); + std::pair vxyz_ = getVxyz(muonVertex); + vxyz["PATDSA"].push_back(vxyz_.first); + vxyzSigma["PATDSA"].push_back(vxyz_.second); + chi2["PATDSA"].push_back(muonVertex.chi2()); + ndof["PATDSA"].push_back(muonVertex.ndof()); + normChi2["PATDSA"].push_back(muonVertex.normalizedChi2()); + vx["PATDSA"].push_back(muonVertex.x()); + vy["PATDSA"].push_back(muonVertex.y()); + vz["PATDSA"].push_back(muonVertex.z()); + t["PATDSA"].push_back(muonVertex.t()); + vxErr["PATDSA"].push_back(muonVertex.xError()); + vyErr["PATDSA"].push_back(muonVertex.yError()); + vzErr["PATDSA"].push_back(muonVertex.zError()); + tErr["PATDSA"].push_back(muonVertex.tError()); + + dR["PATDSA"].push_back(reco::deltaR(muon_i.eta(), muonTrack_j.eta(), muon_i.phi(), muonTrack_j.phi())); + originalMuonIdx1["PATDSA"].push_back(i); + originalMuonIdx2["PATDSA"].push_back(j); + isDSAMuon1["PATDSA"].push_back(0); + isDSAMuon2["PATDSA"].push_back(1); + + displacedTrackIso03Dimuon1["PATDSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, muon_i, muonVertex, beamSpotInput, &muonTrack_j, 0.3)); + displacedTrackIso04Dimuon1["PATDSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, muon_i, muonVertex, beamSpotInput, &muonTrack_j, 0.4)); + displacedTrackIso03Dimuon2["PATDSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, muonTrack_j, muonVertex, beamSpotInput, &muon_i, 0.3)); + displacedTrackIso04Dimuon2["PATDSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, muonTrack_j, muonVertex, beamSpotInput, &muon_i, 0.4)); + displacedTrackIso03Muon1["PATDSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, muon_i, muonVertex, beamSpotInput, nullptr, 0.3)); + displacedTrackIso04Muon1["PATDSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, muon_i, muonVertex, beamSpotInput, nullptr, 0.4)); + displacedTrackIso03Muon2["PATDSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, muonTrack_j, muonVertex, beamSpotInput, nullptr, 0.3)); + displacedTrackIso04Muon2["PATDSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, muonTrack_j, muonVertex, beamSpotInput, nullptr, 0.4)); + + // PAT muons cannot be only tracker muons for proximity deltaR calculations + if (muon_i.isGlobalMuon() || muon_i.isStandAloneMuon()) { + proxDeltaR["PATDSA"].push_back(getProximityDeltaR(*muonTrack_i, muonTrack_j, magneticField, propagator)); + } else + proxDeltaR["PATDSA"].push_back(-1); + + DCA["PATDSA"].push_back(std::get<0>(distanceTuple)); + DCAstatus["PATDSA"].push_back(std::get<1>(distanceTuple)); + DCAx["PATDSA"].push_back(std::get<2>(distanceTuple).x()); + DCAy["PATDSA"].push_back(std::get<2>(distanceTuple).y()); + DCAz["PATDSA"].push_back(std::get<2>(distanceTuple).z()); + + CheckHitPattern checkHitPattern; + checkHitPattern.init(tkerTopo, *tkerGeom, builder); + if (muon_i.isTrackerMuon()) { + CheckHitPattern::Result hitPattern_i = checkHitPattern(*muonTrack_i, transientMuonVertex.vertexState()); + hitsInFrontOfVert1["PATDSA"].push_back(hitPattern_i.hitsInFrontOfVert); + missHitsAfterVert1["PATDSA"].push_back(hitPattern_i.missHitsAfterVert); + } else { + hitsInFrontOfVert1["PATDSA"].push_back(-1); + missHitsAfterVert1["PATDSA"].push_back(-1); + } + hitsInFrontOfVert2["PATDSA"].push_back(-1); + missHitsAfterVert2["PATDSA"].push_back(-1); + + reco::TransientTrack refittedTrack_i = transientMuonVertex.refittedTrack(muonTransientTrack_i); + reco::TransientTrack refittedTrack_j = transientMuonVertex.refittedTrack(muonTransientTrack_j); + std::vector refittedTracks = {refittedTrack_i, refittedTrack_j}; + for (size_t k = 0; k < refittedTracks.size(); ++k) { + const auto& refittedTrack = refittedTracks[k]; + refittedTrackIsDSAMuon["PATDSA"].push_back(0); + refittedTrackOriginalIdx["PATDSA"].push_back(i); + refittedTrackPt["PATDSA"].push_back(refittedTrack.track().pt()); + refittedTrackPtErr["PATDSA"].push_back(refittedTrack.track().ptError()); + refittedTrackPx["PATDSA"].push_back(refittedTrack.track().px()); + refittedTrackPy["PATDSA"].push_back(refittedTrack.track().py()); + refittedTrackPz["PATDSA"].push_back(refittedTrack.track().pz()); + refittedTrackEta["PATDSA"].push_back(refittedTrack.track().eta()); + refittedTrackEtaErr["PATDSA"].push_back(refittedTrack.track().etaError()); + refittedTrackPhi["PATDSA"].push_back(refittedTrack.track().phi()); + refittedTrackPhiErr["PATDSA"].push_back(refittedTrack.track().phiError()); + refittedTrackCharge["PATDSA"].push_back(refittedTrack.track().charge()); + refittedTrackNormChi2["PATDSA"].push_back(refittedTrack.normalizedChi2()); + refittedTrackNdof["PATDSA"].push_back(refittedTrack.ndof()); + refittedTrackChi2["PATDSA"].push_back(refittedTrack.chi2()); + + refittedTrackDzPV["PATDSA"].push_back(refittedTrack.track().dz(pv.position())); + refittedTrackDzPVErr["PATDSA"].push_back(std::hypot(refittedTrack.track().dzError(), pv.zError())); + TrajectoryStateClosestToPoint trajectoryPV_i = refittedTrack.trajectoryStateClosestToPoint(primaryVertex); + refittedTrackDxyPVTraj["PATDSA"].push_back(trajectoryPV_i.perigeeParameters().transverseImpactParameter()); + refittedTrackDxyPVTrajErr["PATDSA"].push_back(trajectoryPV_i.perigeeError().transverseImpactParameterError()); + GlobalVector muonRefTrackDir_i( + refittedTrack.track().px(), refittedTrack.track().py(), refittedTrack.track().pz()); + refittedTrackDxyPVSigned["PATDSA"].push_back( + IPTools::signedTransverseImpactParameter(refittedTrack, muonRefTrackDir_i, pv).second.value()); + refittedTrackDxyPVSignedErr["PATDSA"].push_back( + IPTools::signedTransverseImpactParameter(refittedTrack, muonRefTrackDir_i, pv).second.error()); + refittedTrackIp3DPVSigned["PATDSA"].push_back( + IPTools::signedImpactParameter3D(refittedTrack, muonRefTrackDir_i, pv).second.value()); + refittedTrackIp3DPVSignedErr["PATDSA"].push_back( + IPTools::signedImpactParameter3D(refittedTrack, muonRefTrackDir_i, pv).second.error()); + + refittedTrackIdx["PATDSA"].push_back(pdRefittedTrackIdx_counter); + if (k == 0) + refittedTrackIdx1["PATDSA"].push_back(pdRefittedTrackIdx_counter); + if (k == 1) + refittedTrackIdx2["PATDSA"].push_back(pdRefittedTrackIdx_counter); + pdRefittedTrackIdx_counter++; + } + + refittedTrackIso03Dimuon1["PATDSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, refittedTrack_i.track(), muonVertex, beamSpotInput, &refittedTrack_j.track(), 0.3)); + refittedTrackIso04Dimuon1["PATDSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, refittedTrack_i.track(), muonVertex, beamSpotInput, &refittedTrack_j.track(), 0.4)); + refittedTrackIso03Dimuon2["PATDSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, refittedTrack_j.track(), muonVertex, beamSpotInput, &refittedTrack_i.track(), 0.3)); + refittedTrackIso04Dimuon2["PATDSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, refittedTrack_j.track(), muonVertex, beamSpotInput, &refittedTrack_i.track(), 0.4)); + refittedTrackIso03Muon1["PATDSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, refittedTrack_i.track(), muonVertex, beamSpotInput, nullptr, 0.3)); + refittedTrackIso04Muon1["PATDSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, refittedTrack_i.track(), muonVertex, beamSpotInput, nullptr, 0.4)); + refittedTrackIso03Muon2["PATDSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, refittedTrack_j.track(), muonVertex, beamSpotInput, nullptr, 0.3)); + refittedTrackIso04Muon2["PATDSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, refittedTrack_j.track(), muonVertex, beamSpotInput, nullptr, 0.4)); + } + } + + // dsa muons + for (size_t i = 0; i < dsaMuons.size(); i++) { + const auto& muonTrack_i = dsaMuons.at(i); + reco::TransientTrack muonTransientTrack_i = builder.build(muonTrack_i); + + //dsa-dsa muon vertex + for (size_t j = i + 1; j < dsaMuons.size(); j++) { + const auto& muonTrack_j = dsaMuons.at(j); + reco::TransientTrack muonTransientTrack_j = builder.build(muonTrack_j); + + std::vector muonTransientTracks{}; + muonTransientTracks.push_back(muonTransientTrack_i); + muonTransientTracks.push_back(muonTransientTrack_j); + + TransientVertex transientMuonVertex = vertexFitter.vertex(muonTransientTracks); + reco::Vertex muonVertex = reco::Vertex(transientMuonVertex); + + if (!transientMuonVertex.isValid()) + continue; + std::tuple distanceTuple = + getDistanceBetweenMuonTracks(muonTrack_i, muonTrack_j, magneticField); + // if dca status is good but dca is more than 15 cm + if (std::get<1>(distanceTuple) && std::get<0>(distanceTuple) > 15) + continue; + + nDSADSAVertices++; + + vertexIsValid["DSADSA"].push_back(transientMuonVertex.isValid()); + + std::pair vxy_ = getVxy(muonVertex); + vxy["DSADSA"].push_back(vxy_.first); + vxySigma["DSADSA"].push_back(vxy_.second); + std::pair vxyz_ = getVxyz(muonVertex); + vxyz["DSADSA"].push_back(vxyz_.first); + vxyzSigma["DSADSA"].push_back(vxyz_.second); + chi2["DSADSA"].push_back(muonVertex.chi2()); + ndof["DSADSA"].push_back(muonVertex.ndof()); + normChi2["DSADSA"].push_back(muonVertex.normalizedChi2()); + vx["DSADSA"].push_back(muonVertex.x()); + vy["DSADSA"].push_back(muonVertex.y()); + vz["DSADSA"].push_back(muonVertex.z()); + t["DSADSA"].push_back(muonVertex.t()); + vxErr["DSADSA"].push_back(muonVertex.xError()); + vyErr["DSADSA"].push_back(muonVertex.yError()); + vzErr["DSADSA"].push_back(muonVertex.zError()); + tErr["DSADSA"].push_back(muonVertex.tError()); + dR["DSADSA"].push_back(reco::deltaR(muonTrack_i.eta(), muonTrack_j.eta(), muonTrack_i.phi(), muonTrack_j.phi())); + originalMuonIdx1["DSADSA"].push_back(i); + originalMuonIdx2["DSADSA"].push_back(j); + isDSAMuon1["DSADSA"].push_back(1); + isDSAMuon2["DSADSA"].push_back(1); + + displacedTrackIso03Dimuon1["DSADSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, muonTrack_i, muonVertex, beamSpotInput, &muonTrack_j, 0.3)); + displacedTrackIso04Dimuon1["DSADSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, muonTrack_i, muonVertex, beamSpotInput, &muonTrack_j, 0.4)); + displacedTrackIso03Dimuon2["DSADSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, muonTrack_j, muonVertex, beamSpotInput, &muonTrack_i, 0.3)); + displacedTrackIso04Dimuon2["DSADSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, muonTrack_j, muonVertex, beamSpotInput, &muonTrack_i, 0.4)); + displacedTrackIso03Muon1["DSADSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, muonTrack_i, muonVertex, beamSpotInput, nullptr, 0.3)); + displacedTrackIso04Muon1["DSADSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, muonTrack_i, muonVertex, beamSpotInput, nullptr, 0.4)); + displacedTrackIso03Muon2["DSADSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, muonTrack_j, muonVertex, beamSpotInput, nullptr, 0.3)); + displacedTrackIso04Muon2["DSADSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, muonTrack_j, muonVertex, beamSpotInput, nullptr, 0.4)); + + proxDeltaR["DSADSA"].push_back(getProximityDeltaR(muonTrack_i, muonTrack_j, magneticField, propagator)); + + DCA["DSADSA"].push_back(std::get<0>(distanceTuple)); + DCAstatus["DSADSA"].push_back(std::get<1>(distanceTuple)); + DCAx["DSADSA"].push_back(std::get<2>(distanceTuple).x()); + DCAy["DSADSA"].push_back(std::get<2>(distanceTuple).y()); + DCAz["DSADSA"].push_back(std::get<2>(distanceTuple).z()); + + hitsInFrontOfVert1["DSADSA"].push_back(-1); + missHitsAfterVert1["DSADSA"].push_back(-1); + hitsInFrontOfVert2["DSADSA"].push_back(-1); + missHitsAfterVert2["DSADSA"].push_back(-1); + + reco::TransientTrack refittedTrack_i = transientMuonVertex.refittedTrack(muonTransientTrack_i); + reco::TransientTrack refittedTrack_j = transientMuonVertex.refittedTrack(muonTransientTrack_j); + std::vector refittedTracks = {refittedTrack_i, refittedTrack_j}; + for (size_t k = 0; k < refittedTracks.size(); ++k) { + const auto& refittedTrack = refittedTracks[k]; + refittedTrackIsDSAMuon["DSADSA"].push_back(0); + refittedTrackOriginalIdx["DSADSA"].push_back(i); + refittedTrackPt["DSADSA"].push_back(refittedTrack.track().pt()); + refittedTrackPtErr["DSADSA"].push_back(refittedTrack.track().ptError()); + refittedTrackPx["DSADSA"].push_back(refittedTrack.track().px()); + refittedTrackPy["DSADSA"].push_back(refittedTrack.track().py()); + refittedTrackPz["DSADSA"].push_back(refittedTrack.track().pz()); + refittedTrackEta["DSADSA"].push_back(refittedTrack.track().eta()); + refittedTrackEtaErr["DSADSA"].push_back(refittedTrack.track().etaError()); + refittedTrackPhi["DSADSA"].push_back(refittedTrack.track().phi()); + refittedTrackPhiErr["DSADSA"].push_back(refittedTrack.track().phiError()); + refittedTrackCharge["DSADSA"].push_back(refittedTrack.track().charge()); + refittedTrackNormChi2["DSADSA"].push_back(refittedTrack.normalizedChi2()); + refittedTrackNdof["DSADSA"].push_back(refittedTrack.ndof()); + refittedTrackChi2["DSADSA"].push_back(refittedTrack.chi2()); + + refittedTrackDzPV["DSADSA"].push_back(refittedTrack.track().dz(pv.position())); + refittedTrackDzPVErr["DSADSA"].push_back(std::hypot(refittedTrack.track().dzError(), pv.zError())); + TrajectoryStateClosestToPoint trajectoryPV_i = refittedTrack.trajectoryStateClosestToPoint(primaryVertex); + refittedTrackDxyPVTraj["DSADSA"].push_back(trajectoryPV_i.perigeeParameters().transverseImpactParameter()); + refittedTrackDxyPVTrajErr["DSADSA"].push_back(trajectoryPV_i.perigeeError().transverseImpactParameterError()); + GlobalVector muonRefTrackDir_i( + refittedTrack.track().px(), refittedTrack.track().py(), refittedTrack.track().pz()); + refittedTrackDxyPVSigned["DSADSA"].push_back( + IPTools::signedTransverseImpactParameter(refittedTrack, muonRefTrackDir_i, pv).second.value()); + refittedTrackDxyPVSignedErr["DSADSA"].push_back( + IPTools::signedTransverseImpactParameter(refittedTrack, muonRefTrackDir_i, pv).second.error()); + refittedTrackIp3DPVSigned["DSADSA"].push_back( + IPTools::signedImpactParameter3D(refittedTrack, muonRefTrackDir_i, pv).second.value()); + refittedTrackIp3DPVSignedErr["DSADSA"].push_back( + IPTools::signedImpactParameter3D(refittedTrack, muonRefTrackDir_i, pv).second.error()); + + refittedTrackIdx["DSADSA"].push_back(ddRefittedTrackIdx_counter); + if (k == 0) + refittedTrackIdx1["DSADSA"].push_back(ddRefittedTrackIdx_counter); + if (k == 1) + refittedTrackIdx2["DSADSA"].push_back(ddRefittedTrackIdx_counter); + ddRefittedTrackIdx_counter++; + } + + refittedTrackIso03Dimuon1["DSADSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, refittedTrack_i.track(), muonVertex, beamSpotInput, &refittedTrack_j.track(), 0.3)); + refittedTrackIso04Dimuon1["DSADSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, refittedTrack_i.track(), muonVertex, beamSpotInput, &refittedTrack_j.track(), 0.4)); + refittedTrackIso03Dimuon2["DSADSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, refittedTrack_j.track(), muonVertex, beamSpotInput, &refittedTrack_i.track(), 0.3)); + refittedTrackIso04Dimuon2["DSADSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, refittedTrack_j.track(), muonVertex, beamSpotInput, &refittedTrack_i.track(), 0.4)); + refittedTrackIso03Muon1["DSADSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, refittedTrack_i.track(), muonVertex, beamSpotInput, nullptr, 0.3)); + refittedTrackIso04Muon1["DSADSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, refittedTrack_i.track(), muonVertex, beamSpotInput, nullptr, 0.4)); + refittedTrackIso03Muon2["DSADSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, refittedTrack_j.track(), muonVertex, beamSpotInput, nullptr, 0.3)); + refittedTrackIso04Muon2["DSADSA"].push_back(getDisplacedTrackerIsolation( + generalTracks, refittedTrack_j.track(), muonVertex, beamSpotInput, nullptr, 0.4)); + } + } + + auto patVertexTab = std::make_unique(nPatPatVertices, "PatMuonVertex", false, false); + auto patdsaVertexTab = std::make_unique(nPatDSAVertices, "PatDSAMuonVertex", false, false); + auto dsaVertexTab = std::make_unique(nDSADSAVertices, "DSAMuonVertex", false, false); + + std::map> vertexTables; + vertexTables["PATPAT"] = std::move(patVertexTab); + vertexTables["PATDSA"] = std::move(patdsaVertexTab); + vertexTables["DSADSA"] = std::move(dsaVertexTab); + + for (const auto& [key, table] : vertexTables) { + table->addColumn("isValid", vertexIsValid[key], ""); + table->addColumn("vxy", vxy[key], ""); + table->addColumn("vxySigma", vxySigma[key], ""); + table->addColumn("vxyz", vxyz[key], ""); + table->addColumn("vxyzSigma", vxyzSigma[key], ""); + table->addColumn("chi2", chi2[key], ""); + table->addColumn("ndof", ndof[key], ""); + table->addColumn("normChi2", normChi2[key], ""); + table->addColumn("vx", vx[key], ""); + table->addColumn("vy", vy[key], ""); + table->addColumn("vz", vz[key], ""); + table->addColumn("t", t[key], ""); + table->addColumn("vxErr", vxErr[key], ""); + table->addColumn("vyErr", vyErr[key], ""); + table->addColumn("vzErr", vzErr[key], ""); + table->addColumn("tErr", tErr[key], ""); + table->addColumn("dR", dR[key], ""); + table->addColumn("originalMuonIdx1", originalMuonIdx1[key], ""); + table->addColumn("originalMuonIdx2", originalMuonIdx2[key], ""); + table->addColumn("isDSAMuon1", isDSAMuon1[key], ""); + table->addColumn("isDSAMuon2", isDSAMuon2[key], ""); + table->addColumn("displacedTrackIso03Dimuon1", displacedTrackIso03Dimuon1[key], ""); + table->addColumn("displacedTrackIso04Dimuon1", displacedTrackIso04Dimuon1[key], ""); + table->addColumn("displacedTrackIso03Dimuon2", displacedTrackIso03Dimuon2[key], ""); + table->addColumn("displacedTrackIso04Dimuon2", displacedTrackIso04Dimuon2[key], ""); + table->addColumn("displacedTrackIso03Muon1", displacedTrackIso03Muon1[key], ""); + table->addColumn("displacedTrackIso04Muon1", displacedTrackIso04Muon1[key], ""); + table->addColumn("displacedTrackIso03Muon2", displacedTrackIso03Muon2[key], ""); + table->addColumn("displacedTrackIso04Muon2", displacedTrackIso04Muon2[key], ""); + table->addColumn("dRprox", proxDeltaR[key], ""); + table->addColumn("dca", DCA[key], ""); + table->addColumn("dcaStatus", DCAstatus[key], ""); + table->addColumn("dcax", DCAx[key], ""); + table->addColumn("dcay", DCAy[key], ""); + table->addColumn("dcaz", DCAz[key], ""); + table->addColumn("hitsInFrontOfVert1", hitsInFrontOfVert1[key], ""); + table->addColumn("hitsInFrontOfVert2", hitsInFrontOfVert2[key], ""); + table->addColumn("missHitsAfterVert1", missHitsAfterVert1[key], ""); + table->addColumn("missHitsAfterVert2", missHitsAfterVert2[key], ""); + table->addColumn("refittedTrackIdx1", refittedTrackIdx1[key], ""); + table->addColumn("refittedTrackIdx2", refittedTrackIdx2[key], ""); + table->addColumn("refittedTrackIso03Dimuon1", refittedTrackIso03Dimuon1[key], ""); + table->addColumn("refittedTrackIso04Dimuon1", refittedTrackIso04Dimuon1[key], ""); + table->addColumn("refittedTrackIso03Dimuon2", refittedTrackIso03Dimuon2[key], ""); + table->addColumn("refittedTrackIso04Dimuon2", refittedTrackIso04Dimuon2[key], ""); + table->addColumn("refittedTrackIso03Muon1", refittedTrackIso03Muon1[key], ""); + table->addColumn("refittedTrackIso04Muon1", refittedTrackIso04Muon1[key], ""); + table->addColumn("refittedTrackIso03Muon2", refittedTrackIso03Muon2[key], ""); + table->addColumn("refittedTrackIso04Muon2", refittedTrackIso04Muon2[key], ""); + } + + iEvent.put(std::move(vertexTables["PATPAT"]), "PatMuonVertex"); + iEvent.put(std::move(vertexTables["PATDSA"]), "PatDSAMuonVertex"); + iEvent.put(std::move(vertexTables["DSADSA"]), "DSAMuonVertex"); + + auto patRefittedTracksTab = + std::make_unique(nPatPatVertices * 2, "PatMuonVertexRefittedTracks", false, false); + auto patdsaRefittedTracksTab = + std::make_unique(nPatDSAVertices * 2, "PatDSAMuonVertexRefittedTracks", false, false); + auto dsaRefittedTracksTab = + std::make_unique(nDSADSAVertices * 2, "DSAMuonVertexRefittedTracks", false, false); + + std::map> refittedTracksTables; + refittedTracksTables["PATPAT"] = std::move(patRefittedTracksTab); + refittedTracksTables["PATDSA"] = std::move(patdsaRefittedTracksTab); + refittedTracksTables["DSADSA"] = std::move(dsaRefittedTracksTab); + + for (const auto& [key, table] : refittedTracksTables) { + table->addColumn("idx", refittedTrackIdx[key], ""); + table->addColumn("isDSAMuon", refittedTrackIsDSAMuon[key], ""); + table->addColumn("originalMuonIdx", refittedTrackOriginalIdx[key], ""); + table->addColumn("pt", refittedTrackPt[key], ""); + table->addColumn("ptErr", refittedTrackPtErr[key], ""); + table->addColumn("px", refittedTrackPx[key], ""); + table->addColumn("py", refittedTrackPy[key], ""); + table->addColumn("pz", refittedTrackPz[key], ""); + table->addColumn("eta", refittedTrackEta[key], ""); + table->addColumn("etaErr", refittedTrackEtaErr[key], ""); + table->addColumn("phi", refittedTrackPhi[key], ""); + table->addColumn("phiErr", refittedTrackPhiErr[key], ""); + table->addColumn("charge", refittedTrackCharge[key], ""); + table->addColumn("normChi2", refittedTrackNormChi2[key], ""); + table->addColumn("ndof", refittedTrackNdof[key], ""); + table->addColumn("chi2", refittedTrackChi2[key], ""); + table->addColumn("dzPV", refittedTrackDzPV[key], ""); + table->addColumn("dzPVErr", refittedTrackDzPVErr[key], ""); + table->addColumn("dxyPVTraj", refittedTrackDxyPVTraj[key], ""); + table->addColumn("dxyPVTrajErr", refittedTrackDxyPVTrajErr[key], ""); + table->addColumn("dxyPVSigned", refittedTrackDxyPVSigned[key], ""); + table->addColumn("dxyPVSignedErr", refittedTrackDxyPVSignedErr[key], ""); + table->addColumn("ip3DPVSigned", refittedTrackIp3DPVSigned[key], ""); + table->addColumn("ip3DPVSignedErr", refittedTrackIp3DPVSignedErr[key], ""); + } + + iEvent.put(std::move(refittedTracksTables["PATPAT"]), "PatMuonVertexRefittedTracks"); + iEvent.put(std::move(refittedTracksTables["PATDSA"]), "PatDSAMuonVertexRefittedTracks"); + iEvent.put(std::move(refittedTracksTables["DSADSA"]), "DSAMuonVertexRefittedTracks"); +} + +std::pair MuonVertexTableProducer::getVxy(const reco::Vertex muonVertex) const { + float vxy = sqrt(muonVertex.x() * muonVertex.x() + muonVertex.y() * muonVertex.y()); + float vxySigma = (1 / vxy) * sqrt(muonVertex.x() * muonVertex.x() * muonVertex.xError() * muonVertex.xError() + + muonVertex.y() * muonVertex.y() * muonVertex.yError() * muonVertex.yError()); + return std::make_pair(vxy, vxySigma); +} + +std::pair MuonVertexTableProducer::getVxyz(const reco::Vertex muonVertex) const { + float vxyz = + sqrt(muonVertex.x() * muonVertex.x() + muonVertex.y() * muonVertex.y() + muonVertex.z() * muonVertex.z()); + float vxyzSigma = (1 / vxyz) * sqrt(muonVertex.x() * muonVertex.x() * muonVertex.xError() * muonVertex.xError() + + muonVertex.y() * muonVertex.y() * muonVertex.yError() * muonVertex.yError() + + muonVertex.z() * muonVertex.z() * muonVertex.zError() * muonVertex.zError()); + return std::make_pair(vxyz, vxyzSigma); +} + +template +float MuonVertexTableProducer::getDisplacedTrackerIsolation(const std::vector& generalTracks, + const MuonType1& muon_1, + const reco::Vertex muonVertex, + const reco::BeamSpot& beamspot, + const MuonType2* muon_2, + float maxDR, + float minDR, + float maxDz, + float maxDxy) const { + float trackPtSum = 0; + + int nGeneralTracks = generalTracks.size(); + float muonTrack2_pt = 0; + float muonTrack2_minDR = 9999; + + for (int i = 0; i < nGeneralTracks; i++) { + const reco::Track& generalTrack = (generalTracks)[i]; + + // Muon POG Tracker Isolation recommendation + float dR = deltaR(muon_1.eta(), muon_1.phi(), generalTrack.eta(), generalTrack.phi()); + if (dR > maxDR) + continue; + if (abs(generalTrack.vz() - muonVertex.z()) > maxDz) + continue; + if (generalTrack.dxy(beamspot) > maxDxy) + continue; + if (dR < minDR) + continue; + + // Determine if track belongs to other muon and get pt of the track + // Only if muon is given as input + if (muon_2 != nullptr) { + float dR_2 = deltaR(muon_2->eta(), muon_2->phi(), generalTrack.eta(), generalTrack.phi()); + if (dR_2 < minDR && dR_2 < muonTrack2_minDR) { + muonTrack2_pt = generalTrack.pt(); + muonTrack2_minDR = dR_2; + } + } + + trackPtSum += generalTrack.pt(); + } + + // Remove pt of track that belongs to other muon + trackPtSum -= muonTrack2_pt; + + float ptRatio = trackPtSum / muon_1.pt(); + return ptRatio; +} + +/** +* Proximity match based on EXO-23-010 +* Calculating deltaR between the innermost hit of the DSAMuon trackRef +* and the extracted closest position of PATMuon track +**/ +template +float MuonVertexTableProducer::getProximityDeltaR(const MuonType& track, + const MuonType& trackRef, + const edm::ESHandle& magneticField, + const edm::ESHandle& propagator) const { + FreeTrajectoryState trajState(GlobalPoint(track.vx(), track.vy(), track.vz()), + GlobalVector(track.px(), track.py(), track.pz()), + track.charge(), + magneticField.product()); + + GlobalPoint refPos(trackRef.innerPosition().x(), trackRef.innerPosition().y(), trackRef.innerPosition().z()); + FreeTrajectoryState trajStatePCA(propagator->propagate(trajState, refPos)); + + float dR = deltaR(trajStatePCA.position().eta(), + trajStatePCA.position().phi(), + trackRef.innerPosition().eta(), + trackRef.innerPosition().phi()); + return dR; +} + +/** +* Proximity between the muons based on EXO-23-010 +* Getting Distance of Closest Approach between muon tracks using TwoTrackMinimumDistance +* Returns tuple of distance (float), error of distance (float) and crossing point (GlobalPoint) +**/ +std::tuple MuonVertexTableProducer::getDistanceBetweenMuonTracks( + const reco::Track& track1, const reco::Track& track2, const edm::ESHandle& magneticField) const { + TwoTrackMinimumDistance ttmd; + FreeTrajectoryState fts1(GlobalPoint(track1.vx(), track1.vy(), track1.vz()), + GlobalVector(track1.px(), track1.py(), track1.pz()), + track1.charge(), + magneticField.product()); + FreeTrajectoryState fts2(GlobalPoint(track2.vx(), track2.vy(), track2.vz()), + GlobalVector(track2.px(), track2.py(), track2.pz()), + track2.charge(), + magneticField.product()); + bool status = ttmd.calculate(fts1, fts2); + if (!status) + return std::tuple(-999.f, status, GlobalPoint(-999.f, -999.f, -999.f)); + return std::make_tuple(ttmd.distance(), status, ttmd.crossingPoint()); +} + +#include "FWCore/Framework/interface/MakerMacros.h" +DEFINE_FWK_MODULE(MuonVertexTableProducer); diff --git a/PhysicsTools/NanoAOD/plugins/cscMDSshowerTableProducer.cc b/PhysicsTools/NanoAOD/plugins/cscMDSshowerTableProducer.cc new file mode 100644 index 0000000000000..014b5fb433d0f --- /dev/null +++ b/PhysicsTools/NanoAOD/plugins/cscMDSshowerTableProducer.cc @@ -0,0 +1,390 @@ +#include +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/global/EDProducer.h" + +#include "FWCore/Framework/interface/Event.h" + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" + +#include "DataFormats/NanoAOD/interface/FlatTable.h" +#include "DataFormats/MuonDetId/interface/CSCTriggerNumbering.h" +#include "DataFormats/GeometryVector/interface/GlobalPoint.h" +#include "DataFormats/GeometryVector/interface/LocalPoint.h" +#include "DataFormats/Math/interface/PtEtaPhiMass.h" +#include "DataFormats/CSCRecHit/interface/CSCRecHit2DCollection.h" +#include "DataFormats/DTRecHit/interface/DTRecSegment4DCollection.h" +#include "DataFormats/RPCRecHit/interface/RPCRecHitCollection.h" +#include "DataFormats/Math/interface/deltaR.h" + +#include "Geometry/CSCGeometry/interface/CSCGeometry.h" +#include "Geometry/DTGeometry/interface/DTGeometry.h" +#include "Geometry/RPCGeometry/interface/RPCGeometry.h" +#include "Geometry/Records/interface/MuonGeometryRecord.h" + +#include "fastjet/ClusterSequence.hh" +#include "fastjet/JetDefinition.hh" +#include "fastjet/PseudoJet.hh" + +using RecHitRef = edm::Ref; +using RecHitRefVector = edm::RefVector; + +class cscMDSshowerTableProducer : public edm::global::EDProducer<> { +public: + cscMDSshowerTableProducer(const edm::ParameterSet& iConfig) + : geometryToken_(esConsumes()), + dtgeometryToken_(esConsumes()), + rpcgeometryToken_(esConsumes()), + inputToken_(consumes(iConfig.getParameter("recHitLabel"))), + dtSegmentToken_(consumes(iConfig.getParameter("segmentLabel"))), + rpchitToken_(consumes(iConfig.getParameter("rpcLabel"))), + rParam_(iConfig.getParameter("rParam")), + nRechitMin_(iConfig.getParameter("nRechitMin")), + nStationThres_(iConfig.getParameter("nStationThres")), + stripErr_(iConfig.getParameter("stripErr")), + wireError_(iConfig.getParameter("wireError")), + pruneCut_(iConfig.getParameter("pruneCut")), + name_(iConfig.getParameter("name")) { + produces(name_ + "Rechits"); + produces(name_); + } + + ~cscMDSshowerTableProducer() override {} + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("recHitLabel")->setComment("input cscRechit collection"); + desc.add("segmentLabel")->setComment("input dt segment collection for veto"); + desc.add("rpcLabel")->setComment("input rpcRechit collection for veto"); + desc.add("rParam", 0.4); + desc.add("nRechitMin", 50); + desc.add("nStationThres", 10); + desc.add("stripErr", 7.0); + desc.add("wireError", 8.6); + desc.add("pruneCut", 9.0); + desc.add("name", "cscRechits")->setComment("name of the output collection"); + descriptions.add("cscMDSshowerTable", desc); + } + float getWeightedTime(RecHitRefVector rechits) const; + +private: + void produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const override; + + const edm::ESGetToken geometryToken_; + const edm::ESGetToken dtgeometryToken_; + const edm::ESGetToken rpcgeometryToken_; + edm::EDGetTokenT inputToken_; + edm::EDGetTokenT dtSegmentToken_; + edm::EDGetTokenT rpchitToken_; + const double rParam_; + const int nRechitMin_; // min number of rechits + const int nStationThres_; // min number of rechits to count towards nStation + const double stripErr_, wireError_, pruneCut_; //constants for CSC time + const std::string name_; +}; + +//From: https://github.com/cms-sw/cmssw/blob/master/RecoMuon/MuonIdentification/src/CSCTimingExtractor.cc#L165-L234 +float cscMDSshowerTableProducer::getWeightedTime(RecHitRefVector rechits) const { + bool modified = false; + double totalWeightTimeVtx = 0; + float timeVtx = 0; + + do { + modified = false; + totalWeightTimeVtx = 0; + timeVtx = 0; + for (auto const& rechit : rechits) { + timeVtx += rechit->wireTime() * 1. / (wireError_ * wireError_); + timeVtx += rechit->tpeak() * 1. / (stripErr_ * stripErr_); + totalWeightTimeVtx += 1. / (wireError_ * wireError_); + totalWeightTimeVtx += 1. / (stripErr_ * stripErr_); + } + timeVtx /= totalWeightTimeVtx; + + // cut away outliers + double diff_tvtx_strip, diff_tvtx_wire; + double chimax = 0.0; + int tmmax = 0; + for (size_t i = 0; i < rechits.size(); ++i) { + const auto& rechit = rechits[i]; + //diff_tvtx = (cscHits[i].time - timeVtx) * (cscHits[i].time - timeVtx) * cscHits[i].error; + diff_tvtx_strip = (rechit->tpeak() - timeVtx) * (rechit->tpeak() - timeVtx) * 1. / (stripErr_ * stripErr_); + diff_tvtx_wire = (rechit->wireTime() - timeVtx) * (rechit->wireTime() - timeVtx) * 1. / (wireError_ * wireError_); + + if ((diff_tvtx_strip > chimax) || (diff_tvtx_wire > chimax)) { + tmmax = i; + chimax = std::max(diff_tvtx_strip, diff_tvtx_wire); + } + } + // cut away the outliers and repeat + if (chimax > pruneCut_) { + rechits.erase(rechits.begin() + tmmax); + modified = true; + } + } while (modified); + + return timeVtx; +} + +void cscMDSshowerTableProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const { + auto const& geo = iSetup.getData(geometryToken_); + auto const& dt_geo = iSetup.getData(dtgeometryToken_); + auto const& rpc_geo = iSetup.getData(rpcgeometryToken_); + auto const& rechits = iEvent.get(inputToken_); + auto const& segments = iEvent.get(dtSegmentToken_); + auto const& rpchits = iEvent.get(rpchitToken_); + + std::set unique_ids; + std::vector fjInput; + + edm::RefVector inputs; + + fastjet::JetDefinition jet_def(fastjet::cambridge_algorithm, rParam_); + + int recIt = 0; + for (auto const& rechit : rechits) { + LocalPoint recHitLocalPosition = rechit.localPosition(); + auto detid = rechit.cscDetId(); + auto thischamber = geo.chamber(detid); + if (thischamber) { + GlobalPoint globalPosition = thischamber->toGlobal(recHitLocalPosition); + float x = globalPosition.x(); + float y = globalPosition.y(); + float z = globalPosition.z(); + RecHitRef ref = RecHitRef(&rechits, recIt); + inputs.push_back(ref); + fjInput.push_back(fastjet::PseudoJet(x, y, z, globalPosition.mag())); + fjInput.back().set_user_index(recIt); + } + recIt++; + } + fastjet::ClusterSequence clus_seq(fjInput, jet_def); + + //keep all the clusters + double ptmin = 0.0; + std::vector fjJets = clus_seq.inclusive_jets(ptmin); + + // Constituent rechit fields + std::vector cscRechitsX, cscRechitsY, cscRechitsZ, cscRechitsPhi, cscRechitsEta, cscRechitsE, cscRechitsTpeak, + cscRechitsTwire; + std::vector cscRechitsNStrips, cscRechitsHitWire, cscRechitsWGroupsBX, cscRechitsNWireGroups, cscRechitsQuality, + cscRechitsChamber, cscRechitsIChamber, cscRechitsStation; + ; + + // MDS fields + std::vector clsX, clsY, clsZ, clsPhi, clsEta, clsTime, clsTimeSpread, clsTimeWeighted, clsTimeSpreadWeighted, + clsAvgStation; + std::vector clsSize, clsNstation, cls_nME11, cls_nME12, clsUniqueChamber, cls_nMB1dtSeg, cls_nRE12hit, + cls_nRB1hit; + + for (auto const& fjJet : fjJets) { + // skip if the cluster has too few rechits + if (int(fjJet.constituents().size()) < nRechitMin_) + continue; + // get the constituents from fastjet + RecHitRefVector rechits; + for (auto const& constituent : fjJet.constituents()) { + auto index = constituent.user_index(); + if (index >= 0 && static_cast(index) < inputs.size()) { + rechits.push_back(inputs[index]); + } + } + + //Derive cluster properties + int nME12 = 0, nME11 = 0, nMB1dtSeg = 0, nRE12hit = 0, nRB1hit = 0; + int nStation = 0; + int totStation = 0; + float avgStation = 0.0; + float timeSpread = 0.0; + float time = 0.0; + float time_strip = 0.0; // for timeSpread calculation + double timeWeighted = 0.0; + float timeSpreadWeighted = 0.0; + + std::map station_count_map; + + //fill rechits fields + for (auto const& rechit : rechits) { + LocalPoint recHitLocalPosition = rechit->localPosition(); + auto detid = rechit->cscDetId(); + unique_ids.insert(detid.chamberId()); + auto thischamber = geo.chamber(detid); + int endcap = CSCDetId::endcap(detid) == 1 ? 1 : -1; + if (thischamber) { + GlobalPoint globalPosition = thischamber->toGlobal(recHitLocalPosition); + + cscRechitsX.push_back(globalPosition.x()); + cscRechitsY.push_back(globalPosition.y()); + cscRechitsZ.push_back(globalPosition.z()); + cscRechitsPhi.push_back(globalPosition.phi()); + cscRechitsEta.push_back(globalPosition.eta()); + cscRechitsE.push_back(rechit->energyDepositedInLayer()); //not saved + cscRechitsTpeak.push_back(rechit->tpeak()); + cscRechitsTwire.push_back(rechit->wireTime()); + cscRechitsQuality.push_back(rechit->quality()); + + int stationRing = (CSCDetId::station(detid) * 10 + CSCDetId::ring(detid)); + if (CSCDetId::ring(detid) == 4) + stationRing = (CSCDetId::station(detid) * 10 + 1); // ME1/a has ring==4 + + cscRechitsChamber.push_back(endcap * stationRing); + cscRechitsIChamber.push_back(CSCDetId::chamber(detid)); + cscRechitsStation.push_back(endcap * CSCDetId::station(detid)); + cscRechitsNStrips.push_back(rechit->nStrips()); + cscRechitsHitWire.push_back(rechit->hitWire()); + cscRechitsWGroupsBX.push_back(rechit->wgroupsBX()); + cscRechitsNWireGroups.push_back(rechit->nWireGroups()); + + //compute for cluster fields + station_count_map[CSCDetId::station(detid)]++; + if (stationRing == 11) + nME11++; + if (stationRing == 12) + nME12++; + time += (rechit->tpeak() + rechit->wireTime()); + time_strip += rechit->tpeak(); + } + } + //station statistics + std::map::iterator it; + for (auto const& [station, count] : station_count_map) { + if (count >= nStationThres_) { + nStation++; + avgStation += station * count; + totStation += count; + } + } + if (totStation != 0) { + avgStation = avgStation / totStation; + } + float invN = 1.f / rechits.size(); + time = (time / 2.f) * invN; + time_strip = time_strip * invN; + + // https://github.com/cms-sw/cmssw/blob/master/RecoMuon/MuonIdentification/src/CSCTimingExtractor.cc#L165-L234 + for (auto& rechit : rechits) { + timeSpread += (rechit->tpeak() - time_strip) * (rechit->tpeak() - time_strip); + } + timeSpread = std::sqrt(timeSpread * invN); + + float i_clsEta = etaFromXYZ(fjJet.px() * invN, fjJet.py() * invN, fjJet.pz() * invN); + float i_clsPhi = std::atan2(fjJet.py() * invN, fjJet.px() * invN); + + //MB1 DT seg + for (auto const& segment : segments) { + LocalPoint localPosition = segment.localPosition(); + auto geoid = segment.geographicalId(); + DTChamberId dtdetid = DTChamberId(geoid); + auto thischamber = dt_geo.chamber(dtdetid); + if (thischamber) { + GlobalPoint globalPosition = thischamber->toGlobal(localPosition); + float eta = globalPosition.eta(); + float phi = globalPosition.phi(); + if (dtdetid.station() == 1 && reco::deltaR(eta, phi, i_clsEta, i_clsPhi) < 0.4) + nMB1dtSeg++; + } + } + //RPC hits + for (auto const& rechit : rpchits) { + LocalPoint recHitLocalPosition = rechit.localPosition(); + auto geoid = rechit.geographicalId(); + RPCDetId rpcdetid = RPCDetId(geoid); + auto thischamber = rpc_geo.chamber(rpcdetid); + + if (thischamber) { + GlobalPoint globalPosition = thischamber->toGlobal(recHitLocalPosition); + float eta = globalPosition.eta(); + float phi = globalPosition.phi(); + + //RE12 hits + if (rpcdetid.station() == 1 && rpcdetid.ring() == 2 && abs(rpcdetid.region()) == 1 && + reco::deltaR(eta, phi, i_clsEta, i_clsPhi) < 0.4) + nRE12hit++; + //RB1 hits + if (rpcdetid.station() == 1 && rpcdetid.region() == 0 && reco::deltaR(eta, phi, i_clsEta, i_clsPhi) < 0.4) + nRB1hit++; + } + } + + //fill cluster fields + clsSize.push_back(rechits.size()); + // cluster position is the average position of the constituent rechits + clsX.push_back(fjJet.px() * invN); + clsY.push_back(fjJet.py() * invN); + clsZ.push_back(fjJet.pz() * invN); + clsEta.push_back(i_clsEta); + clsPhi.push_back(i_clsPhi); + + clsTime.push_back(time); + clsTimeSpread.push_back(timeSpread); + cls_nME11.push_back(nME11); + cls_nME12.push_back(nME12); + clsNstation.push_back(nStation); + clsAvgStation.push_back(avgStation); + clsUniqueChamber.push_back(unique_ids.size()); + cls_nMB1dtSeg.push_back(nMB1dtSeg); + cls_nRE12hit.push_back(nRE12hit); + cls_nRB1hit.push_back(nRB1hit); + + //cluster time weighted with unc. and pruned outliers + timeWeighted = cscMDSshowerTableProducer::getWeightedTime(rechits); + + for (auto& rechit : rechits) { + timeSpreadWeighted += (timeWeighted - rechit->tpeak()) * (timeWeighted - rechit->tpeak()); + } + timeSpreadWeighted = std::sqrt(timeSpreadWeighted * invN); + + clsTimeWeighted.push_back(timeWeighted); + clsTimeSpreadWeighted.push_back(timeSpreadWeighted); + } + auto cscRechitTab = std::make_unique(cscRechitsX.size(), name_ + "Rechits", false, false); + + cscRechitTab->addColumn("X", cscRechitsX, "csc rechit X"); + cscRechitTab->addColumn("Y", cscRechitsY, "csc rechit Y"); + cscRechitTab->addColumn("Z", cscRechitsZ, "csc rechit Z"); + cscRechitTab->addColumn("Phi", cscRechitsPhi, "csc rechit Phi"); + cscRechitTab->addColumn("Eta", cscRechitsEta, "csc rechit Eta"); + cscRechitTab->addColumn("E", cscRechitsE, "csc rechit Energy deposited in layer"); + cscRechitTab->addColumn("Tpeak", cscRechitsTpeak, "csc rechit time from cathode"); + cscRechitTab->addColumn("Twire", cscRechitsTwire, "csc rechit time from anode"); + cscRechitTab->addColumn("Quality", cscRechitsQuality, "csc rechit quality"); + cscRechitTab->addColumn("Chamber", cscRechitsChamber, "csc rechit station-Ring"); + cscRechitTab->addColumn("IChamber", cscRechitsIChamber, "csc rechit chamber in ring"); + cscRechitTab->addColumn("Station", cscRechitsStation, "csc rechit station"); + cscRechitTab->addColumn("NStrips", cscRechitsNStrips, "csc rechit nstrips"); + cscRechitTab->addColumn("WGroupsBX", cscRechitsWGroupsBX, "csc rechit wire group BX"); + cscRechitTab->addColumn("HitWire", cscRechitsHitWire, "csc rechit hit wire"); + cscRechitTab->addColumn("NWireGroups", cscRechitsNWireGroups, "csc rechit n wire groups"); + + iEvent.put(std::move(cscRechitTab), name_ + "Rechits"); + + auto clsTab = std::make_unique(clsSize.size(), name_, false, false); + + clsTab->addColumn("size", clsSize, "cluster Size"); + clsTab->addColumn("x", clsX, "cluster X"); + clsTab->addColumn("y", clsY, "cluster Y"); + clsTab->addColumn("z", clsZ, "cluster Z"); + clsTab->addColumn("phi", clsPhi, "cluster Phi"); + clsTab->addColumn("eta", clsEta, "cluster Eta"); + clsTab->addColumn("time", clsTime, "cluster Time"); + clsTab->addColumn("timeSpread", clsTimeSpread, "cluster TimeSpread"); + clsTab->addColumn("timeWeighted", clsTimeWeighted, "cluster TimeWeighted"); + clsTab->addColumn("timeSpreadWeighted", clsTimeSpreadWeighted, "cluster TimeSpreadWeighted"); + clsTab->addColumn("nStation", clsNstation, "cluster nStation"); + clsTab->addColumn("uniqueChamber", clsUniqueChamber, "cluster unique chambers"); + clsTab->addColumn("avgStation", clsAvgStation, "cluster AvgStation"); + clsTab->addColumn("nME11", cls_nME11, "cluster nME11"); + clsTab->addColumn("nME12", cls_nME12, "cluster nME12"); + clsTab->addColumn("nMB1dtSeg", cls_nMB1dtSeg, "cluster nMB1dtSeg"); + clsTab->addColumn("nRE12hit", cls_nRE12hit, "cluster nRE12hit"); + clsTab->addColumn("nRB1hit", cls_nRB1hit, "cluster nRB1hit"); + + iEvent.put(std::move(clsTab), name_); +} + +#include "FWCore/Framework/interface/MakerMacros.h" +DEFINE_FWK_MODULE(cscMDSshowerTableProducer); diff --git a/PhysicsTools/NanoAOD/plugins/dtMDSshowerTableProducer.cc b/PhysicsTools/NanoAOD/plugins/dtMDSshowerTableProducer.cc new file mode 100644 index 0000000000000..28a3a0a1d6eeb --- /dev/null +++ b/PhysicsTools/NanoAOD/plugins/dtMDSshowerTableProducer.cc @@ -0,0 +1,339 @@ +#include +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/global/EDProducer.h" + +#include "FWCore/Framework/interface/Event.h" + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" + +#include "DataFormats/NanoAOD/interface/FlatTable.h" +#include "DataFormats/GeometryVector/interface/GlobalPoint.h" +#include "DataFormats/GeometryVector/interface/LocalPoint.h" +#include "DataFormats/Math/interface/PtEtaPhiMass.h" +#include "DataFormats/DTRecHit/interface/DTRecHitCollection.h" +#include "DataFormats/RPCRecHit/interface/RPCRecHitCollection.h" +#include "DataFormats/Math/interface/deltaPhi.h" + +#include "Geometry/DTGeometry/interface/DTGeometry.h" +#include "Geometry/RPCGeometry/interface/RPCGeometry.h" +#include "Geometry/Records/interface/MuonGeometryRecord.h" + +#include "fastjet/ClusterSequence.hh" +#include "fastjet/JetDefinition.hh" +#include "fastjet/PseudoJet.hh" + +using RecHitRef = edm::Ref; +using RecHitRefVector = edm::RefVector; + +class dtMDSshowerTableProducer : public edm::global::EDProducer<> { +public: + dtMDSshowerTableProducer(const edm::ParameterSet& iConfig) + : dtgeometryToken_(esConsumes()), + rpcgeometryToken_(esConsumes()), + inputToken_(consumes(iConfig.getParameter("recHitLabel"))), + rpchitToken_(consumes(iConfig.getParameter("rpcLabel"))), + rParam_(iConfig.getParameter("rParam")), + nRechitMin_(iConfig.getParameter("nRechitMin")), + nStationThres_(iConfig.getParameter("nStationThres")), + name_(iConfig.getParameter("name")) { + produces(name_ + "Rechits"); + produces(name_); + } + + ~dtMDSshowerTableProducer() override {} + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("recHitLabel")->setComment("input dtRechit collection"); + desc.add("rpcLabel")->setComment("input rpcRechit collection for veto"); + desc.add("rParam", 0.4); + desc.add("nRechitMin", 50); + desc.add("nStationThres", 10); + desc.add("name", "dt1DRecHits")->setComment("name of the output collection"); + descriptions.add("dtMDSshowerTable", desc); + } + float getWeightedTime(RecHitRefVector rechits) const; + +private: + void produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const override; + + const edm::ESGetToken dtgeometryToken_; + const edm::ESGetToken rpcgeometryToken_; + edm::EDGetTokenT inputToken_; + edm::EDGetTokenT rpchitToken_; + const double rParam_; + const int nRechitMin_; // min number of rechits + const int nStationThres_; // min number of rechits to count towards nStation + const std::string name_; +}; + +void dtMDSshowerTableProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const { + auto const& dt_geo = iSetup.getData(dtgeometryToken_); + auto const& rpc_geo = iSetup.getData(rpcgeometryToken_); + auto const& rechits = iEvent.get(inputToken_); + auto const& rpchits = iEvent.get(rpchitToken_); + + std::set unique_ids; + std::vector fjInput; + + RecHitRefVector inputs; + + fastjet::JetDefinition jet_def(fastjet::cambridge_algorithm, rParam_); + + int recIt = 0; + for (auto const& rechit : rechits) { + LocalPoint recHitLocalPosition = rechit.localPosition(); + auto geoid = rechit.geographicalId(); + DTChamberId dtdetid = DTChamberId(geoid); + DTLayerId dtlayerid = DTLayerId(geoid); + + auto thischamber = dt_geo.chamber(dtdetid); + auto thislayer = dt_geo.layer(dtlayerid); + + if (thischamber) { + GlobalPoint globalPosition; + if (thislayer) { + globalPosition = thislayer->toGlobal(recHitLocalPosition); + } else { + globalPosition = thischamber->toGlobal(recHitLocalPosition); + } + float x = globalPosition.x(); + float y = globalPosition.y(); + float z = globalPosition.z(); + RecHitRef ref = RecHitRef(&rechits, recIt); + inputs.push_back(ref); + fjInput.push_back(fastjet::PseudoJet(x, y, z, globalPosition.mag())); + fjInput.back().set_user_index(recIt); + } + recIt++; + } + fastjet::ClusterSequence clus_seq(fjInput, jet_def); + + //keep all the clusters + double ptmin = 0.0; + std::vector fjJets = clus_seq.inclusive_jets(ptmin); + + // Constituent rechit fields + std::vector dtRechitsX, dtRechitsY, dtRechitsZ, dtRechitsPhi, dtRechitsEta; + std::vector dtRechitsLayer, dtRechitsSuperLayer, dtRechitsSector, dtRechitsStation, dtRechitsWheel; + + // MDS fields + std::vector clsX, clsY, clsZ, clsPhi, clsEta, clsAvgStation; + std::vector clsSize, clsNstation, clsWheel, clsUniqueChamber, cls_nRB1hit, cls_nRPC, clsBX; + + for (auto const& fjJet : fjJets) { + // skip if the cluster has too few rechits + if (int(fjJet.constituents().size()) < nRechitMin_) + continue; + // get the constituents from fastjet + RecHitRefVector rechits; + for (auto const& constituent : fjJet.constituents()) { + auto index = constituent.user_index(); + if (index >= 0 && static_cast(index) < inputs.size()) { + rechits.push_back(inputs[index]); + } + } + + //Derive cluster properties + int size_z = 0, size_xy = 0, size = 0; + float avg_x_sl2(0.0), avg_y_sl2(0.0), avg_z_sl2(0.0); + float avg_x(0.0), avg_y(0.0), avg_z(0.0); + int nStation = 0; + int totStation = 0; + float avgStation = 0.0; + + std::map station_count_map; + + //fill rechits fields + for (auto const& rechit : rechits) { + LocalPoint recHitLocalPosition = rechit->localPosition(); + auto geoid = rechit->geographicalId(); + + DTChamberId dtdetid = DTChamberId(geoid); + DTLayerId dtlayerid = DTLayerId(geoid); + + unique_ids.insert(dtdetid); + + auto thischamber = dt_geo.chamber(dtdetid); + auto thislayer = dt_geo.layer(dtlayerid); + + if (thischamber) { + if (thislayer) { + GlobalPoint globalPosition = thislayer->toGlobal(recHitLocalPosition); + dtRechitsX.push_back(globalPosition.x()); + dtRechitsY.push_back(globalPosition.y()); + dtRechitsZ.push_back(globalPosition.z()); + dtRechitsPhi.push_back(globalPosition.phi()); + dtRechitsEta.push_back(globalPosition.eta()); + dtRechitsLayer.push_back(dtlayerid.layer()); + dtRechitsSuperLayer.push_back(dtlayerid.superlayer()); + // use xy-coordinates from SL1/SL3 when available + if (dtlayerid.superlayer() == 1 || dtlayerid.superlayer() == 3) { + avg_x += globalPosition.x(); + avg_y += globalPosition.y(); + avg_z += globalPosition.z(); + size_xy++; + } + // use z-coordinates from SL2 when available + else if (dtlayerid.superlayer() == 2) { + avg_x_sl2 += globalPosition.x(); + avg_y_sl2 += globalPosition.y(); + avg_z_sl2 += globalPosition.z(); + size_z++; + } + } else { + GlobalPoint globalPosition = thischamber->toGlobal(recHitLocalPosition); + dtRechitsX.push_back(globalPosition.x()); + dtRechitsY.push_back(globalPosition.y()); + dtRechitsZ.push_back(globalPosition.z()); + dtRechitsPhi.push_back(globalPosition.phi()); + dtRechitsEta.push_back(globalPosition.eta()); + dtRechitsLayer.push_back(0); //default value; + dtRechitsSuperLayer.push_back(0); //default value + avg_x += globalPosition.x(); + avg_y += globalPosition.y(); + avg_z += globalPosition.z(); + } + dtRechitsSector.push_back(dtdetid.sector()); + dtRechitsStation.push_back(dtdetid.station()); + dtRechitsWheel.push_back(dtdetid.wheel()); + size++; + + //compute for cluster fields + station_count_map[dtdetid.station()]++; + } + } + //station statistics + std::map::iterator it; + for (auto const& [station, count] : station_count_map) { + if (count >= nStationThres_) { + nStation++; + avgStation += station * count; + totStation += count; + } + } + if (totStation != 0) { + avgStation = avgStation / totStation; + } + + //for DT correct position, calculate average Z using sl2 and average XY using sl1/3 + if (size_xy > 0 && size_z > 0) { // both SL1/SL3 and SL2 rechits + avg_x = avg_x / size_xy; + avg_y = avg_y / size_xy; + avg_z = avg_z_sl2 / size_z; + } else if (size_xy == 0 && size_z > 0) // only SL2 rechits + { + avg_x = avg_x_sl2 / size_z; + avg_y = avg_y_sl2 / size_z; + avg_z = avg_z_sl2 / size_z; + } else if (size_xy > 0 && size_z == 0) // no SL2 rechits + { + avg_x = avg_x / size_xy; + avg_y = avg_y / size_xy; + avg_z = avg_z / size_xy; + } else // no SL information + { + avg_x = avg_x / size; + avg_y = avg_y / size; + avg_z = avg_z / size; + } + + float i_clsEta = etaFromXYZ(avg_x, avg_y, avg_z); + float i_clsPhi = std::atan2(avg_y, avg_x); + int i_clsWheel = (std::abs(avg_z) < 126.8) ? 0 + : (avg_z > 126.8 && avg_z < 395.4) ? 1 + : (avg_z < -126.8 && avg_z > -395.4) ? -1 + : (avg_z < 0) ? -2 + : 2; + + // RPC hits + std::map bxCounts; // bx of matched RPC hits : counts + int nRB1hit = 0; + for (auto const& rechit : rpchits) { + LocalPoint recHitLocalPosition = rechit.localPosition(); + auto geoid = rechit.geographicalId(); + RPCDetId rpcdetid = RPCDetId(geoid); + auto thischamber = rpc_geo.chamber(rpcdetid); + + // Only matching RB hits + if (rpcdetid.region() != 0) + continue; + if (thischamber) { + GlobalPoint globalPosition = thischamber->toGlobal(recHitLocalPosition); + + //match to RPC hits with dPhi<0.5 and same wheel in DT + if (reco::deltaPhi(globalPosition.phi(), i_clsPhi) < 0.5 && rpcdetid.ring() == i_clsWheel) { + //RB1 hits + if (rpcdetid.station() == 1) + nRB1hit++; + bxCounts[rechit.BunchX()]++; + } + } + } + // find the mode of BX + int modeBX = 0, maxCount = 0, i_cls_nRPC = 0; + for (const auto& [bx, count] : bxCounts) { + i_cls_nRPC += count; + if (count > maxCount) { + modeBX = bx; + maxCount = count; + } + } + + //fill cluster fields + clsSize.push_back(rechits.size()); + // cluster position is the average position of the constituent rechits + clsX.push_back(avg_x); + clsY.push_back(avg_y); + clsZ.push_back(avg_z); + clsEta.push_back(i_clsEta); + clsPhi.push_back(i_clsPhi); + clsBX.push_back(modeBX); + clsNstation.push_back(nStation); + clsAvgStation.push_back(avgStation); + clsWheel.push_back(i_clsWheel); + clsUniqueChamber.push_back(unique_ids.size()); + cls_nRB1hit.push_back(nRB1hit); + cls_nRPC.push_back(i_cls_nRPC); + } + auto dtRechitTab = std::make_unique(dtRechitsX.size(), name_ + "Rechits", false, false); + + dtRechitTab->addColumn("X", dtRechitsX, "dt rechit X"); + dtRechitTab->addColumn("Y", dtRechitsY, "dt rechit Y"); + dtRechitTab->addColumn("Z", dtRechitsZ, "dt rechit Z"); + dtRechitTab->addColumn("Phi", dtRechitsPhi, "dt rechit Phi"); + dtRechitTab->addColumn("Eta", dtRechitsEta, "dt rechit Eta"); + dtRechitTab->addColumn("Layer", dtRechitsLayer, "dt rechit Layer"); + dtRechitTab->addColumn("SuperLayer", dtRechitsSuperLayer, "dt rechit SuperLayer"); + dtRechitTab->addColumn("Sector", dtRechitsSector, "dt rechit sector"); + dtRechitTab->addColumn("Station", dtRechitsStation, "dt rechit station"); + dtRechitTab->addColumn("Wheel", dtRechitsWheel, "dt rechit nstrips"); + + iEvent.put(std::move(dtRechitTab), name_ + "Rechits"); + + auto clsTab = std::make_unique(clsSize.size(), name_, false, false); + + clsTab->addColumn("size", clsSize, "cluster Size"); + clsTab->addColumn("x", clsX, "cluster X"); + clsTab->addColumn("y", clsY, "cluster Y"); + clsTab->addColumn("z", clsZ, "cluster Z"); + clsTab->addColumn("phi", clsPhi, "cluster Phi"); + clsTab->addColumn("eta", clsEta, "cluster Eta"); + clsTab->addColumn("bx", clsBX, "cluster BX"); + clsTab->addColumn("wheel", clsWheel, "cluster wheel"); + clsTab->addColumn("nStation", clsNstation, "cluster nStation"); + clsTab->addColumn("uniqueChamber", clsUniqueChamber, "cluster unique chambers"); + clsTab->addColumn("avgStation", clsAvgStation, "cluster AvgStation"); + clsTab->addColumn("nRPC", cls_nRPC, "cluster nRPC"); + clsTab->addColumn("nRB1hit", cls_nRB1hit, "cluster nRB1hit"); + + iEvent.put(std::move(clsTab), name_); +} + +#include "FWCore/Framework/interface/MakerMacros.h" +DEFINE_FWK_MODULE(dtMDSshowerTableProducer); diff --git a/PhysicsTools/NanoAOD/python/autoNANO.py b/PhysicsTools/NanoAOD/python/autoNANO.py index e39bcb67d91b2..4cb061ee5dff7 100644 --- a/PhysicsTools/NanoAOD/python/autoNANO.py +++ b/PhysicsTools/NanoAOD/python/autoNANO.py @@ -99,6 +99,9 @@ def expandNanoMapping(seqList, mapping, key): # Custom BTV Nano for SF measurements or tagger training 'BTV': {'sequence': '@PHYS', 'customize': '@PHYS+PhysicsTools/NanoAOD/custom_btv_cff.BTVCustomNanoAOD'}, + # Custom EXO Nano for EXO analyses + 'EXO': {'sequence': '@PHYS', + 'customize': '@PHYS+PhysicsTools/NanoAOD/custom_exo_cff.add_exonanoTables'}, # NANOGEN (from LHE/GEN/AOD) 'GEN': {'sequence': 'PhysicsTools/NanoAOD/nanogen_cff.nanogenSequence', 'customize': 'PhysicsTools/NanoAOD/nanogen_cff.customizeNanoGEN'}, diff --git a/PhysicsTools/NanoAOD/python/custom_displacedtau_cff.py b/PhysicsTools/NanoAOD/python/custom_displacedtau_cff.py new file mode 100644 index 0000000000000..7318d933da82a --- /dev/null +++ b/PhysicsTools/NanoAOD/python/custom_displacedtau_cff.py @@ -0,0 +1,157 @@ +import FWCore.ParameterSet.Config as cms +from PhysicsTools.NanoAOD.common_cff import * +from PhysicsTools.NanoAOD.genparticles_cff import * +from PhysicsTools.NanoAOD.taus_cff import * +from PhysicsTools.NanoAOD.muons_cff import * +from PhysicsTools.NanoAOD.jetsAK4_CHS_cff import * +from PhysicsTools.NanoAOD.jetsAK4_Puppi_cff import * +import os + +def add_displacedtauCHSTables(process, isMC): + + process.linkedObjectsCHS = cms.EDProducer("PATObjectCrossLinker", + jets=cms.InputTag("finalJets"), + muons=cms.InputTag("finalMuons"), + electrons=cms.InputTag("finalElectrons"), + lowPtElectrons=cms.InputTag("finalLowPtElectrons"), + taus=cms.InputTag("finalTaus"), + boostedTaus=cms.InputTag("finalBoostedTaus"), + photons=cms.InputTag("finalPhotons"), + vertices=cms.InputTag("slimmedSecondaryVertices") + ) + + del process.updatedJetsWithUserData.userFloats.leadTrackPt + del process.updatedJetsWithUserData.userFloats.leptonPtRelv0 + del process.updatedJetsWithUserData.userFloats.leptonPtRelInvv0 + del process.updatedJetsWithUserData.userFloats.leptonDeltaR + del process.updatedJetsWithUserData.userFloats.vtxPt + del process.updatedJetsWithUserData.userFloats.vtxMass + del process.updatedJetsWithUserData.userFloats.vtx3dL + del process.updatedJetsWithUserData.userFloats.vtx3deL + del process.updatedJetsWithUserData.userFloats.ptD + del process.updatedJetsWithUserData.userFloats.qgl + del process.updatedJetsWithUserData.userFloats.puIdNanoDisc + del process.updatedJetsWithUserData.userFloats.muonSubtrRawPt + del process.updatedJetsWithUserData.userFloats.muonSubtrRawEta + del process.updatedJetsWithUserData.userFloats.muonSubtrRawPhi + + del process.updatedJetsWithUserData.userInts.vtxNtrk + del process.updatedJetsWithUserData.userInts.leptonPdgId + del process.updatedJetsWithUserData.userInts.puIdNanoId + + print(process.updatedJetsWithUserData.dumpPython()) + + # + # Customize jetTable + # + process.jetTable.src = cms.InputTag("linkedObjectsCHS","jets") + process.jetTable.name = "JetCHS" # Change collection name from "Jet" ->" JetCHS" + + # + # Remove these tagger branches since for CHS, we just want to store ParticleNet. + # Remove also branches related to object linking. It is only done for AK4 Puppi. + # + for varName in process.jetTable.variables.parameterNames_(): + if "btagDeepFlav" in varName or "btagRobustParT" in varName or "btagUParT" in varName: + delattr(process.jetTable.variables, varName) + if "UParTAK4Reg" in varName: + delattr(process.jetTable.variables, varName) + if "svIdx" in varName or "muonIdx" in varName or "electronIdx" in varName: + delattr(process.jetTable.variables, varName) + if "nSVs" in varName or "nElectrons" in varName or "nMuons" in varName: + delattr(process.jetTable.variables, varName) + + del process.jetTable.variables.muonSubtrFactor + del process.jetTable.variables.muonSubtrDeltaEta + del process.jetTable.variables.muonSubtrDeltaPhi + del process.jetTable.variables.qgl + del process.jetTable.variables.puIdDisc + del process.jetTable.variables.puId + + del process.jetTable.externalVariables.bRegCorr + del process.jetTable.externalVariables.bRegRes + del process.jetTable.externalVariables.cRegCorr + del process.jetTable.externalVariables.cRegRes + + process.jetUserDataTask = cms.Task( + process.jercVars, + ) + process.nanoTableTaskCommon.add(process.jetUserDataTask) + + + + + ## displaced tau part + file = "RecoTauTag/TrainingFiles/DisplacedTauId/particlenet_v1_a27159734e304ea4b7f9e0042baa9e22.pb" + process.options = cms.untracked.PSet( + numberOfThreads = cms.untracked.uint32(4), # Global thread count + numberOfStreams = cms.untracked.uint32(4), # Should match threads + ) + + process.disTauTag = cms.EDProducer( + "DisTauTag", + graphPath = cms.FileInPath(file), + jets = cms.InputTag("linkedObjectsCHS","jets"), + pfCandidates = cms.InputTag('packedPFCandidates'), + save_inputs = cms.bool(False), + batchSize = cms.uint32(8), + #numThreads = cms.untracked.uint32(4) + allowUnscheduled = cms.untracked.bool(True) + ) + + process.jetImpactParameters = cms.EDProducer( + "JetImpactParameters", + jets = cms.InputTag("linkedObjectsCHS","jets"), + pfCandidates = cms.InputTag('packedPFCandidates'), + deltaRMax = cms.double(0.4) + ) + + + + d_disTauTagVars = { + "disTauTag_score0": ExtVar("disTauTag:score0" , float, doc = "Score 0"), + "disTauTag_score1": ExtVar("disTauTag:score1" , float, doc = "Score 1"), + "dxy": ExtVar("jetImpactParameters:jetDxy", float, doc = "leadingPtPFCand_dxy which is within dR=0.4 and charged/hasTrackDetails"), + "dz": ExtVar("jetImpactParameters:jetDz", float, doc = "leadingPtPFCand_dz which is within dR=0.4 and charged/hasTrackDetails"), + "dxyerror": ExtVar("jetImpactParameters:jetDxyError", float, doc = "leadingPtPFCand_dxyerror which is within dR=0.4 and charged/hasTrackDetails"), + "dzerror": ExtVar("jetImpactParameters:jetDzError", float, doc = "leadingPtPFCand_dzerror which is within dR=0.4 and charged/hasTrackDetails"), + "charge": ExtVar("jetImpactParameters:jetCharge", float, doc = "leadingPtPFCand_charge which is within dR=0.4 and charged/hasTrackDetails"), + } + + #if useCHSJets: + process.jetTable.externalVariables = process.jetTable.externalVariables.clone(**d_disTauTagVars) + ## for puppi jets, use this! + #else: + # process.jetPuppiTable.externalVariables = process.jetPuppiTable.externalVariables.clone(**d_disTauTagVars) + + process.jetTask = cms.Task( + process.jetCorrFactorsNano, + process.updatedJets, + process.linkedObjectsCHS, + process.updatedJetsWithUserData, + process.finalJets, + process.disTauTag, + process.jetImpactParameters + + ) + + process.nanoTableTaskCommon.add(process.jetTask) + + process.jetTablesTask = cms.Task( + process.jetTable + ) + process.nanoTableTaskCommon.add(process.jetTablesTask) + + # + # Only for MC + # + if isMC: + process.jetCHSMCTable = process.jetMCTable.clone( + src = process.jetTable.src, + name = process.jetTable.name + ) + process.jetMCTask.add(process.jetCHSMCTable) + + return process + + diff --git a/PhysicsTools/NanoAOD/python/custom_exo_cff.py b/PhysicsTools/NanoAOD/python/custom_exo_cff.py new file mode 100644 index 0000000000000..9cedea34d92a1 --- /dev/null +++ b/PhysicsTools/NanoAOD/python/custom_exo_cff.py @@ -0,0 +1,315 @@ +import FWCore.ParameterSet.Config as cms +from PhysicsTools.NanoAOD.common_cff import * + +# displaced tau +from PhysicsTools.NanoAOD.custom_displacedtau_cff import * + +unpackedTracksAndVertices = cms.EDProducer('PATTrackAndVertexUnpacker', + slimmedVertices = cms.InputTag("offlineSlimmedPrimaryVertices"), + slimmedSecondaryVertices = cms.InputTag("slimmedSecondaryVertices"), + additionalTracks= cms.InputTag("lostTracks"), + packedCandidates = cms.InputTag("packedPFCandidates")) + +# ref: https://github.com/cms-sw/cmssw/blob/2bed69b1658e4deeaef914e462741919e9183be3/RecoVertex/AdaptiveVertexFinder/plugins/InclusiveVertexFinder.h#L48 + +displacedInclusiveVertexFinder = cms.EDProducer("InclusiveVertexFinder", + beamSpot = cms.InputTag("offlineBeamSpot"), + primaryVertices = cms.InputTag("offlineSlimmedPrimaryVertices"), + tracks = cms.InputTag("unpackedTracksAndVertices"), + minHits = cms.uint32(6), # 8 + maximumLongitudinalImpactParameter = cms.double(20), # 0.3 + minPt = cms.double(0.8), # 0.8 + maxNTracks = cms.uint32(100), # 30 + + clusterizer = cms.PSet( + seedMax3DIPSignificance = cms.double(9999.), # 9999. + seedMax3DIPValue = cms.double(9999.), # 9999. + seedMin3DIPSignificance = cms.double(1.2), # 1.2 + seedMin3DIPValue = cms.double(0.005), # 0.005 + clusterMaxDistance = cms.double(0.4), # 0.05 + clusterMaxSignificance = cms.double(4.5), # 4.5 + distanceRatio = cms.double(20), # 20 + clusterMinAngleCosine = cms.double(0.5), # 0.5 + ), + + vertexMinAngleCosine = cms.double(0.95), # 0.95 + vertexMinDLen2DSig = cms.double(2.5), # 2.5 + vertexMinDLenSig = cms.double(0.5), # 0.5 + fitterSigmacut = cms.double(3), # 3 + fitterTini = cms.double(256), # 256 + fitterRatio = cms.double(0.25), # 0.25 + useDirectVertexFitter = cms.bool(True), # True + useVertexReco = cms.bool(True), # True + vertexReco = cms.PSet( + finder = cms.string('avr'), + primcut = cms.double(1.0), # 1.0 + seccut = cms.double(3), # 3 + smoothing = cms.bool(True)) # True + ) + +displacedVertexMerger = cms.EDProducer("VertexMerger", + secondaryVertices = cms.InputTag("displacedInclusiveVertexFinder"), + maxFraction = cms.double(0.7), + minSignificance = cms.double(2)) + +# ref: https://github.com/cms-sw/cmssw/blob/2bed69b1658e4deeaef914e462741919e9183be3/RecoVertex/AdaptiveVertexFinder/plugins/VertexArbitrators.cc#L54 + +displacedTrackVertexArbitrator = cms.EDProducer("TrackVertexArbitrator", + beamSpot = cms.InputTag("offlineBeamSpot"), + primaryVertices = cms.InputTag("offlineSlimmedPrimaryVertices"), + tracks = cms.InputTag("unpackedTracksAndVertices"), + secondaryVertices = cms.InputTag("displacedVertexMerger"), + dLenFraction = cms.double(0.333), # 0.333 + dRCut = cms.double(1), # 0.4 + distCut = cms.double(0.1), # 0.04 + sigCut = cms.double(5), # 5 + fitterSigmacut = cms.double(3), # 3 + fitterTini = cms.double(256), # 256 + fitterRatio = cms.double(0.25), # 0.25 + trackMinLayers = cms.int32(4), # 4 + trackMinPt = cms.double(.4), # 0.4 + trackMinPixels = cms.int32(0) # 1 +) + +displacedInclusiveSecondaryVertices = displacedVertexMerger.clone() +displacedInclusiveSecondaryVertices.secondaryVertices = cms.InputTag("displacedTrackVertexArbitrator") +displacedInclusiveSecondaryVertices.maxFraction = 0.2 +displacedInclusiveSecondaryVertices.minSignificance = 10 + +displacedInclusiveVertexing = cms.Sequence(unpackedTracksAndVertices * displacedInclusiveVertexFinder * displacedVertexMerger * displacedTrackVertexArbitrator * displacedInclusiveSecondaryVertices) + +# MDSnano tables +from RecoMuon.MuonRechitClusterProducer.cscRechitClusterProducer_cfi import cscRechitClusterProducer +from RecoMuon.MuonRechitClusterProducer.dtRechitClusterProducer_cfi import dtRechitClusterProducer + +from PhysicsTools.NanoAOD.cscMDSshowerTable_cfi import cscMDSshowerTable +from PhysicsTools.NanoAOD.dtMDSshowerTable_cfi import dtMDSshowerTable + +cscMDSshowerTable = cscMDSshowerTable.clone( + name = cms.string("cscMDSCluster"), + recHitLabel = cms.InputTag("csc2DRecHits"), + segmentLabel = cms.InputTag("dt4DSegments"), + rpcLabel = cms.InputTag("rpcRecHits") +) + +dtMDSshowerTable = dtMDSshowerTable.clone( + name = cms.string("dtMDSCluster"), + recHitLabel = cms.InputTag("dt1DRecHits"), + rpcLabel = cms.InputTag("rpcRecHits") +) + +#DSA muon tables +from PhysicsTools.NanoAOD.simpleTrackFlatTableProducer_cfi import simpleTrackFlatTableProducer +DSAmuonsSimpleTable = simpleTrackFlatTableProducer.clone( + src="displacedStandAloneMuons", + name="DSAMuon", + doc ="Displaced standalone muon tracks", + singleton=False, + extension=False, + variables=cms.PSet( + pt = Var("pt", float, doc="pt of DSA muon"), + ptErr = Var("ptError", float, doc="ptErr of DSA muon"), + eta = Var("eta", float, doc="eta of DSA muon"), + etaErr = Var("etaError", float, doc="etaErr of DSA muon"), + phi = Var("phi", float, doc="phi of DSA muon"), + phiErr = Var("phiError", float, doc="phiErr of DSA muon"), + charge = Var("charge", float, doc="charge of DSA muon"), + dxy = Var("dxy", float, doc="dxy of DSA muon"), + dz = Var("dz", float, doc="dz of DSA muon"), + vx = Var("vx", float, doc="vx of DSA muon"), + vy = Var("vy", float, doc="vy of DSA muon"), + vz = Var("vz", float, doc="vz of DSA muon"), + chi2 = Var("chi2", float, doc="chi2 of DSA muon"), + ndof = Var("ndof", float, doc="ndof of DSA muon"), + normChi2 = Var("normalizedChi2", float, doc="normChi2 of DSA muon"), + ) +) + +DSAmuonsTable = cms.EDProducer("DSAMuonTableProducer", + name=cms.string("DSAMuon"), + dsaMuons=cms.InputTag("displacedStandAloneMuons"), + muons=cms.InputTag("linkedObjects","muons"), + primaryVertex = cms.InputTag("offlineSlimmedPrimaryVertices"), + beamspot = cms.InputTag("offlineBeamSpot") +) + +DSAmuonVertexTable = cms.EDProducer("MuonVertexTableProducer", + dsaMuons=cms.InputTag("displacedStandAloneMuons"), + patMuons=cms.InputTag("linkedObjects","muons"), + beamspot=cms.InputTag("offlineBeamSpot"), + generalTracks=cms.InputTag("generalTracks"), + primaryVertex=cms.InputTag("offlineSlimmedPrimaryVertices") +) + +from PhysicsTools.NanoAOD.simplePATMuonFlatTableProducer_cfi import simplePATMuonFlatTableProducer +PATmuonExtendedSimpleTable = simplePATMuonFlatTableProducer.clone( + src=cms.InputTag("linkedObjects","muons"), + name="Muon", + singleton=False, + extension=True, + variables=cms.PSet( + innerTrackValidFraction = Var("? innerTrack().isNonnull() && innerTrack().isAvailable() ? innerTrack().validFraction() : -1", float, doc=""), + globalTrackNormalizedChi2 = Var("? globalTrack().isNonnull() ? globalTrack().normalizedChi2() : -1", float, doc=""), + CQChi2Position = Var("combinedQuality().chi2LocalPosition", float, doc=""), + CQTrackKink = Var("combinedQuality().trkKink", float, doc=""), + numberOfMatchedStation = Var("numberOfMatchedStations", float, doc=""), + numberOfValidPixelHits = Var("? innerTrack().isNonnull() && innerTrack().isAvailable() ? innerTrack().hitPattern().numberOfValidPixelHits() : 0", float, doc=""), + numberOfValidTrackerHits = Var("? innerTrack().isNonnull() && innerTrack().isAvailable() ? innerTrack().hitPattern().numberOfValidTrackerHits() : 0", float, doc=""), + trackerLayersWithMeasurement = Var("? innerTrack().isNonnull() && innerTrack().isAvailable() ? innerTrack().hitPattern().trackerLayersWithMeasurement() : 0", float, doc=""), + numberInnerHits = Var("? globalTrack().isNonnull() ? globalTrack().hitPattern().numberOfValidMuonHits() : ? outerTrack().isNonnull() ? outerTrack().hitPattern().numberOfValidMuonHits() : 0", float, doc=""), + innerVx = Var("? innerTrack().isNonnull() && innerTrack().isAvailable() ? innerTrack().vx() : -1", float, doc=""), + innerVy = Var("? innerTrack().isNonnull() && innerTrack().isAvailable() ? innerTrack().vy() : -1", float, doc=""), + innerVz = Var("? innerTrack().isNonnull() && innerTrack().isAvailable() ? innerTrack().vz() : -1", float, doc=""), + innerPt = Var("? innerTrack().isNonnull() && innerTrack().isAvailable() ? innerTrack().pt() : -1", float, doc=""), + innerEta = Var("? innerTrack().isNonnull() && innerTrack().isAvailable() ? innerTrack().eta() : -5", float, doc=""), + innerPhi = Var("? innerTrack().isNonnull() && innerTrack().isAvailable() ? innerTrack().phi() : -5", float, doc=""), + ) +) + +PATmuonExtendedTable = cms.EDProducer("MuonExtendedTableProducer", + name=cms.string("Muon"), + rho=cms.InputTag("fixedGridRhoFastjetAll"), + muons=cms.InputTag("linkedObjects","muons"), + primaryVertex=cms.InputTag("offlineSlimmedPrimaryVertices"), + beamspot=cms.InputTag("offlineBeamSpot"), + jets=cms.InputTag("linkedObjects","jets"), + jetsFat=cms.InputTag("slimmedJetsAK8"), + jetsSub=cms.InputTag("slimmedJetsAK8PFPuppiSoftDropPacked", "SubJets") +) + +electronVertexTable = cms.EDProducer("ElectronVertexTableProducer", + electrons=cms.InputTag("linkedObjects","electrons"), + beamspot=cms.InputTag("offlineBeamSpot"), + primaryVertex=cms.InputTag("offlineSlimmedPrimaryVertices") +) + +electronExtendedTable = cms.EDProducer("ElectronExtendedTableProducer", + name=cms.string("Electron"), + rho=cms.InputTag("fixedGridRhoFastjetAll"), + electrons=cms.InputTag("linkedObjects","electrons"), + primaryVertex=cms.InputTag("offlineSlimmedPrimaryVertices"), + jets=cms.InputTag("linkedObjects","jets"), + jetsFat=cms.InputTag("slimmedJetsAK8"), + jetsSub=cms.InputTag("slimmedJetsAK8PFPuppiSoftDropPacked", "SubJets") +) + +dispJetTable = cms.EDProducer("DispJetTableProducer", + electrons=cms.InputTag("linkedObjects","electrons"), + muons=cms.InputTag("linkedObjects","muons"), + primaryVertex = cms.InputTag("offlineSlimmedPrimaryVertices"), + secondaryVertex = cms.InputTag("displacedInclusiveSecondaryVertices") +) + +def add_dispJetTables(process): + # process.load('PhysicsTools.displacedInclusiveVertexing_cff') + process.dispJetTable = dispJetTable + process.unpackedTracksAndVertices = unpackedTracksAndVertices + process.displacedInclusiveVertexFinder = displacedInclusiveVertexFinder + process.displacedVertexMerger = displacedVertexMerger + process.displacedTrackVertexArbitrator = displacedTrackVertexArbitrator + process.displacedInclusiveSecondaryVertices = displacedInclusiveSecondaryVertices + process.dispJetTable = dispJetTable + process.dispJetTask = cms.Task(process.unpackedTracksAndVertices) + process.dispJetTask.add(process.displacedInclusiveVertexFinder) + process.dispJetTask.add(process.displacedVertexMerger) + process.dispJetTask.add(process.displacedTrackVertexArbitrator) + process.dispJetTask.add(process.displacedInclusiveSecondaryVertices) + process.dispJetTask.add(process.dispJetTable) + process.nanoTableTaskCommon.add(process.dispJetTask) + + return process + +def add_mdsTables(process): + process.ca4CSCrechitClusters = cscRechitClusterProducer + process.ca4DTrechitClusters = dtRechitClusterProducer + process.cscMDSshowerTable = cscMDSshowerTable + process.dtMDSshowerTable = dtMDSshowerTable + + process.MDSTask = cms.Task(process.ca4CSCrechitClusters) + process.MDSTask.add(process.ca4DTrechitClusters) + process.MDSTask.add(process.cscMDSshowerTable) + process.MDSTask.add(process.dtMDSshowerTable) + + process.nanoTableTaskCommon.add(process.MDSTask) + + return process + +def add_dsamuonTables(process): + process.load("TrackingTools.TransientTrack.TransientTrackBuilder_cfi") + process.load('TrackPropagation.SteppingHelixPropagator.SteppingHelixPropagatorAny_cfi') + + process.DSAmuonsSimpleTable = DSAmuonsSimpleTable + process.DSAmuonsTable = DSAmuonsTable + process.DSAmuonVertexTable = DSAmuonVertexTable + process.PATmuonExtendedSimpleTable = PATmuonExtendedSimpleTable + process.PATmuonExtendedTable = PATmuonExtendedTable + + process.dsamuonTask = cms.Task( + process.DSAmuonsSimpleTable, + process.DSAmuonsTable + ) + process.dsamuonVertexTask = cms.Task(process.DSAmuonVertexTable) + process.patmuonTask = cms.Task( + process.PATmuonExtendedSimpleTable, + process.PATmuonExtendedTable + ) + + process.nanoTableTaskCommon.add(process.dsamuonTask) + process.nanoTableTaskCommon.add(process.dsamuonVertexTask) + process.nanoTableTaskCommon.add(process.patmuonTask) + + return process + +def add_electronVertexTables(process): + + process.load("TrackingTools.TransientTrack.TransientTrackBuilder_cfi") + process.load('TrackPropagation.SteppingHelixPropagator.SteppingHelixPropagatorAny_cfi') + + process.electronVertexTable = electronVertexTable + process.electronVertexTask = cms.Task(process.electronVertexTable) + process.electronExtendedTable = electronExtendedTable + process.electronExtendedTask = cms.Task(process.electronExtendedTable) + + process.nanoTableTaskCommon.add(process.electronVertexTask) + + return process + +def add_muonExtendedTable(process): + process.load("TrackingTools.TransientTrack.TransientTrackBuilder_cfi") + process.load('TrackPropagation.SteppingHelixPropagator.SteppingHelixPropagatorAny_cfi') + + process.PATmuonExtendedTable = PATmuonExtendedTable + + process.muonExtendedTask = cms.Task(process.PATmuonExtendedTable) + + process.nanoTableTaskCommon.add(process.muonExtendedTask) + + return process + +def update_genParticleTable(process): + + process.genParticleTable.variables.vx = Var("vx",float, doc = "gen particle production vertex x coordinate (cm)", precision=8) + process.genParticleTable.variables.vy = Var("vy",float, doc = "gen particle production vertex y coordinate (cm)", precision=8) + process.genParticleTable.variables.vz = Var("vz",float, doc = "gen particle production vertex z coordinate (cm)", precision=8) + + process.genParticleTable.variables.px = Var("px",float, doc = "gen particle momentum x coordinate", precision=8) + process.genParticleTable.variables.py = Var("py",float, doc = "gen particle momentum y coordinate", precision=8) + process.genParticleTable.variables.pz = Var("pz",float, doc = "gen particle momentum z coordinate", precision=8) + + return process + +def add_exonanoTables(process): + + process = add_mdsTables(process) + process = add_dsamuonTables(process) + process = add_electronVertexTables(process) + process = add_dispJetTables(process) + + isMC = hasattr(process, "nanoSequenceMC") and process.schedule.contains(process.nanoSequenceMC) + + process = add_displacedtauCHSTables(process, isMC) + + if isMC: + process = update_genParticleTable(process) + + return process diff --git a/PhysicsTools/NanoAOD/test/test-exoNano.sh b/PhysicsTools/NanoAOD/test/test-exoNano.sh new file mode 100755 index 0000000000000..eba5f9bb33a33 --- /dev/null +++ b/PhysicsTools/NanoAOD/test/test-exoNano.sh @@ -0,0 +1 @@ +cmsDriver.py exoNanoMC --mc --eventcontent NANOAODSIM --datatier NANOAODSIM --conditions auto:phase1_2025_realistic --step PAT,NANO:@EXO --nThreads 4 --era Run3,Run3_2025 --filein /store/mc/RunIII2024Summer24DRPremix/TTtoLNu2Q_TuneCP5_13p6TeV_powheg-pythia8/AODSIM/140X_mcRun3_2024_realistic_v26-v2/100016/a55a360c-a746-4910-b1af-96466f009717.root -n 100 \ No newline at end of file From 4f9e84a10019fb16e22733e82145b017db4e95a9 Mon Sep 17 00:00:00 2001 From: Zhenbin Wu Date: Thu, 5 Feb 2026 16:10:45 -0600 Subject: [PATCH 21/61] Remove unused variable --- L1Trigger/Phase2L1GMT/src/L1TPhase2GMTBarrelStubProcessor.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/L1Trigger/Phase2L1GMT/src/L1TPhase2GMTBarrelStubProcessor.cc b/L1Trigger/Phase2L1GMT/src/L1TPhase2GMTBarrelStubProcessor.cc index 4fb7dc83402ce..b8743c7e58f5e 100644 --- a/L1Trigger/Phase2L1GMT/src/L1TPhase2GMTBarrelStubProcessor.cc +++ b/L1Trigger/Phase2L1GMT/src/L1TPhase2GMTBarrelStubProcessor.cc @@ -149,7 +149,6 @@ l1t::MuonStubCollection L1TPhase2GMTBarrelStubProcessor::makeStubs(const L1Phase sN = sN | (wr1 << 30); sN = sN | (wq << 51); sN = sN | (wr2 << 55); - unsigned int index = (station - 1) * 4 + phiDigi.index(); os << std::setw(0) << std::dec << sector << " " << wheel << " " << station << " "; os << std::uppercase << std::setfill('0') << std::setw(16) << std::hex << uint64_t(sN) << " "; } From 91ee1bcd481b76b77848d5f4b45c530da19196f7 Mon Sep 17 00:00:00 2001 From: Lovisa Rygaard <62760237+kerstinlovisa@users.noreply.github.com> Date: Thu, 19 Feb 2026 10:48:05 +0100 Subject: [PATCH 22/61] Update PhysicsTools/NanoAOD/python/custom_displacedtau_cff.py Co-authored-by: Matti Kortelainen --- PhysicsTools/NanoAOD/python/custom_displacedtau_cff.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PhysicsTools/NanoAOD/python/custom_displacedtau_cff.py b/PhysicsTools/NanoAOD/python/custom_displacedtau_cff.py index 7318d933da82a..79679c6839a94 100644 --- a/PhysicsTools/NanoAOD/python/custom_displacedtau_cff.py +++ b/PhysicsTools/NanoAOD/python/custom_displacedtau_cff.py @@ -82,7 +82,7 @@ def add_displacedtauCHSTables(process, isMC): ## displaced tau part - file = "RecoTauTag/TrainingFiles/DisplacedTauId/particlenet_v1_a27159734e304ea4b7f9e0042baa9e22.pb" + file = "RecoTauTag/TrainingFiles/data/DisplacedTauId/particlenet_v1_a27159734e304ea4b7f9e0042baa9e22.pb" process.options = cms.untracked.PSet( numberOfThreads = cms.untracked.uint32(4), # Global thread count numberOfStreams = cms.untracked.uint32(4), # Should match threads From 9953a84cceaa1b663f0958a181736fc421195db9 Mon Sep 17 00:00:00 2001 From: Lovisa Date: Fri, 20 Feb 2026 10:25:06 +0100 Subject: [PATCH 23/61] code-format correction --- PhysicsTools/NanoAOD/plugins/DisTauTag.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/PhysicsTools/NanoAOD/plugins/DisTauTag.cc b/PhysicsTools/NanoAOD/plugins/DisTauTag.cc index f8a27692b6b96..96136acea215c 100644 --- a/PhysicsTools/NanoAOD/plugins/DisTauTag.cc +++ b/PhysicsTools/NanoAOD/plugins/DisTauTag.cc @@ -285,7 +285,9 @@ void DisTauTag::produce(edm::StreamID, edm::Event& event, const edm::EventSetup& // Running inference on batch std::vector outputs; - { tensorflow::run(session_, {{"input_1", input_1}, {"input_2", input_2}}, {"final_out"}, &outputs); } + { + tensorflow::run(session_, {{"input_1", input_1}, {"input_2", input_2}}, {"final_out"}, &outputs); + } // Storing results for (size_t batch_jet_idx = 0; batch_jet_idx < current_batch_size; ++batch_jet_idx) { From fdf8e4313401c3dc78fe1af03e16d7a44e476a9a Mon Sep 17 00:00:00 2001 From: Zhenbin Wu Date: Fri, 20 Feb 2026 16:01:06 -0600 Subject: [PATCH 24/61] fixing typo in chi2 cutoff for track conversion --- .../interface/PreTrackMatchedMuon.h | 22 ++++++------------- .../Phase2L1GMT/interface/TrackConverter.h | 2 +- .../plugins/Phase2L1TGMTStubProducer.cc | 16 +++++++------- 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/L1Trigger/Phase2L1GMT/interface/PreTrackMatchedMuon.h b/L1Trigger/Phase2L1GMT/interface/PreTrackMatchedMuon.h index 2b6b5454602c9..31964a33bd7f1 100644 --- a/L1Trigger/Phase2L1GMT/interface/PreTrackMatchedMuon.h +++ b/L1Trigger/Phase2L1GMT/interface/PreTrackMatchedMuon.h @@ -57,13 +57,13 @@ namespace Phase2L1GMT { const uint beta() const { return beta_; } bool isGlobalMuon() const { return isGlobal_; } - const int quality0() const { return quality0_; } - const int quality1() const { return quality1_; } - const int quality2() const { return quality2_; } - const int quality3() const { return quality3_; } - const int quality4() const { return quality4_; } - const int quality() const { return quality_; } - const int offline_pt() const { return offline_pt_; } + const uint quality0() const { return quality0_; } + const uint quality1() const { return quality1_; } + const uint quality2() const { return quality2_; } + const uint quality3() const { return quality3_; } + const uint quality4() const { return quality4_; } + const uint quality() const { return quality_; } + const float offline_pt() const { return offline_pt_; } const float offline_eta() const { return offline_eta_; } const float offline_phi() const { return offline_phi_; } @@ -128,14 +128,6 @@ namespace Phase2L1GMT { const edm::Ptr> trkPtr() const { return trkPtr_; } - // void print() const { - // LogDebug("PreTrackMatchedMuon") << "preconstructed muon : charge=" << charge_ << " pt=" << offline_pt_ << "," - // << pt_ << " eta=" << offline_eta_ << "," << eta_ << " phi=" << offline_phi_ << "," - // << phi_ << " z0=" << z0_ << " d0=" << d0_ << " quality=" << quality_ - // << " isGlobal=" << isGlobal_ << " valid=" << valid_ << " stubs: " << stubID0_ - // << " " << stubID1_ << " " << stubID2_ << " " << stubID3_ << " " << stubID4_; - //} - uint64_t lsb() const { wordtype w = 0; int bstart = 0; diff --git a/L1Trigger/Phase2L1GMT/interface/TrackConverter.h b/L1Trigger/Phase2L1GMT/interface/TrackConverter.h index b6862e31dbbed..8f3f3f90242fd 100644 --- a/L1Trigger/Phase2L1GMT/interface/TrackConverter.h +++ b/L1Trigger/Phase2L1GMT/interface/TrackConverter.h @@ -21,7 +21,7 @@ namespace Phase2L1GMT { uint generateQuality(const edm::Ptr >& track) { uint chi2Cut = 0xf; - if ((track->getChi2RPhiBits() <= chi2Cut) && (track->getChi2RPhiBits() <= chi2Cut)) + if ((track->getChi2RZBits() <= chi2Cut) && (track->getChi2RPhiBits() <= chi2Cut)) return 1; else return 0; diff --git a/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc b/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc index 3c45cc004435a..991f4f49482ca 100644 --- a/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc +++ b/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc @@ -163,23 +163,23 @@ void Phase2L1TGMTStubProducer::fillDescriptions(edm::ConfigurationDescriptions& psd0.add("phiLSB", 0.02453124992); psd0.add("phiBDivider", 16); psd0.add("etaLSB", 0.024586688); - psd0.add>("eta_1", - { - -46, -45, -43, -41, -39, -37, -35, -30, -28, -26, -23, -20, -18, - -15, -9, -6, -3, -1, 1, 3, 6, 9, 15, 18, 20, 23, - 26, 28, 30, 35, 37, 39, 41, 43, 45, 46, //1503 I think the large entries at the end here were a mistake - }); + psd0.add>( + "eta_1", + { + -46, -45, -43, -41, -39, -37, -35, -30, -28, -26, -23, -20, -18, -15, -9, -6, -3, -1, + 1, 3, 6, 9, 15, 18, 20, 23, 26, 28, 30, 35, 37, 39, 41, 43, 45, 46 + }); psd0.add>( "eta_2", { -41, -39, -38, -36, -34, -32, -30, -26, -24, -22, -20, -18, -15, -13, -8, -5, -3, -1, - 1, 3, 5, 8, 13, 15, 18, 20, 22, 24, 26, 30, 32, 34, 36, 38, 39, 41, //1334 + 1, 3, 5, 8, 13, 15, 18, 20, 22, 24, 26, 30, 32, 34, 36, 38, 39, 41 }); psd0.add>( "eta_3", { -35, -34, -32, -31, -29, -27, -26, -22, -20, -19, -17, -15, -13, -11, -6, -4, -2, -1, - 1, 2, 4, 6, 11, 13, 15, 17, 19, 20, 22, 26, 27, 29, 31, 32, 34, 35, //1148 + 1, 2, 4, 6, 11, 13, 15, 17, 19, 20, 22, 26, 27, 29, 31, 32, 34, 35 }); psd0.add>("coarseEta_1", { From 0140ca61df9f02bc2b32413330730a584c28e769 Mon Sep 17 00:00:00 2001 From: Zhenbin Wu Date: Sun, 22 Feb 2026 18:15:25 -0600 Subject: [PATCH 25/61] Apply code format patch --- .../plugins/Phase2L1TGMTStubProducer.cc | 27 +++++++------------ L1Trigger/Phase2L1GMT/src/TPSAlgorithm.cc | 21 +++++---------- 2 files changed, 16 insertions(+), 32 deletions(-) diff --git a/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc b/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc index 991f4f49482ca..5d3c75f0a2c46 100644 --- a/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc +++ b/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc @@ -163,24 +163,15 @@ void Phase2L1TGMTStubProducer::fillDescriptions(edm::ConfigurationDescriptions& psd0.add("phiLSB", 0.02453124992); psd0.add("phiBDivider", 16); psd0.add("etaLSB", 0.024586688); - psd0.add>( - "eta_1", - { - -46, -45, -43, -41, -39, -37, -35, -30, -28, -26, -23, -20, -18, -15, -9, -6, -3, -1, - 1, 3, 6, 9, 15, 18, 20, 23, 26, 28, 30, 35, 37, 39, 41, 43, 45, 46 - }); - psd0.add>( - "eta_2", - { - -41, -39, -38, -36, -34, -32, -30, -26, -24, -22, -20, -18, -15, -13, -8, -5, -3, -1, - 1, 3, 5, 8, 13, 15, 18, 20, 22, 24, 26, 30, 32, 34, 36, 38, 39, 41 - }); - psd0.add>( - "eta_3", - { - -35, -34, -32, -31, -29, -27, -26, -22, -20, -19, -17, -15, -13, -11, -6, -4, -2, -1, - 1, 2, 4, 6, 11, 13, 15, 17, 19, 20, 22, 26, 27, 29, 31, 32, 34, 35 - }); + psd0.add>("eta_1", + {-46, -45, -43, -41, -39, -37, -35, -30, -28, -26, -23, -20, -18, -15, -9, -6, -3, -1, + 1, 3, 6, 9, 15, 18, 20, 23, 26, 28, 30, 35, 37, 39, 41, 43, 45, 46}); + psd0.add>("eta_2", + {-41, -39, -38, -36, -34, -32, -30, -26, -24, -22, -20, -18, -15, -13, -8, -5, -3, -1, + 1, 3, 5, 8, 13, 15, 18, 20, 22, 24, 26, 30, 32, 34, 36, 38, 39, 41}); + psd0.add>("eta_3", + {-35, -34, -32, -31, -29, -27, -26, -22, -20, -19, -17, -15, -13, -11, -6, -4, -2, -1, + 1, 2, 4, 6, 11, 13, 15, 17, 19, 20, 22, 26, 27, 29, 31, 32, 34, 35}); psd0.add>("coarseEta_1", { 0, diff --git a/L1Trigger/Phase2L1GMT/src/TPSAlgorithm.cc b/L1Trigger/Phase2L1GMT/src/TPSAlgorithm.cc index a0ae987f783f8..3efe63f2fd5bb 100644 --- a/L1Trigger/Phase2L1GMT/src/TPSAlgorithm.cc +++ b/L1Trigger/Phase2L1GMT/src/TPSAlgorithm.cc @@ -667,8 +667,7 @@ PreTrackMatchedMuon TPSAlgorithm::processTrack(const ConvertedTTTrack& track, << "eta=" + to_string(ap_int(track.eta())) + ", " << "z0=" + to_string(ap_int(track.z0())) + ", " << "d0=" + to_string(ap_int(track.d0())) + ", " - << "quality=" + to_string(ap_uint<1>(track.quality())) + ", " - << "\n" + << "quality=" + to_string(ap_uint<1>(track.quality())) + ", " << "\n" << std::flush; edm::LogInfo("TPSAlgo") << "Input stubs:" << std::flush; @@ -678,8 +677,7 @@ PreTrackMatchedMuon TPSAlgorithm::processTrack(const ConvertedTTTrack& track, << "layer=" + to_string(stub->tfLayer()) + ", " << "coord1=" + to_string(stub->coord1()) + ", " << "coord2=" + to_string(stub->coord2()) + ", " - << "eta1=" + to_string(stub->eta1()) + ", " - << "eta2=" + to_string(stub->eta2()) + ", " + << "eta1=" + to_string(stub->eta1()) + ", " << "eta2=" + to_string(stub->eta2()) + ", " << "quality=" + to_string(stub->quality()) + ", " << "etaQuality=" + to_string(stub->etaQuality()) + ", " << "id=" + to_string(stub->address()) + ", " << std::flush; @@ -688,16 +686,12 @@ PreTrackMatchedMuon TPSAlgorithm::processTrack(const ConvertedTTTrack& track, edm::LogInfo("TPSAlgo") << "End stubs\n" << std::flush; edm::LogInfo("TPSAlgo") << "Output PreTrackMatchedMuon: " - << "valid=" + to_string(muon.valid()) + ", " - << "q=" + to_string(muon.charge()) + ", " - << "pt=" + to_string(muon.pt()) + ", " - << "phi=" + to_string(muon.phi()) + ", " - << "eta=" + to_string(muon.eta()) + ", " - << "z0=" + to_string(muon.z0()) + ", " + << "valid=" + to_string(muon.valid()) + ", " << "q=" + to_string(muon.charge()) + ", " + << "pt=" + to_string(muon.pt()) + ", " << "phi=" + to_string(muon.phi()) + ", " + << "eta=" + to_string(muon.eta()) + ", " << "z0=" + to_string(muon.z0()) + ", " << "d0=" + to_string(muon.d0()) + ", " << "isGlobalMuon=" + to_string(muon.isGlobalMuon()) + ", " - << "beta=" + to_string(muon.beta()) + ", " - << "quality=" + to_string(muon.quality()) + ", " + << "beta=" + to_string(muon.beta()) + ", " << "quality=" + to_string(muon.quality()) + ", " << "\n" << std::flush; @@ -709,8 +703,7 @@ PreTrackMatchedMuon TPSAlgorithm::processTrack(const ConvertedTTTrack& track, << "layer=" + to_string(stub->tfLayer()) + ", " << "coord1=" + to_string(stub->coord1()) + ", " << "coord2=" + to_string(stub->coord2()) + ", " - << "eta1=" + to_string(stub->eta1()) + ", " - << "eta2=" + to_string(stub->eta2()) + ", " + << "eta1=" + to_string(stub->eta1()) + ", " << "eta2=" + to_string(stub->eta2()) + ", " << "phiQuality=" + to_string(stub->quality()) + ", " << "etaQuality=" + to_string(stub->etaQuality()) + ", " << "id=" + to_string(stub->address()) + ", " From 98e74f20b9b48b9d577f7d16d6a43cd68e722843 Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Wed, 4 Mar 2026 16:40:49 +0100 Subject: [PATCH 26/61] fix res_pt and res_eta axis labels --- Validation/SiTrackerPhase2V/plugins/Phase2OTValidateTracks.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateTracks.cc b/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateTracks.cc index 49637b4cf0ef4..4fca0b9d30fbc 100644 --- a/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateTracks.cc +++ b/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateTracks.cc @@ -676,8 +676,8 @@ void Phase2OTValidateTracks::bookHistograms(DQMStore::IBooker &iBooker, // Nominal L1TF: residual distributions iBooker.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/Residual"); - res_pt = book1DFromPS(iBooker, "res_pt", psRes_pt, "p_{T} [GeV]", "# tracking particles"); - res_eta = book1DFromPS(iBooker, "res_eta", psRes_eta, "#eta", "# tracking particles"); + res_pt = book1DFromPS(iBooker, "res_pt", psRes_pt, "trk p_{T} - tp p_{T} [GeV]", "# tracking particles"); + res_eta = book1DFromPS(iBooker, "res_eta", psRes_eta, "trk #eta - tp #eta", "# tracking particles"); res_ptRel = book1DFromPS(iBooker, "res_ptRel", psRes_ptRel, "Relative p_{T} [GeV]", "# tracking particles"); d0_res_hist = book1DFromPS(iBooker, "res_d0", psRes_d0, "trk d_{0} - tp d_{0} [cm]","# tracking particles"); From 5c58adf054bdd7d62ea1f9b417619eb991a9a36f Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Wed, 4 Mar 2026 17:00:29 +0100 Subject: [PATCH 27/61] Changed folder naming logic --- .../plugins/Phase2OTHarvestTracks.cc | 4 +- .../python/Phase2OTEffClient_cff.py | 81 ++++++++++--------- 2 files changed, 45 insertions(+), 40 deletions(-) diff --git a/Validation/SiTrackerPhase2V/plugins/Phase2OTHarvestTracks.cc b/Validation/SiTrackerPhase2V/plugins/Phase2OTHarvestTracks.cc index c820cfea56565..c4d04752be3d1 100644 --- a/Validation/SiTrackerPhase2V/plugins/Phase2OTHarvestTracks.cc +++ b/Validation/SiTrackerPhase2V/plugins/Phase2OTHarvestTracks.cc @@ -1,5 +1,3 @@ - - // Package: Validation/SiTrackerPhase2V // Class: Phase2OTHarvestTracks @@ -131,4 +129,4 @@ void Phase2OTHarvestTracks::fillDescriptions(edm::ConfigurationDescriptions &des desc.add("TopFolderName", "TrackerPhase2OTL1TrackV"); descriptions.add("Phase2OTHarvestTracks", desc); } -DEFINE_FWK_MODULE(Phase2OTHarvestTracks); +DEFINE_FWK_MODULE(Phase2OTHarvestTracks); \ No newline at end of file diff --git a/Validation/SiTrackerPhase2V/python/Phase2OTEffClient_cff.py b/Validation/SiTrackerPhase2V/python/Phase2OTEffClient_cff.py index c498fcb186faa..cdaf807180185 100644 --- a/Validation/SiTrackerPhase2V/python/Phase2OTEffClient_cff.py +++ b/Validation/SiTrackerPhase2V/python/Phase2OTEffClient_cff.py @@ -1,71 +1,78 @@ import FWCore.ParameterSet.Config as cms -# Must match your C++ TopFolderName default/value +# ============================================================================ +# TRACK EFFICIENCY CLIENT +# ============================================================================ _topFolder = "TrackerPhase2OTL1TrackV" -# Keep outputs names unique so we never collide with anything else -# (prefix with "ClientTest_") phase2OTEffClient = cms.EDProducer( "DQMGenericClient", + # FIX: Point to the folders that actually EXIST in the input file subDirs=cms.untracked.vstring( - f"{_topFolder}/Nominal_L1TF/FinalEfficiency", - f"{_topFolder}/Extended_L1TF/Prompt/FinalEfficiency", - f"{_topFolder}/Extended_L1TF/Displaced/FinalEfficiency", + f"{_topFolder}/Nominal_L1TF", + f"{_topFolder}/Extended_L1TF/Prompt", + f"{_topFolder}/Extended_L1TF/Displaced", ), - # Format per entry: - # " '' " + # FIX: Define Inputs/Outputs relative to those existing folders + # Output: FinalEfficiency/Name + # Input: EfficiencyIngredients/Name efficiency=cms.vstring( # Nominal - "EtaEfficiency '#eta efficiency;tracking particle #eta;Efficiency' ../EfficiencyIngredients/match_tp_eta ../EfficiencyIngredients/tp_eta", - "PtEfficiency 'p_{T} efficiency;p_{T} [GeV];Efficiency' ../EfficiencyIngredients/match_tp_pt ../EfficiencyIngredients/tp_pt", - "PtEfficiencyZoom 'p_{T} efficiency;p_{T} [GeV];Efficiency' ../EfficiencyIngredients/match_tp_pt_zoom ../EfficiencyIngredients/tp_pt_zoom", - "d0Efficiency 'd_{0} efficiency;d_{0} [cm];Efficiency' ../EfficiencyIngredients/match_tp_d0 ../EfficiencyIngredients/tp_d0", - "LxyEfficiency 'L_{xy} efficiency;L_{xy} [cm];Efficiency' ../EfficiencyIngredients/match_tp_Lxy ../EfficiencyIngredients/tp_Lxy", - "z0Efficiency 'z_{0} efficiency;z_{0} [cm];Efficiency' ../EfficiencyIngredients/match_tp_z0 ../EfficiencyIngredients/tp_z0", + "FinalEfficiency/EtaEfficiency '#eta efficiency;tracking particle #eta;Efficiency' EfficiencyIngredients/match_tp_eta EfficiencyIngredients/tp_eta", + "FinalEfficiency/PtEfficiency 'p_{T} efficiency;p_{T} [GeV];Efficiency' EfficiencyIngredients/match_tp_pt EfficiencyIngredients/tp_pt", + "FinalEfficiency/PtEfficiencyZoom 'p_{T} efficiency;p_{T} [GeV];Efficiency' EfficiencyIngredients/match_tp_pt_zoom EfficiencyIngredients/tp_pt_zoom", + "FinalEfficiency/d0Efficiency 'd_{0} efficiency;d_{0} [cm];Efficiency' EfficiencyIngredients/match_tp_d0 EfficiencyIngredients/tp_d0", + "FinalEfficiency/LxyEfficiency 'L_{xy} efficiency;L_{xy} [cm];Efficiency' EfficiencyIngredients/match_tp_Lxy EfficiencyIngredients/tp_Lxy", + "FinalEfficiency/z0Efficiency 'z_{0} efficiency;z_{0} [cm];Efficiency' EfficiencyIngredients/match_tp_z0 EfficiencyIngredients/tp_z0", - # Prompt (Extended) - # (denominators are nominal tp_*) - "EtaEfficiency '#eta efficiency;tracking particle #eta;Efficiency' ../EfficiencyIngredients/match_prompt_tp_eta ../EfficiencyIngredients/tp_eta", - "PtEfficiency 'p_{T} efficiency;p_{T} [GeV];Efficiency' ../EfficiencyIngredients/match_prompt_tp_pt ../EfficiencyIngredients/tp_pt", - "PtEfficiencyZoom 'p_{T} efficiency;p_{T} [GeV];Efficiency' ../EfficiencyIngredients/match_prompt_tp_pt_zoom ../EfficiencyIngredients/tp_pt_zoom", - "d0Efficiency 'd_{0} efficiency;d_{0} [cm];Efficiency' ../EfficiencyIngredients/match_prompt_tp_d0 ../EfficiencyIngredients/tp_d0", - "LxyEfficiency 'L_{xy} efficiency;L_{xy} [cm];Efficiency' ../EfficiencyIngredients/match_prompt_tp_Lxy ../EfficiencyIngredients/tp_Lxy", - "z0Efficiency 'z_{0} efficiency;z_{0} [cm];Efficiency' ../EfficiencyIngredients/match_prompt_tp_z0 ../EfficiencyIngredients/tp_z0", + # Prompt + # Note: If Prompt/Displaced use different ingredient names, ensure they match here. + # Assuming the histogram names in ROOT are "match_prompt_tp_eta", etc. + "FinalEfficiency/EtaEfficiency '#eta efficiency;tracking particle #eta;Efficiency' EfficiencyIngredients/match_prompt_tp_eta EfficiencyIngredients/tp_eta", + "FinalEfficiency/PtEfficiency 'p_{T} efficiency;p_{T} [GeV];Efficiency' EfficiencyIngredients/match_prompt_tp_pt EfficiencyIngredients/tp_pt", + "FinalEfficiency/PtEfficiencyZoom 'p_{T} efficiency;p_{T} [GeV];Efficiency' EfficiencyIngredients/match_prompt_tp_pt_zoom EfficiencyIngredients/tp_pt_zoom", + "FinalEfficiency/d0Efficiency 'd_{0} efficiency;d_{0} [cm];Efficiency' EfficiencyIngredients/match_prompt_tp_d0 EfficiencyIngredients/tp_d0", + "FinalEfficiency/LxyEfficiency 'L_{xy} efficiency;L_{xy} [cm];Efficiency' EfficiencyIngredients/match_prompt_tp_Lxy EfficiencyIngredients/tp_Lxy", + "FinalEfficiency/z0Efficiency 'z_{0} efficiency;z_{0} [cm];Efficiency' EfficiencyIngredients/match_prompt_tp_z0 EfficiencyIngredients/tp_z0", # Displaced - "EtaEfficiency '#eta efficiency;tracking particle #eta;Efficiency' ../EfficiencyIngredients/match_displaced_tp_eta ../EfficiencyIngredients/tp_eta_for_dis", - "PtEfficiency 'p_{T} efficiency;p_{T} [GeV];Efficiency' ../EfficiencyIngredients/match_displaced_tp_pt ../EfficiencyIngredients/tp_pt_for_dis", - "PtEfficiencyZoom 'p_{T} efficiency;p_{T} [GeV];Efficiency' ../EfficiencyIngredients/match_displaced_tp_pt_zoom ../EfficiencyIngredients/tp_pt_zoom_for_dis", - "d0Efficiency 'd_{0} efficiency;d_{0} [cm];Efficiency' ../EfficiencyIngredients/match_displaced_tp_d0 ../EfficiencyIngredients/tp_d0_for_dis", - "LxyEfficiency 'L_{xy} efficiency;L_{xy} [cm];Efficiency' ../EfficiencyIngredients/match_displaced_tp_Lxy ../EfficiencyIngredients/tp_Lxy_for_dis", - "z0Efficiency 'z_{0} efficiency;z_{0} [cm];Efficiency' ../EfficiencyIngredients/match_displaced_tp_z0 ../EfficiencyIngredients/tp_z0_for_dis", + "FinalEfficiency/EtaEfficiency '#eta efficiency;tracking particle #eta;Efficiency' EfficiencyIngredients/match_displaced_tp_eta EfficiencyIngredients/tp_eta_for_dis", + "FinalEfficiency/PtEfficiency 'p_{T} efficiency;p_{T} [GeV];Efficiency' EfficiencyIngredients/match_displaced_tp_pt EfficiencyIngredients/tp_pt_for_dis", + "FinalEfficiency/PtEfficiencyZoom 'p_{T} efficiency;p_{T} [GeV];Efficiency' EfficiencyIngredients/match_displaced_tp_pt_zoom EfficiencyIngredients/tp_pt_zoom_for_dis", + "FinalEfficiency/d0Efficiency 'd_{0} efficiency;d_{0} [cm];Efficiency' EfficiencyIngredients/match_displaced_tp_d0 EfficiencyIngredients/tp_d0_for_dis", + "FinalEfficiency/LxyEfficiency 'L_{xy} efficiency;L_{xy} [cm];Efficiency' EfficiencyIngredients/match_displaced_tp_Lxy EfficiencyIngredients/tp_Lxy_for_dis", + "FinalEfficiency/z0Efficiency 'z_{0} efficiency;z_{0} [cm];Efficiency' EfficiencyIngredients/match_displaced_tp_z0 EfficiencyIngredients/tp_z0_for_dis", ), resolution=cms.vstring(), efficiencyProfile=cms.untracked.vstring(), verbose=cms.untracked.uint32(0) ) +# ============================================================================ +# STUB EFFICIENCY CLIENT +# ============================================================================ _topFolderStubs = "TrackerPhase2OTStubV" phase2OTStubEffClient = cms.EDProducer( "DQMGenericClient", + # FIX: Point to the Top Folder (which definitely exists) subDirs=cms.untracked.vstring( - f"{_topFolderStubs}/FinalEfficiency", + f"{_topFolderStubs}", ), - # " '' " + # FIX: Path logic: FinalEfficiency/Name vs EfficiencyIngredients/Name efficiency=cms.vstring( - "StubEfficiencyBarrel 'Stub Efficiency Barrel;tracking particle p_{T} [GeV];Efficiency' ../EfficiencyIngredients/gen_clusters_if_stub_barrel ../EfficiencyIngredients/gen_clusters_barrel", - "StubEfficiencyZoomBarrel 'Stub Efficiency Zoom Barrel;tracking particle p_{T} [GeV];Efficiency' ../EfficiencyIngredients/gen_clusters_if_stub_zoom_barrel ../EfficiencyIngredients/gen_clusters_zoom_barrel", - "StubEfficiencyEndcaps 'Stub Efficiency Endcaps;tracking particle p_{T} [GeV];Efficiency' ../EfficiencyIngredients/gen_clusters_if_stub_endcaps ../EfficiencyIngredients/gen_clusters_endcaps", - "StubEfficiencyZoomEndcaps 'Stub Efficiency Zoom Endcaps;tracking particle p_{T} [GeV];Efficiency' ../EfficiencyIngredients/gen_clusters_if_stub_zoom_endcaps ../EfficiencyIngredients/gen_clusters_zoom_endcaps", + "FinalEfficiency/StubEfficiencyBarrel 'Stub Efficiency Barrel;tracking particle p_{T} [GeV];Efficiency' EfficiencyIngredients/gen_clusters_if_stub_barrel EfficiencyIngredients/gen_clusters_barrel", + "FinalEfficiency/StubEfficiencyZoomBarrel 'Stub Efficiency Zoom Barrel;tracking particle p_{T} [GeV];Efficiency' EfficiencyIngredients/gen_clusters_if_stub_zoom_barrel EfficiencyIngredients/gen_clusters_zoom_barrel", + "FinalEfficiency/StubEfficiencyEndcaps 'Stub Efficiency Endcaps;tracking particle p_{T} [GeV];Efficiency' EfficiencyIngredients/gen_clusters_if_stub_endcaps EfficiencyIngredients/gen_clusters_endcaps", + "FinalEfficiency/StubEfficiencyZoomEndcaps 'Stub Efficiency Zoom Endcaps;tracking particle p_{T} [GeV];Efficiency' EfficiencyIngredients/gen_clusters_if_stub_zoom_endcaps EfficiencyIngredients/gen_clusters_zoom_endcaps", ), resolution=cms.vstring(), efficiencyProfile=cms.untracked.vstring(), verbose=cms.untracked.uint32(0) ) -# Expose as a Sequence so you can append with one line +# Sequence phase2OTEffClientSeq = cms.Sequence( - phase2OTEffClient # tracks - + phase2OTStubEffClient # stubs + phase2OTEffClient + + phase2OTStubEffClient ) \ No newline at end of file From a8bc65767ad051b5d71d508ebfe0c746dac4ac9e Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Wed, 4 Mar 2026 17:39:34 +0100 Subject: [PATCH 28/61] remove manual efficiency calculation --- .../interface/TrackerPhase2HistUtil.h | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h b/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h index 0edb53c3e8dfa..6b6820bb39c18 100644 --- a/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h +++ b/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h @@ -23,19 +23,6 @@ namespace phase2tkutil { - inline void makeEfficiencyME(TH1* numerator, - TH1* denominator, - dqm::legacy::MonitorElement* me, - const std::string& xAxisTitle) { - TH1* efficiency = me->getTH1(); - efficiency->Divide(numerator, denominator, 1., 1., "B"); - efficiency->SetMinimum(0.0); - efficiency->SetMaximum(1.1); - efficiency->SetStats(false); - efficiency->GetXaxis()->SetTitle(xAxisTitle.c_str()); - efficiency->GetYaxis()->SetTitle("Efficiency"); - } - inline void fillResolutionFromVec(const std::vector& srcVec, dqm::legacy::MonitorElement* destME, const std::string& yAxisTitle) { @@ -50,7 +37,9 @@ namespace phase2tkutil { TH1* hDest = destME->getTH1(); hDest->SetMinimum(0.0); hDest->SetStats(false); - hDest->GetYaxis()->SetTitle(yAxisTitle.c_str()); + if (!yAxisTitle.empty()) { + hDest->GetYaxis()->SetTitle(yAxisTitle.c_str()); + } for (size_t i = 0; i < srcVec.size(); ++i) { TH1* hSrc = srcVec[i]->getTH1(); From 939b587626f3d75081ad52949f93bfc20526c0e2 Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Wed, 4 Mar 2026 17:40:39 +0100 Subject: [PATCH 29/61] remove Phase2OTHarvestStub as file as been removed --- .../SiTrackerPhase2V/python/Phase2TrackerMCHarvesting_cff.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/Validation/SiTrackerPhase2V/python/Phase2TrackerMCHarvesting_cff.py b/Validation/SiTrackerPhase2V/python/Phase2TrackerMCHarvesting_cff.py index ba9617b4be1b6..d1b1d6b77b32f 100644 --- a/Validation/SiTrackerPhase2V/python/Phase2TrackerMCHarvesting_cff.py +++ b/Validation/SiTrackerPhase2V/python/Phase2TrackerMCHarvesting_cff.py @@ -4,7 +4,6 @@ from Validation.SiTrackerPhase2V.Phase2ITRechitHarvester_cfi import * from Validation.SiTrackerPhase2V.Phase2OTHarvestTracks_cfi import * -from Validation.SiTrackerPhase2V.Phase2OTHarvestStub_cfi import * #ITTracking rechit #clone the rechit harvester for tracking rechit Phase2ITtrackingrechitHarvester=Phase2ITRechitHarvester.clone( @@ -78,5 +77,4 @@ * Phase2OTTrackingRechitHarvester_PS * Phase2OTTrackingRechitHarvester_2S * Phase2OTHarvestTracks - * Phase2OTHarvestStub ) From e514f2b0c2a5d7287c5ede94416a98a91871a35e Mon Sep 17 00:00:00 2001 From: Lovisa Date: Thu, 12 Mar 2026 17:46:03 +0100 Subject: [PATCH 30/61] Corrected for additional PR comments --- PhysicsTools/NanoAOD/plugins/DisTauTag.cc | 4 +- .../NanoAOD/plugins/DispJetTableProducer.cc | 91 +------------------ .../plugins/ElectronExtendedTableProducer.cc | 67 ++++++-------- .../plugins/MuonExtendedTableProducer.cc | 71 ++++++--------- .../plugins/cscMDSshowerTableProducer.cc | 4 +- PhysicsTools/NanoAOD/python/custom_exo_cff.py | 2 +- 6 files changed, 68 insertions(+), 171 deletions(-) diff --git a/PhysicsTools/NanoAOD/plugins/DisTauTag.cc b/PhysicsTools/NanoAOD/plugins/DisTauTag.cc index 96136acea215c..f8a27692b6b96 100644 --- a/PhysicsTools/NanoAOD/plugins/DisTauTag.cc +++ b/PhysicsTools/NanoAOD/plugins/DisTauTag.cc @@ -285,9 +285,7 @@ void DisTauTag::produce(edm::StreamID, edm::Event& event, const edm::EventSetup& // Running inference on batch std::vector outputs; - { - tensorflow::run(session_, {{"input_1", input_1}, {"input_2", input_2}}, {"final_out"}, &outputs); - } + { tensorflow::run(session_, {{"input_1", input_1}, {"input_2", input_2}}, {"final_out"}, &outputs); } // Storing results for (size_t batch_jet_idx = 0; batch_jet_idx < current_batch_size; ++batch_jet_idx) { diff --git a/PhysicsTools/NanoAOD/plugins/DispJetTableProducer.cc b/PhysicsTools/NanoAOD/plugins/DispJetTableProducer.cc index 07972b6548991..e5f4e61a8361b 100644 --- a/PhysicsTools/NanoAOD/plugins/DispJetTableProducer.cc +++ b/PhysicsTools/NanoAOD/plugins/DispJetTableProducer.cc @@ -102,78 +102,6 @@ class DispJetTableProducer : public edm::stream::EDProducer<> { mu_IVF_tracksignedIP3Dsig; std::vector mu_IVF_signedIP2D, mu_IVF_signedIP3D, mu_IVF_signedIP2Dsig, mu_IVF_signedIP3Dsig; - el_idx.clear(); - el_lIVF_match.clear(); - el_IVF_df.clear(); - el_IVF_ntracks.clear(); - el_IVF_elid.clear(); - el_IVF_x.clear(); - el_IVF_y.clear(); - el_IVF_z.clear(); - el_IVF_cx.clear(); - el_IVF_cy.clear(); - el_IVF_cz.clear(); - el_IVF_chi2.clear(); - el_IVF_pt.clear(); - el_IVF_eta.clear(); - el_IVF_phi.clear(); - el_IVF_E.clear(); - el_IVF_mass.clear(); - el_IVF_trackcharge.clear(); - el_IVF_trackelid.clear(); - el_IVF_trackvtxid.clear(); - el_IVF_trackpt.clear(); - el_IVF_tracketa.clear(); - el_IVF_trackphi.clear(); - el_IVF_trackE.clear(); - el_IVF_trackdxy.clear(); - el_IVF_trackdz.clear(); - el_IVF_tracksignedIP2D.clear(); - el_IVF_tracksignedIP2Dsig.clear(); - el_IVF_tracksignedIP3D.clear(); - el_IVF_tracksignedIP3Dsig.clear(); - - el_IVF_signedIP2D.clear(); - el_IVF_signedIP2Dsig.clear(); - el_IVF_signedIP3D.clear(); - el_IVF_signedIP3Dsig.clear(); - - mu_idx.clear(); - mu_lIVF_match.clear(); - mu_IVF_df.clear(); - mu_IVF_ntracks.clear(); - mu_IVF_muid.clear(); - mu_IVF_x.clear(); - mu_IVF_y.clear(); - mu_IVF_z.clear(); - mu_IVF_cx.clear(); - mu_IVF_cy.clear(); - mu_IVF_cz.clear(); - mu_IVF_chi2.clear(); - mu_IVF_pt.clear(); - mu_IVF_eta.clear(); - mu_IVF_phi.clear(); - mu_IVF_E.clear(); - mu_IVF_mass.clear(); - mu_IVF_trackcharge.clear(); - mu_IVF_trackmuid.clear(); - mu_IVF_trackvtxid.clear(); - mu_IVF_trackpt.clear(); - mu_IVF_tracketa.clear(); - mu_IVF_trackphi.clear(); - mu_IVF_trackE.clear(); - mu_IVF_trackdxy.clear(); - mu_IVF_trackdz.clear(); - mu_IVF_tracksignedIP2D.clear(); - mu_IVF_tracksignedIP2Dsig.clear(); - mu_IVF_tracksignedIP3D.clear(); - mu_IVF_tracksignedIP3Dsig.clear(); - - mu_IVF_signedIP2D.clear(); - mu_IVF_signedIP2Dsig.clear(); - mu_IVF_signedIP3D.clear(); - mu_IVF_signedIP3Dsig.clear(); - int ntrack_max = 100; int nElectronsSel = 0; int nMuonsSel = 0; @@ -181,12 +109,9 @@ class DispJetTableProducer : public edm::stream::EDProducer<> { for (unsigned int i = 0; i < nElectrons; i++) { const pat::Electron& el = electrons[i]; - if (el.gsfTrack().isNull()) - continue; - if (el.pt() < 7) - continue; - if (fabs(el.eta()) > 2.5) + if (el.gsfTrack().isNull() || el.pt() < 7 || fabs(el.eta()) > 2.5) { continue; + } el_idx.push_back(i); el_lIVF_match.push_back(false); @@ -284,16 +209,10 @@ class DispJetTableProducer : public edm::stream::EDProducer<> { for (unsigned int i = 0; i < nMuons; i++) { const pat::Muon& mu = muons[i]; - if (mu.innerTrack().isNull()) - continue; - if (mu.pt() < 5) - continue; - if (fabs(mu.eta()) > 2.4) - continue; - if (!mu.isPFMuon()) - continue; - if (!(mu.isTrackerMuon() || mu.isGlobalMuon())) + if (mu.innerTrack().isNull() || mu.pt() < 5 || fabs(mu.eta()) > 2.4 || !mu.isPFMuon() || + !(mu.isTrackerMuon() || mu.isGlobalMuon())) { continue; + } mu_idx.push_back(i); mu_lIVF_match.push_back(false); diff --git a/PhysicsTools/NanoAOD/plugins/ElectronExtendedTableProducer.cc b/PhysicsTools/NanoAOD/plugins/ElectronExtendedTableProducer.cc index 61ee491eb4a77..a9bb60f4eedd8 100644 --- a/PhysicsTools/NanoAOD/plugins/ElectronExtendedTableProducer.cc +++ b/PhysicsTools/NanoAOD/plugins/ElectronExtendedTableProducer.cc @@ -60,11 +60,11 @@ class ElectronExtendedTableProducer : public edm::global::EDProducer<> { const std::vector& jets, const reco::Vertex& vertex, const double rho, - std::vector* jetIdx, + std::vector& jetIdx, std::vector relIso0p4, - std::vector* jetPtRatio, - std::vector* jetPtRel, - std::vector* jrtSelectedChargedMultiplicity) const; + std::vector& jetPtRatio, + std::vector& jetPtRel, + std::vector& jrtSelectedChargedMultiplicity) const; std::string name_; edm::EDGetTokenT rhoTag_; @@ -135,7 +135,7 @@ void ElectronExtendedTableProducer::produce(edm::StreamID, edm::Event& iEvent, c relIso0p4.push_back(getPFIso(electron)); fillLeptonJetVariables( - &electron, jets, pv, rho, &jetIdx, relIso0p4, &jetPtRatio, &jetPtRel, &jetSelectedChargedMultiplicity); + &electron, jets, pv, rho, jetIdx, relIso0p4, jetPtRatio, jetPtRel, jetSelectedChargedMultiplicity); const reco::Candidate* el_cand = dynamic_cast(&electron); jetFatIdx.push_back(findMatchedJet(*el_cand, jetFat)); @@ -217,21 +217,21 @@ void ElectronExtendedTableProducer::fillLeptonJetVariables(const reco::GsfElectr const std::vector& jets, const reco::Vertex& vertex, const double rho, - std::vector* jetIdx, + std::vector& jetIdx, std::vector relIso0p4, - std::vector* jetPtRatio, - std::vector* jetPtRel, - std::vector* jetSelectedChargedMultiplicity) const { + std::vector& jetPtRatio, + std::vector& jetPtRel, + std::vector& jetSelectedChargedMultiplicity) const { const reco::Candidate* cand = dynamic_cast(el); int matchedJetIdx = findMatchedJet(*cand, jets); - jetIdx->push_back(matchedJetIdx); + jetIdx.push_back(matchedJetIdx); if (matchedJetIdx < 0) { float ptRatio = (1. / (1. + relIso0p4.back())); - jetPtRatio->push_back(ptRatio); - jetPtRel->push_back(0); - jetSelectedChargedMultiplicity->push_back(0); + jetPtRatio.push_back(ptRatio); + jetPtRel.push_back(0); + jetSelectedChargedMultiplicity.push_back(0); } else { const pat::Jet& jet = jets[matchedJetIdx]; auto rawJetP4 = jet.correctedP4("Uncorrected"); @@ -240,9 +240,9 @@ void ElectronExtendedTableProducer::fillLeptonJetVariables(const reco::GsfElectr bool leptonEqualsJet = ((rawJetP4 - leptonP4).P() < 1e-4); if (leptonEqualsJet) { - jetPtRatio->push_back(1); - jetPtRel->push_back(0); - jetSelectedChargedMultiplicity->push_back(0); + jetPtRatio.push_back(1); + jetPtRel.push_back(0); + jetSelectedChargedMultiplicity.push_back(0); } else { auto L1JetP4 = jet.correctedP4("L1FastJet"); double L2L3JEC = jet.pt() / L1JetP4.pt(); @@ -250,37 +250,28 @@ void ElectronExtendedTableProducer::fillLeptonJetVariables(const reco::GsfElectr float ptRatio = cand->pt() / lepAwareJetP4.pt(); float ptRel = leptonP4.Vect().Cross((lepAwareJetP4 - leptonP4).Vect().Unit()).R(); - jetPtRatio->push_back(ptRatio); - jetPtRel->push_back(ptRel); - jetSelectedChargedMultiplicity->push_back(0); + jetPtRatio.push_back(ptRatio); + jetPtRel.push_back(ptRel); + jetSelectedChargedMultiplicity.push_back(0); for (const auto& daughterPtr : jet.daughterPtrVector()) { const pat::PackedCandidate& daughter = *((const pat::PackedCandidate*)daughterPtr.get()); - if (daughter.charge() == 0) - continue; - if (daughter.fromPV() < 2) - continue; - if (reco::deltaR(daughter, *cand) > 0.4) - continue; - if (!daughter.hasTrackDetails()) + if (daughter.charge() == 0 || daughter.fromPV() < 2 || reco::deltaR(daughter, *cand) > 0.4 || + !daughter.hasTrackDetails()) { continue; + } auto daughterTrack = daughter.pseudoTrack(); - if (daughterTrack.pt() <= 1) - continue; - if (daughterTrack.hitPattern().numberOfValidHits() < 8) - continue; - if (daughterTrack.hitPattern().numberOfValidPixelHits() < 2) + if (daughterTrack.pt() <= 1 || daughterTrack.hitPattern().numberOfValidHits() < 8 || + daughterTrack.hitPattern().numberOfValidPixelHits() < 2 || daughterTrack.normalizedChi2() >= 5 || + std::abs(daughterTrack.dz(vertex.position())) >= 17 || + std::abs(daughterTrack.dxy(vertex.position())) >= 0.2) { continue; - if (daughterTrack.normalizedChi2() >= 5) - continue; - if (std::abs(daughterTrack.dz(vertex.position())) >= 17) - continue; - if (std::abs(daughterTrack.dxy(vertex.position())) >= 0.2) - continue; - ++jetSelectedChargedMultiplicity->back(); + } + + ++jetSelectedChargedMultiplicity.back(); } } } diff --git a/PhysicsTools/NanoAOD/plugins/MuonExtendedTableProducer.cc b/PhysicsTools/NanoAOD/plugins/MuonExtendedTableProducer.cc index 18d12db42cb74..fb4653eac2ba8 100644 --- a/PhysicsTools/NanoAOD/plugins/MuonExtendedTableProducer.cc +++ b/PhysicsTools/NanoAOD/plugins/MuonExtendedTableProducer.cc @@ -63,11 +63,11 @@ class MuonExtendedTableProducer : public edm::global::EDProducer<> { const std::vector& jets, const reco::Vertex& vertex, const double rho, - std::vector* jetIdx, + std::vector& jetIdx, std::vector relIso0p4, - std::vector* jetPtRatio, - std::vector* jetPtRel, - std::vector* jetSelectedChargedMultiplicity) const; + std::vector& jetPtRatio, + std::vector& jetPtRel, + std::vector& jetSelectedChargedMultiplicity) const; std::string name_; edm::EDGetTokenT rhoTag_; @@ -144,7 +144,7 @@ void MuonExtendedTableProducer::produce(edm::StreamID, edm::Event& iEvent, const relIso0p4.push_back(getPFIso(muon)); fillLeptonJetVariables( - &muon, jets, pv, rho, &jetIdx, relIso0p4, &jetPtRatio, &jetPtRel, &jetSelectedChargedMultiplicity); + &muon, jets, pv, rho, jetIdx, relIso0p4, jetPtRatio, jetPtRel, jetSelectedChargedMultiplicity); const reco::Candidate* mu_cand = dynamic_cast(&muon); jetFatIdx.push_back(findMatchedJet(*mu_cand, jetFat)); @@ -246,8 +246,6 @@ bool isSourceCandidatePtrMatch(const T1& lhs, const T2& rhs) { } int MuonExtendedTableProducer::findMatchedJet(const reco::Candidate& lepton, const std::vector& jets) const { - int iJet = -1; - unsigned int nJets = jets.size(); for (unsigned int i = 0; i < nJets; i++) { @@ -257,28 +255,28 @@ int MuonExtendedTableProducer::findMatchedJet(const reco::Candidate& lepton, con } } - return iJet; + return -1; } void MuonExtendedTableProducer::fillLeptonJetVariables(const reco::Muon* mu, const std::vector& jets, const reco::Vertex& vertex, const double rho, - std::vector* jetIdx, + std::vector& jetIdx, std::vector relIso0p4, - std::vector* jetPtRatio, - std::vector* jetPtRel, - std::vector* jetSelectedChargedMultiplicity) const { + std::vector& jetPtRatio, + std::vector& jetPtRel, + std::vector& jetSelectedChargedMultiplicity) const { const reco::Candidate* cand = dynamic_cast(mu); int matchedJetIdx = findMatchedJet(*cand, jets); - jetIdx->push_back(matchedJetIdx); + jetIdx.push_back(matchedJetIdx); if (matchedJetIdx < 0) { float ptRatio = (1. / (1. + relIso0p4.back())); - jetPtRatio->push_back(ptRatio); - jetPtRel->push_back(0); - jetSelectedChargedMultiplicity->push_back(0); + jetPtRatio.push_back(ptRatio); + jetPtRel.push_back(0); + jetSelectedChargedMultiplicity.push_back(0); } else { const pat::Jet& jet = jets[matchedJetIdx]; auto rawJetP4 = jet.correctedP4("Uncorrected"); @@ -287,9 +285,9 @@ void MuonExtendedTableProducer::fillLeptonJetVariables(const reco::Muon* mu, bool leptonEqualsJet = ((rawJetP4 - leptonP4).P() < 1e-4); if (leptonEqualsJet) { - jetPtRatio->push_back(1); - jetPtRel->push_back(0); - jetSelectedChargedMultiplicity->push_back(0); + jetPtRatio.push_back(1); + jetPtRel.push_back(0); + jetSelectedChargedMultiplicity.push_back(0); } else { auto L1JetP4 = jet.correctedP4("L1FastJet"); double L2L3JEC = jet.pt() / L1JetP4.pt(); @@ -297,37 +295,28 @@ void MuonExtendedTableProducer::fillLeptonJetVariables(const reco::Muon* mu, float ptRatio = cand->pt() / lepAwareJetP4.pt(); float ptRel = leptonP4.Vect().Cross((lepAwareJetP4 - leptonP4).Vect().Unit()).R(); - jetPtRatio->push_back(ptRatio); - jetPtRel->push_back(ptRel); - jetSelectedChargedMultiplicity->push_back(0); + jetPtRatio.push_back(ptRatio); + jetPtRel.push_back(ptRel); + jetSelectedChargedMultiplicity.push_back(0); for (const auto& daughterPtr : jet.daughterPtrVector()) { const pat::PackedCandidate& daughter = *((const pat::PackedCandidate*)daughterPtr.get()); - if (daughter.charge() == 0) - continue; - if (daughter.fromPV() < 2) - continue; - if (reco::deltaR(daughter, *cand) > 0.4) - continue; - if (!daughter.hasTrackDetails()) + if (daughter.charge() == 0 || daughter.fromPV() < 2 || reco::deltaR(daughter, *cand) > 0.4 || + !daughter.hasTrackDetails()) { continue; + } auto daughterTrack = daughter.pseudoTrack(); - if (daughterTrack.pt() <= 1) - continue; - if (daughterTrack.hitPattern().numberOfValidHits() < 8) + if (daughterTrack.pt() <= 1 || daughterTrack.hitPattern().numberOfValidHits() < 8 || + daughterTrack.hitPattern().numberOfValidPixelHits() < 2 || daughterTrack.normalizedChi2() >= 5 || + std::abs(daughterTrack.dz(vertex.position())) >= 17 || + std::abs(daughterTrack.dxy(vertex.position())) >= 0.2) { continue; - if (daughterTrack.hitPattern().numberOfValidPixelHits() < 2) - continue; - if (daughterTrack.normalizedChi2() >= 5) - continue; - if (std::abs(daughterTrack.dz(vertex.position())) >= 17) - continue; - if (std::abs(daughterTrack.dxy(vertex.position())) >= 0.2) - continue; - ++jetSelectedChargedMultiplicity->back(); + } + + ++jetSelectedChargedMultiplicity.back(); } } } diff --git a/PhysicsTools/NanoAOD/plugins/cscMDSshowerTableProducer.cc b/PhysicsTools/NanoAOD/plugins/cscMDSshowerTableProducer.cc index 014b5fb433d0f..b1d8316cb61a6 100644 --- a/PhysicsTools/NanoAOD/plugins/cscMDSshowerTableProducer.cc +++ b/PhysicsTools/NanoAOD/plugins/cscMDSshowerTableProducer.cc @@ -40,7 +40,7 @@ class cscMDSshowerTableProducer : public edm::global::EDProducer<> { dtgeometryToken_(esConsumes()), rpcgeometryToken_(esConsumes()), inputToken_(consumes(iConfig.getParameter("recHitLabel"))), - dtSegmentToken_(consumes(iConfig.getParameter("segmentLabel"))), + dtSegmentToken_(consumes(iConfig.getParameter("dtSegmentLabel"))), rpchitToken_(consumes(iConfig.getParameter("rpcLabel"))), rParam_(iConfig.getParameter("rParam")), nRechitMin_(iConfig.getParameter("nRechitMin")), @@ -58,7 +58,7 @@ class cscMDSshowerTableProducer : public edm::global::EDProducer<> { static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { edm::ParameterSetDescription desc; desc.add("recHitLabel")->setComment("input cscRechit collection"); - desc.add("segmentLabel")->setComment("input dt segment collection for veto"); + desc.add("dtSegmentLabel")->setComment("input dt segment collection for veto"); desc.add("rpcLabel")->setComment("input rpcRechit collection for veto"); desc.add("rParam", 0.4); desc.add("nRechitMin", 50); diff --git a/PhysicsTools/NanoAOD/python/custom_exo_cff.py b/PhysicsTools/NanoAOD/python/custom_exo_cff.py index 9cedea34d92a1..f356653c52035 100644 --- a/PhysicsTools/NanoAOD/python/custom_exo_cff.py +++ b/PhysicsTools/NanoAOD/python/custom_exo_cff.py @@ -88,7 +88,7 @@ cscMDSshowerTable = cscMDSshowerTable.clone( name = cms.string("cscMDSCluster"), recHitLabel = cms.InputTag("csc2DRecHits"), - segmentLabel = cms.InputTag("dt4DSegments"), + dtSegmentLabel = cms.InputTag("dt4DSegments"), rpcLabel = cms.InputTag("rpcRecHits") ) From 8263cc138f273cb8162f085e21439f934f8309b0 Mon Sep 17 00:00:00 2001 From: Lovisa Date: Thu, 12 Mar 2026 17:53:41 +0100 Subject: [PATCH 31/61] code format --- PhysicsTools/NanoAOD/plugins/DisTauTag.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/PhysicsTools/NanoAOD/plugins/DisTauTag.cc b/PhysicsTools/NanoAOD/plugins/DisTauTag.cc index f8a27692b6b96..96136acea215c 100644 --- a/PhysicsTools/NanoAOD/plugins/DisTauTag.cc +++ b/PhysicsTools/NanoAOD/plugins/DisTauTag.cc @@ -285,7 +285,9 @@ void DisTauTag::produce(edm::StreamID, edm::Event& event, const edm::EventSetup& // Running inference on batch std::vector outputs; - { tensorflow::run(session_, {{"input_1", input_1}, {"input_2", input_2}}, {"final_out"}, &outputs); } + { + tensorflow::run(session_, {{"input_1", input_1}, {"input_2", input_2}}, {"final_out"}, &outputs); + } // Storing results for (size_t batch_jet_idx = 0; batch_jet_idx < current_batch_size; ++batch_jet_idx) { From 6391c8741bc8994e67021b1596f8ba48b8b7ce2e Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Fri, 20 Mar 2026 22:06:27 +0100 Subject: [PATCH 32/61] ensure both num and den for efficiency hists have same selections --- .../plugins/Phase2OTValidateTracks.cc | 295 ++++++++---------- 1 file changed, 137 insertions(+), 158 deletions(-) diff --git a/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateTracks.cc b/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateTracks.cc index e1fcf4c112e13..c90d6ed8e2512 100644 --- a/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateTracks.cc +++ b/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateTracks.cc @@ -81,7 +81,7 @@ class Phase2OTValidateTracks : public DQMEDAnalyzer { MonitorElement *trackParts_Eta = nullptr; MonitorElement *trackParts_Phi = nullptr; MonitorElement *trackParts_Pt = nullptr; - MonitorElement *n_trackParts = nullptr; + MonitorElement *trackParts_Num = nullptr; unsigned int nTrackParts = 0; // pT and eta for efficiency plots @@ -104,6 +104,15 @@ class Phase2OTValidateTracks : public DQMEDAnalyzer { MonitorElement *tp_eta_for_dis = nullptr; // denominator MonitorElement *tp_d0_for_dis = nullptr; // denominator MonitorElement *tp_z0_for_dis = nullptr; // denominator + MonitorElement *tp_Lxy_for_dis = nullptr; // denominator + + // extended prompt plots for denom + MonitorElement *tp_pt_for_prompt = nullptr; // denominator + MonitorElement *tp_pt_zoom_for_prompt = nullptr; // denominator + MonitorElement *tp_eta_for_prompt = nullptr; // denominator + MonitorElement *tp_d0_for_prompt = nullptr; // denominator + MonitorElement *tp_z0_for_prompt = nullptr; // denominator + MonitorElement *tp_Lxy_for_prompt = nullptr; // denominator // extended tracks pT and eta for efficiency plots MonitorElement *match_prompt_tp_pt = nullptr; // numerator @@ -338,6 +347,7 @@ void Phase2OTValidateTracks::processTrackCollection( int match_id = associatedTP->pdgId(); float chi2dof = thisTrack->chi2Red(); + // ensure that track is uniquely matched to the TP we are looking at! if (dmatch_pt < 0.1 && dmatch_eta < 0.1 && dmatch_phi < 0.1 && tmp_tp_pdgid == match_id) { tp_nMatch++; if (bestTrackIndex < 0 || chi2dof < bestChi2dof) { @@ -361,9 +371,8 @@ void Phase2OTValidateTracks::processTrackCollection( return; if (isExtended) { - // if extended, if "prompt" or "displaced" - if (std::fabs(bestTrack_d0) < TP_maxD0 && tmp_tp_Lxy < TP_maxLxy) { - // extended + prompt + // if extended, if "prompt" + if (std::fabs(tmp_tp_d0) < TP_maxD0) { reseta_vect_ptr = &reseta_prompt_vect; resphi_vect_ptr = &resphi_prompt_vect; resz0_vect_ptr = &resz0_prompt_vect; @@ -379,12 +388,15 @@ void Phase2OTValidateTracks::processTrackCollection( match_tp_pt_ptr = match_prompt_tp_pt; match_tp_pt_zoom_ptr = match_prompt_tp_pt_zoom; + match_tp_Lxy_ptr = match_prompt_tp_Lxy; + + // Unconditional pointer assignment (cuts happen at Fill) match_tp_eta_ptr = match_prompt_tp_eta; match_tp_d0_ptr = match_prompt_tp_d0; - match_tp_Lxy_ptr = match_prompt_tp_Lxy; match_tp_z0_ptr = match_prompt_tp_z0; + + // if extended, if "displaced" } else { - // extended + displaced reseta_vect_ptr = &reseta_displaced_vect; resphi_vect_ptr = &resphi_displaced_vect; resz0_vect_ptr = &resz0_displaced_vect; @@ -400,9 +412,9 @@ void Phase2OTValidateTracks::processTrackCollection( match_tp_pt_ptr = match_displaced_tp_pt; match_tp_pt_zoom_ptr = match_displaced_tp_pt_zoom; + match_tp_Lxy_ptr = match_displaced_tp_Lxy; match_tp_eta_ptr = match_displaced_tp_eta; match_tp_d0_ptr = match_displaced_tp_d0; - match_tp_Lxy_ptr = match_displaced_tp_Lxy; match_tp_z0_ptr = match_displaced_tp_z0; } @@ -419,15 +431,15 @@ void Phase2OTValidateTracks::processTrackCollection( res_eta_ptr = res_eta; res_pt_ptr = res_pt; res_ptRel_ptr = res_ptRel; + res_d0_hist_ptr = d0_res_hist; match_tp_pt_ptr = match_tp_pt; match_tp_pt_zoom_ptr = match_tp_pt_zoom; + match_tp_Lxy_ptr = match_tp_Lxy; + match_tp_eta_ptr = match_tp_eta; match_tp_d0_ptr = match_tp_d0; - match_tp_Lxy_ptr = match_tp_Lxy; match_tp_z0_ptr = match_tp_z0; - - res_d0_hist_ptr = d0_res_hist; } // Compute residuals & fill them @@ -442,17 +454,33 @@ void Phase2OTValidateTracks::processTrackCollection( res_eta_ptr->Fill(eta_res); res_pt_ptr->Fill(pt_diff); res_ptRel_ptr->Fill(pt_res); - res_d0_hist_ptr->Fill(d0_res); // Fill efficiency histograms - match_tp_pt_ptr->Fill(tmp_tp_pt); - if (tmp_tp_pt > 0.f && tmp_tp_pt <= 10.f) - match_tp_pt_zoom_ptr->Fill(tmp_tp_pt); - match_tp_eta_ptr->Fill(tmp_tp_eta); - match_tp_d0_ptr->Fill(tmp_tp_d0); + if (tmp_tp_Lxy < 1.0) { + match_tp_pt_ptr->Fill(tmp_tp_pt); + if (tmp_tp_pt > 0.f && tmp_tp_pt <= 10.f) { + match_tp_pt_zoom_ptr->Fill(tmp_tp_pt); + } + } + + // Lxy efficiency (NO Lxy cut) match_tp_Lxy_ptr->Fill(tmp_tp_Lxy); - match_tp_z0_ptr->Fill(tmp_tp_z0); + + // Eta, d0, z0 efficiencies + if (isExtended && std::fabs(bestTrack_d0) >= TP_maxD0) { + // Displaced track: Fill unconditionally (no Lxy cut for displaced) + match_tp_eta_ptr->Fill(tmp_tp_eta); + match_tp_d0_ptr->Fill(tmp_tp_d0); + match_tp_z0_ptr->Fill(tmp_tp_z0); + } else { + // Prompt or Nominal track: Must pass Lxy cut + if (tmp_tp_Lxy < TP_maxLxy) { + match_tp_eta_ptr->Fill(tmp_tp_eta); + match_tp_d0_ptr->Fill(tmp_tp_d0); + match_tp_z0_ptr->Fill(tmp_tp_z0); + } + } // Fill resolution plots for different abs(eta) bins: float bins[7] = {0.f, 0.7f, 1.0f, 1.2f, 1.6f, 2.0f, 2.4f}; @@ -565,23 +593,49 @@ void Phase2OTValidateTracks::analyze(const edm::Event &iEvent, const edm::EventS if (std::fabs(tmp_tp_z0) > TP_maxZ0) continue; - // To make efficiency plots where the denominator has NO stub cuts + // pT Denominators (No minPt cut yet, strict Lxy cut) if (tmp_tp_Lxy < 1.0) { - tp_pt->Fill(tmp_tp_pt); // pT effic, no cut on pT, but Lxy cut - if (tmp_tp_pt <= 10) - tp_pt_zoom->Fill(tmp_tp_pt); // pT effic, no cut on pT, but Lxy cut - } - tp_pt_for_dis->Fill(tmp_tp_pt); // pT effic for displaced, no cut on pT or Lxy - if (tmp_tp_pt <= 10) { - tp_pt_zoom_for_dis->Fill(tmp_tp_pt); // pT effic for displaced, no cut on pT or Lxy + tp_pt->Fill(tmp_tp_pt); + if (tmp_tp_pt <= 10.f) { + tp_pt_zoom->Fill(tmp_tp_pt); + } + + if (std::fabs(tmp_tp_d0) < TP_maxD0) { + tp_pt_for_prompt->Fill(tmp_tp_pt); + if (tmp_tp_pt <= 10.f) { + tp_pt_zoom_for_prompt->Fill(tmp_tp_pt); + } + } else { + tp_pt_for_dis->Fill(tmp_tp_pt); + if (tmp_tp_pt <= 10.f) { + tp_pt_zoom_for_dis->Fill(tmp_tp_pt); + } + } + } else { + // Displaced has no Lxy cut, fill unconditionally for Lxy + if (std::fabs(tmp_tp_d0) >= TP_maxD0) { + tp_pt_for_dis->Fill(tmp_tp_pt); + if (tmp_tp_pt <= 10.f) { + tp_pt_zoom_for_dis->Fill(tmp_tp_pt); + } + } } if (tmp_tp_pt < TP_minPt) continue; - tp_Lxy->Fill(tmp_tp_Lxy); // Lxy efficiency has no cut on Lxy - tp_eta_for_dis->Fill(tmp_tp_eta); - tp_d0_for_dis->Fill(tmp_tp_d0); - tp_z0_for_dis->Fill(tmp_tp_z0); + + // Lxy Denominators (minPt applied, NO Lxy cut) + tp_Lxy->Fill(tmp_tp_Lxy); + if (std::fabs(tmp_tp_d0) < TP_maxD0) { + tp_Lxy_for_prompt->Fill(tmp_tp_Lxy); + } else { + tp_Lxy_for_dis->Fill(tmp_tp_Lxy); + + // Displaced has NO Lxy cut at all, fill its eta, d0, z0 here + tp_eta_for_dis->Fill(tmp_tp_eta); + tp_d0_for_dis->Fill(tmp_tp_d0); + tp_z0_for_dis->Fill(tmp_tp_z0); + } if (MCTruthTTTrackExtendedHandle.isValid()) { if (nStubTP >= TP_minNStub || nStubLayerTP >= TP_minNLayersStub) { @@ -605,6 +659,12 @@ void Phase2OTValidateTracks::analyze(const edm::Event &iEvent, const edm::EventS tp_eta->Fill(tmp_tp_eta); tp_d0->Fill(tmp_tp_d0); tp_z0->Fill(tmp_tp_z0); + + if (std::fabs(tmp_tp_d0) < TP_maxD0) { + tp_eta_for_prompt->Fill(tmp_tp_eta); + tp_d0_for_prompt->Fill(tmp_tp_d0); + tp_z0_for_prompt->Fill(tmp_tp_z0); + } if (nStubTP < TP_minNStub || nStubLayerTP < TP_minNLayersStub) continue; // nStub cut not included in denominator of efficiency plots @@ -623,7 +683,7 @@ void Phase2OTValidateTracks::analyze(const edm::Event &iEvent, const edm::EventS iEvent); // Regular L1 Tracks } } // end loop over tracking particles - n_trackParts->Fill(nTrackParts); + trackParts_Num->Fill(nTrackParts); nTrackParts = 0; } // end of method @@ -641,6 +701,7 @@ void Phase2OTValidateTracks::bookHistograms(DQMStore::IBooker &iBooker, edm::ParameterSet psEffic_d0 = conf_.getParameter("TH1Effic_d0"); edm::ParameterSet psDisEffic_d0 = conf_.getParameter("TH1DisEffic_d0"); edm::ParameterSet psEffic_Lxy = conf_.getParameter("TH1Effic_Lxy"); + edm::ParameterSet psEffic_displaced_Lxy = conf_.getParameter("TH1displacedEffic_Lxy"); edm::ParameterSet psEffic_z0 = conf_.getParameter("TH1Effic_z0"); edm::ParameterSet psRes_pt = conf_.getParameter("TH1Res_pt"); edm::ParameterSet psRes_eta = conf_.getParameter("TH1Res_eta"); @@ -661,7 +722,7 @@ void Phase2OTValidateTracks::bookHistograms(DQMStore::IBooker &iBooker, trackParts_Pt = book1DFromPS(iBooker, "trackParts_Pt", psTrackParts_Pt, "p_{T} [GeV]", "# tracking particles"); trackParts_Eta = book1DFromPS(iBooker, "trackParts_Eta", psTrackParts_Eta, "#eta", "# tracking particles"); trackParts_Phi = book1DFromPS(iBooker, "trackParts_Phi", psTrackParts_Phi, "#phi", "# tracking particles"); - trackParts_Num = book1DFromPS(iBooker, "trackParts_Num", psTrackParts_Phi, "# track particles per event", "# tracking particles"); + trackParts_Num = book1DFromPS(iBooker, "trackParts_Num", n_trackParticles, "# track particles per event", "# tracking particles"); // Nominal L1TF: efficiency ingredients (denominator + matched numerator) iBooker.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/EfficiencyIngredients"); @@ -708,13 +769,14 @@ void Phase2OTValidateTracks::bookHistograms(DQMStore::IBooker &iBooker, tp_eta_for_dis = book1DFromPS(iBooker, "tp_eta_for_dis", psEffic_eta, "#eta", "# tracking particles"); tp_d0_for_dis = book1DFromPS(iBooker, "tp_d0_for_dis", psDisEffic_d0, "d_{0} [cm]", "# tracking particles"); tp_z0_for_dis = book1DFromPS(iBooker, "tp_z0_for_dis", psEffic_z0, "z_{0} [cm]", "# tracking particles"); + tp_Lxy_for_dis = book1DFromPS(iBooker, "tp_Lxy_for_dis", psEffic_displaced_Lxy, "L_{xy} [cm]", "# tracking particles"); // Numerator: matched displaced TPs match_displaced_tp_pt = book1DFromPS(iBooker, "match_displaced_tp_pt", psEffic_pt, "p_{T} [GeV]", "# matched extended tracking particles"); match_displaced_tp_pt_zoom = book1DFromPS(iBooker, "match_displaced_tp_pt_zoom", psEffic_pt_zoom, "p_{T} [GeV]", "# matched extended tracking particles"); match_displaced_tp_eta = book1DFromPS(iBooker, "match_displaced_tp_eta", psEffic_eta, "#eta", "# matched extended tracking particles"); match_displaced_tp_d0 = book1DFromPS(iBooker, "match_displaced_tp_d0", psDisEffic_d0, "d_{0} [cm]", "# matched extended tracking particles"); - match_displaced_tp_Lxy = book1DFromPS(iBooker, "match_displaced_tp_Lxy", psEffic_Lxy, "L_{xy} [cm]", "# matched extended tracking particles"); + match_displaced_tp_Lxy = book1DFromPS(iBooker, "match_displaced_tp_Lxy", psEffic_displaced_Lxy, "L_{xy} [cm]", "# matched extended tracking particles"); match_displaced_tp_z0 = book1DFromPS(iBooker, "match_displaced_tp_z0", psEffic_z0, "z_{0} [cm]", "# matched extended tracking particles"); // Extended L1TF (Displaced): residual distributions @@ -738,6 +800,16 @@ void Phase2OTValidateTracks::bookHistograms(DQMStore::IBooker &iBooker, // Extended L1TF (Prompt): efficiency ingredients (matched prompt TPs) iBooker.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Prompt/EfficiencyIngredients"); + + // Denominator: prompt TP selection + tp_pt_for_prompt = book1DFromPS(iBooker, "tp_pt_for_prompt", psEffic_pt, "p_{T} [GeV]", "# tracking particles"); + tp_pt_zoom_for_prompt = book1DFromPS(iBooker, "tp_pt_zoom_for_prompt", psEffic_pt_zoom, "p_{T} [GeV]", "# tracking particles"); + tp_eta_for_prompt = book1DFromPS(iBooker, "tp_eta_for_prompt", psEffic_eta, "#eta", "# tracking particles"); + tp_d0_for_prompt = book1DFromPS(iBooker, "tp_d0_for_prompt", psEffic_d0, "d_{0} [cm]", "# tracking particles"); + tp_Lxy_for_prompt = book1DFromPS(iBooker, "tp_Lxy_for_prompt", psEffic_Lxy, "L_{xy} [cm]", "# tracking particles"); + tp_z0_for_prompt = book1DFromPS(iBooker, "tp_z0_for_prompt", psEffic_z0, "z_{0} [cm]", "# tracking particles"); + + // Numerator: matched prompt TPs match_prompt_tp_pt = book1DFromPS(iBooker, "match_prompt_tp_pt", psEffic_pt, "p_{T} [GeV]", "# matched tracking particles"); match_prompt_tp_pt_zoom = book1DFromPS(iBooker, "match_prompt_tp_pt_zoom", psEffic_pt_zoom, "p_{T} [GeV]", "# matched tracking particles"); match_prompt_tp_eta = book1DFromPS(iBooker, "match_prompt_tp_eta", psEffic_eta, "#eta", "# matched tracking particles"); @@ -770,132 +842,39 @@ void Phase2OTValidateTracks::bookHistograms(DQMStore::IBooker &iBooker, void Phase2OTValidateTracks::fillDescriptions(edm::ConfigurationDescriptions &descriptions) { // OuterTrackerMonitorTrackingParticles edm::ParameterSetDescription desc; - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 45); - psd0.add("xmax", 3); - psd0.add("xmin", -3); - desc.add("TH1TrackParts_Eta", psd0); - } - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 60); - psd0.add("xmax", 3.141592653589793); - psd0.add("xmin", -3.141592653589793); - desc.add("TH1TrackParts_Phi", psd0); - } - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 45); - psd0.add("xmax", 100); - psd0.add("xmin", 0); - desc.add("TH1TrackParts_Pt", psd0); - } - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 200); - psd0.add("xmax", 0.5); - psd0.add("xmin", -0.5); - desc.add("TH1Res_ptRel", psd0); - } - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 50); - psd0.add("xmax", 100); - psd0.add("xmin", 0); - desc.add("TH1Effic_pt", psd0); - } - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 50); - psd0.add("xmax", 10); - psd0.add("xmin", 0); - desc.add("TH1Effic_pt_zoom", psd0); - } - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 50); - psd0.add("xmax", 2.5); - psd0.add("xmin", -2.5); - desc.add("TH1Effic_eta", psd0); - } - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 101); - psd0.add("xmax", 0.15); - psd0.add("xmin", -0.15); - desc.add("TH1Effic_d0", psd0); - } - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 101); - psd0.add("xmax", 10); - psd0.add("xmin", -10); - desc.add("TH1DisEffic_d0", psd0); - } - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 25); - psd0.add("xmax", 1.0); - psd0.add("xmin", 0); - desc.add("TH1Effic_Lxy", psd0); - } - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 40); - psd0.add("xmax", 16); - psd0.add("xmin", -16); - desc.add("TH1Effic_z0", psd0); - } - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 100); - psd0.add("xmax", 0.2); - psd0.add("xmin", -0.2); - desc.add("TH1Res_pt", psd0); - } - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 100); - psd0.add("xmax", 0.01); - psd0.add("xmin", -0.01); - desc.add("TH1Res_eta", psd0); - } - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 100); - psd0.add("xmax", 0.01); - psd0.add("xmin", -0.01); - desc.add("TH1Res_phi", psd0); - } - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 100); - psd0.add("xmax", 1.0); - psd0.add("xmin", -1.0); - desc.add("TH1Res_z0", psd0); - } - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 100); - psd0.add("xmax", 0.05); - psd0.add("xmin", -0.05); - desc.add("TH1Res_d0", psd0); - } - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 101); - psd0.add("xmax", 2.0); - psd0.add("xmin", -2.0); - desc.add("TH1Resdisplaced_d0", psd0); - } - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 100); - psd0.add("xmax", 600.0); - psd0.add("xmin", 0.0); - desc.add("n_trackParticles", psd0); - } + auto addHist = [&desc](const std::string& name, int bins, double xmin, double xmax) { + edm::ParameterSetDescription psd; + psd.add("Nbinsx", bins); + psd.add("xmin", xmin); + psd.add("xmax", xmax); + desc.add(name, psd); + }; + + // Tracking particle kinematics + addHist("TH1TrackParts_Eta", 45, -3.0, 3.0); + addHist("TH1TrackParts_Phi", 60, -3.141592653589793, 3.141592653589793); + addHist("TH1TrackParts_Pt", 45, 0.0, 100.0); + addHist("n_trackParticles", 100, 0.0, 600.0); + + // Efficiency plots + addHist("TH1Effic_pt", 50, 0.0, 100.0); + addHist("TH1Effic_pt_zoom", 50, 0.0, 10.0); + addHist("TH1Effic_eta", 50, -2.5, 2.5); + addHist("TH1Effic_d0", 101, -0.15, 0.15); + addHist("TH1DisEffic_d0", 101, -10.0, 10.0); + addHist("TH1Effic_Lxy", 25, 0.0, 1.0); + addHist("TH1displacedEffic_Lxy", 50, 0.0, 10.0); + addHist("TH1Effic_z0", 40, -16.0, 16.0); + + // Resolution plots + addHist("TH1Res_ptRel", 200, -0.5, 0.5); + addHist("TH1Res_pt", 100, -0.2, 0.2); + addHist("TH1Res_eta", 100, -0.01, 0.01); + addHist("TH1Res_phi", 100, -0.01, 0.01); + addHist("TH1Res_z0", 100, -1.0, 1.0); + addHist("TH1Res_d0", 100, -0.05, 0.05); + addHist("TH1Resdisplaced_d0", 101, -2.0, 2.0); + desc.add("TopFolderName", "TrackerPhase2OTL1TrackV"); desc.add("trackingParticleToken", edm::InputTag("mix", "MergedTrackTruth")); desc.add("MCTruthStubInputTag", edm::InputTag("TTStubAssociatorFromPixelDigis", "StubAccepted")); From a07d05b24c05971f81dd1602f75b5e985e2a43cb Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Fri, 20 Mar 2026 22:21:48 +0100 Subject: [PATCH 33/61] update geometry and sample --- DQM/SiTrackerPhase2/test/dqmstep_phase2tk_cfg.py | 8 ++++---- DQM/SiTrackerPhase2/test/harvestingstep_phase2tk_cfg.py | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/DQM/SiTrackerPhase2/test/dqmstep_phase2tk_cfg.py b/DQM/SiTrackerPhase2/test/dqmstep_phase2tk_cfg.py index 122ace8aa0872..eedcadea709ce 100644 --- a/DQM/SiTrackerPhase2/test/dqmstep_phase2tk_cfg.py +++ b/DQM/SiTrackerPhase2/test/dqmstep_phase2tk_cfg.py @@ -10,7 +10,7 @@ # step3_pre4_inDQM.root - input for the next step in the DQM sequence, harvestingstep_phase2tk_cfg.py # Source: /local/reps/CMSSW/CMSSW/Configuration/Applications/python/ConfigBuilder.py,v -# with command line options: step3 --conditions auto:phase2_realistic_T21 -s RAW2DIGI,L1Reco,RECO,RECOSIM,VALIDATION:@phase2Validation,DQM:@phase2 --datatier DQMIO -n 10 --geometry Extended2026D98 --era Phase2C11M9 --eventcontent DQM --no_exec +# with command line options: step3 --conditions auto:phase2_realistic_T21 -s RAW2DIGI,L1Reco,RECO,RECOSIM,VALIDATION:@phase2Validation,DQM:@phase2 --datatier DQMIO -n 10 --geometry Extended2026D110 --era Phase2C11M9 --eventcontent DQM --no_exec import FWCore.ParameterSet.Config as cms from Configuration.Eras.Era_Phase2C11M9_cff import Phase2C11M9 @@ -23,7 +23,7 @@ process.load('FWCore.MessageService.MessageLogger_cfi') process.load('Configuration.EventContent.EventContent_cff') process.load('SimGeneral.MixingModule.mixNoPU_cfi') -process.load('Configuration.Geometry.GeometryExtendedRun4D98Reco_cff') +process.load('Configuration.Geometry.GeometryExtendedRun4D110Reco_cff') process.load('Configuration.StandardSequences.MagneticField_cff') process.load('Configuration.StandardSequences.RawToDigi_Data_cff') process.load('Configuration.StandardSequences.L1Reco_cff') @@ -41,7 +41,7 @@ # Input source process.source = cms.Source("PoolSource", - fileNames = cms.untracked.vstring('/store/relval/CMSSW_14_0_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_133X_mcRun4_realistic_v1_STD_2026D98_PU200_RV229-v1/2580000/0b2b0b0b-f312-48a8-9d46-ccbadc69bbfd.root'), + fileNames = cms.untracked.vstring('/store/relval/CMSSW_15_0_0/RelValTTbar_14TeV/GEN-SIM-RECO/PU_141X_mcRun4_realistic_v3_STD_Run4D110_PU-v3/2580000/01972f5c-64f5-4fea-890d-ffa3bb070b77.root'), secondaryFileNames = cms.untracked.vstring() ) @@ -99,7 +99,7 @@ for a in process.aliases: delattr(process, a) process.RandomNumberGeneratorService.restoreStateLabel=cms.untracked.string("randomEngineStateProducer") from Configuration.AlCa.GlobalTag import GlobalTag -process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase2_realistic_T21', '') +process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase2_realistic_T35', '') # Path and EndPath definitions process.raw2digi_step = cms.Path(process.RawToDigi) diff --git a/DQM/SiTrackerPhase2/test/harvestingstep_phase2tk_cfg.py b/DQM/SiTrackerPhase2/test/harvestingstep_phase2tk_cfg.py index 63acf9b4ca5a7..b6b1dd0204fa1 100644 --- a/DQM/SiTrackerPhase2/test/harvestingstep_phase2tk_cfg.py +++ b/DQM/SiTrackerPhase2/test/harvestingstep_phase2tk_cfg.py @@ -9,7 +9,7 @@ # DQM_V0001_R000000001__Global__CMSSW_X_Y_Z__RECO.root - for local visualization of histograms # Source: /local/reps/CMSSW/CMSSW/Configuration/Applications/python/ConfigBuilder.py,v -# with command line options: step4 --conditions auto:phase2_realistic_T21 -s HARVESTING:@phase2Validation+@phase2+@miniAODValidation+@miniAODDQM --scenario pp --filetype DQM --geometry ExtendedRun4D98 --era Phase2C11M9 --mc -n -1 --no_exec +# with command line options: step4 --conditions auto:phase2_realistic_T21 -s HARVESTING:@phase2Validation+@phase2+@miniAODValidation+@miniAODDQM --scenario pp --filetype DQM --geometry ExtendedRun4D110 --era Phase2C11M9 --mc -n -1 --no_exec import FWCore.ParameterSet.Config as cms from Configuration.Eras.Era_Phase2C11M9_cff import Phase2C11M9 @@ -22,7 +22,7 @@ process.load('FWCore.MessageService.MessageLogger_cfi') process.load('Configuration.EventContent.EventContent_cff') process.load('SimGeneral.MixingModule.mixNoPU_cfi') -process.load('Configuration.Geometry.GeometryExtendedRun4D98Reco_cff') +process.load('Configuration.Geometry.GeometryExtendedRun4D110Reco_cff') process.load('Configuration.StandardSequences.MagneticField_cff') process.load('Configuration.StandardSequences.DQMSaverAtRunEnd_cff') process.load('Configuration.StandardSequences.Harvesting_cff') @@ -80,7 +80,7 @@ # Other statements from Configuration.AlCa.GlobalTag import GlobalTag -process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase2_realistic_T21', '') +process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase2_realistic_T35', '') # Load your sidecar client process.load('Validation.SiTrackerPhase2V.Phase2OTEffClient_cff') From cfc35b0a0247776ad1cf05f962ce31df87ad3b31 Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Fri, 20 Mar 2026 22:29:05 +0100 Subject: [PATCH 34/61] add missing histograms for efficiency plots --- .../python/Phase2OTEffClient_cff.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Validation/SiTrackerPhase2V/python/Phase2OTEffClient_cff.py b/Validation/SiTrackerPhase2V/python/Phase2OTEffClient_cff.py index cdaf807180185..279e169a51fd2 100644 --- a/Validation/SiTrackerPhase2V/python/Phase2OTEffClient_cff.py +++ b/Validation/SiTrackerPhase2V/python/Phase2OTEffClient_cff.py @@ -27,13 +27,12 @@ # Prompt # Note: If Prompt/Displaced use different ingredient names, ensure they match here. - # Assuming the histogram names in ROOT are "match_prompt_tp_eta", etc. - "FinalEfficiency/EtaEfficiency '#eta efficiency;tracking particle #eta;Efficiency' EfficiencyIngredients/match_prompt_tp_eta EfficiencyIngredients/tp_eta", - "FinalEfficiency/PtEfficiency 'p_{T} efficiency;p_{T} [GeV];Efficiency' EfficiencyIngredients/match_prompt_tp_pt EfficiencyIngredients/tp_pt", - "FinalEfficiency/PtEfficiencyZoom 'p_{T} efficiency;p_{T} [GeV];Efficiency' EfficiencyIngredients/match_prompt_tp_pt_zoom EfficiencyIngredients/tp_pt_zoom", - "FinalEfficiency/d0Efficiency 'd_{0} efficiency;d_{0} [cm];Efficiency' EfficiencyIngredients/match_prompt_tp_d0 EfficiencyIngredients/tp_d0", - "FinalEfficiency/LxyEfficiency 'L_{xy} efficiency;L_{xy} [cm];Efficiency' EfficiencyIngredients/match_prompt_tp_Lxy EfficiencyIngredients/tp_Lxy", - "FinalEfficiency/z0Efficiency 'z_{0} efficiency;z_{0} [cm];Efficiency' EfficiencyIngredients/match_prompt_tp_z0 EfficiencyIngredients/tp_z0", + "FinalEfficiency/EtaEfficiency '#eta efficiency;tracking particle #eta;Efficiency' EfficiencyIngredients/match_prompt_tp_eta EfficiencyIngredients/tp_eta_for_prompt", + "FinalEfficiency/PtEfficiency 'p_{T} efficiency;p_{T} [GeV];Efficiency' EfficiencyIngredients/match_prompt_tp_pt EfficiencyIngredients/tp_pt_for_prompt", + "FinalEfficiency/PtEfficiencyZoom 'p_{T} efficiency;p_{T} [GeV];Efficiency' EfficiencyIngredients/match_prompt_tp_pt_zoom EfficiencyIngredients/tp_pt_zoom_for_prompt", + "FinalEfficiency/d0Efficiency 'd_{0} efficiency;d_{0} [cm];Efficiency' EfficiencyIngredients/match_prompt_tp_d0 EfficiencyIngredients/tp_d0_for_prompt", + "FinalEfficiency/LxyEfficiency 'L_{xy} efficiency;L_{xy} [cm];Efficiency' EfficiencyIngredients/match_prompt_tp_Lxy EfficiencyIngredients/tp_Lxy_for_prompt", + "FinalEfficiency/z0Efficiency 'z_{0} efficiency;z_{0} [cm];Efficiency' EfficiencyIngredients/match_prompt_tp_z0 EfficiencyIngredients/tp_z0_for_prompt", # Displaced "FinalEfficiency/EtaEfficiency '#eta efficiency;tracking particle #eta;Efficiency' EfficiencyIngredients/match_displaced_tp_eta EfficiencyIngredients/tp_eta_for_dis", From 0dda3df2a72549deab0eeb5e777827608098efcb Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Mon, 23 Mar 2026 22:51:34 +0100 Subject: [PATCH 35/61] Reduce code duplication in fillDescriptions --- .../plugins/Phase2OTValidateStub.cc | 231 +++++++++--------- 1 file changed, 112 insertions(+), 119 deletions(-) diff --git a/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateStub.cc b/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateStub.cc index 668fa9987f08f..d4ed670f12d72 100644 --- a/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateStub.cc +++ b/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateStub.cc @@ -17,7 +17,7 @@ // // Original Author: // -// Updated by: Brandi Skipworth, 2025 +// Updated by: Brandi Skipworth, 2026 // system include files #include @@ -93,7 +93,7 @@ class Phase2OTValidateStub : public DQMEDAnalyzer { MonitorElement* r_res_is2S_fw_endcap = nullptr; MonitorElement* r_res_isPS_bw_endcap = nullptr; MonitorElement* r_res_is2S_bw_endcap = nullptr; - + // delta_phi hists (PS / 2S, barrel vs endcap) MonitorElement* phi_res_isPS_barrel = nullptr; MonitorElement* phi_res_is2S_barrel = nullptr; @@ -213,7 +213,6 @@ float Phase2OTValidateStub::phiOverBendCorrection(bool isBarrel, float deltaR = std::abs(R1 - R0); float deltaZ = (R1 - R0 > 0) ? (Z1 - Z0) : -(Z1 - Z0); // if module parallel, tilt angle should // be π/2 and deltaZ would approach zero - // fill histograms here tiltAngle = atan(deltaR / std::abs(deltaZ)); } @@ -299,7 +298,7 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet int nStubs = 0; for (auto const& detSet : *Phase2TrackerDigiTTStubHandle) { - nStubs += detSet.size(); + nStubs += detSet.size(); } number_of_stubs->Fill(nStubs); @@ -490,7 +489,6 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet bend_res_is2S_barrel->Fill(bendRes); } } else { - // Fill Summary Endcap plots if (isPSmodule) { r_res_isPS_endcap->Fill(rRes); @@ -507,7 +505,7 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet // Forward Endcap bend_res_fw_endcap->Fill(bendRes); phi_res_fw_endcap->Fill(phiRes); - + // Set pointers to FW vectors phi_res_vec = &phi_res_fw_endcap_discs; bend_res_vec = &bend_res_fw_endcap_discs; @@ -521,7 +519,7 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet // Backward Endcap bend_res_bw_endcap->Fill(bendRes); phi_res_bw_endcap->Fill(phiRes); - + // Set pointers to BW vectors phi_res_vec = &phi_res_bw_endcap_discs; bend_res_vec = &bend_res_bw_endcap_discs; @@ -533,16 +531,16 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet } } } - + if (isBarrel) { if (layer >= 1 && layer <= trklet::N_LAYER) { - (*bend_res_vec)[layer - 1]->Fill(bendRes); - (*phi_res_vec)[layer - 1]->Fill(phiRes); + (*bend_res_vec)[layer - 1]->Fill(bendRes); + (*phi_res_vec)[layer - 1]->Fill(phiRes); } } else { if (layer >= 1 && layer <= trklet::N_DISK) { - (*bend_res_vec)[layer - 1]->Fill(bendRes); - (*phi_res_vec)[layer - 1]->Fill(phiRes); + (*bend_res_vec)[layer - 1]->Fill(bendRes); + (*phi_res_vec)[layer - 1]->Fill(phiRes); } } } // end loop over input stubs @@ -568,11 +566,6 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet else if (detid.subdetId() == StripSubdetector::TID) layer = static_cast(tTopo->layer(detid)) + 5; // fill in array as entries 6-10 - // treat genuine stubs separately (==2 is genuine, ==1 is not) - // Prioritize "Genuine" stubs (value 2) over "Combinatorial/Unknown" stubs (value 1) - // Check if the stub is NOT genuine (findTrackingParticlePtr is null) - // If it is NOT genuine, only record it as '1' if we haven't already found a genuine stub (value < 2) in this layer - // Otherwise (the stub IS genuine), strictly mark the layer as '2', overwriting any previous '1' if (MCTruthTTStubHandle->findTrackingParticlePtr(theStubRefs.at(is)).isNull() && hasStubInLayer[layer] < 2) hasStubInLayer[layer] = 1; else @@ -609,8 +602,7 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet if (nStubTP < TP_minNStub || nStubLayerTP < TP_minNLayersStub) continue; - // Find all clusters that can be associated to a tracking particle with at - // least one hit + // Find all clusters that can be associated to a tracking particle with at least one hit std::vector>, TTCluster>> associatedClusters = MCTruthTTClusterHandle->findTTClusterRefs(tp_ptr); @@ -619,12 +611,15 @@ void Phase2OTValidateStub::analyze(const edm::Event& iEvent, const edm::EventSet // Count genuine clusters first for (const auto& clus : associatedClusters) { - if (!MCTruthTTClusterHandle->isGenuine(clus)) continue; - DetId detid = clus->getDetId(); - if (detid.subdetId() == StripSubdetector::TOB) nValidClustersBarrel++; - else if (detid.subdetId() == StripSubdetector::TID) nValidClustersEndcap++; + if (!MCTruthTTClusterHandle->isGenuine(clus)) + continue; + DetId detid = clus->getDetId(); + if (detid.subdetId() == StripSubdetector::TOB) + nValidClustersBarrel++; + else if (detid.subdetId() == StripSubdetector::TID) + nValidClustersEndcap++; } - + // Define weights (1.0 / N) float weightBarrel = (nValidClustersBarrel > 0) ? 1.0f / nValidClustersBarrel : 0.0f; float weightEndcap = (nValidClustersEndcap > 0) ? 1.0f / nValidClustersEndcap : 0.0f; @@ -758,131 +753,129 @@ void Phase2OTValidateStub::bookHistograms(DQMStore::IBooker& iBooker, edm::Run c iBooker.setCurrentFolder(topFolderName_ + "/Residual"); // z residuals barrel (Summary) - z_res_isPS_barrel = book1DFromPS(iBooker, "#Delta z Barrel PS modules", ps_PS_Res, "tp_z - stub_z", "events"); - z_res_is2S_barrel = book1DFromPS(iBooker, "#Delta z Barrel 2S modules", ps_2S_Res, "tp_z - stub_z [cm]", "events"); - + z_res_isPS_barrel = book1DFromPS(iBooker, "#Delta z Barrel PS modules", ps_PS_Res, "tp_z - stub_z", "events"); + z_res_is2S_barrel = book1DFromPS(iBooker, "#Delta z Barrel 2S modules", ps_2S_Res, "tp_z - stub_z [cm]", "events"); + // r residuals endcaps (Summary) - r_res_isPS_endcap = book1DFromPS(iBooker, "#Delta r Endcaps PS modules", ps_PS_Res, "tp_r - stub_r [cm]", "events"); - r_res_is2S_endcap = book1DFromPS(iBooker, "#Delta r Endcaps 2S modules", ps_2S_Res, "tp_r - stub_r [cm]", "events"); - + r_res_isPS_endcap = book1DFromPS(iBooker, "#Delta r Endcaps PS modules", ps_PS_Res, "tp_r - stub_r [cm]", "events"); + r_res_is2S_endcap = book1DFromPS(iBooker, "#Delta r Endcaps 2S modules", ps_2S_Res, "tp_r - stub_r [cm]", "events"); + // phi residuals (PS / 2S, barrel vs endcaps) (Summary) - phi_res_isPS_barrel = book1DFromPS(iBooker, "#Delta #phi Barrel PS modules", psPhi_Res, "tp_phi - stub_phi", "events"); - phi_res_is2S_barrel = book1DFromPS(iBooker, "#Delta #phi Barrel 2S modules", psPhi_Res, "tp_phi - stub_phi", "events"); - phi_res_isPS_endcap = book1DFromPS(iBooker, "#Delta #phi Endcaps PS modules", psPhi_Res, "tp_phi - stub_phi", "events"); - phi_res_is2S_endcap = book1DFromPS(iBooker, "#Delta #phi Endcaps 2S modules", psPhi_Res, "tp_phi - stub_phi", "events"); + phi_res_isPS_barrel = + book1DFromPS(iBooker, "#Delta #phi Barrel PS modules", psPhi_Res, "tp_phi - stub_phi", "events"); + phi_res_is2S_barrel = + book1DFromPS(iBooker, "#Delta #phi Barrel 2S modules", psPhi_Res, "tp_phi - stub_phi", "events"); + phi_res_isPS_endcap = + book1DFromPS(iBooker, "#Delta #phi Endcaps PS modules", psPhi_Res, "tp_phi - stub_phi", "events"); + phi_res_is2S_endcap = + book1DFromPS(iBooker, "#Delta #phi Endcaps 2S modules", psPhi_Res, "tp_phi - stub_phi", "events"); // bend residuals (PS / 2S, barrel vs endcaps) (Summary) - bend_res_isPS_barrel = book1DFromPS(iBooker, "#Delta bend Barrel PS modules", psBend_Res, "tp_bend - stub_bend", "events"); - bend_res_is2S_barrel = book1DFromPS(iBooker, "#Delta bend Barrel 2S modules", psBend_Res, "tp_bend - stub_bend", "events"); - bend_res_isPS_endcap = book1DFromPS(iBooker, "#Delta bend Endcaps PS modules", psBend_Res, "tp_bend - stub_bend", "events"); - bend_res_is2S_endcap = book1DFromPS(iBooker, "#Delta bend Endcaps 2S modules", psBend_Res, "tp_bend - stub_bend", "events"); + bend_res_isPS_barrel = + book1DFromPS(iBooker, "#Delta bend Barrel PS modules", psBend_Res, "tp_bend - stub_bend", "events"); + bend_res_is2S_barrel = + book1DFromPS(iBooker, "#Delta bend Barrel 2S modules", psBend_Res, "tp_bend - stub_bend", "events"); + bend_res_isPS_endcap = + book1DFromPS(iBooker, "#Delta bend Endcaps PS modules", psBend_Res, "tp_bend - stub_bend", "events"); + bend_res_is2S_endcap = + book1DFromPS(iBooker, "#Delta bend Endcaps 2S modules", psBend_Res, "tp_bend - stub_bend", "events"); iBooker.setCurrentFolder(topFolderName_ + "/Residual/Detailed"); // Detailed Endcap R-Residuals (Split by FW/BW) - r_res_isPS_fw_endcap = book1DFromPS(iBooker, "#Delta r FW Endcap PS modules", ps_PS_Res, "tp_r - stub_r [cm]", "events"); - r_res_is2S_fw_endcap = book1DFromPS(iBooker, "#Delta r FW Endcap 2S modules", ps_2S_Res, "tp_r - stub_r [cm]", "events"); - r_res_isPS_bw_endcap = book1DFromPS(iBooker, "#Delta r BW Endcap PS modules", ps_PS_Res, "tp_r - stub_r [cm]", "events"); - r_res_is2S_bw_endcap = book1DFromPS(iBooker, "#Delta r BW Endcap 2S modules", ps_2S_Res, "tp_r - stub_r [cm]", "events"); + r_res_isPS_fw_endcap = + book1DFromPS(iBooker, "#Delta r FW Endcap PS modules", ps_PS_Res, "tp_r - stub_r [cm]", "events"); + r_res_is2S_fw_endcap = + book1DFromPS(iBooker, "#Delta r FW Endcap 2S modules", ps_2S_Res, "tp_r - stub_r [cm]", "events"); + r_res_isPS_bw_endcap = + book1DFromPS(iBooker, "#Delta r BW Endcap PS modules", ps_PS_Res, "tp_r - stub_r [cm]", "events"); + r_res_is2S_bw_endcap = + book1DFromPS(iBooker, "#Delta r BW Endcap 2S modules", ps_2S_Res, "tp_r - stub_r [cm]", "events"); // Detailed Endcap Phi/Bend (Split by FW/BW) - phi_res_fw_endcap = book1DFromPS(iBooker, "#Delta #phi FW Endcap", psPhi_Res, "tp_phi - stub_phi", "events"); - phi_res_bw_endcap = book1DFromPS(iBooker, "#Delta #phi BW Endcap", psPhi_Res, "tp_phi - stub_phi", "events"); + phi_res_fw_endcap = book1DFromPS(iBooker, "#Delta #phi FW Endcap", psPhi_Res, "tp_phi - stub_phi", "events"); + phi_res_bw_endcap = book1DFromPS(iBooker, "#Delta #phi BW Endcap", psPhi_Res, "tp_phi - stub_phi", "events"); bend_res_fw_endcap = book1DFromPS(iBooker, "#Delta bend FW Endcap", psBend_Res, "tp_bend - stub_bend", "events"); bend_res_bw_endcap = book1DFromPS(iBooker, "#Delta bend BW Endcap", psBend_Res, "tp_bend - stub_bend", "events"); - + // Barrel Layers (Per Layer) for (int i = 0; i < trklet::N_LAYER; ++i) { std::string layerParams = "L" + std::to_string(i + 1); - phi_res_barrel_layers[i] = book1DFromPS(iBooker, "#Delta #phi Barrel " + layerParams, psPhi_Res, "tp_phi - stub_phi", "events"); - bend_res_barrel_layers[i] = book1DFromPS(iBooker, "#Delta bend Barrel " + layerParams, psBend_Res, "tp_bend - stub_bend", "events"); + phi_res_barrel_layers[i] = + book1DFromPS(iBooker, "#Delta #phi Barrel " + layerParams, psPhi_Res, "tp_phi - stub_phi", "events"); + bend_res_barrel_layers[i] = + book1DFromPS(iBooker, "#Delta bend Barrel " + layerParams, psBend_Res, "tp_bend - stub_bend", "events"); } // Endcap Disks (Per Disk, Split FW/BW) for (int i = 0; i < trklet::N_DISK; ++i) { std::string diskParams = "D" + std::to_string(i + 1); - phi_res_fw_endcap_discs[i] = book1DFromPS(iBooker, "#Delta #phi FW Endcap " + diskParams, psPhi_Res, "tp_phi - stub_phi", "events"); - bend_res_fw_endcap_discs[i] = book1DFromPS(iBooker, "#Delta bend FW Endcap " + diskParams, psBend_Res, "tp_bend - stub_bend", "events"); - phi_res_bw_endcap_discs[i] = book1DFromPS(iBooker, "#Delta #phi BW Endcap " + diskParams, psPhi_Res, "tp_phi - stub_phi", "events"); - bend_res_bw_endcap_discs[i] = book1DFromPS(iBooker, "#Delta bend BW Endcap " + diskParams, psBend_Res, "tp_bend - stub_bend", "events"); + phi_res_fw_endcap_discs[i] = + book1DFromPS(iBooker, "#Delta #phi FW Endcap " + diskParams, psPhi_Res, "tp_phi - stub_phi", "events"); + bend_res_fw_endcap_discs[i] = + book1DFromPS(iBooker, "#Delta bend FW Endcap " + diskParams, psBend_Res, "tp_bend - stub_bend", "events"); + phi_res_bw_endcap_discs[i] = + book1DFromPS(iBooker, "#Delta #phi BW Endcap " + diskParams, psPhi_Res, "tp_phi - stub_phi", "events"); + bend_res_bw_endcap_discs[i] = + book1DFromPS(iBooker, "#Delta bend BW Endcap " + diskParams, psBend_Res, "tp_bend - stub_bend", "events"); } // 1D plots for stub efficiency vs pT iBooker.setCurrentFolder(topFolderName_ + "/EfficiencyIngredients"); - gen_clusters_barrel = book1DFromPS(iBooker, "gen_clusters_barrel", psEffic_pt, "p_{T} [GeV]", "# tracking particles"); - gen_clusters_if_stub_barrel = book1DFromPS(iBooker, "gen_clusters_if_stub_barrel", psEffic_pt, "p_{T} [GeV]", "# tracking particles"); - gen_clusters_endcaps = book1DFromPS(iBooker, "gen_clusters_endcaps", psEffic_pt, "p_{T} [GeV]", "# tracking particles"); - gen_clusters_if_stub_endcaps = book1DFromPS(iBooker, "gen_clusters_if_stub_endcaps", psEffic_pt, "p_{T} [GeV]", "# tracking particles"); - - gen_clusters_zoom_barrel = book1DFromPS(iBooker, "gen_clusters_zoom_barrel", psEffic_pt_zoom, "p_{T} [GeV]", "# tracking particles"); - gen_clusters_if_stub_zoom_barrel = book1DFromPS(iBooker, "gen_clusters_if_stub_zoom_barrel", psEffic_pt_zoom, "p_{T} [GeV]", "# tracking particles"); - gen_clusters_zoom_endcaps = book1DFromPS(iBooker, "gen_clusters_zoom_endcaps", psEffic_pt_zoom, "p_{T} [GeV]", "# tracking particles"); - gen_clusters_if_stub_zoom_endcaps= book1DFromPS(iBooker, "gen_clusters_if_stub_zoom_endcaps",psEffic_pt_zoom, "p_{T} [GeV]", "# tracking particles"); + gen_clusters_barrel = book1DFromPS(iBooker, "gen_clusters_barrel", psEffic_pt, "p_{T} [GeV]", "# tracking particles"); + gen_clusters_if_stub_barrel = + book1DFromPS(iBooker, "gen_clusters_if_stub_barrel", psEffic_pt, "p_{T} [GeV]", "# tracking particles"); + gen_clusters_endcaps = + book1DFromPS(iBooker, "gen_clusters_endcaps", psEffic_pt, "p_{T} [GeV]", "# tracking particles"); + gen_clusters_if_stub_endcaps = + book1DFromPS(iBooker, "gen_clusters_if_stub_endcaps", psEffic_pt, "p_{T} [GeV]", "# tracking particles"); + + gen_clusters_zoom_barrel = + book1DFromPS(iBooker, "gen_clusters_zoom_barrel", psEffic_pt_zoom, "p_{T} [GeV]", "# tracking particles"); + gen_clusters_if_stub_zoom_barrel = + book1DFromPS(iBooker, "gen_clusters_if_stub_zoom_barrel", psEffic_pt_zoom, "p_{T} [GeV]", "# tracking particles"); + gen_clusters_zoom_endcaps = + book1DFromPS(iBooker, "gen_clusters_zoom_endcaps", psEffic_pt_zoom, "p_{T} [GeV]", "# tracking particles"); + gen_clusters_if_stub_zoom_endcaps = book1DFromPS( + iBooker, "gen_clusters_if_stub_zoom_endcaps", psEffic_pt_zoom, "p_{T} [GeV]", "# tracking particles"); } void Phase2OTValidateStub::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { // Phase2OTValidateStub edm::ParameterSetDescription desc; - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 900); - psd0.add("xmax", 300); - psd0.add("xmin", -300); - psd0.add("Nbinsy", 900); - psd0.add("ymax", 120); - psd0.add("ymin", 0); - desc.add("TH2TTStub_RZ", psd0); - } - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 100); - psd0.add("xmax", 25000); - psd0.add("xmin", 0); - desc.add("TH1NStubs", psd0); - } - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 99); - psd0.add("xmax", 5.5); - psd0.add("xmin", -5.5); - desc.add("TH1_2S_Res", psd0); - } - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 99); - psd0.add("xmax", 2.0); - psd0.add("xmin", -2.0); - desc.add("TH1_PS_Res", psd0); - } - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 100); - psd0.add("xmax", 0.025); - psd0.add("xmin", -0.025); - desc.add("TH1Phi_Res", psd0); - } - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 59); - psd0.add("xmax", 5.0); - psd0.add("xmin", -5.5); - desc.add("TH1Bend_Res", psd0); - } - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 50); - psd0.add("xmax", 100); - psd0.add("xmin", 0); - desc.add("TH1Effic_pt", psd0); - } - { - edm::ParameterSetDescription psd0; - psd0.add("Nbinsx", 50); - psd0.add("xmax", 10); - psd0.add("xmin", 0); - desc.add("TH1Effic_pt_zoom", psd0); - } + // Helper for 1D histograms + auto addHist = [&desc](const std::string &name, int bins, double xmin, double xmax) { + edm::ParameterSetDescription psd; + psd.add("Nbinsx", bins); + psd.add("xmin", xmin); + psd.add("xmax", xmax); + desc.add(name, psd); + }; + + // Helper for 2D histograms + auto addHist2D = [&desc](const std::string &name, int binsX, double xmin, double xmax, int binsY, double ymin, double ymax) { + edm::ParameterSetDescription psd; + psd.add("Nbinsx", binsX); + psd.add("xmin", xmin); + psd.add("xmax", xmax); + psd.add("Nbinsy", binsY); + psd.add("ymin", ymin); + psd.add("ymax", ymax); + desc.add(name, psd); + }; + + // 2D Histograms + addHist2D("TH2TTStub_RZ", 900, -300.0, 300.0, 900, 0.0, 120.0); + + // 1D Histograms + addHist("TH1NStubs", 100, 0.0, 25000.0); + addHist("TH1_2S_Res", 99, -5.5, 5.5); + addHist("TH1_PS_Res", 99, -2.0, 2.0); + addHist("TH1Phi_Res", 100, -0.025, 0.025); + addHist("TH1Bend_Res", 59, -5.5, 5.0); + addHist("TH1Effic_pt", 50, 0.0, 100.0); + addHist("TH1Effic_pt_zoom", 50, 0.0, 10.0); desc.add("TopFolderName", "TrackerPhase2OTStubV"); desc.add("TTStubs", edm::InputTag("TTStubsFromPhase2TrackerDigis", "StubAccepted")); From f3cba77734b7f83f919f07b111fea3929543907e Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Mon, 23 Mar 2026 22:54:59 +0100 Subject: [PATCH 36/61] updated header comments --- .../interface/TrackerPhase2HistUtil.h | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h b/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h index 6b6820bb39c18..19f9bfad043cc 100644 --- a/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h +++ b/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h @@ -1,7 +1,8 @@ // TrackerPhase2HistUtil.h // ----------------------------------------------------------------------------- -// Helper utility for producing efficiency MonitorElements in Phase-2 tracker +// Helper utility for booking 1D histograms from ParameterSets and filling +// resolution MonitorElements (using standard deviations) in Phase-2 tracker // validation & harvesting code. // // Author: Brandi Skipworth @@ -26,12 +27,13 @@ namespace phase2tkutil { inline void fillResolutionFromVec(const std::vector& srcVec, dqm::legacy::MonitorElement* destME, const std::string& yAxisTitle) { - if (!destME) return; - + if (!destME) + return; + // Check if any source elements are missing if (std::find(srcVec.begin(), srcVec.end(), nullptr) != srcVec.end()) { - edm::LogWarning("TrackerPhase2HistUtil") << "Missing source ME for resolution: " << destME->getName(); - return; + edm::LogWarning("TrackerPhase2HistUtil") << "Missing source ME for resolution: " << destME->getName(); + return; } TH1* hDest = destME->getTH1(); @@ -42,20 +44,20 @@ namespace phase2tkutil { } for (size_t i = 0; i < srcVec.size(); ++i) { - TH1* hSrc = srcVec[i]->getTH1(); - // Bin 1 in destination corresponds to index 0 in vector - hDest->SetBinContent(i + 1, hSrc->GetStdDev()); - hDest->SetBinError(i + 1, hSrc->GetStdDevError()); + TH1* hSrc = srcVec[i]->getTH1(); + // Bin 1 in destination corresponds to index 0 in vector + hDest->SetBinContent(i + 1, hSrc->GetStdDev()); + hDest->SetBinError(i + 1, hSrc->GetStdDevError()); } } - inline dqm::legacy::MonitorElement* book1DFromPS( - dqm::legacy::DQMStore::IBooker& iBooker, - const std::string& name, - const edm::ParameterSet& ps, - const char* xaxis, - const char* yaxis) { - auto h = iBooker.book1D(name, name, + inline dqm::legacy::MonitorElement* book1DFromPS(dqm::legacy::DQMStore::IBooker& iBooker, + const std::string& name, + const edm::ParameterSet& ps, + const char* xaxis, + const char* yaxis) { + auto h = iBooker.book1D(name, + name, ps.getParameter("Nbinsx"), ps.getParameter("xmin"), ps.getParameter("xmax")); From ee2022cb56e717296d2849c2bbac5859b33babb9 Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Mon, 23 Mar 2026 22:56:13 +0100 Subject: [PATCH 37/61] updates from running code-format --- .../plugins/Phase2OTHarvestTracks.cc | 205 +++++++++++++----- 1 file changed, 156 insertions(+), 49 deletions(-) diff --git a/Validation/SiTrackerPhase2V/plugins/Phase2OTHarvestTracks.cc b/Validation/SiTrackerPhase2V/plugins/Phase2OTHarvestTracks.cc index c4d04752be3d1..2d47cb74faadc 100644 --- a/Validation/SiTrackerPhase2V/plugins/Phase2OTHarvestTracks.cc +++ b/Validation/SiTrackerPhase2V/plugins/Phase2OTHarvestTracks.cc @@ -4,8 +4,10 @@ /** * This class is part of the Phase 2 Tracker validation framework and performs * the harvesting step for L1 tracks validation. It processes histograms - * created during the earlier validation steps to calculate efficiencies and - * resolutions for tracking performance. + * created during the earlier validation steps to calculate resolutions for + * tracking performance. Specifically it extracts standard deviations from + * resolution ingredients for Nominal, Extended Prompt, and Extended Displaced + * L1 tracks. * * Usage: * To generate histograms from this code, run the test configuration files @@ -13,7 +15,7 @@ * can then be analyzed or visualized. */ -// Updated by: Brandi Skipworth, 2025 +// Updated by: Brandi Skipworth, 2026 #include #include @@ -51,75 +53,180 @@ void Phase2OTHarvestTracks::dqmEndJob(DQMStore::IBooker &ibooker, DQMStore::IGet float eta_bins[] = {0.0, 0.7, 1.0, 1.2, 1.6, 2.0, 2.4}; int eta_binnum = 6; std::string eta_ranges[6] = {"eta0to0p7", "eta0p7to1", "eta1to1p2", "eta1p2to1p6", "eta1p6to2", "eta2to2p4"}; - + // nominal collection std::vector respt_pt2to3(6, nullptr), respt_pt3to8(6, nullptr), respt_pt8toInf(6, nullptr); - std::vector mereseta_vect(6, nullptr), meresphi_vect(6, nullptr), meresz0_vect(6, nullptr), meresd0_vect(6, nullptr); + std::vector mereseta_vect(6, nullptr), meresphi_vect(6, nullptr), meresz0_vect(6, nullptr), + meresd0_vect(6, nullptr); - std::vector prompt_respt_pt2to3(6, nullptr), prompt_respt_pt3to8(6, nullptr), prompt_respt_pt8toInf(6, nullptr); - std::vector prompt_mereseta_vect(6, nullptr), prompt_meresphi_vect(6, nullptr), prompt_meresz0_vect(6, nullptr), prompt_meresd0_vect(6, nullptr); + std::vector prompt_respt_pt2to3(6, nullptr), prompt_respt_pt3to8(6, nullptr), + prompt_respt_pt8toInf(6, nullptr); + std::vector prompt_mereseta_vect(6, nullptr), prompt_meresphi_vect(6, nullptr), + prompt_meresz0_vect(6, nullptr), prompt_meresd0_vect(6, nullptr); - std::vector displaced_respt_pt2to3(6, nullptr), displaced_respt_pt3to8(6, nullptr), displaced_respt_pt8toInf(6, nullptr); - std::vector displaced_mereseta_vect(6, nullptr), displaced_meresphi_vect(6, nullptr), displaced_meresz0_vect(6, nullptr), displaced_meresd0_vect(6, nullptr); + std::vector displaced_respt_pt2to3(6, nullptr), displaced_respt_pt3to8(6, nullptr), + displaced_respt_pt8toInf(6, nullptr); + std::vector displaced_mereseta_vect(6, nullptr), displaced_meresphi_vect(6, nullptr), + displaced_meresz0_vect(6, nullptr), displaced_meresd0_vect(6, nullptr); for (int i = 0; i < 6; i++) { std::string resIng = topFolderName_ + "/Nominal_L1TF/ResolutionIngredients/"; - respt_pt2to3[i] = igetter.get(resIng + "respt_" + eta_ranges[i] + "_pt2to3"); - respt_pt3to8[i] = igetter.get(resIng + "respt_" + eta_ranges[i] + "_pt3to8"); + respt_pt2to3[i] = igetter.get(resIng + "respt_" + eta_ranges[i] + "_pt2to3"); + respt_pt3to8[i] = igetter.get(resIng + "respt_" + eta_ranges[i] + "_pt3to8"); respt_pt8toInf[i] = igetter.get(resIng + "respt_" + eta_ranges[i] + "_pt8toInf"); - mereseta_vect[i] = igetter.get(resIng + "reseta_" + eta_ranges[i]); - meresphi_vect[i] = igetter.get(resIng + "resphi_" + eta_ranges[i]); - meresz0_vect[i] = igetter.get(resIng + "resz0_" + eta_ranges[i]); - meresd0_vect[i] = igetter.get(resIng + "resd0_" + eta_ranges[i]); + mereseta_vect[i] = igetter.get(resIng + "reseta_" + eta_ranges[i]); + meresphi_vect[i] = igetter.get(resIng + "resphi_" + eta_ranges[i]); + meresz0_vect[i] = igetter.get(resIng + "resz0_" + eta_ranges[i]); + meresd0_vect[i] = igetter.get(resIng + "resd0_" + eta_ranges[i]); std::string promptIng = topFolderName_ + "/Extended_L1TF/Prompt/ResolutionIngredients/"; - prompt_respt_pt2to3[i] = igetter.get(promptIng + "respt_prompt_" + eta_ranges[i] + "_pt2to3"); - prompt_respt_pt3to8[i] = igetter.get(promptIng + "respt_prompt_" + eta_ranges[i] + "_pt3to8"); + prompt_respt_pt2to3[i] = igetter.get(promptIng + "respt_prompt_" + eta_ranges[i] + "_pt2to3"); + prompt_respt_pt3to8[i] = igetter.get(promptIng + "respt_prompt_" + eta_ranges[i] + "_pt3to8"); prompt_respt_pt8toInf[i] = igetter.get(promptIng + "respt_prompt_" + eta_ranges[i] + "_pt8toInf"); - prompt_mereseta_vect[i] = igetter.get(promptIng + "reseta_prompt_" + eta_ranges[i]); - prompt_meresphi_vect[i] = igetter.get(promptIng + "resphi_prompt_" + eta_ranges[i]); - prompt_meresz0_vect[i] = igetter.get(promptIng + "resz0_prompt_" + eta_ranges[i]); - prompt_meresd0_vect[i] = igetter.get(promptIng + "resd0_prompt_" + eta_ranges[i]); + prompt_mereseta_vect[i] = igetter.get(promptIng + "reseta_prompt_" + eta_ranges[i]); + prompt_meresphi_vect[i] = igetter.get(promptIng + "resphi_prompt_" + eta_ranges[i]); + prompt_meresz0_vect[i] = igetter.get(promptIng + "resz0_prompt_" + eta_ranges[i]); + prompt_meresd0_vect[i] = igetter.get(promptIng + "resd0_prompt_" + eta_ranges[i]); std::string dispIng = topFolderName_ + "/Extended_L1TF/Displaced/ResolutionIngredients/"; - displaced_respt_pt2to3[i] = igetter.get(dispIng + "respt_displaced_" + eta_ranges[i] + "_pt2to3"); - displaced_respt_pt3to8[i] = igetter.get(dispIng + "respt_displaced_" + eta_ranges[i] + "_pt3to8"); + displaced_respt_pt2to3[i] = igetter.get(dispIng + "respt_displaced_" + eta_ranges[i] + "_pt2to3"); + displaced_respt_pt3to8[i] = igetter.get(dispIng + "respt_displaced_" + eta_ranges[i] + "_pt3to8"); displaced_respt_pt8toInf[i] = igetter.get(dispIng + "respt_displaced_" + eta_ranges[i] + "_pt8toInf"); - displaced_mereseta_vect[i] = igetter.get(dispIng + "reseta_displaced_" + eta_ranges[i]); - displaced_meresphi_vect[i] = igetter.get(dispIng + "resphi_displaced_" + eta_ranges[i]); - displaced_meresz0_vect[i] = igetter.get(dispIng + "resz0_displaced_" + eta_ranges[i]); - displaced_meresd0_vect[i] = igetter.get(dispIng + "resd0_displaced_" + eta_ranges[i]); + displaced_mereseta_vect[i] = igetter.get(dispIng + "reseta_displaced_" + eta_ranges[i]); + displaced_meresphi_vect[i] = igetter.get(dispIng + "resphi_displaced_" + eta_ranges[i]); + displaced_meresz0_vect[i] = igetter.get(dispIng + "resz0_displaced_" + eta_ranges[i]); + displaced_meresd0_vect[i] = igetter.get(dispIng + "resd0_displaced_" + eta_ranges[i]); } // Final Resolutions - Nominal ibooker.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/FinalResolution"); - phase2tkutil::fillResolutionFromVec(respt_pt2to3, ibooker.book1D("pTResVsEta_2-3", ";|#eta|;#sigma(#Delta p_{T}/p_{T})", eta_binnum, eta_bins), ""); - phase2tkutil::fillResolutionFromVec(respt_pt3to8, ibooker.book1D("pTResVsEta_3-8", ";|#eta|;#sigma(#Delta p_{T}/p_{T})", eta_binnum, eta_bins), ""); - phase2tkutil::fillResolutionFromVec(respt_pt8toInf, ibooker.book1D("pTResVsEta_8-inf", ";|#eta|;#sigma(#Delta p_{T}/p_{T})", eta_binnum, eta_bins), ""); - phase2tkutil::fillResolutionFromVec(mereseta_vect, ibooker.book1D("EtaResolution", ";|#eta|;#sigma(#Delta#eta)", eta_binnum, eta_bins), ""); - phase2tkutil::fillResolutionFromVec(meresphi_vect, ibooker.book1D("PhiResolution", ";|#eta|;#sigma(#Delta#phi)", eta_binnum, eta_bins), ""); - phase2tkutil::fillResolutionFromVec(meresz0_vect, ibooker.book1D("z0Resolution", ";|#eta|;#sigma(#Deltaz0) [cm]", eta_binnum, eta_bins), ""); - phase2tkutil::fillResolutionFromVec(meresd0_vect, ibooker.book1D("d0Resolution", ";|#eta|;#sigma(#Deltad_{0}) [cm]", eta_binnum, eta_bins), ""); + phase2tkutil::fillResolutionFromVec( + respt_pt2to3, + ibooker.book1D( + "pTResVsEta_2-3", "pT resolution vs |#eta| (2-3 GeV);|#eta|;#sigma(#Delta p_{T}/p_{T})", eta_binnum, eta_bins), + ""); + phase2tkutil::fillResolutionFromVec( + respt_pt3to8, + ibooker.book1D( + "pTResVsEta_3-8", "pT resolution vs |#eta| (3-8 GeV);|#eta|;#sigma(#Delta p_{T}/p_{T})", eta_binnum, eta_bins), + ""); + phase2tkutil::fillResolutionFromVec( + respt_pt8toInf, + ibooker.book1D("pTResVsEta_8-inf", + "pT resolution vs |#eta| (8-inf GeV);|#eta|;#sigma(#Delta p_{T}/p_{T})", + eta_binnum, + eta_bins), + ""); + phase2tkutil::fillResolutionFromVec( + mereseta_vect, + ibooker.book1D("EtaResolution", "#eta resolution vs |#eta|;|#eta|;#sigma(#Delta#eta)", eta_binnum, eta_bins), + ""); + phase2tkutil::fillResolutionFromVec( + meresphi_vect, + ibooker.book1D("PhiResolution", "#phi resolution vs |#eta|;|#eta|;#sigma(#Delta#phi)", eta_binnum, eta_bins), + ""); + phase2tkutil::fillResolutionFromVec( + meresz0_vect, + ibooker.book1D("z0Resolution", "z0 resolution vs |#eta|;|#eta|;#sigma(#Deltaz0) [cm]", eta_binnum, eta_bins), + ""); + phase2tkutil::fillResolutionFromVec( + meresd0_vect, + ibooker.book1D("d0Resolution", "d0 resolution vs |#eta|;|#eta|;#sigma(#Deltad_{0}) [cm]", eta_binnum, eta_bins), + ""); // Final Resolutions - Prompt ibooker.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Prompt/FinalResolution"); - phase2tkutil::fillResolutionFromVec(prompt_respt_pt2to3, ibooker.book1D("pTResVsEta_2-3_prompt", ";|#eta|;#sigma(#Delta p_{T}/p_{T})", eta_binnum, eta_bins), ""); - phase2tkutil::fillResolutionFromVec(prompt_respt_pt3to8, ibooker.book1D("pTResVsEta_3-8_prompt", ";|#eta|;#sigma(#Delta p_{T}/p_{T})", eta_binnum, eta_bins), ""); - phase2tkutil::fillResolutionFromVec(prompt_respt_pt8toInf, ibooker.book1D("pTResVsEta_8-inf_prompt", ";|#eta|;#sigma(#Delta p_{T}/p_{T})", eta_binnum, eta_bins), ""); - phase2tkutil::fillResolutionFromVec(prompt_mereseta_vect, ibooker.book1D("EtaResolution_prompt", ";|#eta|;#sigma(#Delta#eta)", eta_binnum, eta_bins), ""); - phase2tkutil::fillResolutionFromVec(prompt_meresphi_vect, ibooker.book1D("PhiResolution_prompt", ";|#eta|;#sigma(#Delta#phi)", eta_binnum, eta_bins), ""); - phase2tkutil::fillResolutionFromVec(prompt_meresz0_vect, ibooker.book1D("z0Resolution_prompt", ";|#eta|;#sigma(#Deltaz0) [cm]", eta_binnum, eta_bins), ""); - phase2tkutil::fillResolutionFromVec(prompt_meresd0_vect, ibooker.book1D("d0Resolution_prompt", ";|#eta|;#sigma(#Deltad_{0}) [cm]", eta_binnum, eta_bins), ""); + phase2tkutil::fillResolutionFromVec( + prompt_respt_pt2to3, + ibooker.book1D("pTResVsEta_2-3_prompt", + "Prompt pT resolution vs |#eta| (2-3 GeV);|#eta|;#sigma(#Delta p_{T}/p_{T})", + eta_binnum, + eta_bins), + ""); + phase2tkutil::fillResolutionFromVec( + prompt_respt_pt3to8, + ibooker.book1D("pTResVsEta_3-8_prompt", + "Prompt pT resolution vs |#eta| (3-8 GeV);|#eta|;#sigma(#Delta p_{T}/p_{T})", + eta_binnum, + eta_bins), + ""); + phase2tkutil::fillResolutionFromVec( + prompt_respt_pt8toInf, + ibooker.book1D("pTResVsEta_8-inf_prompt", + "Prompt pT resolution vs |#eta| (8-inf GeV);|#eta|;#sigma(#Delta p_{T}/p_{T})", + eta_binnum, + eta_bins), + ""); + phase2tkutil::fillResolutionFromVec( + prompt_mereseta_vect, + ibooker.book1D( + "EtaResolution_prompt", "Prompt #eta resolution vs |#eta|;|#eta|;#sigma(#Delta#eta)", eta_binnum, eta_bins), + ""); + phase2tkutil::fillResolutionFromVec( + prompt_meresphi_vect, + ibooker.book1D( + "PhiResolution_prompt", "Prompt #phi resolution vs |#eta|;|#eta|;#sigma(#Delta#phi)", eta_binnum, eta_bins), + ""); + phase2tkutil::fillResolutionFromVec( + prompt_meresz0_vect, + ibooker.book1D( + "z0Resolution_prompt", "Prompt z0 resolution vs |#eta|;|#eta|;#sigma(#Deltaz0) [cm]", eta_binnum, eta_bins), + ""); + phase2tkutil::fillResolutionFromVec(prompt_meresd0_vect, + ibooker.book1D("d0Resolution_prompt", + "Prompt d0 resolution vs |#eta|;|#eta|;#sigma(#Deltad_{0}) [cm]", + eta_binnum, + eta_bins), + ""); // Final Resolutions - Displaced ibooker.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Displaced/FinalResolution"); - phase2tkutil::fillResolutionFromVec(displaced_respt_pt2to3, ibooker.book1D("pTResVsEta_2-3_displaced", ";|#eta|;#sigma(#Delta p_{T}/p_{T})", eta_binnum, eta_bins), ""); - phase2tkutil::fillResolutionFromVec(displaced_respt_pt3to8, ibooker.book1D("pTResVsEta_3-8_displaced", ";|#eta|;#sigma(#Delta p_{T}/p_{T})", eta_binnum, eta_bins), ""); - phase2tkutil::fillResolutionFromVec(displaced_respt_pt8toInf, ibooker.book1D("pTResVsEta_8-inf_displaced", ";|#eta|;#sigma(#Delta p_{T}/p_{T})", eta_binnum, eta_bins), ""); - phase2tkutil::fillResolutionFromVec(displaced_mereseta_vect, ibooker.book1D("EtaResolution_displaced", ";|#eta|;#sigma(#Delta#eta)", eta_binnum, eta_bins), ""); - phase2tkutil::fillResolutionFromVec(displaced_meresphi_vect, ibooker.book1D("PhiResolution_displaced", ";|#eta|;#sigma(#Delta#phi)", eta_binnum, eta_bins), ""); - phase2tkutil::fillResolutionFromVec(displaced_meresz0_vect, ibooker.book1D("z0Resolution_displaced", ";|#eta|;#sigma(#Deltaz0) [cm]", eta_binnum, eta_bins), ""); - phase2tkutil::fillResolutionFromVec(displaced_meresd0_vect, ibooker.book1D("d0Resolution_displaced", ";|#eta|;#sigma(#Deltad_{0}) [cm]", eta_binnum, eta_bins), ""); + phase2tkutil::fillResolutionFromVec( + displaced_respt_pt2to3, + ibooker.book1D("pTResVsEta_2-3_displaced", + "Displaced pT resolution vs |#eta| (2-3 GeV);|#eta|;#sigma(#Delta p_{T}/p_{T})", + eta_binnum, + eta_bins), + ""); + phase2tkutil::fillResolutionFromVec( + displaced_respt_pt3to8, + ibooker.book1D("pTResVsEta_3-8_displaced", + "Displaced pT resolution vs |#eta| (3-8 GeV);|#eta|;#sigma(#Delta p_{T}/p_{T})", + eta_binnum, + eta_bins), + ""); + phase2tkutil::fillResolutionFromVec( + displaced_respt_pt8toInf, + ibooker.book1D("pTResVsEta_8-inf_displaced", + "Displaced pT resolution vs |#eta| (8-inf GeV);|#eta|;#sigma(#Delta p_{T}/p_{T})", + eta_binnum, + eta_bins), + ""); + phase2tkutil::fillResolutionFromVec(displaced_mereseta_vect, + ibooker.book1D("EtaResolution_displaced", + "Displaced #eta resolution vs |#eta|;|#eta|;#sigma(#Delta#eta)", + eta_binnum, + eta_bins), + ""); + phase2tkutil::fillResolutionFromVec(displaced_meresphi_vect, + ibooker.book1D("PhiResolution_displaced", + "Displaced #phi resolution vs |#eta|;|#eta|;#sigma(#Delta#phi)", + eta_binnum, + eta_bins), + ""); + phase2tkutil::fillResolutionFromVec(displaced_meresz0_vect, + ibooker.book1D("z0Resolution_displaced", + "Displaced z0 resolution vs |#eta|;|#eta|;#sigma(#Deltaz0) [cm]", + eta_binnum, + eta_bins), + ""); + phase2tkutil::fillResolutionFromVec( + displaced_meresd0_vect, + ibooker.book1D("d0Resolution_displaced", + "Displaced d0 resolution vs |#eta|;|#eta|;#sigma(#Deltad_{0}) [cm]", + eta_binnum, + eta_bins), + ""); } // end dqmEndJob #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" @@ -129,4 +236,4 @@ void Phase2OTHarvestTracks::fillDescriptions(edm::ConfigurationDescriptions &des desc.add("TopFolderName", "TrackerPhase2OTL1TrackV"); descriptions.add("Phase2OTHarvestTracks", desc); } -DEFINE_FWK_MODULE(Phase2OTHarvestTracks); \ No newline at end of file +DEFINE_FWK_MODULE(Phase2OTHarvestTracks); From f3d4e5d393f56877c936067ca67d97325291bafa Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Mon, 23 Mar 2026 23:01:08 +0100 Subject: [PATCH 38/61] updates from running code-format --- .../plugins/Phase2OTValidateTracks.cc | 287 ++++++++++-------- 1 file changed, 168 insertions(+), 119 deletions(-) diff --git a/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateTracks.cc b/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateTracks.cc index c90d6ed8e2512..2762acca17709 100644 --- a/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateTracks.cc +++ b/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateTracks.cc @@ -16,7 +16,7 @@ // Original Author: Emily MacDonald -// Updated by: Brandi Skipworth, 2025 +// Updated by: Brandi Skipworth, 2026 // system include files #include @@ -81,7 +81,7 @@ class Phase2OTValidateTracks : public DQMEDAnalyzer { MonitorElement *trackParts_Eta = nullptr; MonitorElement *trackParts_Phi = nullptr; MonitorElement *trackParts_Pt = nullptr; - MonitorElement *trackParts_Num = nullptr; + MonitorElement *trackParts_Num = nullptr; unsigned int nTrackParts = 0; // pT and eta for efficiency plots @@ -183,8 +183,7 @@ class Phase2OTValidateTracks : public DQMEDAnalyzer { edm::EDGetTokenT> ttTrackMCTruthToken_; // MC truth association map for tracks edm::EDGetTokenT> - ttTrackMCTruthExtendedToken_; // MC truth association map for extended - // tracks + ttTrackMCTruthExtendedToken_; // MC truth association map for extended tracks edm::EDGetTokenT>> ttStubToken_; // L1 Stub token edm::ESGetToken getTokenTrackerGeom_; // Tracker geometry token int L1Tk_minNStub; @@ -224,11 +223,11 @@ Phase2OTValidateTracks::Phase2OTValidateTracks(const edm::ParameterSet &iConfig) // particle TP_minNLayersStub = conf_.getParameter("TP_minNLayersStub"); // Minimum number of layers with stubs for the // tracking particle to be considered for matching - TP_minPt = conf_.getParameter("TP_minPt"); // min pT to consider matching - TP_maxEta = conf_.getParameter("TP_maxEta"); // max eta to consider matching - TP_maxZ0 = conf_.getParameter("TP_maxZ0"); // max vertZ (or z0) to consider matching - TP_maxLxy = conf_.getParameter("TP_maxLxy"); // max Lxy to consider prompt matching - TP_maxD0 = conf_.getParameter("TP_maxD0"); // max d0 to consider prompt matching + TP_minPt = conf_.getParameter("TP_minPt"); // min pT to consider matching + TP_maxEta = conf_.getParameter("TP_maxEta"); // max eta to consider matching + TP_maxZ0 = conf_.getParameter("TP_maxZ0"); // max vertZ (or z0) to consider matching + TP_maxLxy = conf_.getParameter("TP_maxLxy"); // max Lxy to consider prompt matching + TP_maxD0 = conf_.getParameter("TP_maxD0"); // max d0 to consider prompt matching } Phase2OTValidateTracks::~Phase2OTValidateTracks() = default; @@ -389,13 +388,11 @@ void Phase2OTValidateTracks::processTrackCollection( match_tp_pt_ptr = match_prompt_tp_pt; match_tp_pt_zoom_ptr = match_prompt_tp_pt_zoom; match_tp_Lxy_ptr = match_prompt_tp_Lxy; - - // Unconditional pointer assignment (cuts happen at Fill) match_tp_eta_ptr = match_prompt_tp_eta; match_tp_d0_ptr = match_prompt_tp_d0; match_tp_z0_ptr = match_prompt_tp_z0; - - // if extended, if "displaced" + + // if extended, if "displaced" } else { reseta_vect_ptr = &reseta_displaced_vect; resphi_vect_ptr = &resphi_displaced_vect; @@ -436,7 +433,7 @@ void Phase2OTValidateTracks::processTrackCollection( match_tp_pt_ptr = match_tp_pt; match_tp_pt_zoom_ptr = match_tp_pt_zoom; match_tp_Lxy_ptr = match_tp_Lxy; - + match_tp_eta_ptr = match_tp_eta; match_tp_d0_ptr = match_tp_d0; match_tp_z0_ptr = match_tp_z0; @@ -630,7 +627,7 @@ void Phase2OTValidateTracks::analyze(const edm::Event &iEvent, const edm::EventS tp_Lxy_for_prompt->Fill(tmp_tp_Lxy); } else { tp_Lxy_for_dis->Fill(tmp_tp_Lxy); - + // Displaced has NO Lxy cut at all, fill its eta, d0, z0 here tp_eta_for_dis->Fill(tmp_tp_eta); tp_d0_for_dis->Fill(tmp_tp_d0); @@ -659,7 +656,7 @@ void Phase2OTValidateTracks::analyze(const edm::Event &iEvent, const edm::EventS tp_eta->Fill(tmp_tp_eta); tp_d0->Fill(tmp_tp_d0); tp_z0->Fill(tmp_tp_z0); - + if (std::fabs(tmp_tp_d0) < TP_maxD0) { tp_eta_for_prompt->Fill(tmp_tp_eta); tp_d0_for_prompt->Fill(tmp_tp_d0); @@ -715,125 +712,177 @@ void Phase2OTValidateTracks::bookHistograms(DQMStore::IBooker &iBooker, using phase2tkutil::book1DFromPS; // |eta| bin labels for resolution ingredients - std::string ranges[6] = { "eta0to0p7", "eta0p7to1", "eta1to1p2", "eta1p2to1p6", "eta1p6to2", "eta2to2p4" }; - - // Tracking particle kinematics + std::string ranges[6] = {"eta0to0p7", "eta0p7to1", "eta1to1p2", "eta1p2to1p6", "eta1p6to2", "eta2to2p4"}; + + // Tracking particle kinematics iBooker.setCurrentFolder(topFolderName_ + "/trackParticles"); - trackParts_Pt = book1DFromPS(iBooker, "trackParts_Pt", psTrackParts_Pt, "p_{T} [GeV]", "# tracking particles"); - trackParts_Eta = book1DFromPS(iBooker, "trackParts_Eta", psTrackParts_Eta, "#eta", "# tracking particles"); - trackParts_Phi = book1DFromPS(iBooker, "trackParts_Phi", psTrackParts_Phi, "#phi", "# tracking particles"); - trackParts_Num = book1DFromPS(iBooker, "trackParts_Num", n_trackParticles, "# track particles per event", "# tracking particles"); - + trackParts_Pt = book1DFromPS(iBooker, "trackParts_Pt", psTrackParts_Pt, "p_{T} [GeV]", "# tracking particles"); + trackParts_Eta = book1DFromPS(iBooker, "trackParts_Eta", psTrackParts_Eta, "#eta", "# tracking particles"); + trackParts_Phi = book1DFromPS(iBooker, "trackParts_Phi", psTrackParts_Phi, "#phi", "# tracking particles"); + trackParts_Num = + book1DFromPS(iBooker, "trackParts_Num", n_trackParticles, "# track particles per event", "# tracking particles"); + // Nominal L1TF: efficiency ingredients (denominator + matched numerator) iBooker.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/EfficiencyIngredients"); // Denominator: all selected TPs - tp_pt = book1DFromPS(iBooker, "tp_pt", psEffic_pt, "p_{T} [GeV]", "# tracking particles"); + tp_pt = book1DFromPS(iBooker, "tp_pt", psEffic_pt, "p_{T} [GeV]", "# tracking particles"); tp_pt_zoom = book1DFromPS(iBooker, "tp_pt_zoom", psEffic_pt_zoom, "p_{T} [GeV]", "# tracking particles"); - tp_eta = book1DFromPS(iBooker, "tp_eta", psEffic_eta, "#eta", "# tracking particles"); - tp_d0 = book1DFromPS(iBooker, "tp_d0", psEffic_d0, "d_{0} [cm]", "# tracking particles"); - tp_Lxy = book1DFromPS(iBooker, "tp_Lxy", psEffic_Lxy, "L_{xy} [cm]", "# tracking particles"); - tp_z0 = book1DFromPS(iBooker, "tp_z0", psEffic_z0, "z_{0} [cm]", "# tracking particles"); + tp_eta = book1DFromPS(iBooker, "tp_eta", psEffic_eta, "#eta", "# tracking particles"); + tp_d0 = book1DFromPS(iBooker, "tp_d0", psEffic_d0, "d_{0} [cm]", "# tracking particles"); + tp_Lxy = book1DFromPS(iBooker, "tp_Lxy", psEffic_Lxy, "L_{xy} [cm]", "# tracking particles"); + tp_z0 = book1DFromPS(iBooker, "tp_z0", psEffic_z0, "z_{0} [cm]", "# tracking particles"); // Numerator: matched TPs - match_tp_pt = book1DFromPS(iBooker, "match_tp_pt", psEffic_pt, "p_{T} [GeV]", "# matched tracking particles"); - match_tp_pt_zoom = book1DFromPS(iBooker, "match_tp_pt_zoom", psEffic_pt_zoom, "p_{T} [GeV]", "# matched tracking particles"); - match_tp_eta = book1DFromPS(iBooker, "match_tp_eta", psEffic_eta, "#eta", "# matched tracking particles"); - match_tp_d0 = book1DFromPS(iBooker, "match_tp_d0", psEffic_d0, "d_{0} [cm]", "# matched tracking particles"); - match_tp_Lxy = book1DFromPS(iBooker, "match_tp_Lxy", psEffic_Lxy, "L_{xy} [cm]", "# matched tracking particles"); - match_tp_z0 = book1DFromPS(iBooker, "match_tp_z0", psEffic_z0, "z_{0} [cm]", "# matched tracking particles"); - + match_tp_pt = book1DFromPS(iBooker, "match_tp_pt", psEffic_pt, "p_{T} [GeV]", "# matched tracking particles"); + match_tp_pt_zoom = + book1DFromPS(iBooker, "match_tp_pt_zoom", psEffic_pt_zoom, "p_{T} [GeV]", "# matched tracking particles"); + match_tp_eta = book1DFromPS(iBooker, "match_tp_eta", psEffic_eta, "#eta", "# matched tracking particles"); + match_tp_d0 = book1DFromPS(iBooker, "match_tp_d0", psEffic_d0, "d_{0} [cm]", "# matched tracking particles"); + match_tp_Lxy = book1DFromPS(iBooker, "match_tp_Lxy", psEffic_Lxy, "L_{xy} [cm]", "# matched tracking particles"); + match_tp_z0 = book1DFromPS(iBooker, "match_tp_z0", psEffic_z0, "z_{0} [cm]", "# matched tracking particles"); + // Nominal L1TF: residual distributions iBooker.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/Residual"); - res_pt = book1DFromPS(iBooker, "res_pt", psRes_pt, "trk p_{T} - tp p_{T} [GeV]", "# tracking particles"); - res_eta = book1DFromPS(iBooker, "res_eta", psRes_eta, "trk #eta - tp #eta", "# tracking particles"); - res_ptRel = book1DFromPS(iBooker, "res_ptRel", psRes_ptRel, "Relative p_{T} [GeV]", "# tracking particles"); - d0_res_hist = book1DFromPS(iBooker, "res_d0", psRes_d0, "trk d_{0} - tp d_{0} [cm]","# tracking particles"); - + res_pt = book1DFromPS(iBooker, "res_pt", psRes_pt, "trk p_{T} - tp p_{T} [GeV]", "# tracking particles"); + res_eta = book1DFromPS(iBooker, "res_eta", psRes_eta, "trk #eta - tp #eta", "# tracking particles"); + res_ptRel = book1DFromPS(iBooker, "res_ptRel", psRes_ptRel, "Relative p_{T} [GeV]", "# tracking particles"); + d0_res_hist = book1DFromPS(iBooker, "res_d0", psRes_d0, "trk d_{0} - tp d_{0} [cm]", "# tracking particles"); + // Nominal L1TF: resolution vs eta and pT slices iBooker.setCurrentFolder(topFolderName_ + "/Nominal_L1TF/ResolutionIngredients"); for (int i = 0; i < 6; i++) { - reseta_vect[i] = book1DFromPS(iBooker, "reseta_" + ranges[i], psRes_eta, "#eta_{trk} - #eta_{tp}", "# tracking particles"); - resphi_vect[i] = book1DFromPS(iBooker, "resphi_" + ranges[i], psRes_phi, "#phi_{trk} - #phi_{tp}", "# tracking particles"); - resz0_vect[i] = book1DFromPS(iBooker, "resz0_" + ranges[i], psRes_z0, "z0_{trk} - z0_{tp} [cm]", "# tracking particles"); - resd0_vect[i] = book1DFromPS(iBooker, "resd0_" + ranges[i], psRes_d0, "d0_{trk} - d0_{tp} [cm]", "# tracking particles"); - respt_pt2to3[i] = book1DFromPS(iBooker, "respt_" + ranges[i] + "_pt2to3", psRes_pt, "(p_{T}(trk) - p_{T}(tp))/p_{T}(tp)", "# tracking particles"); - respt_pt3to8[i] = book1DFromPS(iBooker, "respt_" + ranges[i] + "_pt3to8", psRes_pt, "(p_{T}(trk) - p_{T}(tp))/p_{T}(tp)", "# tracking particles"); - respt_pt8toInf[i] = book1DFromPS(iBooker, "respt_" + ranges[i] + "_pt8toInf", psRes_pt, "(p_{T}(trk) - p_{T}(tp))/p_{T}(tp)", "# tracking particles"); + reseta_vect[i] = + book1DFromPS(iBooker, "reseta_" + ranges[i], psRes_eta, "#eta_{trk} - #eta_{tp}", "# tracking particles"); + resphi_vect[i] = + book1DFromPS(iBooker, "resphi_" + ranges[i], psRes_phi, "#phi_{trk} - #phi_{tp}", "# tracking particles"); + resz0_vect[i] = + book1DFromPS(iBooker, "resz0_" + ranges[i], psRes_z0, "z0_{trk} - z0_{tp} [cm]", "# tracking particles"); + resd0_vect[i] = + book1DFromPS(iBooker, "resd0_" + ranges[i], psRes_d0, "d0_{trk} - d0_{tp} [cm]", "# tracking particles"); + respt_pt2to3[i] = book1DFromPS(iBooker, + "respt_" + ranges[i] + "_pt2to3", + psRes_pt, + "(p_{T}(trk) - p_{T}(tp))/p_{T}(tp)", + "# tracking particles"); + respt_pt3to8[i] = book1DFromPS(iBooker, + "respt_" + ranges[i] + "_pt3to8", + psRes_pt, + "(p_{T}(trk) - p_{T}(tp))/p_{T}(tp)", + "# tracking particles"); + respt_pt8toInf[i] = book1DFromPS(iBooker, + "respt_" + ranges[i] + "_pt8toInf", + psRes_pt, + "(p_{T}(trk) - p_{T}(tp))/p_{T}(tp)", + "# tracking particles"); } - + // Extended L1TF (Displaced): efficiency ingredients iBooker.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Displaced/EfficiencyIngredients"); // Denominator: displaced TP selection - tp_pt_for_dis = book1DFromPS(iBooker, "tp_pt_for_dis", psEffic_pt, "p_{T} [GeV]", "# tracking particles"); - tp_pt_zoom_for_dis = book1DFromPS(iBooker, "tp_pt_zoom_for_dis", psEffic_pt_zoom, "p_{T} [GeV]", "# tracking particles"); - tp_eta_for_dis = book1DFromPS(iBooker, "tp_eta_for_dis", psEffic_eta, "#eta", "# tracking particles"); - tp_d0_for_dis = book1DFromPS(iBooker, "tp_d0_for_dis", psDisEffic_d0, "d_{0} [cm]", "# tracking particles"); - tp_z0_for_dis = book1DFromPS(iBooker, "tp_z0_for_dis", psEffic_z0, "z_{0} [cm]", "# tracking particles"); - tp_Lxy_for_dis = book1DFromPS(iBooker, "tp_Lxy_for_dis", psEffic_displaced_Lxy, "L_{xy} [cm]", "# tracking particles"); + tp_pt_for_dis = book1DFromPS(iBooker, "tp_pt_for_dis", psEffic_pt, "p_{T} [GeV]", "# tracking particles"); + tp_pt_zoom_for_dis = + book1DFromPS(iBooker, "tp_pt_zoom_for_dis", psEffic_pt_zoom, "p_{T} [GeV]", "# tracking particles"); + tp_eta_for_dis = book1DFromPS(iBooker, "tp_eta_for_dis", psEffic_eta, "#eta", "# tracking particles"); + tp_d0_for_dis = book1DFromPS(iBooker, "tp_d0_for_dis", psDisEffic_d0, "d_{0} [cm]", "# tracking particles"); + tp_z0_for_dis = book1DFromPS(iBooker, "tp_z0_for_dis", psEffic_z0, "z_{0} [cm]", "# tracking particles"); + tp_Lxy_for_dis = + book1DFromPS(iBooker, "tp_Lxy_for_dis", psEffic_displaced_Lxy, "L_{xy} [cm]", "# tracking particles"); // Numerator: matched displaced TPs - match_displaced_tp_pt = book1DFromPS(iBooker, "match_displaced_tp_pt", psEffic_pt, "p_{T} [GeV]", "# matched extended tracking particles"); - match_displaced_tp_pt_zoom = book1DFromPS(iBooker, "match_displaced_tp_pt_zoom", psEffic_pt_zoom, "p_{T} [GeV]", "# matched extended tracking particles"); - match_displaced_tp_eta = book1DFromPS(iBooker, "match_displaced_tp_eta", psEffic_eta, "#eta", "# matched extended tracking particles"); - match_displaced_tp_d0 = book1DFromPS(iBooker, "match_displaced_tp_d0", psDisEffic_d0, "d_{0} [cm]", "# matched extended tracking particles"); - match_displaced_tp_Lxy = book1DFromPS(iBooker, "match_displaced_tp_Lxy", psEffic_displaced_Lxy, "L_{xy} [cm]", "# matched extended tracking particles"); - match_displaced_tp_z0 = book1DFromPS(iBooker, "match_displaced_tp_z0", psEffic_z0, "z_{0} [cm]", "# matched extended tracking particles"); + match_displaced_tp_pt = book1DFromPS( + iBooker, "match_displaced_tp_pt", psEffic_pt, "p_{T} [GeV]", "# matched extended tracking particles"); + match_displaced_tp_pt_zoom = book1DFromPS( + iBooker, "match_displaced_tp_pt_zoom", psEffic_pt_zoom, "p_{T} [GeV]", "# matched extended tracking particles"); + match_displaced_tp_eta = + book1DFromPS(iBooker, "match_displaced_tp_eta", psEffic_eta, "#eta", "# matched extended tracking particles"); + match_displaced_tp_d0 = book1DFromPS( + iBooker, "match_displaced_tp_d0", psDisEffic_d0, "d_{0} [cm]", "# matched extended tracking particles"); + match_displaced_tp_Lxy = book1DFromPS( + iBooker, "match_displaced_tp_Lxy", psEffic_displaced_Lxy, "L_{xy} [cm]", "# matched extended tracking particles"); + match_displaced_tp_z0 = + book1DFromPS(iBooker, "match_displaced_tp_z0", psEffic_z0, "z_{0} [cm]", "# matched extended tracking particles"); // Extended L1TF (Displaced): residual distributions iBooker.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Displaced/Residual"); - res_displaced_d0 = book1DFromPS(iBooker, "res_displaced_d0", psRes_displaced_d0, "trk d_{0} - tp d_{0} [cm]", "# displaced tracks"); - res_displaced_eta = book1DFromPS(iBooker, "res_displaced_eta", psRes_eta, "#eta_{trk} - #eta_{tp}", "# tracking particles"); - res_displaced_pt = book1DFromPS(iBooker, "res_displaced_pt", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); - res_displaced_ptRel = book1DFromPS(iBooker, "res_displaced_ptRel", psRes_ptRel, "Relative p_{T} [GeV]", "# tracking particles"); + res_displaced_d0 = + book1DFromPS(iBooker, "res_displaced_d0", psRes_displaced_d0, "trk d_{0} - tp d_{0} [cm]", "# displaced tracks"); + res_displaced_eta = + book1DFromPS(iBooker, "res_displaced_eta", psRes_eta, "#eta_{trk} - #eta_{tp}", "# tracking particles"); + res_displaced_pt = + book1DFromPS(iBooker, "res_displaced_pt", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); + res_displaced_ptRel = + book1DFromPS(iBooker, "res_displaced_ptRel", psRes_ptRel, "Relative p_{T} [GeV]", "# tracking particles"); // Extended L1TF (Displaced): resolution vs eta and pT slices iBooker.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Displaced/ResolutionIngredients"); for (int i = 0; i < 6; i++) { - reseta_displaced_vect[i] = book1DFromPS(iBooker, "reseta_displaced_" + ranges[i], psRes_eta, "#eta_{trk} - #eta_{tp}", "# tracking particles"); - resphi_displaced_vect[i] = book1DFromPS(iBooker, "resphi_displaced_" + ranges[i], psRes_phi, "#phi_{trk} - #phi_{tp}", "# tracking particles"); - resd0_displaced_vect[i] = book1DFromPS(iBooker, "resd0_displaced_" + ranges[i], psRes_displaced_d0, "d0_{trk} - d0_{tp} [cm]", "# tracking particles"); - resz0_displaced_vect[i] = book1DFromPS(iBooker, "resz0_displaced_" + ranges[i], psRes_z0, "z0_{trk} - z0_{tp} [cm]", "# tracking particles"); - respt_displaced_pt2to3[i] = book1DFromPS(iBooker, "respt_displaced_" + ranges[i] + "_pt2to3", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); - respt_displaced_pt3to8[i] = book1DFromPS(iBooker, "respt_displaced_" + ranges[i] + "_pt3to8", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); - respt_displaced_pt8toInf[i] = book1DFromPS(iBooker, "respt_displaced_" + ranges[i] + "_pt8toInf", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); + reseta_displaced_vect[i] = book1DFromPS( + iBooker, "reseta_displaced_" + ranges[i], psRes_eta, "#eta_{trk} - #eta_{tp}", "# tracking particles"); + resphi_displaced_vect[i] = book1DFromPS( + iBooker, "resphi_displaced_" + ranges[i], psRes_phi, "#phi_{trk} - #phi_{tp}", "# tracking particles"); + resd0_displaced_vect[i] = book1DFromPS( + iBooker, "resd0_displaced_" + ranges[i], psRes_displaced_d0, "d0_{trk} - d0_{tp} [cm]", "# tracking particles"); + resz0_displaced_vect[i] = book1DFromPS( + iBooker, "resz0_displaced_" + ranges[i], psRes_z0, "z0_{trk} - z0_{tp} [cm]", "# tracking particles"); + respt_displaced_pt2to3[i] = book1DFromPS( + iBooker, "respt_displaced_" + ranges[i] + "_pt2to3", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); + respt_displaced_pt3to8[i] = book1DFromPS( + iBooker, "respt_displaced_" + ranges[i] + "_pt3to8", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); + respt_displaced_pt8toInf[i] = book1DFromPS( + iBooker, "respt_displaced_" + ranges[i] + "_pt8toInf", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); } // Extended L1TF (Prompt): efficiency ingredients (matched prompt TPs) iBooker.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Prompt/EfficiencyIngredients"); - + // Denominator: prompt TP selection - tp_pt_for_prompt = book1DFromPS(iBooker, "tp_pt_for_prompt", psEffic_pt, "p_{T} [GeV]", "# tracking particles"); - tp_pt_zoom_for_prompt = book1DFromPS(iBooker, "tp_pt_zoom_for_prompt", psEffic_pt_zoom, "p_{T} [GeV]", "# tracking particles"); - tp_eta_for_prompt = book1DFromPS(iBooker, "tp_eta_for_prompt", psEffic_eta, "#eta", "# tracking particles"); - tp_d0_for_prompt = book1DFromPS(iBooker, "tp_d0_for_prompt", psEffic_d0, "d_{0} [cm]", "# tracking particles"); - tp_Lxy_for_prompt = book1DFromPS(iBooker, "tp_Lxy_for_prompt", psEffic_Lxy, "L_{xy} [cm]", "# tracking particles"); - tp_z0_for_prompt = book1DFromPS(iBooker, "tp_z0_for_prompt", psEffic_z0, "z_{0} [cm]", "# tracking particles"); + tp_pt_for_prompt = book1DFromPS(iBooker, "tp_pt_for_prompt", psEffic_pt, "p_{T} [GeV]", "# tracking particles"); + tp_pt_zoom_for_prompt = + book1DFromPS(iBooker, "tp_pt_zoom_for_prompt", psEffic_pt_zoom, "p_{T} [GeV]", "# tracking particles"); + tp_eta_for_prompt = book1DFromPS(iBooker, "tp_eta_for_prompt", psEffic_eta, "#eta", "# tracking particles"); + tp_d0_for_prompt = book1DFromPS(iBooker, "tp_d0_for_prompt", psEffic_d0, "d_{0} [cm]", "# tracking particles"); + tp_Lxy_for_prompt = book1DFromPS(iBooker, "tp_Lxy_for_prompt", psEffic_Lxy, "L_{xy} [cm]", "# tracking particles"); + tp_z0_for_prompt = book1DFromPS(iBooker, "tp_z0_for_prompt", psEffic_z0, "z_{0} [cm]", "# tracking particles"); // Numerator: matched prompt TPs - match_prompt_tp_pt = book1DFromPS(iBooker, "match_prompt_tp_pt", psEffic_pt, "p_{T} [GeV]", "# matched tracking particles"); - match_prompt_tp_pt_zoom = book1DFromPS(iBooker, "match_prompt_tp_pt_zoom", psEffic_pt_zoom, "p_{T} [GeV]", "# matched tracking particles"); - match_prompt_tp_eta = book1DFromPS(iBooker, "match_prompt_tp_eta", psEffic_eta, "#eta", "# matched tracking particles"); - match_prompt_tp_d0 = book1DFromPS(iBooker, "match_prompt_tp_d0", psEffic_d0, "d_{0} [cm]", "# matched tracking particles"); - match_prompt_tp_Lxy = book1DFromPS(iBooker, "match_prompt_tp_Lxy", psEffic_Lxy, "L_{xy} [cm]", "# matched tracking particles"); - match_prompt_tp_z0 = book1DFromPS(iBooker, "match_prompt_tp_z0", psEffic_z0, "z_{0} [cm]", "# matched tracking particles"); - + match_prompt_tp_pt = + book1DFromPS(iBooker, "match_prompt_tp_pt", psEffic_pt, "p_{T} [GeV]", "# matched tracking particles"); + match_prompt_tp_pt_zoom = + book1DFromPS(iBooker, "match_prompt_tp_pt_zoom", psEffic_pt_zoom, "p_{T} [GeV]", "# matched tracking particles"); + match_prompt_tp_eta = + book1DFromPS(iBooker, "match_prompt_tp_eta", psEffic_eta, "#eta", "# matched tracking particles"); + match_prompt_tp_d0 = + book1DFromPS(iBooker, "match_prompt_tp_d0", psEffic_d0, "d_{0} [cm]", "# matched tracking particles"); + match_prompt_tp_Lxy = + book1DFromPS(iBooker, "match_prompt_tp_Lxy", psEffic_Lxy, "L_{xy} [cm]", "# matched tracking particles"); + match_prompt_tp_z0 = + book1DFromPS(iBooker, "match_prompt_tp_z0", psEffic_z0, "z_{0} [cm]", "# matched tracking particles"); + // Extended L1TF (Prompt): residual distributions iBooker.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Prompt/Residual"); - res_prompt_d0 = book1DFromPS(iBooker, "res_prompt_d0", psRes_d0, "trk d_{0} - tp d_{0} [cm]", "# tracking particles"); - res_prompt_eta = book1DFromPS(iBooker, "res_prompt_eta", psRes_eta, "#eta_{trk} - #eta_{tp}", "# tracking particles"); - res_prompt_pt = book1DFromPS(iBooker, "res_prompt_pt", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); - res_prompt_ptRel = book1DFromPS(iBooker, "res_prompt_ptRel", psRes_ptRel, "Relative p_{T} [GeV]", "# tracking particles"); + res_prompt_d0 = book1DFromPS(iBooker, "res_prompt_d0", psRes_d0, "trk d_{0} - tp d_{0} [cm]", "# tracking particles"); + res_prompt_eta = book1DFromPS(iBooker, "res_prompt_eta", psRes_eta, "#eta_{trk} - #eta_{tp}", "# tracking particles"); + res_prompt_pt = book1DFromPS(iBooker, "res_prompt_pt", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); + res_prompt_ptRel = + book1DFromPS(iBooker, "res_prompt_ptRel", psRes_ptRel, "Relative p_{T} [GeV]", "# tracking particles"); // Extended L1TF (Prompt): resolution vs eta and pT slices iBooker.setCurrentFolder(topFolderName_ + "/Extended_L1TF/Prompt/ResolutionIngredients"); for (int i = 0; i < 6; i++) { - reseta_prompt_vect[i] = book1DFromPS(iBooker, "reseta_prompt_" + ranges[i], psRes_eta, "#eta_{trk} - #eta_{tp}", "# tracking particles"); - resphi_prompt_vect[i] = book1DFromPS(iBooker, "resphi_prompt_" + ranges[i], psRes_phi, "#phi_{trk} - #phi_{tp}", "# tracking particles"); - resd0_prompt_vect[i] = book1DFromPS(iBooker, "resd0_prompt_" + ranges[i], psRes_d0, "d0_{trk} - d0_{tp} [cm]", "# tracking particles"); - resz0_prompt_vect[i] = book1DFromPS(iBooker, "resz0_prompt_" + ranges[i], psRes_z0, "z0_{trk} - z0_{tp} [cm]", "# tracking particles"); - respt_prompt_pt2to3[i] = book1DFromPS(iBooker, "respt_prompt_" + ranges[i] + "_pt2to3", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); - respt_prompt_pt3to8[i] = book1DFromPS(iBooker, "respt_prompt_" + ranges[i] + "_pt3to8", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); - respt_prompt_pt8toInf[i] = book1DFromPS(iBooker, "respt_prompt_" + ranges[i] + "_pt8toInf", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); + reseta_prompt_vect[i] = book1DFromPS( + iBooker, "reseta_prompt_" + ranges[i], psRes_eta, "#eta_{trk} - #eta_{tp}", "# tracking particles"); + resphi_prompt_vect[i] = book1DFromPS( + iBooker, "resphi_prompt_" + ranges[i], psRes_phi, "#phi_{trk} - #phi_{tp}", "# tracking particles"); + resd0_prompt_vect[i] = + book1DFromPS(iBooker, "resd0_prompt_" + ranges[i], psRes_d0, "d0_{trk} - d0_{tp} [cm]", "# tracking particles"); + resz0_prompt_vect[i] = + book1DFromPS(iBooker, "resz0_prompt_" + ranges[i], psRes_z0, "z0_{trk} - z0_{tp} [cm]", "# tracking particles"); + respt_prompt_pt2to3[i] = book1DFromPS( + iBooker, "respt_prompt_" + ranges[i] + "_pt2to3", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); + respt_prompt_pt3to8[i] = book1DFromPS( + iBooker, "respt_prompt_" + ranges[i] + "_pt3to8", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); + respt_prompt_pt8toInf[i] = book1DFromPS( + iBooker, "respt_prompt_" + ranges[i] + "_pt8toInf", psRes_pt, "p_{T}(trk)-p_{T}(tp)", "# tracking particles"); } } // end of method @@ -842,7 +891,7 @@ void Phase2OTValidateTracks::bookHistograms(DQMStore::IBooker &iBooker, void Phase2OTValidateTracks::fillDescriptions(edm::ConfigurationDescriptions &descriptions) { // OuterTrackerMonitorTrackingParticles edm::ParameterSetDescription desc; - auto addHist = [&desc](const std::string& name, int bins, double xmin, double xmax) { + auto addHist = [&desc](const std::string &name, int bins, double xmin, double xmax) { edm::ParameterSetDescription psd; psd.add("Nbinsx", bins); psd.add("xmin", xmin); @@ -851,30 +900,30 @@ void Phase2OTValidateTracks::fillDescriptions(edm::ConfigurationDescriptions &de }; // Tracking particle kinematics - addHist("TH1TrackParts_Eta", 45, -3.0, 3.0); - addHist("TH1TrackParts_Phi", 60, -3.141592653589793, 3.141592653589793); - addHist("TH1TrackParts_Pt", 45, 0.0, 100.0); - addHist("n_trackParticles", 100, 0.0, 600.0); + addHist("TH1TrackParts_Eta", 45, -3.0, 3.0); + addHist("TH1TrackParts_Phi", 60, -3.141592653589793, 3.141592653589793); + addHist("TH1TrackParts_Pt", 45, 0.0, 100.0); + addHist("n_trackParticles", 100, 0.0, 600.0); // Efficiency plots - addHist("TH1Effic_pt", 50, 0.0, 100.0); - addHist("TH1Effic_pt_zoom", 50, 0.0, 10.0); - addHist("TH1Effic_eta", 50, -2.5, 2.5); - addHist("TH1Effic_d0", 101, -0.15, 0.15); - addHist("TH1DisEffic_d0", 101, -10.0, 10.0); - addHist("TH1Effic_Lxy", 25, 0.0, 1.0); - addHist("TH1displacedEffic_Lxy", 50, 0.0, 10.0); - addHist("TH1Effic_z0", 40, -16.0, 16.0); + addHist("TH1Effic_pt", 50, 0.0, 100.0); + addHist("TH1Effic_pt_zoom", 50, 0.0, 10.0); + addHist("TH1Effic_eta", 50, -2.5, 2.5); + addHist("TH1Effic_d0", 101, -0.15, 0.15); + addHist("TH1DisEffic_d0", 101, -10.0, 10.0); + addHist("TH1Effic_Lxy", 25, 0.0, 1.0); + addHist("TH1displacedEffic_Lxy", 50, 0.0, 10.0); + addHist("TH1Effic_z0", 40, -16.0, 16.0); // Resolution plots - addHist("TH1Res_ptRel", 200, -0.5, 0.5); - addHist("TH1Res_pt", 100, -0.2, 0.2); - addHist("TH1Res_eta", 100, -0.01, 0.01); - addHist("TH1Res_phi", 100, -0.01, 0.01); - addHist("TH1Res_z0", 100, -1.0, 1.0); - addHist("TH1Res_d0", 100, -0.05, 0.05); - addHist("TH1Resdisplaced_d0", 101, -2.0, 2.0); - + addHist("TH1Res_ptRel", 200, -0.5, 0.5); + addHist("TH1Res_pt", 100, -0.2, 0.2); + addHist("TH1Res_eta", 100, -0.01, 0.01); + addHist("TH1Res_phi", 100, -0.01, 0.01); + addHist("TH1Res_z0", 100, -1.0, 1.0); + addHist("TH1Res_d0", 100, -0.05, 0.05); + addHist("TH1Resdisplaced_d0", 101, -2.0, 2.0); + desc.add("TopFolderName", "TrackerPhase2OTL1TrackV"); desc.add("trackingParticleToken", edm::InputTag("mix", "MergedTrackTruth")); desc.add("MCTruthStubInputTag", edm::InputTag("TTStubAssociatorFromPixelDigis", "StubAccepted")); @@ -897,4 +946,4 @@ void Phase2OTValidateTracks::fillDescriptions(edm::ConfigurationDescriptions &de // descriptions.addWithDefaultLabel(desc); } -DEFINE_FWK_MODULE(Phase2OTValidateTracks); \ No newline at end of file +DEFINE_FWK_MODULE(Phase2OTValidateTracks); From 0ef0ddf49c943ca405cfedc311ceda8908b73c5f Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Mon, 23 Mar 2026 23:02:27 +0100 Subject: [PATCH 39/61] add comments --- .../python/Phase2OTEffClient_cff.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Validation/SiTrackerPhase2V/python/Phase2OTEffClient_cff.py b/Validation/SiTrackerPhase2V/python/Phase2OTEffClient_cff.py index 279e169a51fd2..ef03a55026c19 100644 --- a/Validation/SiTrackerPhase2V/python/Phase2OTEffClient_cff.py +++ b/Validation/SiTrackerPhase2V/python/Phase2OTEffClient_cff.py @@ -1,3 +1,15 @@ +# ============================================================================== +# Phase-2 Outer Tracker DQM Efficiency Client Configuration +# +# This configuration defines DQMGenericClient modules to calculate final +# tracking and stub efficiencies for the Phase-2 Outer Tracker. It computes +# ratios for Nominal, Extended Prompt, and Extended Displaced L1 tracks, +# along with Barrel and Endcap stubs, reading from EfficiencyIngredients and +# outputting to FinalEfficiency folders. +# +# Author: Brandi Skipworth +# ============================================================================== + import FWCore.ParameterSet.Config as cms # ============================================================================ @@ -7,13 +19,11 @@ phase2OTEffClient = cms.EDProducer( "DQMGenericClient", - # FIX: Point to the folders that actually EXIST in the input file subDirs=cms.untracked.vstring( f"{_topFolder}/Nominal_L1TF", f"{_topFolder}/Extended_L1TF/Prompt", f"{_topFolder}/Extended_L1TF/Displaced", ), - # FIX: Define Inputs/Outputs relative to those existing folders # Output: FinalEfficiency/Name # Input: EfficiencyIngredients/Name efficiency=cms.vstring( @@ -54,11 +64,10 @@ phase2OTStubEffClient = cms.EDProducer( "DQMGenericClient", - # FIX: Point to the Top Folder (which definitely exists) subDirs=cms.untracked.vstring( f"{_topFolderStubs}", ), - # FIX: Path logic: FinalEfficiency/Name vs EfficiencyIngredients/Name + # Path logic: FinalEfficiency/Name vs EfficiencyIngredients/Name efficiency=cms.vstring( "FinalEfficiency/StubEfficiencyBarrel 'Stub Efficiency Barrel;tracking particle p_{T} [GeV];Efficiency' EfficiencyIngredients/gen_clusters_if_stub_barrel EfficiencyIngredients/gen_clusters_barrel", "FinalEfficiency/StubEfficiencyZoomBarrel 'Stub Efficiency Zoom Barrel;tracking particle p_{T} [GeV];Efficiency' EfficiencyIngredients/gen_clusters_if_stub_zoom_barrel EfficiencyIngredients/gen_clusters_zoom_barrel", From 0930a2d2d32855531664dd175b7a9cc2615fadc1 Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Tue, 24 Mar 2026 00:05:10 +0100 Subject: [PATCH 40/61] Apply cmsbuild code-format patch --- .../interface/TrackerPhase2HistUtil.h | 4 ++-- .../plugins/Phase2OTValidateStub.cc | 23 ++++++++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h b/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h index 19f9bfad043cc..71ee188f02afc 100644 --- a/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h +++ b/Validation/SiTrackerPhase2V/interface/TrackerPhase2HistUtil.h @@ -1,8 +1,8 @@ // TrackerPhase2HistUtil.h // ----------------------------------------------------------------------------- -// Helper utility for booking 1D histograms from ParameterSets and filling -// resolution MonitorElements (using standard deviations) in Phase-2 tracker +// Helper utility for booking 1D histograms from ParameterSets and filling +// resolution MonitorElements (using standard deviations) in Phase-2 tracker // validation & harvesting code. // // Author: Brandi Skipworth diff --git a/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateStub.cc b/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateStub.cc index d4ed670f12d72..ac4cba0110c5f 100644 --- a/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateStub.cc +++ b/Validation/SiTrackerPhase2V/plugins/Phase2OTValidateStub.cc @@ -845,7 +845,7 @@ void Phase2OTValidateStub::fillDescriptions(edm::ConfigurationDescriptions& desc // Phase2OTValidateStub edm::ParameterSetDescription desc; // Helper for 1D histograms - auto addHist = [&desc](const std::string &name, int bins, double xmin, double xmax) { + auto addHist = [&desc](const std::string& name, int bins, double xmin, double xmax) { edm::ParameterSetDescription psd; psd.add("Nbinsx", bins); psd.add("xmin", xmin); @@ -854,16 +854,17 @@ void Phase2OTValidateStub::fillDescriptions(edm::ConfigurationDescriptions& desc }; // Helper for 2D histograms - auto addHist2D = [&desc](const std::string &name, int binsX, double xmin, double xmax, int binsY, double ymin, double ymax) { - edm::ParameterSetDescription psd; - psd.add("Nbinsx", binsX); - psd.add("xmin", xmin); - psd.add("xmax", xmax); - psd.add("Nbinsy", binsY); - psd.add("ymin", ymin); - psd.add("ymax", ymax); - desc.add(name, psd); - }; + auto addHist2D = + [&desc](const std::string& name, int binsX, double xmin, double xmax, int binsY, double ymin, double ymax) { + edm::ParameterSetDescription psd; + psd.add("Nbinsx", binsX); + psd.add("xmin", xmin); + psd.add("xmax", xmax); + psd.add("Nbinsy", binsY); + psd.add("ymin", ymin); + psd.add("ymax", ymax); + desc.add(name, psd); + }; // 2D Histograms addHist2D("TH2TTStub_RZ", 900, -300.0, 300.0, 900, 0.0, 120.0); From b4845fe483b20e7a7be20a22bc850187340b6123 Mon Sep 17 00:00:00 2001 From: Mario Masciovecchio Date: Wed, 18 Mar 2026 11:27:32 -0700 Subject: [PATCH 41/61] Adding pass-through option to MultiTrackSelector (for LST tracking / seeding), and clean configuration --- .../python/TrackingSourceConfig_Tier0_cff.py | 3 + .../plugins/AnalyticalTrackSelector.cc | 8 ++ .../plugins/MultiTrackSelector.cc | 15 +++- .../plugins/MultiTrackSelector.h | 3 + .../python/earlyGeneralTracks_cfi.py | 70 +++++++++------ .../python/multiTrackSelector_cfi.py | 3 + .../python/HighPtTripletStep_cff.py | 86 +++++-------------- .../python/InitialStep_cff.py | 11 +++ .../python/iterativeTkConfig.py | 9 +- 9 files changed, 114 insertions(+), 94 deletions(-) diff --git a/DQM/TrackingMonitorSource/python/TrackingSourceConfig_Tier0_cff.py b/DQM/TrackingMonitorSource/python/TrackingSourceConfig_Tier0_cff.py index bbf5ba3935e36..db37595ae9272 100644 --- a/DQM/TrackingMonitorSource/python/TrackingSourceConfig_Tier0_cff.py +++ b/DQM/TrackingMonitorSource/python/TrackingSourceConfig_Tier0_cff.py @@ -395,10 +395,13 @@ def _copyIfExists(mod, pset, name): from Configuration.ProcessModifiers.seedingDeepCore_cff import seedingDeepCore seedingDeepCore.toReplaceWith(TrackSeedMonSequence,_seedingDeepCore_TrackSeedMonSequence) +from Configuration.ProcessModifiers.seedingLST_cff import seedingLST from Configuration.ProcessModifiers.trackingLST_cff import trackingLST trackingLST.toModify(locals()["TrackSeedMonhighPtTripletStep"], SeedProducer = "lstInputProducer" ) +_LST_TrackSeedMonSequence = TrackSeedMonSequence.copyAndExclude([locals()["TrackSeedMoninitialStep"]]) +(seedingLST | trackingLST).toReplaceWith(TrackSeedMonSequence, _LST_TrackSeedMonSequence) TrackingDQMSourceTier0 += TrackSeedMonSequence diff --git a/RecoTracker/FinalTrackSelectors/plugins/AnalyticalTrackSelector.cc b/RecoTracker/FinalTrackSelectors/plugins/AnalyticalTrackSelector.cc index aedf76cf9066b..c3416adb3de75 100644 --- a/RecoTracker/FinalTrackSelectors/plugins/AnalyticalTrackSelector.cc +++ b/RecoTracker/FinalTrackSelectors/plugins/AnalyticalTrackSelector.cc @@ -113,6 +113,9 @@ AnalyticalTrackSelector::AnalyticalTrackSelector(const edm::ParameterSet& cfg) : beamspot_ = consumes(cfg.getParameter("beamspot")); useVertices_ = cfg.getParameter("useVertices"); useVtxError_ = cfg.getParameter("useVtxError"); + passThroughForAll_ = cfg.getParameter("passThroughForAll"); + passThroughForDisplaced_ = cfg.getParameter("passThroughForDisplaced"); + minLayersForDisplaced_ = cfg.getParameter("minLayersForDisplaced"); if (useVertices_) vertices_ = consumes(cfg.getParameter("vertices")); copyExtras_ = cfg.getUntrackedParameter("copyExtras", false); @@ -402,6 +405,11 @@ void AnalyticalTrackSelector::fillDescriptions(edm::ConfigurationDescriptions& d desc.add("vtxNumber", -1); desc.add("vertexCut", "ndof>=2&!isFake"); + // pass-through options + desc.add("passThroughForAll", false); + desc.add("passThroughForDisplaced", false); + desc.add("minLayersForDisplaced", 4); + desc.addUntracked("copyExtras", false); desc.addUntracked("copyTrajectories", false); desc.add("qualityBit", std::string(""))->setComment("set to ''if you don't want to set the bit"); diff --git a/RecoTracker/FinalTrackSelectors/plugins/MultiTrackSelector.cc b/RecoTracker/FinalTrackSelectors/plugins/MultiTrackSelector.cc index 761cee753c524..aea4f3b94565a 100644 --- a/RecoTracker/FinalTrackSelectors/plugins/MultiTrackSelector.cc +++ b/RecoTracker/FinalTrackSelectors/plugins/MultiTrackSelector.cc @@ -20,7 +20,10 @@ MultiTrackSelector::MultiTrackSelector(const edm::ParameterSet& cfg) hSrc_(consumes(cfg.getParameter("src"))), beamspot_(consumes(cfg.getParameter("beamspot"))), useVertices_(cfg.getParameter("useVertices")), - useVtxError_(cfg.getParameter("useVtxError")) + useVtxError_(cfg.getParameter("useVtxError")), + passThroughForAll_(cfg.getParameter("passThroughForAll")), + passThroughForDisplaced_(cfg.getParameter("passThroughForDisplaced")), + minLayersForDisplaced_(cfg.getParameter("minLayersForDisplaced")) // now get the pset for each selector { if (useVertices_) @@ -344,6 +347,15 @@ bool MultiTrackSelector::select(unsigned int tsNum, using namespace std; + if (passThroughForAll_) + return true; + uint32_t nlayers = tk.hitPattern().trackerLayersWithMeasurement(); + uint32_t npixhits = tk.hitPattern().numberOfValidPixelHits(); + if (passThroughForDisplaced_) { + if (npixhits == 0 && nlayers >= minLayersForDisplaced_) + return true; + } + //cuts on number of valid hits auto nhits = tk.numberOfValidHits(); if ((nhits >= min_hits_bypass_[tsNum]) || (nhits == 0)) @@ -368,7 +380,6 @@ bool MultiTrackSelector::select(unsigned int tsNum, /////////////////////////////// // Cuts on numbers of layers with hits/3D hits/lost hits. - uint32_t nlayers = tk.hitPattern().trackerLayersWithMeasurement(); uint32_t nlayers3D = tk.hitPattern().pixelLayersWithMeasurement() + tk.hitPattern().numberOfValidStripLayersWithMonoAndStereo(); uint32_t nlayersLost = tk.hitPattern().trackerLayersWithoutMeasurement(reco::HitPattern::TRACK_HITS); diff --git a/RecoTracker/FinalTrackSelectors/plugins/MultiTrackSelector.h b/RecoTracker/FinalTrackSelectors/plugins/MultiTrackSelector.h index ff45507aa0927..0dd044dc16a1f 100644 --- a/RecoTracker/FinalTrackSelectors/plugins/MultiTrackSelector.h +++ b/RecoTracker/FinalTrackSelectors/plugins/MultiTrackSelector.h @@ -89,6 +89,9 @@ class dso_hidden MultiTrackSelector : public edm::stream::EDProducer<> { edm::EDGetTokenT beamspot_; bool useVertices_; bool useVtxError_; + bool passThroughForAll_; + bool passThroughForDisplaced_; + uint32_t minLayersForDisplaced_; bool useAnyMVA_; edm::EDGetTokenT vertices_; diff --git a/RecoTracker/FinalTrackSelectors/python/earlyGeneralTracks_cfi.py b/RecoTracker/FinalTrackSelectors/python/earlyGeneralTracks_cfi.py index c7ea1ccd1ee0f..e937bff346abd 100644 --- a/RecoTracker/FinalTrackSelectors/python/earlyGeneralTracks_cfi.py +++ b/RecoTracker/FinalTrackSelectors/python/earlyGeneralTracks_cfi.py @@ -81,35 +81,49 @@ def _extend_displacedGeneral(x): x.inputClassifiers += ['displacedGeneralStep'] (trackingPhase1 & displacedTracking).toModify(earlyGeneralTracks, _extend_displacedGeneral) +from Configuration.ProcessModifiers.trackingIters01_cff import trackingIters01 +(trackingPhase1 & trackingIters01).toModify(earlyGeneralTracks, + trackProducers = ['initialStepTracks', 'highPtTripletStepTracks'], + inputClassifiers = cms.vstring('initialStep','highPtTripletStep') +) + # For Phase2PU140 from Configuration.Eras.Modifier_trackingPhase2PU140_cff import trackingPhase2PU140 from RecoTracker.FinalTrackSelectors.trackListMerger_cfi import trackListMerger as _trackListMerger trackingPhase2PU140.toReplaceWith(earlyGeneralTracks, _trackListMerger.clone( TrackProducers =['initialStepTracks', 'highPtTripletStepTracks', - 'jetCoreRegionalStepTracks', 'lowPtQuadStepTracks', 'lowPtTripletStepTracks', 'detachedQuadStepTracks', 'pixelPairStepTracks', ], - hasSelector = [1,1,1,1,1,1,1], - indivShareFrac = [1.0,0.16,1.0,0.095,0.09,0.09,0.09], + hasSelector = [1,1,1,1,1,1], + indivShareFrac = [1.0,0.16,0.095,0.09,0.09,0.09], selectedTrackQuals = ['initialStepSelector:initialStep', 'highPtTripletStepSelector:highPtTripletStep', - 'jetCoreRegionalStepSelector:jetCoreRegionalStep', 'lowPtQuadStepSelector:lowPtQuadStep', 'lowPtTripletStepSelector:lowPtTripletStep', 'detachedQuadStep', 'pixelPairStepSelector:pixelPairStep', ], - setsToMerge = cms.VPSet( cms.PSet( tLists=cms.vint32(0,1,2,3,4,5,6), pQual=cms.bool(True) ) + setsToMerge = cms.VPSet( cms.PSet( tLists=cms.vint32(0,1,2,3,4,5), pQual=cms.bool(True) ) ), copyExtras = True, makeReKeyedSeeds = cms.untracked.bool(False) ) ) -from Configuration.ProcessModifiers.trackingIters01_cff import trackingIters01 + +from Configuration.ProcessModifiers.trackingLST_cff import trackingLST +def _remove_initial(x): + _idx = x.TrackProducers.index('initialStepTracks') + del x.TrackProducers[_idx] + del x.hasSelector[_idx] + del x.indivShareFrac[_idx] + del x.selectedTrackQuals[_idx] + del x.setsToMerge[0].tLists[_idx] +(trackingPhase2PU140 & trackingLST).toModify(earlyGeneralTracks, _remove_initial) + (trackingPhase2PU140 & trackingIters01).toModify(earlyGeneralTracks, TrackProducers = ['initialStepTracks', 'highPtTripletStepTracks'], hasSelector = [1,1], @@ -118,29 +132,33 @@ def _extend_displacedGeneral(x): 'highPtTripletStepSelector:highPtTripletStep' ], setsToMerge = {0: dict(tLists = [0,1])} - ) +) + +(trackingPhase2PU140 & trackingIters01 & trackingLST).toModify(earlyGeneralTracks, + TrackProducers = ['highPtTripletStepTracks'], + hasSelector = [1], + indivShareFrac = [0.1], + selectedTrackQuals = ['highPtTripletStepSelector:highPtTripletStep'], + setsToMerge = {0: dict(tLists = [0])} +) -(~trackingPhase2PU140 & trackingIters01).toModify(earlyGeneralTracks, - trackProducers = ['initialStepTracks', 'highPtTripletStepTracks'], - inputClassifiers = cms.vstring('initialStep','highPtTripletStep') - ) +from Configuration.ProcessModifiers.jetCoreInPhase2_cff import jetCoreInPhase2 +def _extend_jetCore(x): + _length = len(x.TrackProducers) + x.TrackProducers += ['jetCoreRegionalStepTracks'] + x.hasSelector += [1] + x.indivShareFrac += [1.0] + x.selectedTrackQuals += ['jetCoreRegionalStepSelector:jetCoreRegionalStep'] + x.setsToMerge[0].tLists += [_length] +(trackingPhase2PU140 & jetCoreInPhase2).toModify(earlyGeneralTracks, _extend_jetCore) from Configuration.ProcessModifiers.vectorHits_cff import vectorHits def _extend_pixelLess(x): - x.TrackProducers += ['pixelLessStepTracks'] - x.hasSelector += [1] - x.indivShareFrac += [0.095] - x.selectedTrackQuals += ['pixelLessStepSelector:pixelLessStep'] - x.setsToMerge[0].tLists += [6] + _length = len(x.TrackProducers) + x.TrackProducers += ['pixelLessStepTracks'] + x.hasSelector += [1] + x.indivShareFrac += [0.095] + x.selectedTrackQuals += ['pixelLessStepSelector:pixelLessStep'] + x.setsToMerge[0].tLists += [_length] (trackingPhase2PU140 & vectorHits).toModify(earlyGeneralTracks, _extend_pixelLess) -from Configuration.ProcessModifiers.trackingLST_cff import trackingLST -(trackingPhase2PU140 & trackingLST).toModify(earlyGeneralTracks, - TrackProducers = ['highPtTripletStepLSTpTracks', 'highPtTripletStepLSTT4T5Tracks'], - hasSelector = [1,0], - indivShareFrac = [0.1,0.1], - selectedTrackQuals = ['highPtTripletStepSelector:highPtTripletStep', - 'highPtTripletStepSelectorLSTT4T5:highPtTripletStepLSTT4T5' - ], - setsToMerge = {0: dict(tLists = [0,1])} -) diff --git a/RecoTracker/FinalTrackSelectors/python/multiTrackSelector_cfi.py b/RecoTracker/FinalTrackSelectors/python/multiTrackSelector_cfi.py index 2fe23cc7d8014..43c47c3811a78 100644 --- a/RecoTracker/FinalTrackSelectors/python/multiTrackSelector_cfi.py +++ b/RecoTracker/FinalTrackSelectors/python/multiTrackSelector_cfi.py @@ -85,6 +85,9 @@ useVertices = cms.bool(True), useVtxError = cms.bool(False), vertices = cms.InputTag("firstStepPrimaryVertices"), + passThroughForAll = cms.bool(False), + passThroughForDisplaced = cms.bool(False), + minLayersForDisplaced = cms.uint32(4), trackSelectors = cms.VPSet( looseMTS, tightMTS, highpurityMTS) diff --git a/RecoTracker/IterativeTracking/python/HighPtTripletStep_cff.py b/RecoTracker/IterativeTracking/python/HighPtTripletStep_cff.py index 753e5562b76cc..77f4e2f779a4d 100644 --- a/RecoTracker/IterativeTracking/python/HighPtTripletStep_cff.py +++ b/RecoTracker/IterativeTracking/python/HighPtTripletStep_cff.py @@ -16,6 +16,18 @@ for _eraName, _postfix, _era in _cfg.nonDefaultEras(): _era.toReplaceWith(highPtTripletStepClusters, _cfg.clusterRemoverForIter('HighPtTripletStep', _eraName, _postfix)) +# fast tracking mask producer +from FastSimulation.Tracking.FastTrackerRecHitMaskProducer_cfi import maskProducerFromClusterRemover +highPtTripletStepMasks = maskProducerFromClusterRemover(highPtTripletStepClusters) + +# Cluster removal from seed (phase-2) +from RecoLocalTracker.SubCollectionProducers.seedClusterRemoverPhase2_cfi import seedClusterRemoverPhase2 as _seedClusterRemoverPhase2 +_highPtTripletStepClustersFromSeed = _seedClusterRemoverPhase2.clone() + +from Configuration.Eras.Modifier_trackingPhase2PU140_cff import trackingPhase2PU140 +from Configuration.ProcessModifiers.seedingLST_cff import seedingLST +from Configuration.ProcessModifiers.trackingLST_cff import trackingLST +(trackingPhase2PU140 & (seedingLST | trackingLST)).toReplaceWith(highPtTripletStepClusters, _highPtTripletStepClustersFromSeed) # SEEDING LAYERS import RecoTracker.TkSeedingLayers.PixelLayerTriplets_cfi as _PixelLayerTriplets_cfi @@ -38,8 +50,6 @@ BPix = dict(skipClusters = cms.InputTag('highPtTripletStepClusters')), FPix = dict(skipClusters = cms.InputTag('highPtTripletStepClusters')) ) - -from Configuration.Eras.Modifier_trackingPhase2PU140_cff import trackingPhase2PU140 trackingPhase2PU140.toModify(highPtTripletStepSeedLayers, # combination with gap removed as only source of fakes in current geometry (kept for doc) layerList = ['BPix1+BPix2+BPix3', 'BPix2+BPix3+BPix4', @@ -259,7 +269,6 @@ phase2clustersToSkip = 'highPtTripletStepClusters' ) -from Configuration.ProcessModifiers.trackingLST_cff import trackingLST from RecoTracker.LST.lstOutputConverter_cfi import lstOutputConverter as _lstOutputConverter (trackingPhase2PU140 & trackingLST).toReplaceWith(highPtTripletStepTrackCandidates, _lstOutputConverter.clone()) @@ -284,25 +293,6 @@ from Configuration.Eras.Modifier_phase2_timing_layer_cff import phase2_timing_layer phase2_timing_layer.toModify(highPtTripletStepTracks, TrajectoryInEvent = True) -highPtTripletStepLSTpTracks = highPtTripletStepTracks.clone( - src = 'highPtTripletStepTrackCandidates:pTCsLST' -) -highPtTripletStepLSTT4T5Tracks = highPtTripletStepTracks.clone( - src = 'highPtTripletStepTrackCandidates:t4t5TCsLST' -) -_highPtTripletStepTracks_LST = RecoTracker.FinalTrackSelectors.trackListMerger_cfi.trackListMerger.clone( - TrackProducers = ['highPtTripletStepLSTpTracks', - 'highPtTripletStepLSTT4T5Tracks'], - hasSelector = [1,0], - indivShareFrac = [0.1,0.1], - selectedTrackQuals = ['highPtTripletStepSelector:highPtTripletStep', - 'highPtTripletStepSelectorLSTT4T5:highPtTripletStepLSTT4T5'], - copyExtras = True, - copyMVA = False, - setsToMerge = [cms.PSet( tLists=cms.vint32(0,1), pQual=cms.bool(True) )] -) -(trackingPhase2PU140 & trackingLST).toReplaceWith(highPtTripletStepTracks, _highPtTripletStepTracks_LST) - # Final selection from RecoTracker.FinalTrackSelectors.TrackMVAClassifierPrompt_cfi import * highPtTripletStep = TrackMVAClassifierPrompt.clone( @@ -382,27 +372,9 @@ from Configuration.ProcessModifiers.vectorHits_cff import vectorHits vectorHits.toModify(highPtTripletStepSelector.trackSelectors[2], minNumberLayers = 3, minNumber3DLayers = 3, d0_par1 = ( 0.5, 4.0 ), dz_par1 = ( 0.6, 4.0 )) -(trackingPhase2PU140 & trackingLST).toModify(highPtTripletStepSelector, src = 'highPtTripletStepLSTpTracks') -# Passthrough selector to satisfy the TrackListMerger requirement for selector values -highPtTripletStepSelectorLSTT4T5 = RecoTracker.FinalTrackSelectors.multiTrackSelector_cfi.multiTrackSelector.clone( - src = 'highPtTripletStepLSTT4T5Tracks', - trackSelectors = [ - RecoTracker.FinalTrackSelectors.multiTrackSelector_cfi.looseMTS.clone( - name = 'highPtTripletStepLSTT4T5Loose', - minHitsToBypassChecks = 0 - ), #end of pset - RecoTracker.FinalTrackSelectors.multiTrackSelector_cfi.tightMTS.clone( - name = 'highPtTripletStepLSTT4T5Tight', - preFilterName = 'highPtTripletStepLSTT4T5Loose', - minHitsToBypassChecks = 0 - ), - RecoTracker.FinalTrackSelectors.multiTrackSelector_cfi.highpurityMTS.clone( - name = 'highPtTripletStepLSTT4T5', - preFilterName = 'highPtTripletStepLSTT4T5Tight', - minHitsToBypassChecks = 0 - ), - ] #end of vpset -) #end of clone +(trackingPhase2PU140 & trackingLST).toModify(highPtTripletStepSelector, passThroughForDisplaced = True) + +(trackingPhase2PU140 & seedingLST).toModify(highPtTripletStepSelector, passThroughForAll = True) # Final sequence HighPtTripletStepTask = cms.Task(highPtTripletStepClusters, @@ -431,8 +403,7 @@ from RecoTracker.LST.lstInputProducer_cfi import lstInputProducer from RecoTracker.LST.lstProducerTask_cff import * -_HighPtTripletStepTask_LST.add(siPhase2RecHits, lstInitialStepSeedTracks, lstHighPtTripletStepSeedTracks, lstInputProducer, - lstProducerTask, highPtTripletStepLSTpTracks, highPtTripletStepLSTT4T5Tracks, highPtTripletStepSelectorLSTT4T5) +_HighPtTripletStepTask_LST.add(siPhase2RecHits, lstInitialStepSeedTracks, lstHighPtTripletStepSeedTracks, lstInputProducer, lstProducerTask) (trackingPhase2PU140 & trackingLST).toReplaceWith(HighPtTripletStepTask, _HighPtTripletStepTask_LST) from Configuration.ProcessModifiers.alpakaValidationLST_cff import alpakaValidationLST @@ -446,33 +417,18 @@ lstInput = "lstInputProducerSerialSync", lstPixelSeeds = "lstInputProducerSerialSync" ) -highPtTripletStepLSTpTracksSerialSync = highPtTripletStepLSTpTracks.clone( - src = 'highPtTripletStepTrackCandidatesSerialSync:pTCsLST') -highPtTripletStepLSTT4T5TracksSerialSync = highPtTripletStepLSTT4T5Tracks.clone( - src = 'highPtTripletStepTrackCandidatesSerialSync:t4t5TCsLST') -highPtTripletStepSelectorSerialSync = highPtTripletStepSelector.clone() -(trackingPhase2PU140 & alpakaValidationLST & trackingLST).toModify(highPtTripletStepSelectorSerialSync, src = "highPtTripletStepLSTpTracksSerialSync" ) -highPtTripletStepSelectorLSTT4T5SerialSync = highPtTripletStepSelectorLSTT4T5.clone(src = "highPtTripletStepLSTT4T5TracksSerialSync") highPtTripletStepTracksSerialSync = highPtTripletStepTracks.clone() -(trackingPhase2PU140 & alpakaValidationLST & trackingLST).toModify(highPtTripletStepTracksSerialSync, - TrackProducers = ['highPtTripletStepLSTpTracksSerialSync', - 'highPtTripletStepLSTT4T5TracksSerialSync'], - selectedTrackQuals = ['highPtTripletStepSelectorSerialSync:highPtTripletStep', - 'highPtTripletStepSelectorLSTT4T5SerialSync:highPtTripletStepLSTT4T5'], -) +(trackingPhase2PU140 & alpakaValidationLST & trackingLST).toModify(highPtTripletStepTracksSerialSync, src = "highPtTripletStepTrackCandidatesSerialSync") +highPtTripletStepSelectorSerialSync = highPtTripletStepSelector.clone() +(trackingPhase2PU140 & alpakaValidationLST & trackingLST).toModify(highPtTripletStepSelectorSerialSync, src = "highPtTripletStepTracksSerialSync" ) _HighPtTripletStepTask_LSTSerialSync = HighPtTripletStepTask.copy() -_HighPtTripletStepTask_LSTSerialSync.add(siPhase2RecHits, lstInitialStepSeedTracks, lstHighPtTripletStepSeedTracks, lstInputProducerSerialSync, - lstProducerSerialSync, highPtTripletStepTrackCandidatesSerialSync, - highPtTripletStepLSTpTracksSerialSync, highPtTripletStepLSTT4T5TracksSerialSync, - highPtTripletStepSelectorSerialSync, highPtTripletStepSelectorLSTT4T5SerialSync, - highPtTripletStepTracksSerialSync +_HighPtTripletStepTask_LSTSerialSync.add(siPhase2RecHits, lstInitialStepSeedTracks, lstHighPtTripletStepSeedTracks, lstInputProducerSerialSync, lstProducerSerialSync, + highPtTripletStepTrackCandidatesSerialSync, highPtTripletStepTracksSerialSync, highPtTripletStepSelectorSerialSync ) HighPtTripletStepTaskSerialSync = cms.Task() (trackingPhase2PU140 & alpakaValidationLST & trackingLST).toReplaceWith(HighPtTripletStepTaskSerialSync, _HighPtTripletStepTask_LSTSerialSync) # fast tracking mask producer -from FastSimulation.Tracking.FastTrackerRecHitMaskProducer_cfi import maskProducerFromClusterRemover -highPtTripletStepMasks = maskProducerFromClusterRemover(highPtTripletStepClusters) _HighPtTripletStepTask_fastSim = cms.Task(highPtTripletStepMasks ,highPtTripletStepTrackingRegions ,highPtTripletStepSeeds diff --git a/RecoTracker/IterativeTracking/python/InitialStep_cff.py b/RecoTracker/IterativeTracking/python/InitialStep_cff.py index 9093f4589feda..2557cb285ed1a 100644 --- a/RecoTracker/IterativeTracking/python/InitialStep_cff.py +++ b/RecoTracker/IterativeTracking/python/InitialStep_cff.py @@ -471,11 +471,22 @@ _InitialStepTask_trackingPhase2.replace(initialStepHitTriplets, initialStepHitQuadruplets) _InitialStepTask_trackingPhase2.replace(initialStep, initialStepSelector) trackingPhase2PU140.toReplaceWith(InitialStepTask, _InitialStepTask_trackingPhase2) + + +from Configuration.ProcessModifiers.seedingLST_cff import seedingLST +from Configuration.ProcessModifiers.trackingLST_cff import trackingLST +(trackingPhase2PU140 & (seedingLST | trackingLST)).toModify(firstStepPrimaryVerticesUnsorted, TrackLabel = 'highPtTripletStepTracks') +(trackingPhase2PU140 & (seedingLST | trackingLST)).toModify(initialStepTrackRefsForJets, src = 'highPtTripletStepTracks') + +_InitialStepTask_trackingPhase2_LST = InitialStepTask.copyAndExclude([initialStepTrackCandidatesMkFitSeeds, initialStepTrackCandidatesMkFit, initialStepTrackCandidatesMkFitConfig, initialStepTrackCandidates, initialStepTracks, initialStepSelector]) +(trackingPhase2PU140 & (seedingLST | trackingLST)).toReplaceWith(InitialStepTask, _InitialStepTask_trackingPhase2_LST) + (trackingMkFitCommon & trackingPhase2PU140).toModify(mkFitEventOfHits, stripHits=cms.InputTag('mkFitSiPhase2Hits'), useStripStripQualityDB=cms.bool(False)) (trackingMkFitInitialStep & trackingPhase2PU140).toModify(initialStepTrackCandidatesMkFit, stripHits=cms.InputTag('mkFitSiPhase2Hits')) (trackingMkFitInitialStep & trackingPhase2PU140).toModify(initialStepTrackCandidates, mkFitStripHits=cms.InputTag('mkFitSiPhase2Hits')) (trackingMkFitInitialStep & trackingPhase2PU140).toModify(initialStepTrackCandidatesMkFitConfig, config='RecoTracker/MkFit/data/mkfit-phase2-initialStep.json') + from Configuration.Eras.Modifier_fastSim_cff import fastSim _InitialStepTask_fastSim = cms.Task(initialStepTrackingRegions ,initialStepSeeds diff --git a/RecoTracker/IterativeTracking/python/iterativeTkConfig.py b/RecoTracker/IterativeTracking/python/iterativeTkConfig.py index e41a2fc5524dc..2480d3154a8f1 100644 --- a/RecoTracker/IterativeTracking/python/iterativeTkConfig.py +++ b/RecoTracker/IterativeTracking/python/iterativeTkConfig.py @@ -2,6 +2,7 @@ # iterations. It is used in RECO, DQM, and VALIDATION. Note that here # InitialStepPreSplitting is not counted as an iteration. import FWCore.ParameterSet.Config as cms +import copy _defaultEraName = "" _nonDefaultEraNames = ["trackingLowPU", "trackingPhase1", "trackingPhase2PU140"] @@ -68,6 +69,8 @@ )) from Configuration.ProcessModifiers.vectorHits_cff import vectorHits vectorHits.toModify(_iterations_trackingPhase2PU140_VS.names, func=lambda x: x.append('PixelLessStep')) +from Configuration.ProcessModifiers.jetCoreInPhase2_cff import jetCoreInPhase2 +jetCoreInPhase2.toModify(_iterations_trackingPhase2PU140_VS.names, func=lambda x: x.append('JetCoreRegionalStep')) trackingIters01.toModify(_iterations_trackingPhase2PU140_VS, names = ["InitialStep", "HighPtTripletStep"]) # apply all procModifiers before this @@ -186,14 +189,18 @@ def iterationAlgos(postfix, includeSequenceName=False): else: return [_modulePrefix(i) for i in iterations] +from Configuration.ProcessModifiers.seedingLST_cff import seedingLST +from Configuration.ProcessModifiers.trackingLST_cff import trackingLST def _seedOrTrackProducers(postfix, typ): ret = [] iters = globals()["_iterations"+postfix] + _iters = copy.deepcopy(iters) if typ == "Seeds": multipleSeedProducers = globals()["_multipleSeedProducers"+postfix] else: multipleSeedProducers = None - for i in iters: + (seedingLST | trackingLST).toModify(_iters, func=lambda x: x.remove('InitialStep')) + for i in _iters: seeder = _modulePrefix(i)+typ if multipleSeedProducers is not None and i in multipleSeedProducers: ret.extend([seeder+m for m in multipleSeedProducers[i]]) From adc0cc65b4d567c5ba7eaad33c65e86f25cd4f18 Mon Sep 17 00:00:00 2001 From: Mario Masciovecchio Date: Mon, 23 Mar 2026 09:14:39 -0700 Subject: [PATCH 42/61] Add possibility to mask clusters from seeds on fastSIM --- .../FastTrackerRecHitMaskFromSeedProducer.cc | 93 +++++++++++++++++++ ...stTrackerRecHitMaskFromSeedProducer_cff.py | 11 +++ 2 files changed, 104 insertions(+) create mode 100644 FastSimulation/Tracking/plugins/FastTrackerRecHitMaskFromSeedProducer.cc create mode 100644 FastSimulation/Tracking/python/FastTrackerRecHitMaskFromSeedProducer_cff.py diff --git a/FastSimulation/Tracking/plugins/FastTrackerRecHitMaskFromSeedProducer.cc b/FastSimulation/Tracking/plugins/FastTrackerRecHitMaskFromSeedProducer.cc new file mode 100644 index 0000000000000..8e22f0805724f --- /dev/null +++ b/FastSimulation/Tracking/plugins/FastTrackerRecHitMaskFromSeedProducer.cc @@ -0,0 +1,93 @@ +// system includes +#include + +// framework stuff +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Framework/interface/ESHandle.h" + +// data formats +#include "DataFormats/Common/interface/ValueMap.h" +#include "DataFormats/TrackerRecHit2D/interface/FastTrackerRecHit.h" +#include "DataFormats/TrackerRecHit2D/interface/FastTrackerRecHitCollection.h" +#include "DataFormats/TrajectorySeed/interface/TrajectorySeedCollection.h" + +class FastTrackerRecHitMaskFromSeedProducer : public edm::global::EDProducer<> { +public: + explicit FastTrackerRecHitMaskFromSeedProducer(const edm::ParameterSet&); + + ~FastTrackerRecHitMaskFromSeedProducer() override {} + + void produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const override; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + // an alias + using QualityMaskCollection = std::vector; + + // tokens + edm::EDGetTokenT trajectories_; + + edm::EDGetTokenT recHits_; + + edm::EDGetTokenT > oldHitMaskToken_; + + edm::EDPutTokenT > collectedHits_; +}; + +FastTrackerRecHitMaskFromSeedProducer::FastTrackerRecHitMaskFromSeedProducer(const edm::ParameterSet& iConfig) + : trajectories_(consumes(iConfig.getParameter("trajectories"))), + recHits_(consumes(iConfig.getParameter("recHits"))), + collectedHits_(produces()) { + auto const& oldHitRemovalInfo = iConfig.getParameter("oldHitRemovalInfo"); + if (!oldHitRemovalInfo.label().empty()) { + oldHitMaskToken_ = consumes >(oldHitRemovalInfo); + } +} + +void FastTrackerRecHitMaskFromSeedProducer::produce(edm::StreamID, edm::Event& iEvent, edm::EventSetup const&) const { + // the product + + std::vector collectedHits; + + // input + + auto const& recHits = iEvent.get(recHits_); + + if (!oldHitMaskToken_.isUninitialized()) { + auto const& oldHitMasks = iEvent.get(oldHitMaskToken_); + collectedHits.insert(collectedHits.begin(), oldHitMasks.begin(), oldHitMasks.end()); + } + collectedHits.resize(recHits.size(), false); + + auto const& seeds = iEvent.get(trajectories_); + + // loop over seed tracks and mask hits + for (auto const& seed : seeds) { + for (auto const& hit : seed.recHits()) { + if (!hit.isValid()) + continue; + const FastTrackerRecHit& fasthit = static_cast(hit); + // note: for matched hits nIds() returns 2, otherwise 1 + for (unsigned id_index = 0; id_index < fasthit.nIds(); id_index++) { + collectedHits[unsigned(fasthit.id(id_index))] = true; + } + } + } + + iEvent.emplace(collectedHits_, std::move(collectedHits)); +} + +void FastTrackerRecHitMaskFromSeedProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("trajectories", edm::InputTag("initialStepSeeds")); + desc.add("recHits", edm::InputTag("fastTrackerRecHits")); + desc.add("oldHitRemovalInfo", edm::InputTag("")); + descriptions.addWithDefaultLabel(desc); +} + +DEFINE_FWK_MODULE(FastTrackerRecHitMaskFromSeedProducer); diff --git a/FastSimulation/Tracking/python/FastTrackerRecHitMaskFromSeedProducer_cff.py b/FastSimulation/Tracking/python/FastTrackerRecHitMaskFromSeedProducer_cff.py new file mode 100644 index 0000000000000..8e872cdcb442a --- /dev/null +++ b/FastSimulation/Tracking/python/FastTrackerRecHitMaskFromSeedProducer_cff.py @@ -0,0 +1,11 @@ +import FWCore.ParameterSet.Config as cms + +from FastSimulation.Tracking.fastTrackerRecHitMaskFromSeedProducer_cfi import fastTrackerRecHitMaskFromSeedProducer + +def maskProducerFromSeedClusterRemover(seedClusterRemover): + maskProducer = fastTrackerRecHitMaskFromSeedProducer.clone( + trajectories = seedClusterRemover.trajectories, + ) + if(hasattr(seedClusterRemover,"oldClusterRemovalInfo")): + maskProducer.oldHitRemovalInfo = cms.InputTag(seedClusterRemover.oldClusterRemovalInfo.getModuleLabel().replace("Clusters","Masks")) + return maskProducer From abeed7be932b6318f11d46f42774bf3493cbb063 Mon Sep 17 00:00:00 2001 From: Lovisa Date: Tue, 7 Apr 2026 08:37:05 +0200 Subject: [PATCH 43/61] Updating DisTauTag.cc test_vector to test_score --- PhysicsTools/NanoAOD/plugins/DisTauTag.cc | 25 ++++++++--------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/PhysicsTools/NanoAOD/plugins/DisTauTag.cc b/PhysicsTools/NanoAOD/plugins/DisTauTag.cc index 96136acea215c..5bb8099863e42 100644 --- a/PhysicsTools/NanoAOD/plugins/DisTauTag.cc +++ b/PhysicsTools/NanoAOD/plugins/DisTauTag.cc @@ -32,16 +32,12 @@ #include "PhysicsTools/NanoAOD/interface/DisTauTagScaling.h" -void test_vector(std::vector& values) { - for (auto& value : values) { - if (std::isnan(value)) { - throw std::runtime_error("DisTauTag score output: NaN detected."); - } else if (std::isinf(value)) { - throw std::runtime_error("DisTauTag score output: Infinity detected."); - } else if (!std::isfinite(value)) { - throw std::runtime_error("DisTauTag score output: Non-standard value detected."); - } +std::optional test_score(float value) { + if (!std::isfinite(value)) { + edm::LogWarning("DisTauTag") << "Non-finite score detected (" << value << "); dropping value."; + return std::nullopt; } + return value; } class DisTauTag : public edm::global::EDProducer<> { @@ -285,15 +281,13 @@ void DisTauTag::produce(edm::StreamID, edm::Event& event, const edm::EventSetup& // Running inference on batch std::vector outputs; - { - tensorflow::run(session_, {{"input_1", input_1}, {"input_2", input_2}}, {"final_out"}, &outputs); - } + { tensorflow::run(session_, {{"input_1", input_1}, {"input_2", input_2}}, {"final_out"}, &outputs); } // Storing results for (size_t batch_jet_idx = 0; batch_jet_idx < current_batch_size; ++batch_jet_idx) { const size_t jetIndex = jet_start + batch_jet_idx; - v_score0[jetIndex] = outputs[0].matrix()(batch_jet_idx, 0); - v_score1[jetIndex] = outputs[0].matrix()(batch_jet_idx, 1); + v_score0[jetIndex] = test_score(outputs[0].matrix()(batch_jet_idx, 0)).value_or(-9.f); + v_score1[jetIndex] = test_score(outputs[0].matrix()(batch_jet_idx, 1)).value_or(-9.f); } // Save inputs if requested (for debugging) @@ -321,9 +315,6 @@ void DisTauTag::produce(edm::StreamID, edm::Event& event, const edm::EventSetup& } } - test_vector(v_score0); - test_vector(v_score1); - std::unique_ptr> vm_score0(new edm::ValueMap()); edm::ValueMap::Filler filler_score0(*vm_score0); filler_score0.insert(jets, v_score0.begin(), v_score0.end()); From e890a13540bda295bf0d6233e763caa02d875285 Mon Sep 17 00:00:00 2001 From: Lovisa Date: Tue, 7 Apr 2026 08:43:55 +0200 Subject: [PATCH 44/61] code format fix --- PhysicsTools/NanoAOD/plugins/DisTauTag.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/PhysicsTools/NanoAOD/plugins/DisTauTag.cc b/PhysicsTools/NanoAOD/plugins/DisTauTag.cc index 5bb8099863e42..92d5f0d0ea3c5 100644 --- a/PhysicsTools/NanoAOD/plugins/DisTauTag.cc +++ b/PhysicsTools/NanoAOD/plugins/DisTauTag.cc @@ -281,7 +281,9 @@ void DisTauTag::produce(edm::StreamID, edm::Event& event, const edm::EventSetup& // Running inference on batch std::vector outputs; - { tensorflow::run(session_, {{"input_1", input_1}, {"input_2", input_2}}, {"final_out"}, &outputs); } + { + tensorflow::run(session_, {{"input_1", input_1}, {"input_2", input_2}}, {"final_out"}, &outputs); + } // Storing results for (size_t batch_jet_idx = 0; batch_jet_idx < current_batch_size; ++batch_jet_idx) { From 182a9b243967b2e794fc691ecb82964796c4a650 Mon Sep 17 00:00:00 2001 From: Zhenbin Wu Date: Tue, 7 Apr 2026 14:32:34 -0500 Subject: [PATCH 45/61] Fixes for the second round of comment --- .../L1TMuonPhase2/interface/MuonStub.h | 6 +++-- DataFormats/L1TMuonPhase2/src/MuonStub.cc | 4 ++-- .../Phase2L1GMT/interface/ConvertedTTTrack.h | 7 ++++-- .../Phase2L1GMT/interface/TPSAlgorithm.h | 2 +- .../Phase2L1GMT/interface/TrackConverter.h | 6 ++--- .../plugins/Phase2L1TGMTStubProducer.cc | 9 ++++--- L1Trigger/Phase2L1GMT/src/TPSAlgorithm.cc | 24 ++++++++++++------- 7 files changed, 37 insertions(+), 21 deletions(-) diff --git a/DataFormats/L1TMuonPhase2/interface/MuonStub.h b/DataFormats/L1TMuonPhase2/interface/MuonStub.h index 6e09e4a4af6fd..36e78494c2958 100644 --- a/DataFormats/L1TMuonPhase2/interface/MuonStub.h +++ b/DataFormats/L1TMuonPhase2/interface/MuonStub.h @@ -142,8 +142,10 @@ namespace l1t { void print() const; const Phase2L1GMT::wordtype hybridStubWord() const; - void printHybridStub(std::string module, uint spaces, bool label) const; - void printHybridStubWord(std::string module, uint spaces, bool label) const; + void printHybridStub(const std::string module = "MuonStub", const uint spaces = 0, const bool label = true) const; + void printHybridStubWord(const std::string module = "MuonStub", + const uint spaces = 0, + const bool label = true) const; private: int etaRegion_; //In the barrel this is wheel. In the endcap it is 6-ring diff --git a/DataFormats/L1TMuonPhase2/src/MuonStub.cc b/DataFormats/L1TMuonPhase2/src/MuonStub.cc index d3df0fb5c8aaf..d76c0a5fe3529 100644 --- a/DataFormats/L1TMuonPhase2/src/MuonStub.cc +++ b/DataFormats/L1TMuonPhase2/src/MuonStub.cc @@ -108,7 +108,7 @@ const Phase2L1GMT::wordtype MuonStub::hybridStubWord() const { return w; } -void MuonStub::printHybridStub(std::string module = "MuonStub", uint spaces = 0, bool label = true) const { +void MuonStub::printHybridStub(const std::string module, const uint spaces, const bool label) const { std::string lab = ""; lab.append(spaces, ' '); if (label) @@ -133,7 +133,7 @@ void MuonStub::printHybridStub(std::string module = "MuonStub", uint spaces = 0, << "tfLayer = " << tfLayer_ << std::flush; } -void MuonStub::printHybridStubWord(std::string module = "MuonStub", uint spaces = 0, bool label = true) const { +void MuonStub::printHybridStubWord(const std::string module, const uint spaces, const bool label) const { std::string lab = ""; lab.append(spaces, ' '); if (label) diff --git a/L1Trigger/Phase2L1GMT/interface/ConvertedTTTrack.h b/L1Trigger/Phase2L1GMT/interface/ConvertedTTTrack.h index 40939e0d90631..d17bf47960fcc 100644 --- a/L1Trigger/Phase2L1GMT/interface/ConvertedTTTrack.h +++ b/L1Trigger/Phase2L1GMT/interface/ConvertedTTTrack.h @@ -4,6 +4,7 @@ #include "DataFormats/L1TMuonPhase2/interface/Constants.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" #include +#include namespace Phase2L1GMT { @@ -68,7 +69,7 @@ namespace Phase2L1GMT { offline_phi_ = phi; } - void print(std::string module = "ConvertedTTTrack", uint spaces = 0, bool label = true) const { + void print(const std::string& module = "ConvertedTTTrack", const uint& spaces = 0, const bool& label = true) const { std::string lab = ""; lab.append(spaces, ' '); if (label) @@ -90,7 +91,9 @@ namespace Phase2L1GMT { << "(curvature = " << curvature_ << ")" << std::flush; } - void printWord(std::string module = "ConvertedTTTrack", uint spaces = 0, bool label = true) const { + void printWord(const std::string& module = "ConvertedTTTrack", + const uint& spaces = 0, + const bool& label = true) const { std::string lab = ""; lab.append(spaces, ' '); if (label) diff --git a/L1Trigger/Phase2L1GMT/interface/TPSAlgorithm.h b/L1Trigger/Phase2L1GMT/interface/TPSAlgorithm.h index 78d483c30d7e5..32215f07b11c6 100644 --- a/L1Trigger/Phase2L1GMT/interface/TPSAlgorithm.h +++ b/L1Trigger/Phase2L1GMT/interface/TPSAlgorithm.h @@ -71,7 +71,7 @@ namespace Phase2L1GMT { const std::vector& muonsNext, bool equality) const; std::vector cleanAll(std::vector& muons) const; - std::vector convert(std::vector& muons, uint maximum) const; + std::vector convert(const std::vector& muons, const uint maximum) const; bool outputGT(std::vector& muons) const; void SetQualityBits(std::vector& muons) const; std::vector sort(std::vector& muons, uint maximum) const; diff --git a/L1Trigger/Phase2L1GMT/interface/TrackConverter.h b/L1Trigger/Phase2L1GMT/interface/TrackConverter.h index 8f3f3f90242fd..7f99009aab935 100644 --- a/L1Trigger/Phase2L1GMT/interface/TrackConverter.h +++ b/L1Trigger/Phase2L1GMT/interface/TrackConverter.h @@ -19,7 +19,7 @@ namespace Phase2L1GMT { int verbose_; typedef ap_uint<96> wordtype; - uint generateQuality(const edm::Ptr >& track) { + uint generateQuality(const edm::Ptr >& track) const { uint chi2Cut = 0xf; if ((track->getChi2RZBits() <= chi2Cut) && (track->getChi2RPhiBits() <= chi2Cut)) return 1; @@ -27,7 +27,7 @@ namespace Phase2L1GMT { return 0; } - uint ptLookup(uint absCurv) { + uint ptLookup(const uint absCurv) const { for (auto i : ptShifts) { if (absCurv >= uint(i[0]) && absCurv < uint(i[1])) { if (i[2] < 0) @@ -39,7 +39,7 @@ namespace Phase2L1GMT { return 0; } - uint etaLookup(uint absTanL) { + uint etaLookup(const uint absTanL) const { for (auto i : etaShifts) { if (absTanL >= uint(i[0]) && absTanL < uint(i[1])) { if (i[2] < 0) diff --git a/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc b/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc index 5d3c75f0a2c46..ed680955534ea 100644 --- a/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc +++ b/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc @@ -165,13 +165,16 @@ void Phase2L1TGMTStubProducer::fillDescriptions(edm::ConfigurationDescriptions& psd0.add("etaLSB", 0.024586688); psd0.add>("eta_1", {-46, -45, -43, -41, -39, -37, -35, -30, -28, -26, -23, -20, -18, -15, -9, -6, -3, -1, - 1, 3, 6, 9, 15, 18, 20, 23, 26, 28, 30, 35, 37, 39, 41, 43, 45, 46}); + 1, 3, 6, 9, 15, 18, 20, 23, 26, 28, 30, 35, 37, 39, 41, 43, 45, 46}) + ->setComment("discrete value of eta_1"); psd0.add>("eta_2", {-41, -39, -38, -36, -34, -32, -30, -26, -24, -22, -20, -18, -15, -13, -8, -5, -3, -1, - 1, 3, 5, 8, 13, 15, 18, 20, 22, 24, 26, 30, 32, 34, 36, 38, 39, 41}); + 1, 3, 5, 8, 13, 15, 18, 20, 22, 24, 26, 30, 32, 34, 36, 38, 39, 41}) + ->setComment("discrete value of eta_2"); psd0.add>("eta_3", {-35, -34, -32, -31, -29, -27, -26, -22, -20, -19, -17, -15, -13, -11, -6, -4, -2, -1, - 1, 2, 4, 6, 11, 13, 15, 17, 19, 20, 22, 26, 27, 29, 31, 32, 34, 35}); + 1, 2, 4, 6, 11, 13, 15, 17, 19, 20, 22, 26, 27, 29, 31, 32, 34, 35}) + ->setComment("discrete value of eta_3"); psd0.add>("coarseEta_1", { 0, diff --git a/L1Trigger/Phase2L1GMT/src/TPSAlgorithm.cc b/L1Trigger/Phase2L1GMT/src/TPSAlgorithm.cc index 3efe63f2fd5bb..adc0ba0fce638 100644 --- a/L1Trigger/Phase2L1GMT/src/TPSAlgorithm.cc +++ b/L1Trigger/Phase2L1GMT/src/TPSAlgorithm.cc @@ -95,7 +95,8 @@ std::vector TPSAlgorithm::cleanAll(std::vector TPSAlgorithm::convert(std::vector& muons, uint maximum) const { +std::vector TPSAlgorithm::convert(const std::vector& muons, + const uint maximum) const { std::vector out; for (const auto& mu : muons) { if (out.size() == maximum) @@ -667,7 +668,8 @@ PreTrackMatchedMuon TPSAlgorithm::processTrack(const ConvertedTTTrack& track, << "eta=" + to_string(ap_int(track.eta())) + ", " << "z0=" + to_string(ap_int(track.z0())) + ", " << "d0=" + to_string(ap_int(track.d0())) + ", " - << "quality=" + to_string(ap_uint<1>(track.quality())) + ", " << "\n" + << "quality=" + to_string(ap_uint<1>(track.quality())) + ", " + << "\n" << std::flush; edm::LogInfo("TPSAlgo") << "Input stubs:" << std::flush; @@ -677,7 +679,8 @@ PreTrackMatchedMuon TPSAlgorithm::processTrack(const ConvertedTTTrack& track, << "layer=" + to_string(stub->tfLayer()) + ", " << "coord1=" + to_string(stub->coord1()) + ", " << "coord2=" + to_string(stub->coord2()) + ", " - << "eta1=" + to_string(stub->eta1()) + ", " << "eta2=" + to_string(stub->eta2()) + ", " + << "eta1=" + to_string(stub->eta1()) + ", " + << "eta2=" + to_string(stub->eta2()) + ", " << "quality=" + to_string(stub->quality()) + ", " << "etaQuality=" + to_string(stub->etaQuality()) + ", " << "id=" + to_string(stub->address()) + ", " << std::flush; @@ -686,12 +689,16 @@ PreTrackMatchedMuon TPSAlgorithm::processTrack(const ConvertedTTTrack& track, edm::LogInfo("TPSAlgo") << "End stubs\n" << std::flush; edm::LogInfo("TPSAlgo") << "Output PreTrackMatchedMuon: " - << "valid=" + to_string(muon.valid()) + ", " << "q=" + to_string(muon.charge()) + ", " - << "pt=" + to_string(muon.pt()) + ", " << "phi=" + to_string(muon.phi()) + ", " - << "eta=" + to_string(muon.eta()) + ", " << "z0=" + to_string(muon.z0()) + ", " + << "valid=" + to_string(muon.valid()) + ", " + << "q=" + to_string(muon.charge()) + ", " + << "pt=" + to_string(muon.pt()) + ", " + << "phi=" + to_string(muon.phi()) + ", " + << "eta=" + to_string(muon.eta()) + ", " + << "z0=" + to_string(muon.z0()) + ", " << "d0=" + to_string(muon.d0()) + ", " << "isGlobalMuon=" + to_string(muon.isGlobalMuon()) + ", " - << "beta=" + to_string(muon.beta()) + ", " << "quality=" + to_string(muon.quality()) + ", " + << "beta=" + to_string(muon.beta()) + ", " + << "quality=" + to_string(muon.quality()) + ", " << "\n" << std::flush; @@ -703,7 +710,8 @@ PreTrackMatchedMuon TPSAlgorithm::processTrack(const ConvertedTTTrack& track, << "layer=" + to_string(stub->tfLayer()) + ", " << "coord1=" + to_string(stub->coord1()) + ", " << "coord2=" + to_string(stub->coord2()) + ", " - << "eta1=" + to_string(stub->eta1()) + ", " << "eta2=" + to_string(stub->eta2()) + ", " + << "eta1=" + to_string(stub->eta1()) + ", " + << "eta2=" + to_string(stub->eta2()) + ", " << "phiQuality=" + to_string(stub->quality()) + ", " << "etaQuality=" + to_string(stub->etaQuality()) + ", " << "id=" + to_string(stub->address()) + ", " From 676591c9c5446229369fd7ef2920c1484b87e423 Mon Sep 17 00:00:00 2001 From: Zhenbin Wu Date: Tue, 7 Apr 2026 14:41:38 -0500 Subject: [PATCH 46/61] fix code-format differences --- L1Trigger/Phase2L1GMT/src/TPSAlgorithm.cc | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/L1Trigger/Phase2L1GMT/src/TPSAlgorithm.cc b/L1Trigger/Phase2L1GMT/src/TPSAlgorithm.cc index adc0ba0fce638..2b9cc098ee257 100644 --- a/L1Trigger/Phase2L1GMT/src/TPSAlgorithm.cc +++ b/L1Trigger/Phase2L1GMT/src/TPSAlgorithm.cc @@ -668,8 +668,7 @@ PreTrackMatchedMuon TPSAlgorithm::processTrack(const ConvertedTTTrack& track, << "eta=" + to_string(ap_int(track.eta())) + ", " << "z0=" + to_string(ap_int(track.z0())) + ", " << "d0=" + to_string(ap_int(track.d0())) + ", " - << "quality=" + to_string(ap_uint<1>(track.quality())) + ", " - << "\n" + << "quality=" + to_string(ap_uint<1>(track.quality())) + ", " << "\n" << std::flush; edm::LogInfo("TPSAlgo") << "Input stubs:" << std::flush; @@ -679,8 +678,7 @@ PreTrackMatchedMuon TPSAlgorithm::processTrack(const ConvertedTTTrack& track, << "layer=" + to_string(stub->tfLayer()) + ", " << "coord1=" + to_string(stub->coord1()) + ", " << "coord2=" + to_string(stub->coord2()) + ", " - << "eta1=" + to_string(stub->eta1()) + ", " - << "eta2=" + to_string(stub->eta2()) + ", " + << "eta1=" + to_string(stub->eta1()) + ", " << "eta2=" + to_string(stub->eta2()) + ", " << "quality=" + to_string(stub->quality()) + ", " << "etaQuality=" + to_string(stub->etaQuality()) + ", " << "id=" + to_string(stub->address()) + ", " << std::flush; @@ -689,16 +687,12 @@ PreTrackMatchedMuon TPSAlgorithm::processTrack(const ConvertedTTTrack& track, edm::LogInfo("TPSAlgo") << "End stubs\n" << std::flush; edm::LogInfo("TPSAlgo") << "Output PreTrackMatchedMuon: " - << "valid=" + to_string(muon.valid()) + ", " - << "q=" + to_string(muon.charge()) + ", " - << "pt=" + to_string(muon.pt()) + ", " - << "phi=" + to_string(muon.phi()) + ", " - << "eta=" + to_string(muon.eta()) + ", " - << "z0=" + to_string(muon.z0()) + ", " + << "valid=" + to_string(muon.valid()) + ", " << "q=" + to_string(muon.charge()) + ", " + << "pt=" + to_string(muon.pt()) + ", " << "phi=" + to_string(muon.phi()) + ", " + << "eta=" + to_string(muon.eta()) + ", " << "z0=" + to_string(muon.z0()) + ", " << "d0=" + to_string(muon.d0()) + ", " << "isGlobalMuon=" + to_string(muon.isGlobalMuon()) + ", " - << "beta=" + to_string(muon.beta()) + ", " - << "quality=" + to_string(muon.quality()) + ", " + << "beta=" + to_string(muon.beta()) + ", " << "quality=" + to_string(muon.quality()) + ", " << "\n" << std::flush; @@ -710,8 +704,7 @@ PreTrackMatchedMuon TPSAlgorithm::processTrack(const ConvertedTTTrack& track, << "layer=" + to_string(stub->tfLayer()) + ", " << "coord1=" + to_string(stub->coord1()) + ", " << "coord2=" + to_string(stub->coord2()) + ", " - << "eta1=" + to_string(stub->eta1()) + ", " - << "eta2=" + to_string(stub->eta2()) + ", " + << "eta1=" + to_string(stub->eta1()) + ", " << "eta2=" + to_string(stub->eta2()) + ", " << "phiQuality=" + to_string(stub->quality()) + ", " << "etaQuality=" + to_string(stub->etaQuality()) + ", " << "id=" + to_string(stub->address()) + ", " From 5b2960f3c7b472bd02f876c1c6fcc89b403721da Mon Sep 17 00:00:00 2001 From: Fabio Cossutti Date: Sun, 22 Mar 2026 19:08:57 +0100 Subject: [PATCH 47/61] Squashed commit of the following: commit ea365b302eee5ccba9502359163aabbf56a0b6ca Author: Fabio Cossutti Date: Sun Mar 22 19:05:08 2026 +0100 Remove ioread statements, update debug statements in EtlSimHitsValidation commit bc1de2adadbebcd73a5fcbcfcd0115444d6e6e56 Author: Fabio Cossutti Date: Sun Feb 15 19:30:51 2026 +0100 Temporariliy disable ioread statements for PSimHit commit a61561c0ea4f1261f1db9db577eae283bc376631 Author: Fabio Cossutti Date: Thu Feb 5 18:37:13 2026 +0100 Update PSimHit header and its usage according to comments commit 610740219b71b5d8897961958acc56ae8684bad4 Author: Fabio Cossutti Date: Mon Feb 2 10:00:01 2026 +0100 scram b code-format, add full ioread statement (not working correctly) commit 8b6ebc017700028b2f7ab97ea35778b7bdfe9d2b Author: Fabio Cossutti Date: Sun Feb 1 15:38:40 2026 +0100 Update variables' names commit 0f2f41e93207e192b2dd494aa6cf08b3a22b1cb9 Author: Fabio Cossutti Date: Thu Jan 29 15:59:45 2026 +0100 Update the hit production type definition commit 952d7105e7c376552817e73f8fe2498ec413d0cf Author: Fabio Cossutti Date: Wed Jan 28 18:50:59 2026 +0100 scram b code-checks commit 1f8b1eced17ac9eb1984856b63d6adf166bb6141 Author: Fabio Cossutti Date: Wed Jan 28 17:22:09 2026 +0100 Update MtdSimCluster and dependencies according to the PSimHit update Add test for PSimHit storage of process/hit type Enable backward compatibility for PSimHit commit 0af69f5381026ca64cb6db2b644dd8697b5b3ee9 Author: Fabio Cossutti Date: Mon Jan 26 17:58:27 2026 +0100 Replace MTD hit category with a general PSimHit hit category, use hitClassID to set it in TimingSD commit 5e15e404828b61907842cc2274f4e441d578c50c Author: Fabio Cossutti Date: Fri Jan 23 13:12:11 2026 +0100 Remove any reference to trackIdOffset from PSimHit, MtdSD and dependencies, temporarily silence use of offset to be replaced --- .../plugins/MVATrainingNtuple.cc | 8 +-- .../CaloAnalysis/interface/MtdSimCluster.h | 4 +- .../CaloAnalysis/src/MtdSimLayerCluster.cc | 2 +- .../TrackingHit/interface/PSimHit.h | 23 ++++--- .../TrackingHit/interface/SimHitCategory.h | 22 +++++++ .../TrackingHit/src/classes_def.xml | 3 +- SimDataFormats/TrackingHit/test/BuildFile.xml | 4 ++ .../TrackingHit/test/testPSimHit.cc | 24 +++++++ SimG4CMS/Forward/interface/BscG4Hit.h | 4 ++ SimG4CMS/Forward/interface/MtdHitCategory.h | 15 ----- SimG4CMS/Forward/interface/MtdSD.h | 2 +- SimG4CMS/Forward/src/BSCG4Hit.cc | 5 +- SimG4CMS/Forward/src/MtdSD.cc | 47 +++++--------- SimG4CMS/Forward/src/TimingSD.cc | 2 + .../Application/test/SimHitCaloHitDumper.cc | 3 +- SimG4Core/Notification/src/SimTrackManager.cc | 4 -- .../plugins/MtdTruthAccumulator.cc | 65 ++++++++++--------- .../plugins/BtlLocalRecoValidation.cc | 2 +- .../plugins/BtlSimHitsValidation.cc | 47 +++++++++----- .../plugins/EtlLocalRecoValidation.cc | 2 +- .../plugins/EtlSimHitsValidation.cc | 6 +- Validation/MtdValidation/plugins/MTDHit.h | 1 + .../plugins/MtdTracksValidation.cc | 10 +-- 23 files changed, 175 insertions(+), 130 deletions(-) create mode 100644 SimDataFormats/TrackingHit/interface/SimHitCategory.h create mode 100644 SimDataFormats/TrackingHit/test/BuildFile.xml create mode 100644 SimDataFormats/TrackingHit/test/testPSimHit.cc delete mode 100644 SimG4CMS/Forward/interface/MtdHitCategory.h diff --git a/RecoMTD/TimingIDTools/plugins/MVATrainingNtuple.cc b/RecoMTD/TimingIDTools/plugins/MVATrainingNtuple.cc index ccfbde216417b..aee7654e3fadc 100644 --- a/RecoMTD/TimingIDTools/plugins/MVATrainingNtuple.cc +++ b/RecoMTD/TimingIDTools/plugins/MVATrainingNtuple.cc @@ -709,9 +709,9 @@ void MVATrainingNtuple::analyze(const edm::Event& iEvent, const edm::EventSetup& }); // Check if TP has direct or other sim cluster for BTL for (const auto& simClusterRef : simClustersRefs) { - if (simClusterRef->trackIdOffset() == 0) { + if (simClusterRef->hitProdType() == 0) { isTPmtdDirectETL = true; - } else if (simClusterRef->trackIdOffset() != 0) { + } else if (simClusterRef->hitProdType() != 0) { isTPmtdOtherETL = true; } } @@ -724,9 +724,9 @@ void MVATrainingNtuple::analyze(const edm::Event& iEvent, const edm::EventSetup& }); // Check if TP has direct or other sim cluster for BTL for (const auto& simClusterRef : simClustersRefs) { - if (simClusterRef->trackIdOffset() == 0) { + if (simClusterRef->hitProdType() == 0) { isTPmtdDirectBTL = true; - } else if (simClusterRef->trackIdOffset() != 0) { + } else if (simClusterRef->hitProdType() != 0) { isTPmtdOtherBTL = true; } } diff --git a/SimDataFormats/CaloAnalysis/interface/MtdSimCluster.h b/SimDataFormats/CaloAnalysis/interface/MtdSimCluster.h index b7db1f4afaf60..a7502a65d6d90 100644 --- a/SimDataFormats/CaloAnalysis/interface/MtdSimCluster.h +++ b/SimDataFormats/CaloAnalysis/interface/MtdSimCluster.h @@ -116,9 +116,9 @@ class MtdSimCluster : public SimCluster { ++nsimhits_; } - void setTrackIdOffset(unsigned int offset) { idOffset_ = offset; } + void setHitProdType(unsigned int offset) { idOffset_ = offset; } - unsigned int trackIdOffset() const { return idOffset_; } + unsigned int hitProdType() const { return idOffset_; } protected: std::vector mtdHits_; diff --git a/SimDataFormats/CaloAnalysis/src/MtdSimLayerCluster.cc b/SimDataFormats/CaloAnalysis/src/MtdSimLayerCluster.cc index 201136111fca8..957711f1e822d 100644 --- a/SimDataFormats/CaloAnalysis/src/MtdSimLayerCluster.cc +++ b/SimDataFormats/CaloAnalysis/src/MtdSimLayerCluster.cc @@ -27,7 +27,7 @@ MtdSimLayerCluster::~MtdSimLayerCluster() {} std::ostream &operator<<(std::ostream &s, MtdSimLayerCluster const &tp) { s << "CP momentum, q, ID, & Event #: " << tp.p4() << " " << tp.charge() << " " << tp.pdgId() << " " << tp.eventId().bunchCrossing() << "." << tp.eventId().event() << std::endl; - s << " Offset " << tp.trackIdOffset() << " " + s << " Offset " << tp.hitProdType() << " " << " LC time " << tp.simLCTime() << " LC energy " << tp.simLCEnergy() << std::endl; for (MtdSimLayerCluster::genp_iterator hepT = tp.genParticle_begin(); hepT != tp.genParticle_end(); ++hepT) { diff --git a/SimDataFormats/TrackingHit/interface/PSimHit.h b/SimDataFormats/TrackingHit/interface/PSimHit.h index 375c7e0419cd3..d92aa15ad5994 100644 --- a/SimDataFormats/TrackingHit/interface/PSimHit.h +++ b/SimDataFormats/TrackingHit/interface/PSimHit.h @@ -14,8 +14,6 @@ class TrackingSlaveSD; // for friend declaration only class PSimHit { public: - static constexpr unsigned int k_tidOffset = 200000000; - PSimHit() : theDetUnitId(0) {} PSimHit(const Local3DPoint& entry, @@ -107,15 +105,6 @@ class PSimHit { */ unsigned int trackId() const { return theTrackId; } - /** In case te SimTrack ID is incremented by the k_tidOffset for hit category definition, this - * methods returns the original theTrackId value directly. - */ - unsigned int originalTrackId() const { return theTrackId % k_tidOffset; } - - unsigned int offsetTrackId() const { return theTrackId / k_tidOffset; } - - static unsigned int addTrackIdOffset(unsigned int tId, unsigned int offset) { return offset * k_tidOffset + tId; } - EncodedEventId eventId() const { return theEventId; } void setEventId(EncodedEventId e) { theEventId = e; } @@ -128,10 +117,20 @@ class PSimHit { * value with special significance is zero (for "undefined"), so zero should * not be the ID of any process. */ - unsigned short processType() const { return theProcessType; } + + // use 9 bits (up to 511) for process id, reserve the rest for hit production mechanism id + // 7 bits field available in PSimHit processType, i.e. up 127, to store processes + unsigned short processType() const { return theProcessType & kProcidMask; } + + unsigned short hitProdType() const { return (theProcessType >> kHitidShift) & kHitidMask; } + void setHitProdType(unsigned int hitId) { theProcessType |= hitId << kHitidShift; } void setTof(float tof) { theTof = tof; } + static constexpr unsigned int kProcidMask = 0x1FF; + static constexpr unsigned int kHitidMask = 0x7F; + static constexpr unsigned int kHitidShift = 9; + protected: // properties Local3DPoint theEntryPoint; // position at entry diff --git a/SimDataFormats/TrackingHit/interface/SimHitCategory.h b/SimDataFormats/TrackingHit/interface/SimHitCategory.h new file mode 100644 index 0000000000000..d62e3f34401a7 --- /dev/null +++ b/SimDataFormats/TrackingHit/interface/SimHitCategory.h @@ -0,0 +1,22 @@ +#ifndef SimHitCategory_h +#define SimHitCategory_h + +namespace SimHitCategory { + + // Identification code of sim hit production mechanism, subdetector dependent + + // MTD + + static constexpr unsigned int nCategoriesMTD = 5; + + static constexpr unsigned int prodTypeMTD[nCategoriesMTD] = { + 0, // direct hit from particle coming from tracker + 1, // BTL hit from secondary particle not saved in history + 2, // BTL hit from identified looper + 3, // BTL hit from back-scattering from CALO volume + 4 // ETL hit entering from a rear face of disks + }; + +}; // namespace SimHitCategory + +#endif diff --git a/SimDataFormats/TrackingHit/src/classes_def.xml b/SimDataFormats/TrackingHit/src/classes_def.xml index 9c815102df851..9e96e858a4971 100644 --- a/SimDataFormats/TrackingHit/src/classes_def.xml +++ b/SimDataFormats/TrackingHit/src/classes_def.xml @@ -1,5 +1,6 @@ - + + diff --git a/SimDataFormats/TrackingHit/test/BuildFile.xml b/SimDataFormats/TrackingHit/test/BuildFile.xml new file mode 100644 index 0000000000000..776344822a906 --- /dev/null +++ b/SimDataFormats/TrackingHit/test/BuildFile.xml @@ -0,0 +1,4 @@ + + + + diff --git a/SimDataFormats/TrackingHit/test/testPSimHit.cc b/SimDataFormats/TrackingHit/test/testPSimHit.cc new file mode 100644 index 0000000000000..986837c0cb149 --- /dev/null +++ b/SimDataFormats/TrackingHit/test/testPSimHit.cc @@ -0,0 +1,24 @@ +#include "SimDataFormats/TrackingHit/interface/PSimHit.h" + +#include +#include +#include + +int main() { + Local3DPoint dummy(0, 0, 0); + + for (int procId = 1; procId < 404; procId++) { + for (unsigned short itype = 0; itype < 8; itype++) { + PSimHit testHit(dummy, dummy, 0., 0., 0., 11, 0, 0, 0., 0., procId); + testHit.setHitProdType(itype); + std::cout << " hit procId = " << std::fixed << std::setw(8) << procId << " sim procId = " << std::setw(8) + << testHit.processType() << " hit type = " << std::setw(8) << itype << " sim type = " << std::setw(8) + << testHit.hitProdType() << std::endl; + + assert(procId == testHit.processType()); + assert(itype == testHit.hitProdType()); + } + } + + return 0; +} diff --git a/SimG4CMS/Forward/interface/BscG4Hit.h b/SimG4CMS/Forward/interface/BscG4Hit.h index 4aae1b75e3310..2e76af57b4867 100644 --- a/SimG4CMS/Forward/interface/BscG4Hit.h +++ b/SimG4CMS/Forward/interface/BscG4Hit.h @@ -14,6 +14,8 @@ #include #include +#include "SimDataFormats/TrackingHit/interface/PSimHit.h" + class BscG4Hit : public G4VHit { public: BscG4Hit(); @@ -92,6 +94,8 @@ class BscG4Hit : public G4VHit { int getParentId() const { return theParentId; }; int getProcessId() const { return theProcessId; }; + int getProdType() const { return (theProcessId >> PSimHit::kHitidShift) & PSimHit::kHitidMask; } + void setHitProdType(unsigned int hitId) { theProcessId |= hitId << PSimHit::kHitidShift; } float getVx() const { return theVx; }; float getVy() const { return theVy; }; float getVz() const { return theVz; }; diff --git a/SimG4CMS/Forward/interface/MtdHitCategory.h b/SimG4CMS/Forward/interface/MtdHitCategory.h deleted file mode 100644 index 29c4f02601249..0000000000000 --- a/SimG4CMS/Forward/interface/MtdHitCategory.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef SimG4CMSForward_MtdHitCategory_h -#define SimG4CMSForward_MtdHitCategory_h - -#include - -namespace MtdHitCategory { - static constexpr unsigned int k_idsecOffset = 1; - static constexpr unsigned int k_idloopOffset = 2; - static constexpr unsigned int k_idFromCaloOffset = 3; - static constexpr unsigned int k_idETLfromBack = 4; - static constexpr unsigned int n_categories = - std::max({k_idsecOffset, k_idloopOffset, k_idFromCaloOffset, k_idETLfromBack}); -}; // namespace MtdHitCategory - -#endif diff --git a/SimG4CMS/Forward/interface/MtdSD.h b/SimG4CMS/Forward/interface/MtdSD.h index 19d651fb84996..b82f9d3a16afa 100644 --- a/SimG4CMS/Forward/interface/MtdSD.h +++ b/SimG4CMS/Forward/interface/MtdSD.h @@ -2,7 +2,7 @@ #define SimG4CMSForward_MtdSD_h #include "SimG4CMS/Forward/interface/TimingSD.h" -#include "SimG4CMS/Forward/interface/MtdHitCategory.h" +#include "SimDataFormats/TrackingHit/interface/SimHitCategory.h" #include "FWCore/Framework/interface/Frameworkfwd.h" #include "FWCore/ParameterSet/interface/ParameterSetfwd.h" diff --git a/SimG4CMS/Forward/src/BSCG4Hit.cc b/SimG4CMS/Forward/src/BSCG4Hit.cc index c8b0f74e162c4..f6f6163d9b955 100644 --- a/SimG4CMS/Forward/src/BSCG4Hit.cc +++ b/SimG4CMS/Forward/src/BSCG4Hit.cc @@ -5,6 +5,7 @@ /////////////////////////////////////////////////////////////////////////////// #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "SimG4CMS/Forward/interface/BscG4Hit.h" +#include "SimDataFormats/TrackingHit/interface/SimHitCategory.h" #include BscG4Hit::BscG4Hit() : entry(0., 0., 0.), entrylp(0., 0., 0.), exitlp(0., 0., 0.) { @@ -141,8 +142,8 @@ std::ostream& operator<<(std::ostream& os, const BscG4Hit& hit) { << " EnergyLoss = " << hit.getEnergyLoss() << std::endl << " ParticleType = " << hit.getParticleType() << std::endl << " Pabs = " << hit.getPabs() << std::endl - << " Energy of primary particle (ID = " << hit.getTrackID() << ") = " << hit.getIncidentEnergy() << " (MeV)" - << std::endl + << " Energy of primary particle (ID = " << hit.getTrackID() << " hit type = " << hit.getProdType() + << ") = " << hit.getIncidentEnergy() << " (MeV)" << std::endl << " Entry point in Bsc unit number " << hit.getUnitID() << " is: " << hit.getEntry() << " (mm)" << std::endl; os << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; return os; diff --git a/SimG4CMS/Forward/src/MtdSD.cc b/SimG4CMS/Forward/src/MtdSD.cc index fc5869c86b363..3bf9728baad54 100644 --- a/SimG4CMS/Forward/src/MtdSD.cc +++ b/SimG4CMS/Forward/src/MtdSD.cc @@ -16,8 +16,6 @@ #include -using namespace MtdHitCategory; - //------------------------------------------------------------------- MtdSD::MtdSD(const std::string& name, const SensitiveDetectorCatalog& clg, @@ -111,32 +109,12 @@ int MtdSD::getTrackID(const G4Track* aTrack) { if (!trkInfo->storeTrack()) { theID = trkInfo->idLastStoredAncestor(); } - if (theID >= static_cast(PSimHit::k_tidOffset)) { - edm::LogError("MtdSim") << " SimTrack ID " << theID << " exceeds maximum allowed by PSimHit identifier" - << PSimHit::k_tidOffset << " unreliable MTD hit type"; - } - if (rname == "FastTimerRegionSensBTL") { - if (trkInfo->isInTrkFromBackscattering()) { - theID = PSimHit::addTrackIdOffset(theID, k_idFromCaloOffset); - } else if (trkInfo->isExtSecondary() && !trkInfo->isInTrkFromBackscattering() && !trkInfo->storeTrack()) { - theID = PSimHit::addTrackIdOffset(theID, k_idsecOffset); - } else if (trkInfo->isBTLlooper()) { - theID = PSimHit::addTrackIdOffset(theID, k_idloopOffset); - } -#ifdef EDM_ML_DEBUG - edm::LogVerbatim("MtdSim") << "MtdSD: Track ID: " << aTrack->GetTrackID() - << " BTL Track ID: " << trkInfo->mcTruthID() << ":" << theID; -#endif - } else if (rname == "FastTimerRegionSensETL") { - if (hitClassID == k_idETLfromBack) { - theID = PSimHit::addTrackIdOffset(theID, k_idETLfromBack); - } #ifdef EDM_ML_DEBUG - edm::LogVerbatim("MtdSim") << "MtdSD: Track ID: " << aTrack->GetTrackID() - << " ETL Track ID: " << trkInfo->mcTruthID() << ":" << theID; + edm::LogVerbatim("MtdSim") << "MtdSD: current Track ID: " << aTrack->GetTrackID() + << " stored Track ID: " << trkInfo->mcTruthID() << ":" << theID; #endif - // In the case of ECAL GFlash fast spot may be inside MTD and should be ignored - } else { + // In the case of ECAL GFlash fast spot may be inside MTD and should be ignored + if (rname != "FastTimerRegionSensBTL" && rname != "FastTimerRegionSensETL") { throw cms::Exception("MtdSDError") << "MtdSD called in incorrect region " << rname; } } else { @@ -148,20 +126,31 @@ int MtdSD::getTrackID(const G4Track* aTrack) { } void MtdSD::setHitClassID(const G4Step* aStep) { + hitClassID = 0; TrackInformation* trkInfo = cmsTrackInformation(aStep->GetTrack()); if (nullptr == trkInfo) { return; } const G4String& rname = aStep->GetTrack()->GetVolume()->GetLogicalVolume()->GetRegion()->GetName(); - if (rname == "FastTimerRegionSensETL") { + if (rname == "FastTimerRegionSensBTL") { + if (trkInfo->isInTrkFromBackscattering()) { + hitClassID = SimHitCategory::prodTypeMTD[3]; + } else if (trkInfo->isExtSecondary() && !trkInfo->isInTrkFromBackscattering() && !trkInfo->storeTrack()) { + hitClassID = SimHitCategory::prodTypeMTD[1]; + } else if (trkInfo->isBTLlooper()) { + hitClassID = SimHitCategory::prodTypeMTD[2]; + } + } else if (rname == "FastTimerRegionSensETL") { double zin = std::abs(aStep->GetPreStepPoint()->GetPosition().z()); double zout = std::abs(aStep->GetPostStepPoint()->GetPosition().z()); if (zout - zin < 0.) { - hitClassID = k_idETLfromBack; + hitClassID = SimHitCategory::prodTypeMTD[4]; trkInfo->setETLfromBack(); } else { - hitClassID = 0; trkInfo->setETLfromFront(); } } +#ifdef EDM_ML_DEBUG + edm::LogVerbatim("MtdSim") << "MtdSD: process type = " << hitClassID; +#endif } diff --git a/SimG4CMS/Forward/src/TimingSD.cc b/SimG4CMS/Forward/src/TimingSD.cc index 39c90a5c7a4ac..3998b657d318c 100644 --- a/SimG4CMS/Forward/src/TimingSD.cc +++ b/SimG4CMS/Forward/src/TimingSD.cc @@ -238,6 +238,7 @@ bool TimingSD::checkHit(const G4Step*, BscG4Hit* hit) { hit->setParentId(theTrack->GetParentID()); hit->setProcessId(theEnumerator->processId(theTrack->GetCreatorProcess())); + hit->setHitProdType(hitClassID); hit->setVertexPosition(theTrack->GetVertexPosition()); } @@ -294,6 +295,7 @@ void TimingSD::createNewHit(const G4Step* aStep) { currentHit->setParentId(theTrack->GetParentID()); currentHit->setProcessId(theEnumerator->processId(theTrack->GetCreatorProcess())); + currentHit->setHitProdType(hitClassID); currentHit->setVertexPosition(theTrack->GetVertexPosition()); diff --git a/SimG4Core/Application/test/SimHitCaloHitDumper.cc b/SimG4Core/Application/test/SimHitCaloHitDumper.cc index de105b3387768..80eeb75b26ba5 100644 --- a/SimG4Core/Application/test/SimHitCaloHitDumper.cc +++ b/SimG4Core/Application/test/SimHitCaloHitDumper.cc @@ -373,8 +373,7 @@ void SimHitCaloHitDumper::analyze(const edm::Event& iEvent, const edm::EventSetu for (int ihit = 0; ihit < (*icoll).first; ++ihit) { edm::LogPrint("SimHitCaloHitDumper") << theMTDHits[nhit] << " Energy = " << theMTDHits[nhit].energyLoss() - << " tid orig/offset= " << theMTDHits[nhit].originalTrackId() << " " << theMTDHits[nhit].offsetTrackId() - << " Track Id = " << theMTDHits[nhit].trackId(); + << " Track Id = " << theMTDHits[nhit].trackId() << " hit type = " << theMTDHits[nhit].hitProdType(); nhit++; } } diff --git a/SimG4Core/Notification/src/SimTrackManager.cc b/SimG4Core/Notification/src/SimTrackManager.cc index 16162236a34ea..73d771f0e6128 100644 --- a/SimG4Core/Notification/src/SimTrackManager.cc +++ b/SimG4Core/Notification/src/SimTrackManager.cc @@ -175,10 +175,6 @@ void SimTrackManager::reallyStoreTracks() { } } - if (id >= static_cast(PSimHit::k_tidOffset)) { - edm::LogWarning("SimTrackManager::reallyStoreTracks") - << " SimTrack ID " << id << " exceeds maximum allowed by PSimHit identifier" << PSimHit::k_tidOffset; - } TmpSimTrack* g4simtrack = new TmpSimTrack(id, trkH->particleID(), trkH->momentum(), trkH->totalEnergy(), ivertex, ig, pm, spos, smom); g4simtrack->copyCrossedBoundaryVars(trkH); diff --git a/SimGeneral/CaloAnalysis/plugins/MtdTruthAccumulator.cc b/SimGeneral/CaloAnalysis/plugins/MtdTruthAccumulator.cc index 930a1b5daec5e..0def9d5d6f417 100644 --- a/SimGeneral/CaloAnalysis/plugins/MtdTruthAccumulator.cc +++ b/SimGeneral/CaloAnalysis/plugins/MtdTruthAccumulator.cc @@ -42,6 +42,7 @@ #include "SimDataFormats/CaloAnalysis/interface/MtdSimTracksterFwd.h" #include "SimDataFormats/GeneratorProducts/interface/HepMCProduct.h" #include "SimDataFormats/TrackingHit/interface/PSimHit.h" +#include "SimDataFormats/TrackingHit/interface/SimHitCategory.h" #include "SimDataFormats/Vertex/interface/SimVertex.h" #include "SimGeneral/MixingModule/interface/DecayGraph.h" @@ -59,14 +60,17 @@ #include "Geometry/MTDGeometryBuilder/interface/ProxyMTDTopology.h" #include "Geometry/MTDGeometryBuilder/interface/RectangularMTDTopology.h" -#include "SimG4CMS/Forward/interface/MtdHitCategory.h" - #include namespace { using Index_t = unsigned; - using Barcode_t = int; + using Barcode_t = int64_t; const std::string messageCategoryGraph_("MtdTruthAccumulatorGraphProducer"); + inline int64_t tidAndProc(int a, unsigned short b) { + auto tmpout = static_cast(a) << 32; + tmpout |= b; + return tmpout; + } } // namespace class MtdTruthAccumulator : public DigiAccumulatorMixMod { @@ -88,10 +92,11 @@ class MtdTruthAccumulator : public DigiAccumulatorMixMod { /** @brief Fills the supplied vector with pointers to the SimHits, checking * for bad modules if required */ template - void fillSimHits(std::vector> &returnValue, - std::unordered_map>> &simTrackDetIdMap, - const T &event, - const edm::EventSetup &setup); + void fillSimHits( + std::vector> &returnValue, + std::unordered_map>> &simTrackDetIdMap, + const T &event, + const edm::EventSetup &setup); const std::string messageCategory_; @@ -164,13 +169,14 @@ class MtdTruthAccumulator : public DigiAccumulatorMixMod { /* Graph utility functions */ namespace { + class CaloParticle_dfs_visitor : public boost::default_dfs_visitor { public: CaloParticle_dfs_visitor( MtdTruthAccumulator::OutputCollections &output, MtdTruthAccumulator::calo_particles &caloParticles, std::unordered_multimap &simHitBarcodeToIndex, - std::unordered_map>> &simTrackDetIdMap, + std::unordered_map>> &simTrackDetIdMap, std::unordered_map &vertex_time_map, Selector selector) : output_(output), @@ -188,10 +194,9 @@ namespace { auto const vertex_property = get(vertex_name, g, u); if (!vertex_property.simTrack) return; - // -- loop over possible trackIdOffsets to save also sim clusters from non-direct hits - for (unsigned int offset = 0; offset < MtdHitCategory::n_categories + 1; offset++) { - auto trackIdx = vertex_property.simTrack->trackId(); - trackIdx += offset * (static_cast(PSimHit::k_tidOffset)); + // -- loop over possible hitProdTypes to save also sim clusters from non-direct hits + for (unsigned int offset = 0; offset < SimHitCategory::nCategoriesMTD; offset++) { + auto trackIdx = tidAndProc(vertex_property.simTrack->trackId(), offset); IfLogDebug(DEBUG, messageCategoryGraph_) << " Found " << simHitBarcodeToIndex_.count(trackIdx) << " associated simHits" << std::endl; if (simHitBarcodeToIndex_.count(trackIdx)) { @@ -205,12 +210,10 @@ namespace { simcluster.addHitAndFraction(hit_and_energy.first, hit_and_energy.second); simcluster.addHitEnergy(hit_and_energy.second); simcluster.addHitTime(std::get<1>( - simTrackDetIdMap_[simcluster.g4Tracks()[0].trackId() + - offset * (static_cast(PSimHit::k_tidOffset))][hit_and_energy.first])); + simTrackDetIdMap_[tidAndProc(simcluster.g4Tracks()[0].trackId(), offset)][hit_and_energy.first])); simcluster.addHitPosition(std::get<2>( - simTrackDetIdMap_[simcluster.g4Tracks()[0].trackId() + - offset * (static_cast(PSimHit::k_tidOffset))][hit_and_energy.first])); - simcluster.setTrackIdOffset(offset); + simTrackDetIdMap_[tidAndProc(simcluster.g4Tracks()[0].trackId(), offset)][hit_and_energy.first])); + simcluster.setHitProdType(offset); } } } @@ -248,7 +251,7 @@ namespace { MtdTruthAccumulator::OutputCollections &output_; MtdTruthAccumulator::calo_particles &caloParticles_; std::unordered_multimap &simHitBarcodeToIndex_; - std::unordered_map>> &simTrackDetIdMap_; + std::unordered_map>> &simTrackDetIdMap_; std::unordered_map &vertex_time_map_; Selector selector_; }; @@ -472,7 +475,7 @@ void MtdTruthAccumulator::finalizeEvent(edm::Event &event, edm::EventSetup const SimLCz = 0.; tmpLC.addCluIndex(SC_index); tmpLC.computeClusterTime(); - tmpLC.setTrackIdOffset(sc.trackIdOffset()); // add trackIdoffset + tmpLC.setHitProdType(sc.hitProdType()); // add hitProdType output_.pMtdSimLayerClusters->push_back(tmpLC); LC_indices.push_back(LC_index); LC_index++; @@ -605,13 +608,14 @@ void MtdTruthAccumulator::accumulateEvent(const T &event, event.getByLabel(genParticleLabel_, hGenParticleIndices); std::vector> simHitPointers; - std::unordered_map>> simTrackDetIdMap; + std::unordered_map>> simTrackDetIdMap; fillSimHits(simHitPointers, simTrackDetIdMap, event, setup); // Clear maps from previous event fill them for this one m_simHitBarcodeToIndex.clear(); for (unsigned int i = 0; i < simHitPointers.size(); ++i) { - m_simHitBarcodeToIndex.emplace(simHitPointers[i].second->trackId(), i); + m_simHitBarcodeToIndex.emplace( + tidAndProc(simHitPointers[i].second->trackId(), simHitPointers[i].second->hitProdType()), i); } auto const &tracks = *hSimTracks; @@ -740,7 +744,7 @@ void MtdTruthAccumulator::accumulateEvent(const T &event, template void MtdTruthAccumulator::fillSimHits( std::vector> &returnValue, - std::unordered_map>> &simTrackDetIdMap, + std::unordered_map>> &simTrackDetIdMap, const T &event, const edm::EventSetup &setup) { using namespace geant_units::operators; @@ -781,19 +785,20 @@ void MtdTruthAccumulator::fillSimHits( uniqueId |= pixel.first << 16; uniqueId |= pixel.second; - std::get<0>(simTrackDetIdMap[simHit.trackId()][uniqueId]) += simHit.energyLoss(); + int64_t trackIdx = tidAndProc(simHit.trackId(), simHit.hitProdType()); + std::get<0>(simTrackDetIdMap[trackIdx][uniqueId]) += simHit.energyLoss(); m_detIdToTotalSimEnergy[uniqueId] += simHit.energyLoss(); // --- Get the time of the first SIM hit in the cell - if (std::get<1>(simTrackDetIdMap[simHit.trackId()][uniqueId]) == 0. || - simHit.tof() < std::get<1>(simTrackDetIdMap[simHit.trackId()][uniqueId])) { - std::get<1>(simTrackDetIdMap[simHit.trackId()][uniqueId]) = simHit.tof(); + if (std::get<1>(simTrackDetIdMap[trackIdx][uniqueId]) == 0. || + simHit.tof() < std::get<1>(simTrackDetIdMap[trackIdx][uniqueId])) { + std::get<1>(simTrackDetIdMap[trackIdx][uniqueId]) = simHit.tof(); } - float xSim = std::get<2>(simTrackDetIdMap[simHit.trackId()][uniqueId]).x() + simscaled.x() * simHit.energyLoss(); - float ySim = std::get<2>(simTrackDetIdMap[simHit.trackId()][uniqueId]).y() + simscaled.y() * simHit.energyLoss(); - float zSim = std::get<2>(simTrackDetIdMap[simHit.trackId()][uniqueId]).z() + simscaled.z() * simHit.energyLoss(); + float xSim = std::get<2>(simTrackDetIdMap[trackIdx][uniqueId]).x() + simscaled.x() * simHit.energyLoss(); + float ySim = std::get<2>(simTrackDetIdMap[trackIdx][uniqueId]).y() + simscaled.y() * simHit.energyLoss(); + float zSim = std::get<2>(simTrackDetIdMap[trackIdx][uniqueId]).z() + simscaled.z() * simHit.energyLoss(); LocalPoint posSim(xSim, ySim, zSim); - std::get<2>(simTrackDetIdMap[simHit.trackId()][uniqueId]) = posSim; + std::get<2>(simTrackDetIdMap[trackIdx][uniqueId]) = posSim; #ifdef PRINT_DEBUG IfLogDebug(DEBUG, messageCategory_) diff --git a/Validation/MtdValidation/plugins/BtlLocalRecoValidation.cc b/Validation/MtdValidation/plugins/BtlLocalRecoValidation.cc index 219a6fd5532a2..1beab1d520715 100644 --- a/Validation/MtdValidation/plugins/BtlLocalRecoValidation.cc +++ b/Validation/MtdValidation/plugins/BtlLocalRecoValidation.cc @@ -686,7 +686,7 @@ void BtlLocalRecoValidation::analyze(const edm::Event& iEvent, const edm::EventS float simClusTime = (*simClusterRef).simLCTime(); LocalPoint simClusLocalPos = (*simClusterRef).simLCPos(); const auto& simClusGlobalPos = genericDet->toGlobal(simClusLocalPos); - unsigned int idOffset = (*simClusterRef).trackIdOffset(); + unsigned int idOffset = (*simClusterRef).hitProdType(); float time_res = cluster.time() - simClusTime; float energy_res = cluster.energy() - simClusEnergy; diff --git a/Validation/MtdValidation/plugins/BtlSimHitsValidation.cc b/Validation/MtdValidation/plugins/BtlSimHitsValidation.cc index edff176f70e3c..f4741ca1893dc 100644 --- a/Validation/MtdValidation/plugins/BtlSimHitsValidation.cc +++ b/Validation/MtdValidation/plugins/BtlSimHitsValidation.cc @@ -41,6 +41,14 @@ #include "MTDHit.h" +namespace { + + inline uint64_t cantor(uint64_t a, uint64_t b) { return (a + b + 1) * (a + b) / 2 + b; } + + inline uint64_t hash3(uint64_t a, uint64_t b, uint64_t c) { return cantor(a, cantor(b, c)); } + +} // namespace + class BtlSimHitsValidation : public DQMEDAnalyzer { public: explicit BtlSimHitsValidation(const edm::ParameterSet&); @@ -181,26 +189,28 @@ void BtlSimHitsValidation::analyze(const edm::Event& iEvent, const edm::EventSet DetId id = simHit.detUnitId(); // --- Build a global track ID by combining the SIM hit's eventId and trackId - uint64_t globalTrkID = ((uint64_t)simHit.eventId().rawId() << 32) | simHit.trackId(); + uint64_t cmbID = hash3(simHit.eventId().rawId(), simHit.trackId(), simHit.hitProdType()); // --- Define geoId from MTDTopology to group cells with hits by sensor module BTLDetId detId(id.rawId()); DetId geoId = detId.geographicalId(MTDTopologyMode::crysLayoutFromTopoMode(topology->getMTDTopologyMode())); // --- Sum the energies of SIM hits with the same track ID in the same cell - m_btlHitsPerCellAndModule[geoId.rawId()][id.rawId()][globalTrkID].energy += convertGeVToMeV(simHit.energyLoss()); + m_btlHitsPerCellAndModule[geoId.rawId()][id.rawId()][cmbID].energy += convertGeVToMeV(simHit.energyLoss()); // --- Assign the time and position of the first SIM hit in time to the accumulated hit - if (m_btlHitsPerCellAndModule[geoId.rawId()][id.rawId()][globalTrkID].time == 0. || - simHit.tof() < m_btlHitsPerCellAndModule[geoId.rawId()][id.rawId()][globalTrkID].time) { - m_btlHitsPerCellAndModule[geoId.rawId()][id.rawId()][globalTrkID].time = simHit.tof(); + if (m_btlHitsPerCellAndModule[geoId.rawId()][id.rawId()][cmbID].time == 0. || + simHit.tof() < m_btlHitsPerCellAndModule[geoId.rawId()][id.rawId()][cmbID].time) { + m_btlHitsPerCellAndModule[geoId.rawId()][id.rawId()][cmbID].time = simHit.tof(); auto hit_pos = simHit.localPosition(); - m_btlHitsPerCellAndModule[geoId.rawId()][id.rawId()][globalTrkID].x = hit_pos.x(); - m_btlHitsPerCellAndModule[geoId.rawId()][id.rawId()][globalTrkID].y = hit_pos.y(); - m_btlHitsPerCellAndModule[geoId.rawId()][id.rawId()][globalTrkID].z = hit_pos.z(); + m_btlHitsPerCellAndModule[geoId.rawId()][id.rawId()][cmbID].x = hit_pos.x(); + m_btlHitsPerCellAndModule[geoId.rawId()][id.rawId()][cmbID].y = hit_pos.y(); + m_btlHitsPerCellAndModule[geoId.rawId()][id.rawId()][cmbID].z = hit_pos.z(); - m_btlHitsPerCellAndModule[geoId.rawId()][id.rawId()][globalTrkID].thetaAtEntry = simHit.thetaAtEntry(); + m_btlHitsPerCellAndModule[geoId.rawId()][id.rawId()][cmbID].thetaAtEntry = simHit.thetaAtEntry(); + m_btlHitsPerCellAndModule[geoId.rawId()][id.rawId()][cmbID].prodType = + 2 * simHit.hitProdType(); // for backward compatibility multiply x 2 } } // simHit loop @@ -217,6 +227,7 @@ void BtlSimHitsValidation::analyze(const edm::Event& iEvent, const edm::EventSet meNhits_->Fill(log10(Nhits)); // --- Loop over the BTL sensor modules + std::vector v_hitID; for (const auto& module : m_btlHitsPerCellAndModule) { // --- Loop over the BTL cells for (auto const& cell : module.second) { @@ -229,7 +240,7 @@ void BtlSimHitsValidation::analyze(const edm::Event& iEvent, const edm::EventSet } // --- Loop over the hits in the cell, sum the hit energies and store the hit IDs in a vector - std::vector v_hitID; + v_hitID.clear(); float ene_tot_cell = 0.; for (auto const& hit : m_hits) { @@ -319,8 +330,8 @@ void BtlSimHitsValidation::analyze(const edm::Event& iEvent, const edm::EventSet meNtrkPerCell_->Fill(v_hitID.size()); // --- First hit in the cell - int trackID = (int)(v_hitID[0] & 0xFFFFFFFF) / 100000000; - meHitTrkID1_->Fill(trackID); + int prodID = (int)(m_hits.at(v_hitID[0]).prodType); + meHitTrkID1_->Fill(prodID); // cells in the bulk of energy distribution if (ene_tot_cell < cellEneCut_) { @@ -333,8 +344,8 @@ void BtlSimHitsValidation::analyze(const edm::Event& iEvent, const edm::EventSet // --- Second hit in the cell if (v_hitID.size() == 2) { - trackID = (int)(v_hitID[1] & 0xFFFFFFFF) / 100000000; - meHitTrkID2_->Fill(trackID); + prodID = (int)(m_hits.at(v_hitID[1]).prodType); + meHitTrkID2_->Fill(prodID); meHitDeltaT2_->Fill(deltaT_max); @@ -353,8 +364,8 @@ void BtlSimHitsValidation::analyze(const edm::Event& iEvent, const edm::EventSet } // --- Third hit in the cell else if (v_hitID.size() == 3) { - trackID = (int)(v_hitID[2] & 0xFFFFFFFF) / 100000000; - meHitTrkID3_->Fill(trackID); + prodID = (int)(m_hits.at(v_hitID[2]).prodType); + meHitTrkID3_->Fill(prodID); meHitDeltaT3_->Fill(deltaT_max); @@ -371,8 +382,8 @@ void BtlSimHitsValidation::analyze(const edm::Event& iEvent, const edm::EventSet // --- Fourth hit in the cell and next ones else if (v_hitID.size() >= 4) { for (unsigned int ihit = 3; ihit < v_hitID.size(); ++ihit) { - trackID = (int)(v_hitID[ihit] & 0xFFFFFFFF) / 100000000; - meHitTrkID4_->Fill(trackID); + prodID = (int)(m_hits.at(v_hitID[ihit]).prodType); + meHitTrkID4_->Fill(prodID); // cells in the bulk of energy distribution if (ene_tot_cell < cellEneCut_) { diff --git a/Validation/MtdValidation/plugins/EtlLocalRecoValidation.cc b/Validation/MtdValidation/plugins/EtlLocalRecoValidation.cc index 42b95272511d8..f0a36f541d639 100644 --- a/Validation/MtdValidation/plugins/EtlLocalRecoValidation.cc +++ b/Validation/MtdValidation/plugins/EtlLocalRecoValidation.cc @@ -526,7 +526,7 @@ void EtlLocalRecoValidation::analyze(const edm::Event& iEvent, const edm::EventS (*itp.first).second; // the range of itp.first, itp.second should be always 1 for (unsigned int i = 0; i < simClustersRefs.size(); i++) { const auto& simClusterRef = simClustersRefs[i]; - unsigned int idOffset = (*simClusterRef).trackIdOffset(); + unsigned int idOffset = (*simClusterRef).hitProdType(); meCluTrackIdOffset_[idet]->Fill(float(idOffset)); diff --git a/Validation/MtdValidation/plugins/EtlSimHitsValidation.cc b/Validation/MtdValidation/plugins/EtlSimHitsValidation.cc index 69e926b7cb5e1..a860d03432a6e 100644 --- a/Validation/MtdValidation/plugins/EtlSimHitsValidation.cc +++ b/Validation/MtdValidation/plugins/EtlSimHitsValidation.cc @@ -182,7 +182,7 @@ void EtlSimHitsValidation::analyze(const edm::Event& iEvent, const edm::EventSet (simHitIt->second).y = hit_pos.y(); (simHitIt->second).z = hit_pos.z(); - if (simHit.offsetTrackId() == 0) { + if (simHit.hitProdType() == 0) { if (simHit.exitPoint() != simHit.entryPoint()) { (simHitIt->second).thetaAtEntry = angle_units::operators::convertRadToDeg((simHit.exitPoint() - simHit.entryPoint()).bareTheta()); @@ -194,7 +194,9 @@ void EtlSimHitsValidation::analyze(const edm::Event& iEvent, const edm::EventSet (simHitIt->second).thetaAtEntry = -90.; } } - LogDebug("EtlSimHitsValidation") << "Registered in idet " << idet; + + LogDebug("EtlSimHitsValidation") << "Registered in idet " << idet << " EtlDetId " << id.rawId() << " r/c " + << (uint32_t)pixel.first << " " << (uint32_t)pixel.second; } // simHit loop diff --git a/Validation/MtdValidation/plugins/MTDHit.h b/Validation/MtdValidation/plugins/MTDHit.h index c3186d96d8b93..aa67ed716e83e 100644 --- a/Validation/MtdValidation/plugins/MTDHit.h +++ b/Validation/MtdValidation/plugins/MTDHit.h @@ -8,6 +8,7 @@ struct MTDHit { float y; float z; float thetaAtEntry; + unsigned short prodType; }; #endif //Validation_MtdValidation_MTDHit_h diff --git a/Validation/MtdValidation/plugins/MtdTracksValidation.cc b/Validation/MtdValidation/plugins/MtdTracksValidation.cc index a8f966f89c869..6e8789bcebb75 100644 --- a/Validation/MtdValidation/plugins/MtdTracksValidation.cc +++ b/Validation/MtdValidation/plugins/MtdTracksValidation.cc @@ -906,13 +906,13 @@ void MtdTracksValidation::analyze(const edm::Event& iEvent, const edm::EventSetu // Find the first direct hit in time directSimClusIt = std::find_if(simClustersRefs.begin(), simClustersRefs.end(), [](const auto& simCluster) { MTDDetId mtddetid = simCluster->detIds_and_rows().front().first; - return (mtddetid.mtdSubDetector() == 1 && simCluster->trackIdOffset() == 0); + return (mtddetid.mtdSubDetector() == 1 && simCluster->hitProdType() == 0); }); // Check if TP has direct or other sim cluster for BTL for (const auto& simClusterRef : simClustersRefs) { if (directSimClusIt != simClustersRefs.end() && simClusterRef == *directSimClusIt) { isTPmtdDirectBTL = true; - } else if (simClusterRef->trackIdOffset() != 0) { + } else if (simClusterRef->hitProdType() != 0) { isTPmtdOtherBTL = true; } } @@ -950,7 +950,7 @@ void MtdTracksValidation::analyze(const edm::Event& iEvent, const edm::EventSetu GlobalPoint simClusRecoMatchGlobalPos = geomUtil.globalPosition(detidRecoMatch, simClusRecoMatchLocalPos); - simClusterRef_RecoMatch_trackIdOff = simClusterRef_RecoMatch->trackIdOffset(); + simClusterRef_RecoMatch_trackIdOff = simClusterRef_RecoMatch->hitProdType(); simClusterRef_RecoMatch_DeltaZ = simClusRecoMatchGlobalPos.z() - simClusGlobalPos.z(); simClusterRef_RecoMatch_DeltaPhi = simClusRecoMatchGlobalPos.phi() - simClusGlobalPos.phi(); simClusterRef_RecoMatch_DeltaT = simClusterRef_RecoMatch->simLCTime() - directSimClus->simLCTime(); @@ -964,7 +964,7 @@ void MtdTracksValidation::analyze(const edm::Event& iEvent, const edm::EventSetu isTPmtdDirectCorrectBTL = true; simClusterEarliestTime_correctAssoc = earliestSimHitTimeInSimCluster((*simClusterIt)); - } else if (simClusterRef_RecoMatch->trackIdOffset() != 0) { + } else if (simClusterRef_RecoMatch->hitProdType() != 0) { isTPmtdOtherCorrectBTL = true; } } @@ -1374,7 +1374,7 @@ void MtdTracksValidation::analyze(const edm::Event& iEvent, const edm::EventSetu meBTLTrackMatchedTPnomtdAssocTrackID_->Fill(1); } } - meBTLTrackMatchedTPnomtdAssocTrackIdOff_->Fill(sc->trackIdOffset()); + meBTLTrackMatchedTPnomtdAssocTrackIdOff_->Fill(sc->hitProdType()); } } } From a9fdfc515a67a060a574d27d021afd2bd25d84c7 Mon Sep 17 00:00:00 2001 From: Fabio Cossutti Date: Tue, 24 Mar 2026 18:27:46 +0100 Subject: [PATCH 48/61] Add ioread statements for PSimHit backward compatibility in classes_def.xml --- SimDataFormats/TrackingHit/src/classes_def.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/SimDataFormats/TrackingHit/src/classes_def.xml b/SimDataFormats/TrackingHit/src/classes_def.xml index 9e96e858a4971..dcae308894bd5 100644 --- a/SimDataFormats/TrackingHit/src/classes_def.xml +++ b/SimDataFormats/TrackingHit/src/classes_def.xml @@ -2,6 +2,16 @@ + + > 25) == 0x31) {theTrackId = (onfile.theTrackId % 200000000);} + ]]> + + + > 25) == 0x31) {unsigned short tmp = onfile.theProcessType; tmp |= (onfile.theTrackId / 200000000) << 9 ; theProcessType = tmp;} + ]]> + From 59bf7e643c073e08baa3d575a77a7e427ed774d6 Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Mon, 13 Apr 2026 19:15:33 +0200 Subject: [PATCH 49/61] comment out validation step as per alaperto request --- DQM/SiTrackerPhase2/test/dqmstep_phase2tk_cfg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DQM/SiTrackerPhase2/test/dqmstep_phase2tk_cfg.py b/DQM/SiTrackerPhase2/test/dqmstep_phase2tk_cfg.py index 74e0704aa28d1..fce3163a9eb48 100644 --- a/DQM/SiTrackerPhase2/test/dqmstep_phase2tk_cfg.py +++ b/DQM/SiTrackerPhase2/test/dqmstep_phase2tk_cfg.py @@ -35,7 +35,7 @@ process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') process.maxEvents = cms.untracked.PSet( - input = cms.untracked.int32(10), + input = cms.untracked.int32(-1), output = cms.optional.untracked.allowed(cms.int32,cms.PSet) ) From a94bc1b202ef61ce59b725ed6c35ef629f1590c3 Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Mon, 13 Apr 2026 19:43:47 +0200 Subject: [PATCH 50/61] change number of events to 10 --- DQM/SiTrackerPhase2/test/dqmstep_phase2tk_cfg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DQM/SiTrackerPhase2/test/dqmstep_phase2tk_cfg.py b/DQM/SiTrackerPhase2/test/dqmstep_phase2tk_cfg.py index fce3163a9eb48..74e0704aa28d1 100644 --- a/DQM/SiTrackerPhase2/test/dqmstep_phase2tk_cfg.py +++ b/DQM/SiTrackerPhase2/test/dqmstep_phase2tk_cfg.py @@ -35,7 +35,7 @@ process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') process.maxEvents = cms.untracked.PSet( - input = cms.untracked.int32(-1), + input = cms.untracked.int32(10), output = cms.optional.untracked.allowed(cms.int32,cms.PSet) ) From ba046bc7a5d3c12b30c0cdcf981b72d87feacc57 Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Mon, 13 Apr 2026 19:46:09 +0200 Subject: [PATCH 51/61] commented out validation step --- DQM/SiTrackerPhase2/test/harvestingstep_phase2tk_cfg.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/DQM/SiTrackerPhase2/test/harvestingstep_phase2tk_cfg.py b/DQM/SiTrackerPhase2/test/harvestingstep_phase2tk_cfg.py index 0fb9404224e46..088c4ab7c17f5 100644 --- a/DQM/SiTrackerPhase2/test/harvestingstep_phase2tk_cfg.py +++ b/DQM/SiTrackerPhase2/test/harvestingstep_phase2tk_cfg.py @@ -81,11 +81,13 @@ # Other statements from Configuration.AlCa.GlobalTag import GlobalTag process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase2_realistic_T35', '') -process.trackerphase2ValidationHarvesting_standalone += process.phase2OTEffClientSeq # Path and EndPath definitions -process.trackerphase2ValidationHarvesting_step = cms.Path(process.trackerphase2ValidationHarvesting_standalone) +#process.trackerphase2ValidationHarvesting_step = cms.Path(process.trackerphase2ValidationHarvesting_standalone) +##default path in production +#process.trackerphase2ValidationHarvesting_step = cms.Path(process.trackerphase2ValidationHarvesting) process.dqmsave_step = cms.Path(process.DQMSaver) # Schedule definition -process.schedule = cms.Schedule(process.trackerphase2ValidationHarvesting_step, process.dqmsave_step) +#process.schedule = cms.Schedule(process.trackerphase2ValidationHarvesting_step, process.dqmsave_step) +process.schedule = cms.Schedule(process.dqmsave_step) \ No newline at end of file From 1e375b19b931779037f80a98b80b341f71652533 Mon Sep 17 00:00:00 2001 From: Fabio Cossutti Date: Mon, 27 Apr 2026 10:47:27 +0200 Subject: [PATCH 52/61] Revert "Add ioread statements for PSimHit backward compatibility in classes_def.xml" This reverts commit a9fdfc515a67a060a574d27d021afd2bd25d84c7. --- SimDataFormats/TrackingHit/src/classes_def.xml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/SimDataFormats/TrackingHit/src/classes_def.xml b/SimDataFormats/TrackingHit/src/classes_def.xml index dcae308894bd5..9e96e858a4971 100644 --- a/SimDataFormats/TrackingHit/src/classes_def.xml +++ b/SimDataFormats/TrackingHit/src/classes_def.xml @@ -2,16 +2,6 @@ - - > 25) == 0x31) {theTrackId = (onfile.theTrackId % 200000000);} - ]]> - - - > 25) == 0x31) {unsigned short tmp = onfile.theProcessType; tmp |= (onfile.theTrackId / 200000000) << 9 ; theProcessType = tmp;} - ]]> - From c16c8cce71cb11ea48d68cc13ee6482e6260d520 Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Tue, 28 Apr 2026 19:56:08 +0200 Subject: [PATCH 53/61] comment out unused validation load --- DQM/SiTrackerPhase2/test/harvestingstep_phase2tk_cfg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DQM/SiTrackerPhase2/test/harvestingstep_phase2tk_cfg.py b/DQM/SiTrackerPhase2/test/harvestingstep_phase2tk_cfg.py index 088c4ab7c17f5..cd91a1bbf8b95 100644 --- a/DQM/SiTrackerPhase2/test/harvestingstep_phase2tk_cfg.py +++ b/DQM/SiTrackerPhase2/test/harvestingstep_phase2tk_cfg.py @@ -27,7 +27,7 @@ process.load('Configuration.StandardSequences.DQMSaverAtRunEnd_cff') process.load('Configuration.StandardSequences.Harvesting_cff') process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') -process.load('Validation.SiTrackerPhase2V.Phase2OTEffClient_cff') +#process.load('Validation.SiTrackerPhase2V.Phase2OTEffClient_cff') process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(8000), From 4821d8a8bd078e12396d6ee375a4f24b1799a328 Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Tue, 28 Apr 2026 21:01:50 +0200 Subject: [PATCH 54/61] Increase thresholds for EE high eta and fwd region in presample client --- DQM/EcalMonitorClient/python/PresampleClient_cfi.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DQM/EcalMonitorClient/python/PresampleClient_cfi.py b/DQM/EcalMonitorClient/python/PresampleClient_cfi.py index e051098f16097..c50830c9d71dd 100644 --- a/DQM/EcalMonitorClient/python/PresampleClient_cfi.py +++ b/DQM/EcalMonitorClient/python/PresampleClient_cfi.py @@ -6,8 +6,8 @@ minChannelEntries = 6 expectedMean = 200.0 toleranceLow = 25.0 -toleranceHigh = 60.0 -toleranceHighFwd = 100.0 +toleranceHigh = 80.0 +toleranceHighFwd = 120.0 toleranceRMS = 6.0 toleranceRMSFwd = 6.0 From db8021128982d6a744bf0098b8c6c9a2efe7b4c1 Mon Sep 17 00:00:00 2001 From: Gabriel Moreira Date: Wed, 29 Apr 2026 16:30:47 +0200 Subject: [PATCH 55/61] refactor: update personalPlayback to handle optional extra arguments Please, check the following comment for more information: https://github.com/cms-sw/cmssw/pull/50643#issuecomment-4215060186 Signed-off-by: Gabriel Moreira --- DQMServices/StreamerIO/scripts/personalPlayback.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/DQMServices/StreamerIO/scripts/personalPlayback.py b/DQMServices/StreamerIO/scripts/personalPlayback.py index c91662460d91c..788bf5e8400e0 100755 --- a/DQMServices/StreamerIO/scripts/personalPlayback.py +++ b/DQMServices/StreamerIO/scripts/personalPlayback.py @@ -218,7 +218,7 @@ def do_exec(self): logname="/var/log/hltd/pid/hlt_run$4_pid$$.log" lognamez="/var/log/hltd/pid/hlt_run$4_pid$$_gzip.log.gz" #override the noclobber option by using >| operator for redirection - then keep appending to log -echo startDqmRun invoked $TODAY with arguments $1 $2 $3 $4 $5 $6 $7 $8 >| $logname +echo startDqmRun invoked $TODAY with arguments $@ >| $logname export http_proxy="http://cmsproxy.cms:3128" export https_proxy="https://cmsproxy.cms:3128/" export NO_PROXY=".cms" @@ -232,8 +232,8 @@ def do_exec(self): eval `scram runtime -sh`; cd $3; pwd >> $logname 2>&1 -#exec esMonitoring.py -z $lognamez cmsRun `readlink $6` runInputDir=$5 runNumber=$4 $7 $8 >> $logname 2>&1 -exec esMonitoring.py cmsRun `readlink $6` runInputDir=$5 runNumber=$4 $7 $8 +#exec esMonitoring.py -z $lognamez cmsRun `readlink $6` runInputDir=$5 runNumber=$4 ${{@:7}} >> $logname 2>&1 +exec esMonitoring.py cmsRun `readlink $6` runInputDir=$5 runNumber=$4 ${{@:7}} """ start_dqm_job = start_dqm_job.replace("/var/log/hltd/pid/", '{log_path}/') @@ -361,6 +361,9 @@ def make_args(self, run): args.append(self.cfg_link) # cmsRun arg 1 args.append(f"runkey={self.opts.run_key}") # cmsRun arg 2 + for extra_arg in self.opts.extra_args: + args.append(extra_arg) + return args def discover_latest(self): @@ -472,6 +475,8 @@ def do_exec(self): run_group.add_argument("--cmsRun", type=str, help="cmsRun command to run, for igprof and so on.", default="cmsRun") run_group.add_argument("--run_key", type=str, help="Run key to use (pp_run, cosmic_run or hi_run)", default="pp_run") + client_group = parser.add_argument_group("Client", "Client extra arguments.") + client_group.add_argument("--extra-args", nargs="+", metavar="KEY=VALUE", help="Client extra arguments split by whitespace") parser.add_argument('cmssw_configs', metavar='cmssw_cfg.py', type=str, nargs='*', help='List of cmssw jobs (clients).') From 40574050e49d9ddcd1e7a9ccff1058a20870d917 Mon Sep 17 00:00:00 2001 From: Brandi Skipworth Date: Wed, 29 Apr 2026 16:40:46 +0200 Subject: [PATCH 56/61] Add Phase2OTEffClient to harvesting sequences to enable central DQM GUI plots --- .../SiTrackerPhase2V/python/Phase2TrackerMCHarvesting_cff.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Validation/SiTrackerPhase2V/python/Phase2TrackerMCHarvesting_cff.py b/Validation/SiTrackerPhase2V/python/Phase2TrackerMCHarvesting_cff.py index d1b1d6b77b32f..98c331c578c2e 100644 --- a/Validation/SiTrackerPhase2V/python/Phase2TrackerMCHarvesting_cff.py +++ b/Validation/SiTrackerPhase2V/python/Phase2TrackerMCHarvesting_cff.py @@ -4,6 +4,7 @@ from Validation.SiTrackerPhase2V.Phase2ITRechitHarvester_cfi import * from Validation.SiTrackerPhase2V.Phase2OTHarvestTracks_cfi import * +from Validation.SiTrackerPhase2V.Phase2OTEffClient_cff import * #ITTracking rechit #clone the rechit harvester for tracking rechit Phase2ITtrackingrechitHarvester=Phase2ITRechitHarvester.clone( @@ -65,6 +66,7 @@ * Phase2ITtrackingrechitHarvester * Phase2OTTrackingRechitHarvester_PS * Phase2OTTrackingRechitHarvester_2S + * phase2OTEffClientSeq ) from Configuration.ProcessModifiers.vectorHits_cff import vectorHits @@ -77,4 +79,5 @@ * Phase2OTTrackingRechitHarvester_PS * Phase2OTTrackingRechitHarvester_2S * Phase2OTHarvestTracks + * phase2OTEffClientSeq ) From de5473288bf0a92c9c7bb853b5c0baea25456529 Mon Sep 17 00:00:00 2001 From: Sunanda Date: Thu, 30 Apr 2026 07:42:08 +0200 Subject: [PATCH 57/61] Try to add all the rings in the fine layers of the HGCal Scintillator tiles in the V19 version --- .../HGCalCommonData/src/HGCalDDDConstants.cc | 12 ++++++--- .../src/HGCalGeomParameters.cc | 2 +- Geometry/HGCalGeometry/src/HGCalGeometry.cc | 2 ++ .../HGCalGeometry/src/HGCalGeometryLoader.cc | 6 ++--- .../python/testHGCalValidScintTest_cfg.py | 25 ++++++++++++++++++- 5 files changed, 38 insertions(+), 9 deletions(-) diff --git a/Geometry/HGCalCommonData/src/HGCalDDDConstants.cc b/Geometry/HGCalCommonData/src/HGCalDDDConstants.cc index 31ac7028cb374..d1b046c8a9a28 100644 --- a/Geometry/HGCalCommonData/src/HGCalDDDConstants.cc +++ b/Geometry/HGCalCommonData/src/HGCalDDDConstants.cc @@ -1557,9 +1557,9 @@ bool HGCalDDDConstants::tileExist(int zside, int layer, int ring, int phi) const const auto& index = getIndex(layer, true); bool fine = hgpar_->scintFine(index.first); #ifdef EDM_ML_DEBUG - edm::LogVerbatim("HGCalGeomT") << "TileExist: Layer : " << layer << ":" << index.first << " Fine " << fine; + edm::LogVerbatim("HGCalGeomT") << "TileExist: Layer : " << layer << ":" << index.first << " Fine " << fine << " index " << index.first << " :" << index.second; #endif - bool ok = ((ring >= hgpar_->iradMinBH_[index.first]) && (ring <= hgpar_->iradMaxBH_[index.first])); + bool ok = (fine) ? ((ring >= hgpar_->iradMinBHFine_[index.first]) && (ring <= hgpar_->iradMaxBHFine_[index.first])): ((ring >= hgpar_->iradMinBH_[index.first]) && (ring <= hgpar_->iradMaxBH_[index.first])); if (ok) { if (fine) { int indx = HGCalTileIndex::tileIndex(layer, ring, 1); @@ -1601,9 +1601,13 @@ bool HGCalDDDConstants::tileExist(int zside, int layer, int ring, int phi) const } #ifdef EDM_ML_DEBUG } else { + std::ostringstream st1; + if (fine) + st1 << hgpar_->iradMinBHFine_[index.first] << ":" << hgpar_->iradMaxBHFine_[index.first]; + else + st1 << hgpar_->iradMinBH_[index.first] << ":" << hgpar_->iradMaxBH_[index.first]; edm::LogWarning("HGCalGeomT") << "TileExist:input " << zside << ":" << layer << ":" << ring << ":" << phi - << " Index " << index.first << " Ring limits " << hgpar_->iradMinBH_[index.first] - << ":" << hgpar_->iradMaxBH_[index.first] << " ok " << ok; + << " Index " << index.first << " Ring limits " << st1.str() << " ok " << ok; #endif } return ok; diff --git a/Geometry/HGCalCommonData/src/HGCalGeomParameters.cc b/Geometry/HGCalCommonData/src/HGCalGeomParameters.cc index 4424cd7d15c4d..ff3e54e014fc0 100644 --- a/Geometry/HGCalCommonData/src/HGCalGeomParameters.cc +++ b/Geometry/HGCalCommonData/src/HGCalGeomParameters.cc @@ -2571,7 +2571,7 @@ void HGCalGeomParameters::loadCellTrapezoid(HGCalParameters& php) { double rmin = php.radiusLayer_[kk][std::max((irmin - 1), 0)]; double rmax = php.radiusLayer_[kk][std::min(irmax, irm)]; edm::LogVerbatim("HGCalGeom") << "Layer " << php.firstLayer_ + k << ":" << kk << " Radius range " << irmin << ":" - << irmax << ":" << rmin << ":" << rmax << " Size " << php.radiusLayer_[kk].size(); + << irmax << ":" << rmin << ":" << rmax << " Size " << php.radiusLayer_[kk].size() << " nphi " << php.nPhiLayer_[k] ; #endif mytr.lay = php.firstLayer_ + k; for (int irad = irmin; irad <= irmax; ++irad) { diff --git a/Geometry/HGCalGeometry/src/HGCalGeometry.cc b/Geometry/HGCalGeometry/src/HGCalGeometry.cc index 2d7e66c5d0112..96b84b4ec5640 100644 --- a/Geometry/HGCalGeometry/src/HGCalGeometry.cc +++ b/Geometry/HGCalGeometry/src/HGCalGeometry.cc @@ -108,7 +108,9 @@ void HGCalGeometry::newCell( DetId idc = m_topology.encode(id); if (m_topology.valid(idc)) { HGCScintillatorDetId hid(idc); +#ifdef EDM_ML_DEBUG edm::LogVerbatim("HGCalGeom") << "buildGeom: Layer" << hid.layer() << " Ring " << hid.ring(); +#endif std::pair typm = m_topology.dddConstants().tileType(hid.layer(), hid.ring(), 0); if (typm.first >= 0) { hid.setType(typm.first); diff --git a/Geometry/HGCalGeometry/src/HGCalGeometryLoader.cc b/Geometry/HGCalGeometry/src/HGCalGeometryLoader.cc index 4ea3f11c3eb40..9117e77710497 100644 --- a/Geometry/HGCalGeometry/src/HGCalGeometryLoader.cc +++ b/Geometry/HGCalGeometry/src/HGCalGeometryLoader.cc @@ -86,14 +86,14 @@ HGCalGeometry* HGCalGeometryLoader::build(const HGCalTopology& topology) { } } } else if (topology.tileTrapezoid()) { + auto rings = topology.dddConstants().tileRings(layer); int indx = topology.dddConstants().layerIndex(layer, true); - int ring = topology.dddConstants().getParameter()->iradMinBH_[indx]; + int ring = rings.first + 1; int nphi = topology.dddConstants().getParameter()->scintCells(layer); int type = topology.dddConstants().getParameter()->scintType(layer); #ifdef EDM_ML_DEBUG edm::LogVerbatim("HGCalGeom") << "Trap::Layer " << layer << ":" << indx << " Ring " << ring << ":" - << topology.dddConstants().getParameter()->iradMaxBH_[indx] << " Phi " << nphi - << " Type " << type; + << rings.second << " Phi " << nphi << " Type " << type << " Modules " << topology.dddConstants().getParameter()->firstModule_[indx] << ":" << topology.dddConstants().getParameter()->lastModule_[indx]; #endif for (int md = topology.dddConstants().getParameter()->firstModule_[indx]; md <= topology.dddConstants().getParameter()->lastModule_[indx]; diff --git a/Geometry/HGCalGeometry/test/python/testHGCalValidScintTest_cfg.py b/Geometry/HGCalGeometry/test/python/testHGCalValidScintTest_cfg.py index 4b10ad39d4404..b464ce9292c80 100644 --- a/Geometry/HGCalGeometry/test/python/testHGCalValidScintTest_cfg.py +++ b/Geometry/HGCalGeometry/test/python/testHGCalValidScintTest_cfg.py @@ -1,6 +1,29 @@ +############################################################################### +# Way to use this: +# cmsRun testHGCaValidScintTest_cfg.py geomName=Run4D120 +# +# Options for geomName: Run4D120, Run4D121, Run4D122, Run4D123 +# +############################################################################### import FWCore.ParameterSet.Config as cms +import os, sys, importlib, re +import FWCore.ParameterSet.VarParsing as VarParsing -geomName = "Run4D121" +#################################################################### +### SETUP OPTIONS +options = VarParsing.VarParsing('standard') +options.register('geomName', + "Run4D121", + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.string, + "geometry of operations: Run4D120, Run4D121, Run4D122, Run4D123") +### get and parse the command line arguments + +options.parseArguments() +print(options) + +#################################################################### +geomName = options.geomName geomFile = "Configuration.Geometry.GeometryExtended" + geomName + "Reco_cff" import Configuration.Geometry.defaultPhase2ConditionsEra_cff as _settings GLOBAL_TAG, ERA = _settings.get_era_and_conditions(geomName) From 273dfb2d7ef5b4a934c09ace1e30dd6c4fcce29c Mon Sep 17 00:00:00 2001 From: Sunanda Date: Thu, 30 Apr 2026 07:47:43 +0200 Subject: [PATCH 58/61] Code Check --- Geometry/HGCalCommonData/src/HGCalDDDConstants.cc | 8 +++++--- Geometry/HGCalCommonData/src/HGCalGeomParameters.cc | 3 ++- Geometry/HGCalGeometry/src/HGCalGeometryLoader.cc | 6 ++++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/Geometry/HGCalCommonData/src/HGCalDDDConstants.cc b/Geometry/HGCalCommonData/src/HGCalDDDConstants.cc index d1b046c8a9a28..1be57b68f9db2 100644 --- a/Geometry/HGCalCommonData/src/HGCalDDDConstants.cc +++ b/Geometry/HGCalCommonData/src/HGCalDDDConstants.cc @@ -1557,9 +1557,11 @@ bool HGCalDDDConstants::tileExist(int zside, int layer, int ring, int phi) const const auto& index = getIndex(layer, true); bool fine = hgpar_->scintFine(index.first); #ifdef EDM_ML_DEBUG - edm::LogVerbatim("HGCalGeomT") << "TileExist: Layer : " << layer << ":" << index.first << " Fine " << fine << " index " << index.first << " :" << index.second; + edm::LogVerbatim("HGCalGeomT") << "TileExist: Layer : " << layer << ":" << index.first << " Fine " << fine + << " index " << index.first << " :" << index.second; #endif - bool ok = (fine) ? ((ring >= hgpar_->iradMinBHFine_[index.first]) && (ring <= hgpar_->iradMaxBHFine_[index.first])): ((ring >= hgpar_->iradMinBH_[index.first]) && (ring <= hgpar_->iradMaxBH_[index.first])); + bool ok = (fine) ? ((ring >= hgpar_->iradMinBHFine_[index.first]) && (ring <= hgpar_->iradMaxBHFine_[index.first])) + : ((ring >= hgpar_->iradMinBH_[index.first]) && (ring <= hgpar_->iradMaxBH_[index.first])); if (ok) { if (fine) { int indx = HGCalTileIndex::tileIndex(layer, ring, 1); @@ -1607,7 +1609,7 @@ bool HGCalDDDConstants::tileExist(int zside, int layer, int ring, int phi) const else st1 << hgpar_->iradMinBH_[index.first] << ":" << hgpar_->iradMaxBH_[index.first]; edm::LogWarning("HGCalGeomT") << "TileExist:input " << zside << ":" << layer << ":" << ring << ":" << phi - << " Index " << index.first << " Ring limits " << st1.str() << " ok " << ok; + << " Index " << index.first << " Ring limits " << st1.str() << " ok " << ok; #endif } return ok; diff --git a/Geometry/HGCalCommonData/src/HGCalGeomParameters.cc b/Geometry/HGCalCommonData/src/HGCalGeomParameters.cc index ff3e54e014fc0..26584cdadbd95 100644 --- a/Geometry/HGCalCommonData/src/HGCalGeomParameters.cc +++ b/Geometry/HGCalCommonData/src/HGCalGeomParameters.cc @@ -2571,7 +2571,8 @@ void HGCalGeomParameters::loadCellTrapezoid(HGCalParameters& php) { double rmin = php.radiusLayer_[kk][std::max((irmin - 1), 0)]; double rmax = php.radiusLayer_[kk][std::min(irmax, irm)]; edm::LogVerbatim("HGCalGeom") << "Layer " << php.firstLayer_ + k << ":" << kk << " Radius range " << irmin << ":" - << irmax << ":" << rmin << ":" << rmax << " Size " << php.radiusLayer_[kk].size() << " nphi " << php.nPhiLayer_[k] ; + << irmax << ":" << rmin << ":" << rmax << " Size " << php.radiusLayer_[kk].size() + << " nphi " << php.nPhiLayer_[k]; #endif mytr.lay = php.firstLayer_ + k; for (int irad = irmin; irad <= irmax; ++irad) { diff --git a/Geometry/HGCalGeometry/src/HGCalGeometryLoader.cc b/Geometry/HGCalGeometry/src/HGCalGeometryLoader.cc index 9117e77710497..16fb1b98c7d46 100644 --- a/Geometry/HGCalGeometry/src/HGCalGeometryLoader.cc +++ b/Geometry/HGCalGeometry/src/HGCalGeometryLoader.cc @@ -92,8 +92,10 @@ HGCalGeometry* HGCalGeometryLoader::build(const HGCalTopology& topology) { int nphi = topology.dddConstants().getParameter()->scintCells(layer); int type = topology.dddConstants().getParameter()->scintType(layer); #ifdef EDM_ML_DEBUG - edm::LogVerbatim("HGCalGeom") << "Trap::Layer " << layer << ":" << indx << " Ring " << ring << ":" - << rings.second << " Phi " << nphi << " Type " << type << " Modules " << topology.dddConstants().getParameter()->firstModule_[indx] << ":" << topology.dddConstants().getParameter()->lastModule_[indx]; + edm::LogVerbatim("HGCalGeom") << "Trap::Layer " << layer << ":" << indx << " Ring " << ring << ":" << rings.second + << " Phi " << nphi << " Type " << type << " Modules " + << topology.dddConstants().getParameter()->firstModule_[indx] << ":" + << topology.dddConstants().getParameter()->lastModule_[indx]; #endif for (int md = topology.dddConstants().getParameter()->firstModule_[indx]; md <= topology.dddConstants().getParameter()->lastModule_[indx]; From 367d7da61288e2041267360dfd3c9196bf2f8708 Mon Sep 17 00:00:00 2001 From: Andrea Bocci Date: Thu, 30 Apr 2026 17:40:59 +0200 Subject: [PATCH 59/61] Include the ProcessAcceleratorAlpaka configuration in the python dumps --- .../python/ProcessAcceleratorAlpaka.py | 15 ++++-- .../AlpakaCore/test/BuildFile.xml | 8 +++ .../test/testProcessAcceleratorAlpaka.py | 52 +++++++++++++++++++ 3 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 HeterogeneousCore/AlpakaCore/test/testProcessAcceleratorAlpaka.py diff --git a/HeterogeneousCore/AlpakaCore/python/ProcessAcceleratorAlpaka.py b/HeterogeneousCore/AlpakaCore/python/ProcessAcceleratorAlpaka.py index cadb4ccf6e8fb..414a614523aa5 100644 --- a/HeterogeneousCore/AlpakaCore/python/ProcessAcceleratorAlpaka.py +++ b/HeterogeneousCore/AlpakaCore/python/ProcessAcceleratorAlpaka.py @@ -62,10 +62,10 @@ class ProcessAcceleratorAlpaka(cms.ProcessAccelerator): accelerators that the concrete ProcessAccelerators (like ProcessAcceleratorCUDA) define. """ - def __init__(self): + def __init__(self, backend = None, synchronize = False): super(ProcessAcceleratorAlpaka, self).__init__() - self._backend = None - self._synchronize = False + self._backend = backend + self._synchronize = synchronize # User-facing interface def setBackend(self, backend): @@ -74,6 +74,15 @@ def setBackend(self, backend): def setSynchronize(self, synchronize): self._synchronize = synchronize + # Include the ProcessAcceleratorAlpaka configuration in the python dumps + def dumpPythonImpl(self, options) -> str: + args = [] + if self._backend is not None: + args.append(options.indentation() + f"backend = '{self._backend}'") + if self._synchronize != False: + args.append(options.indentation() + f"synchronize = {self._synchronize}") + return ',\n'.join(args) + # Framework-facing interface def moduleTypeResolver(self, accelerators): return ModuleTypeResolverAlpaka(accelerators, self._backend, self._synchronize) diff --git a/HeterogeneousCore/AlpakaCore/test/BuildFile.xml b/HeterogeneousCore/AlpakaCore/test/BuildFile.xml index 558bb3abae1f6..899ed8c9cef8e 100644 --- a/HeterogeneousCore/AlpakaCore/test/BuildFile.xml +++ b/HeterogeneousCore/AlpakaCore/test/BuildFile.xml @@ -2,6 +2,14 @@ + + + + + + + + diff --git a/HeterogeneousCore/AlpakaCore/test/testProcessAcceleratorAlpaka.py b/HeterogeneousCore/AlpakaCore/test/testProcessAcceleratorAlpaka.py new file mode 100644 index 0000000000000..a09f247744010 --- /dev/null +++ b/HeterogeneousCore/AlpakaCore/test/testProcessAcceleratorAlpaka.py @@ -0,0 +1,52 @@ +import os +import sys + +# choose a different alpaka backend depending on the SCRAM test being run +try: + backend = os.environ['SCRAM_ALPAKA_BACKEND'] +except: + backend = 'SerialSync' + +# map the alpaka backends to the process accelerators +accelerators = { + 'SerialSync': 'cpu', + 'CudaAsync': 'gpu-nvidia', + 'ROCmAsync': 'gpu-amd' +} + +# map the alpaka backends to the names used by the ProcessAcceleratorAlpaka +backends = { + 'SerialSync': 'serial_sync', + 'CudaAsync': 'cuda_async', + 'ROCmAsync': 'rocm_async' +} + +print(f"Testing the alpaka backend {backend} using the process accelerator {accelerators[backend]}", file=sys.stderr) + +import FWCore.ParameterSet.Config as cms +from HeterogeneousCore.AlpakaCore.functions import * + +process = cms.Process('Test') + +process.maxEvents.input = 10 + +process.source = cms.Source('EmptySource') + +process.load('Configuration.StandardSequences.Accelerators_cff') +process.load('HeterogeneousCore.AlpakaCore.ProcessAcceleratorAlpaka_cfi') +process.ProcessAcceleratorAlpaka.setBackend(backends[backend]) + +process.alpakaBackendProducer = cms.EDProducer('AlpakaBackendProducer@alpaka') + +process.alpakaBackendFilter = cms.EDFilter('AlpakaBackendFilter', + producer = cms.InputTag('alpakaBackendProducer', 'backend'), + backends = cms.vstring(backend) +) + +process.mustRun = cms.EDProducer("edmtest::MustRunIntProducer", ivalue=cms.int32(1)) +process.mustNotRun = cms.EDProducer("FailingProducer") + +process.SelectedBackend = cms.Path(process.alpakaBackendProducer + process.alpakaBackendFilter + process.mustRun) +process.AnyOtherBackend = cms.Path(process.alpakaBackendProducer + ~process.alpakaBackendFilter + process.mustNotRun) + +process.options.wantSummary = True From 595f18dd275fed3b415fff31b8316e70a1120700 Mon Sep 17 00:00:00 2001 From: Felice Pantaleo Date: Sat, 25 Apr 2026 12:32:30 +0200 Subject: [PATCH 60/61] LC To Sim associators --- .../plugins/BuildFile.xml | 15 +- ...terCaloParticleAssociatorByHitsProducer.cc | 797 ++++++++++++++++++ 2 files changed, 808 insertions(+), 4 deletions(-) create mode 100644 SimCalorimetry/HGCalAssociatorProducers/plugins/LayerClusterToSimClusterCaloParticleAssociatorByHitsProducer.cc diff --git a/SimCalorimetry/HGCalAssociatorProducers/plugins/BuildFile.xml b/SimCalorimetry/HGCalAssociatorProducers/plugins/BuildFile.xml index 2d57a74056b6b..e7c417bb83019 100644 --- a/SimCalorimetry/HGCalAssociatorProducers/plugins/BuildFile.xml +++ b/SimCalorimetry/HGCalAssociatorProducers/plugins/BuildFile.xml @@ -1,11 +1,18 @@ + + + + + + + + + + - - - - + diff --git a/SimCalorimetry/HGCalAssociatorProducers/plugins/LayerClusterToSimClusterCaloParticleAssociatorByHitsProducer.cc b/SimCalorimetry/HGCalAssociatorProducers/plugins/LayerClusterToSimClusterCaloParticleAssociatorByHitsProducer.cc new file mode 100644 index 0000000000000..6baa8ed0f172d --- /dev/null +++ b/SimCalorimetry/HGCalAssociatorProducers/plugins/LayerClusterToSimClusterCaloParticleAssociatorByHitsProducer.cc @@ -0,0 +1,797 @@ +// Author: Felice Pantaleo, felice.pantaleo@cern.ch 03/2026 + +#include +#include +#include +#include +#include +#include +#include + +#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "FWCore/Utilities/interface/EDGetToken.h" + +#include "DataFormats/Common/interface/MultiSpan.h" +#include "DataFormats/Common/interface/RefProdVector.h" +#include "DataFormats/CaloRecHit/interface/CaloCluster.h" +#include "DataFormats/HGCRecHit/interface/HGCRecHitCollections.h" +#include "DataFormats/ParticleFlowReco/interface/PFCluster.h" +#include "DataFormats/ParticleFlowReco/interface/PFClusterFwd.h" +#include "DataFormats/ParticleFlowReco/interface/PFRecHit.h" +#include "DataFormats/ParticleFlowReco/interface/PFRecHitFwd.h" + +#include "Geometry/CaloGeometry/interface/CaloGeometry.h" +#include "Geometry/Records/interface/CaloGeometryRecord.h" + +#include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" + +#include "SimDataFormats/Associations/interface/TICLAssociationMap.h" +#include "SimDataFormats/CaloAnalysis/interface/CaloParticle.h" +#include "SimDataFormats/CaloAnalysis/interface/SimCluster.h" + +namespace { + + using DetIdRecHitMap = std::unordered_map; + + // Traits used to select the correct rechit container and default products + // from RecHitMapProducer for each hit type. + template + struct HitCollectionTraits; + + template <> + struct HitCollectionTraits { + using Collection = HGCRecHitCollection; + using MultiCollection = edm::RefProdVector; + + static constexpr const char* defaultHitMapInstance = "hgcalRecHitMap"; + static constexpr const char* defaultHitsInstance = "RefProdVectorHGCRecHitCollection"; + }; + + template <> + struct HitCollectionTraits { + using Collection = reco::PFRecHitCollection; + using MultiCollection = edm::RefProdVector; + + static constexpr const char* defaultHitMapInstance = "pfRecHitMap"; + static constexpr const char* defaultHitsInstance = "RefProdVectorPFRecHitCollection"; + }; + + // Compact representation of a rechit contribution to a reconstructed cluster. + // The hit index is the index in the MultiSpan. + struct HitContribution { + DetId detId; + unsigned int hitIndex = 0; + float fraction = 0.f; + float energy = 0.f; + }; + + // Temporary representation of the part of a SimCluster or CaloParticle + // restricted to one detector layer. + // + // fractionByDetId is used for fast lookup when computing reco -> sim scores. + // hitsAndFractions is used when looping over the sim object itself for + // sim -> reco scores. + struct ObjectOnLayer { + std::vector> hitsAndFractions; + std::unordered_map fractionByDetId; + float denominator = 0.f; + + void add(DetId detId, float fraction) { fractionByDetId[detId] += fraction; } + + template + void finalize(const DetIdRecHitMap& hitMap, const edm::MultiSpan& hits) { + hitsAndFractions.reserve(fractionByDetId.size()); + + for (const auto& [detId, fraction] : fractionByDetId) { + const auto hitIt = hitMap.find(detId); + if (hitIt == hitMap.end()) { + continue; + } + + const float energy = hits[hitIt->second].energy(); + denominator += fraction * fraction * energy * energy; + hitsAndFractions.emplace_back(detId, fraction); + } + } + + float fraction(DetId detId) const { + const auto it = fractionByDetId.find(detId); + return it == fractionByDetId.end() ? 0.f : it->second; + } + + bool empty() const { return hitsAndFractions.empty(); } + }; + + // Scores are distances, therefore smaller is better. If two scores are equal, + // prefer the association with larger shared energy. + template + void sortByIncreasingScoreThenDecreasingSharedEnergy(Map& map) { + map.sort([](const auto& a, const auto& b) { + if (a.score() != b.score()) { + return a.score() < b.score(); + } + if (a.sharedEnergy() != b.sharedEnergy()) { + return a.sharedEnergy() > b.sharedEnergy(); + } + return a.index() < b.index(); + }); + } + +} // namespace + +template +class LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT : public edm::global::EDProducer<> { +public: + using MultiCollection = typename HitCollectionTraits::MultiCollection; + + using SimClusterCollection = std::vector; + using CaloParticleCollection = std::vector; + + using LCToSCMap = ticl::AssociationMap; + using SCToLCMap = ticl::AssociationMap; + using LCToCPMap = ticl::AssociationMap; + using CPToLCMap = ticl::AssociationMap; + + explicit LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT(const edm::ParameterSet&); + ~LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT() override = default; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; + + // Returns a layer index. For HGCAL, the z-side is folded into the index, + // so the same layer number on +z and -z is kept distinct. + unsigned int layerIndex(DetId detId, const hgcal::RecHitTools& recHitTools, unsigned int layers) const; + + // Selects only the hits relevant for the current HIT type. + bool acceptSimHit(DetId detId, const hgcal::RecHitTools& recHitTools) const; + + bool passHardScatter(const SimCluster& simCluster) const; + + // Extracts the rechits of a reconstructed cluster and decorates them with + // their MultiSpan index and rechit energy. + std::vector layerClusterHits(const typename CLUSTER::value_type& layerCluster, + const DetIdRecHitMap& hitMap, + const edm::MultiSpan& hits) const; + + // Denominator for the reco -> sim directional score: + // sum_i (recoFraction_i * E_i)^2. + float layerClusterDenominator(const std::vector& hits) const; + + // Build SimCluster-on-layer objects. These are needed because a LayerCluster + // lives on a single layer and should not be compared to the full SimCluster. + std::vector> buildSimClustersOnLayer(const SimClusterCollection& simClusters, + const DetIdRecHitMap& hitMap, + const edm::MultiSpan& hits, + const hgcal::RecHitTools& recHitTools, + unsigned int layers, + unsigned int nLayers) const; + + // Build CaloParticle-on-layer objects by aggregating the fractions of all + // SimClusters belonging to the same CaloParticle on each DetId. + std::vector> buildCaloParticlesOnLayer(const CaloParticleCollection& caloParticles, + const DetIdRecHitMap& hitMap, + const edm::MultiSpan& hits, + const hgcal::RecHitTools& recHitTools, + unsigned int layers, + unsigned int nLayers) const; + + void putEmptyProducts(edm::Event& iEvent) const; + + edm::EDGetTokenT layerClustersToken_; + edm::EDGetTokenT simClustersToken_; + edm::EDGetTokenT caloParticlesToken_; + + edm::EDGetTokenT hitMapToken_; + edm::EDGetTokenT hitsToken_; + + edm::EDGetTokenT> hitToLayerClusterMapToken_; + edm::EDGetTokenT> hitToSimClusterMapToken_; + edm::EDGetTokenT> hitToCaloParticleMapToken_; + + edm::ESGetToken caloGeometryToken_; + + bool hardScatterOnly_; +}; + +template +LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT< + HIT, + CLUSTER>::LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT(const edm::ParameterSet& pset) + : layerClustersToken_(consumes(pset.getParameter("layerClusters"))), + simClustersToken_(consumes(pset.getParameter("simClusters"))), + caloParticlesToken_(consumes(pset.getParameter("caloParticles"))), + hitMapToken_(consumes(pset.getParameter("hitMap"))), + hitsToken_(consumes(pset.getParameter("hits"))), + hitToLayerClusterMapToken_(consumes>( + pset.getParameter("hitToLayerClusterMap"))), + hitToSimClusterMapToken_(consumes>( + pset.getParameter("hitToSimClusterMap"))), + hitToCaloParticleMapToken_(consumes>( + pset.getParameter("hitToCaloParticleMap"))), + caloGeometryToken_(esConsumes()), + hardScatterOnly_(pset.getParameter("hardScatterOnly")) { + produces("layerClusterToSimClusterMap"); + produces("simClusterToLayerClusterMap"); + produces("layerClusterToCaloParticleMap"); + produces("caloParticleToLayerClusterMap"); +} + +template +unsigned int LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT::layerIndex( + DetId detId, + const hgcal::RecHitTools& recHitTools, + unsigned int layers) const { + unsigned int layer = recHitTools.getLayer(detId); + + if constexpr (std::is_same_v) { + layer += layers * ((recHitTools.zside(detId) + 1) >> 1) - 1; + } + + return layer; +} + +template +bool LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT::acceptSimHit( + DetId detId, + const hgcal::RecHitTools& recHitTools) const { + if constexpr (std::is_same_v) { + return !recHitTools.isBarrel(detId); + } else { + return recHitTools.isBarrel(detId); + } +} + +template +bool LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT::passHardScatter( + const SimCluster& simCluster) const { + if (!hardScatterOnly_) { + return true; + } + + if (simCluster.g4Tracks().empty()) { + return false; + } + + const auto& eventId = simCluster.g4Tracks()[0].eventId(); + return eventId.event() == 0 && eventId.bunchCrossing() == 0; +} + +template +std::vector +LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT::layerClusterHits( + const typename CLUSTER::value_type& layerCluster, + const DetIdRecHitMap& hitMap, + const edm::MultiSpan& hits) const { + std::vector result; + const auto& hitsAndFractions = layerCluster.hitsAndFractions(); + result.reserve(hitsAndFractions.size()); + + for (const auto& [detId, fraction] : hitsAndFractions) { + const auto hitIt = hitMap.find(detId); + if (hitIt == hitMap.end()) { + continue; + } + + const unsigned int hitIndex = hitIt->second; + result.push_back({detId, hitIndex, fraction, hits[hitIndex].energy()}); + } + + return result; +} + +template +float LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT::layerClusterDenominator( + const std::vector& hits) const { + float denominator = 0.f; + + for (const auto& hit : hits) { + denominator += hit.fraction * hit.fraction * hit.energy * hit.energy; + } + + return denominator; +} + +template +std::vector> +LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT::buildSimClustersOnLayer( + const SimClusterCollection& simClusters, + const DetIdRecHitMap& hitMap, + const edm::MultiSpan& hits, + const hgcal::RecHitTools& recHitTools, + unsigned int layers, + unsigned int nLayers) const { + std::vector> simClustersOnLayer(simClusters.size(), + std::vector(nLayers)); + + for (unsigned int scId = 0; scId < simClusters.size(); ++scId) { + const auto& simCluster = simClusters[scId]; + + if (!passHardScatter(simCluster)) { + continue; + } + + for (const auto& [detIdRaw, fraction] : simCluster.hits_and_fractions()) { + const DetId detId(detIdRaw); + + // Keep only hits compatible with the hit type used by this producer. + if (!acceptSimHit(detId, recHitTools)) { + continue; + } + + // Ignore simulated hits that do not correspond to a reconstructed hit. + if (hitMap.find(detId) == hitMap.end()) { + continue; + } + + const unsigned int layer = layerIndex(detId, recHitTools, layers); + if (layer >= nLayers) { + continue; + } + + simClustersOnLayer[scId][layer].add(detId, fraction); + } + } + + // Build the vector view and compute the score denominator for each layer. + for (auto& objectLayers : simClustersOnLayer) { + for (auto& objectOnLayer : objectLayers) { + objectOnLayer.finalize(hitMap, hits); + } + } + + return simClustersOnLayer; +} + +template +std::vector> +LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT::buildCaloParticlesOnLayer( + const CaloParticleCollection& caloParticles, + const DetIdRecHitMap& hitMap, + const edm::MultiSpan& hits, + const hgcal::RecHitTools& recHitTools, + unsigned int layers, + unsigned int nLayers) const { + std::vector> caloParticlesOnLayer(caloParticles.size(), + std::vector(nLayers)); + + for (unsigned int cpId = 0; cpId < caloParticles.size(); ++cpId) { + const auto& caloParticle = caloParticles[cpId]; + + for (const auto& simClusterRef : caloParticle.simClusters()) { + const auto& simCluster = *simClusterRef; + + if (!passHardScatter(simCluster)) { + continue; + } + + for (const auto& [detIdRaw, fraction] : simCluster.hits_and_fractions()) { + const DetId detId(detIdRaw); + + if (!acceptSimHit(detId, recHitTools)) { + continue; + } + + if (hitMap.find(detId) == hitMap.end()) { + continue; + } + + const unsigned int layer = layerIndex(detId, recHitTools, layers); + if (layer >= nLayers) { + continue; + } + + // Fractions from different SimClusters of the same CaloParticle are + // aggregated per DetId before computing the CP score. + caloParticlesOnLayer[cpId][layer].add(detId, fraction); + } + } + } + + for (auto& objectLayers : caloParticlesOnLayer) { + for (auto& objectOnLayer : objectLayers) { + objectOnLayer.finalize(hitMap, hits); + } + } + + return caloParticlesOnLayer; +} + +template +void LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT::putEmptyProducts( + edm::Event& iEvent) const { + iEvent.put(std::make_unique(), "layerClusterToSimClusterMap"); + iEvent.put(std::make_unique(), "simClusterToLayerClusterMap"); + iEvent.put(std::make_unique(), "layerClusterToCaloParticleMap"); + iEvent.put(std::make_unique(), "caloParticleToLayerClusterMap"); +} + +template +void LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT::produce( + edm::StreamID, + edm::Event& iEvent, + const edm::EventSetup& iSetup) const { + auto layerClustersHandle = iEvent.getHandle(layerClustersToken_); + auto simClustersHandle = iEvent.getHandle(simClustersToken_); + auto caloParticlesHandle = iEvent.getHandle(caloParticlesToken_); + auto hitMapHandle = iEvent.getHandle(hitMapToken_); + auto hitsHandle = iEvent.getHandle(hitsToken_); + auto hitToLayerClusterMapHandle = iEvent.getHandle(hitToLayerClusterMapToken_); + auto hitToSimClusterMapHandle = iEvent.getHandle(hitToSimClusterMapToken_); + auto hitToCaloParticleMapHandle = iEvent.getHandle(hitToCaloParticleMapToken_); + + if (!layerClustersHandle.isValid() || !simClustersHandle.isValid() || !caloParticlesHandle.isValid() || + !hitMapHandle.isValid() || !hitsHandle.isValid() || !hitToLayerClusterMapHandle.isValid() || + !hitToSimClusterMapHandle.isValid() || !hitToCaloParticleMapHandle.isValid()) { + edm::LogWarning("LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT") + << "Missing input collection. Producing empty association maps."; + putEmptyProducts(iEvent); + return; + } + + const auto& layerClusters = *layerClustersHandle; + const auto& simClusters = *simClustersHandle; + const auto& caloParticles = *caloParticlesHandle; + const auto& hitMap = *hitMapHandle; + const auto& hitToLayerClusterMap = *hitToLayerClusterMapHandle; + const auto& hitToSimClusterMap = *hitToSimClusterMapHandle; + const auto& hitToCaloParticleMap = *hitToCaloParticleMapHandle; + + const auto hitsCollections = iEvent.get(hitsToken_); + edm::MultiSpan rechitSpan(hitsCollections); + + if (rechitSpan.size() == 0 || hitMap.empty()) { + edm::LogWarning("LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT") + << "No valid rechits or empty hit map. Producing empty association maps."; + putEmptyProducts(iEvent); + return; + } + + hgcal::RecHitTools recHitTools; + const auto& geometry = iSetup.getData(caloGeometryToken_); + recHitTools.setGeometry(geometry); + + unsigned int layers = 0; + if constexpr (std::is_same_v) { + layers = recHitTools.lastLayerBH(); + } else { + layers = recHitTools.lastLayerBarrel() + 1; + } + + const unsigned int nLayers = std::is_same_v ? 2 * layers : layers; + + // Precompute the sim truth restricted layer-by-layer. This avoids comparing + // a single-layer reco object with the full longitudinal extent of the truth object. + const auto simClustersOnLayer = + buildSimClustersOnLayer(simClusters, hitMap, rechitSpan, recHitTools, layers, nLayers); + const auto caloParticlesOnLayer = + buildCaloParticlesOnLayer(caloParticles, hitMap, rechitSpan, recHitTools, layers, nLayers); + + auto layerClusterToSimClusterMap = std::make_unique(layerClustersHandle, simClustersHandle, iEvent); + auto simClusterToLayerClusterMap = std::make_unique(simClustersHandle, layerClustersHandle, iEvent); + auto layerClusterToCaloParticleMap = std::make_unique(layerClustersHandle, caloParticlesHandle, iEvent); + auto caloParticleToLayerClusterMap = std::make_unique(caloParticlesHandle, layerClustersHandle, iEvent); + + // Reco -> sim associations. + // + // For each LayerCluster, find candidate SimClusters and CaloParticles through + // the hit -> sim maps, then compute a directional score: + // + // score = sum_i max(0, recoFraction_i - simFraction_i)^2 * E_i^2 + // / sum_i (recoFraction_i * E_i)^2 + // + // This penalizes the part of the reco object that is not covered by the sim object. + for (unsigned int lcId = 0; lcId < layerClusters.size(); ++lcId) { + const auto lcHits = layerClusterHits(layerClusters[lcId], hitMap, rechitSpan); + + if (lcHits.empty()) { + continue; + } + + const unsigned int lcLayer = layerIndex(lcHits.front().detId, recHitTools, layers); + if (lcLayer >= nLayers) { + continue; + } + + const float denominator = layerClusterDenominator(lcHits); + if (denominator <= 0.f) { + continue; + } + + const float invDenominator = 1.f / denominator; + + std::vector associatedSimClusters; + std::vector associatedCaloParticles; + + // Candidate truth objects are those sharing at least one rechit with the LayerCluster. + for (const auto& hit : lcHits) { + if (hit.hitIndex < hitToSimClusterMap.size()) { + for (const auto& simElement : hitToSimClusterMap[hit.hitIndex]) { + associatedSimClusters.push_back(simElement.index()); + } + } + + if (hit.hitIndex < hitToCaloParticleMap.size()) { + for (const auto& cpElement : hitToCaloParticleMap[hit.hitIndex]) { + associatedCaloParticles.push_back(cpElement.index()); + } + } + } + + std::sort(associatedSimClusters.begin(), associatedSimClusters.end()); + associatedSimClusters.erase(std::unique(associatedSimClusters.begin(), associatedSimClusters.end()), + associatedSimClusters.end()); + + std::sort(associatedCaloParticles.begin(), associatedCaloParticles.end()); + associatedCaloParticles.erase(std::unique(associatedCaloParticles.begin(), associatedCaloParticles.end()), + associatedCaloParticles.end()); + + edm::Ref lcRef(layerClustersHandle, lcId); + + for (const unsigned int scId : associatedSimClusters) { + if (scId >= simClustersOnLayer.size()) { + continue; + } + + const auto& simObject = simClustersOnLayer[scId][lcLayer]; + if (simObject.empty()) { + continue; + } + + edm::Ref scRef(simClustersHandle, scId); + + for (const auto& hit : lcHits) { + const float recoFraction = hit.fraction; + const float simFraction = simObject.fraction(hit.detId); + + const float sharedEnergy = std::min(recoFraction, simFraction) * hit.energy; + const float missingRecoFraction = std::max(0.f, recoFraction - simFraction); + const float score = invDenominator * missingRecoFraction * missingRecoFraction * hit.energy * hit.energy; + + // AssociationMap accumulates shared energy and score contributions + // for repeated insertions of the same pair. + layerClusterToSimClusterMap->insert(lcRef, scRef, sharedEnergy, score); + } + } + + for (const unsigned int cpId : associatedCaloParticles) { + if (cpId >= caloParticlesOnLayer.size()) { + continue; + } + + const auto& simObject = caloParticlesOnLayer[cpId][lcLayer]; + if (simObject.empty()) { + continue; + } + + edm::Ref cpRef(caloParticlesHandle, cpId); + + for (const auto& hit : lcHits) { + const float recoFraction = hit.fraction; + const float simFraction = simObject.fraction(hit.detId); + + const float sharedEnergy = std::min(recoFraction, simFraction) * hit.energy; + const float missingRecoFraction = std::max(0.f, recoFraction - simFraction); + const float score = invDenominator * missingRecoFraction * missingRecoFraction * hit.energy * hit.energy; + + layerClusterToCaloParticleMap->insert(lcRef, cpRef, sharedEnergy, score); + } + } + } + + // SimCluster -> reco associations. + // + // The denominator is computed from the SimCluster restricted to the layer. + // The score penalizes the part of the sim object that is not covered by the reco object. + for (unsigned int scId = 0; scId < simClustersOnLayer.size(); ++scId) { + edm::Ref scRef(simClustersHandle, scId); + + for (unsigned int layer = 0; layer < simClustersOnLayer[scId].size(); ++layer) { + const auto& simObject = simClustersOnLayer[scId][layer]; + + if (simObject.empty() || simObject.denominator <= 0.f) { + continue; + } + + const float invDenominator = 1.f / simObject.denominator; + + std::vector associatedLayerClusters; + + // Candidate LayerClusters are found through hit -> LayerCluster associations. + for (const auto& [detId, simFraction] : simObject.hitsAndFractions) { + const auto hitIt = hitMap.find(detId); + if (hitIt == hitMap.end()) { + continue; + } + + const unsigned int hitIndex = hitIt->second; + if (hitIndex >= hitToLayerClusterMap.size()) { + continue; + } + + for (const auto& lcElement : hitToLayerClusterMap[hitIndex]) { + associatedLayerClusters.push_back(lcElement.index()); + } + } + + std::sort(associatedLayerClusters.begin(), associatedLayerClusters.end()); + associatedLayerClusters.erase(std::unique(associatedLayerClusters.begin(), associatedLayerClusters.end()), + associatedLayerClusters.end()); + + for (const unsigned int lcId : associatedLayerClusters) { + if (lcId >= layerClusters.size()) { + continue; + } + + edm::Ref lcRef(layerClustersHandle, lcId); + + for (const auto& [detId, simFraction] : simObject.hitsAndFractions) { + const auto hitIt = hitMap.find(detId); + if (hitIt == hitMap.end()) { + continue; + } + + const unsigned int hitIndex = hitIt->second; + const float energy = rechitSpan[hitIndex].energy(); + + float recoFraction = 0.f; + if (hitIndex < hitToLayerClusterMap.size()) { + const auto& hitToLCVec = hitToLayerClusterMap[hitIndex]; + const auto lcIt = std::find_if(hitToLCVec.begin(), hitToLCVec.end(), [lcId](const auto& element) { + return element.index() == lcId; + }); + + if (lcIt != hitToLCVec.end()) { + recoFraction = lcIt->fraction(); + } + } + + const float sharedEnergy = std::min(recoFraction, simFraction) * energy; + const float missingSimFraction = std::max(0.f, simFraction - recoFraction); + const float score = invDenominator * missingSimFraction * missingSimFraction * energy * energy; + + simClusterToLayerClusterMap->insert(scRef, lcRef, sharedEnergy, score); + } + } + } + } + + // CaloParticle -> reco associations. + // + // Same directional score as SimCluster -> reco, but using the CaloParticle + // fractions aggregated on each DetId and layer. + for (unsigned int cpId = 0; cpId < caloParticlesOnLayer.size(); ++cpId) { + edm::Ref cpRef(caloParticlesHandle, cpId); + + for (unsigned int layer = 0; layer < caloParticlesOnLayer[cpId].size(); ++layer) { + const auto& simObject = caloParticlesOnLayer[cpId][layer]; + + if (simObject.empty() || simObject.denominator <= 0.f) { + continue; + } + + const float invDenominator = 1.f / simObject.denominator; + + std::vector associatedLayerClusters; + + for (const auto& [detId, simFraction] : simObject.hitsAndFractions) { + const auto hitIt = hitMap.find(detId); + if (hitIt == hitMap.end()) { + continue; + } + + const unsigned int hitIndex = hitIt->second; + if (hitIndex >= hitToLayerClusterMap.size()) { + continue; + } + + for (const auto& lcElement : hitToLayerClusterMap[hitIndex]) { + associatedLayerClusters.push_back(lcElement.index()); + } + } + + std::sort(associatedLayerClusters.begin(), associatedLayerClusters.end()); + associatedLayerClusters.erase(std::unique(associatedLayerClusters.begin(), associatedLayerClusters.end()), + associatedLayerClusters.end()); + + for (const unsigned int lcId : associatedLayerClusters) { + if (lcId >= layerClusters.size()) { + continue; + } + + edm::Ref lcRef(layerClustersHandle, lcId); + + for (const auto& [detId, simFraction] : simObject.hitsAndFractions) { + const auto hitIt = hitMap.find(detId); + if (hitIt == hitMap.end()) { + continue; + } + + const unsigned int hitIndex = hitIt->second; + const float energy = rechitSpan[hitIndex].energy(); + + float recoFraction = 0.f; + if (hitIndex < hitToLayerClusterMap.size()) { + const auto& hitToLCVec = hitToLayerClusterMap[hitIndex]; + const auto lcIt = std::find_if(hitToLCVec.begin(), hitToLCVec.end(), [lcId](const auto& element) { + return element.index() == lcId; + }); + + if (lcIt != hitToLCVec.end()) { + recoFraction = lcIt->fraction(); + } + } + + const float sharedEnergy = std::min(recoFraction, simFraction) * energy; + const float missingSimFraction = std::max(0.f, simFraction - recoFraction); + const float score = invDenominator * missingSimFraction * missingSimFraction * energy * energy; + + caloParticleToLayerClusterMap->insert(cpRef, lcRef, sharedEnergy, score); + } + } + } + } + + sortByIncreasingScoreThenDecreasingSharedEnergy(*layerClusterToSimClusterMap); + sortByIncreasingScoreThenDecreasingSharedEnergy(*simClusterToLayerClusterMap); + sortByIncreasingScoreThenDecreasingSharedEnergy(*layerClusterToCaloParticleMap); + sortByIncreasingScoreThenDecreasingSharedEnergy(*caloParticleToLayerClusterMap); + + iEvent.put(std::move(layerClusterToSimClusterMap), "layerClusterToSimClusterMap"); + iEvent.put(std::move(simClusterToLayerClusterMap), "simClusterToLayerClusterMap"); + iEvent.put(std::move(layerClusterToCaloParticleMap), "layerClusterToCaloParticleMap"); + iEvent.put(std::move(caloParticleToLayerClusterMap), "caloParticleToLayerClusterMap"); +} + +template +void LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT::fillDescriptions( + edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + + desc.add("hardScatterOnly", true); + + desc.add("simClusters", edm::InputTag("mix", "MergedCaloTruth")); + desc.add("caloParticles", edm::InputTag("mix", "MergedCaloTruth")); + + desc.add( + "hitMap", + edm::InputTag("recHitMapProducer", HitCollectionTraits::defaultHitMapInstance)); + + desc.add( + "hits", + edm::InputTag("recHitMapProducer", HitCollectionTraits::defaultHitsInstance)); + + desc.add("hitToSimClusterMap", + edm::InputTag("hitToSimClusterCaloParticleAssociator", "hitToSimClusterMap")); + desc.add("hitToCaloParticleMap", + edm::InputTag("hitToSimClusterCaloParticleAssociator", "hitToCaloParticleMap")); + + if constexpr (std::is_same_v) { + desc.add("layerClusters", edm::InputTag("hgcalMergeLayerClusters")); + desc.add("hitToLayerClusterMap", + edm::InputTag("hitToLayerClusterAssociator", "hitToLayerClusterMap")); + } else { + desc.add("layerClusters", edm::InputTag("particleFlowClusterHGCal")); + desc.add("hitToLayerClusterMap", + edm::InputTag("hitToPFClusterAssociator", "hitToLayerClusterMap")); + } + + descriptions.addWithDefaultLabel(desc); +} + +using HGCRecHitCaloClusterToSimClusterCaloParticleAssociatorByHitsProducer = + LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT; + +using HGCRecHitPFClusterToSimClusterCaloParticleAssociatorByHitsProducer = + LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT; + +DEFINE_FWK_MODULE(HGCRecHitCaloClusterToSimClusterCaloParticleAssociatorByHitsProducer); +DEFINE_FWK_MODULE(HGCRecHitPFClusterToSimClusterCaloParticleAssociatorByHitsProducer); \ No newline at end of file From 76c365a261205aa21f857053fa3d72714df0c306 Mon Sep 17 00:00:00 2001 From: Felice Pantaleo Date: Thu, 7 May 2026 16:14:16 +0200 Subject: [PATCH 61/61] code format and rebase to 17_0_0_pre1 --- ...terCaloParticleAssociatorByHitsProducer.cc | 43 +++++++------------ 1 file changed, 15 insertions(+), 28 deletions(-) diff --git a/SimCalorimetry/HGCalAssociatorProducers/plugins/LayerClusterToSimClusterCaloParticleAssociatorByHitsProducer.cc b/SimCalorimetry/HGCalAssociatorProducers/plugins/LayerClusterToSimClusterCaloParticleAssociatorByHitsProducer.cc index 6baa8ed0f172d..6ac4abce1243c 100644 --- a/SimCalorimetry/HGCalAssociatorProducers/plugins/LayerClusterToSimClusterCaloParticleAssociatorByHitsProducer.cc +++ b/SimCalorimetry/HGCalAssociatorProducers/plugins/LayerClusterToSimClusterCaloParticleAssociatorByHitsProducer.cc @@ -203,9 +203,8 @@ class LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT : public edm }; template -LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT< - HIT, - CLUSTER>::LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT(const edm::ParameterSet& pset) +LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT:: + LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT(const edm::ParameterSet& pset) : layerClustersToken_(consumes(pset.getParameter("layerClusters"))), simClustersToken_(consumes(pset.getParameter("simClusters"))), caloParticlesToken_(consumes(pset.getParameter("caloParticles"))), @@ -227,9 +226,7 @@ LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT< template unsigned int LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT::layerIndex( - DetId detId, - const hgcal::RecHitTools& recHitTools, - unsigned int layers) const { + DetId detId, const hgcal::RecHitTools& recHitTools, unsigned int layers) const { unsigned int layer = recHitTools.getLayer(detId); if constexpr (std::is_same_v) { @@ -241,8 +238,7 @@ unsigned int LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT bool LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT::acceptSimHit( - DetId detId, - const hgcal::RecHitTools& recHitTools) const { + DetId detId, const hgcal::RecHitTools& recHitTools) const { if constexpr (std::is_same_v) { return !recHitTools.isBarrel(detId); } else { @@ -309,8 +305,7 @@ LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT::bui const hgcal::RecHitTools& recHitTools, unsigned int layers, unsigned int nLayers) const { - std::vector> simClustersOnLayer(simClusters.size(), - std::vector(nLayers)); + std::vector> simClustersOnLayer(simClusters.size(), std::vector(nLayers)); for (unsigned int scId = 0; scId < simClusters.size(); ++scId) { const auto& simCluster = simClusters[scId]; @@ -416,9 +411,7 @@ void LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT template void LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT::produce( - edm::StreamID, - edm::Event& iEvent, - const edm::EventSetup& iSetup) const { + edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const { auto layerClustersHandle = iEvent.getHandle(layerClustersToken_); auto simClustersHandle = iEvent.getHandle(simClustersToken_); auto caloParticlesHandle = iEvent.getHandle(caloParticlesToken_); @@ -645,9 +638,8 @@ void LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT float recoFraction = 0.f; if (hitIndex < hitToLayerClusterMap.size()) { const auto& hitToLCVec = hitToLayerClusterMap[hitIndex]; - const auto lcIt = std::find_if(hitToLCVec.begin(), hitToLCVec.end(), [lcId](const auto& element) { - return element.index() == lcId; - }); + const auto lcIt = std::find_if( + hitToLCVec.begin(), hitToLCVec.end(), [lcId](const auto& element) { return element.index() == lcId; }); if (lcIt != hitToLCVec.end()) { recoFraction = lcIt->fraction(); @@ -721,9 +713,8 @@ void LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT float recoFraction = 0.f; if (hitIndex < hitToLayerClusterMap.size()) { const auto& hitToLCVec = hitToLayerClusterMap[hitIndex]; - const auto lcIt = std::find_if(hitToLCVec.begin(), hitToLCVec.end(), [lcId](const auto& element) { - return element.index() == lcId; - }); + const auto lcIt = std::find_if( + hitToLCVec.begin(), hitToLCVec.end(), [lcId](const auto& element) { return element.index() == lcId; }); if (lcIt != hitToLCVec.end()) { recoFraction = lcIt->fraction(); @@ -761,13 +752,10 @@ void LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT desc.add("simClusters", edm::InputTag("mix", "MergedCaloTruth")); desc.add("caloParticles", edm::InputTag("mix", "MergedCaloTruth")); - desc.add( - "hitMap", - edm::InputTag("recHitMapProducer", HitCollectionTraits::defaultHitMapInstance)); + desc.add("hitMap", + edm::InputTag("recHitMapProducer", HitCollectionTraits::defaultHitMapInstance)); - desc.add( - "hits", - edm::InputTag("recHitMapProducer", HitCollectionTraits::defaultHitsInstance)); + desc.add("hits", edm::InputTag("recHitMapProducer", HitCollectionTraits::defaultHitsInstance)); desc.add("hitToSimClusterMap", edm::InputTag("hitToSimClusterCaloParticleAssociator", "hitToSimClusterMap")); @@ -780,8 +768,7 @@ void LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT edm::InputTag("hitToLayerClusterAssociator", "hitToLayerClusterMap")); } else { desc.add("layerClusters", edm::InputTag("particleFlowClusterHGCal")); - desc.add("hitToLayerClusterMap", - edm::InputTag("hitToPFClusterAssociator", "hitToLayerClusterMap")); + desc.add("hitToLayerClusterMap", edm::InputTag("hitToPFClusterAssociator", "hitToLayerClusterMap")); } descriptions.addWithDefaultLabel(desc); @@ -794,4 +781,4 @@ using HGCRecHitPFClusterToSimClusterCaloParticleAssociatorByHitsProducer = LayerClusterToSimClusterCaloParticleAssociatorByHitsProducerT; DEFINE_FWK_MODULE(HGCRecHitCaloClusterToSimClusterCaloParticleAssociatorByHitsProducer); -DEFINE_FWK_MODULE(HGCRecHitPFClusterToSimClusterCaloParticleAssociatorByHitsProducer); \ No newline at end of file +DEFINE_FWK_MODULE(HGCRecHitPFClusterToSimClusterCaloParticleAssociatorByHitsProducer);