From 5adbf5c679c08aab43fd6d045345baecea0dd2b1 Mon Sep 17 00:00:00 2001 From: Daniel J Lis Date: Wed, 17 Dec 2025 20:59:39 -0500 Subject: [PATCH 001/393] djl -- add average calo v2 as an option for flow --- .../jetbackground/DetermineTowerBackground.cc | 252 ++++++++++++------ .../jetbackground/DetermineTowerBackground.h | 13 +- offline/packages/jetbackground/Makefile.am | 3 + 3 files changed, 184 insertions(+), 84 deletions(-) diff --git a/offline/packages/jetbackground/DetermineTowerBackground.cc b/offline/packages/jetbackground/DetermineTowerBackground.cc index 9823d337f6..63100bcbea 100644 --- a/offline/packages/jetbackground/DetermineTowerBackground.cc +++ b/offline/packages/jetbackground/DetermineTowerBackground.cc @@ -14,6 +14,10 @@ #include #include +#include +#include +#include + #include #include @@ -52,9 +56,65 @@ DetermineTowerBackground::DetermineTowerBackground(const std::string &name) int DetermineTowerBackground::InitRun(PHCompositeNode *topNode) { + if (_do_flow == 4) + { + if (Verbosity()) + { + std::cout << "Loading the average calo v2" << std::endl; + } + LoadCalibrations(); + + } + return CreateNode(topNode); } +int DetermineTowerBackground::LoadCalibrations() +{ + + CDBTTree *cdbtree_calo_v2 = nullptr; + + std::string calibdir; + if (m_overwrite_average_calo_v2) + { + calibdir = m_overwrite_average_calo_v2_path; + } + else + { + calibdir = CDBInterface::instance()->getUrl(m_calibName); + } + + if (calibdir.empty()) + { + std::cout << "Could not find and load histograms for EMCAL LUTs! defaulting to the identity table!" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + else + { + cdbtree_calo_v2 = new CDBTTree(calibdir); + } + + if (!cdbtree_calo_v2) + { + std::cout << "Error in finding Average Calo v2." << std::endl; + + return Fun4AllReturnCodes::ABORTRUN; + } + + cdbtree_calo_v2->LoadCalibrations(); + + _CENTRALITY_V2.fill(0); + + for (int icent = 0; icent < 100; icent++) + { + _CENTRALITY_V2[icent] = cdbtree_calo_v2->GetFloatValue(icent, "jet_calo_v2"); + } + + delete cdbtree_calo_v2; + + return Fun4AllReturnCodes::EVENT_OK; +} + int DetermineTowerBackground::process_event(PHCompositeNode *topNode) { @@ -481,7 +541,92 @@ int DetermineTowerBackground::process_event(PHCompositeNode *topNode) } } - if ( _do_flow >= 1 ) + + // Get psi + if (_do_flow == 2) + { // HIJING truth flow extraction + PHG4TruthInfoContainer *truthinfo = findNode::getClass(topNode, "G4TruthInfo"); + + if (!truthinfo) + { + std::cout << "DetermineTowerBackground::process_event: FATAL , G4TruthInfo does not exist , cannot extract truth flow with do_flow = " << _do_flow << std::endl; + return -1; + } + + PHG4TruthInfoContainer::Range range = truthinfo->GetPrimaryParticleRange(); + + float Hijing_Qx = 0; + float Hijing_Qy = 0; + + for (PHG4TruthInfoContainer::ConstIterator iter = range.first; iter != range.second; ++iter) + { + PHG4Particle *g4particle = iter->second; + + if (truthinfo->isEmbeded(g4particle->get_track_id()) != 0) + { + continue; + } + + TLorentzVector t; + t.SetPxPyPzE(g4particle->get_px(), g4particle->get_py(), g4particle->get_pz(), g4particle->get_e()); + + float truth_pt = t.Pt(); + if (truth_pt < 0.4) + { + continue; + } + float truth_eta = t.Eta(); + if (std::fabs(truth_eta) > 1.1) + { + continue; + } + float truth_phi = t.Phi(); + int truth_pid = g4particle->get_pid(); + + if (Verbosity() > 10) + { + std::cout << "DetermineTowerBackground::process_event: determining truth flow, using particle w/ pt / eta / phi " << truth_pt << " / " << truth_eta << " / " << truth_phi << " , embed / PID = " << truthinfo->isEmbeded(g4particle->get_track_id()) << " / " << truth_pid << std::endl; + } + + Hijing_Qx += truth_pt * std::cos(2 * truth_phi); + Hijing_Qy += truth_pt * std::sin(2 * truth_phi); + } + + _Psi2 = std::atan2(Hijing_Qy, Hijing_Qx) / 2.0; + + if (Verbosity() > 0) + { + std::cout << "DetermineTowerBackground::process_event: flow extracted from Hijing truth particles, setting Psi2 = " << _Psi2 << " ( " << _Psi2 / M_PI << " * pi ) " << std::endl; + } + } + else if (_do_flow == 3 || _do_flow == 4) + { // sEPD event plane extraction + // get event plane map + EventplaneinfoMap *epmap = findNode::getClass(topNode, "EventplaneinfoMap"); + if (!epmap) + { + std::cout << "DetermineTowerBackground::process_event: FATAL, EventplaneinfoMap does not exist, cannot extract sEPD flow with do_flow = " << _do_flow << std::endl; + exit(-1); + } + if (!(epmap->empty())) + { + auto *EPDNS = epmap->get(EventplaneinfoMap::sEPDNS); + _Psi2 = EPDNS->get_shifted_psi(2); + } + else + { + _is_flow_failure = true; + _Psi2 = 0; + } + + if (Verbosity() > 0) + { + std::cout << "DetermineTowerBackground::process_event: flow extracted from sEPD, setting Psi2 = " << _Psi2 << " ( " << _Psi2 / M_PI << " * pi ) " << std::endl; + } + + } + + if ( _do_flow >= 1 && _do_flow < 4) { if (Verbosity() > 0) @@ -754,88 +899,6 @@ int DetermineTowerBackground::process_event(PHCompositeNode *topNode) { // Calo event plane _Psi2 = std::atan2(Q_y, Q_x) / 2.0; } - else if (_do_flow == 2) - { // HIJING truth flow extraction - PHG4TruthInfoContainer *truthinfo = findNode::getClass(topNode, "G4TruthInfo"); - - if (!truthinfo) - { - std::cout << "DetermineTowerBackground::process_event: FATAL , G4TruthInfo does not exist , cannot extract truth flow with do_flow = " << _do_flow << std::endl; - return -1; - } - - PHG4TruthInfoContainer::Range range = truthinfo->GetPrimaryParticleRange(); - - float Hijing_Qx = 0; - float Hijing_Qy = 0; - - for (PHG4TruthInfoContainer::ConstIterator iter = range.first; iter != range.second; ++iter) - { - PHG4Particle *g4particle = iter->second; - - if (truthinfo->isEmbeded(g4particle->get_track_id()) != 0) - { - continue; - } - - TLorentzVector t; - t.SetPxPyPzE(g4particle->get_px(), g4particle->get_py(), g4particle->get_pz(), g4particle->get_e()); - - float truth_pt = t.Pt(); - if (truth_pt < 0.4) - { - continue; - } - float truth_eta = t.Eta(); - if (std::fabs(truth_eta) > 1.1) - { - continue; - } - float truth_phi = t.Phi(); - int truth_pid = g4particle->get_pid(); - - if (Verbosity() > 10) - { - std::cout << "DetermineTowerBackground::process_event: determining truth flow, using particle w/ pt / eta / phi " << truth_pt << " / " << truth_eta << " / " << truth_phi << " , embed / PID = " << truthinfo->isEmbeded(g4particle->get_track_id()) << " / " << truth_pid << std::endl; - } - - Hijing_Qx += truth_pt * std::cos(2 * truth_phi); - Hijing_Qy += truth_pt * std::sin(2 * truth_phi); - } - - _Psi2 = std::atan2(Hijing_Qy, Hijing_Qx) / 2.0; - - if (Verbosity() > 0) - { - std::cout << "DetermineTowerBackground::process_event: flow extracted from Hijing truth particles, setting Psi2 = " << _Psi2 << " ( " << _Psi2 / M_PI << " * pi ) " << std::endl; - } - } - else if (_do_flow == 3) - { // sEPD event plane extraction - // get event plane map - EventplaneinfoMap *epmap = findNode::getClass(topNode, "EventplaneinfoMap"); - if (!epmap) - { - std::cout << "DetermineTowerBackground::process_event: FATAL, EventplaneinfoMap does not exist, cannot extract sEPD flow with do_flow = " << _do_flow << std::endl; - exit(-1); - } - if (!(epmap->empty())) - { - auto *EPDNS = epmap->get(EventplaneinfoMap::sEPDNS); - _Psi2 = EPDNS->get_shifted_psi(2); - } - else - { - _is_flow_failure = true; - _Psi2 = 0; - } - - if (Verbosity() > 0) - { - std::cout << "DetermineTowerBackground::process_event: flow extracted from sEPD, setting Psi2 = " << _Psi2 << " ( " << _Psi2 / M_PI << " * pi ) " << std::endl; - } - - } if (std::isnan(_Psi2) || std::isinf(_Psi2)) { @@ -890,7 +953,30 @@ int DetermineTowerBackground::process_event(PHCompositeNode *topNode) std::cout << "DetermineTowerBackground::process_event: flow extraction successful, Psi2 = " << _Psi2 << " ( " << _Psi2 / M_PI << " * pi ) , v2 = " << _v2 << std::endl; } } // if do flow + else if (_do_flow == 4) + { + CentralityInfo *centinfo = findNode::getClass(topNode, "CentralityInfo"); + + if (!centinfo) + { + std::cout << "DetermineTowerBackground::process_event: FATAL, CentralityInfo does not exist, cannot extract centrality with do_flow = " << _do_flow << std::endl; + exit(-1); + } + + int centrality_bin = centinfo->get_centrality_bin(CentralityInfo::PROP::mbd_NS); + + if (centrality_bin > 0 && centrality_bin < 95) + { + _v2 = _CENTRALITY_V2[centrality_bin]; + } + else + { + _v2 = 0; + _is_flow_failure = true; + _Psi2 = 0; + } + } // now calculate energy densities... _nTowers = 0; // store how many towers were used to determine bkg diff --git a/offline/packages/jetbackground/DetermineTowerBackground.h b/offline/packages/jetbackground/DetermineTowerBackground.h index a8a6d0209c..a46d48e616 100644 --- a/offline/packages/jetbackground/DetermineTowerBackground.h +++ b/offline/packages/jetbackground/DetermineTowerBackground.h @@ -13,6 +13,7 @@ #include #include #include +#include // forward declarations class PHCompositeNode; @@ -37,7 +38,11 @@ class DetermineTowerBackground : public SubsysReco void SetBackgroundOutputName(const std::string &name) { _backgroundName = name; } void SetSeedType(int seed_type) { _seed_type = seed_type; } void SetFlow(int do_flow) { _do_flow = do_flow; }; - + void SetOverwriteCaloV2(std::string &url) + { + m_overwrite_average_calo_v2 = true; + m_overwrite_average_calo_v2_path = url; + } void SetSeedJetD(float D) { _seed_jet_D = D; }; void SetSeedJetPt(float pt) { _seed_jet_pt = pt; }; void SetSeedMaxConst(float max_const) { _seed_max_const = max_const; }; @@ -55,6 +60,12 @@ class DetermineTowerBackground : public SubsysReco int CreateNode(PHCompositeNode *topNode); void FillNode(PHCompositeNode *topNode); + int LoadCalibrations(); + std::array _CENTRALITY_V2; + std::string m_calibName = "JET_AVERAGE_CALO_V2_SEPD_PSI2"; + bool m_overwrite_average_calo_v2{false}; + std::string m_overwrite_average_calo_v2_path; + int _do_flow{0}; float _v2{0}; float _Psi2{0}; diff --git a/offline/packages/jetbackground/Makefile.am b/offline/packages/jetbackground/Makefile.am index 6fe9740a4e..ad45676fbe 100644 --- a/offline/packages/jetbackground/Makefile.am +++ b/offline/packages/jetbackground/Makefile.am @@ -24,6 +24,8 @@ libjetbackground_la_LDFLAGS = \ libjetbackground_la_LIBADD = \ libjetbackground_io.la \ -lcalo_io \ + -lcentrality_io \ + -lcdbobjects \ -lConstituentSubtractor \ -leventplaneinfo_io \ -lglobalvertex \ @@ -33,6 +35,7 @@ libjetbackground_la_LIBADD = \ -lphg4hit \ -lphparameter \ -lqautils \ + -lffamodules \ -lSubsysReco pkginclude_HEADERS = \ From 35a6b31e4b87d1ce0fe8e10fb3450750dae4538a Mon Sep 17 00:00:00 2001 From: Daniel J Lis Date: Wed, 17 Dec 2025 21:11:40 -0500 Subject: [PATCH 002/393] add return if LoadCalibrations failed --- offline/packages/jetbackground/DetermineTowerBackground.cc | 6 +++++- offline/packages/jetbackground/DetermineTowerBackground.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/offline/packages/jetbackground/DetermineTowerBackground.cc b/offline/packages/jetbackground/DetermineTowerBackground.cc index 63100bcbea..12bc78130d 100644 --- a/offline/packages/jetbackground/DetermineTowerBackground.cc +++ b/offline/packages/jetbackground/DetermineTowerBackground.cc @@ -62,7 +62,11 @@ int DetermineTowerBackground::InitRun(PHCompositeNode *topNode) { std::cout << "Loading the average calo v2" << std::endl; } - LoadCalibrations(); + if (!LoadCalibrations()) + { + std::cout << "Load calibrations failed." << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } } diff --git a/offline/packages/jetbackground/DetermineTowerBackground.h b/offline/packages/jetbackground/DetermineTowerBackground.h index a46d48e616..8905c2c93d 100644 --- a/offline/packages/jetbackground/DetermineTowerBackground.h +++ b/offline/packages/jetbackground/DetermineTowerBackground.h @@ -61,6 +61,7 @@ class DetermineTowerBackground : public SubsysReco void FillNode(PHCompositeNode *topNode); int LoadCalibrations(); + std::array _CENTRALITY_V2; std::string m_calibName = "JET_AVERAGE_CALO_V2_SEPD_PSI2"; bool m_overwrite_average_calo_v2{false}; From 2e9ccc7bd05638acfab1959cc62d9e2bbca8515d Mon Sep 17 00:00:00 2001 From: Daniel J Lis Date: Wed, 17 Dec 2025 22:46:03 -0500 Subject: [PATCH 003/393] djl -- array to vector --- offline/packages/jetbackground/DetermineTowerBackground.cc | 2 +- offline/packages/jetbackground/DetermineTowerBackground.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/offline/packages/jetbackground/DetermineTowerBackground.cc b/offline/packages/jetbackground/DetermineTowerBackground.cc index 12bc78130d..9a2e550e5d 100644 --- a/offline/packages/jetbackground/DetermineTowerBackground.cc +++ b/offline/packages/jetbackground/DetermineTowerBackground.cc @@ -107,7 +107,7 @@ int DetermineTowerBackground::LoadCalibrations() cdbtree_calo_v2->LoadCalibrations(); - _CENTRALITY_V2.fill(0); + _CENTRALITY_V2.assign(100,0); for (int icent = 0; icent < 100; icent++) { diff --git a/offline/packages/jetbackground/DetermineTowerBackground.h b/offline/packages/jetbackground/DetermineTowerBackground.h index 8905c2c93d..ed9e34bf9a 100644 --- a/offline/packages/jetbackground/DetermineTowerBackground.h +++ b/offline/packages/jetbackground/DetermineTowerBackground.h @@ -62,7 +62,7 @@ class DetermineTowerBackground : public SubsysReco int LoadCalibrations(); - std::array _CENTRALITY_V2; + std::vector _CENTRALITY_V2; std::string m_calibName = "JET_AVERAGE_CALO_V2_SEPD_PSI2"; bool m_overwrite_average_calo_v2{false}; std::string m_overwrite_average_calo_v2_path; From ce0d3af05d26ad9aaf3275d50dce0afd8d54b2ec Mon Sep 17 00:00:00 2001 From: Daniel J Lis Date: Fri, 19 Dec 2025 09:12:26 -0500 Subject: [PATCH 004/393] djl -- change error handling to exit and not check for nullptr --- .../jetbackground/DetermineTowerBackground.cc | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/offline/packages/jetbackground/DetermineTowerBackground.cc b/offline/packages/jetbackground/DetermineTowerBackground.cc index 9a2e550e5d..7f021f4f39 100644 --- a/offline/packages/jetbackground/DetermineTowerBackground.cc +++ b/offline/packages/jetbackground/DetermineTowerBackground.cc @@ -91,20 +91,13 @@ int DetermineTowerBackground::LoadCalibrations() if (calibdir.empty()) { std::cout << "Could not find and load histograms for EMCAL LUTs! defaulting to the identity table!" << std::endl; - return Fun4AllReturnCodes::ABORTRUN; + exit(-1); } else { cdbtree_calo_v2 = new CDBTTree(calibdir); } - - if (!cdbtree_calo_v2) - { - std::cout << "Error in finding Average Calo v2." << std::endl; - - return Fun4AllReturnCodes::ABORTRUN; - } - + cdbtree_calo_v2->LoadCalibrations(); _CENTRALITY_V2.assign(100,0); From 6ddbed51e0941f64f3acb2cf6c90bdcf47b33b6d Mon Sep 17 00:00:00 2001 From: Hugo Pereira Da Costa Date: Mon, 14 Apr 2025 10:57:21 -0400 Subject: [PATCH 005/393] Add matching flag to evaluation. Fill ntuple for both matched and unmatched waveforms --- .../SingleMicromegasPoolInput_v2.cc | 51 +++++++++++-------- .../fun4allraw/SingleMicromegasPoolInput_v2.h | 3 ++ 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/offline/framework/fun4allraw/SingleMicromegasPoolInput_v2.cc b/offline/framework/fun4allraw/SingleMicromegasPoolInput_v2.cc index 7500e3badf..89c0caa9f3 100644 --- a/offline/framework/fun4allraw/SingleMicromegasPoolInput_v2.cc +++ b/offline/framework/fun4allraw/SingleMicromegasPoolInput_v2.cc @@ -607,6 +607,7 @@ void SingleMicromegasPoolInput_v2::createQAHistos() m_evaluation_file.reset(new TFile(m_evaluation_filename.c_str(), "RECREATE")); m_evaluation_tree = new TTree("T", "T"); m_evaluation_tree->Branch("is_heartbeat", &m_waveform.is_heartbeat); + m_evaluation_tree->Branch("matched", &m_waveform.matched); m_evaluation_tree->Branch("packet_id", &m_waveform.packet_id); m_evaluation_tree->Branch("fee_id", &m_waveform.fee_id); m_evaluation_tree->Branch("channel", &m_waveform.channel); @@ -912,6 +913,13 @@ void SingleMicromegasPoolInput_v2::process_fee_data(int packet_id, unsigned int // try get gtm bco matching fee const auto& fee_bco = payload.bx_timestamp; + if( m_do_evaluation ) + { + m_waveform.is_heartbeat = is_heartbeat; + m_waveform.fee_id = fee_id; + m_waveform.channel = payload.channel; + m_waveform.fee_bco = fee_bco; + } // find matching gtm bco uint64_t gtm_bco = 0; @@ -920,9 +928,20 @@ void SingleMicromegasPoolInput_v2::process_fee_data(int packet_id, unsigned int { // assign gtm bco gtm_bco = result.value(); - } - else - { + if( m_do_evaluation ) + { + m_waveform.matched = true; + m_waveform.gtm_bco_matched = gtm_bco; + { + const auto predicted = bco_matching_information.get_predicted_fee_bco(gtm_bco);; + if( predicted ) + { + m_waveform.fee_bco_predicted_matched = predicted.value(); + } + } + m_evaluation_tree->Fill(); + } + } else { // increment counter and histogram ++m_waveform_counters[packet_id].dropped_bco; ++m_fee_waveform_counters[fee_id].dropped_bco; @@ -935,28 +954,16 @@ void SingleMicromegasPoolInput_v2::process_fee_data(int packet_id, unsigned int ++m_fee_heartbeat_counters[fee_id].dropped_bco; } - // skip the waverform - continue; - } - - if (m_do_evaluation) - { - m_waveform.is_heartbeat = (payload.type == HEARTBEAT_T); - m_waveform.fee_id = fee_id; - m_waveform.channel = payload.channel; - m_waveform.fee_bco = fee_bco; - - m_waveform.gtm_bco_matched = gtm_bco; + if( m_do_evaluation ) { - const auto predicted = bco_matching_information.get_predicted_fee_bco(gtm_bco); - ; - if (predicted) - { - m_waveform.fee_bco_predicted_matched = predicted.value(); - } + m_waveform.matched = false; + m_waveform.gtm_bco_matched = 0; + m_waveform.fee_bco_predicted_matched = 0; + m_evaluation_tree->Fill(); } - m_evaluation_tree->Fill(); + // skip the waverform + continue; } // ignore heartbeat waveforms diff --git a/offline/framework/fun4allraw/SingleMicromegasPoolInput_v2.h b/offline/framework/fun4allraw/SingleMicromegasPoolInput_v2.h index d8c3c1da62..3746b9eb41 100644 --- a/offline/framework/fun4allraw/SingleMicromegasPoolInput_v2.h +++ b/offline/framework/fun4allraw/SingleMicromegasPoolInput_v2.h @@ -230,6 +230,9 @@ class SingleMicromegasPoolInput_v2 : public SingleStreamingInput /// true if measurement is hearbeat bool is_heartbeat = false; + /// true if matched + bool matched = false; + /// ll1 bco uint64_t gtm_bco_first {0}; From ba90ae834d4c8d8e283828482904d753c6104afb Mon Sep 17 00:00:00 2001 From: bkimelman Date: Tue, 6 Jan 2026 12:05:55 -0500 Subject: [PATCH 006/393] Changes to CM Distortions --- offline/packages/tpc/LaserClusterizer.cc | 146 ++++- .../tpccalib/TpcCentralMembraneMatching.cc | 95 ++- .../tpccalib/TpcCentralMembraneMatching.h | 10 +- .../packages/tpccalib/TpcLaminationFitting.cc | 558 ++++++++++++++---- .../packages/tpccalib/TpcLaminationFitting.h | 46 +- 5 files changed, 726 insertions(+), 129 deletions(-) diff --git a/offline/packages/tpc/LaserClusterizer.cc b/offline/packages/tpc/LaserClusterizer.cc index 170f95944d..6f143bb1c2 100644 --- a/offline/packages/tpc/LaserClusterizer.cc +++ b/offline/packages/tpc/LaserClusterizer.cc @@ -155,6 +155,106 @@ namespace return par[0]*g*cdf; } + void splitWeaklyConnectedRegion(const std::vector ®ion, std::vector> &outputRegions) + { + int N = region.size(); + std::vector> adj(N); + for(int i=0; i() + neigh.get<0>() - region[j].first.get<0>()) < 0.01 && + fabs(region[i].first.get<1>() + neigh.get<1>() - region[j].first.get<1>()) < 0.01 && + fabs(region[i].first.get<2>() + neigh.get<2>() - region[j].first.get<2>()) < 0.01) + { + adj[i].push_back(j); + adj[j].push_back(i); + break; + } + } + } + } + + std::cout << " constructed adjacency list, average degree = " << std::accumulate(adj.begin(), adj.end(), 0.0, [](double s, auto &v) { return s + v.size(); }) / N << ")" << std::endl; + + std::vector disc(N, -1), low(N, -1), parent(N, -1); + std::vector> bridges; + int time=0; + + std::function dfs = [&](int u) + { + disc[u] = low[u] = ++time; + for(auto v : adj[u]) + { + if(disc[v] == -1) + { + parent[v] = u; + dfs(v); + low[u] = std::min(low[u], low[v]); + if(low[v] > disc[u]) + { + bridges.emplace_back(u,v); + } + } + else if(v != parent[u]) + { + low[u] = std::min(low[u], disc[v]); + } + } + }; + + for(int i=0; i> adj2 = adj; + int removed = 0; + for(auto [u,v] : bridges) + { + if(adj[u].size() > 2 && adj[v].size() > 2) + { + adj2[u].erase(std::remove(adj2[u].begin(), adj2[u].end(), v), adj2[u].end()); + adj2[v].erase(std::remove(adj2[v].begin(), adj2[v].end(), u), adj2[v].end()); + removed++; + std::cout << " removed weak bridge between nodes " << u << " (deg = " << adj[u].size() << ") and " << v << " (deg = " << adj[v].size() << ")" << std::endl; + } + } + + std::cout << " Removed " << removed << " weak bridges, now finding connected components" << std::endl; + + std::vector visited(N, false); + for(int i=0; i sub; + std::queue q; + q.push(i); + visited[i] = true; + while(!q.empty()) + { + int u = q.front(); + q.pop(); + sub.push_back(region[u]); + for(auto v : adj2[u]) + { + if(!visited[v]) + { + visited[v] = true; + q.push(v); + } + } + } + outputRegions.push_back(sub); + std::cout << " found subregion of size " << sub.size() << std::endl; + } + std::cout << " finished splitting region into " << outputRegions.size() << " subregions" << std::endl; +} + void findConnectedRegions3(std::vector &clusHits, std::pair &maxKey) { std::vector> regions; @@ -215,11 +315,55 @@ namespace } } regions.push_back(region); + } + std::cout << "finished with normal region finding, now splitting weakly connected regions" << std::endl; + + std::vector> refinedRegions; + int regionNum = 0; + for(auto ®ion : regions) + { + std::vector> tmpRefinedRegions; + std::cout << "starting to split region " << regionNum << " with " << region.size() << " hits" << std::endl; + regionNum++; + splitWeaklyConnectedRegion(region, tmpRefinedRegions); + std::cout << "finished splitting region into " << tmpRefinedRegions.size() << std::endl; + for(auto &subregion : tmpRefinedRegions) + { + refinedRegions.push_back(subregion); + } + std::cout << "total refined regions so far: " << refinedRegions.size() << std::endl; } + std::sort(refinedRegions.begin(), refinedRegions.end(), [&](const auto &a, const auto &b) + { + bool a_has = false; + bool b_has = false; + for(auto &h : a) + { + if(h.second.second.first == maxKey.first && h.second.second.second == maxKey.second) + { + a_has = true; + break; + } + } + for(auto &h : b) + { + if(h.second.second.first == maxKey.first && h.second.second.second == maxKey.second) + { + b_has = true; + break; + } + } + if(a_has != b_has) + { + return a_has; + } + return a.size() > b.size(); + }); + clusHits.clear(); - for(auto hit : regions[0]) + for(auto hit : refinedRegions[0]) { clusHits.push_back(hit); } diff --git a/offline/packages/tpccalib/TpcCentralMembraneMatching.cc b/offline/packages/tpccalib/TpcCentralMembraneMatching.cc index 6fa65dfbdf..60df27bbbb 100644 --- a/offline/packages/tpccalib/TpcCentralMembraneMatching.cc +++ b/offline/packages/tpccalib/TpcCentralMembraneMatching.cc @@ -16,6 +16,8 @@ #include +#include + #include #include @@ -160,11 +162,13 @@ namespace TpcCentralMembraneMatching::TpcCentralMembraneMatching(const std::string& name) : SubsysReco(name) { + /* // calculate stripes center positions CalculateCenters(nPads_R1, R1_e, nGoodStripes_R1_e, keepUntil_R1_e, nStripesIn_R1_e, nStripesBefore_R1_e, cx1_e, cy1_e); CalculateCenters(nPads_R1, R1, nGoodStripes_R1, keepUntil_R1, nStripesIn_R1, nStripesBefore_R1, cx1, cy1); CalculateCenters(nPads_R2, R2, nGoodStripes_R2, keepUntil_R2, nStripesIn_R2, nStripesBefore_R2, cx2, cy2); CalculateCenters(nPads_R3, R3, nGoodStripes_R3, keepUntil_R3, nStripesIn_R3, nStripesBefore_R3, cx3, cy3); + */ } //___________________________________________________________ @@ -1095,7 +1099,31 @@ int TpcCentralMembraneMatching::InitRun(PHCompositeNode* topNode) // Get truth cluster positions //===================== - const double phi_petal = M_PI / 9.0; // angle span of one petal + CDBTTree *cdbttree = new CDBTTree("/sphenix/u/bkimelman/CMStripePattern.root"); + cdbttree->LoadCalibrations(); + auto cdbMap = cdbttree->GetDoubleEntryMap(); + for (const auto &[index, values] : cdbMap) + { + m_truth_index.push_back(index); + double tmpR = cdbttree->GetDoubleValue(index, "truthR"); + double tmpPhi = cdbttree->GetDoubleValue(index, "truthPhi"); + TVector3 dummyPos(tmpR*cos(tmpPhi), tmpR*sin(tmpPhi), (index / 10000 < 18 ? 1.0 : -1.0)); + m_truth_pos.push_back(dummyPos); + truth_r_phi[(index / 10000 < 18 ? 1 : 0)]->Fill(tmpPhi, tmpR); + if(Verbosity() > 2) + { + std::cout << " index " << index << " x " << dummyPos.X() << " y " << dummyPos.Y() + << " phi " << std::atan2(dummyPos.Y(), dummyPos.X()) + << " radius " << get_r(dummyPos.X(), dummyPos.Y()) << std::endl; + } + if(m_savehistograms) + { + hxy_truth->Fill(dummyPos.X(), dummyPos.Y()); + } + + } + + //const double phi_petal = M_PI / 9.0; // angle span of one petal /* * utility function to @@ -1103,6 +1131,7 @@ int TpcCentralMembraneMatching::InitRun(PHCompositeNode* topNode) * - assign proper z, * - insert in container */ + /* auto save_truth_position = [&](TVector3 source) { source.SetZ(-1); @@ -1279,6 +1308,7 @@ for (int j = 0; j < nRadii; ++j) } } } +*/ /* int count[2] = {0, 0}; @@ -2150,7 +2180,14 @@ int TpcCentralMembraneMatching::process_event(PHCompositeNode* topNode) cmdiff->setTruthR(m_truth_pos[i].Perp()); cmdiff->setTruthZ(m_truth_pos[i].Z()); - if (m_averageMode) + if (m_totalDistMode) + { + cmdiff->setRecoPhi(raw_pos[reco_index].Phi()); + cmdiff->setRecoR(raw_pos[reco_index].Perp()); + cmdiff->setRecoZ(raw_pos[reco_index].Z()); + cmdiff->setNclusters(reco_nhits[reco_index]); + } + else if (m_averageMode) { cmdiff->setRecoPhi(static_pos[reco_index].Phi()); cmdiff->setRecoR(static_pos[reco_index].Perp()); @@ -2186,6 +2223,14 @@ int TpcCentralMembraneMatching::process_event(PHCompositeNode* topNode) dr = static_pos[reco_index].Perp() - m_truth_pos[i].Perp(); dphi = delta_phi(static_pos[reco_index].Phi() - m_truth_pos[i].Phi()); } + if(m_totalDistMode) + { + clus_r = raw_pos[reco_index].Perp(); + clus_phi = raw_pos[reco_index].Phi(); + + dr = raw_pos[reco_index].Perp() - m_truth_pos[i].Perp(); + dphi = delta_phi(raw_pos[reco_index].Phi() - m_truth_pos[i].Phi()); + } if (clus_phi < 0) { clus_phi += 2 * M_PI; @@ -2260,6 +2305,8 @@ int TpcCentralMembraneMatching::process_event(PHCompositeNode* topNode) for(int s=0; s<2; s++) { + int N = gr_dR[s]->GetN(); + bool firstGoodR = false; for(int j=1; j<=m_dcc_out->m_hDRint[s]->GetNbinsY(); j++) { @@ -2283,8 +2330,46 @@ int TpcCentralMembraneMatching::process_event(PHCompositeNode* topNode) for(int i=2; i<=m_dcc_out->m_hDRint[s]->GetNbinsX()-1; i++) { double phiVal = m_dcc_out->m_hDRint[s]->GetXaxis()->GetBinCenter(i); - m_dcc_out->m_hDRint[s]->SetBinContent(i, j, gr_dR[s]->Interpolate(phiVal,RVal)); - m_dcc_out->m_hDPint[s]->SetBinContent(i, j, RVal*gr_dPhi[s]->Interpolate(phiVal,RVal)); + + double num_dPhi = 0.0; + double num_dR = 0.0; + double den = 0.0; + double smoothing_parameter = 2.0; + + for(int k=0; kGetX()[k]); + double interp_RdPhi = RVal*interp_dPhi; + double interp_dR = RVal - gr_dR[s]->GetY()[k]; + + double distSq = (interp_RdPhi*interp_RdPhi) + (interp_dR*interp_dR); + + if(distSq > 100.0) continue; + + if(distSq < 1e-9) + { + num_dPhi = gr_dPhi[s]->GetZ()[k]; + num_dR = gr_dR[s]->GetZ()[k]; + + den = 1.0; + + break; + } + + double weight = 1.0 / pow(distSq, smoothing_parameter / 2.0); + num_dPhi += weight * gr_dPhi[s]->GetZ()[k]; + num_dR += weight * gr_dR[s]->GetZ()[k]; + den += weight; + + } + + if(den > 0.0) + { + m_dcc_out->m_hDRint[s]->SetBinContent(i, j, num_dR / den); + m_dcc_out->m_hDPint[s]->SetBinContent(i, j, RVal*(num_dPhi / den)); + } + //m_dcc_out->m_hDRint[s]->SetBinContent(i, j, gr_dR[s]->Interpolate(phiVal,RVal)); + //m_dcc_out->m_hDPint[s]->SetBinContent(i, j, RVal*gr_dPhi[s]->Interpolate(phiVal,RVal)); } } } @@ -2693,6 +2778,7 @@ int TpcCentralMembraneMatching::GetNodes(PHCompositeNode* topNode) return Fun4AllReturnCodes::EVENT_OK; } +/* //_____________________________________________________________ void TpcCentralMembraneMatching::CalculateCenters( int nPads, @@ -2763,3 +2849,4 @@ void TpcCentralMembraneMatching::CalculateCenters( nGoodStripes[j] = i_out; } } +*/ diff --git a/offline/packages/tpccalib/TpcCentralMembraneMatching.h b/offline/packages/tpccalib/TpcCentralMembraneMatching.h index bb09e8d8fe..b88bfbe6e5 100644 --- a/offline/packages/tpccalib/TpcCentralMembraneMatching.h +++ b/offline/packages/tpccalib/TpcCentralMembraneMatching.h @@ -101,6 +101,11 @@ class TpcCentralMembraneMatching : public SubsysReco m_averageMode = averageMode; } + void set_totalDistMode(bool totalDistMode) + { + m_totalDistMode = totalDistMode; + } + void set_event_sequence(int seq) { m_event_sequence = seq; @@ -202,7 +207,8 @@ class TpcCentralMembraneMatching : public SubsysReco bool m_useHeader{true}; bool m_averageMode{false}; - + bool m_totalDistMode{false}; + std::vector e_matched; std::vector e_truthIndex; std::vector e_truthR; @@ -301,6 +307,7 @@ class TpcCentralMembraneMatching : public SubsysReco //@} + /* ///@name central membrane pads definitions //@{ static constexpr double mm{1.0}; @@ -367,6 +374,7 @@ class TpcCentralMembraneMatching : public SubsysReco std::array &nStripesIn, std::array &nStripesBefore, double cx[][nRadii], double cy[][nRadii]); + */ /// store centers of all central membrane pads std::vector m_truth_pos; diff --git a/offline/packages/tpccalib/TpcLaminationFitting.cc b/offline/packages/tpccalib/TpcLaminationFitting.cc index 8c99fbb622..b69672fa8f 100644 --- a/offline/packages/tpccalib/TpcLaminationFitting.cc +++ b/offline/packages/tpccalib/TpcLaminationFitting.cc @@ -8,6 +8,8 @@ #include +#include + #include #include @@ -27,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -59,25 +62,47 @@ int TpcLaminationFitting::InitRun(PHCompositeNode *topNode) { for (int s = 0; s < 2; s++) { + + m_hPetal[s] = new TH2D((boost::format("hPetal_%s") %(s == 1 ? "North" : "South")).str().c_str(), (boost::format("TPC %s;#phi;R [cm]") %(s == 1 ? "North" : "South")).str().c_str(), 500, m_phiModMin[s], m_phiModMax[s], 500, 30, 80); + m_parameterScan[s] = new TH2D((boost::format("parameterScan_%s") %(s == 1 ? "North" : "South")).str().c_str(), (boost::format("TPC %s Lamination Parameter Scan;m;B") %(s == 1 ? "North" : "South")).str().c_str(), 41, -0.0205, 0.0205, 49, -3.0625, 3.0625); + for (int l = 0; l < 18; l++) { - double shift = l * M_PI / 9; + double shift = (l * M_PI / 9); if (s == 0) { shift += M_PI / 18; } + m_laminationIdeal[l][s] = shift; + //this function for the offset was determined from fitting the measured lamination offsets vs ideal lamination phi from field off data in run 75103 + //m_laminationOffset[l][s] = -0.00296837 + 0.0014604 * cos(shift - 1.2246); + if(s == 0) + { + m_laminationOffset[l][s] = -0.00236289 + 0.00143918 * cos(shift - 1.31782); + } + else + { + m_laminationOffset[l][s] = -0.00323259 + 0.00138333 * cos(shift - 1.25373); + } - m_hLamination[l][s] = new TH2D((boost::format("hLamination%d_%s") %l %(s == 1 ? "North" : "South")).str().c_str(), (boost::format("Lamination %d %s, #phi_{expected}=%.2f;R [cm];#phi") %l %(s == 1 ? "North" : "South") %shift).str().c_str(), 200, 30, 80, 200, shift - 0.2, shift + 0.2); - //m_fLamination[l][s] = new TF1((boost::format("fLamination%d_%s") %l %(s == 1 ? "North" : "South")).str().c_str(), "[0]+[1]*exp(-[2]*x)", 30, 80); - //m_fLamination[l][s] = new TF1((boost::format("fLamination%d_%s") %l %(s == 1 ? "North" : "South")).str().c_str(), "[0]*(1+exp(-[2]*(x-[1])))", 30, 80); - m_fLamination[l][s] = new TF1((boost::format("fLamination%d_%s") %l %(s == 1 ? "North" : "South")).str().c_str(), "[3]+[0]*(1-exp(-[2]*(x-[1])))", 30, 80); - //m_fLamination[l][s]->SetParameters(-0.022 + shift, log(3.0/(-0.22 + shift)), 0.12); - m_fLamination[l][s]->SetParameters(-0.011, 30, 0.16, 0.0); - m_fLamination[l][s]->SetParLimits(0, -0.22, 0.0); - m_fLamination[l][s]->SetParLimits(1, 0, 80); - m_fLamination[l][s]->SetParLimits(2, 0.0, 3); - m_fLamination[l][s]->FixParameter(3, shift); - m_laminationCenter[l][s] = shift; + if(m_fieldOff) + { + m_hLamination[l][s] = new TH2D((boost::format("hLamination%d_%s") %l %(s == 1 ? "North" : "South")).str().c_str(), (boost::format("Lamination %d %s, #phi_{ideal}=%.2f;R [cm];#phi") %l %(s == 1 ? "North" : "South") %m_laminationIdeal[l][s]).str().c_str(), 200, 30, 80, 200, m_laminationIdeal[l][s] - 0.2, m_laminationIdeal[l][s] + 0.2); + m_fLamination[l][s] = new TF1((boost::format("fLamination%d_%s") %l %(s == 1 ? "North" : "South")).str().c_str(), "[0]+[1]", 30, 80); + m_fLamination[l][s]->SetParameters(-0.003, m_laminationIdeal[l][s]); + m_fLamination[l][s]->SetParLimits(0, -0.05, 0.05); + m_fLamination[l][s]->FixParameter(1, m_laminationIdeal[l][s]); + } + else + { + m_hLamination[l][s] = new TH2D((boost::format("hLamination%d_%s") %l %(s == 1 ? "North" : "South")).str().c_str(), (boost::format("Lamination %d %s, #phi_{nominal}=%.2f;R [cm];#phi") %l %(s == 1 ? "North" : "South") %(m_laminationIdeal[l][s]+m_laminationOffset[l][s])).str().c_str(), 200, 30, 80, 200, m_laminationIdeal[l][s]+m_laminationOffset[l][s] - 0.2, m_laminationIdeal[l][s]+m_laminationOffset[l][s] + 0.2); + m_fLamination[l][s] = new TF1((boost::format("fLamination%d_%s") %l %(s == 1 ? "North" : "South")).str().c_str(), "[3]+[0]*(1-exp(-[2]*(x-[1])))", 30, 80); + m_fLamination[l][s]->SetParameters(-0.08, 38, 0.16, 0.0); + m_fLamination[l][s]->SetParLimits(0, -0.02, 0.0); + m_fLamination[l][s]->SetParLimits(1, 0, 50); + m_fLamination[l][s]->SetParLimits(2, 0.0, 1.0); + m_fLamination[l][s]->FixParameter(3, m_laminationIdeal[l][s]+m_laminationOffset[l][s]); + } } } @@ -116,6 +141,90 @@ int TpcLaminationFitting::InitRun(PHCompositeNode *topNode) m_run_ZDC_map_auau.insert(std::pair(54969, 9680.)); */ + /* + for(int module=0; module<4; module++) + { + double spacing[nRadii]; + for(int j=0; j m_phiModMax[s]) + { + phi[s] -= M_PI / 9; + } + m_truthR[s].push_back(RValues[module][j]); + m_truthPhi[s].push_back(phi[s]); + } + + } + } + } + */ + CDBTTree *cdbttree = new CDBTTree("/sphenix/u/bkimelman/CMStripePattern.root"); + cdbttree->LoadCalibrations(); + auto cdbMap = cdbttree->GetDoubleEntryMap(); + for (const auto &[index, values] : cdbMap) + { + if(index / 10000 == 18) + { + m_truthR[0].push_back(cdbttree->GetDoubleValue(index, "truthR")); + m_truthPhi[0].push_back(cdbttree->GetDoubleValue(index, "truthPhi")); + } + else if(index / 10000 == 0) + { + m_truthR[1].push_back(cdbttree->GetDoubleValue(index, "truthR")); + m_truthPhi[1].push_back(cdbttree->GetDoubleValue(index, "truthPhi")); + } + } + /* + for(int i=0; i<32; i++) + { + for(int j=0; j<11; j++) + { + int index0 = 18 + i*100 + j; + int index1 = i*100 + j; + + double R0 = cdbttree->GetDoubleValue(index0, "truthR"); + double Phi0 = cdbttree->GetDoubleValue(index0, "truthPhi"); + if(!std::isnan(R0) && !std::isnan(Phi0)) + { + m_truthR[0].push_back(R0); + m_truthPhi[0].push_back(Phi0); + } + + double R1 = cdbttree->GetDoubleValue(index1, "truthR"); + double Phi1 = cdbttree->GetDoubleValue(index1, "truthPhi"); + if(!std::isnan(R1) && !std::isnan(Phi1)) + { + m_truthR[1].push_back(R1); + m_truthPhi[1].push_back(Phi1); + } + } + } + */ + int ret = GetNodes(topNode); return ret; } @@ -205,12 +314,16 @@ int TpcLaminationFitting::GetNodes(PHCompositeNode *topNode) m_dcc_out->m_hDZint[i] = new TH2F((boost::format("hIntDistortionZ%s") % extension[i]).str().c_str(), (boost::format("hIntDistortionZ%s") % extension[i]).str().c_str(), m_phibins + 2, phiMin, phiMax, m_rbins + 2, rMin, rMax); delete m_dcc_out->m_hentries[i]; m_dcc_out->m_hentries[i] = new TH2I((boost::format("hEntries%s") % extension[i]).str().c_str(), (boost::format("hEntries%s") % extension[i]).str().c_str(), m_phibins + 2, phiMin, phiMax, m_rbins + 2, rMin, rMax); + + phiDistortionLamination[i] = new TH2F((boost::format("phiDistortionLamination%s") % extension[i]).str().c_str(), (boost::format("phiDistortionLamination%s") % extension[i]).str().c_str(), m_phibins + 2, phiMin, phiMax, m_rbins + 2, rMin, rMax); + } m_laminationTree = new TTree("laminationTree","laminationTree"); m_laminationTree->Branch("side",&m_side); m_laminationTree->Branch("lamIndex",&m_lamIndex); m_laminationTree->Branch("lamPhi",&m_lamPhi); + m_laminationTree->Branch("lamOffset",&m_lamShift); m_laminationTree->Branch("goodFit",&m_goodFit); m_laminationTree->Branch("A",&m_A); m_laminationTree->Branch("B",&m_B); @@ -266,11 +379,12 @@ int TpcLaminationFitting::process_event(PHCompositeNode *topNode) LaserCluster *cmclus = cmclus_orig; // const unsigned int adc = cmclus->getAdc(); bool side = (bool) TpcDefs::getSide(cmkey); - if (cmclus->getNLayers() <= m_nLayerCut) + if (cmclus->getNLayers() < m_nLayerCut) { continue; } + //Acts::Vector3 pos(cmclus->getX(), cmclus->getY(), cmclus->getZ()); Acts::Vector3 pos(cmclus->getX(), cmclus->getY(), (side ? 1.0 : -1.0)); if (m_dcc_in_module_edge) @@ -284,25 +398,49 @@ int TpcLaminationFitting::process_event(PHCompositeNode *topNode) TVector3 tmp_pos(pos[0], pos[1], pos[2]); - for (int l = 0; l < 18; l++) + if(cmclus->getNLayers() > m_nLayerCut && cmclus->getSDWeightedLayer() > 0.5) { - double shift = m_laminationCenter[l][side]; - - double phi2pi = tmp_pos.Phi(); - if (side && phi2pi < -0.2) - { - phi2pi += 2 * M_PI; - } - if (!side && phi2pi < M_PI / 18 - 0.2) + for (int l = 0; l < 18; l++) { - phi2pi += 2 * M_PI; + double shift = m_laminationIdeal[l][side]; + + double phi2pi = tmp_pos.Phi(); + if (side && phi2pi < -0.2) + { + phi2pi += 2 * M_PI; + } + if (!side && phi2pi < M_PI / 18 - 0.2) + { + phi2pi += 2 * M_PI; + } + + if (phi2pi > shift - 0.2 && phi2pi < shift + 0.2) + { + m_hLamination[l][side]->Fill(tmp_pos.Perp(), phi2pi); + } } + } - if (phi2pi > shift - 0.2 && phi2pi < shift + 0.2) - { - m_hLamination[l][side]->Fill(tmp_pos.Perp(), phi2pi); - } + if(cmclus->getSDWeightedLayer() > 0.5) + { + continue; + } + + double phi2pimod = tmp_pos.Phi(); + if (phi2pimod < 0.0) + { + phi2pimod += 2 * M_PI; + } + while(side && phi2pimod > M_PI / 9) + { + phi2pimod -= M_PI / 9; } + while(!side && phi2pimod > M_PI / 18) + { + phi2pimod -= M_PI / 9; + } + + m_hPetal[side]->Fill(phi2pimod, tmp_pos.Perp()); } return Fun4AllReturnCodes::EVENT_OK; @@ -332,6 +470,7 @@ int TpcLaminationFitting::fitLaminations() //float ZDC = 4500.0; TF1 *Af[2] = {new TF1("AN","pol1",0,100000), new TF1("AS","pol1",0,100000)}; TF1 *Bf[2] = {new TF1("BN","pol1",0,100000), new TF1("BS","pol1",0,100000)}; + //TF1 *Cf[2] = {new TF1("CN","pol1",0,100000), new TF1("CS","pol1",0,100000)}; double Cseed[2] = {0.16, 0.125}; if(ppMode) @@ -353,9 +492,12 @@ int TpcLaminationFitting::fitLaminations() Af[0]->SetParameters(-0.007999,-1.783e-6); Af[1]->SetParameters(-0.003288,-2.297e-6); - + Bf[0]->SetParameters(31.55,0.0006141); Bf[1]->SetParameters(34.7,0.0005226); + + //Cf[0]->SetParameters(5.33e-5,0.0); + //Cf[1]->SetParameters(4.166e-5,0.0); } else { @@ -383,6 +525,9 @@ int TpcLaminationFitting::fitLaminations() Bf[0]->SetParameters(32.96,0.0002997); Bf[1]->SetParameters(31.19,0.0005622); + //Cf[0]->SetParameters(1.316-5,0.0); + //Cf[1]->SetParameters(1.284e-5,0.0); + Cseed[0] = 0.125; Cseed[1] = 0.122; } @@ -404,12 +549,16 @@ int TpcLaminationFitting::fitLaminations() TGraph *gr = new TGraph(); TGraph *proj = new TGraph(); - //m_fLamination[l][s]->SetParameters(-0.022 + m_laminationCenter[l][s], 4.595 * seedScale, 0.138); - //m_fLamination[l][s]->SetParameters(-0.022 + m_laminationCenter[l][s], log(4.595 * seedScale/(-0.022 + m_laminationCenter[l][s])), 0.138); - //m_fLamination[l][s]->SetParameters(-0.011 + m_laminationCenter[l][s], 0.025, 0.16); - //m_fLamination[l][s]->SetParameters(-0.011, 30, 0.16, m_laminationCenter[l][s]); - m_fLamination[l][s]->SetParameters(Af[s]->Eval(m_ZDC_coincidence), Bf[s]->Eval(m_ZDC_coincidence), Cseed[s], m_laminationCenter[l][s]); - m_fLamination[l][s]->FixParameter(3, m_laminationCenter[l][s]); + if(m_fieldOff) + { + m_fLamination[l][s]->SetParameters(0.003, m_laminationIdeal[l][s]); + m_fLamination[l][s]->FixParameter(1, m_laminationIdeal[l][s]); + } + else + { + m_fLamination[l][s]->SetParameters(Af[s]->Eval(m_ZDC_coincidence), Bf[s]->Eval(m_ZDC_coincidence), Cseed[s], m_laminationIdeal[l][s] + m_laminationOffset[l][s]); + m_fLamination[l][s]->FixParameter(3, m_laminationIdeal[l][s] + m_laminationOffset[l][s]); + } TF1 *fitSeed = (TF1 *) m_fLamination[l][s]->Clone(); fitSeed->SetName((boost::format("fitSeed%d_%s") %l %(s == 1 ? "North" : "South")).str().c_str()); @@ -448,7 +597,7 @@ int TpcLaminationFitting::fitLaminations() { double phi = m_hLamination[l][s]->GetYaxis()->GetBinCenter(j); - if (fabs(phi - m_laminationCenter[l][s]) > 0.05) + if (fabs(phi - m_laminationIdeal[l][s]) > 0.05) { continue; } @@ -485,6 +634,7 @@ int TpcLaminationFitting::fitLaminations() double distToFunc = 0.0; int nBinsUsed = 0; + int nBinsUsed_R_lt_45 = 0; for (int i = 1; i <= m_hLamination[l][s]->GetNbinsX(); i++) { @@ -510,6 +660,10 @@ int TpcLaminationFitting::fitLaminations() { distToFunc += j; nBinsUsed++; + if(R < 45.0) + { + nBinsUsed_R_lt_45++; + } break; } } @@ -517,7 +671,7 @@ int TpcLaminationFitting::fitLaminations() m_distanceToFit[l][s] = distToFunc / nBinsUsed; m_nBinsFit[l][s] = nBinsUsed; - if (nBinsUsed < 10 || distToFunc / nBinsUsed > 1.0) + if (nBinsUsed < 10 || distToFunc / nBinsUsed > 1.0 || nBinsUsed_R_lt_45 < 5) { m_laminationGoodFit[l][s] = false; } @@ -531,14 +685,8 @@ int TpcLaminationFitting::fitLaminations() return Fun4AllReturnCodes::EVENT_OK; } -int TpcLaminationFitting::InterpolatePhiDistortions(TH2 *simPhiDistortion[2]) +int TpcLaminationFitting::InterpolatePhiDistortions() { - phiDistortionLamination[0] = (TH2 *) simPhiDistortion[0]->Clone(); - phiDistortionLamination[0]->Reset(); - phiDistortionLamination[0]->SetName("phiDistortionLamination0"); - phiDistortionLamination[1] = (TH2 *) simPhiDistortion[1]->Clone(); - phiDistortionLamination[1]->Reset(); - phiDistortionLamination[1]->SetName("phiDistortionLamination1"); for (int s = 0; s < 2; s++) { @@ -566,51 +714,31 @@ int TpcLaminationFitting::InterpolatePhiDistortions(TH2 *simPhiDistortion[2]) phi -= 2 * M_PI; } int phiBin = phiDistortionLamination[s]->GetXaxis()->FindBin(phi); - //m_fLamination[l][s]->SetParameter(0, m_fLamination[l][s]->GetParameter(0) - m_laminationCenter[l][s]); - m_fLamination[l][s]->SetParameter(3, m_laminationOffset[l][s]); - /* - if(s==0) - { - m_fLamination[l][s]->SetParameter(3, 0.0); - } + if(m_fieldOff) + { + m_fLamination[l][s]->SetParameter(1, 0.0); + } else - { - m_fLamination[l][s]->SetParameter(3, 0.0); - } - */ - //m_fLamination[l][s]->SetParameter(3, 0.0); + { + //m_fLamination[l][s]->SetParameter(3, -1.0*m_laminationOffset[l][s]); + m_fLamination[l][s]->SetParameter(3, 0.0); + } double phiDistortion = R * m_fLamination[l][s]->Integral(phiDistortionLamination[s]->GetYaxis()->GetBinLowEdge(i), phiDistortionLamination[s]->GetYaxis()->GetBinLowEdge(i + 1)) / (phiDistortionLamination[s]->GetYaxis()->GetBinLowEdge(i + 1) - phiDistortionLamination[s]->GetYaxis()->GetBinLowEdge(i)); - //m_fLamination[l][s]->SetParameter(0, m_fLamination[l][s]->GetParameter(0) + m_laminationCenter[l][s]); - m_fLamination[l][s]->SetParameter(3, m_laminationCenter[l][s]); + if(m_fieldOff) + { + m_fLamination[l][s]->SetParameter(1, m_laminationIdeal[l][s]); + } + else + { + //m_fLamination[l][s]->SetParameter(3, m_laminationIdeal[l][s]); + m_fLamination[l][s]->SetParameter(3, m_laminationIdeal[l][s] + m_laminationOffset[l][s]); + } phiDistortionLamination[s]->SetBinContent(phiBin, i, phiDistortion); + m_dcc_out->m_hDPint[s]->SetBinContent(phiBin, i, phiDistortion); } } } - for (int s = 0; s < 2; s++) - { - m_dcc_out->m_hDPint[s] = (TH2 *) phiDistortionLamination[s]->Clone(); - m_dcc_out->m_hDPint[s]->SetName((boost::format("hIntDistortionP%s") %(s == 0 ? "_negz" : "_posz")).str().c_str()); - } - - /* - for(int s=0; s<2; s++) - { - for(int i=1; i<=m_dcc_out->m_hDPint[s]->GetNbinsX(); i++) - { - for(int j=1; j<=m_dcc_out->m_hDPint[s]->GetNbinsY(); j++) - { - if(phiDistortionLamination[s]->GetBinContent(i,j) != 0.0) - { - m_dcc_out->m_hDPint[s]->SetBinContent(i,j, phiDistortionLamination[s]->GetBinContent(i,j)); - } - } - } - } - */ - - // m_dcc_out->m_hDPint[0] = (TH2*)phiDistortionLamination[0]->Clone(); - // m_dcc_out->m_hDPint[1] = (TH2*)phiDistortionLamination[1]->Clone(); for (int s = 0; s < 2; s++) { @@ -629,17 +757,14 @@ int TpcLaminationFitting::InterpolatePhiDistortions(TH2 *simPhiDistortion[2]) laminationPhiBins.push_back(j); } } - if (laminationPhiBins.size() > 1) { laminationPhiBins.push_back(laminationPhiBins[0]); } - for (int lamPair = 0; lamPair < (int) laminationPhiBins.size() - 1; lamPair++) { double dist0 = m_dcc_out->m_hDPint[s]->GetBinContent(laminationPhiBins[lamPair], i); double dist1 = m_dcc_out->m_hDPint[s]->GetBinContent(laminationPhiBins[lamPair + 1], i); - int nEmptyBins = laminationPhiBins[lamPair + 1] - laminationPhiBins[lamPair] - 1; if (laminationPhiBins[lamPair] > laminationPhiBins[lamPair + 1]) { @@ -650,7 +775,6 @@ int TpcLaminationFitting::InterpolatePhiDistortions(TH2 *simPhiDistortion[2]) bool wrap = false; int wrapBin = -1; for (int j = 1; j <= nEmptyBins; j++) - // for(int j=+ 1; j m_dcc_out->m_hDPint[s]->GetNbinsX() - 1) { @@ -674,6 +798,141 @@ int TpcLaminationFitting::InterpolatePhiDistortions(TH2 *simPhiDistortion[2]) return Fun4AllReturnCodes::EVENT_OK; } +int TpcLaminationFitting::doGlobalRMatching(int side) +{ + + std::vector distortedPhi; + TF1 *tmpLamFit = (TF1*)m_fLamination[0][side]->Clone(); + + if(m_fieldOff) + { + tmpLamFit->SetParameters(0.0, 0.0); + } + else + { + double meanA = 0.0; + double meanB = 0.0; + double meanC = 0.0; + double meanOffset = 0.0; + int nGoodFits = 0; + for(int l = 0; l < 18; l++) + { + if(!m_laminationGoodFit[l][side]) + { + continue; + } + meanA += m_fLamination[l][side]->GetParameter(0); + meanB += m_fLamination[l][side]->GetParameter(1); + meanC += m_fLamination[l][side]->GetParameter(2); + meanOffset += m_laminationOffset[l][side]; + nGoodFits++; + } + if(nGoodFits == 0) + { + return Fun4AllReturnCodes::EVENT_OK; + } + + meanA /= nGoodFits; + meanB /= nGoodFits; + meanC /= nGoodFits; + meanOffset /= nGoodFits; + //tmpLamFit->SetParameters(meanA, meanB, meanC, meanOffset); + tmpLamFit->SetParameters(meanA, meanB, meanC, 0.0); + } + + + for(int i=0; i<(int)m_truthPhi[side].size(); i++) + { + double distortedPhiTmp = m_truthPhi[side][i] + tmpLamFit->Eval(m_truthR[side][i]); + while(distortedPhiTmp < m_phiModMin[side]) + { + distortedPhiTmp += M_PI / 9; + } + while(distortedPhiTmp > m_phiModMax[side]) + { + distortedPhiTmp -= M_PI / 9; + } + distortedPhi.push_back(distortedPhiTmp); + } + + double maxSum = 0.0; + double best_m = 0.0; + double best_b = 0.0; + int mStep = 0; + int bStep = 0; + for(double m = -0.02; m<=0.02; m+=0.001) + { + for(double b=-3.0; b<=3.0; b+=0.125) + { + double sum = 0.0; + for(int i=0; i<(int)m_truthR[side].size(); i++) + { + double distortedTruthR = (m_truthR[side][i] + b)/(1.0 - m); + int binR = m_hPetal[side]->GetYaxis()->FindBin(distortedTruthR); + int binPhi = m_hPetal[side]->GetXaxis()->FindBin(distortedPhi[i]); + for(int j=-2; j<=2; j++) + { + int neighborBinR = binR + j; + if(neighborBinR < 1 || neighborBinR > m_hPetal[side]->GetNbinsY()) continue; + for(int k=-5; k<=5; k++) + { + int neighborBinPhi = binPhi + k; + if(neighborBinPhi < 1) + { + neighborBinPhi += m_hPetal[side]->GetNbinsX(); + } + if(neighborBinPhi > m_hPetal[side]->GetNbinsX()) + { + neighborBinPhi -= m_hPetal[side]->GetNbinsX(); + } + sum += m_hPetal[side]->GetBinContent(neighborBinPhi, neighborBinR); + } + } + } + std::cout << "working on side " << side << " m step " << mStep << " b step " << bStep << " with m = " << m << " and b = " << b << " with sum = " << sum << std::endl; + + m_parameterScan[side]->Fill(m, b, sum); + + if(sum > maxSum) + { + maxSum = sum; + best_m = m; + best_b = b; + } + bStep++; + } + mStep++; + } + + std::cout << "Best R distortion for side " << side << " is m = " << best_m << " and b = " << best_b << " with sum of " << maxSum << std::endl; + + for(int j=2; j<=m_dcc_out->m_hDRint[side]->GetNbinsX()-1; j++) + { + for(int i=2; i<=m_dcc_out->m_hDRint[side]->GetNbinsY()-1; i++) + { + double R = m_dcc_out->m_hDRint[side]->GetYaxis()->GetBinCenter(i); + double distortionR = R * best_m + best_b; + m_dcc_out->m_hDRint[side]->SetBinContent(j, i, distortionR); + } + } + + std::vector bestDistortedR; + for(int i=0; i<(int)m_truthR[side].size(); i++) + { + double distortedR = (m_truthR[side][i] + best_b)/(1.0 - best_m); + bestDistortedR.push_back(distortedR); + } + + m_bestRMatch[side] = new TGraph(distortedPhi.size(), &distortedPhi[0], &bestDistortedR[0]); + m_bestRMatch[side]->SetTitle((boost::format("Best R matching TPC %s, m = %.3f b = %.3f") %(side == 0 ? "South" : "North") %best_m %best_b).str().c_str()); + m_bestRMatch[side]->SetName((boost::format("bestRMatch_side%d") %side).str().c_str()); + m_bestRMatch[side]->SetMarkerStyle(25); + m_bestRMatch[side]->SetMarkerSize(0.8); + m_bestRMatch[side]->SetMarkerColor(kRed); + + return Fun4AllReturnCodes::EVENT_OK; +} + int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) { @@ -735,19 +994,55 @@ int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) } m_fLamination[l][s]->Draw("same"); - TLine *line = new TLine(30,m_laminationCenter[l][s],80,m_laminationCenter[l][s]); - line->SetLineColor(kBlue); - line->SetLineStyle(2); - line->Draw("same"); + TLegend *leg = new TLegend(0.15,0.15,0.45,0.4); + + TLine *lineIdeal; + TLine *lineOffset; + if(m_fieldOff) + { + lineIdeal = new TLine(30,m_laminationIdeal[l][s],80,m_laminationIdeal[l][s]); + lineIdeal->SetLineColor(kBlue); + leg->AddEntry(lineIdeal,Form("#phi_{ideal}=%.6f",m_laminationIdeal[l][s]), "l"); + } + else + { + lineIdeal = new TLine(30,m_laminationIdeal[l][s],80,m_laminationIdeal[l][s]); + lineIdeal->SetLineColor(kBlue); + leg->AddEntry(lineIdeal,Form("#phi_{ideal}=%.6f",m_laminationIdeal[l][s]), "l"); + + lineOffset = new TLine(30,m_laminationIdeal[l][s]+m_laminationOffset[l][s],80,m_laminationIdeal[l][s]+m_laminationOffset[l][s]); + lineOffset->SetLineColor(kGreen+2); + lineOffset->SetLineStyle(2); + leg->AddEntry(lineOffset,Form("#phi_{ideal}+#phi_{offset}=%.6f",m_laminationOffset[l][s]), "l"); + lineOffset->Draw("same"); + } + lineIdeal->Draw("same"); + + leg->Draw("same"); + + TPaveText *pars = new TPaveText(0.6, 0.55, 0.85, 0.85, "NDC"); - pars->AddText("#phi = #phi_{ideal} + A#times (1 - e^{-C#times (R - B)})"); - pars->AddText((boost::format("A=%.3f#pm %.3f") %m_fLamination[l][s]->GetParameter(0) %m_fLamination[l][s]->GetParError(0)).str().c_str()); - pars->AddText((boost::format("#phi_{ideal}=%.3f#pm %.3f") %m_fLamination[l][s]->GetParameter(3) %m_fLamination[l][s]->GetParError(3)).str().c_str()); - pars->AddText((boost::format("B=%.3f#pm %.3f") %m_fLamination[l][s]->GetParameter(1) %m_fLamination[l][s]->GetParError(1)).str().c_str()); - pars->AddText((boost::format("C=%.3f#pm %.3f") %m_fLamination[l][s]->GetParameter(2) %m_fLamination[l][s]->GetParError(2)).str().c_str()); - pars->AddText((boost::format("Distance to line=%.2f") %m_distanceToFit[l][s]).str().c_str()); - pars->AddText((boost::format("Number of Bins used=%d") %m_nBinsFit[l][s]).str().c_str()); + if(m_fieldOff) + { + pars->AddText("#phi = #phi_{ideal} + #phi_{offset}"); + pars->AddText((boost::format("#phi_{ideal}=%.3f#pm %.3f") %m_fLamination[l][s]->GetParameter(1) %m_fLamination[l][s]->GetParError(1)).str().c_str()); + pars->AddText((boost::format("#phi_{offset}=%.3f#pm %.3f") %m_fLamination[l][s]->GetParameter(0) %m_fLamination[l][s]->GetParError(0)).str().c_str()); + pars->AddText((boost::format("Distance to line=%.2f") %m_distanceToFit[l][s]).str().c_str()); + pars->AddText((boost::format("Number of Bins used=%d") %m_nBinsFit[l][s]).str().c_str()); + } + else + { + pars->AddText("#phi = #phi_{ideal} + A#times (1 - e^{-C#times (R - B)})"); + pars->AddText((boost::format("A=%.3f#pm %.3f") %m_fLamination[l][s]->GetParameter(0) %m_fLamination[l][s]->GetParError(0)).str().c_str()); + //pars->AddText((boost::format("#phi_{ideal}=%.3f#pm 0.000") %m_laminationIdeal[l][s]).str().c_str()); + pars->AddText((boost::format("#phi_{nominal}=%.3f#pm 0.000") %(m_laminationIdeal[l][s]+m_laminationOffset[l][s])).str().c_str()); + //pars->AddText((boost::format("#phi_{offset}=%.3f#pm 0.000") %m_laminationOffset[l][s]).str().c_str()); + pars->AddText((boost::format("B=%.3f#pm %.3f") %m_fLamination[l][s]->GetParameter(1) %m_fLamination[l][s]->GetParError(1)).str().c_str()); + pars->AddText((boost::format("C=%.3f#pm %.3f") %m_fLamination[l][s]->GetParameter(2) %m_fLamination[l][s]->GetParError(2)).str().c_str()); + pars->AddText((boost::format("Distance to line=%.2f") %m_distanceToFit[l][s]).str().c_str()); + pars->AddText((boost::format("Number of Bins used=%d") %m_nBinsFit[l][s]).str().c_str()); + } pars->Draw("same"); c1->SaveAs(m_QAFileName.c_str()); } @@ -755,22 +1050,23 @@ int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) c1->SaveAs((boost::format("%s]") %m_QAFileName).str().c_str()); } - TFile *simDistortion = new TFile("/cvmfs/sphenix.sdcc.bnl.gov/gcc-12.1.0/release/release_new/new.10/share/calibrations/distortion_maps/average_minus_static_distortion_inverted_10-new.root", "READ"); - TH3 *hIntDistortionP_posz = (TH3 *) simDistortion->Get("hIntDistortionP_posz"); - hIntDistortionP_posz->GetZaxis()->SetRange(2, 2); - TH2 *simPhiDistortion[2]; - simPhiDistortion[1] = (TH2 *) hIntDistortionP_posz->Project3D("yx"); - TH3 *hIntDistortionP_negz = (TH3 *) simDistortion->Get("hIntDistortionP_negz"); - hIntDistortionP_negz->GetZaxis()->SetRange(hIntDistortionP_negz->GetNbinsZ() - 1, hIntDistortionP_negz->GetNbinsZ() - 1); - simPhiDistortion[0] = (TH2 *) hIntDistortionP_negz->Project3D("yx"); - - int interpolateSuccess = InterpolatePhiDistortions(simPhiDistortion); + //TFile *simDistortion = new TFile("/cvmfs/sphenix.sdcc.bnl.gov/gcc-12.1.0/release/release_new/new.10/share/calibrations/distortion_maps/average_minus_static_distortion_inverted_10-new.root", "READ"); + //TH3 *hIntDistortionP_posz = (TH3 *) simDistortion->Get("hIntDistortionP_posz"); + //hIntDistortionP_posz->GetZaxis()->SetRange(2, 2); + //TH2 *simPhiDistortion[2]; + //simPhiDistortion[1] = (TH2 *) hIntDistortionP_posz->Project3D("yx"); + //TH3 *hIntDistortionP_negz = (TH3 *) simDistortion->Get("hIntDistortionP_negz"); + //hIntDistortionP_negz->GetZaxis()->SetRange(hIntDistortionP_negz->GetNbinsZ() - 1, hIntDistortionP_negz->GetNbinsZ() - 1); + //simPhiDistortion[0] = (TH2 *) hIntDistortionP_negz->Project3D("yx"); + + int interpolateSuccess = InterpolatePhiDistortions(); if (interpolateSuccess != Fun4AllReturnCodes::EVENT_OK) { std::cout << PHWHERE << " Return code for lamination interpolation was " << interpolateSuccess << " and not successful" << std::endl; return Fun4AllReturnCodes::ABORTRUN; } + /* for (int s = 0; s < 2; s++) { scaleFactorMap[s] = (TH2 *) m_dcc_out->m_hDPint[s]->Clone(); @@ -785,9 +1081,18 @@ int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) TH3 *hIntDistortionR_negz = (TH3 *) simDistortion->Get("hIntDistortionR_negz"); hIntDistortionR_negz->GetZaxis()->SetRange(hIntDistortionR_negz->GetNbinsZ() - 1, hIntDistortionR_negz->GetNbinsZ() - 1); simRDistortion[0] = (TH2 *) hIntDistortionR_negz->Project3D("yx"); + */ + + for (int s = 0; s < 2; s++) { + int RMatchingSuccess = doGlobalRMatching(s); + if (RMatchingSuccess != Fun4AllReturnCodes::EVENT_OK) + { + std::cout << PHWHERE << " Return code for doGlobalRMatching was " << RMatchingSuccess << " and not successful" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } /* for(int i=1; i<=m_dcc_out->m_hDRint[s]->GetNbinsX(); i++) { @@ -800,10 +1105,11 @@ int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) } } */ - m_dcc_out->m_hDRint[s] = (TH2 *) simRDistortion[s]->Clone(); - m_dcc_out->m_hDRint[s]->SetName((boost::format("hIntDistortionR%s") %(s == 0 ? "_negz" : "_posz")).str().c_str()); - m_dcc_out->m_hDRint[s]->Multiply(scaleFactorMap[s]); + //m_dcc_out->m_hDRint[s] = (TH2 *) simRDistortion[s]->Clone(); + //m_dcc_out->m_hDRint[s]->SetName((boost::format("hIntDistortionR%s") %(s == 0 ? "_negz" : "_posz")).str().c_str()); + //m_dcc_out->m_hDRint[s]->Multiply(scaleFactorMap[s]); } + fill_guarding_bins(m_dcc_out); @@ -815,14 +1121,27 @@ int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) { m_side = s; m_lamIndex = s*18 + l; - m_lamPhi = m_laminationCenter[l][s]; + m_lamPhi = m_laminationIdeal[l][s]; + m_lamShift = m_laminationOffset[l][s]; m_goodFit = m_laminationGoodFit[l][s]; - m_A = m_fLamination[l][s]->GetParameter(0); - m_B = m_fLamination[l][s]->GetParameter(1); - m_C = m_fLamination[l][s]->GetParameter(2); - m_A_err = m_fLamination[l][s]->GetParError(0); - m_B_err = m_fLamination[l][s]->GetParError(1); - m_C_err = m_fLamination[l][s]->GetParError(2); + if(m_fieldOff) + { + m_A = m_fLamination[l][s]->GetParameter(0); + m_A_err = m_fLamination[l][s]->GetParError(0); + m_B = -999; + m_B_err = -999; + m_C = -999; + m_C_err = -999; + } + else + { + m_A = m_fLamination[l][s]->GetParameter(0); + m_B = m_fLamination[l][s]->GetParameter(1); + m_C = m_fLamination[l][s]->GetParameter(2); + m_A_err = m_fLamination[l][s]->GetParError(0); + m_B_err = m_fLamination[l][s]->GetParError(1); + m_C_err = m_fLamination[l][s]->GetParError(2); + } m_dist = m_distanceToFit[l][s]; m_nBins = m_nBinsFit[l][s]; m_laminationTree->Fill(); @@ -841,7 +1160,10 @@ int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) } } phiDistortionLamination[s]->Write(); - scaleFactorMap[s]->Write(); + //scaleFactorMap[s]->Write(); + m_hPetal[s]->Write(); + m_bestRMatch[s]->Write(); + m_parameterScan[s]->Write(); } m_laminationTree->Write(); @@ -860,7 +1182,7 @@ void TpcLaminationFitting::fill_guarding_bins(TpcDistortionCorrectionContainer * { for (int s = 0; s < 2; s++) { - for (const auto &h : {dcc->m_hDRint[s], dcc->m_hDPint[s]}) + for (const auto &h : {dcc->m_hDPint[s], dcc->m_hDRint[s]}) { const auto phibins = h->GetNbinsX(); const auto rbins = h->GetNbinsY(); diff --git a/offline/packages/tpccalib/TpcLaminationFitting.h b/offline/packages/tpccalib/TpcLaminationFitting.h index 73d77533d3..a44160ca02 100644 --- a/offline/packages/tpccalib/TpcLaminationFitting.h +++ b/offline/packages/tpccalib/TpcLaminationFitting.h @@ -44,7 +44,9 @@ class TpcLaminationFitting : public SubsysReco } void set_ppMode(bool mode){ ppMode = mode; } - + + void set_fieldOff(bool fieldOff){ m_fieldOff = fieldOff; } + void set_grid_dimensions(int phibins, int rbins); void set_nLayerCut(unsigned int cut) { m_nLayerCut = cut; } @@ -61,7 +63,8 @@ class TpcLaminationFitting : public SubsysReco int GetNodes(PHCompositeNode *topNode); int fitLaminations(); - int InterpolatePhiDistortions(TH2 *simPhiDistortion[2]); + int InterpolatePhiDistortions(); + int doGlobalRMatching(int side); void fill_guarding_bins(TpcDistortionCorrectionContainer *dcc); TpcDistortionCorrection m_distortionCorrection; @@ -78,12 +81,20 @@ class TpcLaminationFitting : public SubsysReco TH2 *m_hLamination[18][2]{{nullptr}}; TF1 *m_fLamination[18][2]{{nullptr}}; - double m_laminationCenter[18][2]{{0.0}}; + double m_laminationIdeal[18][2]{{0.0}}; + //double m_laminationCenter[18][2]{{0.0}}; double m_laminationOffset[18][2]{{0.0}}; + //double m_laminationOffset{0.00337078}; + //double m_laminationOffset{0.002775}; bool m_laminationGoodFit[18][2]{{false}}; double m_distanceToFit[18][2]{{0.0}}; int m_nBinsFit[18][2]{{0}}; + TH2 *m_hPetal[2]{nullptr}; + TGraph *m_bestRMatch[2]{nullptr}; + TH2 *m_parameterScan[2]{nullptr}; + + TH2 *phiDistortionLamination[2]{nullptr}; TH2 *scaleFactorMap[2]{nullptr}; @@ -103,10 +114,13 @@ class TpcLaminationFitting : public SubsysReco //std::map m_run_ZDC_map_pp; //std::map m_run_ZDC_map_auau; + bool m_fieldOff{false}; + TTree *m_laminationTree{nullptr}; bool m_side{false}; int m_lamIndex{0}; double m_lamPhi{0}; + double m_lamShift{0}; bool m_goodFit{false}; double m_A{0}; double m_B{0}; @@ -117,13 +131,35 @@ class TpcLaminationFitting : public SubsysReco double m_dist{0}; int m_nBins{0}; - int m_phibins{24}; + int m_phibins{80}; static constexpr float m_phiMin{0}; static constexpr float m_phiMax{2. * M_PI}; - int m_rbins{12}; + int m_rbins{52}; static constexpr float m_rMin{20}; // cm static constexpr float m_rMax{80}; // cm + + /* + const int nRadii{8}; + const int nStripes[4]{6,6,8,12}; + const int nPads[4]{96,96,128,192}; + const double RValues[4][8] = {{22.70902789, 23.84100043, 24.97297296, 26.1049455, 27.23691804, 28.36889058, 29.50086312, 30.63283566},{31.7648082, 32.89678074, 34.02875328, 35.16072582, 36.29269836, 37.4246709, 38.55664344, 39.68861597},{42.1705532, 44.2119258, 46.2532984, 48.29467608, 50.336069, 52.3774416, 54.4188015, 56.4601868},{59.46048725, 61.6545823, 63.84867738, 66.04277246, 68.23686754, 70.43096262, 72.6250577, 74.81915277}}; + + const int keepThisAndAfter[8]{1,0,1,0,1,0,1,0}; + const int keepUntil[4][8]{{4,4,5,4,5,5,5,5},{5,5,6,5,6,5,6,5},{7,7,8,7,8,8,8,8},{11,10,11,11,11,11,12,11}}; + + const double phi_petal = M_PI/6.0; + const int pr_mult = 3; + const int dw_mult = 8; + const double diffwidth = 0.06; + const double adjust = 0.015; + */ + + std::vector m_truthR[2]; + std::vector m_truthPhi[2]; + + double m_phiModMin[2]{-M_PI/18, 0.0}; + double m_phiModMax[2]{M_PI/18, M_PI/9}; }; #endif From 67423a3fe8df962d45028aaf31bd5fb99066a974 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Tue, 6 Jan 2026 15:17:57 -0500 Subject: [PATCH 007/393] clang-format --- offline/packages/trackreco/PHActsTrkFitter.cc | 299 +++++++++--------- offline/packages/trackreco/PHActsTrkFitter.h | 39 ++- 2 files changed, 176 insertions(+), 162 deletions(-) diff --git a/offline/packages/trackreco/PHActsTrkFitter.cc b/offline/packages/trackreco/PHActsTrkFitter.cc index a26ee1fa0a..f66767d305 100644 --- a/offline/packages/trackreco/PHActsTrkFitter.cc +++ b/offline/packages/trackreco/PHActsTrkFitter.cc @@ -5,7 +5,6 @@ * \author Tony Frawley */ - #include "PHActsTrkFitter.h" #include "ActsPropagator.h" @@ -25,7 +24,7 @@ #include #include #include -//#include +// #include #include #include #include @@ -134,8 +133,8 @@ int PHActsTrkFitter::InitRun(PHCompositeNode* topNode) MaterialSurfaceSelector selector; if (m_fitSiliconMMs || m_directNavigation) { - m_tGeometry->geometry().tGeometry->visitSurfaces(selector,false); - //std::cout<<"selector.surfaces.size() "<geometry().tGeometry->visitSurfaces(selector, false); + // std::cout<<"selector.surfaces.size() "<(m_evalname); m_evaluator->Init(topNode); - if(m_actsEvaluator && !m_simActsEvaluator) + if (m_actsEvaluator && !m_simActsEvaluator) { m_evaluator->isData(); } @@ -182,10 +181,10 @@ int PHActsTrkFitter::InitRun(PHCompositeNode* topNode) _tpccellgeo = findNode::getClass(topNode, "TPCGEOMCONTAINER"); if (!_tpccellgeo) - { - std::cout << PHWHERE << " unable to find DST node TPCGEOMCONTAINER" << std::endl; - return Fun4AllReturnCodes::ABORTRUN; - } + { + std::cout << PHWHERE << " unable to find DST node TPCGEOMCONTAINER" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } if (Verbosity() > 1) { @@ -287,7 +286,7 @@ int PHActsTrkFitter::End(PHCompositeNode* /*topNode*/) { m_evaluator->End(); } - if(m_useOutlierFinder) + if (m_useOutlierFinder) { m_outlierFinder.Write(); } @@ -314,44 +313,43 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) // capture the input crossing value, and set crossing parameters //============================== - short silicon_crossing = SHRT_MAX; + short silicon_crossing = SHRT_MAX; auto siseed = m_siliconSeeds->get(siid); - if(siseed) - { - silicon_crossing = siseed->get_crossing(); - } + if (siseed) + { + silicon_crossing = siseed->get_crossing(); + } short crossing = silicon_crossing; short int crossing_estimate = crossing; - if(m_enable_crossing_estimate) - { - crossing_estimate = track->get_crossing_estimate(); // geometric crossing estimate from matcher - } + if (m_enable_crossing_estimate) + { + crossing_estimate = track->get_crossing_estimate(); // geometric crossing estimate from matcher + } //=============================== - // must have silicon seed with valid crossing if we are doing a SC calibration fit if (m_fitSiliconMMs) + { + if ((siid == std::numeric_limits::max()) || (silicon_crossing == SHRT_MAX)) { - if( (siid == std::numeric_limits::max()) || (silicon_crossing == SHRT_MAX)) - { - continue; - } + continue; } + } // do not skip TPC only tracks, just set crossing to the nominal zero - if(!siseed) - { - crossing = 0; - } + if (!siseed) + { + crossing = 0; + } if (Verbosity() > 1) { - if(siseed) - { - std::cout << "tpc and si id " << tpcid << ", " << siid << " silicon_crossing " << silicon_crossing - << " crossing " << crossing << " crossing estimate " << crossing_estimate << std::endl; - } + if (siseed) + { + std::cout << "tpc and si id " << tpcid << ", " << siid << " silicon_crossing " << silicon_crossing + << " crossing " << crossing << " crossing estimate " << crossing_estimate << std::endl; + } } auto tpcseed = m_tpcSeeds->get(tpcid); @@ -381,7 +379,7 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) if (Verbosity() > 1 && siseed) { std::cout << " m_pp_mode " << m_pp_mode << " m_enable_crossing_estimate " << m_enable_crossing_estimate - << " INTT crossing " << crossing << " crossing_estimate " << crossing_estimate << std::endl; + << " INTT crossing " << crossing << " crossing_estimate " << crossing_estimate << std::endl; } short int this_crossing = crossing; @@ -390,35 +388,35 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) std::vector chisq_ndf; std::vector svtx_vec; - if(m_pp_mode) + if (m_pp_mode) + { + if (m_enable_crossing_estimate && crossing == SHRT_MAX) + { + // this only happens if there is a silicon seed but no assigned INTT crossing, and only in pp_mode + // If there is no INTT crossing, start with the crossing_estimate value, vary up and down, fit, and choose the best chisq/ndf + use_estimate = true; + nvary = max_bunch_search; + if (Verbosity() > 1) + { + std::cout << " No INTT crossing: use crossing_estimate " << crossing_estimate << " with nvary " << nvary << std::endl; + } + } + else { - if (m_enable_crossing_estimate && crossing == SHRT_MAX) - { - // this only happens if there is a silicon seed but no assigned INTT crossing, and only in pp_mode - // If there is no INTT crossing, start with the crossing_estimate value, vary up and down, fit, and choose the best chisq/ndf - use_estimate = true; - nvary = max_bunch_search; - if (Verbosity() > 1) - { - std::cout << " No INTT crossing: use crossing_estimate " << crossing_estimate << " with nvary " << nvary << std::endl; - } - } - else - { - // use INTT crossing - crossing_estimate = crossing; - } + // use INTT crossing + crossing_estimate = crossing; } + } else + { + // non pp mode, we want only crossing zero, veto others + if (siseed && silicon_crossing != 0) { - // non pp mode, we want only crossing zero, veto others - if(siseed && silicon_crossing != 0) - { - crossing = 0; - //continue; - } - crossing_estimate = crossing; + crossing = 0; + // continue; } + crossing_estimate = crossing; + } // Fit this track assuming either: // crossing = INTT value, if it exists (uses nvary = 0) @@ -441,16 +439,16 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) makeSourceLinks.initialize(_tpccellgeo); makeSourceLinks.setVerbosity(Verbosity()); makeSourceLinks.set_pp_mode(m_pp_mode); - for(const auto& layer : m_ignoreLayer) + for (const auto& layer : m_ignoreLayer) { makeSourceLinks.ignoreLayer(layer); } // loop over modifiedTransformSet and replace transient elements modified for the previous track with the default transforms // does nothing if m_transient_id_set is empty makeSourceLinks.resetTransientTransformMap( - m_alignmentTransformationMapTransient, - m_transient_id_set, - m_tGeometry); + m_alignmentTransformationMapTransient, + m_transient_id_set, + m_tGeometry); if (m_use_clustermover) { @@ -459,37 +457,56 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) { // silicon source links sourceLinks = makeSourceLinks.getSourceLinksClusterMover( - siseed, + siseed, + measurements, + m_clusterContainer, + m_tGeometry, + m_globalPositionWrapper, + this_crossing); + } + + // tpc source links + const auto tpcSourceLinks = makeSourceLinks.getSourceLinksClusterMover( + tpcseed, measurements, m_clusterContainer, m_tGeometry, m_globalPositionWrapper, this_crossing); - } - - // tpc source links - const auto tpcSourceLinks = makeSourceLinks.getSourceLinksClusterMover( - tpcseed, - measurements, - m_clusterContainer, - m_tGeometry, - m_globalPositionWrapper, - this_crossing); // add tpc sourcelinks to silicon source links sourceLinks.insert(sourceLinks.end(), tpcSourceLinks.begin(), tpcSourceLinks.end()); - - } else { - + } + else + { // make source links using transient transforms for distortion corrections - if(Verbosity() > 1) - { std::cout << "Calling getSourceLinks for si seed, siid " << siid << " and tpcid " << tpcid << std::endl; } + if (Verbosity() > 1) + { + std::cout << "Calling getSourceLinks for si seed, siid " << siid << " and tpcid " << tpcid << std::endl; + } if (siseed && !m_ignoreSilicon) { // silicon source links sourceLinks = makeSourceLinks.getSourceLinks( - siseed, + siseed, + measurements, + m_clusterContainer, + m_tGeometry, + m_globalPositionWrapper, + m_alignmentTransformationMapTransient, + m_transient_id_set, + this_crossing); + } + + if (Verbosity() > 1) + { + std::cout << "Calling getSourceLinks for tpc seed, siid " << siid << " and tpcid " << tpcid << std::endl; + } + + // tpc source links + const auto tpcSourceLinks = makeSourceLinks.getSourceLinks( + tpcseed, measurements, m_clusterContainer, m_tGeometry, @@ -497,21 +514,6 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) m_alignmentTransformationMapTransient, m_transient_id_set, this_crossing); - } - - if(Verbosity() > 1) - { std::cout << "Calling getSourceLinks for tpc seed, siid " << siid << " and tpcid " << tpcid << std::endl; } - - // tpc source links - const auto tpcSourceLinks = makeSourceLinks.getSourceLinks( - tpcseed, - measurements, - m_clusterContainer, - m_tGeometry, - m_globalPositionWrapper, - m_alignmentTransformationMapTransient, - m_transient_id_set, - this_crossing); // add tpc sourcelinks to silicon source links sourceLinks.insert(sourceLinks.end(), tpcSourceLinks.begin(), tpcSourceLinks.end()); @@ -524,15 +526,15 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) Acts::Vector3 position(0, 0, 0); if (siseed) { - position = TrackSeedHelper::get_xyz(siseed)*Acts::UnitConstants::cm; + position = TrackSeedHelper::get_xyz(siseed) * Acts::UnitConstants::cm; } - if(!siseed || !is_valid(position) || m_ignoreSilicon) + if (!siseed || !is_valid(position) || m_ignoreSilicon) { - position = TrackSeedHelper::get_xyz(tpcseed)*Acts::UnitConstants::cm; + position = TrackSeedHelper::get_xyz(tpcseed) * Acts::UnitConstants::cm; } if (!is_valid(position)) { - if(Verbosity() > 4) + if (Verbosity() > 4) { std::cout << "Invalid position of " << position.transpose() << std::endl; } @@ -559,26 +561,26 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) for (const auto& surface_apr : m_materialSurfaces) { - if(m_forceSiOnlyFit) + if (m_forceSiOnlyFit) { - if(surface_apr->geometryId().volume() >12) + if (surface_apr->geometryId().volume() > 12) { continue; } } bool pop_flag = false; - if(surface_apr->geometryId().approach() == 1) + if (surface_apr->geometryId().approach() == 1) { surfaces.push_back(surface_apr); } else { pop_flag = true; - for (const auto& surface_sns: surfaces_tmp) + for (const auto& surface_sns : surfaces_tmp) { if (surface_apr->geometryId().volume() == surface_sns->geometryId().volume()) { - if ( surface_apr->geometryId().layer()==surface_sns->geometryId().layer()) + if (surface_apr->geometryId().layer() == surface_sns->geometryId().layer()) { pop_flag = false; surfaces.push_back(surface_sns); @@ -594,9 +596,9 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) surfaces.pop_back(); pop_flag = false; } - if (surface_apr->geometryId().volume() == 12&& surface_apr->geometryId().layer()==8) + if (surface_apr->geometryId().volume() == 12 && surface_apr->geometryId().layer() == 8) { - for (const auto& surface_sns: surfaces_tmp) + for (const auto& surface_sns : surfaces_tmp) { if (14 == surface_sns->geometryId().volume()) { @@ -619,13 +621,13 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) { // make sure micromegas are in the tracks, if required if (m_useMicromegas && - std::none_of(surfaces.begin(), surfaces.end(), [this](const auto& surface) - { return m_tGeometry->maps().isMicromegasSurface(surface); })) - { - continue; + std::none_of(surfaces.begin(), surfaces.end(), [this](const auto& surface) + { return m_tGeometry->maps().isMicromegasSurface(surface); })) + { + continue; + } } } - } float px = std::numeric_limits::quiet_NaN(); float py = std::numeric_limits::quiet_NaN(); @@ -635,7 +637,7 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) float seedphi = 0; float seedtheta = 0; float seedeta = 0; - if(siseed) + if (siseed) { seedphi = siseed->get_phi(); seedtheta = siseed->get_theta(); @@ -659,7 +661,9 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) px = pt * std::cos(phi); py = pt * std::sin(phi); pz = pt * std::cosh(eta) * std::cos(theta); - } else { + } + else + { px = seedpt * std::cos(seedphi); py = seedpt * std::sin(seedphi); pz = seedpt * std::cosh(seedeta) * std::cos(seedtheta); @@ -668,14 +672,14 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) Acts::Vector3 momentum(px, py, pz); if (!is_valid(momentum)) { - if(Verbosity() > 4) + if (Verbosity() > 4) { std::cout << "Invalid momentum of " << momentum.transpose() << std::endl; } continue; } - auto pSurface = Acts::Surface::makeShared( position); + auto pSurface = Acts::Surface::makeShared(position); Acts::Vector4 actsFourPos(position(0), position(1), position(2), 10 * Acts::UnitConstants::ns); Acts::BoundSquareMatrix cov = setDefaultCovariance(); @@ -723,8 +727,10 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) auto trackStateContainer = std::make_shared(); ActsTrackFittingAlgorithm::TrackContainer tracks(trackContainer, trackStateContainer); - if(Verbosity() > 1) - { std::cout << "Calling fitTrack for track with siid " << siid << " tpcid " << tpcid << " crossing " << crossing << std::endl; } + if (Verbosity() > 1) + { + std::cout << "Calling fitTrack for track with siid " << siid << " tpcid " << tpcid << " crossing " << crossing << std::endl; + } auto result = fitTrack(sourceLinks, seed, kfOptions, surfaces, calibrator, tracks); fitTimer.stop(); @@ -761,7 +767,7 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) if (ivary != nvary) { - if(Verbosity() > 3) + if (Verbosity() > 3) { std::cout << "Skipping track fit for trial variation" << std::endl; } @@ -806,7 +812,6 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) if (getTrackFitResult(result, track, &newTrack, tracks, measurements)) { - // insert in dedicated map m_directedTrackMap->insertWithKey(&newTrack, trid); } @@ -822,11 +827,7 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) m_trackMap->insertWithKey(&newTrack, trid); } } // end insert track for normal fit - } // end case where INTT crossing is known - - - - + } // end case where INTT crossing is known } else if (!m_fitSiliconMMs) { @@ -840,7 +841,7 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) << std::endl; } } // end fit failed case - } // end ivary loop + } // end ivary loop trackTimer.stop(); auto trackTime = trackTimer.get_accumulated_time(); @@ -855,10 +856,10 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) } bool PHActsTrkFitter::getTrackFitResult( - const FitResult& fitOutput, - TrackSeed* seed, SvtxTrack* track, - const ActsTrackFittingAlgorithm::TrackContainer& tracks, - const ActsTrackFittingAlgorithm::MeasurementContainer& measurements) + const FitResult& fitOutput, + TrackSeed* seed, SvtxTrack* track, + const ActsTrackFittingAlgorithm::TrackContainer& tracks, + const ActsTrackFittingAlgorithm::MeasurementContainer& measurements) { /// Make a trajectory state for storage, which conforms to Acts track fit /// analysis tool @@ -872,12 +873,12 @@ bool PHActsTrkFitter::getTrackFitResult( // retrieve track parameters from fit result Acts::BoundTrackParameters parameters = ActsExamples::TrackParameters(outtrack.referenceSurface().getSharedPtr(), - outtrack.parameters(), outtrack.covariance(), outtrack.particleHypothesis()); + outtrack.parameters(), outtrack.covariance(), outtrack.particleHypothesis()); indexedParams.emplace( - outtrack.tipIndex(), - ActsExamples::TrackParameters{outtrack.referenceSurface().getSharedPtr(), - outtrack.parameters(), outtrack.covariance(), outtrack.particleHypothesis()}); + outtrack.tipIndex(), + ActsExamples::TrackParameters{outtrack.referenceSurface().getSharedPtr(), + outtrack.parameters(), outtrack.covariance(), outtrack.particleHypothesis()}); if (Verbosity() > 2) { @@ -948,7 +949,9 @@ ActsTrackFittingAlgorithm::TrackFitterResult PHActsTrkFitter::fitTrack( { // use direct fit for silicon MM gits or direct navigation if (m_fitSiliconMMs || m_directNavigation) - { return (*m_fitCfg.dFit)(sourceLinks, seed, kfOptions, surfSequence, calibrator, tracks); } + { + return (*m_fitCfg.dFit)(sourceLinks, seed, kfOptions, surfSequence, calibrator, tracks); + } // use full fit in all other cases return (*m_fitCfg.fit)(sourceLinks, seed, kfOptions, calibrator, tracks); @@ -986,9 +989,9 @@ SourceLinkVec PHActsTrkFitter::getSurfaceVector(const SourceLinkVec& sourceLinks } } - if(m_forceSiOnlyFit) + if (m_forceSiOnlyFit) { - if(m_tGeometry->maps().isMicromegasSurface(surf)||m_tGeometry->maps().isTpcSurface(surf)) + if (m_tGeometry->maps().isMicromegasSurface(surf) || m_tGeometry->maps().isTpcSurface(surf)) { continue; } @@ -1059,10 +1062,10 @@ void PHActsTrkFitter::checkSurfaceVec(SurfacePtrVec& surfaces) const } void PHActsTrkFitter::updateSvtxTrack( - const std::vector& tips, - const Trajectory::IndexedParameters& paramsMap, - const ActsTrackFittingAlgorithm::TrackContainer& tracks, - SvtxTrack* track) + const std::vector& tips, + const Trajectory::IndexedParameters& paramsMap, + const ActsTrackFittingAlgorithm::TrackContainer& tracks, + SvtxTrack* track) { const auto& mj = tracks.trackStateContainer(); @@ -1133,31 +1136,37 @@ void PHActsTrkFitter::updateSvtxTrack( trackStateTimer.restart(); if (m_fillSvtxTrackStates) - { transformer.fillSvtxTrackStates(mj, trackTip, track, m_transient_geocontext); } + { + transformer.fillSvtxTrackStates(mj, trackTip, track, m_transient_geocontext); + } // in using silicon mm fit also extrapolate track parameters to all TPC surfaces with clusters // get all tpc clusters auto* seed = track->get_tpc_seed(); - if( m_fitSiliconMMs && seed ) + if (m_fitSiliconMMs && seed) { - // acts propagator ActsPropagator propagator(m_tGeometry); // loop over cluster keys associated to TPC seed - for( auto key_iter = seed->begin_cluster_keys(); key_iter != seed->end_cluster_keys(); ++key_iter ) + for (auto key_iter = seed->begin_cluster_keys(); key_iter != seed->end_cluster_keys(); ++key_iter) { const auto& cluskey = *key_iter; // make sure cluster is from TPC const auto detId = TrkrDefs::getTrkrId(cluskey); if (detId != TrkrDefs::tpcId) - { continue; } + { + continue; + } // get layer, propagate const auto layer = TrkrDefs::getLayer(cluskey); auto result = propagator.propagateTrack(params, layer); - if( !result.ok() ) { continue; } + if (!result.ok()) + { + continue; + } // get path length and extrapolated parameters auto& [pathLength, trackStateParams] = result.value(); diff --git a/offline/packages/trackreco/PHActsTrkFitter.h b/offline/packages/trackreco/PHActsTrkFitter.h index c6e0afec35..d0e221a40e 100644 --- a/offline/packages/trackreco/PHActsTrkFitter.h +++ b/offline/packages/trackreco/PHActsTrkFitter.h @@ -21,8 +21,8 @@ #include #include #include -#include #include +#include #include @@ -130,18 +130,19 @@ class PHActsTrkFitter : public SubsysReco void set_track_map_name(const std::string& map_name) { _track_map_name = map_name; } void set_svtx_seed_map_name(const std::string& map_name) { _svtx_seed_map_name = map_name; } - void set_svtx_alignment_state_map_name(const std::string& map_name) { - _svtx_alignment_state_map_name = map_name; - m_alignStates.alignmentStateMap(map_name); + void set_svtx_alignment_state_map_name(const std::string& map_name) + { + _svtx_alignment_state_map_name = map_name; + m_alignStates.alignmentStateMap(map_name); } /// Set flag for pp running void set_pp_mode(bool ispp) { m_pp_mode = ispp; } - void set_enable_geometric_crossing_estimate(bool flag) { m_enable_crossing_estimate = flag ; } + void set_enable_geometric_crossing_estimate(bool flag) { m_enable_crossing_estimate = flag; } void set_use_clustermover(bool use) { m_use_clustermover = use; } void ignoreLayer(int layer) { m_ignoreLayer.insert(layer); } - void setTrkrClusterContainerName(std::string &name){ m_clusterContainerName = name; } + void setTrkrClusterContainerName(std::string& name) { m_clusterContainerName = name; } void setDirectNavigation(bool flag) { m_directNavigation = flag; } private: @@ -155,10 +156,10 @@ class PHActsTrkFitter : public SubsysReco /// Convert the acts track fit result to an svtx track void updateSvtxTrack( - const std::vector& tips, - const Trajectory::IndexedParameters& paramsMap, - const ActsTrackFittingAlgorithm::TrackContainer& tracks, - SvtxTrack* track); + const std::vector& tips, + const Trajectory::IndexedParameters& paramsMap, + const ActsTrackFittingAlgorithm::TrackContainer& tracks, + SvtxTrack* track); /// Helper function to call either the regular navigation or direct /// navigation, depending on m_fitSiliconMMs @@ -240,7 +241,7 @@ class PHActsTrkFitter : public SubsysReco // max variation of bunch crossing away from crossing_estimate short int max_bunch_search = 2; - //name of TRKR_CLUSTER container + // name of TRKR_CLUSTER container std::string m_clusterContainerName = "TRKR_CLUSTER"; //!@name evaluator @@ -253,7 +254,7 @@ class PHActsTrkFitter : public SubsysReco //@} //! tracks -// SvtxTrackMap* m_seedTracks = nullptr; + // SvtxTrackMap* m_seedTracks = nullptr; //! tpc global position wrapper TpcGlobalPositionWrapper m_globalPositionWrapper; @@ -268,7 +269,7 @@ class PHActsTrkFitter : public SubsysReco int _n_iteration = 0; std::string _track_map_name = "SvtxTrackMap"; std::string _svtx_seed_map_name = "SvtxTrackSeedContainer"; - std::string _svtx_alignment_state_map_name = "SvtxAlignmentStateMap"; + std::string _svtx_alignment_state_map_name = "SvtxAlignmentStateMap"; /// Default particle assumption to pion unsigned int m_pHypothesis = 211; @@ -292,14 +293,18 @@ class PHActsTrkFitter : public SubsysReco std::vector m_materialSurfaces = {}; - struct MaterialSurfaceSelector { + struct MaterialSurfaceSelector + { std::vector surfaces = {}; /// @param surface is the test surface - void operator()(const Acts::Surface* surface) { - if (surface->surfaceMaterial() != nullptr) { + void operator()(const Acts::Surface* surface) + { + if (surface->surfaceMaterial() != nullptr) + { if (std::find(surfaces.begin(), surfaces.end(), surface) == - surfaces.end()) { + surfaces.end()) + { surfaces.push_back(surface); } } From 014600afcfdbfe9b29cefb45d37aaddde106f174 Mon Sep 17 00:00:00 2001 From: "Blair D. Seidlitz" Date: Tue, 6 Jan 2026 16:06:00 -0500 Subject: [PATCH 008/393] adding quality flag to total energy calc and correlations --- offline/QA/Calorimeters/CaloValid.cc | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/offline/QA/Calorimeters/CaloValid.cc b/offline/QA/Calorimeters/CaloValid.cc index bef0cf3809..8575c565b9 100644 --- a/offline/QA/Calorimeters/CaloValid.cc +++ b/offline/QA/Calorimeters/CaloValid.cc @@ -330,7 +330,10 @@ int CaloValid::process_towers(PHCompositeNode* topNode) status = status >> 1U; // clang-tidy mark 1 as unsigned } - totalcemc += offlineenergy; + if (isGood) + { + totalcemc += offlineenergy; + } h_emcaltime->Fill(_timef); if (offlineenergy > emcal_hit_threshold) { @@ -402,7 +405,10 @@ int CaloValid::process_towers(PHCompositeNode* topNode) status = status >> 1U; // clang-tidy mark 1 as unsigned } - totalihcal += offlineenergy; + if(isGood) + { + totalihcal += offlineenergy; + } h_ihcaltime->Fill(_timef); if (offlineenergy > ihcal_hit_threshold) @@ -467,7 +473,10 @@ int CaloValid::process_towers(PHCompositeNode* topNode) status = status >> 1U; // clang-tidy mark 1 as unsigned } - totalohcal += offlineenergy; + if(isGood) + { + totalohcal += offlineenergy; + } h_ohcaltime->Fill(_timef); if (offlineenergy > ohcal_hit_threshold) From 2a654bd1530246ac915364ec030134ee9363cfa4 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 6 Jan 2026 16:14:48 -0500 Subject: [PATCH 009/393] clang-tidy for PHGenFit --- .../packages/PHGenFitPkg/PHGenFit/Fitter.cc | 24 ++++----- .../packages/PHGenFitPkg/PHGenFit/Track.cc | 50 ++++++++----------- 2 files changed, 31 insertions(+), 43 deletions(-) diff --git a/offline/packages/PHGenFitPkg/PHGenFit/Fitter.cc b/offline/packages/PHGenFitPkg/PHGenFit/Fitter.cc index 8fe89b5019..127af3539e 100644 --- a/offline/packages/PHGenFitPkg/PHGenFit/Fitter.cc +++ b/offline/packages/PHGenFitPkg/PHGenFit/Fitter.cc @@ -51,9 +51,9 @@ namespace PHGenFit const std::string& /*track_rep_choice*/, const bool doEventDisplay) : verbosity(1000) + , _tgeo_manager(new TGeoManager("Default", "Geane geometry")) , _doEventDisplay(doEventDisplay) { - _tgeo_manager = new TGeoManager("Default", "Geane geometry"); TGeoManager::Import(tgeo_file_name.data()); assert(field); @@ -73,26 +73,24 @@ namespace PHGenFit } // init fitter - if (fitter_choice.compare("KalmanFitterRefTrack") == 0) + if (fitter_choice == "KalmanFitterRefTrack") { _fitter = new genfit::KalmanFitterRefTrack(); } - else if (fitter_choice.compare("KalmanFitter") == 0) -// NOLINTNEXTLINE(bugprone-branch-clone) - { + else if (fitter_choice == "KalmanFitter") + { // NOLINT(bugprone-branch-clone) _fitter = new genfit::KalmanFitter(); } - else if (fitter_choice.compare("DafSimple") == 0) + else if (fitter_choice == "DafSimple") { _fitter = new genfit::DAF(false); } - else if (fitter_choice.compare("DafRef") == 0) + else if (fitter_choice == "DafRef") { _fitter = new genfit::DAF(true); } else -// NOLINTNEXTLINE(bugprone-branch-clone) - { + { // NOLINT(bugprone-branch-clone) _fitter = new genfit::KalmanFitter(); } @@ -289,19 +287,19 @@ namespace PHGenFit } // init fitter - if (fitter_choice.compare("KalmanFitterRefTrack") == 0) + if (fitter_choice == "KalmanFitterRefTrack") { _fitter = new genfit::KalmanFitterRefTrack(); } - else if (fitter_choice.compare("KalmanFitter") == 0) + else if (fitter_choice == "KalmanFitter") { _fitter = new genfit::KalmanFitter(); } - else if (fitter_choice.compare("DafSimple") == 0) + else if (fitter_choice == "DafSimple") { _fitter = new genfit::DAF(false); } - else if (fitter_choice.compare("DafRef") == 0) + else if (fitter_choice == "DafRef") { _fitter = new genfit::DAF(true); } diff --git a/offline/packages/PHGenFitPkg/PHGenFit/Track.cc b/offline/packages/PHGenFitPkg/PHGenFit/Track.cc index b1643e8cd0..0e06f15984 100644 --- a/offline/packages/PHGenFitPkg/PHGenFit/Track.cc +++ b/offline/packages/PHGenFitPkg/PHGenFit/Track.cc @@ -48,8 +48,8 @@ #define WILD_DOUBLE (-999999) -//#define _DEBUG_ -//#define _PRINT_MATRIX_ +// #define _DEBUG_ +// #define _PRINT_MATRIX_ #ifdef _DEBUG_ #include @@ -60,11 +60,10 @@ ofstream fout_matrix("matrix.txt"); namespace PHGenFit { Track::Track(genfit::AbsTrackRep* rep, const TVector3& seed_pos, const TVector3& seed_mom, const TMatrixDSym& seed_cov, const int v) + : verbosity(v) { // TODO Add input param check - verbosity = v; - genfit::MeasuredStateOnPlane seedMSoP(rep); seedMSoP.setPosMomCov(seed_pos, seed_mom, seed_cov); // const genfit::StateOnPlane seedSoP(seedMSoP); @@ -78,12 +77,12 @@ namespace PHGenFit } Track::Track(const PHGenFit::Track& t) + : verbosity(t.verbosity) + , _track(new genfit::Track(*(t.getGenFitTrack()))) + , _clusterIDs(t.get_cluster_IDs()) + , _clusterkeys(t.get_cluster_keys()) + , _vertex_id(t.get_vertex_id()) { - _track = new genfit::Track(*(t.getGenFitTrack())); - verbosity = t.verbosity; - _clusterIDs = t.get_cluster_IDs(); - _clusterkeys = t.get_cluster_keys(); - _vertex_id = t.get_vertex_id(); } int Track::addMeasurement(PHGenFit::Measurement* measurement) @@ -191,10 +190,8 @@ namespace PHGenFit delete state; return nullptr; } - else - { - return state; - } + + return state; } double Track::extrapolateToLine(genfit::MeasuredStateOnPlane& state, const TVector3& line_point, const TVector3& line_direction, const int tr_point_id) const @@ -240,10 +237,8 @@ namespace PHGenFit delete state; return nullptr; } - else - { - return state; - } + + return state; } double Track::extrapolateToCylinder(genfit::MeasuredStateOnPlane& state, double radius, const TVector3& line_point, const TVector3& line_direction, const int tr_point_id, const int direction) const @@ -361,10 +356,8 @@ namespace PHGenFit delete state; return nullptr; } - else - { - return state; - } + + return state; } int Track::updateOneMeasurementKalman( @@ -385,7 +378,7 @@ namespace PHGenFit << std::endl; #endif - if (measurements.size() == 0) + if (measurements.empty()) { return -1; } @@ -437,11 +430,11 @@ namespace PHGenFit #endif continue; } - //#ifdef _DEBUG_ + // #ifdef _DEBUG_ // std::cout << __LINE__ << "\n ###################################################################"<Print(); // std::cout << __LINE__ << "\n ###################################################################"<getFittedState(true)); @@ -579,7 +572,7 @@ namespace PHGenFit // std::cout << err_phi << "\t" << err_z << "\t"; } #endif - for (auto rawMeasurement : rawMeasurements) + for (auto* rawMeasurement : rawMeasurements) { fi->addMeasurementsOnPlane( rawMeasurement->constructMeasurementsOnPlane(*state)); @@ -598,7 +591,7 @@ namespace PHGenFit << ": size of fi's MeasurementsOnPlane: " << measurements_on_plane.size() << std::endl; #endif - for (auto it : measurements_on_plane) + for (auto* it : measurements_on_plane) { const genfit::MeasurementOnPlane& mOnPlane = *it; // const double weight = mOnPlane.getWeight(); @@ -769,10 +762,7 @@ namespace PHGenFit delete state; return nullptr; } - else - { - return state; - } + return state; } double Track::get_chi2() const From 3e9477772211f43dff6202bba49303d9ef0e7254 Mon Sep 17 00:00:00 2001 From: "Blair D. Seidlitz" Date: Tue, 6 Jan 2026 16:29:08 -0500 Subject: [PATCH 010/393] appeasing the rabbit --- offline/QA/Calorimeters/CaloValid.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/offline/QA/Calorimeters/CaloValid.cc b/offline/QA/Calorimeters/CaloValid.cc index 8575c565b9..52707a05cc 100644 --- a/offline/QA/Calorimeters/CaloValid.cc +++ b/offline/QA/Calorimeters/CaloValid.cc @@ -405,7 +405,7 @@ int CaloValid::process_towers(PHCompositeNode* topNode) status = status >> 1U; // clang-tidy mark 1 as unsigned } - if(isGood) + if (isGood) { totalihcal += offlineenergy; } @@ -473,7 +473,7 @@ int CaloValid::process_towers(PHCompositeNode* topNode) status = status >> 1U; // clang-tidy mark 1 as unsigned } - if(isGood) + if (isGood) { totalohcal += offlineenergy; } From 667a5cc7bf9431851db82eea27e80063aafc0e64 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 6 Jan 2026 16:34:15 -0500 Subject: [PATCH 011/393] clang-tidy for mvtx --- offline/packages/mvtx/CylinderGeom_Mvtx.cc | 32 ++-- offline/packages/mvtx/CylinderGeom_Mvtx.h | 10 +- offline/packages/mvtx/MvtxClusterPruner.cc | 178 ++++++++++---------- offline/packages/mvtx/MvtxClusterizer.cc | 133 +++++++-------- offline/packages/mvtx/MvtxClusterizer.h | 4 +- offline/packages/mvtx/MvtxHitPruner.cc | 14 +- offline/packages/mvtx/SegmentationAlpide.cc | 9 +- 7 files changed, 184 insertions(+), 196 deletions(-) diff --git a/offline/packages/mvtx/CylinderGeom_Mvtx.cc b/offline/packages/mvtx/CylinderGeom_Mvtx.cc index e220d1474d..ab22c80bdc 100644 --- a/offline/packages/mvtx/CylinderGeom_Mvtx.cc +++ b/offline/packages/mvtx/CylinderGeom_Mvtx.cc @@ -8,7 +8,6 @@ #include #include // for operator<<, basic_ostream::operator<<, basic_... -using namespace std; using Segmentation = SegmentationAlpide; CylinderGeom_Mvtx::CylinderGeom_Mvtx( @@ -89,7 +88,7 @@ void CylinderGeom_Mvtx::get_sensor_indices_from_world_coords(std::vector double chip_delta_z = (inner_loc_chip_in_module[8][2] - inner_loc_chip_in_module[0][2]) / 8.0; // int chip_tmp = (int) (world[2]/chip_delta_z) + 4; // 0-9 int chip_tmp = round(world[2] / chip_delta_z) + 4; // 0-9 - // std::cout << " z " << world[2] << " chip_delta_z " << chip_delta_z << " chip_tmp " << chip_tmp << endl; + // std::cout << " z " << world[2] << " chip_delta_z " << chip_delta_z << " chip_tmp " << chip_tmp << std::endl; stave_index = stave_tmp; chip_index = chip_tmp; @@ -102,15 +101,15 @@ bool CylinderGeom_Mvtx::get_pixel_from_local_coords(TVector3 sensor_local, int& double EPS = 5e-6; if (fabs(fabs(sensor_local.X()) - SegmentationAlpide::ActiveMatrixSizeRows / 2.F) < EPS) { - // cout << " Adjusting X, before X= " << sensor_local.X() << endl; + // std::cout << " Adjusting X, before X= " << sensor_local.X() << std::endl; sensor_local.SetX(((sensor_local.X() < 0) ? -1 : 1) * (SegmentationAlpide::ActiveMatrixSizeRows / 2.F - EPS)); - // cout << " Adjusting X, after X= " << sensor_local.X() << endl; + // std::cout << " Adjusting X, after X= " << sensor_local.X() << std::endl; } if (fabs(fabs(sensor_local.Z()) - SegmentationAlpide::ActiveMatrixSizeCols / 2.F) < EPS) { - // cout << " Adjusting Z, before Z= " << sensor_local.Z() << endl; + // std::cout << " Adjusting Z, before Z= " << sensor_local.Z() << std::endl; sensor_local.SetZ(((sensor_local.Z() < 0) ? -1 : 1) * (SegmentationAlpide::ActiveMatrixSizeCols / 2.F - EPS)); - // cout << " Adjusting Z, after Z= " << sensor_local.Z() << endl; + // std::cout << " Adjusting Z, after Z= " << sensor_local.Z() << std::endl; } // YCM (2020-01-02): go from sensor to chip local coords TVector3 in_chip = sensor_local; @@ -122,21 +121,22 @@ bool CylinderGeom_Mvtx::get_pixel_from_local_coords(TVector3 sensor_local, int& int CylinderGeom_Mvtx::get_pixel_from_local_coords(const TVector3& sensor_local) { - int Ngridx, Ngridz; + int Ngridx; + int Ngridz; bool px_in = get_pixel_from_local_coords(sensor_local, Ngridx, Ngridz); if (!px_in) { - cout << PHWHERE + std::cout << PHWHERE << " Pixel is out sensor. (" << sensor_local.X() << ", " << sensor_local.Y() << ", " << sensor_local.Z() << ")." - << endl; + << std::endl; } if (Ngridx < 0 || Ngridx >= get_NX() || Ngridz < 0 || Ngridz >= get_NZ()) { - cout << PHWHERE << "Wrong pixel value X= " << Ngridx << " and Z= " << Ngridz << endl; + std::cout << PHWHERE << "Wrong pixel value X= " << Ngridx << " and Z= " << Ngridz << std::endl; } // numbering starts at zero @@ -157,8 +157,8 @@ TVector3 CylinderGeom_Mvtx::get_local_coords_from_pixel(int iRow, int iCol) bool check = SegmentationAlpide::detectorToLocal((float) iRow, (float) iCol, local); if (!check) { - cout << PHWHERE << "Pixel coord ( " << iRow << ", " << iCol << " )" - << "out of range" << endl; + std::cout << PHWHERE << "Pixel coord ( " << iRow << ", " << iCol << " )" + << "out of range" << std::endl; } // Transform location in chip to location in sensors TVector3 trChipToSens(loc_sensor_in_chip[0], @@ -177,7 +177,7 @@ void CylinderGeom_Mvtx::identify(std::ostream& os) const << ", pixel_x: " << pixel_x << ", pixel_z: " << pixel_z << ", pixel_thickness: " << pixel_thickness - << endl; + << std::endl; return; } @@ -192,17 +192,17 @@ int CylinderGeom_Mvtx::get_NX() const return SegmentationAlpide::NRows; } -int CylinderGeom_Mvtx::get_pixel_X_from_pixel_number(int NXZ) +int CylinderGeom_Mvtx::get_pixel_X_from_pixel_number(int NXZ) const { return NXZ % get_NX(); } -int CylinderGeom_Mvtx::get_pixel_Z_from_pixel_number(int NXZ) +int CylinderGeom_Mvtx::get_pixel_Z_from_pixel_number(int NXZ) const { return NXZ / get_NX(); } -int CylinderGeom_Mvtx::get_pixel_number_from_xbin_zbin(int xbin, int zbin) // obsolete +int CylinderGeom_Mvtx::get_pixel_number_from_xbin_zbin(int xbin, int zbin) const // obsolete { return xbin + zbin * get_NX(); } diff --git a/offline/packages/mvtx/CylinderGeom_Mvtx.h b/offline/packages/mvtx/CylinderGeom_Mvtx.h index e28da2c594..047673a549 100644 --- a/offline/packages/mvtx/CylinderGeom_Mvtx.h +++ b/offline/packages/mvtx/CylinderGeom_Mvtx.h @@ -13,7 +13,7 @@ class CylinderGeom_Mvtx : public PHG4CylinderGeom public: CylinderGeom_Mvtx( int layer, - int in_Nstaves, + int in_N_staves, double in_layer_nominal_radius, double in_phistep, double in_phitilt, @@ -31,7 +31,7 @@ class CylinderGeom_Mvtx : public PHG4CylinderGeom { } - ~CylinderGeom_Mvtx() override {} + ~CylinderGeom_Mvtx() override = default; // from PHObject void identify(std::ostream& os = std::cout) const override; @@ -53,11 +53,11 @@ class CylinderGeom_Mvtx : public PHG4CylinderGeom TVector3 get_local_coords_from_pixel(int NXZ); TVector3 get_local_coords_from_pixel(int iRow, int iCol); - int get_pixel_X_from_pixel_number(int NXZ); + int get_pixel_X_from_pixel_number(int NXZ) const; - int get_pixel_Z_from_pixel_number(int NXZ); + int get_pixel_Z_from_pixel_number(int NXZ) const; - int get_pixel_number_from_xbin_zbin(int xbin, int zbin); // obsolete + int get_pixel_number_from_xbin_zbin(int xbin, int zbin) const; // obsolete double get_stave_phi_tilt() const { return stave_phi_tilt; } double get_stave_phi_0() const { return stave_phi_0; } diff --git a/offline/packages/mvtx/MvtxClusterPruner.cc b/offline/packages/mvtx/MvtxClusterPruner.cc index 24d41db63d..456b302dd9 100644 --- a/offline/packages/mvtx/MvtxClusterPruner.cc +++ b/offline/packages/mvtx/MvtxClusterPruner.cc @@ -12,108 +12,116 @@ #include #include -#include #include +#include -#include #include +#include namespace { //! range adaptor to be able to use range-based for loop - template class range_adaptor + template + class range_adaptor { - public: - range_adaptor( const T& range ):m_range(range){} - const typename T::first_type& begin() {return m_range.first;} - const typename T::second_type& end() {return m_range.second;} - private: + public: + explicit range_adaptor(const T& range) + : m_range(range) + { + } + const typename T::first_type& begin() { return m_range.first; } + const typename T::second_type& end() { return m_range.second; } + + private: T m_range; }; // print cluster information - void print_cluster_information( TrkrDefs::cluskey ckey, TrkrCluster* cluster ) + void print_cluster_information(TrkrDefs::cluskey ckey, TrkrCluster* cluster) { - if( cluster ) + if (cluster) { std::cout << " MVTX cluster: " << ckey - << " position: (" << cluster->getLocalX() << ", " << cluster->getLocalY() << ")" - << " size: " << (int)cluster->getSize() - << " layer: " << (int)TrkrDefs::getLayer(ckey) - << " stave: " << (int) MvtxDefs::getStaveId(ckey) - << " chip: " << (int)MvtxDefs::getChipId(ckey) - << " strobe: " << (int)MvtxDefs::getStrobeId(ckey) - << " index: " << (int)TrkrDefs::getClusIndex(ckey) - << std::endl; - } else { + << " position: (" << cluster->getLocalX() << ", " << cluster->getLocalY() << ")" + << " size: " << (int) cluster->getSize() + << " layer: " << (int) TrkrDefs::getLayer(ckey) + << " stave: " << (int) MvtxDefs::getStaveId(ckey) + << " chip: " << (int) MvtxDefs::getChipId(ckey) + << " strobe: " << MvtxDefs::getStrobeId(ckey) + << " index: " << (int) TrkrDefs::getClusIndex(ckey) + << std::endl; + } + else + { std::cout << " MVTX cluster: " << ckey - << " layer: " << (int)TrkrDefs::getLayer(ckey) - << " stave: " << (int) MvtxDefs::getStaveId(ckey) - << " chip: " << (int)MvtxDefs::getChipId(ckey) - << " strobe: " << (int)MvtxDefs::getStrobeId(ckey) - << " index: " << (int)TrkrDefs::getClusIndex(ckey) - << std::endl; + << " layer: " << (int) TrkrDefs::getLayer(ckey) + << " stave: " << (int) MvtxDefs::getStaveId(ckey) + << " chip: " << (int) MvtxDefs::getChipId(ckey) + << " strobe: " << MvtxDefs::getStrobeId(ckey) + << " index: " << (int) TrkrDefs::getClusIndex(ckey) + << std::endl; } } using hitkeyset_t = std::set; - using clustermap_t = std::map; + using clustermap_t = std::map; -} +} // namespace //_____________________________________________________________________________ -MvtxClusterPruner::MvtxClusterPruner(const std::string &name) +MvtxClusterPruner::MvtxClusterPruner(const std::string& name) : SubsysReco(name) { } //_____________________________________________________________________________ -int MvtxClusterPruner::InitRun(PHCompositeNode * /*topNode*/) +int MvtxClusterPruner::InitRun(PHCompositeNode* /*topNode*/) { std::cout << "MvtxClusterPruner::InitRun - m_use_strict_matching: " << m_use_strict_matching << std::endl; return Fun4AllReturnCodes::EVENT_OK; } //_____________________________________________________________________________ -int MvtxClusterPruner::process_event(PHCompositeNode *topNode) +int MvtxClusterPruner::process_event(PHCompositeNode* topNode) { // load relevant nodes - auto trkrclusters = findNode::getClass(topNode, "TRKR_CLUSTER"); - if( !trkrclusters ) + auto* trkrclusters = findNode::getClass(topNode, "TRKR_CLUSTER"); + if (!trkrclusters) { std::cout << "MvtxClusterPruner::process_event - TRKR_CLUSTER not found. Doing nothing" << std::endl; return Fun4AllReturnCodes::EVENT_OK; } - auto clusterhitassoc = findNode::getClass(topNode, "TRKR_CLUSTERHITASSOC"); - if( !clusterhitassoc ) + auto* clusterhitassoc = findNode::getClass(topNode, "TRKR_CLUSTERHITASSOC"); + if (!clusterhitassoc) { std::cout << "MvtxClusterPruner::process_event - TRKR_CLUSTERHITASSOC not found. Doing nothing" << std::endl; return Fun4AllReturnCodes::EVENT_OK; } // lambda method to create map of cluster keys and associated hits - auto get_cluster_map = [trkrclusters,clusterhitassoc]( TrkrDefs::hitsetkey key ) + auto get_cluster_map = [trkrclusters, clusterhitassoc](TrkrDefs::hitsetkey key) { clustermap_t out; // get all clusters for this hitsetkey - const auto cluster_range= trkrclusters->getClusters(key); - for( const auto& [ckey,cluster]:range_adaptor(cluster_range) ) + const auto cluster_range = trkrclusters->getClusters(key); + for (const auto& [ckey, cluster] : range_adaptor(cluster_range)) { // get associated hits const auto& hit_range = clusterhitassoc->getHits(ckey); hitkeyset_t hitkeys; - std::transform(hit_range.first, hit_range.second, std::inserter(hitkeys,hitkeys.end()), - [](const TrkrClusterHitAssoc::Map::value_type& pair ){ return pair.second; }); - out.emplace(ckey,std::move(hitkeys)); + std::transform(hit_range.first, hit_range.second, std::inserter(hitkeys, hitkeys.end()), + [](const TrkrClusterHitAssoc::Map::value_type& pair) + { return pair.second; }); + out.emplace(ckey, std::move(hitkeys)); } return out; }; // loop over MVTX hitset keys const auto hitsetkeys = trkrclusters->getHitSetKeys(TrkrDefs::mvtxId); - for( const auto& hitsetkey:hitsetkeys ) + for (const auto& hitsetkey : hitsetkeys) { // get layer, stave, chip and current strobe const auto layer = TrkrDefs::getLayer(hitsetkey); @@ -125,111 +133,109 @@ int MvtxClusterPruner::process_event(PHCompositeNode *topNode) const auto cluster_map1 = get_cluster_map(hitsetkey); // get clusters for the next strobe - int next_strobe = current_strobe+1; + int next_strobe = current_strobe + 1; const auto hitsetkey_next_strobe = MvtxDefs::genHitSetKey(layer, stave, chip, next_strobe); const auto clusterk_map2 = get_cluster_map(hitsetkey_next_strobe); // loop over clusters from first range - for( auto [ckey1,hitkeys1]:cluster_map1) + for (auto [ckey1, hitkeys1] : cluster_map1) { // increment counter ++m_cluster_counter_total; // get correcponding cluser - auto cluster1 = Verbosity() ? trkrclusters->findCluster(ckey1):nullptr; + auto* cluster1 = Verbosity() ? trkrclusters->findCluster(ckey1) : nullptr; // loop over clusters from second range - for( auto [ckey2,hitkeys2]:clusterk_map2) + for (auto [ckey2, hitkeys2] : clusterk_map2) { - auto cluster2 = Verbosity() ? trkrclusters->findCluster(ckey2):nullptr; + auto* cluster2 = Verbosity() ? trkrclusters->findCluster(ckey2) : nullptr; - if( m_use_strict_matching ) + if (m_use_strict_matching) { // see if hitsets are identical - if(hitkeys1 == hitkeys2) + if (hitkeys1 == hitkeys2) { // increment counter ++m_cluster_counter_deleted; - if( Verbosity() ) + if (Verbosity()) { std::cout << "Removing cluster "; - print_cluster_information( ckey2, cluster2); + print_cluster_information(ckey2, cluster2); std::cout << "Keeping cluster "; - print_cluster_information( ckey1, cluster1); + print_cluster_information(ckey1, cluster1); } // always remove second cluster trkrclusters->removeCluster(ckey2); break; } - - } else { - + } + else + { // make sure first set is larger than second const bool swapped = hitkeys2.size() > hitkeys1.size(); - if( swapped ) { std::swap(hitkeys2,hitkeys1); } + if (swapped) + { + std::swap(hitkeys2, hitkeys1); + } // see if hitkeys2 is a subset of hitkeys1 - if( std::includes(hitkeys1.begin(), hitkeys1.end(), hitkeys2.begin(), hitkeys2.end()) ) + if (std::includes(hitkeys1.begin(), hitkeys1.end(), hitkeys2.begin(), hitkeys2.end())) { // increment counter ++m_cluster_counter_deleted; - if( swapped ) + if (swapped) { - - if( Verbosity() ) + if (Verbosity()) { std::cout << "Removing cluster "; - print_cluster_information( ckey1, cluster1); + print_cluster_information(ckey1, cluster1); std::cout << "Keeping cluster "; - print_cluster_information( ckey2, cluster2); + print_cluster_information(ckey2, cluster2); } // remove first cluster trkrclusters->removeCluster(ckey1); break; - } else { - - if( Verbosity() ) - { - std::cout << "Removing cluster "; - print_cluster_information( ckey2, cluster2); - - std::cout << "Keeping cluster "; - print_cluster_information( ckey1, cluster1); - } + } + if (Verbosity()) + { + std::cout << "Removing cluster "; + print_cluster_information(ckey2, cluster2); - // remove second cluster - trkrclusters->removeCluster(ckey2); + std::cout << "Keeping cluster "; + print_cluster_information(ckey1, cluster1); } + + // remove second cluster + trkrclusters->removeCluster(ckey2); } - } // strict matching + } // strict matching - } // second cluster loop - } // first cluster loop - } // hitsetkey loop + } // second cluster loop + } // first cluster loop + } // hitsetkey loop return Fun4AllReturnCodes::EVENT_OK; - } //_____________________________________________________________________________ -int MvtxClusterPruner::End(PHCompositeNode * /*topNode*/) +int MvtxClusterPruner::End(PHCompositeNode* /*topNode*/) { - std::cout << "MvtxClusterPruner::End -" - << " m_cluster_counter_total: " << m_cluster_counter_total - << std::endl; - std::cout << "MvtxClusterPruner::End -" - << " m_cluster_counter_deleted: " << m_cluster_counter_deleted - << " fraction: " << double( m_cluster_counter_deleted )/m_cluster_counter_total - << std::endl; + << " m_cluster_counter_total: " << m_cluster_counter_total + << std::endl; + std::cout << "MvtxClusterPruner::End -" + << " m_cluster_counter_deleted: " << m_cluster_counter_deleted + << " fraction: " << double(m_cluster_counter_deleted) / m_cluster_counter_total + << std::endl; return Fun4AllReturnCodes::EVENT_OK; } diff --git a/offline/packages/mvtx/MvtxClusterizer.cc b/offline/packages/mvtx/MvtxClusterizer.cc index 7970b369eb..eb54930acd 100644 --- a/offline/packages/mvtx/MvtxClusterizer.cc +++ b/offline/packages/mvtx/MvtxClusterizer.cc @@ -63,7 +63,7 @@ namespace /// convenience square method template - inline constexpr T square(const T &x) + constexpr T square(const T &x) { return x * x; } @@ -71,65 +71,45 @@ namespace bool MvtxClusterizer::are_adjacent( const std::pair &lhs, - const std::pair &rhs) + const std::pair &rhs) const { if (GetZClustering()) { return - // column adjacent - ( (MvtxDefs::getCol(lhs.first) > MvtxDefs::getCol(rhs.first)) ? - MvtxDefs::getCol(lhs.first)<=MvtxDefs::getCol(rhs.first)+1: - MvtxDefs::getCol(rhs.first)<=MvtxDefs::getCol(lhs.first)+1) && + // column adjacent + ((MvtxDefs::getCol(lhs.first) > MvtxDefs::getCol(rhs.first)) ? MvtxDefs::getCol(lhs.first) <= MvtxDefs::getCol(rhs.first) + 1 : MvtxDefs::getCol(rhs.first) <= MvtxDefs::getCol(lhs.first) + 1) && - // row adjacent - ( (MvtxDefs::getRow(lhs.first) > MvtxDefs::getRow(rhs.first)) ? - MvtxDefs::getRow(lhs.first)<=MvtxDefs::getRow(rhs.first)+1: - MvtxDefs::getRow(rhs.first)<=MvtxDefs::getRow(lhs.first)+1); - - } else { - - return + // row adjacent + ((MvtxDefs::getRow(lhs.first) > MvtxDefs::getRow(rhs.first)) ? MvtxDefs::getRow(lhs.first) <= MvtxDefs::getRow(rhs.first) + 1 : MvtxDefs::getRow(rhs.first) <= MvtxDefs::getRow(lhs.first) + 1); + } + return // column identical - MvtxDefs::getCol(rhs.first)==MvtxDefs::getCol(lhs.first) && + MvtxDefs::getCol(rhs.first) == MvtxDefs::getCol(lhs.first) && // row adjacent - ( (MvtxDefs::getRow(lhs.first) > MvtxDefs::getRow(rhs.first)) ? - MvtxDefs::getRow(lhs.first)<=MvtxDefs::getRow(rhs.first)+1: - MvtxDefs::getRow(rhs.first)<=MvtxDefs::getRow(lhs.first)+1); - - } + ((MvtxDefs::getRow(lhs.first) > MvtxDefs::getRow(rhs.first)) ? MvtxDefs::getRow(lhs.first) <= MvtxDefs::getRow(rhs.first) + 1 : MvtxDefs::getRow(rhs.first) <= MvtxDefs::getRow(lhs.first) + 1); } -bool MvtxClusterizer::are_adjacent(RawHit *lhs, RawHit *rhs) +bool MvtxClusterizer::are_adjacent(RawHit *lhs, RawHit *rhs) const { if (GetZClustering()) { return - // phi adjacent (== column) - ((lhs->getPhiBin() > rhs->getPhiBin()) ? - lhs->getPhiBin() <= rhs->getPhiBin()+1: - rhs->getPhiBin() <= lhs->getPhiBin()+1) && + // phi adjacent (== column) + ((lhs->getPhiBin() > rhs->getPhiBin()) ? lhs->getPhiBin() <= rhs->getPhiBin() + 1 : rhs->getPhiBin() <= lhs->getPhiBin() + 1) && - // time adjacent (== row) - ((lhs->getTBin() > rhs->getTBin()) ? - lhs->getTBin() <= rhs->getTBin()+1: - rhs->getTBin() <= lhs->getTBin()+1); - - } else { - - return + // time adjacent (== row) + ((lhs->getTBin() > rhs->getTBin()) ? lhs->getTBin() <= rhs->getTBin() + 1 : rhs->getTBin() <= lhs->getTBin() + 1); + } + return // phi identical (== column) lhs->getPhiBin() == rhs->getPhiBin() && // time adjacent (== row) - ((lhs->getTBin() > rhs->getTBin()) ? - lhs->getTBin() <= rhs->getTBin()+1: - rhs->getTBin() <= lhs->getTBin()+1); - - } + ((lhs->getTBin() > rhs->getTBin()) ? lhs->getTBin() <= rhs->getTBin() + 1 : rhs->getTBin() <= lhs->getTBin() + 1); } MvtxClusterizer::MvtxClusterizer(const std::string &name) @@ -165,7 +145,7 @@ int MvtxClusterizer::InitRun(PHCompositeNode *topNode) } // Create the Cluster node if required - auto trkrclusters = + auto *trkrclusters = findNode::getClass(dstNode, "TRKR_CLUSTER"); if (!trkrclusters) { @@ -183,7 +163,7 @@ int MvtxClusterizer::InitRun(PHCompositeNode *topNode) DetNode->addNode(TrkrClusterContainerNode); } - auto clusterhitassoc = + auto *clusterhitassoc = findNode::getClass(topNode, "TRKR_CLUSTERHITASSOC"); if (!clusterhitassoc) { @@ -208,14 +188,14 @@ int MvtxClusterizer::InitRun(PHCompositeNode *topNode) if (!mClusHitsVerbose) { PHNodeIterator dstiter(dstNode); - auto DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); + auto *DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); if (!DetNode) { DetNode = new PHCompositeNode("TRKR"); dstNode->addNode(DetNode); } mClusHitsVerbose = new ClusHitsVerbosev1(); - auto newNode = new PHIODataNode(mClusHitsVerbose, "Trkr_SvtxClusHitsVerbose", "PHObject"); + auto *newNode = new PHIODataNode(mClusHitsVerbose, "Trkr_SvtxClusHitsVerbose", "PHObject"); DetNode->addNode(newNode); } } @@ -227,13 +207,13 @@ int MvtxClusterizer::InitRun(PHCompositeNode *topNode) if (Verbosity() > 0) { std::cout << "====================== MvtxClusterizer::InitRun() " - "=====================" - << std::endl; + "=====================" + << std::endl; std::cout << " Z-dimension Clustering = " << std::boolalpha << m_makeZClustering - << std::noboolalpha << std::endl; + << std::noboolalpha << std::endl; std::cout << "==================================================================" - "=========" - << std::endl; + "=========" + << std::endl; } return Fun4AllReturnCodes::EVENT_OK; @@ -283,7 +263,7 @@ int MvtxClusterizer::process_event(PHCompositeNode *topNode) // reset MVTX clusters and cluster associations const auto hitsetkeys = m_clusterlist->getHitSetKeys(TrkrDefs::mvtxId); - for( const auto& hitsetkey:hitsetkeys) + for (const auto &hitsetkey : hitsetkeys) { m_clusterlist->removeClusters(hitsetkey); m_clusterhitassoc->removeAssocs(hitsetkey); @@ -337,8 +317,8 @@ void MvtxClusterizer::ClusterMvtx(PHCompositeNode *topNode) unsigned int chip = MvtxDefs::getChipId(hitsetitr->first); unsigned int strobe = MvtxDefs::getStrobeId(hitsetitr->first); std::cout << "MvtxClusterizer found hitsetkey " << hitsetitr->first - << " layer " << layer << " stave " << stave << " chip " << chip - << " strobe " << strobe << std::endl; + << " layer " << layer << " stave " << stave << " chip " << chip + << " strobe " << strobe << std::endl; } if (Verbosity() > 2) @@ -394,7 +374,7 @@ void MvtxClusterizer::ClusterMvtx(PHCompositeNode *topNode) std::vector component(num_vertices(G)); // this is the actual clustering, performed by boost - boost::connected_components(G, &component[0]); + boost::connected_components(G, component.data()); // Loop over the components(hits) compiling a list of the // unique connected groups (ie. clusters). @@ -405,7 +385,7 @@ void MvtxClusterizer::ClusterMvtx(PHCompositeNode *topNode) cluster_ids.insert(component[i]); clusters.insert(make_pair(component[i], hitvec[i])); } - for (const auto& clusid:cluster_ids) + for (const auto &clusid : cluster_ids) { auto clusrange = clusters.equal_range(clusid); auto ckey = TrkrDefs::genClusKey(hitset->getHitSetKey(), clusid); @@ -413,7 +393,8 @@ void MvtxClusterizer::ClusterMvtx(PHCompositeNode *topNode) // determine the size of the cluster in phi and z std::set phibins; std::set zbins; - std::map m_phi, m_z; // Note, there are no "cut" bins for Svtx Clusters + std::map m_phi; + std::map m_z; // Note, there are no "cut" bins for Svtx Clusters // determine the cluster position... double locxsum = 0.; @@ -426,7 +407,7 @@ void MvtxClusterizer::ClusterMvtx(PHCompositeNode *topNode) // we need the geometry object for this layer to get the global positions int layer = TrkrDefs::getLayer(ckey); - auto layergeom = dynamic_cast(geom_container->GetLayerGeom(layer)); + auto *layergeom = dynamic_cast(geom_container->GetLayerGeom(layer)); if (!layergeom) { exit(1); @@ -574,11 +555,11 @@ void MvtxClusterizer::ClusterMvtx(PHCompositeNode *topNode) if (Verbosity() > 0) { std::cout << " MvtxClusterizer: cluskey " << ckey << " layer " << layer - << " rad " << layergeom->get_radius() << " phibins " - << phibins.size() << " pitch " << pitch << " phisize " << phisize - << " zbins " << zbins.size() << " length " << length << " zsize " - << zsize << " local x " << locclusx << " local y " << locclusz - << std::endl; + << " rad " << layergeom->get_radius() << " phibins " + << phibins.size() << " pitch " << pitch << " phisize " << phisize + << " zbins " << zbins.size() << " length " << length << " zsize " + << zsize << " local x " << locclusx << " local y " << locclusz + << std::endl; } auto clus = std::make_unique(); @@ -605,7 +586,7 @@ void MvtxClusterizer::ClusterMvtx(PHCompositeNode *topNode) } } // clusitr loop - } // loop over hitsets + } // loop over hitsets if (Verbosity() > 1) { @@ -650,8 +631,8 @@ void MvtxClusterizer::ClusterMvtxRaw(PHCompositeNode *topNode) unsigned int chip = MvtxDefs::getChipId(hitsetitr->first); unsigned int strobe = MvtxDefs::getStrobeId(hitsetitr->first); std::cout << "MvtxClusterizer found hitsetkey " << hitsetitr->first - << " layer " << layer << " stave " << stave << " chip " << chip - << " strobe " << strobe << std::endl; + << " layer " << layer << " stave " << stave << " chip " << chip + << " strobe " << strobe << std::endl; } if (Verbosity() > 2) @@ -695,7 +676,7 @@ void MvtxClusterizer::ClusterMvtxRaw(PHCompositeNode *topNode) std::vector component(num_vertices(G)); // this is the actual clustering, performed by boost - boost::connected_components(G, &component[0]); + boost::connected_components(G, component.data()); // Loop over the components(hits) compiling a list of the // unique connected groups (ie. clusters). @@ -709,7 +690,7 @@ void MvtxClusterizer::ClusterMvtxRaw(PHCompositeNode *topNode) } // std::cout << "found cluster #: "<< clusters.size()<< std::endl; // loop over the componenets and make clusters - for( const auto& clusid:cluster_ids) + for (const auto &clusid : cluster_ids) { auto clusrange = clusters.equal_range(clusid); @@ -731,7 +712,7 @@ void MvtxClusterizer::ClusterMvtxRaw(PHCompositeNode *topNode) // we need the geometry object for this layer to get the global positions int layer = TrkrDefs::getLayer(ckey); - auto layergeom = dynamic_cast( + auto *layergeom = dynamic_cast( geom_container->GetLayerGeom(layer)); if (!layergeom) { @@ -845,11 +826,11 @@ void MvtxClusterizer::ClusterMvtxRaw(PHCompositeNode *topNode) if (Verbosity() > 0) { std::cout << " MvtxClusterizer: cluskey " << ckey << " layer " << layer - << " rad " << layergeom->get_radius() << " phibins " - << phibins.size() << " pitch " << pitch << " phisize " << phisize - << " zbins " << zbins.size() << " length " << length << " zsize " - << zsize << " local x " << locclusx << " local y " << locclusz - << std::endl; + << " rad " << layergeom->get_radius() << " phibins " + << phibins.size() << " pitch " << pitch << " phisize " << phisize + << " zbins " << zbins.size() << " length " << length << " zsize " + << zsize << " local x " << locclusx << " local y " << locclusz + << std::endl; } auto clus = std::make_unique(); @@ -875,7 +856,7 @@ void MvtxClusterizer::ClusterMvtxRaw(PHCompositeNode *topNode) m_clusterlist->addClusterSpecifyKey(ckey, clus.release()); } } // clusitr loop - } // loop over hitsets + } // loop over hitsets if (Verbosity() > 1) { @@ -898,11 +879,11 @@ void MvtxClusterizer::PrintClusters(PHCompositeNode *topNode) } std::cout << "================= After MvtxClusterizer::process_event() " - "====================" - << std::endl; + "====================" + << std::endl; std::cout << " There are " << clusterlist->size() - << " clusters recorded: " << std::endl; + << " clusters recorded: " << std::endl; if (Verbosity() > 3) { @@ -910,8 +891,8 @@ void MvtxClusterizer::PrintClusters(PHCompositeNode *topNode) } std::cout << "==================================================================" - "=========" - << std::endl; + "=========" + << std::endl; } return; diff --git a/offline/packages/mvtx/MvtxClusterizer.h b/offline/packages/mvtx/MvtxClusterizer.h index ce4794b5d1..10c65914cd 100644 --- a/offline/packages/mvtx/MvtxClusterizer.h +++ b/offline/packages/mvtx/MvtxClusterizer.h @@ -65,8 +65,8 @@ class MvtxClusterizer : public SubsysReco private: // bool are_adjacent(const pixel lhs, const pixel rhs); bool record_ClusHitsVerbose{false}; - bool are_adjacent(const std::pair &lhs, const std::pair &rhs); - bool are_adjacent(RawHit *lhs, RawHit *rhs); + bool are_adjacent(const std::pair &lhs, const std::pair &rhs) const; + bool are_adjacent(RawHit *lhs, RawHit *rhs) const; void ClusterMvtx(PHCompositeNode *topNode); void ClusterMvtxRaw(PHCompositeNode *topNode); diff --git a/offline/packages/mvtx/MvtxHitPruner.cc b/offline/packages/mvtx/MvtxHitPruner.cc index 4f141a4c3f..d4395b6f4a 100644 --- a/offline/packages/mvtx/MvtxHitPruner.cc +++ b/offline/packages/mvtx/MvtxHitPruner.cc @@ -54,7 +54,7 @@ namespace template class range_adaptor { public: - range_adaptor( const T& range ):m_range(range){} + explicit range_adaptor( const T& range ):m_range(range){} const typename T::first_type& begin() {return m_range.first;} const typename T::second_type& end() {return m_range.second;} private: @@ -98,7 +98,8 @@ int MvtxHitPruner::process_event(PHCompositeNode *topNode) // get strobe, skip if already zero const int strobe = MvtxDefs::getStrobeId(hitsetkey); - if( strobe == 0 ) continue; + if( strobe == 0 ) { continue; +} // get the hitsetkey value for strobe 0 const auto bare_hitsetkey = MvtxDefs::resetStrobe(hitsetkey); @@ -117,7 +118,7 @@ int MvtxHitPruner::process_event(PHCompositeNode *topNode) for (const auto& bare_hitsetkey : bare_hitset_set) { // find matching hitset of creater - auto bare_hitset = (m_hits->findOrAddHitSet(bare_hitsetkey))->second; + auto *bare_hitset = (m_hits->findOrAddHitSet(bare_hitsetkey))->second; if (Verbosity()) { std::cout @@ -131,7 +132,8 @@ int MvtxHitPruner::process_event(PHCompositeNode *topNode) for( const auto& [unused,hitsetkey]:range_adaptor(bare_hitsetrange) ) { const int strobe = MvtxDefs::getStrobeId(hitsetkey); - if( strobe == 0 ) continue; + if( strobe == 0 ) { continue; +} if (Verbosity()) { @@ -143,7 +145,7 @@ int MvtxHitPruner::process_event(PHCompositeNode *topNode) } // copy all hits to the hitset with strobe 0 - auto hitset = m_hits->findHitSet(hitsetkey); + auto *hitset = m_hits->findHitSet(hitsetkey); if (Verbosity()) { @@ -181,7 +183,7 @@ int MvtxHitPruner::process_event(PHCompositeNode *topNode) << hitkey << std::endl; } - auto new_hit = new TrkrHitv2; + auto *new_hit = new TrkrHitv2; new_hit->CopyFrom(old_hit); bare_hitset->addHitSpecificKey(hitkey, new_hit); } diff --git a/offline/packages/mvtx/SegmentationAlpide.cc b/offline/packages/mvtx/SegmentationAlpide.cc index 6b9aecddd0..0b1aae48cf 100644 --- a/offline/packages/mvtx/SegmentationAlpide.cc +++ b/offline/packages/mvtx/SegmentationAlpide.cc @@ -5,16 +5,15 @@ */ #include "SegmentationAlpide.h" -#include - #include +#include void SegmentationAlpide::print() { - std::cout << (boost::format("Pixel size: %.2f (along %d rows) %.2f (along %d columns) microns") % (PitchRow * 1e4) % NRows % (PitchCol * 1e4) % NCols).str() + std::cout << std::format("Pixel size: {:.2f} (along {} rows) {:.2f} (along {} columns) microns", (PitchRow * 1e4), NRows, (PitchCol * 1e4), NCols) << std::endl; - std::cout << (boost::format("Passive edges: bottom: %.2f, top: %.2f, left/right: %.2f microns") % (PassiveEdgeReadOut * 1e4) % (PassiveEdgeTop * 1e4) % (PassiveEdgeSide * 1e4)).str() + std::cout << std::format("Passive edges: bottom: {:.2f}, top: {:.2f}, left/right: {:.2f} microns", (PassiveEdgeReadOut * 1e4), (PassiveEdgeTop * 1e4), (PassiveEdgeSide * 1e4)) << std::endl; - std::cout << (boost::format("Active/Total size: %.6f/%.6f (rows) %.6f/%.6f (cols) cm") % ActiveMatrixSizeRows % SensorSizeRows % ActiveMatrixSizeCols % SensorSizeCols).str() + std::cout << std::format("Active/Total size: {:.6f}/{:.6f} (rows) {:.6f}/{:.6f} (cols) cm", ActiveMatrixSizeRows, SensorSizeRows, ActiveMatrixSizeCols, SensorSizeCols) << std::endl; } From 45a8c5b431b3774a7e229368f91d7e8f537d26bb Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 6 Jan 2026 18:15:18 -0500 Subject: [PATCH 012/393] clang-tidy for tpc --- offline/packages/tpc/LaserClusterizer.cc | 680 ++++++++---------- offline/packages/tpc/LaserEventIdentifier.cc | 2 +- offline/packages/tpc/Tpc3DClusterizer.cc | 385 ++++++---- offline/packages/tpc/TpcClusterMover.cc | 20 +- offline/packages/tpc/TpcClusterMover.h | 2 +- offline/packages/tpc/TpcClusterizer.cc | 103 +-- .../tpc/TpcCombinedRawDataUnpacker.cc | 4 +- .../tpc/TpcCombinedRawDataUnpackerDebug.cc | 20 +- .../packages/tpc/TpcDistortionCorrection.cc | 2 +- .../tpc/TpcLoadDistortionCorrection.cc | 8 +- offline/packages/tpc/TpcRawDataTree.cc | 2 +- offline/packages/tpc/TpcRawWriter.cc | 8 +- offline/packages/tpc/TpcSimpleClusterizer.cc | 37 +- offline/packages/tpc/TrainingHits.cc | 18 +- 14 files changed, 635 insertions(+), 656 deletions(-) diff --git a/offline/packages/tpc/LaserClusterizer.cc b/offline/packages/tpc/LaserClusterizer.cc index 170f95944d..84e0477caa 100644 --- a/offline/packages/tpc/LaserClusterizer.cc +++ b/offline/packages/tpc/LaserClusterizer.cc @@ -31,13 +31,10 @@ #include #include +#include #include #include #include -//#include -//#include -#include -//#include #include #include @@ -46,15 +43,16 @@ #include #include // for sqrt, cos, sin +#include #include #include #include // for _Rb_tree_cons... +#include +#include #include +#include #include // for pair #include -#include -#include -#include #include @@ -68,12 +66,9 @@ using adcKey = std::pair; using pointKeyLaser = std::pair; using hitData = std::pair; - -int layerMins[3] = {7,23,39}; +int layerMins[3] = {7, 23, 39}; int layerMaxes[3] = {22, 38, 54}; - - namespace { struct thread_data @@ -101,28 +96,25 @@ namespace pthread_mutex_t mythreadlock; const std::vector neighborOffsets = { - point(1, 0, 0), point(-1, 0, 0), - point(0, 1, 0), point(0, -1, 0), - point(0, 0, 1), point(0, 0, -1), - point(0, 0, 2), point(0, 0, -2) - }; - + point(1, 0, 0), point(-1, 0, 0), + point(0, 1, 0), point(0, -1, 0), + point(0, 0, 1), point(0, 0, -1), + point(0, 0, 2), point(0, 0, -2)}; - double layerFunction(double *x, double *par) + double layerFunction(double *x, const double *par) { double A = par[0]; double mu = par[1]; - double binCenter = round(x[0]); double overlapLow = std::max(binCenter - 0.5, mu - 0.5); double overlapHigh = std::min(binCenter + 0.5, mu + 0.5); double overlap = overlapHigh - overlapLow; - if(overlap <= 0.0) + if (overlap <= 0.0) { return 0.0; } - return A*overlap; + return A * overlap; /* if(fabs(x[0] - mu) < 1) { @@ -131,28 +123,26 @@ namespace } return 0.0; */ - - } double phiFunction(double *x, double *par) { - if(par[2] < 0.0) + if (par[2] < 0.0) { return 0.0; } - return par[0] * TMath::Gaus(x[0],par[1],par[2],false); + return par[0] * TMath::Gaus(x[0], par[1], par[2], false); } double timeFunction(double *x, double *par) { - if(par[2] < 0.0) + if (par[2] < 0.0) { return 0.0; } - double g = TMath::Gaus(x[0],par[1],par[2],true); - double cdf = 1 + TMath::Erfc(par[3]*(x[0]-par[1])/(sqrt(2.0)*par[2])); - return par[0]*g*cdf; + double g = TMath::Gaus(x[0], par[1], par[2], true); + double cdf = 1 + TMath::Erfc(par[3] * (x[0] - par[1]) / (sqrt(2.0) * par[2])); + return par[0] * g * cdf; } void findConnectedRegions3(std::vector &clusHits, std::pair &maxKey) @@ -160,21 +150,22 @@ namespace std::vector> regions; std::vector unvisited; - for(auto &clusHit : clusHits) + unvisited.reserve(clusHits.size()); + for (auto &clusHit : clusHits) { unvisited.push_back(clusHit); } - while(!unvisited.empty()) + while (!unvisited.empty()) { std::vector region; std::queue q; unsigned int mIndex = 0; - int i=0; - for(auto hit : unvisited) + int i = 0; + for (auto hit : unvisited) { - if(hit.second.second.first == maxKey.first && hit.second.second.second == maxKey.second) + if (hit.second.second.first == maxKey.first && hit.second.second.second == maxKey.second) { mIndex = i; break; @@ -183,11 +174,11 @@ namespace } auto seed = unvisited[mIndex]; - unvisited.erase(unvisited.begin()+mIndex); + unvisited.erase(unvisited.begin() + mIndex); q.push(seed); region.push_back(seed); - while(!q.empty()) + while (!q.empty()) { float ix = q.front().first.get<0>(); float iy = q.front().first.get<1>(); @@ -200,13 +191,12 @@ namespace float ny = iy + neigh.get<1>(); float nz = iz + neigh.get<2>(); - for(unsigned int v=0; v() - nx) < 0.01 && fabs(unvisited[v].first.get<1>() - ny) < 0.01 && fabs(unvisited[v].first.get<2>() - nz) < 0.01) + if (fabs(unvisited[v].first.get<0>() - nx) < 0.01 && fabs(unvisited[v].first.get<1>() - ny) < 0.01 && fabs(unvisited[v].first.get<2>() - nz) < 0.01) { auto newSeed = unvisited[v]; - unvisited.erase(unvisited.begin()+v); + unvisited.erase(unvisited.begin() + v); q.push(newSeed); region.push_back(newSeed); break; @@ -215,18 +205,15 @@ namespace } } regions.push_back(region); - } clusHits.clear(); - for(auto hit : regions[0]) + for (auto hit : regions[0]) { clusHits.push_back(hit); } - } - void remove_hits(std::vector &clusHits, bgi::rtree> &rtree, std::multimap &adcMap) { for (auto &clusHit : clusHits) @@ -237,51 +224,44 @@ namespace for (auto iterAdc = adcMap.begin(); iterAdc != adcMap.end();) { - if(iterAdc->second.second == spechitkey) - { - iterAdc = adcMap.erase(iterAdc); - break; - } - else - { - ++iterAdc; - } + if (iterAdc->second.second == spechitkey) + { + iterAdc = adcMap.erase(iterAdc); + break; + } + + ++iterAdc; } } - } void calc_cluster_parameter(std::vector &clusHits, thread_data &my_data, std::pair maxADCKey) { - - - findConnectedRegions3(clusHits, maxADCKey); - double rSum = 0.0; double phiSum = 0.0; double tSum = 0.0; - + double layerSum = 0.0; double iphiSum = 0.0; double itSum = 0.0; - + double adcSum = 0.0; - + double maxAdc = 0.0; TrkrDefs::hitsetkey maxKey = 0; - + unsigned int nHits = clusHits.size(); - + auto *clus = new LaserClusterv2; - + int meanSide = 0; - + std::vector usedLayer; std::vector usedIPhi; std::vector usedIT; - + double meanLayer = 0.0; double meanIPhi = 0.0; double meanIT = 0.0; @@ -293,113 +273,110 @@ namespace unsigned int adc = clusHit.second.first; int side = TpcDefs::getSide(spechitkey.second); - + if (side) { - meanSide++; + meanSide++; } else { - meanSide--; + meanSide--; } - + PHG4TpcGeom *layergeom = my_data.geom_container->GetLayerCellGeom((int) coords[0]); - + double r = layergeom->get_radius(); double phi = layergeom->get_phi(coords[1], side); double t = layergeom->get_zcenter(fabs(coords[2])); - + double hitzdriftlength = t * my_data.tGeometry->get_drift_velocity(); double hitZ = my_data.tdriftmax * my_data.tGeometry->get_drift_velocity() - hitzdriftlength; - - - bool foundLayer = false; - for (float i : usedLayer) - { - if (coords[0] == i) - { - foundLayer = true; - break; - } - } - - if (!foundLayer) - { - usedLayer.push_back(coords[0]); - } - - bool foundIPhi = false; - for (float i : usedIPhi) - { - if (coords[1] == i) - { - foundIPhi = true; - break; - } - } - - if (!foundIPhi) - { - usedIPhi.push_back(coords[1]); - } - - bool foundIT = false; - for (float i : usedIT) - { - if (coords[2] == i) - { - foundIT = true; - break; - } - } - - if (!foundIT) - { - usedIT.push_back(coords[2]); - } - - clus->addHit(); - clus->setHitLayer(clus->getNhits() - 1, coords[0]); - clus->setHitIPhi(clus->getNhits() - 1, coords[1]); - clus->setHitIT(clus->getNhits() - 1, coords[2]); - clus->setHitX(clus->getNhits() - 1, r * cos(phi)); - clus->setHitY(clus->getNhits() - 1, r * sin(phi)); - clus->setHitZ(clus->getNhits() - 1, hitZ); - clus->setHitAdc(clus->getNhits() - 1, (float) adc); - - rSum += r * adc; - phiSum += phi * adc; - tSum += t * adc; - - layerSum += coords[0] * adc; - iphiSum += coords[1] * adc; - itSum += coords[2] * adc; - - meanLayer += coords[0]; - meanIPhi += coords[1]; - meanIT += coords[2]; - - adcSum += adc; - - if (adc > maxAdc) - { - maxAdc = adc; - maxKey = spechitkey.second; - } - - } - + + bool foundLayer = false; + for (float i : usedLayer) + { + if (coords[0] == i) + { + foundLayer = true; + break; + } + } + + if (!foundLayer) + { + usedLayer.push_back(coords[0]); + } + + bool foundIPhi = false; + for (float i : usedIPhi) + { + if (coords[1] == i) + { + foundIPhi = true; + break; + } + } + + if (!foundIPhi) + { + usedIPhi.push_back(coords[1]); + } + + bool foundIT = false; + for (float i : usedIT) + { + if (coords[2] == i) + { + foundIT = true; + break; + } + } + + if (!foundIT) + { + usedIT.push_back(coords[2]); + } + + clus->addHit(); + clus->setHitLayer(clus->getNhits() - 1, coords[0]); + clus->setHitIPhi(clus->getNhits() - 1, coords[1]); + clus->setHitIT(clus->getNhits() - 1, coords[2]); + clus->setHitX(clus->getNhits() - 1, r * cos(phi)); + clus->setHitY(clus->getNhits() - 1, r * sin(phi)); + clus->setHitZ(clus->getNhits() - 1, hitZ); + clus->setHitAdc(clus->getNhits() - 1, (float) adc); + + rSum += r * adc; + phiSum += phi * adc; + tSum += t * adc; + + layerSum += coords[0] * adc; + iphiSum += coords[1] * adc; + itSum += coords[2] * adc; + + meanLayer += coords[0]; + meanIPhi += coords[1]; + meanIT += coords[2]; + + adcSum += adc; + + if (adc > maxAdc) + { + maxAdc = adc; + maxKey = spechitkey.second; + } + } + if (nHits == 0) { return; } - double clusR = rSum / adcSum; double clusPhi = phiSum / adcSum; double clusT = tSum / adcSum; double zdriftlength = clusT * my_data.tGeometry->get_drift_velocity(); - + double clusX = clusR * cos(clusPhi); double clusY = clusR * sin(clusPhi); double clusZ = my_data.tdriftmax * my_data.tGeometry->get_drift_velocity() - zdriftlength; @@ -408,10 +385,10 @@ namespace clusZ = -clusZ; for (int i = 0; i < (int) clus->getNhits(); i++) { - clus->setHitZ(i, -1 * clus->getHitZ(i)); + clus->setHitZ(i, -1 * clus->getHitZ(i)); } } - + std::sort(usedLayer.begin(), usedLayer.end()); std::sort(usedIPhi.begin(), usedIPhi.end()); std::sort(usedIT.begin(), usedIT.end()); @@ -419,30 +396,28 @@ namespace meanLayer = meanLayer / nHits; meanIPhi = meanIPhi / nHits; meanIT = meanIT / nHits; - + double sigmaLayer = 0.0; double sigmaIPhi = 0.0; double sigmaIT = 0.0; - + double sigmaWeightedLayer = 0.0; double sigmaWeightedIPhi = 0.0; double sigmaWeightedIT = 0.0; - - pthread_mutex_lock(&mythreadlock); - my_data.hitHist = new TH3D(Form("hitHist_event%d_side%d_sector%d_module%d_cluster%d",my_data.eventNum,(int)my_data.side,(int)my_data.sector,(int)my_data.module,(int)my_data.cluster_vector.size()),";layer;iphi;it",usedLayer.size()+2,usedLayer[0]-1.5,*usedLayer.rbegin()+1.5,usedIPhi.size()+2,usedIPhi[0]-1.5,*usedIPhi.rbegin()+1.5,usedIT.size()+2,usedIT[0]-1.5,*usedIT.rbegin()+1.5); + pthread_mutex_lock(&mythreadlock); + my_data.hitHist = new TH3D(std::format("hitHist_event{}_side{}_sector{}_module{}_cluster{}", my_data.eventNum, (int) my_data.side, (int) my_data.sector, (int) my_data.module, (int) my_data.cluster_vector.size()).c_str(), ";layer;iphi;it", usedLayer.size() + 2, usedLayer[0] - 1.5, *usedLayer.rbegin() + 1.5, usedIPhi.size() + 2, usedIPhi[0] - 1.5, *usedIPhi.rbegin() + 1.5, usedIT.size() + 2, usedIT[0] - 1.5, *usedIT.rbegin() + 1.5); - //TH3D *hitHist = new TH3D(Form("hitHist_event%d_side%d_sector%d_module%d_cluster%d",my_data.eventNum,(int)my_data.side,(int)my_data.sector,(int)my_data.module,(int)my_data.cluster_vector.size()),";layer;iphi;it",usedLayer.size()+2,usedLayer[0]-1.5,*usedLayer.rbegin()+1.5,usedIPhi.size()+2,usedIPhi[0]-1.5,*usedIPhi.rbegin()+1.5,usedIT.size()+2,usedIT[0]-1.5,*usedIT.rbegin()+1.5); + // TH3D *hitHist = new TH3D(Form("hitHist_event%d_side%d_sector%d_module%d_cluster%d",my_data.eventNum,(int)my_data.side,(int)my_data.sector,(int)my_data.module,(int)my_data.cluster_vector.size()),";layer;iphi;it",usedLayer.size()+2,usedLayer[0]-1.5,*usedLayer.rbegin()+1.5,usedIPhi.size()+2,usedIPhi[0]-1.5,*usedIPhi.rbegin()+1.5,usedIT.size()+2,usedIT[0]-1.5,*usedIT.rbegin()+1.5); for (int i = 0; i < (int) clus->getNhits(); i++) { - my_data.hitHist->Fill(clus->getHitLayer(i), clus->getHitIPhi(i), clus->getHitIT(i), clus->getHitAdc(i)); sigmaLayer += pow(clus->getHitLayer(i) - meanLayer, 2); sigmaIPhi += pow(clus->getHitIPhi(i) - meanIPhi, 2); sigmaIT += pow(clus->getHitIT(i) - meanIT, 2); - + sigmaWeightedLayer += clus->getHitAdc(i) * pow(clus->getHitLayer(i) - (layerSum / adcSum), 2); sigmaWeightedIPhi += clus->getHitAdc(i) * pow(clus->getHitIPhi(i) - (iphiSum / adcSum), 2); sigmaWeightedIT += clus->getHitAdc(i) * pow(clus->getHitIT(i) - (itSum / adcSum), 2); @@ -451,20 +426,18 @@ namespace bool fitSuccess = false; ROOT::Fit::Fitter *fit3D = new ROOT::Fit::Fitter; - if(my_data.doFitting) + if (my_data.doFitting) { - double par_init[7] = { - maxAdc, - meanLayer, - meanIPhi, 0.75, - meanIT, 0.5, 1 - }; + maxAdc, + meanLayer, + meanIPhi, 0.75, + meanIT, 0.5, 1}; double satThreshold = 900.0; double sigma_ADC = 20.0; - auto nll = [&](const double* par) + auto nll = [&](const double *par) { double nll_val = 0.0; @@ -472,37 +445,37 @@ namespace int ny = my_data.hitHist->GetNbinsY(); int nz = my_data.hitHist->GetNbinsZ(); - double parLayer[2] = {1.0,par[1]}; - double parPhi[4] = {1.0,par[2],par[3]}; - double parTime[4] = {1.0,par[4],par[5],par[6]}; + double parLayer[2] = {1.0, par[1]}; + double parPhi[4] = {1.0, par[2], par[3]}; + double parTime[4] = {1.0, par[4], par[5], par[6]}; double xyz[3]; for (int i = 1; i <= nx; ++i) { - xyz[0] = my_data.hitHist->GetXaxis()->GetBinCenter(i); + xyz[0] = my_data.hitHist->GetXaxis()->GetBinCenter(i); for (int j = 1; j <= ny; ++j) { - xyz[1] = my_data.hitHist->GetYaxis()->GetBinCenter(j); + xyz[1] = my_data.hitHist->GetYaxis()->GetBinCenter(j); for (int k = 1; k <= nz; ++k) { xyz[2] = my_data.hitHist->GetZaxis()->GetBinCenter(k); double observed = my_data.hitHist->GetBinContent(i, j, k); - double expected = par[0]*layerFunction(&xyz[0], parLayer)*phiFunction(&xyz[1], parPhi)*timeFunction(&xyz[2], parTime); + double expected = par[0] * layerFunction(&xyz[0], parLayer) * phiFunction(&xyz[1], parPhi) * timeFunction(&xyz[2], parTime); - if(observed <= my_data.adc_threshold) + if (observed <= my_data.adc_threshold) { double arg = (expected - my_data.adc_threshold) / (sqrt(2.0) * sigma_ADC); double tail_prob = 0.5 * TMath::Erfc(arg); nll_val -= log(tail_prob + 1e-12); } - else if(observed < satThreshold) + else if (observed < satThreshold) { double resid = (observed - expected) / sigma_ADC; nll_val += 0.5 * (resid * resid + log(2 * TMath::Pi() * sigma_ADC * sigma_ADC)); } - else if(observed >= satThreshold) + else if (observed >= satThreshold) { double arg = (satThreshold - expected) / (sqrt(2.0) * sigma_ADC); double tail_prob = 0.5 * TMath::Erfc(arg); @@ -518,35 +491,33 @@ namespace fit3D->Config().ParSettings(0).SetName("amp"); fit3D->Config().ParSettings(0).SetStepSize(10); - fit3D->Config().ParSettings(0).SetLimits(0,5000); + fit3D->Config().ParSettings(0).SetLimits(0, 5000); fit3D->Config().ParSettings(1).SetName("mu_layer"); fit3D->Config().ParSettings(1).SetStepSize(0.1); - fit3D->Config().ParSettings(1).SetLimits(usedLayer[0],*usedLayer.rbegin()); + fit3D->Config().ParSettings(1).SetLimits(usedLayer[0], *usedLayer.rbegin()); fit3D->Config().ParSettings(2).SetName("mu_phi"); fit3D->Config().ParSettings(2).SetStepSize(0.1); - fit3D->Config().ParSettings(2).SetLimits(usedIPhi[0],*usedIPhi.rbegin()); + fit3D->Config().ParSettings(2).SetLimits(usedIPhi[0], *usedIPhi.rbegin()); fit3D->Config().ParSettings(3).SetName("sig_phi"); fit3D->Config().ParSettings(3).SetStepSize(0.1); - fit3D->Config().ParSettings(3).SetLimits(0.01,2); + fit3D->Config().ParSettings(3).SetLimits(0.01, 2); fit3D->Config().ParSettings(4).SetName("mu_t"); fit3D->Config().ParSettings(4).SetStepSize(0.1); - fit3D->Config().ParSettings(4).SetLimits(usedIT[0],*usedIT.rbegin()); + fit3D->Config().ParSettings(4).SetLimits(usedIT[0], *usedIT.rbegin()); fit3D->Config().ParSettings(5).SetName("sig_t"); fit3D->Config().ParSettings(5).SetStepSize(0.1); - fit3D->Config().ParSettings(5).SetLimits(0.01,10); + fit3D->Config().ParSettings(5).SetLimits(0.01, 10); fit3D->Config().ParSettings(6).SetName("lambda_t"); fit3D->Config().ParSettings(6).SetStepSize(0.01); - fit3D->Config().ParSettings(6).SetLimits(0,5); + fit3D->Config().ParSettings(6).SetLimits(0, 5); - - if(usedLayer.size() == 1) + if (usedLayer.size() == 1) { fit3D->Config().ParSettings(1).Fix(); } fitSuccess = fit3D->FitFCN(); - if (my_data.Verbosity > 2) { std::cout << "fit success: " << fitSuccess << std::endl; @@ -554,13 +525,9 @@ namespace } pthread_mutex_unlock(&mythreadlock); - - - if(my_data.doFitting && fitSuccess) + if (my_data.doFitting && fitSuccess) { - - const ROOT::Fit::FitResult& result = fit3D->Result(); - + const ROOT::Fit::FitResult &result = fit3D->Result(); PHG4TpcGeom *layergeomLow = my_data.geom_container->GetLayerCellGeom((int) floor(result.Parameter(1))); PHG4TpcGeom *layergeomHigh = my_data.geom_container->GetLayerCellGeom((int) ceil(result.Parameter(1))); @@ -569,12 +536,12 @@ namespace double RHigh = layergeomHigh->get_radius(); double phiHigh_RLow = -999.0; - if(ceil(result.Parameter(2)) < layergeomLow->get_phibins()) + if (ceil(result.Parameter(2)) < layergeomLow->get_phibins()) { phiHigh_RLow = layergeomLow->get_phi(ceil(result.Parameter(2)), (meanSide < 0 ? 0 : 1)); } double phiHigh_RHigh = -999.0; - if(ceil(result.Parameter(2)) < layergeomHigh->get_phibins()) + if (ceil(result.Parameter(2)) < layergeomHigh->get_phibins()) { phiHigh_RHigh = layergeomHigh->get_phi(ceil(result.Parameter(2)), (meanSide < 0 ? 0 : 1)); } @@ -587,18 +554,17 @@ namespace double meanPhi_RLow = ((result.Parameter(2) - floor(result.Parameter(2)))) * (phiHigh_RLow - phiLow_RLow) + phiLow_RLow; double meanPhi_RHigh = ((result.Parameter(2) - floor(result.Parameter(2)))) * (phiHigh_RHigh - phiLow_RHigh) + phiLow_RHigh; - double meanPhi = 0.5*(meanPhi_RLow + meanPhi_RHigh); - if(phiHigh_RLow == -999.0 && phiHigh_RHigh != -999.0) + double meanPhi = 0.5 * (meanPhi_RLow + meanPhi_RHigh); + if (phiHigh_RLow == -999.0 && phiHigh_RHigh != -999.0) { meanPhi = meanPhi_RHigh; } - else if(phiHigh_RLow != -999.0 && phiHigh_RHigh == -999.0) + else if (phiHigh_RLow != -999.0 && phiHigh_RHigh == -999.0) { meanPhi = meanPhi_RLow; } - - if(phiHigh_RLow == -999.0 && phiHigh_RHigh == -999.0) + if (phiHigh_RLow == -999.0 && phiHigh_RHigh == -999.0) { clus->setAdc(adcSum); clus->setX(clusX); @@ -619,10 +585,10 @@ namespace clus->setSDWeightedIT(sqrt(sigmaWeightedIT / adcSum)); } else - { + { clus->setAdc(adcSum); - clus->setX(meanR*cos(meanPhi)); - clus->setY(meanR*sin(meanPhi)); + clus->setX(meanR * cos(meanPhi)); + clus->setY(meanR * sin(meanPhi)); clus->setZ(clusZ); clus->setFitMode(true); clus->setLayer(result.Parameter(1)); @@ -663,25 +629,18 @@ namespace const auto ckey = TrkrDefs::genClusKey(maxKey, my_data.cluster_vector.size()); my_data.cluster_vector.push_back(clus); my_data.cluster_key_vector.push_back(ckey); - - if(fit3D) - { - delete fit3D; - } - if(my_data.hitHist) + delete fit3D; + + if (my_data.hitHist) { delete my_data.hitHist; my_data.hitHist = nullptr; } - - } - void ProcessModuleData(thread_data *my_data) { - if (my_data->Verbosity > 2) { pthread_mutex_lock(&mythreadlock); @@ -693,85 +652,84 @@ namespace std::multimap adcMap; - if (my_data->hitsets.size() == 0) + if (my_data->hitsets.empty()) { return; } - for(int i=0; i<(int)my_data->hitsets.size(); i++) + for (int i = 0; i < (int) my_data->hitsets.size(); i++) { auto *hitset = my_data->hitsets[i]; unsigned int layer = my_data->layers[i]; bool side = my_data->side; unsigned int sector = my_data->sector; - TrkrDefs::hitsetkey hitsetKey = TpcDefs::genHitSetKey(layer, sector, (int)side); + TrkrDefs::hitsetkey hitsetKey = TpcDefs::genHitSetKey(layer, sector, (int) side); TrkrHitSet::ConstRange hitrangei = hitset->getHits(); for (TrkrHitSet::ConstIterator hitr = hitrangei.first; hitr != hitrangei.second; ++hitr) { - float_t fadc = hitr->second->getAdc(); - unsigned short adc = 0; - if (fadc > my_data->adc_threshold) - { - adc = (unsigned short) fadc; - } - else - { - continue; - } - - int iphi = TpcDefs::getPad(hitr->first); - int it = TpcDefs::getTBin(hitr->first); - - if(fabs(it - my_data->peakTimeBin) > 5) - { - continue; - } - - point coords = point((int) layer, iphi, it); - - std::vector testduplicate; - rtree.query(bgi::intersects(box(point(layer - 0.001, iphi - 0.001, it - 0.001), - point(layer + 0.001, iphi + 0.001, it + 0.001))), - std::back_inserter(testduplicate)); - if (!testduplicate.empty()) - { - testduplicate.clear(); - continue; - } - - TrkrDefs::hitkey hitKey = TpcDefs::genHitKey(iphi, it); - - auto spechitkey = std::make_pair(hitKey, hitsetKey); - pointKeyLaser coordsKey = std::make_pair(coords, spechitkey); - adcMap.insert(std::make_pair(adc, coordsKey)); + float_t fadc = hitr->second->getAdc(); + unsigned short adc = 0; + if (fadc > my_data->adc_threshold) + { + adc = (unsigned short) fadc; + } + else + { + continue; + } + + int iphi = TpcDefs::getPad(hitr->first); + int it = TpcDefs::getTBin(hitr->first); + + if (fabs(it - my_data->peakTimeBin) > 5) + { + continue; + } + + point coords = point((int) layer, iphi, it); + + std::vector testduplicate; + rtree.query(bgi::intersects(box(point(layer - 0.001, iphi - 0.001, it - 0.001), + point(layer + 0.001, iphi + 0.001, it + 0.001))), + std::back_inserter(testduplicate)); + if (!testduplicate.empty()) + { + testduplicate.clear(); + continue; + } + + TrkrDefs::hitkey hitKey = TpcDefs::genHitKey(iphi, it); + + auto spechitkey = std::make_pair(hitKey, hitsetKey); + pointKeyLaser coordsKey = std::make_pair(coords, spechitkey); + adcMap.insert(std::make_pair(adc, coordsKey)); auto adckey = std::make_pair(adc, spechitkey); - rtree.insert(std::make_pair(point(1.0*layer, 1.0*iphi, 1.0*it), adckey)); + rtree.insert(std::make_pair(point(1.0 * layer, 1.0 * iphi, 1.0 * it), adckey)); } } - //finished filling rtree + // finished filling rtree - while (adcMap.size() > 0) + while (!adcMap.empty()) { auto iterKey = adcMap.rbegin(); - if(iterKey == adcMap.rend()) + if (iterKey == adcMap.rend()) { - break; + break; } - auto coords = iterKey->second.first; int layer = coords.get<0>(); int iphi = coords.get<1>(); int it = coords.get<2>(); - + if (my_data->Verbosity > 2) { pthread_mutex_lock(&mythreadlock); - std::cout << "working on cluster " << my_data->cluster_vector.size() << " side: " << my_data->side << " sector: " << my_data->sector << " module: " << (layer<23 ? 1 : (layer<39 ? 2 : 3) ) << std::endl; + // NOLINTNEXTLINE (readability-avoid-nested-conditional-operator) + std::cout << "working on cluster " << my_data->cluster_vector.size() << " side: " << my_data->side << " sector: " << my_data->sector << " module: " << (layer < 23 ? 1 : (layer < 39 ? 2 : 3)) << std::endl; pthread_mutex_unlock(&mythreadlock); - } std::vector clusHits; @@ -781,17 +739,16 @@ namespace calc_cluster_parameter(clusHits, *my_data, iterKey->second.second); remove_hits(clusHits, rtree, adcMap); - } } void *ProcessModule(void *threadarg) { - auto my_data = static_cast(threadarg); + auto *my_data = static_cast(threadarg); ProcessModuleData(my_data); pthread_exit(nullptr); } -} //namespace +} // namespace LaserClusterizer::LaserClusterizer(const std::string &name) : SubsysReco(name) @@ -818,7 +775,7 @@ int LaserClusterizer::InitRun(PHCompositeNode *topNode) { laserClusterNodeName = "LAMINATION_CLUSTER"; } - auto laserclusters = findNode::getClass(dstNode, laserClusterNodeName); + auto *laserclusters = findNode::getClass(dstNode, laserClusterNodeName); if (!laserclusters) { PHNodeIterator dstiter(dstNode); @@ -835,7 +792,7 @@ int LaserClusterizer::InitRun(PHCompositeNode *topNode) new PHIODataNode(laserclusters, laserClusterNodeName, "PHObject"); DetNode->addNode(LaserClusterContainerNode); } - + m_geom_container = findNode::getClass(topNode, "TPCGEOMCONTAINER"); if (!m_geom_container) @@ -873,7 +830,7 @@ int LaserClusterizer::process_event(PHCompositeNode *topNode) return Fun4AllReturnCodes::ABORTRUN; } - if((eventHeader->get_RunNumber() > 66153 && !m_laserEventInfo->isGl1LaserEvent()) || (eventHeader->get_RunNumber() <= 66153 && !m_laserEventInfo->isLaserEvent())) + if ((eventHeader->get_RunNumber() > 66153 && !m_laserEventInfo->isGl1LaserEvent()) || (eventHeader->get_RunNumber() <= 66153 && !m_laserEventInfo->isLaserEvent())) { return Fun4AllReturnCodes::EVENT_OK; } @@ -897,7 +854,7 @@ int LaserClusterizer::process_event(PHCompositeNode *topNode) std::cout << PHWHERE << "ERROR: Can't find node TRKR_HITSET" << std::endl; return Fun4AllReturnCodes::ABORTRUN; } - + // get node for clusters std::string laserClusterNodeName = "LASER_CLUSTER"; if (m_lamination) @@ -921,8 +878,9 @@ int LaserClusterizer::process_event(PHCompositeNode *topNode) return Fun4AllReturnCodes::ABORTRUN; } - TrkrHitSetContainer::ConstRange hitsetrange = m_hits->getHitSets(TrkrDefs::TrkrId::tpcId);; - + TrkrHitSetContainer::ConstRange hitsetrange = m_hits->getHitSets(TrkrDefs::TrkrId::tpcId); + ; + struct thread_pair_t { pthread_t thread{}; @@ -938,123 +896,122 @@ int LaserClusterizer::process_event(PHCompositeNode *topNode) if (pthread_mutex_init(&mythreadlock, nullptr) != 0) { - std::cout << std::endl << " mutex init failed" << std::endl; + std::cout << std::endl + << " mutex init failed" << std::endl; return 1; } - - for (unsigned int sec=0; sec<12; sec++) + + for (unsigned int sec = 0; sec < 12; sec++) { - for (int s=0; s<2; s++) + for (int s = 0; s < 2; s++) { - for (unsigned int mod=0; mod<3; mod++) + for (unsigned int mod = 0; mod < 3; mod++) { - - if(Verbosity() > 2) + if (Verbosity() > 2) { std::cout << "making thread for side: " << s << " sector: " << sec << " module: " << mod << std::endl; } - thread_pair_t &thread_pair = threads.emplace_back(); - - std::vector hitsets; - std::vector layers; - - std::vector cluster_vector; - std::vector cluster_key_vector; - - for (TrkrHitSetContainer::ConstIterator hitsetitr = hitsetrange.first; - hitsetitr != hitsetrange.second; - ++hitsetitr) - { - unsigned int layer = TrkrDefs::getLayer(hitsetitr->first); - int side = TpcDefs::getSide(hitsetitr->first); - unsigned int sector = TpcDefs::getSectorId(hitsetitr->first); - if (sector != sec || side != s) - { - continue; - } - if ((mod==0 && (layer<7 || layer>22)) || (mod==1 && (layer<=22 || layer>38) ) || (mod==2 && (layer<=38 || layer>54))) - { - continue; - } - - TrkrHitSet *hitset = hitsetitr->second; - - hitsets.push_back(hitset); - layers.push_back(layer); - - } - - thread_pair.data.geom_container = m_geom_container; - thread_pair.data.tGeometry = m_tGeometry; - thread_pair.data.hitsets = hitsets; - thread_pair.data.layers = layers; - thread_pair.data.side = (bool)s; - thread_pair.data.sector = sec; + thread_pair_t &thread_pair = threads.emplace_back(); + + std::vector hitsets; + std::vector layers; + + std::vector cluster_vector; + std::vector cluster_key_vector; + + for (TrkrHitSetContainer::ConstIterator hitsetitr = hitsetrange.first; + hitsetitr != hitsetrange.second; + ++hitsetitr) + { + unsigned int layer = TrkrDefs::getLayer(hitsetitr->first); + int side = TpcDefs::getSide(hitsetitr->first); + unsigned int sector = TpcDefs::getSectorId(hitsetitr->first); + if (sector != sec || side != s) + { + continue; + } + if ((mod == 0 && (layer < 7 || layer > 22)) || (mod == 1 && (layer <= 22 || layer > 38)) || (mod == 2 && (layer <= 38 || layer > 54))) + { + continue; + } + + TrkrHitSet *hitset = hitsetitr->second; + + hitsets.push_back(hitset); + layers.push_back(layer); + } + + thread_pair.data.geom_container = m_geom_container; + thread_pair.data.tGeometry = m_tGeometry; + thread_pair.data.hitsets = hitsets; + thread_pair.data.layers = layers; + thread_pair.data.side = (bool) s; + thread_pair.data.sector = sec; thread_pair.data.module = mod; - thread_pair.data.cluster_vector = cluster_vector; - thread_pair.data.cluster_key_vector = cluster_key_vector; - thread_pair.data.adc_threshold = m_adc_threshold; - thread_pair.data.peakTimeBin = m_laserEventInfo->getPeakSample(s); - thread_pair.data.layerMin = 3; - thread_pair.data.layerMax = 3; - thread_pair.data.tdriftmax = m_tdriftmax; + thread_pair.data.cluster_vector = cluster_vector; + thread_pair.data.cluster_key_vector = cluster_key_vector; + thread_pair.data.adc_threshold = m_adc_threshold; + thread_pair.data.peakTimeBin = m_laserEventInfo->getPeakSample(s); + thread_pair.data.layerMin = 3; + thread_pair.data.layerMax = 3; + thread_pair.data.tdriftmax = m_tdriftmax; thread_pair.data.eventNum = m_event; thread_pair.data.Verbosity = Verbosity(); thread_pair.data.hitHist = nullptr; thread_pair.data.doFitting = m_do_fitting; - int rc; - rc = pthread_create(&thread_pair.thread, &attr, ProcessModule, (void *) &thread_pair.data); - - if (rc) - { - std::cout << "Error:unable to create thread," << rc << std::endl; - } - - if (m_do_sequential) - { - //wait for termination of thread - int rc2 = pthread_join(thread_pair.thread, nullptr); - if (rc2) - { - std::cout << "Error:unable to join," << rc2 << std::endl; - } - - //add clusters from thread to laserClusterContainer - const auto &data(thread_pair.data); - for(int index = 0; index < (int) data.cluster_vector.size(); ++index) - { - auto cluster = data.cluster_vector[index]; - const auto ckey = data.cluster_key_vector[index]; - - m_clusterlist->addClusterSpecifyKey(ckey, cluster); - } - } + int rc; + rc = pthread_create(&thread_pair.thread, &attr, ProcessModule, (void *) &thread_pair.data); + + if (rc) + { + std::cout << "Error:unable to create thread," << rc << std::endl; + } + + if (m_do_sequential) + { + // wait for termination of thread + int rc2 = pthread_join(thread_pair.thread, nullptr); + if (rc2) + { + std::cout << "Error:unable to join," << rc2 << std::endl; + } + + // add clusters from thread to laserClusterContainer + const auto &data(thread_pair.data); + for (int index = 0; index < (int) data.cluster_vector.size(); ++index) + { + auto *cluster = data.cluster_vector[index]; + const auto ckey = data.cluster_key_vector[index]; + + m_clusterlist->addClusterSpecifyKey(ckey, cluster); + } + } } } } - + pthread_attr_destroy(&attr); if (!m_do_sequential) { - for (const auto & thread_pair : threads) + for (const auto &thread_pair : threads) { int rc2 = pthread_join(thread_pair.thread, nullptr); if (rc2) { - std::cout << "Error:unable to join," << rc2 << std::endl; + std::cout << "Error:unable to join," << rc2 << std::endl; } - - //const auto &data(thread_pair.data); - - for(int index = 0; index < (int) thread_pair.data.cluster_vector.size(); ++index) + + // const auto &data(thread_pair.data); + + for (int index = 0; index < (int) thread_pair.data.cluster_vector.size(); ++index) { - auto cluster = thread_pair.data.cluster_vector[index]; - const auto ckey = thread_pair.data.cluster_key_vector[index]; - - m_clusterlist->addClusterSpecifyKey(ckey, cluster); + auto *cluster = thread_pair.data.cluster_vector[index]; + const auto ckey = thread_pair.data.cluster_key_vector[index]; + + m_clusterlist->addClusterSpecifyKey(ckey, cluster); } } } @@ -1067,5 +1024,4 @@ int LaserClusterizer::process_event(PHCompositeNode *topNode) } return Fun4AllReturnCodes::EVENT_OK; - } diff --git a/offline/packages/tpc/LaserEventIdentifier.cc b/offline/packages/tpc/LaserEventIdentifier.cc index 8b6035db05..5968d2f09f 100644 --- a/offline/packages/tpc/LaserEventIdentifier.cc +++ b/offline/packages/tpc/LaserEventIdentifier.cc @@ -130,7 +130,7 @@ int LaserEventIdentifier::process_event(PHCompositeNode *topNode) } else if(m_runnumber > 66153) { - if ((gl1pkt->getGTMAllBusyVector() & (1<<14)) == 0) + if ((gl1pkt->getGTMAllBusyVector() & (1U<<14U)) == 0) { m_laserEventInfo->setIsGl1LaserEvent(true); m_laserEventInfo->setIsGl1LaserPileupEvent(false); diff --git a/offline/packages/tpc/Tpc3DClusterizer.cc b/offline/packages/tpc/Tpc3DClusterizer.cc index e19cbf507f..562231b71b 100644 --- a/offline/packages/tpc/Tpc3DClusterizer.cc +++ b/offline/packages/tpc/Tpc3DClusterizer.cc @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -72,7 +73,7 @@ int Tpc3DClusterizer::InitRun(PHCompositeNode *topNode) } // Create the Cluster node if required - auto laserclusters = findNode::getClass(dstNode, "LASER_CLUSTER"); + auto *laserclusters = findNode::getClass(dstNode, "LASER_CLUSTER"); if (!laserclusters) { PHNodeIterator dstiter(dstNode); @@ -111,13 +112,14 @@ int Tpc3DClusterizer::InitRun(PHCompositeNode *topNode) m_clusterTree->Branch("time_erase", &time_erase); m_clusterTree->Branch("time_all", &time_all); } - - if (m_output){ + + if (m_output) + { m_outputFile = new TFile(m_outputFileName.c_str(), "RECREATE"); - m_clusterNT = new TNtuple("clus3D", "clus3D","event:seed:x:y:z:r:phi:phibin:tbin:adc:maxadc:layer:phielem:zelem:size:phisize:tsize:lsize"); + m_clusterNT = new TNtuple("clus3D", "clus3D", "event:seed:x:y:z:r:phi:phibin:tbin:adc:maxadc:layer:phielem:zelem:size:phisize:tsize:lsize"); } - + m_geom_container = findNode::getClass(topNode, "TPCGEOMCONTAINER"); if (!m_geom_container) @@ -145,10 +147,13 @@ int Tpc3DClusterizer::InitRun(PHCompositeNode *topNode) int Tpc3DClusterizer::process_event(PHCompositeNode *topNode) { ++m_event; - recoConsts* rc = recoConsts::instance(); - if (rc->FlagExist("RANDOMSEED")){ - m_seed = (int)rc->get_IntFlag("RANDOMSEED"); - } else { + recoConsts *rc = recoConsts::instance(); + if (rc->FlagExist("RANDOMSEED")) + { + m_seed = rc->get_IntFlag("RANDOMSEED"); + } + else + { m_seed = std::numeric_limits::quiet_NaN(); } @@ -163,11 +168,12 @@ int Tpc3DClusterizer::process_event(PHCompositeNode *topNode) } // get node containing the digitized hits m_hits = findNode::getClass(topNode, "TRKR_HITSET"); - if (!m_hits){ + if (!m_hits) + { std::cout << PHWHERE << "ERROR: Can't find node TRKR_HITSET" << std::endl; return Fun4AllReturnCodes::ABORTRUN; } - + // get node for clusters m_clusterlist = findNode::getClass(topNode, "LASER_CLUSTER"); if (!m_clusterlist) @@ -193,7 +199,8 @@ int Tpc3DClusterizer::process_event(PHCompositeNode *topNode) bgi::rtree> rtree_reject; for (TrkrHitSetContainer::ConstIterator hitsetitr = hitsetrange.first; hitsetitr != hitsetrange.second; - ++hitsetitr){ + ++hitsetitr) + { TrkrHitSet *hitset = hitsetitr->second; unsigned int layer = TrkrDefs::getLayer(hitsetitr->first); int side = TpcDefs::getSide(hitsetitr->first); @@ -202,49 +209,54 @@ int Tpc3DClusterizer::process_event(PHCompositeNode *topNode) TrkrHitSet::ConstRange hitrangei = hitset->getHits(); for (TrkrHitSet::ConstIterator hitr = hitrangei.first; - hitr != hitrangei.second; - ++hitr){ + hitr != hitrangei.second; + ++hitr) + { int iphi = TpcDefs::getPad(hitr->first); int it = TpcDefs::getTBin(hitr->first); // std::cout << " iphi: " << iphi << " it: " << it << std::endl; - float_t fadc = (hitr->second->getAdc());// - m_pedestal; // proper int rounding +0.5 + float_t fadc = (hitr->second->getAdc()); // - m_pedestal; // proper int rounding +0.5 unsigned short adc = 0; - if (fadc > 0){ - adc = (unsigned short) fadc; + if (fadc > 0) + { + adc = (unsigned short) fadc; } - if (adc <= 0){ - continue; + if (adc <= 0) + { + continue; } - + std::vector testduplicate; rtree.query(bgi::intersects(box(point(layer - 0.001, iphi - 0.001, it - 0.001), - point(layer + 0.001, iphi + 0.001, it + 0.001))), - std::back_inserter(testduplicate)); - if (!testduplicate.empty()){ - testduplicate.clear(); - continue; + point(layer + 0.001, iphi + 0.001, it + 0.001))), + std::back_inserter(testduplicate)); + if (!testduplicate.empty()) + { + testduplicate.clear(); + continue; } TrkrDefs::hitkey hitKey = TpcDefs::genHitKey(iphi, it); - + auto spechitkey = std::make_pair(hitKey, hitsetKey); rtree_reject.insert(std::make_pair(point(1.0 * layer, 1.0 * iphi, 1.0 * it), spechitkey)); } } - + std::multimap, std::array>> adcMap; // std::cout << "n hitsets: " << std::distance(hitsetrange.first,hitsetrange.second) // << std::endl; for (TrkrHitSetContainer::ConstIterator hitsetitr = hitsetrange.first; hitsetitr != hitsetrange.second; - ++hitsetitr){ + ++hitsetitr) + { TrkrHitSet *hitset = hitsetitr->second; unsigned int layer = TrkrDefs::getLayer(hitsetitr->first); int side = TpcDefs::getSide(hitsetitr->first); unsigned int sector = TpcDefs::getSectorId(hitsetitr->first); - //PHG4TpcGeom *layergeom = m_geom_container->GetLayerCellGeom(layer); - // double r = layergeom->get_radius(); - + // PHG4TpcGeom *layergeom = m_geom_container->GetLayerCellGeom(layer); + // double r = layergeom->get_radius(); + TrkrDefs::hitsetkey hitsetKey = TpcDefs::genHitSetKey(layer, sector, side); TrkrHitSet::ConstRange hitrangei = hitset->getHits(); @@ -252,74 +264,122 @@ int Tpc3DClusterizer::process_event(PHCompositeNode *topNode) // << std::endl; // int nhits = 0; for (TrkrHitSet::ConstIterator hitr = hitrangei.first; - hitr != hitrangei.second; - ++hitr){ + hitr != hitrangei.second; + ++hitr) + { int iphi = TpcDefs::getPad(hitr->first); int it = TpcDefs::getTBin(hitr->first); // std::cout << " iphi: " << iphi << " it: " << it << std::endl; - float_t fadc = (hitr->second->getAdc());// - m_pedestal; // proper int rounding +0.5 + float_t fadc = (hitr->second->getAdc()); // - m_pedestal; // proper int rounding +0.5 unsigned short adc = 0; // std::cout << " nhit: " << nhits++ << "adc: " << fadc << " phi: " << iphi << " it: " << it << std::endl; - if (fadc > 0){ - adc = (unsigned short) fadc; + if (fadc > 0) + { + adc = (unsigned short) fadc; } - if (adc <= 0){ - continue; + if (adc <= 0) + { + continue; } - if(layer>=7+32){ - //if(side==1)continue; - if(abs(iphi-0)<=2) continue; - if(abs(iphi-191)<=2) continue; - if(abs(iphi-206)<=1) continue; - if(abs(iphi-383)<=2) continue; - if(abs(iphi-576)<=2) continue; - if(abs(iphi-767)<=2) continue; - if(abs(iphi-960)<=2) continue; - if(abs(iphi-1522)<=2) continue; - if(abs(iphi-1344)<=2) continue; - if(abs(iphi-1536)<=2) continue; - if(abs(iphi-1728)<=2) continue; - if(abs(iphi-1920)<=2) continue; - if(abs(iphi-2111)<=2) continue; - if(abs(iphi-2303)<=2) continue; + if (layer >= 7 + 32) + { + // if(side==1)continue; + if (abs(iphi - 0) <= 2) + { + continue; + } + if (abs(iphi - 191) <= 2) + { + continue; + } + if (abs(iphi - 206) <= 1) + { + continue; + } + if (abs(iphi - 383) <= 2) + { + continue; + } + if (abs(iphi - 576) <= 2) + { + continue; + } + if (abs(iphi - 767) <= 2) + { + continue; + } + if (abs(iphi - 960) <= 2) + { + continue; + } + if (abs(iphi - 1522) <= 2) + { + continue; + } + if (abs(iphi - 1344) <= 2) + { + continue; + } + if (abs(iphi - 1536) <= 2) + { + continue; + } + if (abs(iphi - 1728) <= 2) + { + continue; + } + if (abs(iphi - 1920) <= 2) + { + continue; + } + if (abs(iphi - 2111) <= 2) + { + continue; + } + if (abs(iphi - 2303) <= 2) + { + continue; + } } /* double phi = layergeom->get_phi(iphi); double m_sampa_tbias = 39.6; double zdriftlength = (layergeom->get_zcenter(it)+ m_sampa_tbias) * m_tGeometry->get_drift_velocity(); - + float x = r * cos(phi); float y = r * sin(phi); float z = m_tdriftmax * m_tGeometry->get_drift_velocity() - zdriftlength; if (side == 0){ - z = -z; - it = -it; + z = -z; + it = -it; } */ std::array coords = {(int) layer, iphi, it}; - + std::vector testduplicate; rtree.query(bgi::intersects(box(point(layer - 0.001, iphi - 0.001, it - 0.001), - point(layer + 0.001, iphi + 0.001, it + 0.001))), - std::back_inserter(testduplicate)); - if (!testduplicate.empty()){ - testduplicate.clear(); - continue; + point(layer + 0.001, iphi + 0.001, it + 0.001))), + std::back_inserter(testduplicate)); + if (!testduplicate.empty()) + { + testduplicate.clear(); + continue; } - - //test for isolated hit + + // test for isolated hit std::vector testisolated; rtree_reject.query(bgi::intersects(box(point(layer - 1.001, iphi - 1.001, it - 1.001), - point(layer + 1.001, iphi + 1.001, it + 1.001))), - std::back_inserter(testisolated)); - if(testisolated.size()==1){ - //testisolated.clear(); - continue; + point(layer + 1.001, iphi + 1.001, it + 1.001))), + std::back_inserter(testisolated)); + if (testisolated.size() == 1) + { + // testisolated.clear(); + continue; } - + TrkrDefs::hitkey hitKey = TpcDefs::genHitKey(iphi, it); - + auto spechitkey = std::make_pair(hitKey, hitsetKey); auto keyCoords = std::make_pair(spechitkey, coords); adcMap.insert(std::make_pair(adc, keyCoords)); @@ -327,38 +387,43 @@ int Tpc3DClusterizer::process_event(PHCompositeNode *topNode) rtree.insert(std::make_pair(point(1.0 * layer, 1.0 * iphi, 1.0 * it), spechitkey)); } } - - if (Verbosity() > 1){ + + if (Verbosity() > 1) + { std::cout << "finished looping over hits" << std::endl; std::cout << "map size: " << adcMap.size() << std::endl; std::cout << "rtree size: " << rtree.size() << std::endl; } - + // done filling rTree - + t_all->restart(); - - while (adcMap.size() > 0){ + + while (!adcMap.empty()) + { auto iterKey = adcMap.rbegin(); - if (iterKey == adcMap.rend()){ + if (iterKey == adcMap.rend()) + { break; } - + auto coords = iterKey->second.second; int layer = coords[0]; int iphi = coords[1]; int it = coords[2]; - + int layerMax = layer + 1; - if (layer == 22 || layer == 38 || layer == 54){ + if (layer == 22 || layer == 38 || layer == 54) + { layerMax = layer; } int layerMin = layer - 1; - if (layer == 7 || layer == 23 || layer == 39){ + if (layer == 7 || layer == 23 || layer == 39) + { layerMin = layer; } - + std::vector clusHits; t_search->restart(); @@ -376,21 +441,24 @@ int Tpc3DClusterizer::process_event(PHCompositeNode *topNode) clusHits.clear(); } - if (m_debug){ + if (m_debug) + { m_nClus = (int) m_eventClusters.size(); } t_all->stop(); - if (m_debug){ + if (m_debug) + { time_search = t_search->get_accumulated_time() / 1000.; time_clus = t_clus->get_accumulated_time() / 1000.; time_erase = t_erase->get_accumulated_time() / 1000.; time_all = t_all->get_accumulated_time() / 1000.; - + m_clusterTree->Fill(); } - - if (Verbosity()){ + + if (Verbosity()) + { std::cout << "rtree search time: " << t_search->get_accumulated_time() / 1000. << " sec" << std::endl; std::cout << "clustering time: " << t_clus->get_accumulated_time() / 1000. << " sec" << std::endl; std::cout << "erasing time: " << t_erase->get_accumulated_time() / 1000. << " sec" << std::endl; @@ -401,30 +469,33 @@ int Tpc3DClusterizer::process_event(PHCompositeNode *topNode) return Fun4AllReturnCodes::EVENT_OK; } -int Tpc3DClusterizer::ResetEvent(PHCompositeNode * /*topNode*/){ +int Tpc3DClusterizer::ResetEvent(PHCompositeNode * /*topNode*/) +{ m_itHist_0->Reset(); m_itHist_1->Reset(); - + if (m_debug) - { - m_tHist_0->Reset(); - m_tHist_1->Reset(); - - m_eventClusters.clear(); - } - + { + m_tHist_0->Reset(); + m_tHist_1->Reset(); + + m_eventClusters.clear(); + } + return Fun4AllReturnCodes::EVENT_OK; } int Tpc3DClusterizer::End(PHCompositeNode * /*topNode*/) { - if (m_debug){ + if (m_debug) + { m_debugFile->cd(); m_clusterTree->Write(); m_debugFile->Close(); } - if (m_output){ + if (m_output) + { m_outputFile->cd(); m_clusterNT->Write(); m_outputFile->Close(); @@ -434,7 +505,7 @@ int Tpc3DClusterizer::End(PHCompositeNode * /*topNode*/) void Tpc3DClusterizer::calc_cluster_parameter(std::vector &clusHits, std::multimap, std::array>> &adcMap) { - //std::cout << "nu clus" << std::endl; + // std::cout << "nu clus" << std::endl; double rSum = 0.0; double phiSum = 0.0; double tSum = 0.0; @@ -449,9 +520,12 @@ void Tpc3DClusterizer::calc_cluster_parameter(std::vector &clusHi TrkrDefs::hitsetkey maxKey = 0; unsigned int nHits = clusHits.size(); - int iphimin = 6666, iphimax = -1; - int ilaymin = 6666, ilaymax = -1; - float itmin = 66666666.6, itmax = -6666666666.6; + int iphimin = 6666; + int iphimax = -1; + int ilaymin = 6666; + int ilaymax = -1; + float itmin = 66666666.6; + float itmax = -6666666666.6; auto *clus = new LaserClusterv1; for (auto &clusHit : clusHits) @@ -468,21 +542,21 @@ void Tpc3DClusterizer::calc_cluster_parameter(std::vector &clusHi double phi = layergeom->get_phi(coords[1], side); double t = layergeom->get_zcenter(fabs(coords[2])); int tbin = coords[2]; - int lay = coords[0];//TrkrDefs::getLayer(spechitkey.second); + int lay = coords[0]; // TrkrDefs::getLayer(spechitkey.second); double hitzdriftlength = t * m_tGeometry->get_drift_velocity(); double hitZ = m_tdriftmax * m_tGeometry->get_drift_velocity() - hitzdriftlength; /*std::cout << " lay: " << lay - << " phi: " << phi - << " t: " << t - << " side: " << side - << std::endl; + << " phi: " << phi + << " t: " << t + << " side: " << side + << std::endl; */ - if(phiiphimax){iphimax = phi;} - if(layilaymax){ilaymax = lay;} - if(tbinitmax){itmax = tbin;} + iphimin = std::min(phi, iphimin); + iphimax = std::max(phi, iphimax); + ilaymin = std::min(lay, ilaymin); + ilaymax = std::max(lay, ilaymax); + itmin = std::min(tbin, itmin); + itmax = std::max(tbin, itmax); for (auto &iterKey : adcMap) { @@ -522,7 +596,7 @@ void Tpc3DClusterizer::calc_cluster_parameter(std::vector &clusHi if (nHits == 0) { - std::cout << "no hits"<< std::endl; + std::cout << "no hits" << std::endl; return; } @@ -554,55 +628,57 @@ void Tpc3DClusterizer::calc_cluster_parameter(std::vector &clusHi clus->setLayer(layerSum / adcSum); clus->setIPhi(iphiSum / adcSum); clus->setIT(itSum / adcSum); - int phisize = iphimax - iphimin + 1; - int lsize = ilaymax - ilaymin + 1; - int tsize = itmax - itmin +1; + int phisize = iphimax - iphimin + 1; + int lsize = ilaymax - ilaymin + 1; + int tsize = itmax - itmin + 1; if (m_debug) { m_currentCluster = (LaserCluster *) clus->CloneMe(); m_eventClusters.push_back((LaserCluster *) m_currentCluster->CloneMe()); } // if(nHits>1&&tsize>5){ - if(nHits>=1){ + if (nHits >= 1) + { const auto ckey = TrkrDefs::genClusKey(maxKey, m_clusterlist->size()); m_clusterlist->addClusterSpecifyKey(ckey, clus); - } else { + } + else + { delete clus; } - - //event:seed:x:y:z:r:phi:phibin:tbin::adc:maxadc:layer:phielem:zelem:size:phisize:tsize:lsize + // event:seed:x:y:z:r:phi:phibin:tbin::adc:maxadc:layer:phielem:zelem:size:phisize:tsize:lsize //"event:seed:x:y:z:r:phi:phibin:tbin::adc:maxadc:layer:phielem:zelem:size:phisize:tsize:lsize" /* std::cout << " l size: " << lsize - << " phisize : " << phisize - << " tsize: " << tsize - << " maxside: " << maxside - << std::endl; + << " phisize : " << phisize + << " tsize: " << tsize + << " maxside: " << maxside + << std::endl; */ // if (m_output){ - float fX[20] = {0}; - int n = 0; - fX[n++] = m_event; - fX[n++] = m_seed; - fX[n++] = clusX; - fX[n++] = clusY; - fX[n++] = clusZ; - fX[n++] = clusR; - fX[n++] = clusPhi; - fX[n++] = clusiPhi; - fX[n++] = clusT; - fX[n++] = adcSum; - fX[n++] = maxAdc; - fX[n++] = (layerSum/adcSum); - fX[n++] = maxsector; - fX[n++] = maxside; - fX[n++] = nHits; - fX[n++] = phisize; - fX[n++] = tsize; - fX[n++] = lsize; - m_clusterNT->Fill(fX); - // } + float fX[20] = {0}; + int n = 0; + fX[n++] = m_event; + fX[n++] = m_seed; + fX[n++] = clusX; + fX[n++] = clusY; + fX[n++] = clusZ; + fX[n++] = clusR; + fX[n++] = clusPhi; + fX[n++] = clusiPhi; + fX[n++] = clusT; + fX[n++] = adcSum; + fX[n++] = maxAdc; + fX[n++] = (layerSum / adcSum); + fX[n++] = maxsector; + fX[n++] = maxside; + fX[n++] = nHits; + fX[n++] = phisize; + fX[n++] = tsize; + fX[n++] = lsize; + m_clusterNT->Fill(fX); + // } } void Tpc3DClusterizer::remove_hits(std::vector &clusHits, bgi::rtree> &rtree, std::multimap, std::array>> &adcMap) @@ -611,10 +687,11 @@ void Tpc3DClusterizer::remove_hits(std::vector &clusHits, bgi::rt { auto spechitkey = clusHit.second; - if(rtree.size()==0){ + if (rtree.empty()) + { std::cout << "not good" << std::endl; } - //rtree.remove(clusHit); + // rtree.remove(clusHit); for (auto iterAdc = adcMap.begin(); iterAdc != adcMap.end();) { @@ -623,10 +700,8 @@ void Tpc3DClusterizer::remove_hits(std::vector &clusHits, bgi::rt iterAdc = adcMap.erase(iterAdc); break; } - else - { - ++iterAdc; - } + + ++iterAdc; } } } diff --git a/offline/packages/tpc/TpcClusterMover.cc b/offline/packages/tpc/TpcClusterMover.cc index 643fe5587f..39c5e156d4 100644 --- a/offline/packages/tpc/TpcClusterMover.cc +++ b/offline/packages/tpc/TpcClusterMover.cc @@ -17,19 +17,20 @@ namespace { - [[maybe_unused]] std::ostream& operator << (std::ostream& out, const Acts::Vector3& v ) + [[maybe_unused]] std::ostream& operator<<(std::ostream& out, const Acts::Vector3& v) { out << "(" << v.x() << ", " << v.y() << ", " << v.z() << ")"; return out; } -} +} // namespace TpcClusterMover::TpcClusterMover() + : inner_tpc_spacing((mid_tpc_min_radius - inner_tpc_min_radius) / 16.0) + , mid_tpc_spacing((outer_tpc_min_radius - mid_tpc_min_radius) / 16.0) + , outer_tpc_spacing((outer_tpc_max_radius - outer_tpc_min_radius) / 16.0) { // initialize layer radii - inner_tpc_spacing = (mid_tpc_min_radius - inner_tpc_min_radius) / 16.0; - mid_tpc_spacing = (outer_tpc_min_radius - mid_tpc_min_radius) / 16.0; - outer_tpc_spacing = (outer_tpc_max_radius - outer_tpc_min_radius) / 16.0; + for (int i = 0; i < 16; ++i) { layer_radius[i] = inner_tpc_min_radius + (double) i * inner_tpc_spacing + 0.5 * inner_tpc_spacing; @@ -44,7 +45,7 @@ TpcClusterMover::TpcClusterMover() } } -void TpcClusterMover::initialize_geometry(PHG4TpcGeomContainer *cellgeo) +void TpcClusterMover::initialize_geometry(PHG4TpcGeomContainer* cellgeo) { if (_verbosity > 0) { @@ -65,7 +66,6 @@ void TpcClusterMover::initialize_geometry(PHG4TpcGeomContainer *cellgeo) //____________________________________________________________________________.. std::vector> TpcClusterMover::processTrack(const std::vector>& global_in) { - // Get the global positions of the TPC clusters for this track, already corrected for distortions, and move them to the surfaces // The input object contains all clusters for the track @@ -74,7 +74,7 @@ std::vector> TpcClusterMover::proces std::vector tpc_global_vec; std::vector tpc_cluskey_vec; - for (const auto& [ckey,global]:global_in) + for (const auto& [ckey, global] : global_in) { const auto trkrid = TrkrDefs::getTrkrId(ckey); if (trkrid == TrkrDefs::tpcId) @@ -85,7 +85,7 @@ std::vector> TpcClusterMover::proces else { // si clusters stay where they are - global_moved.emplace_back(ckey,global); + global_moved.emplace_back(ckey, global); } } @@ -158,7 +158,7 @@ std::vector> TpcClusterMover::proces return global_moved; } -int TpcClusterMover::get_circle_circle_intersection(double target_radius, double R, double X0, double Y0, double xclus, double yclus, double &x, double &y) +int TpcClusterMover::get_circle_circle_intersection(double target_radius, double R, double X0, double Y0, double xclus, double yclus, double& x, double& y) const { // finds the intersection of the fitted circle with the cylinder having radius = target_radius const auto [xplus, yplus, xminus, yminus] = TrackFitUtils::circle_circle_intersection(target_radius, R, X0, Y0); diff --git a/offline/packages/tpc/TpcClusterMover.h b/offline/packages/tpc/TpcClusterMover.h index dc67312f7f..92a053e990 100644 --- a/offline/packages/tpc/TpcClusterMover.h +++ b/offline/packages/tpc/TpcClusterMover.h @@ -27,7 +27,7 @@ class TpcClusterMover void initialize_geometry(PHG4TpcGeomContainer *cellgeo); private: - int get_circle_circle_intersection(double target_radius, double R, double X0, double Y0, double xclus, double yclus, double &x, double &y); + int get_circle_circle_intersection(double target_radius, double R, double X0, double Y0, double xclus, double yclus, double &x, double &y) const; double _z_start = 0.0; double _y_start = 0.0; diff --git a/offline/packages/tpc/TpcClusterizer.cc b/offline/packages/tpc/TpcClusterizer.cc index bd5fc3c340..05fb1fe121 100644 --- a/offline/packages/tpc/TpcClusterizer.cc +++ b/offline/packages/tpc/TpcClusterizer.cc @@ -25,7 +25,6 @@ #include #include #include -#include #include #include // for SubsysReco @@ -50,6 +49,7 @@ #include +#include #include #include // for sqrt, cos, sin #include @@ -64,7 +64,7 @@ namespace { template - inline constexpr T square(const T &x) + constexpr T square(const T &x) { return x * x; } @@ -365,20 +365,14 @@ namespace int isosum = 0; int isophimin = iphi - 1; - if (isophimin < 0) - { - isophimin = 0; - } + isophimin = std::max(isophimin, 0); int isophimax = iphi + 1; if (!(isophimax < NPhiBinsMax)) { isophimax = NPhiBinsMax - 1; } int isotmin = it - 1; - if (isotmin < 0) - { - isotmin = 0; - } + isotmin = std::max(isotmin, 0); int isotmax = it + 1; if (!(isotmax < NTBinsMax)) { @@ -537,30 +531,15 @@ namespace continue; } - if (adc > max_adc) - { - max_adc = adc; - } + max_adc = std::max(adc, max_adc); - if (iphi > phibinhi) - { - phibinhi = iphi; - } + phibinhi = std::max(iphi, phibinhi); - if (iphi < phibinlo) - { - phibinlo = iphi; - } + phibinlo = std::min(iphi, phibinlo); - if (it > tbinhi) - { - tbinhi = it; - } + tbinhi = std::max(it, tbinhi); - if (it < tbinlo) - { - tbinlo = it; - } + tbinlo = std::min(it, tbinlo); // if(it==it_center){ yg_sum += adc; } // update phi sums @@ -686,7 +665,7 @@ namespace // std::cout << "clus num" << my_data.cluster_vector.size() << " X " << local(0) << " Y " << clust << std::endl; if (sqrt(phi_err_square) > my_data.min_err_squared) { - auto clus = new TrkrClusterv5; + auto *clus = new TrkrClusterv5; // auto clus = std::make_unique(); clus_base = clus; clus->setAdc(adc_sum); @@ -738,19 +717,19 @@ namespace if (my_data.fillClusHitsVerbose && b_made_cluster) { // push the data back to - my_data.phivec_ClusHitsVerbose.push_back(std::vector>{}); - my_data.zvec_ClusHitsVerbose.push_back(std::vector>{}); + my_data.phivec_ClusHitsVerbose.emplace_back(); + my_data.zvec_ClusHitsVerbose.emplace_back(); auto &vphi = my_data.phivec_ClusHitsVerbose.back(); auto &vz = my_data.zvec_ClusHitsVerbose.back(); for (auto &entry : m_phi) { - vphi.push_back({entry.first, entry.second}); + vphi.emplace_back(entry.first, entry.second); } for (auto &entry : m_z) { - vz.push_back({entry.first, entry.second}); + vz.emplace_back(entry.first, entry.second); } } @@ -875,7 +854,7 @@ namespace } if (adc > my_data->edge_threshold) { - adcval[phibin][tbin] = (unsigned short) adc; + adcval[phibin][tbin] = adc; } } } @@ -967,7 +946,7 @@ namespace } */ // std::cout << "done filling " << std::endl; - while (all_hit_map.size() > 0) + while (!all_hit_map.empty()) { // std::cout << "all hit map size: " << all_hit_map.size() << std::endl; auto iter = all_hit_map.rbegin(); @@ -1013,22 +992,10 @@ namespace { continue; } - if (wiphi > wphibinhi) - { - wphibinhi = wiphi; - } - if (wiphi < wphibinlo) - { - wphibinlo = wiphi; - } - if (wit > wtbinhi) - { - wtbinhi = wit; - } - if (wit < wtbinlo) - { - wtbinlo = wit; - } + wphibinhi = std::max(wiphi, wphibinhi); + wphibinlo = std::min(wiphi, wphibinlo); + wtbinhi = std::max(wit, wtbinhi); + wtbinlo = std::min(wit, wtbinlo); } char wtsize = wtbinhi - wtbinlo + 1; char wphisize = wphibinhi - wphibinlo + 1; @@ -1077,7 +1044,7 @@ namespace } void *ProcessSector(void *threadarg) { - auto my_data = static_cast(threadarg); + auto *my_data = static_cast(threadarg); ProcessSectorData(my_data); pthread_exit(nullptr); } @@ -1133,7 +1100,7 @@ int TpcClusterizer::InitRun(PHCompositeNode *topNode) } // Create the Cluster node if required - auto trkrclusters = findNode::getClass(dstNode, "TRKR_CLUSTER"); + auto *trkrclusters = findNode::getClass(dstNode, "TRKR_CLUSTER"); if (!trkrclusters) { PHNodeIterator dstiter(dstNode); @@ -1151,7 +1118,7 @@ int TpcClusterizer::InitRun(PHCompositeNode *topNode) DetNode->addNode(TrkrClusterContainerNode); } - auto clusterhitassoc = findNode::getClass(topNode, "TRKR_CLUSTERHITASSOC"); + auto *clusterhitassoc = findNode::getClass(topNode, "TRKR_CLUSTERHITASSOC"); if (!clusterhitassoc) { PHNodeIterator dstiter(dstNode); @@ -1168,7 +1135,7 @@ int TpcClusterizer::InitRun(PHCompositeNode *topNode) DetNode->addNode(newNode); } - auto training_container = findNode::getClass(dstNode, "TRAINING_HITSET"); + auto *training_container = findNode::getClass(dstNode, "TRAINING_HITSET"); if (!training_container) { PHNodeIterator dstiter(dstNode); @@ -1217,18 +1184,18 @@ int TpcClusterizer::InitRun(PHCompositeNode *topNode) if (!mClusHitsVerbose) { PHNodeIterator dstiter(dstNode); - auto DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); + auto *DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); if (!DetNode) { DetNode = new PHCompositeNode("TRKR"); dstNode->addNode(DetNode); } mClusHitsVerbose = new ClusHitsVerbosev1(); - auto newNode = new PHIODataNode(mClusHitsVerbose, "Trkr_SvtxClusHitsVerbose", "PHObject"); + auto *newNode = new PHIODataNode(mClusHitsVerbose, "Trkr_SvtxClusHitsVerbose", "PHObject"); DetNode->addNode(newNode); } } - auto geom = + auto *geom = findNode::getClass(topNode, "TPCGEOMCONTAINER"); if (!geom) { @@ -1489,18 +1456,18 @@ int TpcClusterizer::process_event(PHCompositeNode *topNode) const auto ckey = TrkrDefs::genClusKey(hitsetkey, index); // get cluster - auto cluster = data.cluster_vector[index]; + auto *cluster = data.cluster_vector[index]; // insert in map m_clusterlist->addClusterSpecifyKey(ckey, cluster); if (mClusHitsVerbose) { - for (auto &hit : data.phivec_ClusHitsVerbose[index]) + for (const auto &hit : data.phivec_ClusHitsVerbose[index]) { mClusHitsVerbose->addPhiHit(hit.first, hit.second); } - for (auto &hit : data.zvec_ClusHitsVerbose[index]) + for (const auto &hit : data.zvec_ClusHitsVerbose[index]) { mClusHitsVerbose->addZHit(hit.first, hit.second); } @@ -1624,7 +1591,7 @@ int TpcClusterizer::process_event(PHCompositeNode *topNode) const auto ckey = TrkrDefs::genClusKey(hitsetkey, index); // get cluster - auto cluster = data.cluster_vector[index]; + auto *cluster = data.cluster_vector[index]; // insert in map m_clusterlist->addClusterSpecifyKey(ckey, cluster); @@ -1668,7 +1635,7 @@ int TpcClusterizer::process_event(PHCompositeNode *topNode) const auto ckey = TrkrDefs::genClusKey(hitsetkey, index); // get cluster - auto cluster = data.cluster_vector[index]; + auto *cluster = data.cluster_vector[index]; // insert in map // std::cout << "X: " << cluster->getLocalX() << "Y: " << cluster->getLocalY() << std::endl; @@ -1676,11 +1643,11 @@ int TpcClusterizer::process_event(PHCompositeNode *topNode) if (mClusHitsVerbose) { - for (auto &hit : data.phivec_ClusHitsVerbose[index]) + for (const auto &hit : data.phivec_ClusHitsVerbose[index]) { mClusHitsVerbose->addPhiHit(hit.first, (float) hit.second); } - for (auto &hit : data.zvec_ClusHitsVerbose[index]) + for (const auto &hit : data.zvec_ClusHitsVerbose[index]) { mClusHitsVerbose->addZHit(hit.first, (float) hit.second); } @@ -1698,7 +1665,7 @@ int TpcClusterizer::process_event(PHCompositeNode *topNode) m_clusterhitassoc->addAssoc(ckey, hkey); } - for (auto v_hit : thread_pair.data.v_hits) + for (auto *v_hit : thread_pair.data.v_hits) { if (_store_hits) { diff --git a/offline/packages/tpc/TpcCombinedRawDataUnpacker.cc b/offline/packages/tpc/TpcCombinedRawDataUnpacker.cc index c194567d58..5f276c3c3a 100644 --- a/offline/packages/tpc/TpcCombinedRawDataUnpacker.cc +++ b/offline/packages/tpc/TpcCombinedRawDataUnpacker.cc @@ -57,7 +57,7 @@ void TpcCombinedRawDataUnpacker::ReadZeroSuppressedData() { m_do_zs_emulation = true; m_do_baseline_corr = false; - auto cdb = CDBInterface::instance(); + auto *cdb = CDBInterface::instance(); std::string dir = cdb->getUrl("TPC_ZS_THRESHOLDS"); auto cdbtree = std::make_unique(dir); @@ -75,7 +75,7 @@ void TpcCombinedRawDataUnpacker::ReadZeroSuppressedData() { name.str(""); name << "R"<GetSingleFloatValue(name.str().c_str()); + m_zs_threshold[i] = cdbtree->GetSingleFloatValue(name.str()); if(Verbosity() > 1) { std::cout << "Loading ADU threshold of " << m_zs_threshold[i] << " for region " << i << std::endl; diff --git a/offline/packages/tpc/TpcCombinedRawDataUnpackerDebug.cc b/offline/packages/tpc/TpcCombinedRawDataUnpackerDebug.cc index 0bb412197f..803a822aa9 100644 --- a/offline/packages/tpc/TpcCombinedRawDataUnpackerDebug.cc +++ b/offline/packages/tpc/TpcCombinedRawDataUnpackerDebug.cc @@ -34,6 +34,7 @@ #include #include +#include #include #include // for exit #include // for exit @@ -234,14 +235,8 @@ int TpcCombinedRawDataUnpackerDebug::process_event(PHCompositeNode* topNode) TpcRawHit* tpchit = tpccont->get_hit(i); uint64_t gtm_bco = tpchit->get_gtm_bco(); - if (gtm_bco < bco_min) - { - bco_min = gtm_bco; - } - if (gtm_bco > bco_max) - { - bco_max = gtm_bco; - } + bco_min = std::min(gtm_bco, bco_min); + bco_max = std::max(gtm_bco, bco_max); int fee = tpchit->get_fee(); int channel = tpchit->get_channel(); @@ -539,7 +534,7 @@ int TpcCombinedRawDataUnpackerDebug::process_event(PHCompositeNode* topNode) for (int binx = 1; binx < hist2d->GetNbinsX(); binx++) { - double timebin = ((TAxis*) hist2d->GetXaxis())->GetBinCenter(binx); + double timebin = ( hist2d->GetXaxis())->GetBinCenter(binx); std::string histname1d = "h" + std::to_string(hiter.first) + "_" + std::to_string((int) timebin); TH1D* hist1d = hist2d->ProjectionY(histname1d.c_str(), binx, binx); float local_ped = 0; @@ -697,11 +692,8 @@ int TpcCombinedRawDataUnpackerDebug::process_event(PHCompositeNode* topNode) if ((float(adc) - pedestal_offset - corr) > (hpedwidth2 * m_ped_sig_cut)) { float nuadc = (float(adc) - corr - pedestal_offset); - if (nuadc < 0) - { - nuadc = 0; - } - hitr->second->setAdc(float(nuadc)); + nuadc = std::max(nuadc, 0); + hitr->second->setAdc(nuadc); #ifdef DEBUG // hitr->second->setAdc(10); if (tbin == 383 && layer >= 7 + 32 && fee == 21) diff --git a/offline/packages/tpc/TpcDistortionCorrection.cc b/offline/packages/tpc/TpcDistortionCorrection.cc index b759331e77..8974053b48 100644 --- a/offline/packages/tpc/TpcDistortionCorrection.cc +++ b/offline/packages/tpc/TpcDistortionCorrection.cc @@ -15,7 +15,7 @@ namespace { template - inline constexpr T square(const T& x) + constexpr T square(const T& x) { return x * x; } diff --git a/offline/packages/tpc/TpcLoadDistortionCorrection.cc b/offline/packages/tpc/TpcLoadDistortionCorrection.cc index 0ce2ffa4e1..65bf156a7a 100644 --- a/offline/packages/tpc/TpcLoadDistortionCorrection.cc +++ b/offline/packages/tpc/TpcLoadDistortionCorrection.cc @@ -58,7 +58,7 @@ int TpcLoadDistortionCorrection::InitRun(PHCompositeNode* topNode) } /// Get the RUN node and check - auto runNode = dynamic_cast(iter.findFirst("PHCompositeNode", "RUN")); + auto *runNode = dynamic_cast(iter.findFirst("PHCompositeNode", "RUN")); if (!runNode) { std::cout << "TpcLoadDistortionCorrection::InitRun - RUN Node missing, quitting" << std::endl; @@ -74,17 +74,17 @@ int TpcLoadDistortionCorrection::InitRun(PHCompositeNode* topNode) } // get distortion correction object and create if not found - auto distortion_correction_object = findNode::getClass(topNode, m_node_name[i]); + auto *distortion_correction_object = findNode::getClass(topNode, m_node_name[i]); if (!distortion_correction_object) { std::cout << "TpcLoadDistortionCorrection::InitRun - creating TpcDistortionCorrectionContainer in node " << m_node_name[i] << std::endl; distortion_correction_object = new TpcDistortionCorrectionContainer; - auto node = new PHDataNode(distortion_correction_object, m_node_name[i]); + auto *node = new PHDataNode(distortion_correction_object, m_node_name[i]); runNode->addNode(node); } std::cout << "TpcLoadDistortionCorrection::InitRun - reading corrections from " << m_correction_filename[i] << std::endl; - auto distortion_tfile = TFile::Open(m_correction_filename[i].c_str()); + auto *distortion_tfile = TFile::Open(m_correction_filename[i].c_str()); if (!distortion_tfile) { std::cout << "TpcLoadDistortionCorrection::InitRun - cannot open " << m_correction_filename[i] << std::endl; diff --git a/offline/packages/tpc/TpcRawDataTree.cc b/offline/packages/tpc/TpcRawDataTree.cc index 6199fb7425..1141b5de55 100644 --- a/offline/packages/tpc/TpcRawDataTree.cc +++ b/offline/packages/tpc/TpcRawDataTree.cc @@ -61,7 +61,7 @@ int TpcRawDataTree::InitRun(PHCompositeNode * /*unused*/) m_SampleTree->Branch("nWaveormInFrame", &m_nWaveormInFrame, "nWaveormInFrame/I"); m_SampleTree->Branch("maxFEECount", &m_maxFEECount, "maxFEECount/I"); m_SampleTree->Branch("nSamples", &m_nSamples, "nSamples/I"); - m_SampleTree->Branch("adcSamples", &m_adcSamples[0], "adcSamples[nSamples]/s"); + m_SampleTree->Branch("adcSamples", m_adcSamples.data(), "adcSamples[nSamples]/s"); m_SampleTree->Branch("fee", &m_fee, "fee/I"); m_SampleTree->Branch("sampaAddress", &m_sampaAddress, "sampaAddress/I"); m_SampleTree->Branch("sampaChannel", &m_sampaChannel, "sampaChannel/I"); diff --git a/offline/packages/tpc/TpcRawWriter.cc b/offline/packages/tpc/TpcRawWriter.cc index 5d7711e2bb..41c5f26df3 100644 --- a/offline/packages/tpc/TpcRawWriter.cc +++ b/offline/packages/tpc/TpcRawWriter.cc @@ -76,7 +76,7 @@ int TpcRawWriter::InitRun(PHCompositeNode *topNode) } // Create the Cluster node if required - auto trkrclusters = findNode::getClass(dstNode, "TRKR_CLUSTER"); + auto *trkrclusters = findNode::getClass(dstNode, "TRKR_CLUSTER"); if (!trkrclusters) { PHNodeIterator dstiter(dstNode); @@ -94,7 +94,7 @@ int TpcRawWriter::InitRun(PHCompositeNode *topNode) DetNode->addNode(TrkrClusterContainerNode); } - auto clusterhitassoc = findNode::getClass(topNode, "TRKR_CLUSTERHITASSOC"); + auto *clusterhitassoc = findNode::getClass(topNode, "TRKR_CLUSTERHITASSOC"); if (!clusterhitassoc) { PHNodeIterator dstiter(dstNode); @@ -116,7 +116,7 @@ int TpcRawWriter::InitRun(PHCompositeNode *topNode) if (!m_rawhits) { PHNodeIterator dstiter(dstNode); - auto DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); + auto *DetNode = dynamic_cast(dstiter.findFirst("PHCompositeNode", "TRKR")); if (!DetNode) { DetNode = new PHCompositeNode("TRKR"); @@ -124,7 +124,7 @@ int TpcRawWriter::InitRun(PHCompositeNode *topNode) } m_rawhits = new RawHitSetContainerv1; - auto newNode = new PHIODataNode(m_rawhits, "TRKR_RAWHITSET", "PHObject"); + auto *newNode = new PHIODataNode(m_rawhits, "TRKR_RAWHITSET", "PHObject"); DetNode->addNode(newNode); } diff --git a/offline/packages/tpc/TpcSimpleClusterizer.cc b/offline/packages/tpc/TpcSimpleClusterizer.cc index f439d1d682..f1fb0d5b76 100644 --- a/offline/packages/tpc/TpcSimpleClusterizer.cc +++ b/offline/packages/tpc/TpcSimpleClusterizer.cc @@ -33,6 +33,7 @@ #include +#include #include #include // for sqrt, cos, sin #include @@ -46,7 +47,7 @@ namespace { template - inline constexpr T square(const T &x) + constexpr T square(const T &x) { return x * x; } @@ -142,22 +143,10 @@ namespace int iphi = iter.second.first + my_data.phioffset; int iz = iter.second.second + my_data.zoffset; - if (iphi > phibinhi) - { - phibinhi = iphi; - } - if (iphi < phibinlo) - { - phibinlo = iphi; - } - if (iz > zbinhi) - { - zbinhi = iz; - } - if (iz < zbinlo) - { - zbinlo = iz; - } + phibinhi = std::max(iphi, phibinhi); + phibinlo = std::min(iphi, phibinlo); + zbinhi = std::max(iz, zbinhi); + zbinlo = std::min(iz, zbinlo); // update phi sums double phi_center = my_data.layergeom->get_phicenter(iphi, my_data.side); @@ -205,7 +194,7 @@ namespace clusz -= (clusz < 0) ? my_data.par0_neg : my_data.par0_pos; // create cluster and fill - auto clus = new TrkrClusterv3; + auto *clus = new TrkrClusterv3; clus->setAdc(adc_sum); /// Get the surface key to find the surface from the map @@ -280,7 +269,7 @@ namespace void *ProcessSector(void *threadarg) { - auto my_data = (struct thread_data *) threadarg; + auto *my_data = (struct thread_data *) threadarg; const auto &pedestal = my_data->pedestal; const auto &phibins = my_data->phibins; @@ -332,11 +321,11 @@ namespace all_hit_map.insert(std::make_pair(adc, thisHit)); } // adcval[phibin][zbin] = (unsigned short) adc; - adcval[phibin][zbin] = (unsigned short) adc; + adcval[phibin][zbin] = adc; } } - while (all_hit_map.size() > 0) + while (!all_hit_map.empty()) { auto iter = all_hit_map.rbegin(); if (iter == all_hit_map.rend()) @@ -413,7 +402,7 @@ int TpcSimpleClusterizer::InitRun(PHCompositeNode *topNode) } // Create the Cluster node if required - auto trkrclusters = findNode::getClass(dstNode, "TRKR_CLUSTER"); + auto *trkrclusters = findNode::getClass(dstNode, "TRKR_CLUSTER"); if (!trkrclusters) { PHNodeIterator dstiter(dstNode); @@ -431,7 +420,7 @@ int TpcSimpleClusterizer::InitRun(PHCompositeNode *topNode) DetNode->addNode(TrkrClusterContainerNode); } - auto clusterhitassoc = findNode::getClass(topNode, "TRKR_CLUSTERHITASSOC"); + auto *clusterhitassoc = findNode::getClass(topNode, "TRKR_CLUSTERHITASSOC"); if (!clusterhitassoc) { PHNodeIterator dstiter(dstNode); @@ -614,7 +603,7 @@ int TpcSimpleClusterizer::process_event(PHCompositeNode *topNode) const auto ckey = TrkrDefs::genClusKey(hitsetkey, index); // get cluster - auto cluster = data.cluster_vector[index]; + auto *cluster = data.cluster_vector[index]; // insert in map m_clusterlist->addClusterSpecifyKey(ckey, cluster); diff --git a/offline/packages/tpc/TrainingHits.cc b/offline/packages/tpc/TrainingHits.cc index 3a70db0854..20a810b225 100644 --- a/offline/packages/tpc/TrainingHits.cc +++ b/offline/packages/tpc/TrainingHits.cc @@ -1,17 +1,17 @@ #include "TrainingHits.h" TrainingHits::TrainingHits() + : radius(0.) + , phi(0.) + , z(0.) + , phistep(0.) + , zstep(0.) + , layer(0) + , ntouch(0) + , nedge(0) + , cluskey(0) { v_adc.fill(0); - radius = 0.; - phi = 0.; - z = 0.; - phistep = 0.; - zstep = 0.; - layer = 0; - ntouch = 0; - nedge = 0; - cluskey = 0; } void TrainingHits::Reset() From 1ba5701e07a88eaa3ecde2bf040490e06e24effb Mon Sep 17 00:00:00 2001 From: Hugo Pereira Da Costa Date: Mon, 15 Dec 2025 20:18:53 -0500 Subject: [PATCH 013/393] Added sample to hit key. This will allow to use timed hits. --- offline/packages/micromegas/MicromegasDefs.cc | 17 +++++++++++++---- offline/packages/micromegas/MicromegasDefs.h | 8 ++++++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/offline/packages/micromegas/MicromegasDefs.cc b/offline/packages/micromegas/MicromegasDefs.cc index 0766d78b8e..78732951f7 100644 --- a/offline/packages/micromegas/MicromegasDefs.cc +++ b/offline/packages/micromegas/MicromegasDefs.cc @@ -30,6 +30,7 @@ namespace //! bit shift for hit key static constexpr unsigned int kBitShiftStrip = 0; + static constexpr unsigned int kBitShiftSample = 8; } @@ -65,19 +66,27 @@ namespace MicromegasDefs } //________________________________________________________________ - TrkrDefs::hitkey genHitKey(uint16_t strip) + TrkrDefs::hitkey genHitKey(uint16_t strip, uint16_t sample) { - TrkrDefs::hitkey key = strip << kBitShiftStrip; - return key; + const TrkrDefs::hitkey key = strip << kBitShiftStrip; + const TrkrDefs::hitkey tmp = sample << kBitShiftSample; + return key|tmp; } //________________________________________________________________ - uint16_t getStrip( TrkrDefs::hitkey key ) + uint8_t getStrip( TrkrDefs::hitkey key ) { TrkrDefs::hitkey tmp = (key >> kBitShiftStrip); return tmp; } + //________________________________________________________________ + uint16_t getSample( TrkrDefs::hitkey key ) + { + TrkrDefs::hitkey tmp = (key >> kBitShiftSample); + return tmp; + } + //________________________________________________________________ SegmentationType getSegmentationType(TrkrDefs::cluskey key) { diff --git a/offline/packages/micromegas/MicromegasDefs.h b/offline/packages/micromegas/MicromegasDefs.h index c95fdffd72..b206b8f895 100644 --- a/offline/packages/micromegas/MicromegasDefs.h +++ b/offline/packages/micromegas/MicromegasDefs.h @@ -60,11 +60,15 @@ namespace MicromegasDefs /*! * @brief Generate a hitkey from strip index inside tile * @param[in] strip strip index + * @param[in] sample sample index */ - TrkrDefs::hitkey genHitKey(uint16_t strip ); + TrkrDefs::hitkey genHitKey(uint16_t strip, uint16_t sample = 0 ); //! get strip from hit key - uint16_t getStrip(TrkrDefs::hitkey); + uint8_t getStrip(TrkrDefs::hitkey); + + //! get sample from hit key + uint16_t getSample(TrkrDefs::hitkey); /*! * @brief Get the segmentation type from cluster key From 815ceef6091af9d078e45087f67a4a5b4fdd3205 Mon Sep 17 00:00:00 2001 From: Hugo Pereira Da Costa Date: Mon, 15 Dec 2025 22:23:29 -0500 Subject: [PATCH 014/393] Add sample to hit key --- .../MicromegasCombinedDataDecoder.cc | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/offline/packages/micromegas/MicromegasCombinedDataDecoder.cc b/offline/packages/micromegas/MicromegasCombinedDataDecoder.cc index a5269617f7..50bcb97cd6 100644 --- a/offline/packages/micromegas/MicromegasCombinedDataDecoder.cc +++ b/offline/packages/micromegas/MicromegasCombinedDataDecoder.cc @@ -203,13 +203,14 @@ int MicromegasCombinedDataDecoder::process_event(PHCompositeNode* topNode) // loop over sample_range find maximum const auto sample_range = std::make_pair(rawhit->get_sample_begin(), rawhit->get_sample_end()); - std::vector adc_list; + using sample_pair_t = std::pair; + std::vector adc_list; for (auto is = std::max(m_sample_min, sample_range.first); is < std::min(m_sample_max, sample_range.second); ++is) { const uint16_t adc = rawhit->get_adc(is); if (adc != MicromegasDefs::m_adc_invalid) { - adc_list.push_back(adc); + adc_list.emplace_back(is, adc); } } @@ -220,16 +221,18 @@ int MicromegasCombinedDataDecoder::process_event(PHCompositeNode* topNode) // get max adc value in range /* TODO: use more advanced signal processing */ - auto max_adc = *std::max_element(adc_list.begin(), adc_list.end()); + auto max_adc = *std::max_element(adc_list.begin(), adc_list.end(), + [](const sample_pair_t& first, const sample_pair_t& second) + { return first.second < second.second; } ); // compare to hard min_adc value - if (max_adc < m_min_adc) + if (max_adc.second < m_min_adc) { continue; } // compare to threshold - if (max_adc < pedestal + m_n_sigma * rms) + if (max_adc.second < pedestal + m_n_sigma * rms) { continue; } @@ -243,7 +246,8 @@ int MicromegasCombinedDataDecoder::process_event(PHCompositeNode* topNode) << " tile: " << tile << " channel: " << channel << " strip: " << strip - << " adc: " << max_adc + << " sample: " << max_adc.first + << " adc: " << max_adc.second << std::endl; } @@ -251,19 +255,19 @@ int MicromegasCombinedDataDecoder::process_event(PHCompositeNode* topNode) const auto hitset_it = trkrhitsetcontainer->findOrAddHitSet(hitsetkey); // generate hit key - const TrkrDefs::hitkey hitkey = MicromegasDefs::genHitKey(strip); + const TrkrDefs::hitkey hitkey = MicromegasDefs::genHitKey(strip, max_adc.first); // find existing hit, or create auto hit = hitset_it->second->getHit(hitkey); if (hit) { - // std::cout << "MicromegasCombinedDataDecoder::process_event - duplicated hit, hitsetkey: " << hitsetkey << " strip: " << strip << std::endl; + std::cout << "MicromegasCombinedDataDecoder::process_event - duplicated hit, hitsetkey: " << hitsetkey << " strip: " << strip << std::endl; continue; } // create hit, assign adc and insert in hitset hit = new TrkrHitv2; - hit->setAdc(max_adc); + hit->setAdc(max_adc.second); hitset_it->second->addHitSpecificKey(hitkey, hit); // increment counter From d0a251d8b689ab4392265b30107b165fd32021d9 Mon Sep 17 00:00:00 2001 From: Hugo Pereira Da Costa Date: Mon, 15 Dec 2025 22:56:37 -0500 Subject: [PATCH 015/393] fixed comments --- offline/packages/micromegas/MicromegasCombinedDataDecoder.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/offline/packages/micromegas/MicromegasCombinedDataDecoder.h b/offline/packages/micromegas/MicromegasCombinedDataDecoder.h index 32eebc56e0..3789284f26 100644 --- a/offline/packages/micromegas/MicromegasCombinedDataDecoder.h +++ b/offline/packages/micromegas/MicromegasCombinedDataDecoder.h @@ -49,10 +49,10 @@ class MicromegasCombinedDataDecoder : public SubsysReco /** This removes faulty channels for which calibration has failed */ void set_min_adc(double value) { m_min_adc = value; } - /// set min sample for noise estimation + /// set min sample for signal hits void set_sample_min(uint16_t value) { m_sample_min = value; } - /// set min sample for noise estimation + /// set max sample for signal hits void set_sample_max(uint16_t value) { m_sample_max = value; } private: From 0f8adaa30c2faff52d68041b095452bae425a906 Mon Sep 17 00:00:00 2001 From: Hugo Pereira Da Costa Date: Mon, 15 Dec 2025 22:56:44 -0500 Subject: [PATCH 016/393] Sort hits by strip number if multiple hits are found on the same strip only the first one, timewise, is kept. --- .../micromegas/MicromegasClusterizer.cc | 36 +++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/offline/packages/micromegas/MicromegasClusterizer.cc b/offline/packages/micromegas/MicromegasClusterizer.cc index c57d6ed3f5..a28ed156b6 100644 --- a/offline/packages/micromegas/MicromegasClusterizer.cc +++ b/offline/packages/micromegas/MicromegasClusterizer.cc @@ -157,8 +157,10 @@ int MicromegasClusterizer::process_event(PHCompositeNode *topNode) // geometry PHG4CylinderGeomContainer* geonode = nullptr; for( std::string geonodename: {"CYLINDERGEOM_MICROMEGAS_FULL", "CYLINDERGEOM_MICROMEGAS" } ) - { if(( geonode = findNode::getClass(topNode, geonodename.c_str()) )) { break; -}} + { + if(( geonode = findNode::getClass(topNode, geonodename.c_str()) )) + { break;} + } assert(geonode); // hitset container @@ -182,8 +184,8 @@ int MicromegasClusterizer::process_event(PHCompositeNode *topNode) for( auto hitset_it = hitset_range.first; hitset_it != hitset_range.second; ++hitset_it ) { // get hitset, key and layer - TrkrHitSet* hitset = hitset_it->second; - const TrkrDefs::hitsetkey hitsetkey = hitset_it->first; + const auto& [hitsetkey, hitset] = *hitset_it; + const auto layer = TrkrDefs::getLayer(hitsetkey); const auto tileid = MicromegasDefs::getTileId(hitsetkey); @@ -215,17 +217,32 @@ int MicromegasClusterizer::process_event(PHCompositeNode *topNode) using range_list_t = std::vector; range_list_t ranges; - // loop over hits - const auto hit_range = hitset->getHits(); + // Make a local copy of hitsets, sorted along strips + /* when there are multiple hits on the same strip, only the first one (in time) is kept */ + class StripSortFtor + { + public: + bool operator() ( const TrkrDefs::hitkey& first, const TrkrDefs::hitkey& second ) const + { return MicromegasDefs::getStrip(first) < MicromegasDefs::getStrip(second); } + }; + + using LocalMap = std::map; + LocalMap local_hitmap; + + { + // loop over hits + const auto hit_range = hitset->getHits(); + std::copy( hit_range.first, hit_range.second, std::inserter(local_hitmap, local_hitmap.end()) ); + } // keep track of first iterator of runing cluster - auto begin = hit_range.first; + auto begin = local_hitmap.begin(); // keep track of previous strip uint16_t previous_strip = 0; bool first = true; - for( auto hit_it = hit_range.first; hit_it != hit_range.second; ++hit_it ) + for( auto hit_it = local_hitmap.begin(); hit_it != local_hitmap.end(); ++hit_it ) { // get hit key @@ -257,8 +274,7 @@ int MicromegasClusterizer::process_event(PHCompositeNode *topNode) } // store last cluster - if( begin != hit_range.second ) { ranges.push_back( std::make_pair( begin, hit_range.second ) ); -} + if( begin != local_hitmap.end() ) { ranges.push_back( std::make_pair( begin, local_hitmap.end() ) ); } // initialize cluster count int cluster_count = 0; From 49ff81c07d86cc01fbabbd9174b4a7c922fa86e4 Mon Sep 17 00:00:00 2001 From: Hugo Pereira Da Costa Date: Mon, 15 Dec 2025 23:36:50 -0500 Subject: [PATCH 017/393] default max sample is 1024 (full range) --- offline/packages/micromegas/MicromegasCombinedDataDecoder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/micromegas/MicromegasCombinedDataDecoder.h b/offline/packages/micromegas/MicromegasCombinedDataDecoder.h index 3789284f26..33033f1992 100644 --- a/offline/packages/micromegas/MicromegasCombinedDataDecoder.h +++ b/offline/packages/micromegas/MicromegasCombinedDataDecoder.h @@ -85,7 +85,7 @@ class MicromegasCombinedDataDecoder : public SubsysReco uint16_t m_sample_min = 0; /// max sample for signal - uint16_t m_sample_max = 100; + uint16_t m_sample_max = 1024; /// keep track of number of hits per hitsetid using hitcountmap_t = std::map; From 0c648ef39945d565c448104949e8fa09e3134ce8 Mon Sep 17 00:00:00 2001 From: Hugo Pereira Da Costa Date: Mon, 15 Dec 2025 23:37:12 -0500 Subject: [PATCH 018/393] implemented min and max sample range for selecting clusters. --- offline/QA/Tracking/MicromegasClusterQA.cc | 10 ++++++++++ offline/QA/Tracking/MicromegasClusterQA.h | 13 +++++++++++++ 2 files changed, 23 insertions(+) diff --git a/offline/QA/Tracking/MicromegasClusterQA.cc b/offline/QA/Tracking/MicromegasClusterQA.cc index 41efeffaa7..6feb510c54 100644 --- a/offline/QA/Tracking/MicromegasClusterQA.cc +++ b/offline/QA/Tracking/MicromegasClusterQA.cc @@ -73,6 +73,9 @@ int MicromegasClusterQA::InitRun(PHCompositeNode* topNode) << (m_calibration_filename.empty() ? "unspecified" : m_calibration_filename) << std::endl; + std::cout << "MicromegasClusterQA::InitRun - m_sample_min: " << m_sample_min << std::endl; + std::cout << "MicromegasClusterQA::InitRun - m_sample_max: " << m_sample_max << std::endl; + // read calibrations if (!m_calibration_filename.empty()) { @@ -162,6 +165,13 @@ int MicromegasClusterQA::process_event(PHCompositeNode* topNode) // find associated hits const auto hit_range = m_cluster_hit_map->getHits(ckey); + // check hit samples + // if none of the associated hits' sample is within acceptable range, skip the cluster + if( std::none_of( hit_range.first, hit_range.second, + [this]( const TrkrClusterHitAssoc::Map::value_type& pair ) + { return MicromegasDefs::getSample( pair.second ) >= m_sample_min && MicromegasDefs::getSample( pair.second ) < m_sample_max; } ) ) + { continue; } + // store cluster size and fill cluster size histogram const int cluster_size = std::distance(hit_range.first, hit_range.second); m_h_cluster_size->Fill(detid, cluster_size); diff --git a/offline/QA/Tracking/MicromegasClusterQA.h b/offline/QA/Tracking/MicromegasClusterQA.h index 338e5302de..d6de8344c4 100644 --- a/offline/QA/Tracking/MicromegasClusterQA.h +++ b/offline/QA/Tracking/MicromegasClusterQA.h @@ -51,6 +51,13 @@ class MicromegasClusterQA : public SubsysReco m_calibration_filename = value; } + /// set min sample for signal hits + void set_sample_min(uint16_t value) { m_sample_min = value; } + + /// set max sample for signal hits + void set_sample_max(uint16_t value) { m_sample_max = value; } + + private: void create_histograms(); @@ -98,6 +105,12 @@ class MicromegasClusterQA : public SubsysReco /// keep track of detector names std::vector m_detector_names; + /// min sample for signal + uint16_t m_sample_min = 0; + + /// max sample for signal + uint16_t m_sample_max = 1024; + ///@name calibration filename //@{ From 9e7cf18f915644e5ddeaffa3788646752b84595d Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 6 Jan 2026 19:12:01 -0500 Subject: [PATCH 019/393] fix bad bug found by coderabbit --- offline/packages/PHGenFitPkg/PHGenFit/Fitter.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/PHGenFitPkg/PHGenFit/Fitter.cc b/offline/packages/PHGenFitPkg/PHGenFit/Fitter.cc index 127af3539e..aeb01dee62 100644 --- a/offline/packages/PHGenFitPkg/PHGenFit/Fitter.cc +++ b/offline/packages/PHGenFitPkg/PHGenFit/Fitter.cc @@ -233,7 +233,7 @@ namespace PHGenFit { _fitter = new genfit::KalmanFitterRefTrack(); } - if (fitter_choice == PHGenFit::Fitter::DafSimple) + else if (fitter_choice == PHGenFit::Fitter::DafSimple) { _fitter = new genfit::DAF(false); } From 514cbf6da040c597ebcf629d6abae888b307001f Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 6 Jan 2026 19:14:02 -0500 Subject: [PATCH 020/393] better performace according to code rabbit --- offline/packages/tpc/TpcDistortionCorrection.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/tpc/TpcDistortionCorrection.cc b/offline/packages/tpc/TpcDistortionCorrection.cc index 8974053b48..71b9ea8b2f 100644 --- a/offline/packages/tpc/TpcDistortionCorrection.cc +++ b/offline/packages/tpc/TpcDistortionCorrection.cc @@ -15,7 +15,7 @@ namespace { template - constexpr T square(const T& x) + constexpr T square(const T x) { return x * x; } From 5c1fb73ad663c9c906fe52346fdd680f761c9353 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 6 Jan 2026 19:18:30 -0500 Subject: [PATCH 021/393] make coderabbit happy --- offline/packages/tpc/LaserClusterizer.cc | 1 - offline/packages/tpc/TpcClusterizer.cc | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/offline/packages/tpc/LaserClusterizer.cc b/offline/packages/tpc/LaserClusterizer.cc index 84e0477caa..754ee8d248 100644 --- a/offline/packages/tpc/LaserClusterizer.cc +++ b/offline/packages/tpc/LaserClusterizer.cc @@ -879,7 +879,6 @@ int LaserClusterizer::process_event(PHCompositeNode *topNode) } TrkrHitSetContainer::ConstRange hitsetrange = m_hits->getHitSets(TrkrDefs::TrkrId::tpcId); - ; struct thread_pair_t { diff --git a/offline/packages/tpc/TpcClusterizer.cc b/offline/packages/tpc/TpcClusterizer.cc index 05fb1fe121..4548bde728 100644 --- a/offline/packages/tpc/TpcClusterizer.cc +++ b/offline/packages/tpc/TpcClusterizer.cc @@ -1206,13 +1206,13 @@ int TpcClusterizer::InitRun(PHCompositeNode *topNode) AdcClockPeriod = geom->GetFirstLayerCellGeom()->get_zstep(); std::cout << "FirstLayerCellGeomv1 streamer: " << std::endl; - auto *g1 = (PHG4TpcGeomv1*) geom->GetFirstLayerCellGeom(); // cast because << not in the base class + auto *g1 = static_cast (geom->GetFirstLayerCellGeom()); // cast because << not in the base class std::cout << *g1 << std::endl; std::cout << "LayerCellGeomv1 streamer for layer 24: " << std::endl; - auto *g2 = (PHG4TpcGeomv1*) geom->GetLayerCellGeom(24); // cast because << not in the base class + auto *g2 = static_cast (geom->GetLayerCellGeom(24)); // cast because << not in the base class std::cout << *g2 << std::endl; std::cout << "LayerCellGeomv1 streamer for layer 40: " << std::endl; - auto *g3 = (PHG4TpcGeomv1*) geom->GetLayerCellGeom(40); // cast because << not in the base class + auto *g3 = static_cast (geom->GetLayerCellGeom(40)); // cast because << not in the base class std::cout << *g3 << std::endl; return Fun4AllReturnCodes::EVENT_OK; From 3f3052247cb9dd147110341d056b36471b009495 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 6 Jan 2026 19:21:03 -0500 Subject: [PATCH 022/393] fix botched formatting --- offline/packages/mvtx/MvtxHitPruner.cc | 82 +++++++++++++++----------- 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/offline/packages/mvtx/MvtxHitPruner.cc b/offline/packages/mvtx/MvtxHitPruner.cc index d4395b6f4a..58cbb423c4 100644 --- a/offline/packages/mvtx/MvtxHitPruner.cc +++ b/offline/packages/mvtx/MvtxHitPruner.cc @@ -51,26 +51,33 @@ namespace { //! range adaptor to be able to use range-based for loop - template class range_adaptor + template + class range_adaptor { - public: - explicit range_adaptor( const T& range ):m_range(range){} - const typename T::first_type& begin() {return m_range.first;} - const typename T::second_type& end() {return m_range.second;} - private: + public: + explicit range_adaptor(const T& range) + : m_range(range) + { + } + const typename T::first_type& begin() { return m_range.first; } + const typename T::second_type& end() { return m_range.second; } + + private: T m_range; }; -} +} // namespace -MvtxHitPruner::MvtxHitPruner(const std::string &name) +MvtxHitPruner::MvtxHitPruner(const std::string& name) : SubsysReco(name) { } -int MvtxHitPruner::InitRun(PHCompositeNode * /*topNode*/) -{ return Fun4AllReturnCodes::EVENT_OK; } +int MvtxHitPruner::InitRun(PHCompositeNode* /*topNode*/) +{ + return Fun4AllReturnCodes::EVENT_OK; +} -int MvtxHitPruner::process_event(PHCompositeNode *topNode) +int MvtxHitPruner::process_event(PHCompositeNode* topNode) { // get node containing the digitized hits m_hits = findNode::getClass(topNode, "TRKR_HITSET"); @@ -93,13 +100,14 @@ int MvtxHitPruner::process_event(PHCompositeNode *topNode) std::set bare_hitset_set; const auto hitsetrange = m_hits->getHitSets(TrkrDefs::TrkrId::mvtxId); - for( const auto& [hitsetkey,hitset]:range_adaptor(hitsetrange) ) + for (const auto& [hitsetkey, hitset] : range_adaptor(hitsetrange)) { - // get strobe, skip if already zero const int strobe = MvtxDefs::getStrobeId(hitsetkey); - if( strobe == 0 ) { continue; -} + if (strobe == 0) + { + continue; + } // get the hitsetkey value for strobe 0 const auto bare_hitsetkey = MvtxDefs::resetStrobe(hitsetkey); @@ -118,44 +126,46 @@ int MvtxHitPruner::process_event(PHCompositeNode *topNode) for (const auto& bare_hitsetkey : bare_hitset_set) { // find matching hitset of creater - auto *bare_hitset = (m_hits->findOrAddHitSet(bare_hitsetkey))->second; + auto* bare_hitset = (m_hits->findOrAddHitSet(bare_hitsetkey))->second; if (Verbosity()) { std::cout - << "MvtxHitPruner::process_event - bare_hitset " << bare_hitsetkey - << " initially has " << bare_hitset->size() << " hits " - << std::endl; + << "MvtxHitPruner::process_event - bare_hitset " << bare_hitsetkey + << " initially has " << bare_hitset->size() << " hits " + << std::endl; } // get all hitsets with non-zero strobe that match the bare hitset key auto bare_hitsetrange = hitset_multimap.equal_range(bare_hitsetkey); - for( const auto& [unused,hitsetkey]:range_adaptor(bare_hitsetrange) ) + for (const auto& [unused, hitsetkey] : range_adaptor(bare_hitsetrange)) { const int strobe = MvtxDefs::getStrobeId(hitsetkey); - if( strobe == 0 ) { continue; -} + if (strobe == 0) + { + continue; + } if (Verbosity()) { std::cout << "MvtxHitPruner::process_event -" - << " process hitsetkey " << hitsetkey - << " from strobe " << strobe - << " for bare_hitsetkey " << bare_hitsetkey - << std::endl; + << " process hitsetkey " << hitsetkey + << " from strobe " << strobe + << " for bare_hitsetkey " << bare_hitsetkey + << std::endl; } // copy all hits to the hitset with strobe 0 - auto *hitset = m_hits->findHitSet(hitsetkey); + auto* hitset = m_hits->findHitSet(hitsetkey); if (Verbosity()) { std::cout << "MvtxHitPruner::process_event - hitsetkey " << hitsetkey - << " has strobe " << strobe << " and has " << hitset->size() - << " hits, so copy it" << std::endl; + << " has strobe " << strobe << " and has " << hitset->size() + << " hits, so copy it" << std::endl; } TrkrHitSet::ConstRange hitrangei = hitset->getHits(); - for( const auto& [hitkey,old_hit]:range_adaptor(hitrangei) ) + for (const auto& [hitkey, old_hit] : range_adaptor(hitrangei)) { if (Verbosity()) { @@ -168,9 +178,9 @@ int MvtxHitPruner::process_event(PHCompositeNode *topNode) if (Verbosity()) { std::cout - << "MvtxHitPruner::process_event - hitkey " << hitkey - << " is already in bare hitsest, do not copy" - << std::endl; + << "MvtxHitPruner::process_event - hitkey " << hitkey + << " is already in bare hitsest, do not copy" + << std::endl; } continue; } @@ -179,11 +189,11 @@ int MvtxHitPruner::process_event(PHCompositeNode *topNode) if (Verbosity()) { std::cout - << "MvtxHitPruner::process_event - copying over hitkey " - << hitkey << std::endl; + << "MvtxHitPruner::process_event - copying over hitkey " + << hitkey << std::endl; } - auto *new_hit = new TrkrHitv2; + auto* new_hit = new TrkrHitv2; new_hit->CopyFrom(old_hit); bare_hitset->addHitSpecificKey(hitkey, new_hit); } From 078517886c6a4a094cb5e34a04be0ba2408496fa Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Tue, 6 Jan 2026 21:00:52 -0500 Subject: [PATCH 023/393] clang-tidy --- offline/packages/trackreco/PHActsTrkFitter.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/offline/packages/trackreco/PHActsTrkFitter.cc b/offline/packages/trackreco/PHActsTrkFitter.cc index f66767d305..2ca1426301 100644 --- a/offline/packages/trackreco/PHActsTrkFitter.cc +++ b/offline/packages/trackreco/PHActsTrkFitter.cc @@ -314,7 +314,7 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) // capture the input crossing value, and set crossing parameters //============================== short silicon_crossing = SHRT_MAX; - auto siseed = m_siliconSeeds->get(siid); + auto *siseed = m_siliconSeeds->get(siid); if (siseed) { silicon_crossing = siseed->get_crossing(); @@ -352,7 +352,7 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) } } - auto tpcseed = m_tpcSeeds->get(tpcid); + auto *tpcseed = m_tpcSeeds->get(tpcid); /// Need to also check that the tpc seed wasn't removed by the ghost finder if (!tpcseed) From e06322f2d50ad00157f219c6871c0deed0c6d7d4 Mon Sep 17 00:00:00 2001 From: Hugo Pereira Da Costa Date: Tue, 6 Jan 2026 23:01:50 -0500 Subject: [PATCH 024/393] Update offline/packages/micromegas/MicromegasDefs.cc Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- offline/packages/micromegas/MicromegasDefs.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/micromegas/MicromegasDefs.cc b/offline/packages/micromegas/MicromegasDefs.cc index 78732951f7..b26a02564a 100644 --- a/offline/packages/micromegas/MicromegasDefs.cc +++ b/offline/packages/micromegas/MicromegasDefs.cc @@ -77,7 +77,7 @@ namespace MicromegasDefs uint8_t getStrip( TrkrDefs::hitkey key ) { TrkrDefs::hitkey tmp = (key >> kBitShiftStrip); - return tmp; + return tmp & 0xFF; } //________________________________________________________________ From 89660ef82ddcb6517de607817a00f1afacb04b11 Mon Sep 17 00:00:00 2001 From: Hugo Pereira Da Costa Date: Tue, 6 Jan 2026 23:05:57 -0500 Subject: [PATCH 025/393] Update offline/packages/micromegas/MicromegasDefs.cc Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- offline/packages/micromegas/MicromegasDefs.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/micromegas/MicromegasDefs.cc b/offline/packages/micromegas/MicromegasDefs.cc index b26a02564a..0e669b1d88 100644 --- a/offline/packages/micromegas/MicromegasDefs.cc +++ b/offline/packages/micromegas/MicromegasDefs.cc @@ -84,7 +84,7 @@ namespace MicromegasDefs uint16_t getSample( TrkrDefs::hitkey key ) { TrkrDefs::hitkey tmp = (key >> kBitShiftSample); - return tmp; + return tmp & 0xFFFF; } //________________________________________________________________ From 2f32421454bc8ff6608e9ca2fb4eab9ac5218384 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Wed, 7 Jan 2026 10:22:55 -0500 Subject: [PATCH 026/393] handle max between a double and an int correctly with rounding --- offline/packages/tpc/TpcClusterizer.cc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/offline/packages/tpc/TpcClusterizer.cc b/offline/packages/tpc/TpcClusterizer.cc index 4548bde728..c0137613f5 100644 --- a/offline/packages/tpc/TpcClusterizer.cc +++ b/offline/packages/tpc/TpcClusterizer.cc @@ -531,14 +531,10 @@ namespace continue; } - max_adc = std::max(adc, max_adc); - + max_adc = std::max(max_adc, static_cast(std::round(adc))); // preserves rounding (0.5 -> 1) phibinhi = std::max(iphi, phibinhi); - phibinlo = std::min(iphi, phibinlo); - tbinhi = std::max(it, tbinhi); - tbinlo = std::min(it, tbinlo); // if(it==it_center){ yg_sum += adc; } From 3fe3cd3fd97d4994f46577d85609972ae240632b Mon Sep 17 00:00:00 2001 From: cdean-github Date: Wed, 7 Jan 2026 11:45:04 -0500 Subject: [PATCH 027/393] CD: New version of silicon pooling --- .../Fun4AllStreamingInputManager.cc | 132 +++++------------- .../fun4allraw/SingleMvtxPoolInput.cc | 11 +- 2 files changed, 43 insertions(+), 100 deletions(-) diff --git a/offline/framework/fun4allraw/Fun4AllStreamingInputManager.cc b/offline/framework/fun4allraw/Fun4AllStreamingInputManager.cc index 78b3e3a365..0bea81197b 100644 --- a/offline/framework/fun4allraw/Fun4AllStreamingInputManager.cc +++ b/offline/framework/fun4allraw/Fun4AllStreamingInputManager.cc @@ -776,9 +776,15 @@ int Fun4AllStreamingInputManager::FillIntt() { h_taggedAllFee_intt->Fill(refbcobitshift); } - while (m_InttRawHitMap.begin()->first <= select_crossings - m_intt_negative_bco) + + for (auto& [bco, hitinfo] : m_InttRawHitMap) { - for (auto *intthititer : m_InttRawHitMap.begin()->second.InttRawHitVector) + if (bco > select_crossings) + { + break; + } + + for (auto *intthititer : hitinfo.InttRawHitVector) { if (Verbosity() > 1) { @@ -788,25 +794,9 @@ int Fun4AllStreamingInputManager::FillIntt() } inttcont->AddHit(intthititer); } - for (auto *iter : m_InttInputVector) - { - iter->CleanupUsedPackets(m_InttRawHitMap.begin()->first); - if (m_intt_negative_bco < 2) // triggered mode - { - iter->clearPacketBClkStackMap(m_InttRawHitMap.begin()->first); - iter->clearFeeGTML1BCOMap(m_InttRawHitMap.begin()->first); - } - } - m_InttRawHitMap.begin()->second.InttRawHitVector.clear(); - m_InttRawHitMap.erase(m_InttRawHitMap.begin()); - if (m_InttRawHitMap.empty()) - { - break; - } - } + } return 0; } - int Fun4AllStreamingInputManager::FillMvtx() { int iret = FillMvtxPool(); @@ -846,7 +836,7 @@ int Fun4AllStreamingInputManager::FillMvtx() } select_crossings += m_RefBCO; - uint64_t ref_bco_minus_range = m_RefBCO < m_mvtx_bco_range ? 0 : m_RefBCO - m_mvtx_bco_range; + uint64_t ref_bco_minus_range = m_RefBCO < m_mvtx_negative_bco ? 0 : m_RefBCO - m_mvtx_negative_bco; if (Verbosity() > 2) { std::cout << "select MVTX crossings" @@ -981,90 +971,42 @@ int Fun4AllStreamingInputManager::FillMvtx() } taggedPacketsFEEs.clear(); - if (m_mvtx_is_triggered) + uint64_t lower_limit = m_mvtx_is_triggered ? select_crossings : select_crossings - m_mvtx_bco_range - m_mvtx_negative_bco; + uint64_t upper_limit = m_mvtx_is_triggered ? select_crossings + m_mvtx_bco_range : select_crossings; + + for (auto& [bco, hitinfo] : m_MvtxRawHitMap) { - while (select_crossings <= m_MvtxRawHitMap.begin()->first && m_MvtxRawHitMap.begin()->first <= select_crossings + m_mvtx_bco_range) // triggered + if (bco < lower_limit) { - if (Verbosity() > 2) - { - std::cout << "Adding 0x" << std::hex << m_MvtxRawHitMap.begin()->first - << " ref: 0x" << select_crossings << std::dec << std::endl; - } - for (auto *mvtxFeeIdInfo : m_MvtxRawHitMap.begin()->second.MvtxFeeIdInfoVector) - { - if (Verbosity() > 1) - { - mvtxFeeIdInfo->identify(); - } - mvtxEvtHeader->AddFeeIdInfo(mvtxFeeIdInfo); - delete mvtxFeeIdInfo; - } - m_MvtxRawHitMap.begin()->second.MvtxFeeIdInfoVector.clear(); - mvtxEvtHeader->AddL1Trg(m_MvtxRawHitMap.begin()->second.MvtxL1TrgBco); + continue; + } + if (bco > upper_limit) + { + break; + } - for (auto *mvtxhititer : m_MvtxRawHitMap.begin()->second.MvtxRawHitVector) - { - if (Verbosity() > 1) - { - mvtxhititer->identify(); - } - mvtxcont->AddHit(mvtxhititer); - } - for (auto *iter : m_MvtxInputVector) - { - iter->CleanupUsedPackets(m_MvtxRawHitMap.begin()->first); - } - m_MvtxRawHitMap.begin()->second.MvtxRawHitVector.clear(); - m_MvtxRawHitMap.begin()->second.MvtxL1TrgBco.clear(); - m_MvtxRawHitMap.erase(m_MvtxRawHitMap.begin()); - // m_MvtxRawHitMap.empty() need to be checked here since we do not call FillPoolMvtx() - if (m_MvtxRawHitMap.empty()) - { - break; - } + if (Verbosity() > 2) + { + std::cout << "Adding 0x" << std::hex << bco + << " ref: 0x" << select_crossings << std::dec << std::endl; } - } - else - { - while (select_crossings - m_mvtx_bco_range - m_mvtx_negative_bco <= m_MvtxRawHitMap.begin()->first && m_MvtxRawHitMap.begin()->first <= select_crossings) // streamed + for (auto *mvtxFeeIdInfo : hitinfo.MvtxFeeIdInfoVector) { - if (Verbosity() > 2) - { - std::cout << "Adding 0x" << std::hex << m_MvtxRawHitMap.begin()->first - << " ref: 0x" << select_crossings << std::dec << std::endl; - } - for (auto *mvtxFeeIdInfo : m_MvtxRawHitMap.begin()->second.MvtxFeeIdInfoVector) + if (Verbosity() > 1) { - if (Verbosity() > 1) - { - mvtxFeeIdInfo->identify(); - } - mvtxEvtHeader->AddFeeIdInfo(mvtxFeeIdInfo); - delete mvtxFeeIdInfo; + mvtxFeeIdInfo->identify(); } - m_MvtxRawHitMap.begin()->second.MvtxFeeIdInfoVector.clear(); - mvtxEvtHeader->AddL1Trg(m_MvtxRawHitMap.begin()->second.MvtxL1TrgBco); + mvtxEvtHeader->AddFeeIdInfo(mvtxFeeIdInfo); + } + mvtxEvtHeader->AddL1Trg(hitinfo.MvtxL1TrgBco); - for (auto *mvtxhititer : m_MvtxRawHitMap.begin()->second.MvtxRawHitVector) - { - if (Verbosity() > 1) - { - mvtxhititer->identify(); - } - mvtxcont->AddHit(mvtxhititer); - } - for (auto *iter : m_MvtxInputVector) - { - iter->CleanupUsedPackets(m_MvtxRawHitMap.begin()->first); - } - m_MvtxRawHitMap.begin()->second.MvtxRawHitVector.clear(); - m_MvtxRawHitMap.begin()->second.MvtxL1TrgBco.clear(); - m_MvtxRawHitMap.erase(m_MvtxRawHitMap.begin()); - // m_MvtxRawHitMap.empty() need to be checked here since we do not call FillPoolMvtx() - if (m_MvtxRawHitMap.empty()) + for (auto *mvtxhititer : hitinfo.MvtxRawHitVector) + { + if (Verbosity() > 1) { - break; + mvtxhititer->identify(); } + mvtxcont->AddHit(mvtxhititer); } } @@ -1422,7 +1364,7 @@ int Fun4AllStreamingInputManager::FillMicromegasPool() int Fun4AllStreamingInputManager::FillMvtxPool() { - uint64_t ref_bco_minus_range = m_RefBCO < m_mvtx_bco_range ? m_mvtx_bco_range : m_RefBCO - m_mvtx_bco_range; + uint64_t ref_bco_minus_range = m_RefBCO < m_mvtx_negative_bco ? m_mvtx_negative_bco : m_RefBCO - m_mvtx_negative_bco; for (auto *iter : m_MvtxInputVector) { if (Verbosity() > 3) diff --git a/offline/framework/fun4allraw/SingleMvtxPoolInput.cc b/offline/framework/fun4allraw/SingleMvtxPoolInput.cc index de98a9936e..4ce498ee9e 100644 --- a/offline/framework/fun4allraw/SingleMvtxPoolInput.cc +++ b/offline/framework/fun4allraw/SingleMvtxPoolInput.cc @@ -1,7 +1,7 @@ #include "SingleMvtxPoolInput.h" -#include "MvtxRawDefs.h" #include "Fun4AllStreamingInputManager.h" +#include "MvtxRawDefs.h" #include "mvtx_pool.h" #include @@ -29,7 +29,8 @@ #include SingleMvtxPoolInput::SingleMvtxPoolInput(const std::string &name) - : SingleStreamingInput(name), plist(new Packet *[2]) + : SingleStreamingInput(name) + , plist(new Packet *[2]) { m_rawHitContainerName = "MVTXRAWHIT"; @@ -161,7 +162,7 @@ void SingleMvtxPoolInput::FillPool(const uint64_t minBCO) m_BclkStack.insert(strb_bco); m_FEEBclkMap[feeId] = strb_bco; - if (strb_bco < minBCO - m_NegativeBco) + if (strb_bco < minBCO) { continue; } @@ -206,7 +207,7 @@ void SingleMvtxPoolInput::FillPool(const uint64_t minBCO) auto it = m_BclkStack.lower_bound(lv1Bco); // auto const strb_it = (it == m_BclkStack.begin()) ? (*it == lv1Bco ? it : m_BclkStack.cend()) : --it; // this is equivalent but human readable for the above: - auto strb_it = m_BclkStack.cend(); + auto strb_it = m_BclkStack.cend(); if (it == m_BclkStack.begin()) { @@ -462,7 +463,7 @@ void SingleMvtxPoolInput::ConfigureStreamingInputManager() else if (m_strobeWidth > 9 && m_strobeWidth < 11) { m_BcoRange = 500; - m_NegativeBco = 500; + m_NegativeBco = 120; } else if (m_strobeWidth < 1) // triggered mode { From c6b077cd4329601bbc6bf975e1336f1bff6fc48d Mon Sep 17 00:00:00 2001 From: Hugo Pereira Da Costa Date: Wed, 7 Jan 2026 14:54:21 -0500 Subject: [PATCH 028/393] - removed static as per clang-tidy - consolidated all key setters/getters with masks --- offline/packages/micromegas/MicromegasDefs.cc | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/offline/packages/micromegas/MicromegasDefs.cc b/offline/packages/micromegas/MicromegasDefs.cc index 0e669b1d88..8a35461492 100644 --- a/offline/packages/micromegas/MicromegasDefs.cc +++ b/offline/packages/micromegas/MicromegasDefs.cc @@ -25,12 +25,12 @@ namespace * 8 - 16 segmentation type * 0 - 8 tile id */ - static constexpr unsigned int kBitShiftSegmentation = 8; - static constexpr unsigned int kBitShiftTileId = 0; + constexpr unsigned int kBitShiftSegmentation = 8; + constexpr unsigned int kBitShiftTileId = 0; //! bit shift for hit key - static constexpr unsigned int kBitShiftStrip = 0; - static constexpr unsigned int kBitShiftSample = 8; + constexpr unsigned int kBitShiftStrip = 0; + constexpr unsigned int kBitShiftSample = 8; } @@ -42,10 +42,10 @@ namespace MicromegasDefs { TrkrDefs::hitsetkey key = TrkrDefs::genHitSetKey(TrkrDefs::TrkrId::micromegasId, layer); - TrkrDefs::hitsetkey tmp = to_underlying_type(type); + TrkrDefs::hitsetkey tmp = to_underlying_type(type)&0x1U; key |= (tmp << kBitShiftSegmentation); - tmp = tile; + tmp = tile&0xFFU; key |= (tmp << kBitShiftTileId); return key; @@ -55,21 +55,21 @@ namespace MicromegasDefs SegmentationType getSegmentationType(TrkrDefs::hitsetkey key) { TrkrDefs::hitsetkey tmp = (key >> kBitShiftSegmentation); - return static_cast(tmp); + return static_cast(tmp&0x1U); } //________________________________________________________________ uint8_t getTileId(TrkrDefs::hitsetkey key) { TrkrDefs::hitsetkey tmp = (key >> kBitShiftTileId); - return tmp; + return tmp&0xFFU; } //________________________________________________________________ TrkrDefs::hitkey genHitKey(uint16_t strip, uint16_t sample) { - const TrkrDefs::hitkey key = strip << kBitShiftStrip; - const TrkrDefs::hitkey tmp = sample << kBitShiftSample; + const TrkrDefs::hitkey key = (strip&0xFFU) << kBitShiftStrip; + const TrkrDefs::hitkey tmp = (sample&0xFFFFU) << kBitShiftSample; return key|tmp; } @@ -77,14 +77,14 @@ namespace MicromegasDefs uint8_t getStrip( TrkrDefs::hitkey key ) { TrkrDefs::hitkey tmp = (key >> kBitShiftStrip); - return tmp & 0xFF; + return tmp & 0xFFU; } //________________________________________________________________ uint16_t getSample( TrkrDefs::hitkey key ) { TrkrDefs::hitkey tmp = (key >> kBitShiftSample); - return tmp & 0xFFFF; + return tmp & 0xFFFFU; } //________________________________________________________________ From f5a6ec82f5784410804b0d115be034816b496ebe Mon Sep 17 00:00:00 2001 From: Hugo Pereira Da Costa Date: Wed, 7 Jan 2026 15:10:41 -0500 Subject: [PATCH 029/393] clang-tidy --- offline/packages/micromegas/MicromegasClusterizer.cc | 11 +++++++---- .../micromegas/MicromegasCombinedDataDecoder.cc | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/offline/packages/micromegas/MicromegasClusterizer.cc b/offline/packages/micromegas/MicromegasClusterizer.cc index a28ed156b6..9444d9ef26 100644 --- a/offline/packages/micromegas/MicromegasClusterizer.cc +++ b/offline/packages/micromegas/MicromegasClusterizer.cc @@ -158,9 +158,12 @@ int MicromegasClusterizer::process_event(PHCompositeNode *topNode) PHG4CylinderGeomContainer* geonode = nullptr; for( std::string geonodename: {"CYLINDERGEOM_MICROMEGAS_FULL", "CYLINDERGEOM_MICROMEGAS" } ) { - if(( geonode = findNode::getClass(topNode, geonodename.c_str()) )) - { break;} + // try load node and test + geonode = findNode::getClass(topNode, geonodename); + if( geonode ) { break;} } + + //ma assert(geonode); // hitset container @@ -261,7 +264,7 @@ int MicromegasClusterizer::process_event(PHCompositeNode *topNode) } else if( strip - previous_strip > 1 ) { // store current cluster range - ranges.push_back( std::make_pair( begin, hit_it ) ); + ranges.emplace_back( begin, hit_it ); // reinitialize begin of next cluster range begin = hit_it; @@ -274,7 +277,7 @@ int MicromegasClusterizer::process_event(PHCompositeNode *topNode) } // store last cluster - if( begin != local_hitmap.end() ) { ranges.push_back( std::make_pair( begin, local_hitmap.end() ) ); } + if( begin != local_hitmap.end() ) { ranges.emplace_back( begin, local_hitmap.end() ); } // initialize cluster count int cluster_count = 0; diff --git a/offline/packages/micromegas/MicromegasCombinedDataDecoder.cc b/offline/packages/micromegas/MicromegasCombinedDataDecoder.cc index 50bcb97cd6..1c34357280 100644 --- a/offline/packages/micromegas/MicromegasCombinedDataDecoder.cc +++ b/offline/packages/micromegas/MicromegasCombinedDataDecoder.cc @@ -258,7 +258,7 @@ int MicromegasCombinedDataDecoder::process_event(PHCompositeNode* topNode) const TrkrDefs::hitkey hitkey = MicromegasDefs::genHitKey(strip, max_adc.first); // find existing hit, or create - auto hit = hitset_it->second->getHit(hitkey); + auto* hit = hitset_it->second->getHit(hitkey); if (hit) { std::cout << "MicromegasCombinedDataDecoder::process_event - duplicated hit, hitsetkey: " << hitsetkey << " strip: " << strip << std::endl; From af55b25f25d7c859a488ed1e03aa779aa8969fe9 Mon Sep 17 00:00:00 2001 From: Shuonli Date: Wed, 7 Jan 2026 19:57:56 -0500 Subject: [PATCH 030/393] add e22 showershape --- offline/packages/CaloReco/PhotonClusterBuilder.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/offline/packages/CaloReco/PhotonClusterBuilder.cc b/offline/packages/CaloReco/PhotonClusterBuilder.cc index 263ae04ef0..edcf5f4418 100644 --- a/offline/packages/CaloReco/PhotonClusterBuilder.cc +++ b/offline/packages/CaloReco/PhotonClusterBuilder.cc @@ -566,6 +566,7 @@ void PhotonClusterBuilder::calculate_shower_shapes(RawCluster* rc, PhotonCluster photon->set_shower_shape_parameter("et3", showershape[2]); photon->set_shower_shape_parameter("et4", showershape[3]); photon->set_shower_shape_parameter("e11", e11); + photon->set_shower_shape_parameter("e22", showershape[8] + showershape[9] + showershape[10] + showershape[11]); photon->set_shower_shape_parameter("e33", e33); photon->set_shower_shape_parameter("e55", e55); photon->set_shower_shape_parameter("e77", e77); From 8d61916570e48698737f61814f3c6131093c64f4 Mon Sep 17 00:00:00 2001 From: Hugo Pereira Da Costa Date: Wed, 7 Jan 2026 20:05:29 -0500 Subject: [PATCH 031/393] more clang-tidy --- offline/packages/micromegas/MicromegasClusterizer.cc | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/offline/packages/micromegas/MicromegasClusterizer.cc b/offline/packages/micromegas/MicromegasClusterizer.cc index 9444d9ef26..5da9264c11 100644 --- a/offline/packages/micromegas/MicromegasClusterizer.cc +++ b/offline/packages/micromegas/MicromegasClusterizer.cc @@ -253,16 +253,9 @@ int MicromegasClusterizer::process_event(PHCompositeNode *topNode) // get strip number const auto strip = MicromegasDefs::getStrip( hitkey ); - - if( first ) + if( !first && (strip - previous_strip > 1 ) ) { - previous_strip = strip; - first = false; - continue; - - } else if( strip - previous_strip > 1 ) { - // store current cluster range ranges.emplace_back( begin, hit_it ); @@ -272,6 +265,7 @@ int MicromegasClusterizer::process_event(PHCompositeNode *topNode) } // update previous strip + first = false; previous_strip = strip; } From 3a535f03b5f98661ee09fcd6a9f5e8f0cc9eb828 Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Thu, 8 Jan 2026 01:20:38 +0000 Subject: [PATCH 032/393] =?UTF-8?q?=F0=9F=93=9D=20Add=20docstrings=20to=20?= =?UTF-8?q?`photonclass`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Docstrings generation was requested by @blackcathj. * https://github.com/sPHENIX-Collaboration/coresoftware/pull/4095#issuecomment-3721466089 The following files were modified: * `offline/packages/CaloReco/PhotonClusterBuilder.cc` --- offline/packages/CaloReco/PhotonClusterBuilder.cc | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/offline/packages/CaloReco/PhotonClusterBuilder.cc b/offline/packages/CaloReco/PhotonClusterBuilder.cc index 263ae04ef0..59bb5be1ae 100644 --- a/offline/packages/CaloReco/PhotonClusterBuilder.cc +++ b/offline/packages/CaloReco/PhotonClusterBuilder.cc @@ -272,6 +272,17 @@ void PhotonClusterBuilder::calculate_bdt_score(PhotonClusterv1* photon) photon->set_shower_shape_parameter("bdt_score", bdt_score); } +/// @brief Extracts and stores shower-shape and isolation observables for a cluster onto a PhotonClusterv1. +/// +— Computes a 7x7 local energy grid around the cluster lead tower, derives moments, summed energies +— (e.g., e11, e22, e33, e55, e77 and related e13..e75), centroid and width metrics (weta, wphi, cog variants), +— timing and saturation counters, closest HCAL tower ET summaries, and calorimeter-layer isolation values, +— and attaches these values to the provided photon via set_shower_shape_parameter. +/// +@param rc Pointer to the RawCluster providing tower membership and shower-shape inputs; if rc->get_shower_shapes(...) is empty the function returns without modifying the photon. +///@param photon PhotonClusterv1 instance to receive computed shower-shape and isolation parameters. +///@param cluster_eta Pseudorapidity of the cluster (used for ET calculations and stored as "cluster_eta"). +///@param cluster_phi Azimuthal angle of the cluster (used for storage as "cluster_phi"). void PhotonClusterBuilder::calculate_shower_shapes(RawCluster* rc, PhotonClusterv1* photon, float cluster_eta, float cluster_phi) { std::vector showershape = rc->get_shower_shapes(m_shape_min_tower_E); @@ -566,6 +577,7 @@ void PhotonClusterBuilder::calculate_shower_shapes(RawCluster* rc, PhotonCluster photon->set_shower_shape_parameter("et3", showershape[2]); photon->set_shower_shape_parameter("et4", showershape[3]); photon->set_shower_shape_parameter("e11", e11); + photon->set_shower_shape_parameter("e22", showershape[8] + showershape[9] + showershape[10] + showershape[11]); photon->set_shower_shape_parameter("e33", e33); photon->set_shower_shape_parameter("e55", e55); photon->set_shower_shape_parameter("e77", e77); @@ -909,4 +921,4 @@ double PhotonClusterBuilder::deltaR(double eta1, double phi1, double eta2, doubl dphi += 2 * M_PI; } return sqrt(pow(eta1 - eta2, 2) + pow(dphi, 2)); -} +} \ No newline at end of file From 66f7822a0485031066f4a504adf35c8b037023b4 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Thu, 8 Jan 2026 11:02:53 -0500 Subject: [PATCH 033/393] =?UTF-8?q?Revert=20"=F0=9F=93=9D=20Add=20docstrin?= =?UTF-8?q?gs=20to=20`photonclass`"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- offline/packages/CaloReco/PhotonClusterBuilder.cc | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/offline/packages/CaloReco/PhotonClusterBuilder.cc b/offline/packages/CaloReco/PhotonClusterBuilder.cc index 59bb5be1ae..edcf5f4418 100644 --- a/offline/packages/CaloReco/PhotonClusterBuilder.cc +++ b/offline/packages/CaloReco/PhotonClusterBuilder.cc @@ -272,17 +272,6 @@ void PhotonClusterBuilder::calculate_bdt_score(PhotonClusterv1* photon) photon->set_shower_shape_parameter("bdt_score", bdt_score); } -/// @brief Extracts and stores shower-shape and isolation observables for a cluster onto a PhotonClusterv1. -/// -— Computes a 7x7 local energy grid around the cluster lead tower, derives moments, summed energies -— (e.g., e11, e22, e33, e55, e77 and related e13..e75), centroid and width metrics (weta, wphi, cog variants), -— timing and saturation counters, closest HCAL tower ET summaries, and calorimeter-layer isolation values, -— and attaches these values to the provided photon via set_shower_shape_parameter. -/// -@param rc Pointer to the RawCluster providing tower membership and shower-shape inputs; if rc->get_shower_shapes(...) is empty the function returns without modifying the photon. -///@param photon PhotonClusterv1 instance to receive computed shower-shape and isolation parameters. -///@param cluster_eta Pseudorapidity of the cluster (used for ET calculations and stored as "cluster_eta"). -///@param cluster_phi Azimuthal angle of the cluster (used for storage as "cluster_phi"). void PhotonClusterBuilder::calculate_shower_shapes(RawCluster* rc, PhotonClusterv1* photon, float cluster_eta, float cluster_phi) { std::vector showershape = rc->get_shower_shapes(m_shape_min_tower_E); @@ -921,4 +910,4 @@ double PhotonClusterBuilder::deltaR(double eta1, double phi1, double eta2, doubl dphi += 2 * M_PI; } return sqrt(pow(eta1 - eta2, 2) + pow(dphi, 2)); -} \ No newline at end of file +} From 7e92dc741cb391e4d3ab4a21b9d0df7b3c2d6262 Mon Sep 17 00:00:00 2001 From: emclaughlin2 Date: Thu, 8 Jan 2026 13:24:39 -0500 Subject: [PATCH 034/393] Fix bugs in CaloValid to select correct MB + 10 cm trigger --- offline/QA/Calorimeters/CaloValid.cc | 8 ++++---- offline/QA/Calorimeters/CaloValid.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/offline/QA/Calorimeters/CaloValid.cc b/offline/QA/Calorimeters/CaloValid.cc index 243395c2bb..756169c105 100644 --- a/offline/QA/Calorimeters/CaloValid.cc +++ b/offline/QA/Calorimeters/CaloValid.cc @@ -267,7 +267,7 @@ int CaloValid::process_towers(PHCompositeNode* topNode) uint64_t raw[64] = {0}; uint64_t live[64] = {0}; // long long int scaled[64] = { 0 }; - Gl1Packet* gl1PacketInfo = findNode::getClass(topNode, 14001); + Gl1Packet* gl1PacketInfo = findNode::getClass(topNode, "14001"); if (!gl1PacketInfo) { gl1PacketInfo = findNode::getClass(topNode, "GL1Packet"); @@ -344,7 +344,7 @@ int CaloValid::process_towers(PHCompositeNode* topNode) { h_cemc_etaphi_time->Fill(ieta, iphi, _timef); h_cemc_etaphi->Fill(ieta, iphi); - if (isGood && (scaledBits[10] || scaledBits[11])) + if (isGood && (scaledBits[10] || scaledBits[12])) { h_cemc_etaphi_wQA->Fill(ieta, iphi, offlineenergy); } @@ -420,7 +420,7 @@ int CaloValid::process_towers(PHCompositeNode* topNode) { h_ihcal_etaphi->Fill(ieta, iphi); h_ihcal_etaphi_time->Fill(ieta, iphi, _timef); - if (isGood && (scaledBits[10] || scaledBits[11])) + if (isGood && (scaledBits[10] || scaledBits[12])) { h_ihcal_etaphi_wQA->Fill(ieta, iphi, offlineenergy); } @@ -488,7 +488,7 @@ int CaloValid::process_towers(PHCompositeNode* topNode) { h_ohcal_etaphi_time->Fill(ieta, iphi, _timef); h_ohcal_etaphi->Fill(ieta, iphi); - if (isGood && (scaledBits[10] || scaledBits[11])) + if (isGood && (scaledBits[10] || scaledBits[12])) { h_ohcal_etaphi_wQA->Fill(ieta, iphi, offlineenergy); } diff --git a/offline/QA/Calorimeters/CaloValid.h b/offline/QA/Calorimeters/CaloValid.h index 2e2f9e278e..baaede0fe5 100644 --- a/offline/QA/Calorimeters/CaloValid.h +++ b/offline/QA/Calorimeters/CaloValid.h @@ -55,7 +55,7 @@ class CaloValid : public SubsysReco TriggerAnalyzer* trigAna{nullptr}; TH3* h_pi0_trigIB_mass{nullptr}; - std::vector triggerIndices{10, 28, 29, 30, 31}; // MBD NS>=1, Photon Triggers + std::vector triggerIndices{10, 12, 28, 29, 30, 31}; // MBD NS>=1, Photon Triggers TH1* h_cemc_channel_pedestal[128 * 192]{nullptr}; TH1* h_ihcal_channel_pedestal[32 * 48]{nullptr}; From a573ec3353165b9f96dee9bdd29a1b22439f5bc9 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Thu, 8 Jan 2026 16:42:46 -0500 Subject: [PATCH 035/393] make setters functional --- offline/packages/trackreco/PHActsTrkFitter.h | 2 +- offline/packages/trackreco/PHSiliconTpcTrackMatching.cc | 4 ++-- offline/packages/trackreco/PHSiliconTpcTrackMatching.h | 6 +++++- offline/packages/trackreco/PHSimpleVertexFinder.h | 2 +- offline/packages/trackreco/PHTpcDeltaZCorrection.h | 2 +- 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/offline/packages/trackreco/PHActsTrkFitter.h b/offline/packages/trackreco/PHActsTrkFitter.h index d0e221a40e..cca5095c79 100644 --- a/offline/packages/trackreco/PHActsTrkFitter.h +++ b/offline/packages/trackreco/PHActsTrkFitter.h @@ -142,7 +142,7 @@ class PHActsTrkFitter : public SubsysReco void set_enable_geometric_crossing_estimate(bool flag) { m_enable_crossing_estimate = flag; } void set_use_clustermover(bool use) { m_use_clustermover = use; } void ignoreLayer(int layer) { m_ignoreLayer.insert(layer); } - void setTrkrClusterContainerName(std::string& name) { m_clusterContainerName = name; } + void setTrkrClusterContainerName(const std::string& name) { m_clusterContainerName = name; } void setDirectNavigation(bool flag) { m_directNavigation = flag; } private: diff --git a/offline/packages/trackreco/PHSiliconTpcTrackMatching.cc b/offline/packages/trackreco/PHSiliconTpcTrackMatching.cc index 2e66a6df28..6aaae4bf93 100644 --- a/offline/packages/trackreco/PHSiliconTpcTrackMatching.cc +++ b/offline/packages/trackreco/PHSiliconTpcTrackMatching.cc @@ -445,10 +445,10 @@ int PHSiliconTpcTrackMatching::GetNodes(PHCompositeNode *topNode) svtxNode->addNode(node); } - _cluster_map = findNode::getClass(topNode, "TRKR_CLUSTER"); + _cluster_map = findNode::getClass(topNode, _cluster_map_name); if (!_cluster_map) { - std::cout << PHWHERE << " ERROR: Can't find node TRKR_CLUSTER" << std::endl; + std::cout << PHWHERE << " ERROR: Can't find node " <<_cluster_map_name << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } diff --git a/offline/packages/trackreco/PHSiliconTpcTrackMatching.h b/offline/packages/trackreco/PHSiliconTpcTrackMatching.h index acb157bd83..6de4a1dd3a 100644 --- a/offline/packages/trackreco/PHSiliconTpcTrackMatching.h +++ b/offline/packages/trackreco/PHSiliconTpcTrackMatching.h @@ -139,7 +139,10 @@ class PHSiliconTpcTrackMatching : public SubsysReco, public PHParameterInterface void set_file_name(const std::string &name) { _file_name = name; } void set_pp_mode(const bool flag) { _pp_mode = flag; } void set_use_intt_crossing(const bool flag) { _use_intt_crossing = flag; } - + void set_cluster_map_name(const std::string &name) + { + _cluster_map_name = name; + } int InitRun(PHCompositeNode *topNode) override; int process_event(PHCompositeNode *) override; @@ -210,6 +213,7 @@ class PHSiliconTpcTrackMatching : public SubsysReco, public PHParameterInterface int _n_iteration = 0; std::string _track_map_name = "TpcTrackSeedContainer"; std::string _silicon_track_map_name = "SiliconTrackSeedContainer"; + std::string _cluster_map_name = "TRKR_CLUSTER"; std::string m_fieldMap = "1.4"; std::vector getTrackletClusterList(TrackSeed* tracklet); }; diff --git a/offline/packages/trackreco/PHSimpleVertexFinder.h b/offline/packages/trackreco/PHSimpleVertexFinder.h index da0e36fabf..6915693c4b 100644 --- a/offline/packages/trackreco/PHSimpleVertexFinder.h +++ b/offline/packages/trackreco/PHSimpleVertexFinder.h @@ -54,7 +54,7 @@ class PHSimpleVertexFinder : public SubsysReco void setTrackMapName(const std::string &name) { _track_map_name = name; } void setVertexMapName(const std::string &name) { _vertex_map_name = name; } void zeroField(const bool flag) { _zero_field = flag; } - void setTrkrClusterContainerName(std::string &name){ m_clusterContainerName = name; } + void setTrkrClusterContainerName(const std::string &name){ m_clusterContainerName = name; } void set_pp_mode(bool mode) { _pp_mode = mode; } private: diff --git a/offline/packages/trackreco/PHTpcDeltaZCorrection.h b/offline/packages/trackreco/PHTpcDeltaZCorrection.h index 46d099f587..4d383cc854 100644 --- a/offline/packages/trackreco/PHTpcDeltaZCorrection.h +++ b/offline/packages/trackreco/PHTpcDeltaZCorrection.h @@ -32,7 +32,7 @@ class PHTpcDeltaZCorrection : public SubsysReco, public PHParameterInterface int process_event(PHCompositeNode *topNode) override; int End(PHCompositeNode *topNode) override; void SetDefaultParameters() override; - void setTrkrClusterContainerName(std::string &name) { m_clusterContainerName = name; } + void setTrkrClusterContainerName(const std::string &name) { m_clusterContainerName = name; } private: /// load nodes From fcb63122023840acf3277b9267bb32e223d81238 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Thu, 8 Jan 2026 18:55:38 -0500 Subject: [PATCH 036/393] Fix Gl1Packet ID type from string to integer Tonight I am going to have fried rabbit... I added the integer interface so we can just use the packet id as nodename without having to convert to strings (that's done inside the code - that's the only thing this interface does). Sorry about that --- offline/QA/Calorimeters/CaloValid.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/QA/Calorimeters/CaloValid.cc b/offline/QA/Calorimeters/CaloValid.cc index 756169c105..19c834bdab 100644 --- a/offline/QA/Calorimeters/CaloValid.cc +++ b/offline/QA/Calorimeters/CaloValid.cc @@ -267,7 +267,7 @@ int CaloValid::process_towers(PHCompositeNode* topNode) uint64_t raw[64] = {0}; uint64_t live[64] = {0}; // long long int scaled[64] = { 0 }; - Gl1Packet* gl1PacketInfo = findNode::getClass(topNode, "14001"); + Gl1Packet* gl1PacketInfo = findNode::getClass(topNode, 14001); if (!gl1PacketInfo) { gl1PacketInfo = findNode::getClass(topNode, "GL1Packet"); From 36cd47aa98888fa88e97872d9894c15eb288f70c Mon Sep 17 00:00:00 2001 From: silas-gross Date: Fri, 9 Jan 2026 08:46:01 -0500 Subject: [PATCH 037/393] adding more of the skeleton structure --- .../HepMCTrigger/HepMCParticleTrigger.cc | 165 ++++++++++++++++++ .../HepMCTrigger/HepMCParticleTrigger.h | 123 +++++++++++++ 2 files changed, 288 insertions(+) create mode 100644 generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc create mode 100644 generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h diff --git a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc new file mode 100644 index 0000000000..71e35b3bb9 --- /dev/null +++ b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc @@ -0,0 +1,165 @@ +#include "HepMCJetTrigger.h" + +#include +#include +#include + +#include + +#include +#include + +#include + +#include + +#include +#include +#include + +//____________________________________________________________________________.. +// NOLINTNEXTLINE(bugprone-easily-swappable-parameters) +HepMCJetTrigger::HepMCJetTrigger(float trigger_thresh, int n_incom, bool up_lim, const std::string& name) + : SubsysReco(name) + , threshold(trigger_thresh) + , goal_event_number(n_incom) + , set_event_limit(up_lim) + , _theEtaHigh(-999.9) + , _theEtaLow(-999.9) + , _thePtHigh(999.9) + , _thePtLow(-999.9) + , _thePHigh(999.9) + , _thePLow(-999.9) + , _thePzHigh(999.9) + , _thePzLow(-999.9) + , + + _doEtaHighCut(false) + , _doEtaLowCut(false) + , _doBothEtaCut(false) + , + + _doAbsEtaHighCut(false) + , _doAbsEtaLowCut(false) + , _doBothAbsEtaCut(false) + , + + _doPtHighCut(false) + , _doPtLowCut(false) + , _doBothPtCut(false) + , + + _doPHighCut(false) + , _doPLowCut(false) + , _doBothPCut(false) + , + + _doPzHighCut(false) + , _doPzLowCut(false) + , _doBothPzCut(false) +{ +} + +//____________________________________________________________________________.. +int HepMCJetTrigger::process_event(PHCompositeNode* topNode) +{ + // std::cout << "HepMCJetTrigger::process_event(PHCompositeNode *topNode) Processing Event" << std::endl; + n_evts++; + if (this->set_event_limit == true) + { // needed to keep all HepMC output at the same number of events + if (n_good >= this->goal_event_number) + { + return Fun4AllReturnCodes::ABORTEVENT; + } + } + PHHepMCGenEventMap* phg = findNode::getClass(topNode, "PHHepMCGenEventMap"); + if (!phg) + { + return Fun4AllReturnCodes::ABORTEVENT; + } + for (PHHepMCGenEventMap::ConstIter eventIter = phg->begin(); eventIter != phg->end(); ++eventIter) + { + PHHepMCGenEvent* hepev = eventIter->second; + if (!hepev) + { + return Fun4AllReturnCodes::ABORTEVENT; + } + HepMC::GenEvent* ev = hepev->getEvent(); + if (!ev) + { + return Fun4AllReturnCodes::ABORTEVENT; + } + bool const good_event = isGoodEvent(ev); + if (good_event) + { + n_good++; + } + if (!good_event) + { + return Fun4AllReturnCodes::ABORTEVENT; + } + } + return Fun4AllReturnCodes::EVENT_OK; +} +void HepMCParticleTrigger::AddParticles(const std::string &particles) +{ + std::vector addedParts = convertToInt() + _theParticles.insert( +} +bool HepMCParticleTrigger::isGoodEvent(HepMC::GenEvent* e1) +{ + // this is really just the call to actually evaluate and return the filter + if (this->threshold == 0) + { + return true; + } + std::vector n_trigger_particles = jetsAboveThreshold(jets); + for(auto ntp:n_trigger_particles) + { + if(ntp <=0 ) return false; + } + return true; +} + +std::vector HepMCParticleTrigger::getParticles(HepMC::GenEvent* e1) +{ + for (HepMC::GenEvent::particle_const_iterator iter = e1->particles_begin(); iter != e1->particles_end(); ++iter) + { + if (m_doStableParticleOnly && ((*iter)->end_vertex() && (*iter)->status() != 1)) continue; + else{ + auto p = (*iter)->momentum(); + float px = p.px(); + float py = p.py(); + float pz = p.pz(); + float p = std::sqrt(std::pow(px, 2) + std::pow(py, 2) + std::pow(pz, 2)); + float pt = std::sqrt(std::pow(px, 2) + std::pow(py, 2)); + int pid = (*iter)->pid(); + double eta = p.eta(); + if((_doEtaHighCut || _doBothEtaCut ) && eta > _theEtaHigh) continue; + if((_doEtaLowCut || _doBothEtaCut ) && eta < _theEtaLow) continue; + if((_doAbsEtaHighCut || _doBothAbsEtaCut ) && std::abs(eta) > _theAbsEtaHigh) continue; + if((_doAbsEtaLowCut || _doBothAbsEtaCut ) && std::abs(eta) < _theAbsEtaLow) continue; + if((_doPtHighCut || _doBothPtCut ) && pt > _thePtHigh) continue; + if((_doPLowCut || _doBothPCut ) && pt < _thePtLow) continue; + if((_doPHighCut || _doBothPCut ) && p > _thePHigh) continue; + if((_doPLowCut || _doBothPCut ) && p < _thePLow) continue; + if((_doPzHighCut || _doBothPzCut ) && pz > _thePzHigh) continue; + if((_doPzLowCut || _doBothPzCut ) && pz < _thePzLow) continue; + + } + return output; +} +int HepMCParticle::particlesAboveThreshold(const std::vector& jets) +{ + // search through for the number of identified jets above the threshold + int n_good_jets = 0; + for (const auto& j : jets) + { + float const pt = j.pt(); + if (pt > this->threshold) + { + n_good_jets++; + } + } + return n_good_jets; +} diff --git a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h new file mode 100644 index 0000000000..33f2c82486 --- /dev/null +++ b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h @@ -0,0 +1,123 @@ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef HEPMCJETTRIGGER_H +#define HEPMCJETTRIGGER_H + +#include + +#include + +#include +#include + +class PHCompositeNode; +namespace HepMC +{ + class GenEvent; +} + +class HepMCJetTrigger : public SubsysReco +{ + public: + HepMCJetTrigger(float trigger_thresh = 10., int n_incom = 1000, bool up_lim = false, const std::string& name = "HepMCJetTrigger"); + + ~HepMCJetTrigger() override = default; + + /** Called during initialization. + Typically this is where you can book histograms, and e.g. + register them to Fun4AllServer (so they can be output to file + using Fun4AllServer::dumpHistos() method). + */ + + /** Called for first event when run number is known. + Typically this is where you may want to fetch data from + database, because you know the run number. A place + to book histograms which have to know the run number. + */ + + /** Called for each event. + This is where you do the real work. + */ + int process_event(PHCompositeNode* topNode) override; + + /// Clean up internals after each event. + + /// Called at the end of each run. + + /// Called at the end of all processing. + + /// Reset + void AddParticles(const std::string &particles); + void AddParticles(int particle); + void AddParticles(std::vector particles); + void AddParticlespID(std::vector particles); + + void AddParents(const std::string &parents); + void AddParents(int parent); + void AddParents(std::vector parents); + void AddParentspID(std::vector parents); + + void SetPtHigh(double pt); + void SetPtLow(double pt); + void SetPtHighLow(double ptHigh, double ptLow); + + void SetPHigh(double p); + void SetPLow(double p); + void SetPHighLow(double pHigh, double pLow); + + void SetEtaHigh(double eta); + void SetEtaLow(double eta); + void SetEtaHighLow(double etaHigh, double etaLow); + + void SetAbsEtaHigh(double eta); + void SetAbsEtaLow(double eta); + void SetAbsEtaHighLow(double etaHigh, double etaLow); + + void SetPzHigh(double pz); + void SetPzLow(double pz); + void SetPzHighLow(double pzHigh, double pzLow); + + void SetStableParticleOnly(bool b) { m_doStableParticleOnly = b; } + private: + std::vector _theParents; + std::vector _theParticles; + + bool isGoodEvent(HepMC::GenEvent* e1); + std::vector findAllParticles(HepMC::GenEvent* e1); + int particleAboveThreshold(std::map n_particles, int particle); + float threshold{0.}; + int goal_event_number{1000}; + int n_evts{0}; + int n_good{0}; + bool set_event_limit{false}; + float _theEtaHigh{-999.9}; + float _theEtaLow{-999.9}; + float _thePtHigh(999.9}; + float _thePtLow(-999.9}; + float _thePHigh(999.9}; + float _thePLow(-999.9}; + float _thePzHigh(999.9}; + float _thePzLow(-999.9}; + + bool _doEtaHighCut{false}; + bool _doEtaLowCut{false}; + bool _doBothEtaCut{false}; + + bool _doAbsEtaHighCut{false}; + bool _doAbsEtaLowCut{false}; + bool _doBothAbsEtaCut{false}; + + bool _doPtHighCut{false}; + bool _doPtLowCut{false}; + bool _doBothPtCut{false}; + + bool _doPHighCut{false}; + bool _doPLowCut{false}; + bool _doBothPCut{false}; + + bool _doPzHighCut{false}; + bool _doPzLowCut{false}; + bool _doBothPzCut{false}; +}; + +#endif // HEPMCJETTRIGGER_H From c3615514e6b4be3508b379a356831e285fe4ce25 Mon Sep 17 00:00:00 2001 From: silas-gross Date: Fri, 9 Jan 2026 19:29:25 -0500 Subject: [PATCH 038/393] Nearly done, just need to dust around the edges --- .../HepMCTrigger/HepMCParticleTrigger.cc | 172 +++++++++++++++--- .../HepMCTrigger/HepMCParticleTrigger.h | 48 +++-- 2 files changed, 171 insertions(+), 49 deletions(-) diff --git a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc index 71e35b3bb9..3bf04c5e65 100644 --- a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc +++ b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc @@ -101,29 +101,152 @@ int HepMCJetTrigger::process_event(PHCompositeNode* topNode) } return Fun4AllReturnCodes::EVENT_OK; } -void HepMCParticleTrigger::AddParticles(const std::string &particles) +void HepMCParticleTrigger::AddParticle(int particlePid) { - std::vector addedParts = convertToInt() - _theParticles.insert( + _theParticles.push_back(particlePid); + return; +} +void HepMCParticleTrigger::AddParticles(std::vector particles) +{ + for(auto p:particles) _theParticles.push_back(p); + return; +} + +void SetPtHigh(double pt) +{ + _thePtHigh=pt; + _doPtHighCut=true; + if(_doPtLowCut) _doBothPtCut=true; + return; +} +void SetPtLow(double pt) +{ + _thePtLow=pt; + _doPtLowCut=true; + if(_doPtHighCut) _doBothPtCut=true; + return; +} +void SetPtHighLow(double ptHigh, double ptLow) +{ + _thePtHigh=pt; + _doPtHighCut=true; + _thePtLow=pt; + _doPtLowCut=true; + _doBothPtCut=true; + return; +} +void SetPHigh(double pt) +{ + _thePHigh=pt; + _doPHighCut=true; + if(_doPLowCut) _doBothPCut=true; + return; +} +void SetPLow(double pt) +{ + _thePLow=pt; + _doPLowCut=true; + if(_doPHighCut) _doBothPCut=true; + return; +} +void SetPHighLow(double ptHigh, double ptLow) +{ + _thePHigh=pt; + _doPHighCut=true; + _thePLow=pt; + _doPLowCut=true; + _doBothPCut=true; + return; +} +void SetPzHigh(double pt) +{ + _thePzHigh=pt; + _doPzHighCut=true; + if(_doPzLowCut) _doBothPzCut=true; + return; +} +void SetPzLow(double pt) +{ + _thePzLow=pt; + _doPzLowCut=true; + if(_doPzHighCut) _doBothPzCut=true; + return; +} +void SetPzHighLow(double ptHigh, double ptLow) +{ + _thePzHigh=pt; + _doPzHighCut=true; + _thePzLow=pt; + _doPzLowCut=true; + _doBothPzCut=true; + return; +} +void SetEtaHigh(double pt) +{ + _theEtaHigh=pt; + _doEtaHighCut=true; + if(_doEtaLowCut) _doBothEtaCut=true; + return; +} +void SetEtaLow(double pt) +{ + _theEtaLow=pt; + _doEtaLowCut=true; + if(_doEtaHighCut) _doBothEtaCut=true; + return; +} +void SetEtaHighLow(double ptHigh, double ptLow) +{ + _theEtaHigh=pt; + _doEtaHighCut=true; + _theEtaLow=pt; + _doEtaLowCut=true; + _doBothEtaCut=true; + return; +} +void SetAbsEtaHigh(double pt) +{ + _theAbsEtaHigh=pt; + _doAbsEtaHighCut=true; + if(_doAbsEtaLowCut) _doBothAbsEtaCut=true; + return; +} +void SetAbsEtaLow(double pt) +{ + _theAbsEtaLow=pt; + _doAbsEtaLowCut=true; + if(_doAbsEtaHighCut) _doBothAbsEtaCut=true; + return; +} +void SetAbsEtaHighLow(double ptHigh, double ptLow) +{ + _theAbsEtaHigh=pt; + _doAbsEtaHighCut=true; + _theAbsEtaLow=pt; + _doAbsEtaLowCut=true; + _doBothAbsEtaCut=true; + return; } bool HepMCParticleTrigger::isGoodEvent(HepMC::GenEvent* e1) { // this is really just the call to actually evaluate and return the filter - if (this->threshold == 0) + /*if (this->threshold == 0) { return true; - } - std::vector n_trigger_particles = jetsAboveThreshold(jets); + }*/ + std::vector n_trigger_particles = getParticles(e1); for(auto ntp:n_trigger_particles) { - if(ntp <=0 ) return false; + if(ntp <=0 ) return false; //make sure all } return true; } std::vector HepMCParticleTrigger::getParticles(HepMC::GenEvent* e1) -{ - for (HepMC::GenEvent::particle_const_iterator iter = e1->particles_begin(); iter != e1->particles_end(); ++iter) +{ + std::vector n_trigger {}; + std::map particle_types; + for (HepMC::GenEvent::particle_const_iterator iter = e1->particles_begin(); iter != e1->particles_end(); ++iter) { if (m_doStableParticleOnly && ((*iter)->end_vertex() && (*iter)->status() != 1)) continue; else{ @@ -137,29 +260,30 @@ std::vector HepMCParticleTrigger::getParticles(HepMC::GenEvent* e1) double eta = p.eta(); if((_doEtaHighCut || _doBothEtaCut ) && eta > _theEtaHigh) continue; if((_doEtaLowCut || _doBothEtaCut ) && eta < _theEtaLow) continue; - if((_doAbsEtaHighCut || _doBothAbsEtaCut ) && std::abs(eta) > _theAbsEtaHigh) continue; - if((_doAbsEtaLowCut || _doBothAbsEtaCut ) && std::abs(eta) < _theAbsEtaLow) continue; + if((_doAbsEtaHighCut || _doBothAbsEtaCut ) && std::abs(eta) > _theEtaHigh) continue; + if((_doAbsEtaLowCut || _doBothAbsEtaCut ) && std::abs(eta) < _theEtaLow) continue; if((_doPtHighCut || _doBothPtCut ) && pt > _thePtHigh) continue; if((_doPLowCut || _doBothPCut ) && pt < _thePtLow) continue; if((_doPHighCut || _doBothPCut ) && p > _thePHigh) continue; if((_doPLowCut || _doBothPCut ) && p < _thePLow) continue; if((_doPzHighCut || _doBothPzCut ) && pz > _thePzHigh) continue; if((_doPzLowCut || _doBothPzCut ) && pz < _thePzLow) continue; + if(particle_types.find(pid) != particle_types.end()) particle_types[pid]++; + else particle_types[pid]=1; + } + for(auto p:_theParticles) + { + n_trigger.push_back(particlesAboveThreshold(particle_types, p)); //make sure we have at least one of each required particle + } } - return output; + return n_trigger; } -int HepMCParticle::particlesAboveThreshold(const std::vector& jets) +int HepMCParticle::particlesAboveThreshold(std::map n_particles, int trigger_particle ) { - // search through for the number of identified jets above the threshold - int n_good_jets = 0; - for (const auto& j : jets) - { - float const pt = j.pt(); - if (pt > this->threshold) - { - n_good_jets++; - } - } - return n_good_jets; + // search through for the number of identified trigger particles passing cuts + for(auto p:n_particles){ + if(std::abs(p.first) == std::abs(trigger_particle)) return p.second; //accept both trigger particle and antiparticle + } + return 0; } diff --git a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h index 33f2c82486..a20eab5c6a 100644 --- a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h +++ b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h @@ -47,44 +47,42 @@ class HepMCJetTrigger : public SubsysReco /// Called at the end of all processing. /// Reset - void AddParticles(const std::string &particles); - void AddParticles(int particle); - void AddParticles(std::vector particles); - void AddParticlespID(std::vector particles); + void AddParticles(std::vector); + void AddParticle(int); - void AddParents(const std::string &parents); +/* void AddParents(const std::string &parents); void AddParents(int parent); void AddParents(std::vector parents); void AddParentspID(std::vector parents); - - void SetPtHigh(double pt); - void SetPtLow(double pt); - void SetPtHighLow(double ptHigh, double ptLow); - - void SetPHigh(double p); - void SetPLow(double p); - void SetPHighLow(double pHigh, double pLow); +*/ + void SetPtHigh(double); + void SetPtLow(double); + void SetPtHighLow(double, double); + + void SetPHigh(double); + void SetPLow(double); + void SetPHighLow(double, double); - void SetEtaHigh(double eta); - void SetEtaLow(double eta); - void SetEtaHighLow(double etaHigh, double etaLow); + void SetEtaHigh(double); + void SetEtaLow(double); + void SetEtaHighLow(double, double); - void SetAbsEtaHigh(double eta); - void SetAbsEtaLow(double eta); - void SetAbsEtaHighLow(double etaHigh, double etaLow); + void SetAbsEtaHigh(double); + void SetAbsEtaLow(double); + void SetAbsEtaHighLow(double, double); - void SetPzHigh(double pz); - void SetPzLow(double pz); - void SetPzHighLow(double pzHigh, double pzLow); + void SetPzHigh(double); + void SetPzLow(double); + void SetPzHighLow(double, double); void SetStableParticleOnly(bool b) { m_doStableParticleOnly = b; } private: - std::vector _theParents; - std::vector _theParticles; - bool isGoodEvent(HepMC::GenEvent* e1); std::vector findAllParticles(HepMC::GenEvent* e1); int particleAboveThreshold(std::map n_particles, int particle); + std::vector _theParentsi {}; + std::vector _theParticles {}; + bool m_doStableParticleOnly {true}; float threshold{0.}; int goal_event_number{1000}; int n_evts{0}; From 23ef520ae205100966a33f7e55d89c06fd76cf95 Mon Sep 17 00:00:00 2001 From: silas-gross Date: Sat, 10 Jan 2026 00:37:51 -0500 Subject: [PATCH 039/393] Bare minimum working version of HepMC particle trigger. Requires input of trigger particle to be in the form of the PDG ID number, working on mimizing friction --- .../HepMCTrigger/HepMCParticleTrigger.cc | 83 ++++++++++--------- .../HepMCTrigger/HepMCParticleTrigger.h | 30 +++---- generators/Herwig/HepMCTrigger/Makefile.am | 15 +++- 3 files changed, 73 insertions(+), 55 deletions(-) diff --git a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc index 3bf04c5e65..78df141289 100644 --- a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc +++ b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc @@ -1,4 +1,4 @@ -#include "HepMCJetTrigger.h" +#include "HepMCParticleTrigger.h" #include #include @@ -16,10 +16,10 @@ #include #include #include - +#include //____________________________________________________________________________.. // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) -HepMCJetTrigger::HepMCJetTrigger(float trigger_thresh, int n_incom, bool up_lim, const std::string& name) +HepMCParticleTrigger::HepMCParticleTrigger(float trigger_thresh, int n_incom, bool up_lim, const std::string& name) : SubsysReco(name) , threshold(trigger_thresh) , goal_event_number(n_incom) @@ -58,12 +58,17 @@ HepMCJetTrigger::HepMCJetTrigger(float trigger_thresh, int n_incom, bool up_lim, , _doPzLowCut(false) , _doBothPzCut(false) { + if(threshold != 0 ) + { + _doPtLowCut=true; + _thePtLow=threshold; + } } //____________________________________________________________________________.. -int HepMCJetTrigger::process_event(PHCompositeNode* topNode) +int HepMCParticleTrigger::process_event(PHCompositeNode* topNode) { - // std::cout << "HepMCJetTrigger::process_event(PHCompositeNode *topNode) Processing Event" << std::endl; + // std::cout << "HepMCParticleTrigger::process_event(PHCompositeNode *topNode) Processing Event" << std::endl; n_evts++; if (this->set_event_limit == true) { // needed to keep all HepMC output at the same number of events @@ -112,117 +117,117 @@ void HepMCParticleTrigger::AddParticles(std::vector particles) return; } -void SetPtHigh(double pt) +void HepMCParticleTrigger::SetPtHigh(double pt) { _thePtHigh=pt; _doPtHighCut=true; if(_doPtLowCut) _doBothPtCut=true; return; } -void SetPtLow(double pt) +void HepMCParticleTrigger::SetPtLow(double pt) { _thePtLow=pt; _doPtLowCut=true; if(_doPtHighCut) _doBothPtCut=true; return; } -void SetPtHighLow(double ptHigh, double ptLow) +void HepMCParticleTrigger::SetPtHighLow(double ptHigh, double ptLow) { - _thePtHigh=pt; + _thePtHigh=ptHigh; _doPtHighCut=true; - _thePtLow=pt; + _thePtLow=ptLow; _doPtLowCut=true; _doBothPtCut=true; return; } -void SetPHigh(double pt) +void HepMCParticleTrigger::SetPHigh(double pt) { _thePHigh=pt; _doPHighCut=true; if(_doPLowCut) _doBothPCut=true; return; } -void SetPLow(double pt) +void HepMCParticleTrigger::SetPLow(double pt) { _thePLow=pt; _doPLowCut=true; if(_doPHighCut) _doBothPCut=true; return; } -void SetPHighLow(double ptHigh, double ptLow) +void HepMCParticleTrigger::SetPHighLow(double ptHigh, double ptLow) { - _thePHigh=pt; + _thePHigh=ptHigh; _doPHighCut=true; - _thePLow=pt; + _thePLow=ptLow; _doPLowCut=true; _doBothPCut=true; return; } -void SetPzHigh(double pt) +void HepMCParticleTrigger::SetPzHigh(double pt) { _thePzHigh=pt; _doPzHighCut=true; if(_doPzLowCut) _doBothPzCut=true; return; } -void SetPzLow(double pt) +void HepMCParticleTrigger::SetPzLow(double pt) { _thePzLow=pt; _doPzLowCut=true; if(_doPzHighCut) _doBothPzCut=true; return; } -void SetPzHighLow(double ptHigh, double ptLow) +void HepMCParticleTrigger::SetPzHighLow(double ptHigh, double ptLow) { - _thePzHigh=pt; + _thePzHigh=ptHigh; _doPzHighCut=true; - _thePzLow=pt; + _thePzLow=ptLow; _doPzLowCut=true; _doBothPzCut=true; return; } -void SetEtaHigh(double pt) +void HepMCParticleTrigger::SetEtaHigh(double pt) { _theEtaHigh=pt; _doEtaHighCut=true; if(_doEtaLowCut) _doBothEtaCut=true; return; } -void SetEtaLow(double pt) +void HepMCParticleTrigger::SetEtaLow(double pt) { _theEtaLow=pt; _doEtaLowCut=true; if(_doEtaHighCut) _doBothEtaCut=true; return; } -void SetEtaHighLow(double ptHigh, double ptLow) +void HepMCParticleTrigger::SetEtaHighLow(double ptHigh, double ptLow) { - _theEtaHigh=pt; + _theEtaHigh=ptHigh; _doEtaHighCut=true; - _theEtaLow=pt; + _theEtaLow=ptLow; _doEtaLowCut=true; _doBothEtaCut=true; return; } -void SetAbsEtaHigh(double pt) +void HepMCParticleTrigger::SetAbsEtaHigh(double pt) { - _theAbsEtaHigh=pt; + _theEtaHigh=pt; _doAbsEtaHighCut=true; if(_doAbsEtaLowCut) _doBothAbsEtaCut=true; return; } -void SetAbsEtaLow(double pt) +void HepMCParticleTrigger::SetAbsEtaLow(double pt) { - _theAbsEtaLow=pt; + _theEtaLow=pt; _doAbsEtaLowCut=true; if(_doAbsEtaHighCut) _doBothAbsEtaCut=true; return; } -void SetAbsEtaHighLow(double ptHigh, double ptLow) +void HepMCParticleTrigger::SetAbsEtaHighLow(double ptHigh, double ptLow) { - _theAbsEtaHigh=pt; + _theEtaHigh=ptHigh; _doAbsEtaHighCut=true; - _theAbsEtaLow=pt; + _theEtaLow=ptLow; _doAbsEtaLowCut=true; _doBothAbsEtaCut=true; return; @@ -237,7 +242,7 @@ bool HepMCParticleTrigger::isGoodEvent(HepMC::GenEvent* e1) std::vector n_trigger_particles = getParticles(e1); for(auto ntp:n_trigger_particles) { - if(ntp <=0 ) return false; //make sure all + if(ntp <=0 ) return false; //make sure all particles have at least 1 } return true; } @@ -254,9 +259,9 @@ std::vector HepMCParticleTrigger::getParticles(HepMC::GenEvent* e1) float px = p.px(); float py = p.py(); float pz = p.pz(); - float p = std::sqrt(std::pow(px, 2) + std::pow(py, 2) + std::pow(pz, 2)); + float p_M = std::sqrt(std::pow(px, 2) + std::pow(py, 2) + std::pow(pz, 2)); float pt = std::sqrt(std::pow(px, 2) + std::pow(py, 2)); - int pid = (*iter)->pid(); + int pid = (*iter)->pdg_id(); double eta = p.eta(); if((_doEtaHighCut || _doBothEtaCut ) && eta > _theEtaHigh) continue; if((_doEtaLowCut || _doBothEtaCut ) && eta < _theEtaLow) continue; @@ -264,8 +269,8 @@ std::vector HepMCParticleTrigger::getParticles(HepMC::GenEvent* e1) if((_doAbsEtaLowCut || _doBothAbsEtaCut ) && std::abs(eta) < _theEtaLow) continue; if((_doPtHighCut || _doBothPtCut ) && pt > _thePtHigh) continue; if((_doPLowCut || _doBothPCut ) && pt < _thePtLow) continue; - if((_doPHighCut || _doBothPCut ) && p > _thePHigh) continue; - if((_doPLowCut || _doBothPCut ) && p < _thePLow) continue; + if((_doPHighCut || _doBothPCut ) && p_M > _thePHigh) continue; + if((_doPLowCut || _doBothPCut ) && p_M < _thePLow) continue; if((_doPzHighCut || _doBothPzCut ) && pz > _thePzHigh) continue; if((_doPzLowCut || _doBothPzCut ) && pz < _thePzLow) continue; if(particle_types.find(pid) != particle_types.end()) particle_types[pid]++; @@ -273,13 +278,13 @@ std::vector HepMCParticleTrigger::getParticles(HepMC::GenEvent* e1) } for(auto p:_theParticles) { - n_trigger.push_back(particlesAboveThreshold(particle_types, p)); //make sure we have at least one of each required particle + n_trigger.push_back(particleAboveThreshold(particle_types, p)); //make sure we have at least one of each required particle } } return n_trigger; } -int HepMCParticle::particlesAboveThreshold(std::map n_particles, int trigger_particle ) +int HepMCParticleTrigger::particleAboveThreshold(std::map n_particles, int trigger_particle ) { // search through for the number of identified trigger particles passing cuts for(auto p:n_particles){ diff --git a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h index a20eab5c6a..904c8b381b 100644 --- a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h +++ b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h @@ -1,7 +1,7 @@ // Tell emacs that this is a C++ source // -*- C++ -*-. -#ifndef HEPMCJETTRIGGER_H -#define HEPMCJETTRIGGER_H +#ifndef HEPMCPARTICLETRIGGER_H +#define HEPMCPARTICLETRIGGER_H #include @@ -9,6 +9,7 @@ #include #include +#include class PHCompositeNode; namespace HepMC @@ -16,12 +17,12 @@ namespace HepMC class GenEvent; } -class HepMCJetTrigger : public SubsysReco +class HepMCParticleTrigger : public SubsysReco { public: - HepMCJetTrigger(float trigger_thresh = 10., int n_incom = 1000, bool up_lim = false, const std::string& name = "HepMCJetTrigger"); + HepMCParticleTrigger(float trigger_thresh = 10., int n_incom = 1000, bool up_lim = false, const std::string& name = "HepMCParticleTrigger"); - ~HepMCJetTrigger() override = default; + ~HepMCParticleTrigger() override = default; /** Called during initialization. Typically this is where you can book histograms, and e.g. @@ -78,9 +79,9 @@ class HepMCJetTrigger : public SubsysReco void SetStableParticleOnly(bool b) { m_doStableParticleOnly = b; } private: bool isGoodEvent(HepMC::GenEvent* e1); - std::vector findAllParticles(HepMC::GenEvent* e1); + std::vector getParticles(HepMC::GenEvent* e1); int particleAboveThreshold(std::map n_particles, int particle); - std::vector _theParentsi {}; +// std::vector _theParentsi {}; std::vector _theParticles {}; bool m_doStableParticleOnly {true}; float threshold{0.}; @@ -88,14 +89,15 @@ class HepMCJetTrigger : public SubsysReco int n_evts{0}; int n_good{0}; bool set_event_limit{false}; + float _theEtaHigh{-999.9}; float _theEtaLow{-999.9}; - float _thePtHigh(999.9}; - float _thePtLow(-999.9}; - float _thePHigh(999.9}; - float _thePLow(-999.9}; - float _thePzHigh(999.9}; - float _thePzLow(-999.9}; + float _thePtHigh{999.9}; + float _thePtLow{-999.9}; + float _thePHigh{999.9}; + float _thePLow{-999.9}; + float _thePzHigh{999.9}; + float _thePzLow{-999.9}; bool _doEtaHighCut{false}; bool _doEtaLowCut{false}; @@ -118,4 +120,4 @@ class HepMCJetTrigger : public SubsysReco bool _doBothPzCut{false}; }; -#endif // HEPMCJETTRIGGER_H +#endif // HEPMCPARTICLETRIGGER_H diff --git a/generators/Herwig/HepMCTrigger/Makefile.am b/generators/Herwig/HepMCTrigger/Makefile.am index 17ef6c4221..9807a9a78e 100644 --- a/generators/Herwig/HepMCTrigger/Makefile.am +++ b/generators/Herwig/HepMCTrigger/Makefile.am @@ -12,20 +12,31 @@ AM_LDFLAGS = \ `fastjet-config --libs` pkginclude_HEADERS = \ - HepMCJetTrigger.h + HepMCJetTrigger.h \ + HepMCParticleTrigger.h lib_LTLIBRARIES = \ - libHepMCJetTrigger.la + libHepMCJetTrigger.la \ + libHepMCParticleTrigger.la libHepMCJetTrigger_la_SOURCES = \ HepMCJetTrigger.cc +libHepMCParticleTrigger_la_SOURCES = \ + HepMCParticleTrigger.cc + libHepMCJetTrigger_la_LIBADD = \ -lphool \ -lSubsysReco \ -lfun4all \ -lphhepmc +libHepMCParticleTrigger_la_LIBADD = \ + -lphool \ + -lSubsysReco \ + -lfun4all \ + -lphhepmc + BUILT_SOURCES = testexternals.cc noinst_PROGRAMS = \ From 498393ae4ce57bd504a198d8ec1eea5f3d3cc533 Mon Sep 17 00:00:00 2001 From: silas-gross Date: Sat, 10 Jan 2026 02:55:04 -0500 Subject: [PATCH 040/393] Fixed to adress issues found by CodeRabbit --- .../Herwig/HepMCTrigger/HepMCParticleTrigger.cc | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc index 78df141289..95ec6fbe08 100644 --- a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc +++ b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc @@ -268,7 +268,7 @@ std::vector HepMCParticleTrigger::getParticles(HepMC::GenEvent* e1) if((_doAbsEtaHighCut || _doBothAbsEtaCut ) && std::abs(eta) > _theEtaHigh) continue; if((_doAbsEtaLowCut || _doBothAbsEtaCut ) && std::abs(eta) < _theEtaLow) continue; if((_doPtHighCut || _doBothPtCut ) && pt > _thePtHigh) continue; - if((_doPLowCut || _doBothPCut ) && pt < _thePtLow) continue; + if((_doPtLowCut || _doBothPtCut ) && pt < _thePtLow) continue; if((_doPHighCut || _doBothPCut ) && p_M > _thePHigh) continue; if((_doPLowCut || _doBothPCut ) && p_M < _thePLow) continue; if((_doPzHighCut || _doBothPzCut ) && pz > _thePzHigh) continue; @@ -276,12 +276,11 @@ std::vector HepMCParticleTrigger::getParticles(HepMC::GenEvent* e1) if(particle_types.find(pid) != particle_types.end()) particle_types[pid]++; else particle_types[pid]=1; } - for(auto p:_theParticles) - { - n_trigger.push_back(particleAboveThreshold(particle_types, p)); //make sure we have at least one of each required particle - } - - } + } + for(auto p:_theParticles) + { + n_trigger.push_back(particleAboveThreshold(particle_types, p)); //make sure we have at least one of each required particle + } return n_trigger; } int HepMCParticleTrigger::particleAboveThreshold(std::map n_particles, int trigger_particle ) From e18445b324ad8d1bf30b997e075cfeea18f64e0a Mon Sep 17 00:00:00 2001 From: silas-gross Date: Sat, 10 Jan 2026 04:03:37 -0500 Subject: [PATCH 041/393] a few more code rabbit fixes --- .../HepMCTrigger/HepMCParticleTrigger.cc | 22 +++++++++---------- .../HepMCTrigger/HepMCParticleTrigger.h | 3 ++- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc index 95ec6fbe08..bd23087b24 100644 --- a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc +++ b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc @@ -77,6 +77,7 @@ int HepMCParticleTrigger::process_event(PHCompositeNode* topNode) return Fun4AllReturnCodes::ABORTEVENT; } } + bool good_event; PHHepMCGenEventMap* phg = findNode::getClass(topNode, "PHHepMCGenEventMap"); if (!phg) { @@ -94,16 +95,16 @@ int HepMCParticleTrigger::process_event(PHCompositeNode* topNode) { return Fun4AllReturnCodes::ABORTEVENT; } - bool const good_event = isGoodEvent(ev); - if (good_event) - { - n_good++; - } + good_event = isGoodEvent(ev); if (!good_event) { return Fun4AllReturnCodes::ABORTEVENT; } } + if (good_event) + { + n_good++; + } return Fun4AllReturnCodes::EVENT_OK; } void HepMCParticleTrigger::AddParticle(int particlePid) @@ -253,7 +254,7 @@ std::vector HepMCParticleTrigger::getParticles(HepMC::GenEvent* e1) std::map particle_types; for (HepMC::GenEvent::particle_const_iterator iter = e1->particles_begin(); iter != e1->particles_end(); ++iter) { - if (m_doStableParticleOnly && ((*iter)->end_vertex() && (*iter)->status() != 1)) continue; + if (m_doStableParticleOnly && ((*iter)->end_vertex() || (*iter)->status() != 1)) continue; else{ auto p = (*iter)->momentum(); float px = p.px(); @@ -283,11 +284,10 @@ std::vector HepMCParticleTrigger::getParticles(HepMC::GenEvent* e1) } return n_trigger; } -int HepMCParticleTrigger::particleAboveThreshold(std::map n_particles, int trigger_particle ) +int HepMCParticleTrigger::particleAboveThreshold(const std::map& n_particles, int trigger_particle ) { // search through for the number of identified trigger particles passing cuts - for(auto p:n_particles){ - if(std::abs(p.first) == std::abs(trigger_particle)) return p.second; //accept both trigger particle and antiparticle - } - return 0; + auto it = n_particles.find(std::abs(trigger_particle)); + if( it!= n_particles.end()) return it->second; + else return 0; } diff --git a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h index 904c8b381b..a0124f5292 100644 --- a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h +++ b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h @@ -10,6 +10,7 @@ #include #include #include +#include class PHCompositeNode; namespace HepMC @@ -80,7 +81,7 @@ class HepMCParticleTrigger : public SubsysReco private: bool isGoodEvent(HepMC::GenEvent* e1); std::vector getParticles(HepMC::GenEvent* e1); - int particleAboveThreshold(std::map n_particles, int particle); + int particleAboveThreshold(const std::map& n_particles, int particle); // std::vector _theParentsi {}; std::vector _theParticles {}; bool m_doStableParticleOnly {true}; From ebbee62e94b22bb02b900d2859f47a0ac4990aa1 Mon Sep 17 00:00:00 2001 From: silas-gross Date: Sat, 10 Jan 2026 04:57:16 -0500 Subject: [PATCH 042/393] Is this the last one CodeRabbit??? --- generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc index bd23087b24..242769aa07 100644 --- a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc +++ b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc @@ -77,7 +77,7 @@ int HepMCParticleTrigger::process_event(PHCompositeNode* topNode) return Fun4AllReturnCodes::ABORTEVENT; } } - bool good_event; + bool good_event {false}; PHHepMCGenEventMap* phg = findNode::getClass(topNode, "PHHepMCGenEventMap"); if (!phg) { From 3d0a2e419b572423830dc759d8401b54a1e7e053 Mon Sep 17 00:00:00 2001 From: silas-gross Date: Sat, 10 Jan 2026 05:15:06 -0500 Subject: [PATCH 043/393] fixed pdgid lookup issue --- generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc index 242769aa07..00620e8378 100644 --- a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc +++ b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc @@ -262,7 +262,7 @@ std::vector HepMCParticleTrigger::getParticles(HepMC::GenEvent* e1) float pz = p.pz(); float p_M = std::sqrt(std::pow(px, 2) + std::pow(py, 2) + std::pow(pz, 2)); float pt = std::sqrt(std::pow(px, 2) + std::pow(py, 2)); - int pid = (*iter)->pdg_id(); + int pid = std::abs((*iter)->pdg_id()); double eta = p.eta(); if((_doEtaHighCut || _doBothEtaCut ) && eta > _theEtaHigh) continue; if((_doEtaLowCut || _doBothEtaCut ) && eta < _theEtaLow) continue; From 5628bd2ead56b013c7747ed54bac89cabdbf7601 Mon Sep 17 00:00:00 2001 From: Daniel J Lis Date: Sat, 10 Jan 2026 11:50:00 -0500 Subject: [PATCH 044/393] code rabbit found a bug in the return value --- .../jetbackground/DetermineTowerBackground.cc | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/offline/packages/jetbackground/DetermineTowerBackground.cc b/offline/packages/jetbackground/DetermineTowerBackground.cc index 7f021f4f39..c359b6914c 100644 --- a/offline/packages/jetbackground/DetermineTowerBackground.cc +++ b/offline/packages/jetbackground/DetermineTowerBackground.cc @@ -62,7 +62,7 @@ int DetermineTowerBackground::InitRun(PHCompositeNode *topNode) { std::cout << "Loading the average calo v2" << std::endl; } - if (!LoadCalibrations()) + if (LoadCalibrations()) { std::cout << "Load calibrations failed." << std::endl; return Fun4AllReturnCodes::ABORTRUN; @@ -78,25 +78,20 @@ int DetermineTowerBackground::LoadCalibrations() CDBTTree *cdbtree_calo_v2 = nullptr; - std::string calibdir; + std::string calibdir = CDBInterface::instance()->getUrl(m_calibName); if (m_overwrite_average_calo_v2) { calibdir = m_overwrite_average_calo_v2_path; } - else - { - calibdir = CDBInterface::instance()->getUrl(m_calibName); - } if (calibdir.empty()) { - std::cout << "Could not find and load histograms for EMCAL LUTs! defaulting to the identity table!" << std::endl; + std::cout << "Could not find filename for calo average v2, exiting" << std::endl; exit(-1); } - else - { - cdbtree_calo_v2 = new CDBTTree(calibdir); - } + + cdbtree_calo_v2 = new CDBTTree(calibdir); + cdbtree_calo_v2->LoadCalibrations(); From 62c7a10ac75901e77b8f97c2186ddc74c8191233 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Sat, 10 Jan 2026 16:52:22 -0500 Subject: [PATCH 045/393] add hook to run shell script before opening an input file --- offline/framework/fun4all/InputFileHandler.cc | 11 +++++++++++ offline/framework/fun4all/InputFileHandler.h | 7 +++++++ 2 files changed, 18 insertions(+) diff --git a/offline/framework/fun4all/InputFileHandler.cc b/offline/framework/fun4all/InputFileHandler.cc index 8939b67568..0e0333f4a6 100644 --- a/offline/framework/fun4all/InputFileHandler.cc +++ b/offline/framework/fun4all/InputFileHandler.cc @@ -89,6 +89,17 @@ int InputFileHandler::OpenNextFile() { std::cout << PHWHERE << " opening next file: " << *iter << std::endl; } + if (!GetOpeningScript().empty()) + { + std::vector stringvec; + stringvec.push_back(*iter); + if (! m_FileName.empty()) + { + stringvec.push_back(m_FileName); + } + RunBeforeOpening(stringvec); + } + std::cout << "closing " << m_FileName << ", opening " << *iter << std::endl; if (fileopen(*iter)) { std::cout << PHWHERE << " could not open file: " << *iter << std::endl; diff --git a/offline/framework/fun4all/InputFileHandler.h b/offline/framework/fun4all/InputFileHandler.h index 823ae33b38..646c42b055 100644 --- a/offline/framework/fun4all/InputFileHandler.h +++ b/offline/framework/fun4all/InputFileHandler.h @@ -32,12 +32,19 @@ class InputFileHandler std::pair::const_iterator, std::list::const_iterator> FileOpenListBeginEnd() { return std::make_pair(m_FileListOpened.begin(), m_FileListOpened.end()); } const std::list &GetFileList() const { return m_FileListCopy; } const std::list &GetFileOpenedList() const { return m_FileListOpened; } + void SetOpeningScript(const std::string &script) {m_RunBeforeOpeningScript = script;} + const std::string &GetOpeningScript() const {return m_RunBeforeOpeningScript;} + void SetOpeningScriptArgs(const std::string &args) {m_OpeningArgs = args;} + const std::string &GetOpeningScriptArgs() const {return m_OpeningArgs;} + void RunBeforeOpening(const std::vector &stringvec); private: int m_IsOpen{0}; int m_Repeat{0}; uint64_t m_Verbosity{0}; std::string m_FileName; + std::string m_RunBeforeOpeningScript; + std::string m_OpeningArgs; std::list m_FileList; std::list m_FileListCopy; std::list m_FileListOpened; // all files which were opened during running From 5d5a980f6c6c53c795e3921a53450ac6eaed5189 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Sat, 10 Jan 2026 17:29:25 -0500 Subject: [PATCH 046/393] do not save cdb files if they are empty (do not exist) --- offline/framework/ffamodules/CDBInterface.cc | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/offline/framework/ffamodules/CDBInterface.cc b/offline/framework/ffamodules/CDBInterface.cc index 2b4feef203..2a0b3e1b3c 100644 --- a/offline/framework/ffamodules/CDBInterface.cc +++ b/offline/framework/ffamodules/CDBInterface.cc @@ -185,11 +185,14 @@ std::string CDBInterface::getUrl(const std::string &domain, const std::string &f std::cout << "... reply: " << return_url << std::endl; } } - auto pret = m_UrlVector.insert(make_tuple(domain_noconst, return_url, timestamp)); - if (!pret.second && Verbosity() > 1) + if (! return_url.empty()) { - std::cout << PHWHERE << "not adding again " << domain_noconst << ", url: " << return_url - << ", time stamp: " << timestamp << std::endl; + auto pret = m_UrlVector.insert(make_tuple(domain_noconst, return_url, timestamp)); + if (!pret.second && Verbosity() > 1) + { + std::cout << PHWHERE << "not adding again " << domain_noconst << ", url: " << return_url + << ", time stamp: " << timestamp << std::endl; + } } return return_url; } From fd444863e9a16fa6e644291f04fb53028990ee8d Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Sat, 10 Jan 2026 17:29:38 -0500 Subject: [PATCH 047/393] cleanup, modernize --- offline/framework/ffamodules/CDBInterface.h | 1 - offline/framework/ffamodules/FlagHandler.h | 4 +--- offline/framework/ffamodules/HeadReco.h | 4 +--- offline/framework/ffamodules/SyncReco.h | 6 ++---- offline/framework/ffamodules/Timing.cc | 2 -- offline/framework/ffamodules/Timing.h | 8 +++----- 6 files changed, 7 insertions(+), 18 deletions(-) diff --git a/offline/framework/ffamodules/CDBInterface.h b/offline/framework/ffamodules/CDBInterface.h index c88fae9dee..4132b35a34 100644 --- a/offline/framework/ffamodules/CDBInterface.h +++ b/offline/framework/ffamodules/CDBInterface.h @@ -10,7 +10,6 @@ #include #include // for tuple -class PHCompositeNode; class SphenixClient; class CDBInterface : public SubsysReco diff --git a/offline/framework/ffamodules/FlagHandler.h b/offline/framework/ffamodules/FlagHandler.h index f5cc06bcdb..fd7e40cca3 100644 --- a/offline/framework/ffamodules/FlagHandler.h +++ b/offline/framework/ffamodules/FlagHandler.h @@ -7,14 +7,12 @@ #include -class PHCompositeNode; - class FlagHandler : public SubsysReco { public: FlagHandler(const std::string &name = "FlagHandler"); - ~FlagHandler() override {} + ~FlagHandler() override = default; /** Create the Flag Node if it does not exist, if it exists, read back flags and copy them into recoConsts diff --git a/offline/framework/ffamodules/HeadReco.h b/offline/framework/ffamodules/HeadReco.h index ca2f6cf34e..53fbc3c6c3 100644 --- a/offline/framework/ffamodules/HeadReco.h +++ b/offline/framework/ffamodules/HeadReco.h @@ -7,13 +7,11 @@ #include // for string -class PHCompositeNode; - class HeadReco : public SubsysReco { public: HeadReco(const std::string &name = "HeadReco"); - ~HeadReco() override {} + ~HeadReco() override = default; int Init(PHCompositeNode *topNode) override; int InitRun(PHCompositeNode *topNode) override; int process_event(PHCompositeNode *topNode) override; diff --git a/offline/framework/ffamodules/SyncReco.h b/offline/framework/ffamodules/SyncReco.h index 0a490302a0..73d0954593 100644 --- a/offline/framework/ffamodules/SyncReco.h +++ b/offline/framework/ffamodules/SyncReco.h @@ -5,13 +5,11 @@ #include -class PHCompositeNode; - class SyncReco : public SubsysReco { public: SyncReco(const std::string &name = "SYNC"); - ~SyncReco() override {} + ~SyncReco() override = default; int Init(PHCompositeNode *topNode) override; int InitRun(PHCompositeNode *topNode) override; @@ -24,7 +22,7 @@ class SyncReco : public SubsysReco // just if we need to override the segment for e.g. embedding // where we want to reuse hijing files which normally set // the segment number - int forced_segment = -1; + int forced_segment {-1}; }; #endif /* FFAMODULES_SYNCRECO_H */ diff --git a/offline/framework/ffamodules/Timing.cc b/offline/framework/ffamodules/Timing.cc index f662ba1b33..16210e4f73 100644 --- a/offline/framework/ffamodules/Timing.cc +++ b/offline/framework/ffamodules/Timing.cc @@ -3,8 +3,6 @@ #include #include // for SubsysReco -#include - #include Timing::Timing(const std::string &name) diff --git a/offline/framework/ffamodules/Timing.h b/offline/framework/ffamodules/Timing.h index 01b95638e0..a9a5ccd39d 100644 --- a/offline/framework/ffamodules/Timing.h +++ b/offline/framework/ffamodules/Timing.h @@ -8,15 +8,13 @@ #include // for string #include -class PHCompositeNode; - class Timing : public SubsysReco { public: Timing(const std::string &name = "Timing"); - ~Timing() override {} - int InitRun(PHCompositeNode *topNode) override; - int process_event(PHCompositeNode *topNode) override; + ~Timing() override = default; + int InitRun(PHCompositeNode * /*topNode*/) override; + int process_event(PHCompositeNode * /*topNode*/) override; void SetCallCounter(unsigned int i) { calls = i; } private: From 51336ae67e987750787913f562142fd6352f54b7 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Sat, 10 Jan 2026 18:57:49 -0500 Subject: [PATCH 048/393] fix clang-tidy for HepMCTrigger --- .../HepMCTrigger/HepMCParticleTrigger.cc | 384 ++++++++++-------- .../HepMCTrigger/HepMCParticleTrigger.h | 48 +-- 2 files changed, 229 insertions(+), 203 deletions(-) diff --git a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc index 00620e8378..e60473bdef 100644 --- a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc +++ b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc @@ -14,9 +14,9 @@ #include #include +#include #include #include -#include //____________________________________________________________________________.. // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) HepMCParticleTrigger::HepMCParticleTrigger(float trigger_thresh, int n_incom, bool up_lim, const std::string& name) @@ -24,45 +24,12 @@ HepMCParticleTrigger::HepMCParticleTrigger(float trigger_thresh, int n_incom, bo , threshold(trigger_thresh) , goal_event_number(n_incom) , set_event_limit(up_lim) - , _theEtaHigh(-999.9) - , _theEtaLow(-999.9) - , _thePtHigh(999.9) - , _thePtLow(-999.9) - , _thePHigh(999.9) - , _thePLow(-999.9) - , _thePzHigh(999.9) - , _thePzLow(-999.9) - , - - _doEtaHighCut(false) - , _doEtaLowCut(false) - , _doBothEtaCut(false) - , - - _doAbsEtaHighCut(false) - , _doAbsEtaLowCut(false) - , _doBothAbsEtaCut(false) - , - - _doPtHighCut(false) - , _doPtLowCut(false) - , _doBothPtCut(false) - , - - _doPHighCut(false) - , _doPLowCut(false) - , _doBothPCut(false) - , - - _doPzHighCut(false) - , _doPzLowCut(false) - , _doBothPzCut(false) { - if(threshold != 0 ) - { - _doPtLowCut=true; - _thePtLow=threshold; - } + if (threshold != 0) + { + _doPtLowCut = true; + _thePtLow = threshold; + } } //____________________________________________________________________________.. @@ -77,7 +44,7 @@ int HepMCParticleTrigger::process_event(PHCompositeNode* topNode) return Fun4AllReturnCodes::ABORTEVENT; } } - bool good_event {false}; + bool good_event{false}; PHHepMCGenEventMap* phg = findNode::getClass(topNode, "PHHepMCGenEventMap"); if (!phg) { @@ -101,137 +68,170 @@ int HepMCParticleTrigger::process_event(PHCompositeNode* topNode) return Fun4AllReturnCodes::ABORTEVENT; } } - if (good_event) - { - n_good++; - } + if (good_event) + { + n_good++; + } return Fun4AllReturnCodes::EVENT_OK; } void HepMCParticleTrigger::AddParticle(int particlePid) { - _theParticles.push_back(particlePid); - return; + _theParticles.push_back(particlePid); + return; } -void HepMCParticleTrigger::AddParticles(std::vector particles) +void HepMCParticleTrigger::AddParticles(const std::vector& particles) { - for(auto p:particles) _theParticles.push_back(p); - return; + for (auto p : particles) + { + _theParticles.push_back(p); + } + return; } -void HepMCParticleTrigger::SetPtHigh(double pt) +void HepMCParticleTrigger::SetPtHigh(double pt) { - _thePtHigh=pt; - _doPtHighCut=true; - if(_doPtLowCut) _doBothPtCut=true; - return; + _thePtHigh = pt; + _doPtHighCut = true; + if (_doPtLowCut) + { + _doBothPtCut = true; + } + return; } -void HepMCParticleTrigger::SetPtLow(double pt) +void HepMCParticleTrigger::SetPtLow(double pt) { - _thePtLow=pt; - _doPtLowCut=true; - if(_doPtHighCut) _doBothPtCut=true; - return; + _thePtLow = pt; + _doPtLowCut = true; + if (_doPtHighCut) + { + _doBothPtCut = true; + } + return; } -void HepMCParticleTrigger::SetPtHighLow(double ptHigh, double ptLow) +void HepMCParticleTrigger::SetPtHighLow(double ptHigh, double ptLow) { - _thePtHigh=ptHigh; - _doPtHighCut=true; - _thePtLow=ptLow; - _doPtLowCut=true; - _doBothPtCut=true; - return; + _thePtHigh = ptHigh; + _doPtHighCut = true; + _thePtLow = ptLow; + _doPtLowCut = true; + _doBothPtCut = true; + return; } -void HepMCParticleTrigger::SetPHigh(double pt) +void HepMCParticleTrigger::SetPHigh(double pt) { - _thePHigh=pt; - _doPHighCut=true; - if(_doPLowCut) _doBothPCut=true; - return; + _thePHigh = pt; + _doPHighCut = true; + if (_doPLowCut) + { + _doBothPCut = true; + } + return; } -void HepMCParticleTrigger::SetPLow(double pt) +void HepMCParticleTrigger::SetPLow(double pt) { - _thePLow=pt; - _doPLowCut=true; - if(_doPHighCut) _doBothPCut=true; - return; + _thePLow = pt; + _doPLowCut = true; + if (_doPHighCut) + { + _doBothPCut = true; + } + return; } -void HepMCParticleTrigger::SetPHighLow(double ptHigh, double ptLow) +void HepMCParticleTrigger::SetPHighLow(double ptHigh, double ptLow) { - _thePHigh=ptHigh; - _doPHighCut=true; - _thePLow=ptLow; - _doPLowCut=true; - _doBothPCut=true; - return; + _thePHigh = ptHigh; + _doPHighCut = true; + _thePLow = ptLow; + _doPLowCut = true; + _doBothPCut = true; + return; } -void HepMCParticleTrigger::SetPzHigh(double pt) +void HepMCParticleTrigger::SetPzHigh(double pt) { - _thePzHigh=pt; - _doPzHighCut=true; - if(_doPzLowCut) _doBothPzCut=true; - return; + _thePzHigh = pt; + _doPzHighCut = true; + if (_doPzLowCut) + { + _doBothPzCut = true; + } + return; } -void HepMCParticleTrigger::SetPzLow(double pt) +void HepMCParticleTrigger::SetPzLow(double pt) { - _thePzLow=pt; - _doPzLowCut=true; - if(_doPzHighCut) _doBothPzCut=true; - return; + _thePzLow = pt; + _doPzLowCut = true; + if (_doPzHighCut) + { + _doBothPzCut = true; + } + return; } -void HepMCParticleTrigger::SetPzHighLow(double ptHigh, double ptLow) +void HepMCParticleTrigger::SetPzHighLow(double ptHigh, double ptLow) { - _thePzHigh=ptHigh; - _doPzHighCut=true; - _thePzLow=ptLow; - _doPzLowCut=true; - _doBothPzCut=true; - return; + _thePzHigh = ptHigh; + _doPzHighCut = true; + _thePzLow = ptLow; + _doPzLowCut = true; + _doBothPzCut = true; + return; } -void HepMCParticleTrigger::SetEtaHigh(double pt) +void HepMCParticleTrigger::SetEtaHigh(double pt) { - _theEtaHigh=pt; - _doEtaHighCut=true; - if(_doEtaLowCut) _doBothEtaCut=true; - return; + _theEtaHigh = pt; + _doEtaHighCut = true; + if (_doEtaLowCut) + { + _doBothEtaCut = true; + } + return; } -void HepMCParticleTrigger::SetEtaLow(double pt) +void HepMCParticleTrigger::SetEtaLow(double pt) { - _theEtaLow=pt; - _doEtaLowCut=true; - if(_doEtaHighCut) _doBothEtaCut=true; - return; + _theEtaLow = pt; + _doEtaLowCut = true; + if (_doEtaHighCut) + { + _doBothEtaCut = true; + } + return; } -void HepMCParticleTrigger::SetEtaHighLow(double ptHigh, double ptLow) +void HepMCParticleTrigger::SetEtaHighLow(double ptHigh, double ptLow) { - _theEtaHigh=ptHigh; - _doEtaHighCut=true; - _theEtaLow=ptLow; - _doEtaLowCut=true; - _doBothEtaCut=true; - return; + _theEtaHigh = ptHigh; + _doEtaHighCut = true; + _theEtaLow = ptLow; + _doEtaLowCut = true; + _doBothEtaCut = true; + return; } -void HepMCParticleTrigger::SetAbsEtaHigh(double pt) +void HepMCParticleTrigger::SetAbsEtaHigh(double pt) { - _theEtaHigh=pt; - _doAbsEtaHighCut=true; - if(_doAbsEtaLowCut) _doBothAbsEtaCut=true; - return; + _theEtaHigh = pt; + _doAbsEtaHighCut = true; + if (_doAbsEtaLowCut) + { + _doBothAbsEtaCut = true; + } + return; } -void HepMCParticleTrigger::SetAbsEtaLow(double pt) +void HepMCParticleTrigger::SetAbsEtaLow(double pt) { - _theEtaLow=pt; - _doAbsEtaLowCut=true; - if(_doAbsEtaHighCut) _doBothAbsEtaCut=true; - return; + _theEtaLow = pt; + _doAbsEtaLowCut = true; + if (_doAbsEtaHighCut) + { + _doBothAbsEtaCut = true; + } + return; } -void HepMCParticleTrigger::SetAbsEtaHighLow(double ptHigh, double ptLow) +void HepMCParticleTrigger::SetAbsEtaHighLow(double ptHigh, double ptLow) { - _theEtaHigh=ptHigh; - _doAbsEtaHighCut=true; - _theEtaLow=ptLow; - _doAbsEtaLowCut=true; - _doBothAbsEtaCut=true; - return; + _theEtaHigh = ptHigh; + _doAbsEtaHighCut = true; + _theEtaLow = ptLow; + _doAbsEtaLowCut = true; + _doBothAbsEtaCut = true; + return; } bool HepMCParticleTrigger::isGoodEvent(HepMC::GenEvent* e1) { @@ -241,53 +241,97 @@ bool HepMCParticleTrigger::isGoodEvent(HepMC::GenEvent* e1) return true; }*/ std::vector n_trigger_particles = getParticles(e1); - for(auto ntp:n_trigger_particles) + for (auto ntp : n_trigger_particles) { - if(ntp <=0 ) return false; //make sure all particles have at least 1 + if (ntp <= 0) + { + return false; // make sure all particles have at least 1 + } } return true; } std::vector HepMCParticleTrigger::getParticles(HepMC::GenEvent* e1) -{ - std::vector n_trigger {}; - std::map particle_types; - for (HepMC::GenEvent::particle_const_iterator iter = e1->particles_begin(); iter != e1->particles_end(); ++iter) +{ + std::vector n_trigger{}; + std::map particle_types; + for (HepMC::GenEvent::particle_const_iterator iter = e1->particles_begin(); iter != e1->particles_end(); ++iter) { - if (m_doStableParticleOnly && ((*iter)->end_vertex() || (*iter)->status() != 1)) continue; - else{ - auto p = (*iter)->momentum(); - float px = p.px(); - float py = p.py(); - float pz = p.pz(); - float p_M = std::sqrt(std::pow(px, 2) + std::pow(py, 2) + std::pow(pz, 2)); - float pt = std::sqrt(std::pow(px, 2) + std::pow(py, 2)); - int pid = std::abs((*iter)->pdg_id()); - double eta = p.eta(); - if((_doEtaHighCut || _doBothEtaCut ) && eta > _theEtaHigh) continue; - if((_doEtaLowCut || _doBothEtaCut ) && eta < _theEtaLow) continue; - if((_doAbsEtaHighCut || _doBothAbsEtaCut ) && std::abs(eta) > _theEtaHigh) continue; - if((_doAbsEtaLowCut || _doBothAbsEtaCut ) && std::abs(eta) < _theEtaLow) continue; - if((_doPtHighCut || _doBothPtCut ) && pt > _thePtHigh) continue; - if((_doPtLowCut || _doBothPtCut ) && pt < _thePtLow) continue; - if((_doPHighCut || _doBothPCut ) && p_M > _thePHigh) continue; - if((_doPLowCut || _doBothPCut ) && p_M < _thePLow) continue; - if((_doPzHighCut || _doBothPzCut ) && pz > _thePzHigh) continue; - if((_doPzLowCut || _doBothPzCut ) && pz < _thePzLow) continue; - if(particle_types.find(pid) != particle_types.end()) particle_types[pid]++; - else particle_types[pid]=1; - } + if (m_doStableParticleOnly && ((*iter)->end_vertex() || (*iter)->status() != 1)) + { + continue; + } + auto p = (*iter)->momentum(); + float px = p.px(); + float py = p.py(); + float pz = p.pz(); + float p_M = std::sqrt(std::pow(px, 2) + std::pow(py, 2) + std::pow(pz, 2)); + float pt = std::sqrt(std::pow(px, 2) + std::pow(py, 2)); + int pid = std::abs((*iter)->pdg_id()); + double eta = p.eta(); + if ((_doEtaHighCut || _doBothEtaCut) && eta > _theEtaHigh) + { + continue; + } + if ((_doEtaLowCut || _doBothEtaCut) && eta < _theEtaLow) + { + continue; + } + if ((_doAbsEtaHighCut || _doBothAbsEtaCut) && std::abs(eta) > _theEtaHigh) + { + continue; + } + if ((_doAbsEtaLowCut || _doBothAbsEtaCut) && std::abs(eta) < _theEtaLow) + { + continue; + } + if ((_doPtHighCut || _doBothPtCut) && pt > _thePtHigh) + { + continue; + } + if ((_doPtLowCut || _doBothPtCut) && pt < _thePtLow) + { + continue; + } + if ((_doPHighCut || _doBothPCut) && p_M > _thePHigh) + { + continue; + } + if ((_doPLowCut || _doBothPCut) && p_M < _thePLow) + { + continue; + } + if ((_doPzHighCut || _doBothPzCut) && pz > _thePzHigh) + { + continue; + } + if ((_doPzLowCut || _doBothPzCut) && pz < _thePzLow) + { + continue; + } + if (particle_types.contains(pid)) + { + particle_types[pid]++; + } + else + { + particle_types[pid] = 1; + } } - for(auto p:_theParticles) + n_trigger.reserve(_theParticles.size()); + for (auto p : _theParticles) { - n_trigger.push_back(particleAboveThreshold(particle_types, p)); //make sure we have at least one of each required particle - } + n_trigger.push_back(particleAboveThreshold(particle_types, p)); // make sure we have at least one of each required particle + } return n_trigger; } -int HepMCParticleTrigger::particleAboveThreshold(const std::map& n_particles, int trigger_particle ) +int HepMCParticleTrigger::particleAboveThreshold(const std::map& n_particles, int trigger_particle) { - // search through for the number of identified trigger particles passing cuts + // search through for the number of identified trigger particles passing cuts auto it = n_particles.find(std::abs(trigger_particle)); - if( it!= n_particles.end()) return it->second; - else return 0; + if (it != n_particles.end()) + { + return it->second; + } + return 0; } diff --git a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h index a0124f5292..33e9a1316f 100644 --- a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h +++ b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h @@ -7,10 +7,10 @@ #include +#include +#include #include #include -#include -#include class PHCompositeNode; namespace HepMC @@ -25,38 +25,19 @@ class HepMCParticleTrigger : public SubsysReco ~HepMCParticleTrigger() override = default; - /** Called during initialization. - Typically this is where you can book histograms, and e.g. - register them to Fun4AllServer (so they can be output to file - using Fun4AllServer::dumpHistos() method). - */ - - /** Called for first event when run number is known. - Typically this is where you may want to fetch data from - database, because you know the run number. A place - to book histograms which have to know the run number. - */ - /** Called for each event. This is where you do the real work. */ int process_event(PHCompositeNode* topNode) override; - /// Clean up internals after each event. - - /// Called at the end of each run. - - /// Called at the end of all processing. - - /// Reset - void AddParticles(std::vector); + void AddParticles(const std::vector&); void AddParticle(int); -/* void AddParents(const std::string &parents); - void AddParents(int parent); - void AddParents(std::vector parents); - void AddParentspID(std::vector parents); -*/ + /* void AddParents(const std::string &parents); + void AddParents(int parent); + void AddParents(std::vector parents); + void AddParentspID(std::vector parents); + */ void SetPtHigh(double); void SetPtLow(double); void SetPtHighLow(double, double); @@ -64,11 +45,11 @@ class HepMCParticleTrigger : public SubsysReco void SetPHigh(double); void SetPLow(double); void SetPHighLow(double, double); - + void SetEtaHigh(double); void SetEtaLow(double); void SetEtaHighLow(double, double); - + void SetAbsEtaHigh(double); void SetAbsEtaLow(double); void SetAbsEtaHighLow(double, double); @@ -76,15 +57,16 @@ class HepMCParticleTrigger : public SubsysReco void SetPzHigh(double); void SetPzLow(double); void SetPzHighLow(double, double); - + void SetStableParticleOnly(bool b) { m_doStableParticleOnly = b; } + private: bool isGoodEvent(HepMC::GenEvent* e1); std::vector getParticles(HepMC::GenEvent* e1); int particleAboveThreshold(const std::map& n_particles, int particle); -// std::vector _theParentsi {}; - std::vector _theParticles {}; - bool m_doStableParticleOnly {true}; + // std::vector _theParentsi {}; + std::vector _theParticles{}; + bool m_doStableParticleOnly{true}; float threshold{0.}; int goal_event_number{1000}; int n_evts{0}; From b0df38c7862f4cc32eb8299d3bbbc3021e54a4c9 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Sat, 10 Jan 2026 21:37:25 -0500 Subject: [PATCH 049/393] fix typo in initialiation --- generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h index 33e9a1316f..f0f9f78e3d 100644 --- a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h +++ b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h @@ -73,7 +73,7 @@ class HepMCParticleTrigger : public SubsysReco int n_good{0}; bool set_event_limit{false}; - float _theEtaHigh{-999.9}; + float _theEtaHigh{999.9}; float _theEtaLow{-999.9}; float _thePtHigh{999.9}; float _thePtLow{-999.9}; From 11cb711723dcd5aef7c01433ac1fccc3955e47bc Mon Sep 17 00:00:00 2001 From: mchiu-bnl Date: Mon, 12 Jan 2026 15:10:44 -0500 Subject: [PATCH 050/393] fixed crash when calopackets are empty --- offline/packages/mbd/MbdEvent.cc | 42 ++++++++++++++++++++++++++++---- offline/packages/mbd/MbdReco.cc | 7 +++--- offline/packages/mbd/MbdReco.h | 2 ++ offline/packages/mbd/MbdSig.h | 2 ++ 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/offline/packages/mbd/MbdEvent.cc b/offline/packages/mbd/MbdEvent.cc index d8c72b4395..9b68641cbd 100644 --- a/offline/packages/mbd/MbdEvent.cc +++ b/offline/packages/mbd/MbdEvent.cc @@ -484,9 +484,17 @@ int MbdEvent::SetRawData(std::array< CaloPacket *,2> &dstp, MbdRawContainer *bbc } _mbdsig[feech].SetNSamples( _nsamples ); - _mbdsig[feech].SetXY(m_samp[feech], m_adc[feech]); - + + if ( _nsamples > 0 && _nsamples <= 30 ) + { + _mbdsig[feech].SetXY(m_samp[feech], m_adc[feech]); + } /* + else + { + std::cout << PHWHERE << " empty feech " << feech << std::endl; + } + std::cout << "feech " << feech << std::endl; _mbdsig[feech].Print(); */ @@ -548,6 +556,7 @@ int MbdEvent::SetRawData(Event *event, MbdRawContainer *bbcraws, MbdPmtContainer // int flag_err = 0; Packet *p[2]{nullptr}; + int tot_nsamples{0}; for (int ipkt = 0; ipkt < 2; ipkt++) { int pktid = 1001 + ipkt; // packet id @@ -565,6 +574,7 @@ int MbdEvent::SetRawData(Event *event, MbdRawContainer *bbcraws, MbdPmtContainer if (p[ipkt]) { _nsamples = p[ipkt]->iValue(0, "SAMPLES"); + tot_nsamples += _nsamples; { static int counter = 0; if ( counter<1 ) @@ -618,6 +628,12 @@ int MbdEvent::SetRawData(Event *event, MbdRawContainer *bbcraws, MbdPmtContainer } } + // If packets are missing, stop processing + if ( tot_nsamples == 0 ) + { + return -1002; + } + // Fill MbdRawContainer int status = ProcessPackets(bbcraws); if ( _fitsonly ) @@ -637,7 +653,7 @@ int MbdEvent::ProcessPackets(MbdRawContainer *bbcraws) // Do a quick sanity check that all fem counters agree if (m_xmitclocks[0] != m_xmitclocks[1]) { - std::cout << __FILE__ << ":" << __LINE__ << " ERROR, xmitclocks don't agree" << std::endl; + std::cout << __FILE__ << ":" << __LINE__ << " ERROR, xmitclocks don't agree, evt " << m_evt << std::endl; } /* // format changed in run2024, need to update check @@ -673,6 +689,11 @@ int MbdEvent::ProcessPackets(MbdRawContainer *bbcraws) int pmtch = _mbdgeom->get_pmt(ifeech); int type = _mbdgeom->get_type(ifeech); // 0 = T-channel, 1 = Q-channel + if ( _mbdsig[ifeech].GetNSamples()==0 ) + { + continue; + } + // time channel if (type == 0) { @@ -739,6 +760,11 @@ int MbdEvent::ProcessRawContainer(MbdRawContainer *bbcraws, MbdPmtContainer *bbc int pmtch = _mbdgeom->get_pmt(ifeech); int type = _mbdgeom->get_type(ifeech); // 0 = T-channel, 1 = Q-channel + if ( _mbdsig[ifeech].GetNSamples()==0 ) + { + continue; + } + // time channel if (type == 0) { @@ -854,8 +880,14 @@ int MbdEvent::ProcessRawContainer(MbdRawContainer *bbcraws, MbdPmtContainer *bbc */ TGraphErrors *gsubpulse = _mbdsig[ifeech].GetGraph(); - Double_t *y = gsubpulse->GetY(); - h2_trange->Fill( y[samp_max], pmtch ); // fill ped-subtracted tdc + if ( gsubpulse ) + { + Double_t *y = gsubpulse->GetY(); + if ( y ) + { + h2_trange->Fill( y[samp_max], pmtch ); // fill ped-subtracted tdc + } + } } } diff --git a/offline/packages/mbd/MbdReco.cc b/offline/packages/mbd/MbdReco.cc index c19ed37ba9..004e191e78 100644 --- a/offline/packages/mbd/MbdReco.cc +++ b/offline/packages/mbd/MbdReco.cc @@ -103,7 +103,8 @@ int MbdReco::process_event(PHCompositeNode *topNode) int status = Fun4AllReturnCodes::EVENT_OK; if ( m_evtheader!=nullptr ) { - m_mbdevent->set_EventNumber( m_evtheader->get_EvtSequence() ); + _evtnum = m_evtheader->get_EvtSequence(); + m_mbdevent->set_EventNumber( _evtnum ); } if ( m_event!=nullptr ) @@ -125,7 +126,7 @@ int MbdReco::process_event(PHCompositeNode *topNode) static int counter = 0; if ( counter<3 ) { - std::cout << PHWHERE << " Warning, MBD discarding event " << std::endl; + std::cout << PHWHERE << " Warning, MBD discarding event " << _evtnum << std::endl; counter++; } return Fun4AllReturnCodes::DISCARDEVENT; @@ -135,7 +136,7 @@ int MbdReco::process_event(PHCompositeNode *topNode) static int counter = 0; if ( counter<3 ) { - std::cout << PHWHERE << " Warning, MBD aborting event " << std::endl; + std::cout << PHWHERE << " Warning, MBD aborting event " << _evtnum << std::endl; counter++; } return Fun4AllReturnCodes::ABORTEVENT; diff --git a/offline/packages/mbd/MbdReco.h b/offline/packages/mbd/MbdReco.h index 0dfc7d7cbc..6e00de68f3 100644 --- a/offline/packages/mbd/MbdReco.h +++ b/offline/packages/mbd/MbdReco.h @@ -52,6 +52,8 @@ class MbdReco : public SubsysReco float m_tres = 0.05; std::unique_ptr m_gaussian = nullptr; + int _evtnum{-1}; + std::unique_ptr m_mbdevent{nullptr}; Event *m_event{nullptr}; std::arraym_mbdpacket{nullptr}; diff --git a/offline/packages/mbd/MbdSig.h b/offline/packages/mbd/MbdSig.h index 0b8b420ffa..e933f33392 100644 --- a/offline/packages/mbd/MbdSig.h +++ b/offline/packages/mbd/MbdSig.h @@ -32,6 +32,8 @@ class MbdSig void SetY(const Float_t *y, const int invert = 1); void SetXY(const Float_t *x, const Float_t *y, const int invert = 1); + int GetNSamples() { return _nsamples; } + void SetCalib(MbdCalib *mcal); TH1 *GetHist() { return hpulse; } From 47ab938f88fedef594dd30a2a29ce9522ead5c16 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Mon, 12 Jan 2026 17:02:32 -0500 Subject: [PATCH 051/393] call script before opening --- offline/framework/fun4all/InputFileHandler.cc | 50 +++++++++++++++++-- offline/framework/fun4all/InputFileHandler.h | 13 ++--- 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/offline/framework/fun4all/InputFileHandler.cc b/offline/framework/fun4all/InputFileHandler.cc index 0e0333f4a6..a20a6befe9 100644 --- a/offline/framework/fun4all/InputFileHandler.cc +++ b/offline/framework/fun4all/InputFileHandler.cc @@ -3,10 +3,13 @@ #include +#include + #include #include #include #include +#include int InputFileHandler::AddFile(const std::string &filename) { @@ -93,13 +96,15 @@ int InputFileHandler::OpenNextFile() { std::vector stringvec; stringvec.push_back(*iter); - if (! m_FileName.empty()) + if (!m_FileName.empty()) + { + stringvec.push_back(m_FileName); + } + if (RunBeforeOpening(stringvec)) { - stringvec.push_back(m_FileName); + std::cout << PHWHERE << " RunBeforeOpening() failed" << std::endl; } - RunBeforeOpening(stringvec); } - std::cout << "closing " << m_FileName << ", opening " << *iter << std::endl; if (fileopen(*iter)) { std::cout << PHWHERE << " could not open file: " << *iter << std::endl; @@ -156,3 +161,40 @@ int InputFileHandler::fileopen(const std::string &fname) std::cout << "InputFileHandler::fileopen opening " << fname << std::endl; return 0; } + +int InputFileHandler::RunBeforeOpening(const std::vector &stringvec) +{ + if (m_RunBeforeOpeningScript.empty()) + { + return 0; + } + if (!std::filesystem::exists(m_RunBeforeOpeningScript)) + { + std::cout << PHWHERE << " script " << m_RunBeforeOpeningScript << " not found" + << std::endl; + return -1; + } + if (!((std::filesystem::status(m_RunBeforeOpeningScript).permissions() & std::filesystem::perms::owner_exec) == std::filesystem::perms::owner_exec)) + { + std::cout << PHWHERE << "RunAfterClosing() closing script " + << m_RunBeforeOpeningScript << " is not owner executable" << std::endl; + return -1; + } + std::string fullcmd = m_RunBeforeOpeningScript + " " + m_OpeningArgs; + for (auto iter : stringvec) + { + fullcmd += " " + iter; + } + + if (m_Verbosity > 1) + { + std::cout << PHWHERE << " running " << fullcmd << std::endl; + } + int iret = gSystem->Exec(fullcmd.c_str()); + + if (iret) + { + iret = iret >> 8U; + } + return iret; +} diff --git a/offline/framework/fun4all/InputFileHandler.h b/offline/framework/fun4all/InputFileHandler.h index 646c42b055..49df4aa379 100644 --- a/offline/framework/fun4all/InputFileHandler.h +++ b/offline/framework/fun4all/InputFileHandler.h @@ -4,13 +4,14 @@ #include #include #include +#include class InputFileHandler { public: InputFileHandler() = default; virtual ~InputFileHandler() = default; - virtual int fileopen(const std::string & /*filename*/);// { return 0; } + virtual int fileopen(const std::string & /*filename*/); // { return 0; } virtual int fileclose() { return -1; } virtual int ResetFileList(); @@ -32,11 +33,11 @@ class InputFileHandler std::pair::const_iterator, std::list::const_iterator> FileOpenListBeginEnd() { return std::make_pair(m_FileListOpened.begin(), m_FileListOpened.end()); } const std::list &GetFileList() const { return m_FileListCopy; } const std::list &GetFileOpenedList() const { return m_FileListOpened; } - void SetOpeningScript(const std::string &script) {m_RunBeforeOpeningScript = script;} - const std::string &GetOpeningScript() const {return m_RunBeforeOpeningScript;} - void SetOpeningScriptArgs(const std::string &args) {m_OpeningArgs = args;} - const std::string &GetOpeningScriptArgs() const {return m_OpeningArgs;} - void RunBeforeOpening(const std::vector &stringvec); + void SetOpeningScript(const std::string &script) { m_RunBeforeOpeningScript = script; } + const std::string &GetOpeningScript() const { return m_RunBeforeOpeningScript; } + void SetOpeningScriptArgs(const std::string &args) { m_OpeningArgs = args; } + const std::string &GetOpeningScriptArgs() const { return m_OpeningArgs; } + int RunBeforeOpening(const std::vector &stringvec); private: int m_IsOpen{0}; From 7eb599f293223b5530071e4ba02bfe301e2edbe9 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Mon, 12 Jan 2026 17:17:20 -0500 Subject: [PATCH 052/393] make rabbit happy --- offline/framework/fun4all/InputFileHandler.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/framework/fun4all/InputFileHandler.cc b/offline/framework/fun4all/InputFileHandler.cc index a20a6befe9..4e285f3b5d 100644 --- a/offline/framework/fun4all/InputFileHandler.cc +++ b/offline/framework/fun4all/InputFileHandler.cc @@ -176,7 +176,7 @@ int InputFileHandler::RunBeforeOpening(const std::vector &stringvec } if (!((std::filesystem::status(m_RunBeforeOpeningScript).permissions() & std::filesystem::perms::owner_exec) == std::filesystem::perms::owner_exec)) { - std::cout << PHWHERE << "RunAfterClosing() closing script " + std::cout << PHWHERE << "RunBeforeOpeningScript script " << m_RunBeforeOpeningScript << " is not owner executable" << std::endl; return -1; } From 5d10d3e240bbbbf4720810f486b25202ae9abc38 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Mon, 12 Jan 2026 20:18:02 -0500 Subject: [PATCH 053/393] fix clang-tidy for InputFileHandler --- offline/framework/fun4all/InputFileHandler.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/offline/framework/fun4all/InputFileHandler.cc b/offline/framework/fun4all/InputFileHandler.cc index 4e285f3b5d..0fdc858db8 100644 --- a/offline/framework/fun4all/InputFileHandler.cc +++ b/offline/framework/fun4all/InputFileHandler.cc @@ -181,7 +181,7 @@ int InputFileHandler::RunBeforeOpening(const std::vector &stringvec return -1; } std::string fullcmd = m_RunBeforeOpeningScript + " " + m_OpeningArgs; - for (auto iter : stringvec) + for (const auto& iter : stringvec) { fullcmd += " " + iter; } @@ -190,11 +190,11 @@ int InputFileHandler::RunBeforeOpening(const std::vector &stringvec { std::cout << PHWHERE << " running " << fullcmd << std::endl; } - int iret = gSystem->Exec(fullcmd.c_str()); + unsigned int iret = gSystem->Exec(fullcmd.c_str()); if (iret) { iret = iret >> 8U; } - return iret; + return static_cast (iret); } From f9373cf567102acb861ddebec86acf21f4fe0a65 Mon Sep 17 00:00:00 2001 From: silas-gross Date: Mon, 12 Jan 2026 22:18:10 -0500 Subject: [PATCH 054/393] Fixed issues around the edges of Jet, set better default behavior of Particle. Keeping the Pythia Trigger style for now --- generators/Herwig/HepMCTrigger/HepMCJetTrigger.cc | 3 +++ .../Herwig/HepMCTrigger/HepMCParticleTrigger.cc | 15 +++++++-------- .../Herwig/HepMCTrigger/HepMCParticleTrigger.h | 12 ++++++------ 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/generators/Herwig/HepMCTrigger/HepMCJetTrigger.cc b/generators/Herwig/HepMCTrigger/HepMCJetTrigger.cc index 02ca208f25..b22db801b5 100644 --- a/generators/Herwig/HepMCTrigger/HepMCJetTrigger.cc +++ b/generators/Herwig/HepMCTrigger/HepMCJetTrigger.cc @@ -96,6 +96,8 @@ std::vector HepMCJetTrigger::findAllJets(HepMC::GenEvent* e1 if (!(*iter)->end_vertex() && (*iter)->status() == 1) { auto p = (*iter)->momentum(); + auto pd = std::abs((*iter)->pdg_id()); + if( pd >=12 && pd <=18) continue; //keep jet in the expected behavioro fastjet::PseudoJet pj(p.px(), p.py(), p.pz(), p.e()); pj.set_user_index((*iter)->barcode()); input.push_back(pj); @@ -122,6 +124,7 @@ int HepMCJetTrigger::jetsAboveThreshold(const std::vector& j for (const auto& j : jets) { float const pt = j.pt(); + if(std::abs(j.eta()) > 1.1) continue; if (pt > this->threshold) { n_good_jets++; diff --git a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc index 00620e8378..db5fff40f0 100644 --- a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc +++ b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc @@ -24,19 +24,19 @@ HepMCParticleTrigger::HepMCParticleTrigger(float trigger_thresh, int n_incom, bo , threshold(trigger_thresh) , goal_event_number(n_incom) , set_event_limit(up_lim) - , _theEtaHigh(-999.9) - , _theEtaLow(-999.9) + , _theEtaHigh(1) + , _theEtaLow(-1) , _thePtHigh(999.9) - , _thePtLow(-999.9) + , _thePtLow(0) , _thePHigh(999.9) , _thePLow(-999.9) , _thePzHigh(999.9) , _thePzLow(-999.9) , - _doEtaHighCut(false) - , _doEtaLowCut(false) - , _doBothEtaCut(false) + _doEtaHighCut(true) + , _doEtaLowCut(true) + , _doBothEtaCut(true) , _doAbsEtaHighCut(false) @@ -48,8 +48,7 @@ HepMCParticleTrigger::HepMCParticleTrigger(float trigger_thresh, int n_incom, bo , _doPtLowCut(false) , _doBothPtCut(false) , - - _doPHighCut(false) + _doPHighCut(false) , _doPLowCut(false) , _doBothPCut(false) , diff --git a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h index a0124f5292..054a7958e3 100644 --- a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h +++ b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h @@ -49,7 +49,7 @@ class HepMCParticleTrigger : public SubsysReco /// Called at the end of all processing. /// Reset - void AddParticles(std::vector); + void AddParticles(std::vector); //exclusively take input in the form of a pdg_ids (22 for photon, primary use case) void AddParticle(int); /* void AddParents(const std::string &parents); @@ -91,8 +91,8 @@ class HepMCParticleTrigger : public SubsysReco int n_good{0}; bool set_event_limit{false}; - float _theEtaHigh{-999.9}; - float _theEtaLow{-999.9}; + float _theEtaHigh{1.1}; + float _theEtaLow{-1.1}; float _thePtHigh{999.9}; float _thePtLow{-999.9}; float _thePHigh{999.9}; @@ -100,9 +100,9 @@ class HepMCParticleTrigger : public SubsysReco float _thePzHigh{999.9}; float _thePzLow{-999.9}; - bool _doEtaHighCut{false}; - bool _doEtaLowCut{false}; - bool _doBothEtaCut{false}; + bool _doEtaHighCut{true}; + bool _doEtaLowCut{true}; + bool _doBothEtaCut{true}; bool _doAbsEtaHighCut{false}; bool _doAbsEtaLowCut{false}; From a284e7e6ed03611202bb5747d14bc9b68a4a6470 Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Tue, 13 Jan 2026 15:44:06 -0500 Subject: [PATCH 055/393] sEPD Event Plane Calibration This commit introduces the sEPD Q Vector calibration engine and CDB generation components for the sEPD Event Plane calibration pipeline. It establishes a centralized definition system and implements the physics logic for re-centering, flattening, and database payload generation. Summary: - sEPD_TreeGen.h/cc: Extract event-level and tower-level sEPD data into TTrees and QA histograms. - QVecDefs.h: Establishes a shared namespace for harmonics, centrality bins, and standardized naming conventions for histograms. - QVecCalib.h/cc: Orchestrates the three-pass calibration logic (Re-centering, Flattening, and Validation). - QVecCDB.h/cc: Manages the transformation of calibration moments and bad tower maps into standardized CDB payloads. - GenQVecCalib.cc & GenQVecCDB.cc: Executable drivers for the calibration processing and database commitment stages. --- .../sepd/sepd_eventplanecalib/GenQVecCDB.cc | 43 + .../sepd/sepd_eventplanecalib/GenQVecCalib.cc | 54 + .../sepd/sepd_eventplanecalib/Makefile.am | 68 + .../sepd/sepd_eventplanecalib/QVecCDB.cc | 192 +++ .../sepd/sepd_eventplanecalib/QVecCDB.h | 139 ++ .../sepd/sepd_eventplanecalib/QVecCalib.cc | 1172 +++++++++++++++++ .../sepd/sepd_eventplanecalib/QVecCalib.h | 386 ++++++ .../sepd/sepd_eventplanecalib/QVecDefs.h | 55 + .../sepd/sepd_eventplanecalib/autogen.sh | 8 + .../sepd/sepd_eventplanecalib/configure.ac | 16 + .../sepd/sepd_eventplanecalib/sEPD_TreeGen.cc | 289 ++++ .../sepd/sepd_eventplanecalib/sEPD_TreeGen.h | 177 +++ 12 files changed, 2599 insertions(+) create mode 100644 calibrations/sepd/sepd_eventplanecalib/GenQVecCDB.cc create mode 100644 calibrations/sepd/sepd_eventplanecalib/GenQVecCalib.cc create mode 100644 calibrations/sepd/sepd_eventplanecalib/Makefile.am create mode 100644 calibrations/sepd/sepd_eventplanecalib/QVecCDB.cc create mode 100644 calibrations/sepd/sepd_eventplanecalib/QVecCDB.h create mode 100644 calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc create mode 100644 calibrations/sepd/sepd_eventplanecalib/QVecCalib.h create mode 100644 calibrations/sepd/sepd_eventplanecalib/QVecDefs.h create mode 100644 calibrations/sepd/sepd_eventplanecalib/autogen.sh create mode 100644 calibrations/sepd/sepd_eventplanecalib/configure.ac create mode 100644 calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc create mode 100644 calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.h diff --git a/calibrations/sepd/sepd_eventplanecalib/GenQVecCDB.cc b/calibrations/sepd/sepd_eventplanecalib/GenQVecCDB.cc new file mode 100644 index 0000000000..7118d71b99 --- /dev/null +++ b/calibrations/sepd/sepd_eventplanecalib/GenQVecCDB.cc @@ -0,0 +1,43 @@ +#include "QVecCDB.h" + +#include +#include + +int main(int argc, const char* const argv[]) +{ + const std::vector args(argv, argv + argc); + + if (args.size() < 3 || args.size() > 5) + { + std::cout << "Usage: " << args[0] << " input_file runnumber [output_dir] [cdb_tag]" << std::endl; + return 1; + } + + const std::string &input_file = args[1]; + int runnumber = std::stoi(args[2]); + const std::string output_dir = (args.size() >= 4) ? args[3] : "."; + const std::string cdb_tag = (args.size() >= 5) ? args[4] : "new_newcdbtag_v008"; + + std::cout << std::format("{:#<20}\n", ""); + std::cout << std::format("Analysis Params\n"); + std::cout << std::format("Input File: {}\n", input_file); + std::cout << std::format("Run: {}\n", runnumber); + std::cout << std::format("Output Dir: {}\n", output_dir); + std::cout << std::format("CDB Tag: {}\n", cdb_tag); + std::cout << std::format("{:#<20}\n", ""); + + try + { + QVecCDB analysis(input_file, runnumber, output_dir, cdb_tag); + analysis.run(); + } + catch (const std::exception& e) + { + std::cout << "An exception occurred: " << e.what() << std::endl; + return 1; + } + + std::cout << "======================================" << std::endl; + std::cout << "done" << std::endl; + return 0; +} diff --git a/calibrations/sepd/sepd_eventplanecalib/GenQVecCalib.cc b/calibrations/sepd/sepd_eventplanecalib/GenQVecCalib.cc new file mode 100644 index 0000000000..67ec64fbeb --- /dev/null +++ b/calibrations/sepd/sepd_eventplanecalib/GenQVecCalib.cc @@ -0,0 +1,54 @@ +#include "QVecCalib.h" + +#include + +int main(int argc, const char* const argv[]) +{ + const std::vector args(argv, argv + argc); + + if (args.size() < 4 || args.size() > 7) + { + std::cout << "Usage: " << args[0] << " [pass] [events] [output_directory]" << std::endl; + return 1; // Indicate error + } + + const std::string &input_file = args[1]; + const std::string &input_hist = args[2]; + const std::string &input_Q_calib = args[3]; + const std::string &pass_str = (argc >= 5) ? args[4] : "ComputeRecentering"; // Default to the first pass + long long events = (argc >= 6) ? std::stoll(args[5]) : 0; + std::string output_dir = (argc >= 7) ? args[6] : "."; + + const std::map pass_map = { + {"ComputeRecentering", QVecCalib::Pass::ComputeRecentering}, + {"ApplyRecentering", QVecCalib::Pass::ApplyRecentering}, + {"ApplyFlattening", QVecCalib::Pass::ApplyFlattening} + }; + + QVecCalib::Pass pass = QVecCalib::Pass::ComputeRecentering; + if (pass_map.contains(pass_str)) + { + pass = pass_map.at(pass_str); + } + else + { + std::cout << "Error: Invalid pass specified: " << pass_str << std::endl; + std::cout << "Available passes are: ComputeRecentering, ApplyRecentering, ApplyFlattening" << std::endl; + return 1; + } + + try + { + QVecCalib analysis(input_file, input_hist, input_Q_calib, static_cast(pass), events, output_dir); + analysis.run(); + } + catch (const std::exception& e) + { + std::cout << "An exception occurred: " << e.what() << std::endl; + return 1; + } + + std::cout << "======================================" << std::endl; + std::cout << "done" << std::endl; + return 0; +} diff --git a/calibrations/sepd/sepd_eventplanecalib/Makefile.am b/calibrations/sepd/sepd_eventplanecalib/Makefile.am new file mode 100644 index 0000000000..f1da8a7800 --- /dev/null +++ b/calibrations/sepd/sepd_eventplanecalib/Makefile.am @@ -0,0 +1,68 @@ +AUTOMAKE_OPTIONS = foreign + +bin_PROGRAMS = \ + GenQVecCalib \ + GenQVecCDB + +AM_CPPFLAGS = \ + -I$(includedir) \ + -I$(OFFLINE_MAIN)/include \ + -I$(ROOTSYS)/include + +AM_LDFLAGS = \ + -L$(libdir) \ + -L$(OFFLINE_MAIN)/lib \ + -L$(OFFLINE_MAIN)/lib64 \ + `root-config --libs` + +pkginclude_HEADERS = \ + sEPD_TreeGen.h \ + QVecCalib.h \ + QVecCDB.h \ + QVecDefs.h + +lib_LTLIBRARIES = \ + libsepd_eventplanecalib.la + +libsepd_eventplanecalib_la_SOURCES = \ + sEPD_TreeGen.cc \ + QVecCalib.cc \ + QVecCDB.cc + +libsepd_eventplanecalib_la_LIBADD = \ + -lphool \ + -lSubsysReco \ + -lcentrality_io \ + -lfun4all \ + -lffamodules \ + -lglobalvertex_io \ + -lcalotrigger_io \ + -lcalotrigger \ + -lcdbobjects \ + -lepd_io + +GenQVecCalib_SOURCES = GenQVecCalib.cc +# GenQVecCalib_CXXFLAGS = -fsanitize=address +GenQVecCalib_LDADD = libsepd_eventplanecalib.la + +GenQVecCDB_SOURCES = GenQVecCDB.cc +# GenQVecCDB_CXXFLAGS = -fsanitize=address +GenQVecCDB_LDADD = libsepd_eventplanecalib.la + +BUILT_SOURCES = testexternals.cc + +noinst_PROGRAMS = \ + testexternals + +testexternals_SOURCES = testexternals.cc +testexternals_LDADD = libsepd_eventplanecalib.la + +testexternals.cc: + echo "//*** this is a generated file. Do not commit, do not edit" > $@ + echo "int main()" >> $@ + echo "{" >> $@ + echo " return 0;" >> $@ + echo "}" >> $@ + +clean-local: + rm -f $(BUILT_SOURCES) diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecCDB.cc b/calibrations/sepd/sepd_eventplanecalib/QVecCDB.cc new file mode 100644 index 0000000000..96e18d1ffe --- /dev/null +++ b/calibrations/sepd/sepd_eventplanecalib/QVecCDB.cc @@ -0,0 +1,192 @@ +#include "QVecCDB.h" + +// ==================================================================== +// sPHENIX Includes +// ==================================================================== +#include +#include + +// ==================================================================== +// ROOT Includes +// ==================================================================== +#include + +// ==================================================================== +// Standard C++ Includes +// ==================================================================== +#include +#include +#include +#include +#include + +template +std::unique_ptr QVecCDB::load_and_clone(const std::string& name) { + auto* obj = dynamic_cast(m_tfile->Get(name.c_str())); + if (!obj) + { + throw std::runtime_error(std::format("Could not find histogram '{}' in file '{}'", name, m_tfile->GetName())); + } + return std::unique_ptr(static_cast(obj->Clone())); +} + +QVecShared::CorrectionMoments& QVecCDB::getData(size_t h_idx, size_t cent_bin, QVecShared::Subdetector sub) { + return m_correction_data[h_idx][cent_bin][static_cast(sub)]; +} + +void QVecCDB::load_data() +{ + m_tfile = std::unique_ptr(TFile::Open(m_input_file.c_str())); + + // Check if the file was opened successfully. + if (!m_tfile || m_tfile->IsZombie()) + { + throw std::runtime_error(std::format("Could not open file '{}'", m_input_file)); + } + + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + load_correction_data(h_idx); + } +} + +void QVecCDB::load_correction_data(size_t h_idx) +{ + int n = m_harmonics[h_idx]; + + // Load recentering terms (x, y) + auto pS_x = load_and_clone(QVecShared::get_hist_name("S", "x", n)); + auto pS_y = load_and_clone(QVecShared::get_hist_name("S", "y", n)); + auto pN_x = load_and_clone(QVecShared::get_hist_name("N", "x", n)); + auto pN_y = load_and_clone(QVecShared::get_hist_name("N", "y", n)); + + // Load flattening terms (xx, yy, xy) + auto pS_xx = load_and_clone(QVecShared::get_hist_name("S", "xx", n)); + auto pS_yy = load_and_clone(QVecShared::get_hist_name("S", "yy", n)); + auto pS_xy = load_and_clone(QVecShared::get_hist_name("S", "xy", n)); + auto pN_xx = load_and_clone(QVecShared::get_hist_name("N", "xx", n)); + auto pN_yy = load_and_clone(QVecShared::get_hist_name("N", "yy", n)); + auto pN_xy = load_and_clone(QVecShared::get_hist_name("N", "xy", n)); + + for (size_t cent_bin = 0; cent_bin < m_cent_bins; ++cent_bin) + { + int bin = static_cast(cent_bin) + 1; // ROOT bins start at 1 + + // South + auto& dataS = getData(h_idx, cent_bin, QVecShared::Subdetector::S); + dataS.avg_Q = {pS_x->GetBinContent(bin), pS_y->GetBinContent(bin)}; + dataS.avg_Q_xx = pS_xx->GetBinContent(bin); + dataS.avg_Q_yy = pS_yy->GetBinContent(bin); + dataS.avg_Q_xy = pS_xy->GetBinContent(bin); + + // North + auto& dataN = getData(h_idx, cent_bin, QVecShared::Subdetector::N); + dataN.avg_Q = {pN_x->GetBinContent(bin), pN_y->GetBinContent(bin)}; + dataN.avg_Q_xx = pN_xx->GetBinContent(bin); + dataN.avg_Q_yy = pN_yy->GetBinContent(bin); + dataN.avg_Q_xy = pN_xy->GetBinContent(bin); + } +} + +void QVecCDB::write_cdb() +{ + std::string output_dir = std::format("{}/{}", m_output_dir, m_runnumber); + + if (std::filesystem::create_directories(output_dir)) + { + std::cout << std::format("Success: Directory {} created.\n", output_dir); + } + else + { + std::cout << std::format("Info: Directory {} already exists.\n", output_dir); + } + + write_cdb_EventPlane(output_dir); + write_cdb_BadTowers(output_dir); +} + +void QVecCDB::write_cdb_BadTowers(const std::string &output_dir) +{ + std::string payload = "SEPD_HotMap"; + std::string fieldname_status = "status"; + std::string fieldname_sigma = "SEPD_sigma"; + std::string output_file = std::format("{}/{}-{}-{}.root", output_dir, payload, m_cdb_tag, m_runnumber); + + std::unique_ptr cdbttree = std::make_unique(output_file); + + auto h_sEPD_Bad_Channels = load_and_clone("h_sEPD_Bad_Channels"); + + for (int channel = 0; channel < h_sEPD_Bad_Channels->GetNbinsX(); ++channel) + { + unsigned int key = TowerInfoDefs::encode_epd(channel); + int status = h_sEPD_Bad_Channels->GetBinContent(channel+1); + + float sigma = 0; + + // Hot + if (status == 2) + { + sigma = SIGMA_HOT; + } + + // Cold + else if (status == 3) + { + sigma = SIGMA_COLD; + } + + cdbttree->SetIntValue(key, fieldname_status, status); + cdbttree->SetFloatValue(key, fieldname_sigma, sigma); + } + + std::cout << std::format("Saving CDB: {} to {}\n", payload, output_file); + + cdbttree->Commit(); + cdbttree->WriteCDBTTree(); +} + +void QVecCDB::write_cdb_EventPlane(const std::string &output_dir) +{ + std::string payload = "SEPD_EventPlaneCalib"; + std::string output_file = std::format("{}/{}-{}-{}.root", output_dir, payload, m_cdb_tag, m_runnumber); + + std::unique_ptr cdbttree = std::make_unique(output_file); + + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + int n = m_harmonics[h_idx]; + + // Define lambdas to generate field names consistently + auto field = [&](const char* det, const char* var) { + return std::format("Q_{}_{}_{}_avg", det, var, n); + }; + + for (size_t cent_bin = 0; cent_bin < m_cent_bins; ++cent_bin) + { + int key = static_cast(cent_bin); + + // Access data references to clean up the calls + const auto& S = getData(h_idx, cent_bin, QVecShared::Subdetector::S); + const auto& N = getData(h_idx, cent_bin, QVecShared::Subdetector::N); + + // South + cdbttree->SetDoubleValue(key, field("S", "x"), S.avg_Q.x); + cdbttree->SetDoubleValue(key, field("S", "y"), S.avg_Q.y); + cdbttree->SetDoubleValue(key, field("S", "xx"), S.avg_Q_xx); + cdbttree->SetDoubleValue(key, field("S", "yy"), S.avg_Q_yy); + cdbttree->SetDoubleValue(key, field("S", "xy"), S.avg_Q_xy); + + // North + cdbttree->SetDoubleValue(key, field("N", "x"), N.avg_Q.x); + cdbttree->SetDoubleValue(key, field("N", "y"), N.avg_Q.y); + cdbttree->SetDoubleValue(key, field("N", "xx"), N.avg_Q_xx); + cdbttree->SetDoubleValue(key, field("N", "yy"), N.avg_Q_yy); + cdbttree->SetDoubleValue(key, field("N", "xy"), N.avg_Q_xy); + } + } + + std::cout << std::format("Saving CDB: {} to {}\n", payload, output_file); + + cdbttree->Commit(); + cdbttree->WriteCDBTTree(); +} diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecCDB.h b/calibrations/sepd/sepd_eventplanecalib/QVecCDB.h new file mode 100644 index 0000000000..1840b2b52b --- /dev/null +++ b/calibrations/sepd/sepd_eventplanecalib/QVecCDB.h @@ -0,0 +1,139 @@ +#ifndef QVECCDB_H +#define QVECCDB_H + +#include "QVecDefs.h" + +// ==================================================================== +// ROOT Includes +// ==================================================================== +#include + +// ==================================================================== +// Standard C++ Includes +// ==================================================================== +#include +#include + +/** + * @class QVecCDB + * @brief Generates sPHENIX Calibration Database (CDB) payloads for sEPD calibrations. + * + * QVecCDB is responsible for consolidating the correction parameters derived + * during the calibration stage into standardized database formats: + * * - **SEPD_EventPlaneCalib**: Encapsulates re-centering offsets (, ) and + * flattening moments (, , ) indexed by centrality bin. + * - **SEPD_HotMap**: Maps sEPD tower statuses (Dead, Hot, or Cold) to their + * respective channel IDs for use in reconstruction. + * * The class interfaces with the `CDBTTree` object to commit these payloads + * for a specific run number and database tag. + */ +class QVecCDB +{ + public: + // The constructor takes the configuration + QVecCDB(std::string input_file, int runnumber, std::string output_dir, std::string cdb_tag) + : m_input_file(std::move(input_file)) + , m_runnumber(runnumber) + , m_output_dir(std::move(output_dir)) + , m_cdb_tag(std::move(cdb_tag)) + { + } + + void run() + { + load_data(); + write_cdb(); + } + + private: + + static constexpr size_t m_cent_bins = QVecShared::CENT_BINS; + static constexpr auto m_harmonics = QVecShared::HARMONICS; + + static constexpr float SIGMA_HOT = 6.0F; + static constexpr float SIGMA_COLD = -6.0F; + + // Holds all correction data + // key: [Harmonic][Cent][Subdetector] + // Harmonics {2,3,4} -> 3 elements + // Subdetectors {S,N} -> 2 elements + std::array, m_cent_bins>, m_harmonics.size()> m_correction_data; + + // --- Member Variables --- + std::string m_input_file; + int m_runnumber; + std::string m_output_dir; + std::string m_cdb_tag; + + std::unique_ptr m_tfile; + + // --- Private Helper Methods --- +/** + * @brief Safely retrieves a ROOT object from the internal TFile and returns a managed unique_ptr. + * * Utilizes the internal m_tfile member to locate the object. Performs a + * dynamic_cast for type safety and Clones the object for persistent use. + * * @tparam T The ROOT class type (e.g., TProfile, TH3). + * @param name The name of the object within the internal file. + * @return std::unique_ptr A managed pointer to the cloned object. + * @throws std::runtime_error If the object is not found or type mismatch occurs. + */ + template + std::unique_ptr load_and_clone(const std::string& name); + +/** + * @brief Provides safe access to the internal correction data storage. + * * This accessor handles the mapping between the physics-based Subdetector enum + * and the zero-based indexing of the underlying multi-dimensional array. + * * @param h_idx The index of the harmonic order in the m_harmonics array. + * @param cent_bin The index of the centrality bin. + * @param sub The subdetector arm (South or North) using the QVecShared enum. + * @return QVecShared::CorrectionMoments& A reference to the specific data entry. + */ + QVecShared::CorrectionMoments& getData(size_t h_idx, size_t cent_bin, QVecShared::Subdetector sub); + +/** + * @brief High-level orchestrator for loading calibration input from a ROOT file. + * * Opens the input file specified in the constructor and validates its integrity + * before iteratively calling load_correction_data() for every defined harmonic. + * * Throws a std::runtime_error if the file cannot be opened or is found to be + * a "zombie" file. + */ + void load_data(); + +/** + * @brief Loads 1st and 2nd order correction parameters from a calibration file. + * * Iterates through harmonics and centrality bins to populate the internal + * correction matrix using the centralized QVecShared naming scheme. + * * @param h_idx The index of the harmonic to load. + */ + void load_correction_data(size_t h_idx); + +/** + * @brief Top-level orchestrator for the CDB writing phase. + * + * This method manages the creation of the run-specific directory structure + * (e.g., [output_dir]/[runnumber]) within the base output path. Once the + * filesystem is prepared, it delegates the generation and commitment of + * specific calibration payloads to write_cdb_EventPlane() and + * write_cdb_BadTowers(). + */ + void write_cdb(); + +/** + * @brief Writes the Event Plane calibration constants to a CDB-formatted TTree. + * * Formats the re-centering and flattening moments into a CDBTTree payload + * indexed by centrality bin for sPHENIX database integration. + * * @param output_dir The filesystem directory where the .root payload will be saved. + */ + void write_cdb_EventPlane(const std::string &output_dir); + +/** + * @brief Writes the Hot/Cold tower status map to a CDB-formatted TTree. + * * Encodes sEPD channel indices into TowerInfo keys and maps status codes (1=Dead, + * 2=Hot, 3=Cold) to the final database payload. + * * @param output_dir The filesystem directory where the .root payload will be saved. + */ + void write_cdb_BadTowers(const std::string &output_dir); +}; + +#endif // QVECCDB_H diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc new file mode 100644 index 0000000000..afa9eb8ed8 --- /dev/null +++ b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc @@ -0,0 +1,1172 @@ +#include "QVecCalib.h" + +// ==================================================================== +// sPHENIX Includes +// ==================================================================== +#include + +// ==================================================================== +// Standard C++ Includes +// ==================================================================== +#include +#include +#include +#include +#include + +// ==================================================================== +// ROOT Includes +// ==================================================================== +#include + +std::unique_ptr QVecCalib::setupTChain(const std::string& input_filepath, const std::string& tree_name_in_file) +{ + // 1. Pre-check: Does the file exist at all? (C++17 filesystem or traditional fstream) + if (!std::filesystem::exists(input_filepath)) + { + std::cout << "Error: Input file does not exist: " << input_filepath << std::endl; + return nullptr; // Return a null unique_ptr indicating failure + } + + // 2. Open the file to check for the TTree directly + // Use TFile::Open and unique_ptr for robust file handling (RAII) + std::unique_ptr file_checker(TFile::Open(input_filepath.c_str(), "READ")); + + if (!file_checker || file_checker->IsZombie()) + { + std::cout << "Error: Could not open file " << input_filepath << " to check for TTree." << std::endl; + return nullptr; + } + + // Check if the TTree exists in the file + // Get() returns a TObject*, which can be cast to TTree*. + // If the object doesn't exist or isn't a TTree, Get() returns nullptr. + TTree* tree_obj = dynamic_cast(file_checker->Get(tree_name_in_file.c_str())); + if (!tree_obj) + { + std::cout << "Error: TTree '" << tree_name_in_file << "' not found in file " << input_filepath << std::endl; + return nullptr; + } + // File will be automatically closed by file_checker's unique_ptr destructor + + // 3. If everything checks out, create and configure the TChain + std::unique_ptr chain = std::make_unique(tree_name_in_file.c_str()); + if (!chain) + { // Check if make_unique failed (e.g. out of memory) + std::cout << "Error: Could not create TChain object." << std::endl; + return nullptr; + } + + chain->Add(input_filepath.c_str()); + + // 4. Verify TChain's state (optional but good final check) + // GetEntries() will be -1 if no valid trees were added. + if (chain->GetEntries() == 0) + { + std::cout << "Warning: TChain has 0 entries after adding file. This might indicate a problem." << std::endl; + // Depending on your logic, you might return nullptr here too. + } + else + { + std::cout << "Successfully set up TChain for tree '" << tree_name_in_file + << "' from file '" << input_filepath << "'. Entries: " << chain->GetEntries() << std::endl; + } + + return chain; // Return the successfully created and configured TChain +} + +void QVecCalib::setup_chain() +{ + std::cout << "Processing... setup_chain" << std::endl; + + m_chain = setupTChain(m_input_file, "T"); + + if (m_chain == nullptr) + { + throw std::runtime_error(std::format("Error in TChain Setup from file: {}", m_input_file)); + } + + // Setup branches + m_chain->SetBranchStatus("*", false); + m_chain->SetBranchStatus("event_id", true); + m_chain->SetBranchStatus("event_centrality", true); + m_chain->SetBranchStatus("sepd_totalcharge", true); + m_chain->SetBranchStatus("sepd_channel", true); + m_chain->SetBranchStatus("sepd_charge", true); + m_chain->SetBranchStatus("sepd_phi", true); + + m_chain->SetBranchAddress("event_id", &m_event_data.event_id); + m_chain->SetBranchAddress("event_centrality", &m_event_data.event_centrality); + m_chain->SetBranchAddress("sepd_totalcharge", &m_event_data.sepd_totalcharge); + m_chain->SetBranchAddress("sepd_channel", &m_event_data.sepd_channel); + m_chain->SetBranchAddress("sepd_charge", &m_event_data.sepd_charge); + m_chain->SetBranchAddress("sepd_phi", &m_event_data.sepd_phi); + + std::cout << "Finished... setup_chain" << std::endl; +} + +void QVecCalib::process_QA_hist() +{ + TH1::AddDirectory(kFALSE); + auto file = std::unique_ptr(TFile::Open(m_input_hist.c_str())); + + // Check if the file was opened successfully. + if (!file || file->IsZombie()) + { + throw std::runtime_error(std::format("Could not open file '{}'", m_input_hist)); + } + + // Get List of Bad Channels + process_bad_channels(file.get()); + + // Get sEPD Total Charge Bounds as function of centrality + process_sEPD_event_thresholds(file.get()); +} + +void QVecCalib::process_sEPD_event_thresholds(TFile* file) +{ + std::string sepd_totalcharge_centrality = "h2SEPD_totalcharge_centrality"; + + auto* hist = file->Get(sepd_totalcharge_centrality.c_str()); + + // Check if the hist is stored in the file + if (hist == nullptr) + { + throw std::runtime_error(std::format("Cannot find hist: {}", sepd_totalcharge_centrality)); + } + + m_hists2D["h2SEPD_Charge"] = std::unique_ptr(static_cast(hist->Clone("h2SEPD_Charge"))); + m_hists2D["h2SEPD_Chargev2"] = std::unique_ptr(static_cast(hist->Clone("h2SEPD_Chargev2"))); + + auto* h2SEPD_Charge = m_hists2D["h2SEPD_Charge"].get(); + auto* h2SEPD_Chargev2 = m_hists2D["h2SEPD_Chargev2"].get(); + + auto* h2SEPD_Charge_py = h2SEPD_Charge->ProfileY("h2SEPD_Charge_py", 1, -1, "s"); + + int binsx = h2SEPD_Charge->GetNbinsX(); + int binsy = h2SEPD_Charge->GetNbinsY(); + int ymin = h2SEPD_Charge->GetYaxis()->GetXmin(); + int ymax = h2SEPD_Charge->GetYaxis()->GetXmax(); + + m_profiles["hSEPD_Charge_Min"] = std::make_unique("hSEPD_Charge_Min", "; Centrality [%]; sEPD Total Charge", binsy, ymin, ymax); + m_profiles["hSEPD_Charge_Max"] = std::make_unique("hSEPD_Charge_Max", "; Centrality [%]; sEPD Total Charge", binsy, ymin, ymax); + + auto* hSEPD_Charge_Min = m_profiles["hSEPD_Charge_Min"].get(); + auto* hSEPD_Charge_Max = m_profiles["hSEPD_Charge_Max"].get(); + + for (int y = 1; y <= binsy; ++y) + { + double cent = h2SEPD_Charge_py->GetBinCenter(y); + double mean = h2SEPD_Charge_py->GetBinContent(y); + double sigma = h2SEPD_Charge_py->GetBinError(y); + double charge_low = mean - m_sEPD_sigma_threshold * sigma; + double charge_high = mean + m_sEPD_sigma_threshold * sigma; + + hSEPD_Charge_Min->Fill(cent, charge_low); + hSEPD_Charge_Max->Fill(cent, charge_high); + + for (int x = 1; x <= binsx; ++x) + { + double charge = h2SEPD_Charge->GetXaxis()->GetBinCenter(x); + double zscore = (charge - mean) / sigma; + + if (std::fabs(zscore) > m_sEPD_sigma_threshold) + { + h2SEPD_Chargev2->SetBinContent(x, y, 0); + } + } + } +} + +void QVecCalib::process_bad_channels(TFile* file) +{ + std::string sepd_charge_hist = "hSEPD_Charge"; + + auto* hist = file->Get(sepd_charge_hist.c_str()); + + // Check if the hist is stored in the file + if (hist == nullptr) + { + throw std::runtime_error(std::format("Cannot find hist: {}", sepd_charge_hist)); + } + + auto* hSEPD_Charge = dynamic_cast(hist); + + int sepd_channels = 744; + int rbins = 16; + int bins_charge = 40; + + m_hists2D["h2SEPD_South_Charge_rbin"] = std::make_unique("h2SEPD_South_Charge_rbin", + "sEPD South; r_{bin}; Avg Charge", + rbins, -0.5, rbins - 0.5, + bins_charge, 0, bins_charge); + + m_hists2D["h2SEPD_North_Charge_rbin"] = std::make_unique("h2SEPD_North_Charge_rbin", + "sEPD North; r_{bin}; Avg Charge", + rbins, -0.5, rbins - 0.5, + bins_charge, 0, bins_charge); + + m_hists2D["h2SEPD_South_Charge_rbinv2"] = std::make_unique("h2SEPD_South_Charge_rbinv2", + "sEPD South; r_{bin}; Avg Charge", + rbins, -0.5, rbins - 0.5, + bins_charge, 0, bins_charge); + + m_hists2D["h2SEPD_North_Charge_rbinv2"] = std::make_unique("h2SEPD_North_Charge_rbinv2", + "sEPD North; r_{bin}; Avg Charge", + rbins, -0.5, rbins - 0.5, + bins_charge, 0, bins_charge); + + m_profiles["h_sEPD_Bad_Channels"] = std::make_unique("h_sEPD_Bad_Channels", "sEPD Bad Channels; Channel; Status", sepd_channels, -0.5, sepd_channels-0.5); + + auto* h2S = m_hists2D["h2SEPD_South_Charge_rbin"].get(); + auto* h2N = m_hists2D["h2SEPD_North_Charge_rbin"].get(); + + auto* h2Sv2 = m_hists2D["h2SEPD_South_Charge_rbinv2"].get(); + auto* h2Nv2 = m_hists2D["h2SEPD_North_Charge_rbinv2"].get(); + + auto* hBad = m_profiles["h_sEPD_Bad_Channels"].get(); + + for (int channel = 0; channel < sepd_channels; ++channel) + { + unsigned int key = TowerInfoDefs::encode_epd(static_cast(channel)); + int rbin = static_cast(TowerInfoDefs::get_epd_rbin(key)); + unsigned int arm = TowerInfoDefs::get_epd_arm(key); + + double avg_charge = hSEPD_Charge->GetBinContent(channel + 1); + + auto* h2 = (arm == 0) ? h2S : h2N; + + h2->Fill(rbin, avg_charge); + } + + auto* hSpx = h2S->ProfileX("hSpx", 2, -1, "s"); + auto* hNpx = h2N->ProfileX("hNpx", 2, -1, "s"); + + int ctr_dead = 0; + int ctr_hot = 0; + int ctr_cold = 0; + + for (int channel = 0; channel < sepd_channels; ++channel) + { + unsigned int key = TowerInfoDefs::encode_epd(static_cast(channel)); + int rbin = static_cast(TowerInfoDefs::get_epd_rbin(key)); + unsigned int arm = TowerInfoDefs::get_epd_arm(key); + + auto* h2 = (arm == 0) ? h2Sv2 : h2Nv2; + auto* hprof = (arm == 0) ? hSpx : hNpx; + + double charge = hSEPD_Charge->GetBinContent(channel + 1); + double mean_charge = hprof->GetBinContent(rbin + 1); + double sigma = hprof->GetBinError(rbin + 1); + double zscore = (charge - mean_charge) / sigma; + + if (charge < m_sEPD_min_avg_charge_threshold || std::fabs(zscore) > m_sEPD_sigma_threshold) + { + m_bad_channels.insert(channel); + + std::string type; + int status_fill; + + // dead channel + if (charge == 0) + { + type = "Dead"; + status_fill = 1; + ++ctr_dead; + } + // hot channel + else if (zscore > m_sEPD_sigma_threshold) + { + type = "Hot"; + status_fill = 2; + ++ctr_hot; + } + // cold channel + else + { + type = "Cold"; + status_fill = 3; + ++ctr_cold; + } + + hBad->Fill(channel, status_fill); + std::cout << std::format("{:4} Channel: {:3d}, arm: {}, rbin: {:2d}, Mean: {:5.2f}, Charge: {:5.2f}, Z-Score: {:5.2f}\n", type, channel, arm, rbin, mean_charge, charge, zscore); + } + else + { + h2->Fill(rbin, charge); + } + } + + std::cout << std::format("Total Bad Channels: {}, Dead: {}, Hot: {}, Cold: {}\n", m_bad_channels.size(), ctr_dead, ctr_hot, ctr_cold); + + std::cout << "Finished processing Hot sEPD channels" << std::endl; +} + +void QVecCalib::init_hists() +{ + unsigned int bins_Q = 100; + double Q_low = -1; + double Q_high = 1; + + unsigned int bins_psi = 126; + double psi_low = -std::numbers::pi; + double psi_high = std::numbers::pi; + + m_hists1D["h_Cent"] = std::make_unique("h_Cent", "", m_cent_bins, m_cent_low, m_cent_high); + + std::string pass_suffix; + if (m_pass == Pass::ApplyRecentering) + { + pass_suffix = "_corr"; + } + else if (m_pass == Pass::ApplyFlattening) + { + pass_suffix = "_corr2"; + } + + // n = 2, 3, 4, etc. + for (int n : m_harmonics) + { + std::string psi_hist_name = std::format("h3_sEPD_Psi_{}", n); + std::string psi_hist_title = std::format("sEPD #Psi (Order {0}): |z| < 10 cm and MB; {0}#Psi^{{S}}_{{{0}}}; {0}#Psi^{{N}}_{{{0}}}; Centrality [%]", n); + + if (m_pass == Pass::ComputeRecentering) + { + psi_hist_name = std::format("h3_sEPD_Psi_{}", n); + } + + if (m_pass == Pass::ApplyRecentering) + { + psi_hist_name = std::format("h3_sEPD_Psi_{}_corr", n); + } + + if (m_pass == Pass::ApplyFlattening) + { + psi_hist_name = std::format("h3_sEPD_Psi_{}_corr2", n); + } + + m_hists3D[psi_hist_name] = std::make_unique(psi_hist_name.c_str(), psi_hist_title.c_str(), bins_psi, psi_low, psi_high, bins_psi, psi_low, psi_high, m_cent_bins, m_cent_low, m_cent_high); + + // South, North + for (auto det : m_subdetectors) + { + std::string det_str = (det == QVecShared::Subdetector::S) ? "S" : "N"; + std::string det_name = (det == QVecShared::Subdetector::S) ? "South" : "North"; + + if (m_pass == Pass::ComputeRecentering) + { + std::string q_hist_name = std::format("h3_sEPD_Q_{}_{}", det_str, n); + std::string q_hist_title = std::format("sEPD {} Q (Order {}): |z| < 10 cm and MB; Q_{{x}}; Q_{{y}}; Centrality [%]", det_name, n); + m_hists3D[q_hist_name] = std::make_unique(q_hist_name.c_str(), q_hist_title.c_str(), + bins_Q, Q_low, Q_high, bins_Q, Q_low, Q_high, m_cent_bins, m_cent_low, m_cent_high); + } + + std::string q_avg_sq_cross_name; + std::string q_avg_sq_cross_title = std::format("sEPD {0}; Centrality [%]; ", det_name, n); + + if (m_pass == Pass::ApplyRecentering) + { + q_avg_sq_cross_name = QVecShared::get_hist_name(det_str, "xy", n); + } + + if (m_pass == Pass::ApplyFlattening) + { + q_avg_sq_cross_name = QVecShared::get_hist_name(det_str, "xy", n, "_corr"); + } + + if (!q_avg_sq_cross_name.empty()) + { + m_profiles[q_avg_sq_cross_name] = std::make_unique(q_avg_sq_cross_name.c_str(), q_avg_sq_cross_title.c_str(), + m_cent_bins, m_cent_low, m_cent_high); + } + + for (auto comp : m_components) + { + std::string comp_str = (comp == QVecShared::QComponent::X) ? "x" : "y"; + std::string name = QVecShared::get_hist_name(det_str, comp_str, n, pass_suffix); + + auto add_profile = [&](const std::string& prof_name, std::string_view label_suffix = "") + { + std::string title = std::format("sEPD {}; Centrality [%]; ", det_name, n, comp_str, label_suffix); + m_profiles[prof_name] = std::make_unique(prof_name.c_str(), title.c_str(), m_cent_bins, m_cent_low, m_cent_high); + }; + + add_profile(name); + + // 2. Only generate strings and profiles for the current pass + switch (m_pass) + { + case Pass::ComputeRecentering: + { + break; + } + + case Pass::ApplyRecentering: + { + std::string name_sq = QVecShared::get_hist_name(det_str, comp_str+comp_str, n); + add_profile(name_sq, "^{2}"); + break; + } + + case Pass::ApplyFlattening: + { + std::string name_sq_corr = QVecShared::get_hist_name(det_str, comp_str+comp_str, n, "_corr"); + add_profile(name_sq_corr, "^{2}"); + break; + } + } + } + } + } +} + +void QVecCalib::process_averages(double cent, QVecShared::QVec q_S, QVecShared::QVec q_N, const AverageHists& h) +{ + double psi_S = std::atan2(q_S.y, q_S.x); + double psi_N = std::atan2(q_N.y, q_N.x); + + h.S_x_avg->Fill(cent, q_S.x); + h.S_y_avg->Fill(cent, q_S.y); + h.N_x_avg->Fill(cent, q_N.x); + h.N_y_avg->Fill(cent, q_N.y); + + h.Q_S->Fill(q_S.x, q_S.y, cent); + h.Q_N->Fill(q_N.x, q_N.y, cent); + h.Psi->Fill(psi_S, psi_N, cent); +} + +void QVecCalib::process_recentering(double cent, size_t h_idx, QVecShared::QVec q_S, QVecShared::QVec q_N, const RecenterHists& h) +{ + size_t cent_bin = static_cast(m_hists1D["h_Cent"]->FindBin(cent) - 1); + + double Q_S_x_avg = m_correction_data[cent_bin][h_idx][0].avg_Q.x; + double Q_S_y_avg = m_correction_data[cent_bin][h_idx][0].avg_Q.y; + double Q_N_x_avg = m_correction_data[cent_bin][h_idx][1].avg_Q.x; + double Q_N_y_avg = m_correction_data[cent_bin][h_idx][1].avg_Q.y; + + QVecShared::QVec q_S_corr = {q_S.x - Q_S_x_avg, q_S.y - Q_S_y_avg}; + QVecShared::QVec q_N_corr = {q_N.x - Q_N_x_avg, q_N.y - Q_N_y_avg}; + + double psi_S_corr = std::atan2(q_S_corr.y, q_S_corr.x); + double psi_N_corr = std::atan2(q_N_corr.y, q_N_corr.x); + + h.S_x_corr_avg->Fill(cent, q_S_corr.x); + h.S_y_corr_avg->Fill(cent, q_S_corr.y); + h.N_x_corr_avg->Fill(cent, q_N_corr.x); + h.N_y_corr_avg->Fill(cent, q_N_corr.y); + + h.S_xx_avg->Fill(cent, q_S_corr.x * q_S_corr.x); + h.S_yy_avg->Fill(cent, q_S_corr.y * q_S_corr.y); + h.S_xy_avg->Fill(cent, q_S_corr.x * q_S_corr.y); + h.N_xx_avg->Fill(cent, q_N_corr.x * q_N_corr.x); + h.N_yy_avg->Fill(cent, q_N_corr.y * q_N_corr.y); + h.N_xy_avg->Fill(cent, q_N_corr.x * q_N_corr.y); + + h.Psi_corr->Fill(psi_S_corr, psi_N_corr, cent); +} + +void QVecCalib::process_flattening(double cent, size_t h_idx, QVecShared::QVec q_S, QVecShared::QVec q_N, const FlatteningHists& h) +{ + size_t cent_bin = static_cast(m_hists1D["h_Cent"]->FindBin(cent) - 1); + + double Q_S_x_avg = m_correction_data[cent_bin][h_idx][0].avg_Q.x; + double Q_S_y_avg = m_correction_data[cent_bin][h_idx][0].avg_Q.y; + double Q_N_x_avg = m_correction_data[cent_bin][h_idx][1].avg_Q.x; + double Q_N_y_avg = m_correction_data[cent_bin][h_idx][1].avg_Q.y; + + QVecShared::QVec q_S_corr = {q_S.x - Q_S_x_avg, q_S.y - Q_S_y_avg}; + QVecShared::QVec q_N_corr = {q_N.x - Q_N_x_avg, q_N.y - Q_N_y_avg}; + + const auto& X_S = m_correction_data[cent_bin][h_idx][0].X_matrix; + const auto& X_N = m_correction_data[cent_bin][h_idx][1].X_matrix; + + double Q_S_x_corr2 = X_S[0][0] * q_S_corr.x + X_S[0][1] * q_S_corr.y; + double Q_S_y_corr2 = X_S[1][0] * q_S_corr.x + X_S[1][1] * q_S_corr.y; + double Q_N_x_corr2 = X_N[0][0] * q_N_corr.x + X_N[0][1] * q_N_corr.y; + double Q_N_y_corr2 = X_N[1][0] * q_N_corr.x + X_N[1][1] * q_N_corr.y; + + QVecShared::QVec q_S_corr2 = {Q_S_x_corr2, Q_S_y_corr2}; + QVecShared::QVec q_N_corr2 = {Q_N_x_corr2, Q_N_y_corr2}; + + double psi_S = std::atan2(q_S_corr2.y, q_S_corr2.x); + double psi_N = std::atan2(q_N_corr2.y, q_N_corr2.x); + + h.S_x_corr2_avg->Fill(cent, q_S_corr2.x); + h.S_y_corr2_avg->Fill(cent, q_S_corr2.y); + h.N_x_corr2_avg->Fill(cent, q_N_corr2.x); + h.N_y_corr2_avg->Fill(cent, q_N_corr2.y); + + h.S_xx_corr_avg->Fill(cent, q_S_corr2.x * q_S_corr2.x); + h.S_yy_corr_avg->Fill(cent, q_S_corr2.y * q_S_corr2.y); + h.S_xy_corr_avg->Fill(cent, q_S_corr2.x * q_S_corr2.y); + h.N_xx_corr_avg->Fill(cent, q_N_corr2.x * q_N_corr2.x); + h.N_yy_corr_avg->Fill(cent, q_N_corr2.y * q_N_corr2.y); + h.N_xy_corr_avg->Fill(cent, q_N_corr2.x * q_N_corr2.y); + + h.Psi_corr2->Fill(psi_S, psi_N, cent); +} + +void QVecCalib::compute_averages(size_t cent_bin, int h_idx) +{ + int n = m_harmonics[h_idx]; + + std::string S_x_avg_name = QVecShared::get_hist_name("S", "x", n); + std::string S_y_avg_name = QVecShared::get_hist_name("S", "y", n); + std::string N_x_avg_name = QVecShared::get_hist_name("N", "x", n); + std::string N_y_avg_name = QVecShared::get_hist_name("N", "y", n); + + int bin = static_cast(cent_bin + 1); + + double Q_S_x_avg = m_profiles[S_x_avg_name]->GetBinContent(bin); + double Q_S_y_avg = m_profiles[S_y_avg_name]->GetBinContent(bin); + double Q_N_x_avg = m_profiles[N_x_avg_name]->GetBinContent(bin); + double Q_N_y_avg = m_profiles[N_y_avg_name]->GetBinContent(bin); + + m_correction_data[cent_bin][h_idx][0].avg_Q = {Q_S_x_avg, Q_S_y_avg}; + m_correction_data[cent_bin][h_idx][1].avg_Q = {Q_N_x_avg, Q_N_y_avg}; + + std::cout << std::format( + "Centrality Bin: {}, " + "Harmonic: {}, " + "Q_S_x_avg: {:13.10f}, " + "Q_S_y_avg: {:13.10f}, " + "Q_N_x_avg: {:13.10f}, " + "Q_N_y_avg: {:13.10f}\n", + cent_bin, + n, + Q_S_x_avg, + Q_S_y_avg, + Q_N_x_avg, + Q_N_y_avg); +} + +std::array, 2> QVecCalib::calculate_flattening_matrix(double xx, double yy, double xy, int n, int cent_bin, const std::string& det_label) +{ + double D_arg = (xx * yy) - (xy * xy); + if (D_arg <= 0) + { + throw std::runtime_error(std::format( + "Invalid D-term ({}) for n={}, cent={}, det={}", D_arg, n, cent_bin, det_label)); + } + double D = std::sqrt(D_arg); + + double N_term = D * (xx + yy + (2 * D)); + if (N_term <= 0) + { + throw std::runtime_error(std::format( + "Invalid N-term ({}) for n={}, cent={}, det={}", N_term, n, cent_bin, det_label)); + } + double inv_sqrt_N = 1.0 / std::sqrt(N_term); + + std::array, 2> mat{}; + mat[0][0] = inv_sqrt_N * (yy + D); + mat[0][1] = -inv_sqrt_N * xy; + mat[1][0] = mat[0][1]; + mat[1][1] = inv_sqrt_N * (xx + D); + return mat; +} + +void QVecCalib::compute_recentering(size_t cent_bin, int h_idx) +{ + int n = m_harmonics[h_idx]; + + std::string S_x_corr_avg_name = QVecShared::get_hist_name("S", "x", n, "_corr"); + std::string S_y_corr_avg_name = QVecShared::get_hist_name("S", "y", n, "_corr"); + std::string N_x_corr_avg_name = QVecShared::get_hist_name("N", "x", n, "_corr"); + std::string N_y_corr_avg_name = QVecShared::get_hist_name("N", "y", n, "_corr"); + + int bin = static_cast(cent_bin + 1); + + double Q_S_x_corr_avg = m_profiles[S_x_corr_avg_name]->GetBinContent(bin); + double Q_S_y_corr_avg = m_profiles[S_y_corr_avg_name]->GetBinContent(bin); + double Q_N_x_corr_avg = m_profiles[N_x_corr_avg_name]->GetBinContent(bin); + double Q_N_y_corr_avg = m_profiles[N_y_corr_avg_name]->GetBinContent(bin); + + // -- Compute 2nd Order Correction -- + std::string S_xx_avg_name = QVecShared::get_hist_name("S", "xx", n); + std::string S_yy_avg_name = QVecShared::get_hist_name("S", "yy", n); + std::string S_xy_avg_name = QVecShared::get_hist_name("S", "xy", n); + std::string N_xx_avg_name = QVecShared::get_hist_name("N", "xx", n); + std::string N_yy_avg_name = QVecShared::get_hist_name("N", "yy", n); + std::string N_xy_avg_name = QVecShared::get_hist_name("N", "xy", n); + + double Q_S_xx_avg = m_profiles[S_xx_avg_name]->GetBinContent(bin); + double Q_S_yy_avg = m_profiles[S_yy_avg_name]->GetBinContent(bin); + double Q_S_xy_avg = m_profiles[S_xy_avg_name]->GetBinContent(bin); + double Q_N_xx_avg = m_profiles[N_xx_avg_name]->GetBinContent(bin); + double Q_N_yy_avg = m_profiles[N_yy_avg_name]->GetBinContent(bin); + double Q_N_xy_avg = m_profiles[N_xy_avg_name]->GetBinContent(bin); + + m_correction_data[cent_bin][h_idx][0].avg_Q_xx = Q_S_xx_avg; + m_correction_data[cent_bin][h_idx][0].avg_Q_yy = Q_S_yy_avg; + m_correction_data[cent_bin][h_idx][0].avg_Q_xy = Q_S_xy_avg; + m_correction_data[cent_bin][h_idx][1].avg_Q_xx = Q_N_xx_avg; + m_correction_data[cent_bin][h_idx][1].avg_Q_yy = Q_N_yy_avg; + m_correction_data[cent_bin][h_idx][1].avg_Q_xy = Q_N_xy_avg; + + for (size_t det_idx = 0; det_idx < 2; ++det_idx) + { + double xx = (det_idx == 0) ? Q_S_xx_avg : Q_N_xx_avg; + double yy = (det_idx == 0) ? Q_S_yy_avg : Q_N_yy_avg; + double xy = (det_idx == 0) ? Q_S_xy_avg : Q_N_xy_avg; + + std::string label = (det_idx == 0) ? "S" : "N"; + + m_correction_data[cent_bin][h_idx][det_idx].X_matrix = calculate_flattening_matrix(xx, yy, xy, n, cent_bin, label); + } + + std::cout << std::format( + "Centrality Bin: {}, " + "Harmonic: {}, " + "Q_S_x_corr_avg: {:13.10f}, " + "Q_S_y_corr_avg: {:13.10f}, " + "Q_N_x_corr_avg: {:13.10f}, " + "Q_N_y_corr_avg: {:13.10f}, " + "Q_S_xx_avg / Q_S_yy_avg: {:13.10f}, " + "Q_N_xx_avg / Q_N_yy_avg: {:13.10f}, " + "Q_S_xy_avg: {:13.10f}, " + "Q_N_xy_avg: {:13.10f}\n", + cent_bin, + n, + Q_S_x_corr_avg, + Q_S_y_corr_avg, + Q_N_x_corr_avg, + Q_N_y_corr_avg, + Q_S_xx_avg / Q_S_yy_avg, + Q_N_xx_avg / Q_N_yy_avg, + Q_S_xy_avg, + Q_N_xy_avg); +} + +void QVecCalib::print_flattening(size_t cent_bin, int n) const +{ + std::string S_x_corr2_avg_name = QVecShared::get_hist_name("S", "x", n, "_corr2"); + std::string S_y_corr2_avg_name = QVecShared::get_hist_name("S", "y", n, "_corr2"); + std::string N_x_corr2_avg_name = QVecShared::get_hist_name("N", "x", n, "_corr2"); + std::string N_y_corr2_avg_name = QVecShared::get_hist_name("N", "y", n, "_corr2"); + + std::string S_xx_corr_avg_name = QVecShared::get_hist_name("S", "xx", n, "_corr"); + std::string S_yy_corr_avg_name = QVecShared::get_hist_name("S", "yy", n, "_corr"); + std::string S_xy_corr_avg_name = QVecShared::get_hist_name("S", "xy", n, "_corr"); + std::string N_xx_corr_avg_name = QVecShared::get_hist_name("N", "xx", n, "_corr"); + std::string N_yy_corr_avg_name = QVecShared::get_hist_name("N", "yy", n, "_corr"); + std::string N_xy_corr_avg_name = QVecShared::get_hist_name("N", "xy", n, "_corr"); + + int bin = static_cast(cent_bin + 1); + + double Q_S_x_corr2_avg = m_profiles.at(S_x_corr2_avg_name)->GetBinContent(bin); + double Q_S_y_corr2_avg = m_profiles.at(S_y_corr2_avg_name)->GetBinContent(bin); + double Q_N_x_corr2_avg = m_profiles.at(N_x_corr2_avg_name)->GetBinContent(bin); + double Q_N_y_corr2_avg = m_profiles.at(N_y_corr2_avg_name)->GetBinContent(bin); + + double Q_S_xx_corr_avg = m_profiles.at(S_xx_corr_avg_name)->GetBinContent(bin); + double Q_S_yy_corr_avg = m_profiles.at(S_yy_corr_avg_name)->GetBinContent(bin); + double Q_S_xy_corr_avg = m_profiles.at(S_xy_corr_avg_name)->GetBinContent(bin); + double Q_N_xx_corr_avg = m_profiles.at(N_xx_corr_avg_name)->GetBinContent(bin); + double Q_N_yy_corr_avg = m_profiles.at(N_yy_corr_avg_name)->GetBinContent(bin); + double Q_N_xy_corr_avg = m_profiles.at(N_xy_corr_avg_name)->GetBinContent(bin); + + std::cout << std::format( + "Centrality Bin: {}, " + "Harmonic: {}, " + "Q_S_x_corr2_avg: {:13.10f}, " + "Q_S_y_corr2_avg: {:13.10f}, " + "Q_N_x_corr2_avg: {:13.10f}, " + "Q_N_y_corr2_avg: {:13.10f}, " + "Q_S_xx_corr_avg / Q_S_yy_corr_avg: {:13.10f}, " + "Q_N_xx_corr_avg / Q_N_yy_corr_avg: {:13.10f}, " + "Q_S_xy_corr_avg: {:13.10f}, " + "Q_N_xy_corr_avg: {:13.10f}\n", + cent_bin, + n, + Q_S_x_corr2_avg, + Q_S_y_corr2_avg, + Q_N_x_corr2_avg, + Q_N_y_corr2_avg, + Q_S_xx_corr_avg / Q_S_yy_corr_avg, + Q_N_xx_corr_avg / Q_N_yy_corr_avg, + Q_S_xy_corr_avg, + Q_N_xy_corr_avg); +} + +std::vector QVecCalib::prepare_average_hists() +{ + std::vector hists_cache; + for (int n : m_harmonics) + { + + std::string S_x_avg_name = QVecShared::get_hist_name("S", "x", n); + std::string S_y_avg_name = QVecShared::get_hist_name("S", "y", n); + std::string N_x_avg_name = QVecShared::get_hist_name("N", "x", n); + std::string N_y_avg_name = QVecShared::get_hist_name("N", "y", n); + + std::string hist_Q_S_name = std::format("h3_sEPD_Q_S_{}", n); + std::string hist_Q_N_name = std::format("h3_sEPD_Q_N_{}", n); + std::string psi_Q_name = std::format("h3_sEPD_Psi_{}", n); + + AverageHists h; + + h.S_x_avg = m_profiles.at(S_x_avg_name).get(); + h.S_y_avg = m_profiles.at(S_y_avg_name).get(); + h.N_x_avg = m_profiles.at(N_x_avg_name).get(); + h.N_y_avg = m_profiles.at(N_y_avg_name).get(); + + h.Q_S = m_hists3D.at(hist_Q_S_name).get(); + h.Q_N = m_hists3D.at(hist_Q_N_name).get(); + + h.Psi = m_hists3D.at(psi_Q_name).get(); + + hists_cache.push_back(h); + } + + return hists_cache; +} + +bool QVecCalib::process_sEPD() +{ + size_t nChannels = m_event_data.sepd_channel->size(); + + double sepd_total_charge_south = 0; + double sepd_total_charge_north = 0; + + // Loop over all sEPD Channels + for (size_t idx = 0; idx < nChannels; ++idx) + { + int channel = m_event_data.sepd_channel->at(idx); + double charge = m_event_data.sepd_charge->at(idx); + double phi = m_event_data.sepd_phi->at(idx); + + // Skip Bad Channels + if (m_bad_channels.contains(channel)) + { + continue; + } + + unsigned int key = TowerInfoDefs::encode_epd(static_cast(channel)); + unsigned int arm = TowerInfoDefs::get_epd_arm(key); + + // arm = 0: South + // arm = 1: North + double& sepd_total_charge = (arm == 0) ? sepd_total_charge_south : sepd_total_charge_north; + + // Compute total charge for the respective sEPD arm + sepd_total_charge += charge; + + // Compute Raw Q vectors for each harmonic and respective arm + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + int n = m_harmonics[h_idx]; + m_event_data.q_vectors[h_idx][arm].x += charge * std::cos(n * phi); + m_event_data.q_vectors[h_idx][arm].y += charge * std::sin(n * phi); + } + } + + // Skip Events with Zero sEPD Total Charge in either arm + if (sepd_total_charge_south == 0 || sepd_total_charge_north == 0) + { + return false; + } + + // Normalize the Q-vectors by total charge + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + for (auto det : m_subdetectors) + { + size_t det_idx = (det == QVecShared::Subdetector::S) ? 0 : 1; + double sepd_total_charge = (det_idx == 0) ? sepd_total_charge_south : sepd_total_charge_north; + m_event_data.q_vectors[h_idx][det_idx].x /= sepd_total_charge; + m_event_data.q_vectors[h_idx][det_idx].y /= sepd_total_charge; + } + } + + return true; +} + +std::vector QVecCalib::prepare_recenter_hists() +{ + std::vector hists_cache; + for (int n : m_harmonics) + { + std::string S_x_corr_avg_name = QVecShared::get_hist_name("S", "x", n, "_corr"); + std::string S_y_corr_avg_name = QVecShared::get_hist_name("S", "y", n, "_corr"); + std::string N_x_corr_avg_name = QVecShared::get_hist_name("N", "x", n, "_corr"); + std::string N_y_corr_avg_name = QVecShared::get_hist_name("N", "y", n, "_corr"); + + std::string S_xx_avg_name = QVecShared::get_hist_name("S", "xx", n); + std::string S_yy_avg_name = QVecShared::get_hist_name("S", "yy", n); + std::string S_xy_avg_name = QVecShared::get_hist_name("S", "xy", n); + std::string N_xx_avg_name = QVecShared::get_hist_name("N", "xx", n); + std::string N_yy_avg_name = QVecShared::get_hist_name("N", "yy", n); + std::string N_xy_avg_name = QVecShared::get_hist_name("N", "xy", n); + + std::string psi_Q_corr_name = std::format("h3_sEPD_Psi_{}_corr", n); + + RecenterHists h; + + h.S_x_corr_avg = m_profiles.at(S_x_corr_avg_name).get(); + h.S_y_corr_avg = m_profiles.at(S_y_corr_avg_name).get(); + h.N_x_corr_avg = m_profiles.at(N_x_corr_avg_name).get(); + h.N_y_corr_avg = m_profiles.at(N_y_corr_avg_name).get(); + + h.S_xx_avg = m_profiles.at(S_xx_avg_name).get(); + h.S_yy_avg = m_profiles.at(S_yy_avg_name).get(); + h.S_xy_avg = m_profiles.at(S_xy_avg_name).get(); + h.N_xx_avg = m_profiles.at(N_xx_avg_name).get(); + h.N_yy_avg = m_profiles.at(N_yy_avg_name).get(); + h.N_xy_avg = m_profiles.at(N_xy_avg_name).get(); + + h.Psi_corr = m_hists3D.at(psi_Q_corr_name).get(); + + hists_cache.push_back(h); + } + + return hists_cache; +} + +std::vector QVecCalib::prepare_flattening_hists() +{ + std::vector hists_cache; + for (int n : m_harmonics) + { + + std::string S_x_corr2_avg_name = QVecShared::get_hist_name("S", "x", n, "_corr2"); + std::string S_y_corr2_avg_name = QVecShared::get_hist_name("S", "y", n, "_corr2"); + std::string N_x_corr2_avg_name = QVecShared::get_hist_name("N", "x", n, "_corr2"); + std::string N_y_corr2_avg_name = QVecShared::get_hist_name("N", "y", n, "_corr2"); + + std::string S_xx_corr_avg_name = QVecShared::get_hist_name("S", "xx", n, "_corr"); + std::string S_yy_corr_avg_name = QVecShared::get_hist_name("S", "yy", n, "_corr"); + std::string S_xy_corr_avg_name = QVecShared::get_hist_name("S", "xy", n, "_corr"); + std::string N_xx_corr_avg_name = QVecShared::get_hist_name("N", "xx", n, "_corr"); + std::string N_yy_corr_avg_name = QVecShared::get_hist_name("N", "yy", n, "_corr"); + std::string N_xy_corr_avg_name = QVecShared::get_hist_name("N", "xy", n, "_corr"); + + std::string psi_Q_corr2_name = std::format("h3_sEPD_Psi_{}_corr2", n); + + FlatteningHists h; + + h.S_x_corr2_avg = m_profiles.at(S_x_corr2_avg_name).get(); + h.S_y_corr2_avg = m_profiles.at(S_y_corr2_avg_name).get(); + h.N_x_corr2_avg = m_profiles.at(N_x_corr2_avg_name).get(); + h.N_y_corr2_avg = m_profiles.at(N_y_corr2_avg_name).get(); + + h.S_xx_corr_avg = m_profiles.at(S_xx_corr_avg_name).get(); + h.S_yy_corr_avg = m_profiles.at(S_yy_corr_avg_name).get(); + h.S_xy_corr_avg = m_profiles.at(S_xy_corr_avg_name).get(); + + h.N_xx_corr_avg = m_profiles.at(N_xx_corr_avg_name).get(); + h.N_yy_corr_avg = m_profiles.at(N_yy_corr_avg_name).get(); + h.N_xy_corr_avg = m_profiles.at(N_xy_corr_avg_name).get(); + + h.Psi_corr2 = m_hists3D.at(psi_Q_corr2_name).get(); + + hists_cache.push_back(h); + } + + return hists_cache; +} + +bool QVecCalib::process_event_check() +{ + auto* hSEPD_Charge_Min = m_profiles["hSEPD_Charge_Min"].get(); + auto* hSEPD_Charge_Max = m_profiles["hSEPD_Charge_Max"].get(); + + double cent = m_event_data.event_centrality; + int cent_bin = hSEPD_Charge_Min->FindBin(cent); + + double sepd_totalcharge = m_event_data.sepd_totalcharge; + + double sepd_totalcharge_min = hSEPD_Charge_Min->GetBinContent(cent_bin); + double sepd_totalcharge_max = hSEPD_Charge_Max->GetBinContent(cent_bin); + + return sepd_totalcharge > sepd_totalcharge_min && sepd_totalcharge < sepd_totalcharge_max; +} + +void QVecCalib::run_event_loop() +{ + std::cout << std::format("Pass: {}\n", static_cast(m_pass)); + + long long n_entries = m_chain->GetEntries(); + if (m_events_to_process > 0) + { + n_entries = std::min(m_events_to_process, n_entries); + } + + std::vector average_hists; + std::vector recenter_hists; + std::vector flattening_hists; + + if (m_pass == Pass::ComputeRecentering) + { + average_hists = prepare_average_hists(); + } + else if (m_pass == Pass::ApplyRecentering) + { + recenter_hists = prepare_recenter_hists(); + } + else if (m_pass == Pass::ApplyFlattening) + { + flattening_hists = prepare_flattening_hists(); + } + + std::map ctr; + // Event Loop + for (long long i = 0; i < n_entries; ++i) + { + // Load Event Data from TChain + m_chain->GetEntry(i); + m_event_data.reset(); + + if (i % 10000 == 0) + { + std::cout << std::format("Processing {}/{}: {:.2f} %", i, n_entries, static_cast(i) * 100. / static_cast(n_entries)) << std::endl; + } + + double cent = m_event_data.event_centrality; + + // Identify Centrality Bin + size_t cent_bin = static_cast(m_hists1D["h_Cent"]->FindBin(cent) - 1); + + // ensure centrality is valid + if (cent_bin >= m_cent_bins) + { + std::cout << std::format("Weird Centrality: {}, Skipping Event: {}\n", cent, m_event_data.event_id); + ++ctr["invalid_cent_bin"]; + continue; + } + + bool isGood = process_event_check(); + + // Skip Events with non correlation between centrality and sEPD + if (!isGood) + { + ++ctr["bad_centrality_sepd_correlation"]; + continue; + } + + isGood = process_sEPD(); + + // Skip Events with Zero sEPD Total Charge in either arm + if (!isGood) + { + ++ctr["zero_sepd_total_charge"]; + continue; + } + + m_hists1D["h_Cent"]->Fill(cent); + + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + const auto& q_S = m_event_data.q_vectors[h_idx][0]; // 0 for South + const auto& q_N = m_event_data.q_vectors[h_idx][1]; // 1 for North + + // --- First Pass: Derive 1st Order --- + if (m_pass == Pass::ComputeRecentering) + { + process_averages(cent, q_S, q_N, average_hists[h_idx]); + } + + // --- Second Pass: Apply 1st Order, Derive 2nd Order --- + else if (m_pass == Pass::ApplyRecentering) + { + process_recentering(cent, h_idx, q_S, q_N, recenter_hists[h_idx]); + } + + // --- Third Pass: Apply 2nd Order, Validate --- + else if (m_pass == Pass::ApplyFlattening) + { + process_flattening(cent, h_idx, q_S, q_N, flattening_hists[h_idx]); + } + } + } + + std::cout << "Skipped Event Types\n"; + for (const auto& [name, events] : ctr) + { + std::cout << std::format("{}: {}, {:.2f} %\n", name, events, events * 100. / static_cast(n_entries)); + } + + // --------------- + + std::cout << std::format("{:#<20}\n", ""); + for (size_t cent_bin = 0; cent_bin < m_cent_bins; ++cent_bin) + { + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + int n = m_harmonics[h_idx]; + + if (m_pass == Pass::ComputeRecentering) + { + compute_averages(cent_bin, h_idx); + } + + else if (m_pass == Pass::ApplyRecentering) + { + compute_recentering(cent_bin, h_idx); + } + + else if (m_pass == Pass::ApplyFlattening) + { + print_flattening(cent_bin, n); + } + } + } + + std::cout << "Event loop finished." << std::endl; +} + +template +std::unique_ptr QVecCalib::load_and_clone(TFile* file, const std::string& name) { + auto* obj = dynamic_cast(file->Get(name.c_str())); + if (!obj) + { + throw std::runtime_error(std::format("Could not find histogram '{}' in file '{}'", name, file->GetName())); + } + return std::unique_ptr(static_cast(obj->Clone())); +} + +void QVecCalib::load_correction_data() +{ + TH1::AddDirectory(kFALSE); + + auto file = std::unique_ptr(TFile::Open(m_input_Q_calib.c_str())); + + // Check if the file was opened successfully. + if (!file || file->IsZombie()) + { + throw std::runtime_error(std::format("Could not open file '{}'", m_input_Q_calib)); + } + + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + int n = m_harmonics[h_idx]; + + std::string S_x_avg_name = QVecShared::get_hist_name("S", "x", n); + std::string S_y_avg_name = QVecShared::get_hist_name("S", "y", n); + std::string N_x_avg_name = QVecShared::get_hist_name("N", "x", n); + std::string N_y_avg_name = QVecShared::get_hist_name("N", "y", n); + + std::string psi_hist_name = std::format("h3_sEPD_Psi_{}", n); + + m_profiles[S_x_avg_name] = load_and_clone(file.get(), S_x_avg_name); + m_profiles[S_y_avg_name] = load_and_clone(file.get(), S_y_avg_name); + m_profiles[N_x_avg_name] = load_and_clone(file.get(), N_x_avg_name); + m_profiles[N_y_avg_name] = load_and_clone(file.get(), N_y_avg_name); + + m_hists3D[psi_hist_name] = load_and_clone(file.get(), psi_hist_name); + + std::string S_xx_avg_name = QVecShared::get_hist_name("S", "xx", n); + std::string S_yy_avg_name = QVecShared::get_hist_name("S", "yy", n); + std::string S_xy_avg_name = QVecShared::get_hist_name("S", "xy", n); + std::string N_xx_avg_name = QVecShared::get_hist_name("N", "xx", n); + std::string N_yy_avg_name = QVecShared::get_hist_name("N", "yy", n); + std::string N_xy_avg_name = QVecShared::get_hist_name("N", "xy", n); + + std::string psi_corr_hist_name = std::format("h3_sEPD_Psi_{}_corr", n); + + if(m_pass == Pass::ApplyFlattening) + { + m_profiles[S_xx_avg_name] = load_and_clone(file.get(), S_xx_avg_name); + m_profiles[S_yy_avg_name] = load_and_clone(file.get(), S_yy_avg_name); + m_profiles[S_xy_avg_name] = load_and_clone(file.get(), S_xy_avg_name); + m_profiles[N_xx_avg_name] = load_and_clone(file.get(), N_xx_avg_name); + m_profiles[N_yy_avg_name] = load_and_clone(file.get(), N_yy_avg_name); + m_profiles[N_xy_avg_name] = load_and_clone(file.get(), N_xy_avg_name); + + m_hists3D[psi_corr_hist_name] = load_and_clone(file.get(), psi_corr_hist_name); + } + + size_t south_idx = static_cast(QVecShared::Subdetector::S); + size_t north_idx = static_cast(QVecShared::Subdetector::N); + + for (size_t cent_bin = 0; cent_bin < m_cent_bins; ++cent_bin) + { + int bin = static_cast(cent_bin) + 1; + + double Q_S_x_avg = m_profiles[S_x_avg_name]->GetBinContent(bin); + double Q_S_y_avg = m_profiles[S_y_avg_name]->GetBinContent(bin); + double Q_N_x_avg = m_profiles[N_x_avg_name]->GetBinContent(bin); + double Q_N_y_avg = m_profiles[N_y_avg_name]->GetBinContent(bin); + + // Recentering Params + m_correction_data[cent_bin][h_idx][south_idx].avg_Q = {Q_S_x_avg, Q_S_y_avg}; + m_correction_data[cent_bin][h_idx][north_idx].avg_Q = {Q_N_x_avg, Q_N_y_avg}; + + if (m_pass == Pass::ApplyFlattening) + { + double Q_S_xx_avg = m_profiles[S_xx_avg_name]->GetBinContent(bin); + double Q_S_yy_avg = m_profiles[S_yy_avg_name]->GetBinContent(bin); + double Q_S_xy_avg = m_profiles[S_xy_avg_name]->GetBinContent(bin); + double Q_N_xx_avg = m_profiles[N_xx_avg_name]->GetBinContent(bin); + double Q_N_yy_avg = m_profiles[N_yy_avg_name]->GetBinContent(bin); + double Q_N_xy_avg = m_profiles[N_xy_avg_name]->GetBinContent(bin); + + // Flattening Params + m_correction_data[cent_bin][h_idx][south_idx].avg_Q_xx = Q_S_xx_avg; + m_correction_data[cent_bin][h_idx][south_idx].avg_Q_yy = Q_S_yy_avg; + m_correction_data[cent_bin][h_idx][south_idx].avg_Q_xy = Q_S_xy_avg; + + m_correction_data[cent_bin][h_idx][north_idx].avg_Q_xx = Q_N_xx_avg; + m_correction_data[cent_bin][h_idx][north_idx].avg_Q_yy = Q_N_yy_avg; + m_correction_data[cent_bin][h_idx][north_idx].avg_Q_xy = Q_N_xy_avg; + + for (size_t det_idx = 0; det_idx < 2; ++det_idx) + { + double xx = (det_idx == 0) ? Q_S_xx_avg : Q_N_xx_avg; + double yy = (det_idx == 0) ? Q_S_yy_avg : Q_N_yy_avg; + double xy = (det_idx == 0) ? Q_S_xy_avg : Q_N_xy_avg; + + std::string label = (det_idx == 0) ? "S" : "N"; + + m_correction_data[cent_bin][h_idx][det_idx].X_matrix = calculate_flattening_matrix(xx, yy, xy, n, cent_bin, label); + } + } + } + } +} + +void QVecCalib::process_events() +{ + if (m_pass == Pass::ApplyRecentering || m_pass == Pass::ApplyFlattening) + { + load_correction_data(); + } + + run_event_loop(); +} + +void QVecCalib::save_results() const +{ + std::filesystem::create_directories(m_output_dir); + + std::filesystem::path input_path(m_input_file); + std::string output_stem = input_path.stem().string(); + std::string output_filename = std::format("{}/Q-vec-corr_Pass-{}_{}.root", m_output_dir, static_cast(m_pass), output_stem); + + auto output_file = std::make_unique(output_filename.c_str(), "RECREATE"); + + for (const auto& [name, hist] : m_hists1D) + { + std::cout << std::format("Saving 1D: {}\n", name); + hist->Write(); + } + for (const auto& [name, hist] : m_hists2D) + { + std::cout << std::format("Saving 2D: {}\n", name); + hist->Write(); + } + for (const auto& [name, hist] : m_hists3D) + { + std::cout << std::format("Saving 3D: {}\n", name); + hist->Write(); + } + for (const auto& [name, hist] : m_profiles) + { + std::cout << std::format("Saving Profile: {}\n", name); + hist->Write(); + } + output_file->Close(); + + std::cout << std::format("Results saved to: {}", output_filename) << std::endl; +} diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.h b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.h new file mode 100644 index 0000000000..7317ae1488 --- /dev/null +++ b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.h @@ -0,0 +1,386 @@ +#ifndef QVECCALIB_H +#define QVECCALIB_H + +#include "QVecDefs.h" + +// ==================================================================== +// ROOT Includes +// ==================================================================== + +#include +#include +#include +#include +#include +#include + +// ==================================================================== +// Standard C++ Includes +// ==================================================================== +#include +#include +#include + +/** + * @class QVecCalib + * @brief Orchestrates the multi-pass anisotropy calibration for the sEPD Q-vectors. + * + * This class implements a three-pass correction procedure designed to remove + * detector-induced biases from the sEPD event plane reconstruction: + * * 1. **ComputeRecentering**: Calculates the first-order vector offsets (re-centering) + * per centrality bin. + * 2. **ApplyRecentering**: Applies the first-order offsets and computes the + * second-order whitening/flattening matrix. + * 3. **ApplyFlattening**: Applies the full correction (re-centering + flattening) + * to produce final validated event planes. + * * The class manages event-level selections based on charge-centrality correlations + * and handles the exclusion of "bad" (hot/cold/dead) sEPD channels. + */ +class QVecCalib +{ + public: + // The constructor takes the configuration + QVecCalib(std::string input_file, std::string input_hist, std::string input_Q_calib, int pass, long long events, std::string output_dir) + : m_input_file(std::move(input_file)) + , m_input_hist(std::move(input_hist)) + , m_input_Q_calib(std::move(input_Q_calib)) + , m_pass(static_cast(pass)) + , m_events_to_process(events) + , m_output_dir(std::move(output_dir)) + { + } + + void run() + { + setup_chain(); + process_QA_hist(); + init_hists(); + process_events(); + save_results(); + } + + enum class Pass + { + ComputeRecentering, + ApplyRecentering, + ApplyFlattening + }; + + private: + + struct CorrectionData : public QVecShared::CorrectionMoments + { + std::array, 2> X_matrix{}; + }; + + static constexpr size_t m_cent_bins = QVecShared::CENT_BINS; + static constexpr auto m_harmonics = QVecShared::HARMONICS; + double m_cent_low = -0.5; + double m_cent_high = 79.5; + + // Holds all correction data + // key: [Cent][Harmonic][Subdetector] + // Harmonics {2,3,4} -> 3 elements + // Subdetectors {S,N} -> 2 elements + std::array, m_harmonics.size()>, m_cent_bins> m_correction_data; + + // Store harmonic orders and subdetectors for easy iteration + static constexpr std::array m_subdetectors = {QVecShared::Subdetector::S, QVecShared::Subdetector::N}; + static constexpr std::array m_components = {QVecShared::QComponent::X, QVecShared::QComponent::Y}; + + struct EventData + { + int event_id{0}; // NOLINT(misc-non-private-member-variables-in-classes) + double event_zvertex{0.0}; // NOLINT(misc-non-private-member-variables-in-classes) + double event_centrality{0.0}; // NOLINT(misc-non-private-member-variables-in-classes) + double sepd_totalcharge{0.0}; // NOLINT(misc-non-private-member-variables-in-classes) + + std::array, m_harmonics.size()> q_vectors; // NOLINT(misc-non-private-member-variables-in-classes) + + void reset() + { + for (auto& q_vec_harmonic : q_vectors) + { + for (auto& q_vec : q_vec_harmonic) + { + q_vec.x = 0.0; + q_vec.y = 0.0; + } + } + } + + std::vector* sepd_channel{nullptr}; // NOLINT(misc-non-private-member-variables-in-classes) + std::vector* sepd_charge{nullptr}; // NOLINT(misc-non-private-member-variables-in-classes) + std::vector* sepd_phi{nullptr}; // NOLINT(misc-non-private-member-variables-in-classes) + }; + + struct AverageHists + { + TProfile* S_x_avg{nullptr}; + TProfile* S_y_avg{nullptr}; + TProfile* N_x_avg{nullptr}; + TProfile* N_y_avg{nullptr}; + + TH3* Q_S{nullptr}; + TH3* Q_N{nullptr}; + + TH3* Psi{nullptr}; + }; + + struct RecenterHists + { + TProfile* S_x_corr_avg{nullptr}; + TProfile* S_y_corr_avg{nullptr}; + TProfile* N_x_corr_avg{nullptr}; + TProfile* N_y_corr_avg{nullptr}; + + TProfile* S_xx_avg{nullptr}; + TProfile* S_yy_avg{nullptr}; + TProfile* S_xy_avg{nullptr}; + TProfile* N_xx_avg{nullptr}; + TProfile* N_yy_avg{nullptr}; + TProfile* N_xy_avg{nullptr}; + + TH3* Psi_corr{nullptr}; + }; + + struct FlatteningHists + { + TProfile* S_x_corr2_avg{nullptr}; + TProfile* S_y_corr2_avg{nullptr}; + TProfile* N_x_corr2_avg{nullptr}; + TProfile* N_y_corr2_avg{nullptr}; + + TProfile* S_xx_corr_avg{nullptr}; + TProfile* S_yy_corr_avg{nullptr}; + TProfile* S_xy_corr_avg{nullptr}; + + TProfile* N_xx_corr_avg{nullptr}; + TProfile* N_yy_corr_avg{nullptr}; + TProfile* N_xy_corr_avg{nullptr}; + + TH3* Psi_corr2{nullptr}; + }; + + // --- Member Variables --- + EventData m_event_data; + std::unique_ptr m_chain; + + // Configuration stored as members + std::string m_input_file; + std::string m_input_hist; + std::string m_input_Q_calib; + Pass m_pass{0}; + long long m_events_to_process; + std::string m_output_dir; + + // Hists + std::map> m_hists1D; + std::map> m_hists2D; + std::map> m_hists3D; + std::map> m_profiles; + + // sEPD Bad Channels + std::unordered_set m_bad_channels; + + double m_sEPD_min_avg_charge_threshold{1}; + double m_sEPD_sigma_threshold{3}; + + // --- Private Helper Methods --- + +/** + * @brief Sets up a TChain and performs structural validation of the input ROOT file. + * * Verifies file existence, ensures the requested TTree exists, and checks for + * non-zero entries before returning a configured chain. + * * @param input_filepath Path to the input .root file. + * @param tree_name_in_file Name of the TTree inside the file. + * @return std::unique_ptr A configured TChain, or nullptr if validation fails. + */ + std::unique_ptr setupTChain(const std::string& input_filepath, const std::string& tree_name_in_file); + +/** + * @brief Orchestrates the TChain initialization and branch configuration. + * * Sets the branch statuses and addresses for event-level data (ID, centrality, charge) + * and sEPD tower-level data (channel, charge, phi) needed for the calibration. + */ + void setup_chain(); + +/** + * @brief Initializes all output histograms and profiles. + * * Dynamically generates histogram names using the shared naming helper based on + * the current calibration pass (e.g., adding "_corr" or "_corr2" suffixes). + */ + void init_hists(); + +/** + * @brief Safely retrieves a ROOT object from a file and returns a managed unique_ptr. + * * Performs a dynamic_cast to verify the requested type T and Clones the object + * to ensure it remains valid after the source file is closed. + * * @tparam T The ROOT class type (e.g., TProfile, TH3). + * @param file Pointer to the source TFile. + * @param name The name of the object within the file. + * @return std::unique_ptr A managed pointer to the cloned object. + * @throws std::runtime_error If the object is not found or type mismatch occurs. + */ + template + std::unique_ptr load_and_clone(TFile* file, const std::string& name); + +/** + * @brief Loads the results of previous passes from a calibration file. + * * Populates the internal correction data structure with averages and/or + * matrices required for the current processing pass. + */ + void load_correction_data(); + +/** + * @brief High-level orchestrator for the event processing phase. + * * If the current pass requires existing calibration data (Recentering or Flattening), + * it triggers the data loading sequence before starting the main event loop. + */ + void process_events(); + +/** + * @brief Validates events based on sEPD total charge vs. centrality correlation. + * * Compares the current event's total charge against the 3-sigma bounds derived + * from the QA histograms to reject pile-up or background-dominated events. + * @return True if the event falls within the acceptable charge window. + */ + bool process_event_check(); + +/** + * @brief Performs the primary tower-by-tower Q-vector calculation and normalization. + * * Loops through sEPD channels, excludes bad channels, calculates the raw Q-vector + * for all harmonics, and normalizes the results by the total arm charge. + * @return True if both South and North arms have non-zero total charge. + */ + bool process_sEPD(); + +/** + * @brief Primary event loop orchestrator. + * * Iterates through the TChain entries, performs event selection, executes + * normalization/re-centering/flattening logic based on the current pass, + * and fills the output histograms. + */ + void run_event_loop(); + +/** + * @brief Finalizes the analysis by writing all histograms to the output ROOT file. + * * Creates the output directory if it does not exist and ensures all 1D, 2D, + * 3D histograms and TProfiles are safely persisted to disk. + */ + void save_results() const; + +/** + * @brief Calculates and fills profiles for the initial Q-vector averages. + * @param cent The event centrality. + * @param q_S The South arm normalized Q-vector. + * @param q_N The North arm normalized Q-vector. + * @param h Reference to the cache of profiles for the first pass. + */ + static void process_averages(double cent, QVecShared::QVec q_S, QVecShared::QVec q_N, const AverageHists& h); + +/** + * @brief Applies re-centering offsets and fills profiles for second-moment calculation. + * @param cent The event centrality. + * @param h_idx Harmonic index. + * @param q_S The South arm normalized Q-vector. + * @param q_N The North arm normalized Q-vector. + * @param h Reference to the cache of profiles for the second pass. + */ + void process_recentering(double cent, size_t h_idx, QVecShared::QVec q_S, QVecShared::QVec q_N, const RecenterHists& h); + +/** + * @brief Applies the full correction (re-centering + flattening) for validation. + * @param cent The event centrality. + * @param h_idx Harmonic index. + * @param q_S The South arm normalized Q-vector. + * @param q_N The North arm normalized Q-vector. + * @param h Reference to the cache of profiles for the third pass. + */ + void process_flattening(double cent, size_t h_idx, QVecShared::QVec q_S, QVecShared::QVec q_N, const FlatteningHists& h); + +/** + * @brief Calculates the 2x2 anisotropy correction (whitening) matrix. + * * This matrix transforms the elliptical Q-vector distribution into a circularly + * symmetric (isotropic) distribution. It effectively corrects for detector + * acceptance effects and gain non-uniformities by normalizing the second-order + * moments of the Q-vector. + * * @param xx The second moment. + * @param yy The second moment. + * @param xy The cross-moment. + * @param n Harmonic order (used for error logging context). + * @param cent_bin Centrality bin (used for error logging context). + * @param det_label Detector label ("S" or "N"). + * @return std::array, 2> The 2x2 correction matrix. + */ + std::array, 2> calculate_flattening_matrix(double xx, double yy, double xy, int n, int cent_bin, const std::string& det_label); + + +/** + * @brief Computes 1st-order re-centering offsets for a specific centrality bin. + * * Extracts average Q-vector components from histograms and stores them in the + * correction data matrix for use in subsequent processing passes. + * * @param cent_bin The index of the centrality bin. + * @param h_idx The index of the harmonic order in the harmonics array. + */ + void compute_averages(size_t cent_bin, int h_idx); + +/** + * @brief Computes re-centering parameters and solves the flattening matrices. + * * Extracts the re-centered second moments from the profiles and populates the + * internal CorrectionData matrix with calculated flattening coefficients. + * @param cent_bin The centrality bin index. + * @param h_idx The harmonic index. + */ + void compute_recentering(size_t cent_bin, int h_idx); + +/** + * @brief Logs the final corrected moments to verify successful flattening. + * @param cent_bin The centrality bin index. + * @param n The harmonic order. + */ + void print_flattening(size_t cent_bin, int n) const; + +/** + * @brief Prepares a vector of pointers to histograms used in the first pass. + * @return A vector of AverageHists structs, indexed by harmonic. + */ + std::vector prepare_average_hists(); + +/** + * @brief Prepares a vector of pointers to histograms used in the second pass. + * @return A vector of RecenterHists structs, indexed by harmonic. + */ + std::vector prepare_recenter_hists(); + +/** + * @brief Prepares a vector of pointers to histograms used in the third pass. + * @return A vector of FlatteningHists structs, indexed by harmonic. + */ + std::vector prepare_flattening_hists(); + +/** + * @brief Top-level driver for processing Quality Assurance histograms. + * * Loads the reference histogram file to identify bad channels and establish + * event-level charge thresholds as a function of centrality. + */ + void process_QA_hist(); + +/** + * @brief Identifies and catalogs "Bad" (Hot, Cold, or Dead) sEPD channels. + * * Uses a reference charge histogram to compute Z-scores based on mean charge + * per radial bin. Channels exceeding the sigma threshold are added to the internal exclusion set. + * * @param file Pointer to the open TFile containing QA histograms. + */ + void process_bad_channels(TFile* file); + +/** + * @brief Establishes sEPD charge-cut thresholds for event selection. + * * Uses the 2D total charge vs. centrality distribution to derive mean and + * sigma values, generating a 1D profile of the selection window. + * @param file Pointer to the open QA histogram file. + */ + void process_sEPD_event_thresholds(TFile* file); +}; + +#endif // QVECCALIB_H diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h b/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h new file mode 100644 index 0000000000..f74c62f574 --- /dev/null +++ b/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h @@ -0,0 +1,55 @@ +#ifndef QVECDEFS_H +#define QVECDEFS_H + +#include +#include +#include +#include + +namespace QVecShared +{ + static constexpr size_t CENT_BINS = 8; + static constexpr std::array HARMONICS = {2, 3, 4}; + + enum class Subdetector + { + S, // South + N // North + }; + + enum class QComponent + { + X, + Y + }; + + struct QVec + { + double x{0.0}; + double y{0.0}; + }; + + struct CorrectionMoments + { + QVec avg_Q{}; // Mean Q vector + double avg_Q_xx{0.0}; + double avg_Q_yy{0.0}; + double avg_Q_xy{0.0}; + }; + + /** + * @brief Centralized helper to generate standard histogram names for the sEPD calibration. + * * Standardizes the naming convention: h_sEPD_Q_{det}_{var}_{n}{suffix}_avg + * * @param det The detector arm ("S" for South, "N" for North). + * @param var The physics variable or moment (e.g., "x", "y", "xx", "xy"). + * @param n The harmonic order (e.g., 2, 3, 4). + * @param suffix Optional pass-specific suffix (e.g., "_corr", "_corr2"). + * @return A formatted std::string representing the ROOT histogram name. + */ + inline std::string get_hist_name(const std::string& det, const std::string& var, int n, const std::string& suffix = "") + { + return std::format("h_sEPD_Q_{}_{}_{}{}_avg", det, var, n, suffix); + } +} // namespace QVecShared + +#endif // QVECDEFS_H diff --git a/calibrations/sepd/sepd_eventplanecalib/autogen.sh b/calibrations/sepd/sepd_eventplanecalib/autogen.sh new file mode 100644 index 0000000000..dea267bbfd --- /dev/null +++ b/calibrations/sepd/sepd_eventplanecalib/autogen.sh @@ -0,0 +1,8 @@ +#!/bin/sh +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +(cd $srcdir; aclocal -I ${OFFLINE_MAIN}/share;\ +libtoolize --force; automake -a --add-missing; autoconf) + +$srcdir/configure "$@" diff --git a/calibrations/sepd/sepd_eventplanecalib/configure.ac b/calibrations/sepd/sepd_eventplanecalib/configure.ac new file mode 100644 index 0000000000..4abe4ad0ce --- /dev/null +++ b/calibrations/sepd/sepd_eventplanecalib/configure.ac @@ -0,0 +1,16 @@ +AC_INIT(sepd_eventplanecalib,[1.00]) +AC_CONFIG_SRCDIR([configure.ac]) + +AM_INIT_AUTOMAKE +AC_PROG_CXX(CC g++) + +LT_INIT([disable-static]) + +dnl no point in suppressing warnings people should +dnl at least see them, so here we go for g++: -Wall +if test $ac_cv_prog_gxx = yes; then + CXXFLAGS="$CXXFLAGS -Wshadow -Wall -Wextra -Werror" +fi + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc b/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc new file mode 100644 index 0000000000..be03589d40 --- /dev/null +++ b/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc @@ -0,0 +1,289 @@ +#include "sEPD_TreeGen.h" + +// -- c++ +#include +#include + +// -- event +#include + +// -- Fun4All +#include +#include + +// -- Nodes +#include +#include + +// -- Calo +#include +#include +#include + +// -- Vtx +#include +#include + +// -- MB +#include +#include +#include + +// -- sEPD +#include + +//____________________________________________________________________________.. +sEPD_TreeGen::sEPD_TreeGen(const std::string &name) + : SubsysReco(name) +{ +} + +//____________________________________________________________________________.. +int sEPD_TreeGen::Init([[maybe_unused]] PHCompositeNode *topNode) +{ + Fun4AllServer *se = Fun4AllServer::instance(); + se->Print("NODETREE"); + + unsigned int bins_sepd_totalcharge{100}; + double sepd_totalcharge_low{0}; + double sepd_totalcharge_high{2e4}; + + unsigned int bins_centrality{80}; + double centrality_low{-0.5}; + double centrality_high{79.5}; + + hSEPD_Charge = std::make_unique("hSEPD_Charge", "|z| < 10 cm and MB; Channel; Avg Charge", m_sepd_channels, 0, m_sepd_channels); + hSEPD_Charge->Sumw2(); + + h2SEPD_totalcharge_centrality = std::make_unique("h2SEPD_totalcharge_centrality", "|z| < 10 cm and MB; sEPD Total Charge; Centrality [%]", bins_sepd_totalcharge, sepd_totalcharge_low, sepd_totalcharge_high, bins_centrality, centrality_low, centrality_high); + + m_output = std::make_unique(m_outtree_name.c_str(), "recreate"); + m_output->cd(); + + // TTree + m_tree = std::make_unique("T", "T"); + m_tree->SetDirectory(m_output.get()); + m_tree->Branch("event_id", &m_data.event_id); + m_tree->Branch("event_zvertex", &m_data.event_zvertex); + m_tree->Branch("event_centrality", &m_data.event_centrality); + m_tree->Branch("sepd_totalcharge", &m_data.sepd_totalcharge); + m_tree->Branch("sepd_channel", &m_data.sepd_channel); + m_tree->Branch("sepd_charge", &m_data.sepd_charge); + m_tree->Branch("sepd_phi", &m_data.sepd_phi); + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int sEPD_TreeGen::process_event_check(PHCompositeNode *topNode) +{ + GlobalVertexMap *vertexmap = findNode::getClass(topNode, "GlobalVertexMap"); + + if (!vertexmap) + { + std::cout << PHWHERE << "GlobalVertexMap Node missing, doing nothing." << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + if (!vertexmap->empty()) + { + GlobalVertex *vtx = vertexmap->begin()->second; + m_data.event_zvertex = vtx->get_z(); + } + + MinimumBiasInfo *m_mb_info = findNode::getClass(topNode, "MinimumBiasInfo"); + if (!m_mb_info) + { + std::cout << PHWHERE << "MinimumBiasInfo Node missing, doing nothing." << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + // skip event if not minimum bias + if (!m_mb_info->isAuAuMinimumBias()) + { + if (Verbosity() > 2) + { + std::cout << "Event: " << m_data.event_id << ", Not Min Bias, Skipping" << std::endl; + } + return Fun4AllReturnCodes::ABORTEVENT; + } + + // skip event if zvtx is too large + if (std::abs(m_data.event_zvertex) >= m_cuts.m_zvtx_max) + { + if (Verbosity() > 2) + { + std::cout << "Event: " << m_data.event_id << ", Z: " << m_data.event_zvertex << " cm, Skipping" << std::endl; + } + return Fun4AllReturnCodes::ABORTEVENT; + } + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int sEPD_TreeGen::process_centrality(PHCompositeNode *topNode) +{ + CentralityInfo *centInfo = findNode::getClass(topNode, "CentralityInfo"); + if (!centInfo) + { + std::cout << PHWHERE << "CentralityInfo Node missing, doing nothing." << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + m_data.event_centrality = centInfo->get_centile(CentralityInfo::PROP::mbd_NS) * 100; + + // skip event if centrality is too peripheral + if (!std::isfinite(m_data.event_centrality) || m_data.event_centrality < 0 || m_data.event_centrality >= m_cuts.m_cent_max) + { + if(Verbosity() > 2) + { + std::cout << "Event: " << m_data.event_id << ", Centrality: " << m_data.event_centrality << ", Skipping" << std::endl; + } + return Fun4AllReturnCodes::ABORTEVENT; + } + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int sEPD_TreeGen::process_sEPD(PHCompositeNode *topNode) +{ + TowerInfoContainer *towerinfosEPD = findNode::getClass(topNode, "TOWERINFO_CALIB_SEPD"); + if (!towerinfosEPD) + { + std::cout << PHWHERE << "TOWERINFO_CALIB_SEPD Node missing, doing nothing." << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + EpdGeom *epdgeom = findNode::getClass(topNode, "TOWERGEOM_EPD"); + if (!epdgeom) + { + std::cout << PHWHERE << "TOWERGEOM_EPD Node missing, doing nothing." << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + // sepd + unsigned int sepd_channels = towerinfosEPD->size(); + + if(sepd_channels != m_sepd_channels) + { + if (Verbosity() > 2) + { + std::cout << "Event: " << m_data.event_id << ", SEPD Channels = " << sepd_channels << " != " << m_sepd_channels << std::endl; + } + return Fun4AllReturnCodes::ABORTEVENT; + } + + m_data.sepd_totalcharge = 0; + + for (unsigned int channel = 0; channel < sepd_channels; ++channel) + { + unsigned int key = TowerInfoDefs::encode_epd(channel); + + TowerInfo *tower = towerinfosEPD->get_tower_at_channel(channel); + + double charge = tower->get_energy(); + bool isZS = tower->get_isZS(); + double phi = epdgeom->get_phi(key); + + // exclude ZS + // exclude Nmips + if (isZS || charge < m_cuts.m_sepd_charge_min) + { + continue; + } + + m_data.sepd_channel.push_back(channel); + m_data.sepd_charge.push_back(charge); + m_data.sepd_phi.push_back(phi); + + m_data.sepd_totalcharge += charge; + + hSEPD_Charge->Fill(channel, charge); + } + + h2SEPD_totalcharge_centrality->Fill(m_data.sepd_totalcharge, m_data.event_centrality); + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int sEPD_TreeGen::process_event(PHCompositeNode *topNode) +{ + EventHeader *eventInfo = findNode::getClass(topNode, "EventHeader"); + if (!eventInfo) + { + std::cout << PHWHERE << "EventHeader Node missing, doing nothing." << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + m_data.event_id = eventInfo->get_EvtSequence(); + + if (Verbosity() > 1 && m_event % 20 == 0) + { + std::cout << "Progress: " << m_event << ", Global: " << m_data.event_id << std::endl; + } + ++m_event; + + int ret = process_event_check(topNode); + if (ret) + { + return ret; + } + + ret = process_centrality(topNode); + if (ret) + { + return ret; + } + + ret = process_sEPD(topNode); + if (ret) + { + return ret; + } + + // Fill the TTree + m_tree->Fill(); + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int sEPD_TreeGen::ResetEvent([[maybe_unused]] PHCompositeNode *topNode) +{ + // Event + m_data.event_id = -1; + m_data.event_zvertex = 9999; + m_data.event_centrality = 9999; + + // sEPD + m_data.sepd_totalcharge = 0; + m_data.sepd_channel.clear(); + m_data.sepd_charge.clear(); + m_data.sepd_phi.clear(); + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int sEPD_TreeGen::End([[maybe_unused]] PHCompositeNode *topNode) +{ + std::cout << "sEPD_TreeGen::End" << std::endl; + + TFile output(m_outfile_name.c_str(), "recreate"); + output.cd(); + + hSEPD_Charge->Write(); + h2SEPD_totalcharge_centrality->Write(); + + output.Close(); + + // TTree + m_output->cd(); + m_tree->Write(); + m_output->Close(); + + return Fun4AllReturnCodes::EVENT_OK; +} diff --git a/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.h b/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.h new file mode 100644 index 0000000000..225e62cc8f --- /dev/null +++ b/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.h @@ -0,0 +1,177 @@ +#ifndef SEPD_TREEGEN_H +#define SEPD_TREEGEN_H + +// -- sPHENIX +#include + +// -- c++ +#include +#include +#include +#include +#include + +// -- ROOT +#include +#include +#include +#include + +class PHCompositeNode; + +/** + * @class sEPD_TreeGen + * @brief SubsysReco module to produce flat TTrees and QA histograms for sEPD calibration. + * + * This module extracts event-level info (vertex, centrality) and sEPD tower-level info + * (charge, phi, channel ID), applying basic event selections (Minimum Bias, Z-vertex) + * and tower-level cuts (charge threshold, zero-suppression). + */ +class sEPD_TreeGen : public SubsysReco +{ + public: + /** + * @brief Constructor for sEPD_TreeGen. + * @param name The name assigned to this SubsysReco module. + */ + explicit sEPD_TreeGen(const std::string &name = "sEPD_TreeGen"); + + /** + * @brief Initializes the module and creates the output TTree and QA histograms. + * @param topNode Pointer to the node tree. + * @return Fun4All return code. + */ + int Init(PHCompositeNode *topNode) override; + + /** + * @brief Main event-by-event processing method. + * @details Orchestrates event checks, centrality retrieval, sEPD tower processing, + * and fills the TTree for valid events. + * @param topNode Pointer to the node tree. + * @return Fun4All return code. + */ + int process_event(PHCompositeNode *topNode) override; + + /** + * @brief Resets event-level data structures before the next event. + * @param topNode Pointer to the node tree. + * @return Fun4All return code. + */ + int ResetEvent(PHCompositeNode *topNode) override; + + /** + * @brief Finalizes the module, writing all histograms and the TTree to disk. + * @param topNode Pointer to the node tree. + * @return Fun4All return code. + */ + int End(PHCompositeNode *topNode) override; + + /** + * @brief Sets the filename for the QA histograms ROOT file. + * @param file Output path for histograms. + */ + void set_filename(const std::string &file) + { + m_outfile_name = file; + } + + /** + * @brief Sets the filename for the flat TTree ROOT file. + * @param file Output path for the TTree. + */ + void set_tree_filename(const std::string &file) + { + m_outtree_name = file; + } + + /** + * @brief Sets the maximum allowed Z-vertex position for event selection. + * @param zvtx_max Maximum vertex Z in cm. + */ + void set_zvtx_max(double zvtx_max) + { + m_cuts.m_zvtx_max = zvtx_max; + } + + /** + * @brief Sets the minimum charge threshold for individual sEPD towers. + * @param charge_min Minimum charge to include a tower in the TTree. + */ + void set_sepd_charge_threshold(double charge_min) + { + m_cuts.m_sepd_charge_min= charge_min; + } + + /** + * @brief Sets the maximum centrality centile allowed for processing. + * @param cent_max Maximum centile (e.g., 80 for 0-80%). + */ + void set_cent_max(double cent_max) + { + m_cuts.m_cent_max = cent_max; + } + + private: + /** + * @brief Validates event-level conditions (GlobalVertex, Minimum Bias). + * @param topNode Pointer to the node tree. + * @return Fun4All return code. + */ + int process_event_check(PHCompositeNode *topNode); + + /** + * @brief Processes individual sEPD towers and calculates total charge. + * @details Applies tower cuts, fills QA histograms, and stores tower data in vectors. + * @param topNode Pointer to the node tree. + * @return Fun4All return code. + */ + int process_sEPD(PHCompositeNode *topNode); + + /** + * @brief Retrieves and validates centrality information. + * @param topNode Pointer to the node tree. + * @return Fun4All return code. + */ + int process_centrality(PHCompositeNode *topNode); + + int m_event{0}; + + std::string m_outfile_name{"test.root"}; + std::string m_outtree_name{"tree.root"}; + + static constexpr int m_sepd_channels = 744; + + // Cuts + struct Cuts + { + double m_zvtx_max{10}; /*cm*/ + double m_sepd_charge_min{0.2}; + double m_cent_max{80}; + }; + + Cuts m_cuts; + + struct EventData + { + int event_id{0}; + double event_zvertex{9999}; + double event_centrality{9999}; + + double sepd_totalcharge{-9999}; + + std::vector sepd_channel; + std::vector sepd_charge; + std::vector sepd_phi; + }; + + EventData m_data; + + std::unique_ptr m_output; + std::unique_ptr m_tree; + + std::unique_ptr hSEPD_Charge; + std::unique_ptr h2SEPD_totalcharge_centrality; +}; + + +#endif // SEPD_TREEGEN_H From 5b6afdad8db9020398c62b702844714cfdda6619 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Wed, 14 Jan 2026 12:19:16 -0500 Subject: [PATCH 056/393] add type 37: hijing O+O 0-15fm --- offline/framework/frog/CreateFileList.pl | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/offline/framework/frog/CreateFileList.pl b/offline/framework/frog/CreateFileList.pl index cc59083d8c..19b552b764 100755 --- a/offline/framework/frog/CreateFileList.pl +++ b/offline/framework/frog/CreateFileList.pl @@ -74,7 +74,8 @@ "33" => "JS pythia8 Jet ptmin = 15GeV", "34" => "JS pythia8 Jet ptmin = 50GeV", "35" => "JS pythia8 Jet ptmin = 70GeV", - "36" => "JS pythia8 Jet ptmin = 5GeV" + "36" => "JS pythia8 Jet ptmin = 5GeV", + "37" => "hijing O+O (0-15fm)" ); my %pileupdesc = ( @@ -926,6 +927,20 @@ $pileupstring = $pp_pileupstring; &commonfiletypes(); } + elsif ($prodtype == 37) + { + if (defined $nopileup) + { + $filenamestring = sprintf("sHijing_OO_0_15fm"); + } + else + { + $filenamestring = sprintf("sHijing_OO_0_15fm%s",$AuAu_pileupstring); + } + $notlike{$filenamestring} = ["pythia8" ,"single", "special"]; + $pileupstring = $AuAu_pileupstring; + &commonfiletypes(); + } else { From 85e50bbfda8ad12507ea9416f698e6c37857e7e6 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Wed, 14 Jan 2026 13:18:51 -0500 Subject: [PATCH 057/393] clang-tidy for HepMCJetTrigger --- generators/Herwig/HepMCTrigger/HepMCJetTrigger.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/generators/Herwig/HepMCTrigger/HepMCJetTrigger.cc b/generators/Herwig/HepMCTrigger/HepMCJetTrigger.cc index b22db801b5..792720a962 100644 --- a/generators/Herwig/HepMCTrigger/HepMCJetTrigger.cc +++ b/generators/Herwig/HepMCTrigger/HepMCJetTrigger.cc @@ -97,7 +97,10 @@ std::vector HepMCJetTrigger::findAllJets(HepMC::GenEvent* e1 { auto p = (*iter)->momentum(); auto pd = std::abs((*iter)->pdg_id()); - if( pd >=12 && pd <=18) continue; //keep jet in the expected behavioro + if (pd >= 12 && pd <= 18) + { + continue; // keep jet in the expected behavioro + } fastjet::PseudoJet pj(p.px(), p.py(), p.pz(), p.e()); pj.set_user_index((*iter)->barcode()); input.push_back(pj); @@ -124,7 +127,10 @@ int HepMCJetTrigger::jetsAboveThreshold(const std::vector& j for (const auto& j : jets) { float const pt = j.pt(); - if(std::abs(j.eta()) > 1.1) continue; + if (std::abs(j.eta()) > 1.1) + { + continue; + } if (pt > this->threshold) { n_good_jets++; From e3fffcefbc47645a4973ffab7209b6956eec9238 Mon Sep 17 00:00:00 2001 From: Anthony Denis Frawley Date: Wed, 14 Jan 2026 15:04:20 -0500 Subject: [PATCH 058/393] Fixed bug in logic for using existing parameter sets --- .../trackbase/AlignmentTransformation.cc | 121 ++++++++++-------- .../trackbase/AlignmentTransformation.h | 3 +- 2 files changed, 71 insertions(+), 53 deletions(-) diff --git a/offline/packages/trackbase/AlignmentTransformation.cc b/offline/packages/trackbase/AlignmentTransformation.cc index b3eb79fcb0..2e8647ab01 100644 --- a/offline/packages/trackbase/AlignmentTransformation.cc +++ b/offline/packages/trackbase/AlignmentTransformation.cc @@ -277,6 +277,7 @@ void AlignmentTransformation::createMap(PHCompositeNode* topNode) surf = surfMaps.getTpcSurface(this_hitsetkey, (unsigned int) sskey); Eigen::Vector3d localFrameTranslation(0, 0, 0); + use_module_tilt = false; if (test_layer < 4 || use_module_tilt_always) { // get the local frame translation that puts the local surface center at the tilted position after the local rotations are applied @@ -285,6 +286,9 @@ void AlignmentTransformation::createMap(PHCompositeNode* topNode) double this_radius = std::sqrt(this_center[0] * this_center[0] + this_center[1] * this_center[1]); float moduleRadius = TpcModuleRadii[side][sector][this_region]; // radius of the center of the module in cm localFrameTranslation = getTpcLocalFrameTranslation(moduleRadius, this_radius, sensorAngles) * 10; // cm to mm + + // set this flag for later use + use_module_tilt = true; } Acts::Transform3 transform; @@ -417,70 +421,83 @@ Acts::Transform3 AlignmentTransformation::newMakeTransform(const Surface& surf, Acts::Transform3 transform; //! If we read the survey parameters directly, that is the full transform if (survey) - { - //! The millepede affines will just be what was read in, which was the - //! survey information. This should (in principle) be equivalent to - //! the ideal position + any misalignment - transform = mpGlobalTranslationAffine * mpGlobalRotationAffine * mpLocalRotationAffine; - } - else - { - if (trkrid == TrkrDefs::tpcId) { - transform = mpGlobalTranslationAffine * mpGlobalRotationAffine * actsTranslationAffine * actsRotationAffine * mpLocalTranslationAffine * mpLocalRotationAffine; + //! The millepede affines will just be what was read in, which was the + //! survey information. This should (in principle) be equivalent to + //! the ideal position + any misalignment + transform = mpGlobalTranslationAffine * mpGlobalRotationAffine * mpLocalRotationAffine; } - else + else { - if(use_new_silicon_rotation_order) + // not survey. this is the normal usage + + if (trkrid == TrkrDefs::tpcId) { - transform = mpGlobalTranslationAffine * mpGlobalRotationAffine * actsTranslationAffine * actsRotationAffine * mpLocalTranslationAffine * mpLocalRotationAffine; + if(use_module_tilt) + { + // use module tilt transforms with local rotation followed by local translation + transform = mpGlobalTranslationAffine * mpGlobalRotationAffine * actsTranslationAffine * actsRotationAffine * mpLocalTranslationAffine * mpLocalRotationAffine; + } + else + { + // backward compatibility for old alignment params sets + transform = mpGlobalTranslationAffine * mpGlobalRotationAffine * actsTranslationAffine * mpLocalRotationAffine * actsRotationAffine; + } } else { - // needed for backward compatibility to existing local rotations in MVTX - transform = mpGlobalTranslationAffine * mpGlobalRotationAffine * actsTranslationAffine * mpLocalRotationAffine * actsRotationAffine; + // silicon and TPOT + if(use_new_silicon_rotation_order) + { + // use new transform order for silicon as well as TPC + transform = mpGlobalTranslationAffine * mpGlobalRotationAffine * actsTranslationAffine * actsRotationAffine * mpLocalTranslationAffine * mpLocalRotationAffine; + } + else + { + // needed for backward compatibility to existing local rotation parmeter sets in silicon + transform = mpGlobalTranslationAffine * mpGlobalRotationAffine * actsTranslationAffine * mpLocalRotationAffine * actsRotationAffine; + } } } - } - + if (localVerbosity) - { - Acts::Transform3 actstransform = actsTranslationAffine * actsRotationAffine; - - std::cout << "newMakeTransform" << std::endl; - std::cout << "Input sensorAngles: " << std::endl - << sensorAngles << std::endl; - std::cout << "Input sensorAnglesGlobal: " << std::endl - << sensorAnglesGlobal << std::endl; - std::cout << "Input translation: " << std::endl - << millepedeTranslation << std::endl; - std::cout << "mpLocalRotationAffine: " << std::endl - << mpLocalRotationAffine.matrix() << std::endl; - std::cout << "mpLocalTranslationAffine: " << std::endl - << mpLocalTranslationAffine.matrix() << std::endl; - std::cout << "actsRotationAffine: " << std::endl - << actsRotationAffine.matrix() << std::endl; - std::cout << "actsTranslationAffine: " << std::endl - << actsTranslationAffine.matrix() << std::endl; - std::cout << "mpRotationGlobalAffine: " << std::endl - << mpGlobalRotationAffine.matrix() << std::endl; - std::cout << "mpTranslationGlobalAffine: " << std::endl - << mpGlobalTranslationAffine.matrix() << std::endl; - std::cout << "Overall transform: " << std::endl - << transform.matrix() << std::endl; - std::cout << "overall * idealinv " << std::endl - << (transform * actstransform.inverse()).matrix() << std::endl; - std::cout << "overall - ideal " << std::endl; - for (int test = 0; test < transform.matrix().rows(); test++) { - for (int test2 = 0; test2 < transform.matrix().cols(); test2++) - { - std::cout << transform(test, test2) - actstransform(test, test2) << ", "; - } - std::cout << std::endl; + Acts::Transform3 actstransform = actsTranslationAffine * actsRotationAffine; + + std::cout << "newMakeTransform" << std::endl; + std::cout << "Input sensorAngles: " << std::endl + << sensorAngles << std::endl; + std::cout << "Input sensorAnglesGlobal: " << std::endl + << sensorAnglesGlobal << std::endl; + std::cout << "Input translation: " << std::endl + << millepedeTranslation << std::endl; + std::cout << "mpLocalRotationAffine: " << std::endl + << mpLocalRotationAffine.matrix() << std::endl; + std::cout << "mpLocalTranslationAffine: " << std::endl + << mpLocalTranslationAffine.matrix() << std::endl; + std::cout << "actsRotationAffine: " << std::endl + << actsRotationAffine.matrix() << std::endl; + std::cout << "actsTranslationAffine: " << std::endl + << actsTranslationAffine.matrix() << std::endl; + std::cout << "mpRotationGlobalAffine: " << std::endl + << mpGlobalRotationAffine.matrix() << std::endl; + std::cout << "mpTranslationGlobalAffine: " << std::endl + << mpGlobalTranslationAffine.matrix() << std::endl; + std::cout << "Overall transform: " << std::endl + << transform.matrix() << std::endl; + std::cout << "overall * idealinv " << std::endl + << (transform * actstransform.inverse()).matrix() << std::endl; + std::cout << "overall - ideal " << std::endl; + for (int test = 0; test < transform.matrix().rows(); test++) + { + for (int test2 = 0; test2 < transform.matrix().cols(); test2++) + { + std::cout << transform(test, test2) - actstransform(test, test2) << ", "; + } + std::cout << std::endl; + } } - } - + return transform; } diff --git a/offline/packages/trackbase/AlignmentTransformation.h b/offline/packages/trackbase/AlignmentTransformation.h index 7055d6c65a..e8eb3882d1 100644 --- a/offline/packages/trackbase/AlignmentTransformation.h +++ b/offline/packages/trackbase/AlignmentTransformation.h @@ -128,7 +128,8 @@ class AlignmentTransformation bool use_new_silicon_rotation_order = false; bool use_module_tilt_always = false; - + bool use_module_tilt = false; // starts at false in all cases + bool use_intt_survey_geometry = false; Acts::Transform3 newMakeTransform(const Surface& surf, Eigen::Vector3d& millepedeTranslation, Eigen::Vector3d& sensorAngles, Eigen::Vector3d& localFrameTranslation, Eigen::Vector3d& sensorAnglesGlobal, unsigned int trkrid, bool survey); From d7d58e14c6c7b42e216013978b7c7678a0319892 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Wed, 14 Jan 2026 21:22:31 -0500 Subject: [PATCH 059/393] this change fixes the tpc drift velocity being set to zero --- generators/PHPythia8/PHPythia8.cc | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/generators/PHPythia8/PHPythia8.cc b/generators/PHPythia8/PHPythia8.cc index 9aa14d4684..64010072ad 100644 --- a/generators/PHPythia8/PHPythia8.cc +++ b/generators/PHPythia8/PHPythia8.cc @@ -45,8 +45,12 @@ PHPythia8::PHPythia8(const std::string &name) std::string thePath(charPath); thePath += "/xmldoc/"; + // the pythia8 ctor messes with the formatting, so we save the cout state here + // and restore it later + std::ios old_state(nullptr); + old_state.copyfmt(std::cout); m_Pythia8.reset(new Pythia8::Pythia(thePath)); - + std::cout.copyfmt(old_state); m_Pythia8ToHepMC.reset(new HepMC::Pythia8ToHepMC()); m_Pythia8ToHepMC->set_store_proc(true); m_Pythia8ToHepMC->set_store_pdf(true); @@ -92,8 +96,19 @@ int PHPythia8::Init(PHCompositeNode *topNode) // print out seed so we can make this is reproducible std::cout << "PHPythia8 random seed: " << seed << std::endl; + + // this is empirical - something in the pythia8::init() method interferes + // with our macros (it sets the tpc drift verlocity back to 0) + // not the feintest idea right now what this could be + // but saving the old cout state and restoring it aftwerwards + // gets our tpc drift velocity back + std::ios old_state(nullptr); + old_state.copyfmt(std::cout); + m_Pythia8->init(); + std::cout.copyfmt(old_state); + return Fun4AllReturnCodes::EVENT_OK; } From 04e747faa66d7639f44ca83177286d894b5b6437 Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Thu, 15 Jan 2026 14:17:58 +0000 Subject: [PATCH 060/393] =?UTF-8?q?=F0=9F=93=9D=20Add=20docstrings=20to=20?= =?UTF-8?q?`fix-tpc-drift-pythia8`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Docstrings generation was requested by @pinkenburg. * https://github.com/sPHENIX-Collaboration/coresoftware/pull/4111#issuecomment-3752587001 The following files were modified: * `generators/PHPythia8/PHPythia8.cc` --- generators/PHPythia8/PHPythia8.cc | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/generators/PHPythia8/PHPythia8.cc b/generators/PHPythia8/PHPythia8.cc index 64010072ad..1be3aa9edc 100644 --- a/generators/PHPythia8/PHPythia8.cc +++ b/generators/PHPythia8/PHPythia8.cc @@ -33,6 +33,20 @@ #include #include // for operator<<, endl +/** + * @brief Construct a PHPythia8 generator instance and configure HepMC conversion. + * + * Initializes the Pythia8 engine using the path from the environment variable + * `PYTHIA8`, configures a HepMC::Pythia8ToHepMC converter to store process, + * PDF, and cross-section information, and sets the default embedding ID to 1. + * The constructor preserves and restores std::cout formatting around Pythia8 + * construction to avoid altering global stream state. + * + * If `PYTHIA8` is not set, an error message is printed and the Pythia8 instance + * remains uninitialized. + * + * @param name Name forwarded to the SubsysReco base class (module instance name). + */ PHPythia8::PHPythia8(const std::string &name) : SubsysReco(name) { @@ -59,6 +73,18 @@ PHPythia8::PHPythia8(const std::string &name) PHHepMCGenHelper::set_embedding_id(1); // default embedding ID to 1 } +/** + * @brief Initialize the Pythia8 generator, configure nodes, and seed the RNG. + * + * Performs module initialization: reads an optional configuration file and any + * queued Pythia command strings, creates the required node tree under the + * provided top-level node, sets Pythia's random seed (mapped from PHRandomSeed + * into Pythia's valid range) and prints it for reproducibility, then calls + * Pythia8::init(). + * + * @param topNode Top-level PHCompositeNode under which generator nodes are created. + * @return int Fun4All return code; returns Fun4AllReturnCodes::EVENT_OK on success. + */ int PHPythia8::Init(PHCompositeNode *topNode) { if (!m_ConfigFileName.empty()) @@ -336,4 +362,4 @@ void PHPythia8::register_trigger(PHPy8GenTrigger *theTrigger) std::cout << "PHPythia8::registerTrigger - trigger " << theTrigger->GetName() << " registered" << std::endl; } m_RegisteredTriggers.push_back(theTrigger); -} +} \ No newline at end of file From 1fe3891016c2d54c2234f779caaf090aff5989ea Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Thu, 15 Jan 2026 09:24:08 -0500 Subject: [PATCH 061/393] Fix missing newline at end of PHPythia8.cc Add newline at the end of PHPythia8.cc file --- generators/PHPythia8/PHPythia8.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generators/PHPythia8/PHPythia8.cc b/generators/PHPythia8/PHPythia8.cc index 1be3aa9edc..56f2b2bb9c 100644 --- a/generators/PHPythia8/PHPythia8.cc +++ b/generators/PHPythia8/PHPythia8.cc @@ -362,4 +362,4 @@ void PHPythia8::register_trigger(PHPy8GenTrigger *theTrigger) std::cout << "PHPythia8::registerTrigger - trigger " << theTrigger->GetName() << " registered" << std::endl; } m_RegisteredTriggers.push_back(theTrigger); -} \ No newline at end of file +} From 69de5bb2327e92359b07d420c31cc82be47c0e73 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Thu, 15 Jan 2026 14:30:14 -0500 Subject: [PATCH 062/393] do not read flow angles if flow afterburner was not run --- offline/framework/ffamodules/HeadReco.cc | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/offline/framework/ffamodules/HeadReco.cc b/offline/framework/ffamodules/HeadReco.cc index 75e879fdff..17214758c8 100644 --- a/offline/framework/ffamodules/HeadReco.cc +++ b/offline/framework/ffamodules/HeadReco.cc @@ -84,10 +84,13 @@ int HeadReco::process_event(PHCompositeNode *topNode) { evtheader->set_ImpactParameter(hi->impact_parameter()); evtheader->set_EventPlaneAngle(hi->event_plane_angle()); - for (unsigned int n = 1; n <= 6; ++n) - { - evtheader->set_FlowPsiN(n, genevt->get_flow_psi(n)); - } + if (! genevt->get_flow_psi_map().empty()) + { + for (unsigned int n = 1; n <= 6; ++n) + { + evtheader->set_FlowPsiN(n, genevt->get_flow_psi(n)); + } + } evtheader->set_eccentricity(hi->eccentricity()); evtheader->set_ncoll(hi->Ncoll()); evtheader->set_npart(hi->Npart_targ() + hi->Npart_proj()); From 3d192990eaa8a96baa4b7b9e604c0287b7dd666d Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Thu, 15 Jan 2026 14:34:23 -0500 Subject: [PATCH 063/393] return NAN if flow psi vector is empty --- generators/phhepmc/PHHepMCGenEventv1.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/generators/phhepmc/PHHepMCGenEventv1.cc b/generators/phhepmc/PHHepMCGenEventv1.cc index bc8eef6f41..3aa7515365 100644 --- a/generators/phhepmc/PHHepMCGenEventv1.cc +++ b/generators/phhepmc/PHHepMCGenEventv1.cc @@ -9,6 +9,7 @@ #include #include // for cout +#include #include // for map #include #include // for swap @@ -109,6 +110,6 @@ float PHHepMCGenEventv1::get_flow_psi(unsigned int n) const return it->second; } - std::cout << "PHHepMCGenEventv1::get_flow_psi - Warning - requested reaction plane angle psi_n for n=" << n << " does not exist. Returning 0.0" << std::endl; - return 0.0F; + std::cout << "PHHepMCGenEventv1::get_flow_psi - Warning - requested reaction plane angle psi_n for n=" << n << " does not exist. Returning NAN" << std::endl; + return std::numeric_limits::quiet_NaN(); } From b209d8585c6ec207b4c60215f8996bb185be86ad Mon Sep 17 00:00:00 2001 From: Michael Peters Date: Thu, 15 Jan 2026 16:34:44 -0500 Subject: [PATCH 064/393] dEdxFitter initial commit --- calibrations/tpc/dEdx/GlobaldEdxFitter.h | 404 +++++++++++++++++++++++ calibrations/tpc/dEdx/Makefile.am | 49 +++ calibrations/tpc/dEdx/autogen.sh | 8 + calibrations/tpc/dEdx/bethe_bloch.h | 208 ++++++++++++ calibrations/tpc/dEdx/configure.ac | 16 + calibrations/tpc/dEdx/dEdxFitter.cc | 228 +++++++++++++ calibrations/tpc/dEdx/dEdxFitter.h | 88 +++++ calibrations/tpc/dEdx/test_sample_size.C | 185 +++++++++++ 8 files changed, 1186 insertions(+) create mode 100644 calibrations/tpc/dEdx/GlobaldEdxFitter.h create mode 100644 calibrations/tpc/dEdx/Makefile.am create mode 100755 calibrations/tpc/dEdx/autogen.sh create mode 100644 calibrations/tpc/dEdx/bethe_bloch.h create mode 100644 calibrations/tpc/dEdx/configure.ac create mode 100644 calibrations/tpc/dEdx/dEdxFitter.cc create mode 100644 calibrations/tpc/dEdx/dEdxFitter.h create mode 100644 calibrations/tpc/dEdx/test_sample_size.C diff --git a/calibrations/tpc/dEdx/GlobaldEdxFitter.h b/calibrations/tpc/dEdx/GlobaldEdxFitter.h new file mode 100644 index 0000000000..267e30f0a4 --- /dev/null +++ b/calibrations/tpc/dEdx/GlobaldEdxFitter.h @@ -0,0 +1,404 @@ +#ifndef GLOBALDEDXFITTER_H +#define GLOBALDEDXFITTER_H + +#include "bethe_bloch.h" +#include "TF1.h" +#include "TF2.h" +#include "TF3.h" +#include "TChain.h" +#include "TGraph.h" +#include "Math/Minimizer.h" +#include "Math/Functor.h" +#include "Math/Factory.h" + +const double m_pi = 0.1396; // GeV +const double m_K = 0.4937; // GeV +const double m_p = 0.9382; // GeV +const double m_d = 1.876; // GeV + +class GlobaldEdxFitter +{ + public: + GlobaldEdxFitter(double xmin = 10., double xmax = 50.) + { + min_norm = xmin; + max_norm = xmax; + }; + void processResidualData(size_t ntracks = 200000, + size_t skip = 0, + std::string infile="/sphenix/tg/tg01/hf/mjpeters/run53877_tracks/track_output_53877*.root_resid.root"); + void addTrack(double trk_dEdx, double trk_p); + size_t getNtracks() + { + return dEdx.size(); + } + + double get_fitquality(double norm, double ZS_loss = 0.); + double get_fitquality_new(double A); + TF1* create_TF1(std::string name); + TF2* create_TF2(std::string name); + TF3* create_TF3_new(std::string name); + double get_minimum(); + double get_minimum_new(); + std::pair get_minimum_ZS(); + void set_range(double xmin, double xmax, double ZSmin, double ZSmax) + { + min_norm = xmin; + max_norm = xmax; + min_ZS = ZSmin; + max_ZS = ZSmax; + } + void reset() + { + p.clear(); + dEdx.clear(); + betagamma.clear(); + } + std::vector get_betagamma(double A); + TGraph* graph_vsbetagamma(double A); + TGraph* graph_vsp(); + private: + std::vector p; + std::vector dEdx; + std::vector betagamma; + + double get_fitquality_functor(const double* x); + + double get_fitquality_wrapper(double* x, double* p); + double get_fitquality_wrapper_ZS(double* x, double* p); + double get_fitquality_wrapper_new(double* x, double* p); + double min_norm = 10.; + double max_norm = 50.; + double min_ZS = 0.; + double max_ZS = 200.; + double min_B = 8.; + double max_B = 12.; +}; + +void GlobaldEdxFitter::processResidualData(size_t ntracks, size_t skip, std::string infile) +{ + std::unique_ptr t = std::make_unique(); + t->Add((infile+"?#residualtree").c_str()); +// TFile* f = TFile::Open(infile.c_str()); +// TTree* t = (TTree*)f->Get("residualtree"); + + float px; + float py; + float pz; + float dedx; + float eta; + int nmaps; + int nintt; + int ntpc; + float dcaxy; + + t->SetBranchAddress("px",&px); + t->SetBranchAddress("py",&py); + t->SetBranchAddress("pz",&pz); + t->SetBranchAddress("dedx",&dedx); + t->SetBranchAddress("eta",&eta); + t->SetBranchAddress("nmaps",&nmaps); + t->SetBranchAddress("nintt",&nintt); + t->SetBranchAddress("ntpc",&ntpc); + t->SetBranchAddress("dcaxy",&dcaxy); + + for(size_t entry=skip; entry<(skip+ntracks); entry++) + { + //if(entry==t->GetEntries()-1) break; + if(entry % 1000 == 0) std::cout << entry << std::endl; + t->GetEntry(entry); + if(nmaps>0 && nintt>0 && fabs(eta)<1. && dcaxy<0.5 && ntpc>30) + { + p.push_back(sqrt(px*px+py*py+pz*pz)); + dEdx.push_back(dedx); + } + } + std::cout << "number of good tracks: " << p.size() << std::endl; + //f->Close(); +} + +void GlobaldEdxFitter::addTrack(double trk_dEdx, double trk_p) +{ + dEdx.push_back(trk_dEdx); + p.push_back(trk_p); +} + +double GlobaldEdxFitter::get_fitquality_new(double A) +{ + double chi2 = 0.; + double ndf = -1.; + + double pi_chi2 = 0.; + double K_chi2 = 0.; + double p_chi2 = 0.; + double d_chi2 = 0.; + double pi_ndf = -1.; + double K_ndf = -1.; + double p_ndf = -1.; + double d_ndf = -1.; + + for(size_t i=0; i GlobaldEdxFitter::get_betagamma(double A) +{ + std::vector betagamma; + for(size_t i=0; iGetMinimumXYZ(minA,minB,minC); + delete f; + return std::make_tuple(minA,minB,minC); +*/ + ROOT::Math::Minimizer* minimizer = ROOT::Math::Factory::CreateMinimizer("Minuit2"); + minimizer->SetMaxFunctionCalls(1000000); + minimizer->SetMaxIterations(10000); + minimizer->SetTolerance(0.1); + minimizer->SetPrintLevel(1); + ROOT::Math::Functor f(this,&GlobaldEdxFitter::get_fitquality_functor,1); + double step[1] = {.01}; + double variable[1] = {20.}; + minimizer->SetFunction(f); + minimizer->SetVariable(0,"A",variable[0],step[0]); + minimizer->Minimize(); + const double *xs = minimizer->X(); + return xs[0]; +} + +double GlobaldEdxFitter::get_minimum() +{ + TF1* f = create_TF1("temp"); + f->SetNpx(1000); + double minX = f->GetMinimumX(); + delete f; + return minX; +} + +std::pair GlobaldEdxFitter::get_minimum_ZS() +{ + TF2* f = create_TF2("temp"); + double minX; + double minY; + f->GetMinimumXY(minX,minY); + delete f; + return std::make_pair(minX,minY); +} + +TGraph* GlobaldEdxFitter::graph_vsbetagamma(double A) +{ + std::vector betagamma = get_betagamma(A); + TGraph* g = new TGraph(dEdx.size(),betagamma.data(),dEdx.data()); + return g; +} + +TGraph* GlobaldEdxFitter::graph_vsp() +{ + TGraph* g = new TGraph(dEdx.size(),p.data(),dEdx.data()); + return g; +} + +#endif diff --git a/calibrations/tpc/dEdx/Makefile.am b/calibrations/tpc/dEdx/Makefile.am new file mode 100644 index 0000000000..03dda87d60 --- /dev/null +++ b/calibrations/tpc/dEdx/Makefile.am @@ -0,0 +1,49 @@ +AUTOMAKE_OPTIONS = foreign + +AM_CPPFLAGS = \ + -I$(includedir) \ + -I$(OFFLINE_MAIN)/include \ + -isystem$(ROOTSYS)/include + +AM_LDFLAGS = \ + -L$(libdir) \ + -L$(OFFLINE_MAIN)/lib \ + -L$(OFFLINE_MAIN)/lib64 + +pkginclude_HEADERS = \ + dEdxFitter.h \ + GlobaldEdxFitter.h \ + bethe_bloch.h + +lib_LTLIBRARIES = \ + libdedxfitter.la + +libdedxfitter_la_SOURCES = \ + dEdxFitter.cc + +libdedxfitter_la_LIBADD = \ + -lphool \ + -ltrack_io \ + -lg4detectors \ + -ltrackbase_historic_io \ + -ltrack_reco \ + -lglobalvertex \ + -lSubsysReco + +BUILT_SOURCES = testexternals.cc + +noinst_PROGRAMS = \ + testexternals + +testexternals_SOURCES = testexternals.cc +testexternals_LDADD = libdedxfitter.la + +testexternals.cc: + echo "//*** this is a generated file. Do not commit, do not edit" > $@ + echo "int main()" >> $@ + echo "{" >> $@ + echo " return 0;" >> $@ + echo "}" >> $@ + +clean-local: + rm -f $(BUILT_SOURCES) diff --git a/calibrations/tpc/dEdx/autogen.sh b/calibrations/tpc/dEdx/autogen.sh new file mode 100755 index 0000000000..dea267bbfd --- /dev/null +++ b/calibrations/tpc/dEdx/autogen.sh @@ -0,0 +1,8 @@ +#!/bin/sh +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +(cd $srcdir; aclocal -I ${OFFLINE_MAIN}/share;\ +libtoolize --force; automake -a --add-missing; autoconf) + +$srcdir/configure "$@" diff --git a/calibrations/tpc/dEdx/bethe_bloch.h b/calibrations/tpc/dEdx/bethe_bloch.h new file mode 100644 index 0000000000..3b134224ee --- /dev/null +++ b/calibrations/tpc/dEdx/bethe_bloch.h @@ -0,0 +1,208 @@ +#ifndef BETHE_BLOCH_H +#define BETHE_BLOCH_H + +#include "TMath.h" + +namespace dedx_constants +{ + // hadron masses + constexpr double m_pi = 0.1396; // GeV + constexpr double m_K = 0.4937; // GeV + constexpr double m_p = 0.9382; // GeV + constexpr double m_d = 1.876; // GeV + + // electron mass [eV] + constexpr double m_e = 511e3; + + // TPC gas fractions + constexpr double ar_frac = 0.75; + constexpr double cf4_frac = 0.2; + constexpr double isobutane_frac = 0.05; + + // Mean excitation [src: W. Blum, W. Riegler, L. Rolandi, "Particle Detection with Drift Chambers"] + constexpr double ar_I = 188; // eV + constexpr double cf4_I = 115; // eV + constexpr double isobutane_I = 48.3; // eV + + // Mean excitation of mixture approximated using Bragg additivity rule + constexpr double sphenix_I = ar_frac*ar_I + cf4_frac*cf4_I + isobutane_frac*isobutane_I; +} + +// Bethe-Bloch fit function, vs. betagamma +// A = normalization constant, equal to (ADC conversion)*4pi*n*Z^2*e^4/(m_e*c^2*4pi*epsilon_0^2) +// B = A*(ln(2*m_e/I)-1) - (zero-suppression loss factor) +const double bethe_bloch_new(const double betagamma, const double A, const double B, const double C) +{ + const double beta = betagamma/sqrt(1.+betagamma*betagamma); + + return A/(beta*beta)*TMath::Log(betagamma) + A/(beta*beta)*B - A - C; +} + +const double bethe_bloch_new_2D(const double betagamma, const double A, const double B) +{ + const double beta = betagamma/sqrt(1.+betagamma*betagamma); + + return A/(beta*beta)*(2.*TMath::Log(2.*dedx_constants::m_e/dedx_constants::sphenix_I * betagamma) - beta*beta) - B; +} + +const double bethe_bloch_new_1D(const double betagamma, const double A) +{ + const double beta = betagamma/sqrt(1.+betagamma*betagamma); + + return A/(beta*beta)*(2.*TMath::Log(2.*dedx_constants::m_e/dedx_constants::sphenix_I * betagamma) - beta*beta); +} + +// dE/dx for one gas species, up to normalization +const double bethe_bloch_species(const double betagamma, const double I) +{ + const double m_e = 511e3; // eV + + const double beta = betagamma/sqrt(1.+betagamma*betagamma); + + return 1./(beta*beta)*(TMath::Log(2.*m_e/I*betagamma*betagamma)-beta*beta); +} + +// dE/dx for TPC gas mixture, up to normalization +const double bethe_bloch_total(const double betagamma) +{ + return dedx_constants::ar_frac * bethe_bloch_species(betagamma,dedx_constants::ar_I) + + dedx_constants::cf4_frac * bethe_bloch_species(betagamma,dedx_constants::cf4_I) + + dedx_constants::isobutane_frac * bethe_bloch_species(betagamma,dedx_constants::isobutane_I); +} + +Double_t bethe_bloch_new_wrapper(Double_t* x, Double_t* par) +{ + Double_t betagamma = x[0]; + Double_t A = par[0]; + Double_t B = par[1]; + Double_t C = par[2]; + + return bethe_bloch_new(betagamma,A,B,C); +} + +Double_t bethe_bloch_new_2D_wrapper(Double_t* x, Double_t* par) +{ + Double_t betagamma = x[0]; + Double_t A = par[0]; + Double_t B = par[1]; + + return bethe_bloch_new_2D(betagamma,A,B); +} + +Double_t bethe_bloch_new_1D_wrapper(Double_t* x, Double_t* par) +{ + Double_t betagamma = x[0]; + Double_t A = par[0]; + + return bethe_bloch_new_1D(betagamma,A); +} + +// wrapper function for TF1 constructor, for fitting +Double_t bethe_bloch_wrapper(Double_t* ln_bg, Double_t* par) +{ + Double_t betagamma = exp(ln_bg[0]); + + Double_t norm = par[0]; + + return norm * bethe_bloch_total(betagamma); +} + +Double_t bethe_bloch_vs_p_wrapper(Double_t* x, Double_t* par) +{ + Double_t p = x[0]; + Double_t norm = par[0]; + Double_t m = par[1]; + + return norm * bethe_bloch_total(fabs(p)/m); +} + +Double_t bethe_bloch_vs_logp_wrapper(Double_t* x, Double_t* par) +{ + Double_t p = pow(10.,x[0]); + Double_t norm = par[0]; + Double_t m = par[1]; + + return norm * bethe_bloch_total(fabs(p)/m); +} + +Double_t bethe_bloch_vs_p_wrapper_ZS(Double_t* x, Double_t* par) +{ + Double_t p = x[0]; + Double_t norm = par[0]; + Double_t m = par[1]; + Double_t ZS_loss = par[2]; + + return norm * bethe_bloch_total(fabs(p)/m) - ZS_loss; +} + +Double_t bethe_bloch_vs_p_wrapper_new(Double_t* x, Double_t* par) +{ + Double_t p = x[0]; + Double_t A = par[0]; + Double_t B = par[1]; + Double_t C = par[2]; + Double_t m = par[3]; + + return bethe_bloch_new(fabs(p)/m,A,B,C); +} + +Double_t bethe_bloch_vs_p_wrapper_new_2D(Double_t* x, Double_t* par) +{ + Double_t p = x[0]; + Double_t A = par[0]; + Double_t B = par[1]; + Double_t m = par[2]; + + return bethe_bloch_new_2D(fabs(p)/m,A,B); +} + +Double_t bethe_bloch_vs_p_wrapper_new_1D(Double_t* x, Double_t* par) +{ + Double_t p = x[0]; + Double_t A = par[0]; + Double_t m = par[1]; + + return bethe_bloch_new_1D(fabs(p)/m,A); +} + +Double_t bethe_bloch_vs_logp_wrapper_ZS(Double_t* x, Double_t* par) +{ + Double_t p = pow(10.,x[0]); + Double_t norm = par[0]; + Double_t m = par[1]; + Double_t ZS_loss = par[2]; + + return norm * bethe_bloch_total(fabs(p)/m) - ZS_loss; +} + +Double_t bethe_bloch_vs_logp_wrapper_new(Double_t* x, Double_t* par) +{ + Double_t p = pow(10.,x[0]); + Double_t A = par[0]; + Double_t B = par[1]; + Double_t C = par[2]; + Double_t m = par[3]; + + return bethe_bloch_new(fabs(p)/m,A,B,C); +} + +Double_t bethe_bloch_vs_logp_wrapper_new_1D(Double_t* x, Double_t* par) +{ + Double_t p = pow(10.,x[0]); + Double_t A = par[0]; + Double_t m = par[1]; + + return bethe_bloch_new_1D(fabs(p)/m,A); +} + +// ratio of dE/dx between two particle species at the same momentum +// (useful for dE/dx peak fits) +const double dedx_ratio(const double p, const double m1, const double m2) +{ + const double betagamma1 = fabs(p)/m1; + const double betagamma2 = fabs(p)/m2; + + return bethe_bloch_total(betagamma1)/bethe_bloch_total(betagamma2); +} + +#endif // BETHE_BLOCH_H diff --git a/calibrations/tpc/dEdx/configure.ac b/calibrations/tpc/dEdx/configure.ac new file mode 100644 index 0000000000..aed59969a8 --- /dev/null +++ b/calibrations/tpc/dEdx/configure.ac @@ -0,0 +1,16 @@ +AC_INIT( dEdxFitter,[1.00]) +AC_CONFIG_SRCDIR([configure.ac]) + +AM_INIT_AUTOMAKE +AC_PROG_CXX(CC g++) + +LT_INIT([disable-static]) + +dnl no point in suppressing warnings people should +dnl at least see them, so here we go for g++: -Wall +if test $ac_cv_prog_gxx = yes; then + CXXFLAGS="$CXXFLAGS -Wall -Werror" +fi + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/calibrations/tpc/dEdx/dEdxFitter.cc b/calibrations/tpc/dEdx/dEdxFitter.cc new file mode 100644 index 0000000000..01c867f601 --- /dev/null +++ b/calibrations/tpc/dEdx/dEdxFitter.cc @@ -0,0 +1,228 @@ +#include "dEdxFitter.h" + +#include +#include +#include +#include +#include +#include + +#include + +//____________________________________ +dEdxFitter::dEdxFitter(const std::string &name): + SubsysReco(name) +{ + //initialize + fitter = std::make_unique(); +} + +//___________________________________ +int dEdxFitter::InitRun(PHCompositeNode *topNode) +{ + std::cout << PHWHERE << " Opening file " << _outfile << std::endl; + PHTFileServer::get().open( _outfile, "RECREATE"); + + return 0; +} + +//__________________________________ +//Call user instructions for every event +int dEdxFitter::process_event(PHCompositeNode *topNode) +{ + _event++; + if(_event%1000==0) std::cout << PHWHERE << "Events processed: " << _event << std::endl; + + GetNodes(topNode); + + if(Verbosity()>1) + { + std::cout << "--------------------------------" << std::endl; + std::cout << "event " << _event << std::endl; + } + + process_tracks(topNode); + + return 0; +} + +//_____________________________________ +void dEdxFitter::process_tracks(PHCompositeNode *topNode) +{ + + for(const auto &[key, track] : *_trackmap) + { + if(!track) continue; + + double trackID = track->get_id(); + if(Verbosity()>1) std::cout << "track ID " << trackID << std::endl; + if(std::isnan(track->get_x()) || + std::isnan(track->get_y()) || + std::isnan(track->get_z()) || + std::isnan(track->get_px()) || + std::isnan(track->get_py()) || + std::isnan(track->get_pz())) + { + std::cout << "malformed track:" << std::endl; + track->identify(); + std::cout << "skipping..." << std::endl; + continue; + } + + // ignore TPC-only tracks + if(!track->get_silicon_seed()) + { + if(Verbosity()>1) std::cout << "TPC-only track, skipping..." << std::endl; + continue; + } + + std::tuple nclus = get_nclus(track); + int nmaps = std::get<0>(nclus); + int nintt = std::get<1>(nclus); + int ntpc = std::get<2>(nclus); + + if(nmaps>=nmaps_cut && nintt>=nintt_cut && ntpc>=ntpc_cut && fabs(track->get_eta())addTrack(get_dedx(track),track->get_p()); + } + + if(fitter->getNtracks() > ntracks_to_fit) + { + minima.push_back(fitter->get_minimum()); + fitter->reset(); + } + } +} + +std::tuple dEdxFitter::get_nclus(SvtxTrack* track) +{ + int nmaps = 0; + int nintt = 0; + int ntpc = 0; + + for(auto it = track->get_silicon_seed()->begin_cluster_keys(); it != track->get_silicon_seed()->end_cluster_keys(); ++it) + { + TrkrDefs::cluskey ckey = *it; + auto trkrid = TrkrDefs::getTrkrId(ckey); + if(trkrid == TrkrDefs::mvtxId) + { + nmaps++; + } + else if(trkrid == TrkrDefs::inttId) + { + nintt++; + } + } + for(auto it = track->get_tpc_seed()->begin_cluster_keys(); it != track->get_tpc_seed()->end_cluster_keys(); ++it) + { + ntpc++; + } + + return std::make_tuple(nmaps,nintt,ntpc); +} + +double dEdxFitter::get_dedx(SvtxTrack* track) +{ + float layerThicknesses[4] = {0.0, 0.0, 0.0, 0.0}; + // These are randomly chosen layer thicknesses for the TPC, to get the + // correct region thicknesses in an easy to pass way to the helper fxn + layerThicknesses[0] = _tpcgeom->GetLayerCellGeom(7)->get_thickness(); + layerThicknesses[1] = _tpcgeom->GetLayerCellGeom(8)->get_thickness(); + layerThicknesses[2] = _tpcgeom->GetLayerCellGeom(27)->get_thickness(); + layerThicknesses[3] = _tpcgeom->GetLayerCellGeom(50)->get_thickness(); + + return TrackAnalysisUtils::calc_dedx(track->get_tpc_seed(), _clustermap, _geometry, layerThicknesses); +} + +double dEdxFitter::get_dcaxy(SvtxTrack* track) +{ + auto vertexit = _vertexmap->find(track->get_vertex_id()); + if(vertexit != _vertexmap->end()) + { + SvtxVertex* vtx = vertexit->second; + Acts::Vector3 vertex(vtx->get_x(),vtx->get_y(),vtx->get_z()); + auto dcapair = TrackAnalysisUtils::get_dca(track,vertex); + return dcapair.first.first; + } + else + { + return std::numeric_limits::quiet_NaN(); + } +} + +//___________________________________ +void dEdxFitter::GetNodes(PHCompositeNode *topNode) +{ + + _trackmap = findNode::getClass(topNode,"SvtxTrackMap"); + if(!_trackmap && _event<2) + { + std::cout << PHWHERE << " cannot find SvtxTrackMap" << std::endl; + } + + _clustermap = findNode::getClass(topNode,"TRKR_CLUSTER"); + if(!_clustermap && _event<2) + { + std::cout << PHWHERE << " cannot find TrkrClusterContainer TRKR_CLUSTER" << std::endl; + } + + _geometry = findNode::getClass(topNode,"ActsGeometry"); + if(!_geometry && _event<2) + { + std::cout << PHWHERE << " cannot find ActsGeometry" << std::endl; + } + + _tpcgeom = findNode::getClass(topNode,"TPCGEOMCONTAINER"); + if(!_tpcgeom && _event<2) + { + std::cout << PHWHERE << " cannot find PHG4TpcGeomContainer TPCGEOMCONTAINER" << std::endl; + } + + _vertexmap = findNode::getClass(topNode,"SvtxVertexMap"); + if(!_vertexmap && _event<2) + { + std::cout << PHWHERE << " cannot find SvtxVertexMap" << std::endl; + } +} + +//______________________________________ +int dEdxFitter::End(PHCompositeNode *topNode) +{ + if(minima.size()==0) + { + minima.push_back(fitter->get_minimum()); + } + + PHTFileServer::get().cd( _outfile ); + + double avg_minimum = 0.; + for(double m : minima) + { + avg_minimum += m; + } + avg_minimum /= (double)minima.size(); + + TF1* pi_band = new TF1("pi_band","bethe_bloch_new_1D(fabs(x)/[1],[0])"); + pi_band->SetParameter(0,avg_minimum); + pi_band->SetParameter(1,dedx_constants::m_pi); + pi_band->Write(); + + TF1* K_band = new TF1("K_band","bethe_bloch_new_1D(fabs(x)/[1],[0])"); + K_band->SetParameter(0,avg_minimum); + K_band->SetParameter(1,dedx_constants::m_K); + K_band->Write(); + + TF1* p_band = new TF1("p_band","bethe_bloch_new_1D(fabs(x)/[1],[0])"); + p_band->SetParameter(0,avg_minimum); + p_band->SetParameter(1,dedx_constants::m_p); + p_band->Write(); + + TF1* d_band = new TF1("d_band","bethe_bloch_new_1D(fabs(x)/[1],[0])"); + d_band->SetParameter(0,avg_minimum); + d_band->SetParameter(1,dedx_constants::m_d); + d_band->Write(); + + if(Verbosity()>0) std::cout << "dEdxFitter extracted minimum: " << avg_minimum << std::endl; + + return 0; +} diff --git a/calibrations/tpc/dEdx/dEdxFitter.h b/calibrations/tpc/dEdx/dEdxFitter.h new file mode 100644 index 0000000000..ca4fca546d --- /dev/null +++ b/calibrations/tpc/dEdx/dEdxFitter.h @@ -0,0 +1,88 @@ +#ifndef __DEDXFITTER_H__ +#define __DEDXFITTER_H__ + +#include +#include +#include +#include +#include +#include +#include + +#include "GlobaldEdxFitter.h" + +//Forward declerations +class PHCompositeNode; +class TFile; + +// dEdx fit analysis module +class dEdxFitter: public SubsysReco +{ + public: + //Default constructor + dEdxFitter(const std::string &name="dEdxFitter"); + + //Initialization, called for initialization + int InitRun(PHCompositeNode *); + + //Process Event, called for each event + int process_event(PHCompositeNode *); + + //End, write and close files + int End(PHCompositeNode *); + + //Change output filename + void set_filename(const char* file) + { if(file) _outfile = file; } + + void set_nmaps_cut(int nmaps) + { nmaps_cut = nmaps; } + + void set_nintt_cut(int nintt) + { nintt_cut = nintt; } + + void set_ntpc_cut(int ntpc) + { ntpc_cut = ntpc; } + + void set_eta_cut(float eta) + { eta_cut = eta; } + + void set_dcaxy_cut(float dcaxy) + { dcaxy_cut = dcaxy; } + + void set_ntracks_to_fit(size_t ntrk) + { ntracks_to_fit = ntrk; } + + private: + //output filename + std::string _outfile = "dedx_outfile.root"; + size_t _event; + + SvtxTrackMap* _trackmap = nullptr; + TrkrClusterContainer* _clustermap = nullptr; + ActsGeometry* _geometry = nullptr; + PHG4TpcGeomContainer* _tpcgeom = nullptr; + SvtxVertexMap* _vertexmap = nullptr; + + //Get all the nodes + void GetNodes(PHCompositeNode *); + + void process_tracks(PHCompositeNode *); + + int nmaps_cut = 1; + int nintt_cut = 1; + int ntpc_cut = 30; + float eta_cut = 1.; + float dcaxy_cut = 0.5; + + size_t ntracks_to_fit = 40000; + std::vector minima; + std::unique_ptr fitter; + + std::tuple get_nclus(SvtxTrack* track); + double get_dedx(SvtxTrack* track); + double get_dcaxy(SvtxTrack* track); + +}; + +#endif //* __DEDXFITTER_H__ *// diff --git a/calibrations/tpc/dEdx/test_sample_size.C b/calibrations/tpc/dEdx/test_sample_size.C new file mode 100644 index 0000000000..30d4b5cb00 --- /dev/null +++ b/calibrations/tpc/dEdx/test_sample_size.C @@ -0,0 +1,185 @@ +#include "GlobaldEdxFitter.h" + +void test_sample_size(std::string infile="/sphenix/tg/tg01/hf/mjpeters/run53877_tracks/track_output_53877_02613_53877-2613.root_resid.root") +{ + std::vector samplesizes = {1000,2000,5000,10000,20000,50000,100000,200000,500000,1000000};//,2000000,5000000}; + + const int n_samples = 20; + const float fluctuation_ymin = 5.; + const float fluctuation_ymax = 26.; + const int distribution_nbins = 30; + const float distribution_xmin = 5.; + const float distribution_xmax = 26.; + + + EColor base_color = kRed; + + std::vector> fitvalues_all; + std::vector fitvalues_avg; + std::vector fitvalues_stdev; + + std::vector fluctuations; + std::vector distributions; + + std::vector dist_h; + + std::vector> gfs; + + for(int i=0; i()); + + std::string fluctuation_canvasname = "fluctuations_"+std::to_string((int)floor(samplesizes[i])); + std::string distribution_canvasname = "distributions_"+std::to_string((int)floor(samplesizes[i])); + fluctuations.push_back(new TCanvas(fluctuation_canvasname.c_str(),fluctuation_canvasname.c_str(),600,600)); + distributions.push_back(new TCanvas(distribution_canvasname.c_str(),distribution_canvasname.c_str(),600,600)); + + for(int j=0;jprocessResidualData(floor(samplesizes[i]),j*samplesizes[i]); + double min = gfs[i]->get_minimum(); + std::cout << "minimum: " << min << std::endl; + fitvalues_all[i].push_back(min); + if(jreset(); +/* + tf1s[i]->cd(); + TF1* tf1copy = gfs[i]->create_TF1(("ntrk_"+std::to_string(samplesizes[i])).c_str()); + tf1copy->SetLineColor(base_color); + tf1copy->GetYaxis()->SetRangeUser(1.,tf1copy->GetMaximum()); + if(i==0) tf1copy->Draw(); + else tf1copy->Draw("SAME"); +*/ + } + } + + std::vector sample_index(n_samples); + std::iota(sample_index.begin(),sample_index.end(),0.); + + for(int i=0; icd(); + TGraph* g = new TGraph(n_samples,sample_index.data(),fitvalues_all[i].data()); + g->GetYaxis()->SetRangeUser(fluctuation_ymin,fluctuation_ymax); + g->SetMarkerStyle(kFullCircle); + g->SetMarkerSize(1.); + g->Draw("APL"); + + distributions[i]->cd(); + std::string hname = "h_"+std::to_string(floor(samplesizes[i])); + std::string htitle = "Distribution of fit results for sample size "+std::to_string(floor(samplesizes[i])); +/* + auto bounds = std::minmax_element(fitvalues_all[i].begin(),fitvalues_all[i].end()); + float lowerbound = floor(*bounds.first); + float upperbound = ceil(*bounds.second); +*/ + TH1F* h = new TH1F(hname.c_str(),htitle.c_str(),distribution_nbins,distribution_xmin,distribution_xmax); + for(int j=0; jFill(fitvalues_all[i][j]); + } + h->Draw(); + } + + for(int i=0; i errx(n_samples,0.); + + TCanvas* cg = new TCanvas("cg","sizes",600,600); + TGraph* g = new TGraphErrors(samplesizes.size(),samplesizes.data(),fitvalues_avg.data(),errx.data(),fitvalues_stdev.data()); + g->SetMarkerStyle(kFullCircle); + g->SetMarkerSize(1); + g->Draw("APL"); + cg->SetLogx(); + + TCanvas* cbg = new TCanvas("vsbetagamma","vsbetagamma",600,600); + TGraph* gbg = gfs.back()->graph_vsbetagamma(fitvalues_avg.back()); + gbg->SetMarkerStyle(kFullCircle); + gbg->SetMarkerSize(0.2); + gbg->Draw("AP"); + cbg->SetLogx(); + + double best_A = fitvalues_avg.back(); + + TF1* bethe = new TF1("bethebloch_vslnbg",bethe_bloch_new_1D_wrapper,0.,100.,2,1); + bethe->SetParameter(0,best_A); + bethe->SetNpx(1000); + bethe->Draw("SAME"); + + TF1* bethe_directfit = new TF1("bethebloch_directfit",bethe_bloch_new_1D_wrapper,0.,10.,1,1); + bethe_directfit->SetParameter(0,best_A); + bethe_directfit->SetLineColor(kBlue); + gbg->Fit(bethe_directfit); + double newbest_A = bethe_directfit->GetParameter(0); + std::cout << "new best: " << newbest_A << std::endl; + + TCanvas* cbands = new TCanvas("bands","bands",600,600); + TGraph* gp = gfs.back()->graph_vsp(); + gp->SetMarkerStyle(kFullCircle); + gp->SetMarkerSize(0.1); + gp->Draw("AP"); + cbands->SetLogx(); + + for(double mass : {m_pi, m_K, m_p, m_d}) + { + TF1* band = new TF1(("band_"+std::to_string(mass)).c_str(),bethe_bloch_vs_p_wrapper_new_1D,0.,10.,2,1); + band->SetParameter(0,best_A); + band->SetParameter(1,mass); + band->SetNpx(1000); + band->Draw("SAME"); + + TF1* directband = new TF1(("directband_"+std::to_string(mass)).c_str(),bethe_bloch_vs_p_wrapper_new_1D,0.,10.,2,1); + directband->SetLineColor(kBlue); + directband->SetParameters(best_A,mass); + directband->SetNpx(1000); + directband->Draw("SAME"); + } + + TCanvas* cb = new TCanvas("fullbands","fullbands",600,600); + TFile* f_h = TFile::Open("/sphenix/tg/tg01/hf/mjpeters/run53877_tracks/dedx/merged_dedx.root"); + TH2F* dedx_h = (TH2F*)f_h->Get("dedx_log_30"); + dedx_h->Draw("COLZ"); + cb->SetLogz(); + + for(float mass : {m_pi, m_K, m_p, m_d}) + { + TF1* band = new TF1(("band_"+std::to_string(mass)).c_str(),bethe_bloch_vs_logp_wrapper_new_1D,-1.,5.,2,1); + band->SetParameter(0,best_A); + band->SetParameter(1,mass); + band->Draw("SAME"); + + TF1* directband = new TF1(("directband_"+std::to_string(mass)).c_str(),bethe_bloch_vs_logp_wrapper_new_1D,-1.,5.,2,1); + directband->SetLineColor(kBlue); + directband->SetParameters(newbest_A,mass); + directband->SetNpx(1000); + directband->Draw("SAME"); + } + + TFile* fout = new TFile("dedxfitvals.root","RECREATE"); + for(auto& c : fluctuations) c->Write(); + for(auto& c : distributions) c->Write(); + cg->Write(); + cbg->Write(); + cbands->Write(); + cb->Write(); + +} From 2525b3b9ba9979a96302e781f8d9afe5c9f549e2 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Thu, 15 Jan 2026 16:37:33 -0500 Subject: [PATCH 065/393] restor cout state after every call to pythia8 --- generators/PHPythia8/PHPythia8.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/generators/PHPythia8/PHPythia8.cc b/generators/PHPythia8/PHPythia8.cc index 56f2b2bb9c..35f219771d 100644 --- a/generators/PHPythia8/PHPythia8.cc +++ b/generators/PHPythia8/PHPythia8.cc @@ -123,17 +123,13 @@ int PHPythia8::Init(PHCompositeNode *topNode) std::cout << "PHPythia8 random seed: " << seed << std::endl; - // this is empirical - something in the pythia8::init() method interferes - // with our macros (it sets the tpc drift verlocity back to 0) - // not the feintest idea right now what this could be - // but saving the old cout state and restoring it aftwerwards - // gets our tpc drift velocity back +// pythia again messes with the cout formatting std::ios old_state(nullptr); - old_state.copyfmt(std::cout); + old_state.copyfmt(std::cout); // save current state m_Pythia8->init(); - std::cout.copyfmt(old_state); + std::cout.copyfmt(old_state); // restore state to saved state return Fun4AllReturnCodes::EVENT_OK; } @@ -211,6 +207,9 @@ int PHPythia8::process_event(PHCompositeNode * /*topNode*/) bool passedGen = false; bool passedTrigger = false; // int genCounter = 0; +// pythia again messes with the cout formatting in its event loop + std::ios old_state(nullptr); + old_state.copyfmt(std::cout); // save current state while (!passedTrigger) { @@ -306,6 +305,8 @@ int PHPythia8::process_event(PHCompositeNode * /*topNode*/) ++m_EventCount; + std::cout.copyfmt(old_state); // restore state to saved state + // save statistics if (m_IntegralNode) { From bd1ae49728ee04de2524280630f1e9956fd76d7d Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Thu, 15 Jan 2026 17:04:52 -0500 Subject: [PATCH 066/393] restore cout state after each call to subsystem code --- offline/framework/fun4all/Fun4AllServer.cc | 9 +++++++-- offline/framework/fun4all/Fun4AllServer.h | 3 ++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/offline/framework/fun4all/Fun4AllServer.cc b/offline/framework/fun4all/Fun4AllServer.cc index 9d8779204e..9dc68afbb0 100644 --- a/offline/framework/fun4all/Fun4AllServer.cc +++ b/offline/framework/fun4all/Fun4AllServer.cc @@ -128,9 +128,9 @@ void Fun4AllServer::InitAll() { gSystem->IgnoreSignal((ESignals) i); } + m_saved_cout_state.copyfmt(std::cout); // save current state Fun4AllMonitoring::instance()->Snapshot("StartUp"); - std::string histomanagername; - histomanagername = Name() + "HISTOS"; + std::string histomanagername = Name() + "HISTOS"; ServerHistoManager = new Fun4AllHistoManager(histomanagername); registerHistoManager(ServerHistoManager); double uplim = NFRAMEWORKBINS - 0.5; @@ -245,6 +245,7 @@ int Fun4AllServer::registerSubsystem(SubsysReco *subsystem, const std::string &t << subsystem->Name() << std::endl; exit(1); } + std::cout.copyfmt(m_saved_cout_state); // restore cout to default formatting gROOT->cd(currdir.c_str()); if (iret) { @@ -576,6 +577,7 @@ int Fun4AllServer::process_event() ffamemtracker->Snapshot("Fun4AllServerProcessEvent"); #endif int retcode = Subsystem.first->process_event(Subsystem.second); + std::cout.copyfmt(m_saved_cout_state); // restore cout to default formatting #ifdef FFAMEMTRACKER ffamemtracker->Snapshot("Fun4AllServerProcessEvent"); #endif @@ -899,6 +901,7 @@ int Fun4AllServer::BeginRun(const int runno) for (iter = Subsystems.begin(); iter != Subsystems.end(); ++iter) { iret = BeginRunSubsystem(*iter); + std::cout.copyfmt(m_saved_cout_state); // restore cout to default formatting } for (; !NewSubsystems.empty(); NewSubsystems.pop_front()) { @@ -1092,6 +1095,7 @@ int Fun4AllServer::EndRun(const int runno) << (*iter).first->Name() << std::endl; exit(1); } + std::cout.copyfmt(m_saved_cout_state); // restore cout to default formatting } gROOT->cd(currdir.c_str()); @@ -1144,6 +1148,7 @@ int Fun4AllServer::End() << (*iter).first->Name() << std::endl; exit(1); } + std::cout.copyfmt(m_saved_cout_state); // restore cout to default formatting } gROOT->cd(currdir.c_str()); PHNodeIterator nodeiter(TopNode); diff --git a/offline/framework/fun4all/Fun4AllServer.h b/offline/framework/fun4all/Fun4AllServer.h index 0c7ea72c14..9f360b9502 100644 --- a/offline/framework/fun4all/Fun4AllServer.h +++ b/offline/framework/fun4all/Fun4AllServer.h @@ -143,7 +143,8 @@ class Fun4AllServer : public Fun4AllBase int eventnumber{0}; int eventcounter{0}; int keep_db_connected{0}; - + + std::ios m_saved_cout_state{nullptr}; std::vector ComplaintList; std::vector ResetNodeList {"DST"}; std::vector> Subsystems; From 04d53767137b4b03b84e5aeef28e911b6f304b1b Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Thu, 15 Jan 2026 17:22:26 -0500 Subject: [PATCH 067/393] resotre cout before sending abortrun --- generators/PHPythia8/PHPythia8.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/generators/PHPythia8/PHPythia8.cc b/generators/PHPythia8/PHPythia8.cc index 35f219771d..58b1f67e5d 100644 --- a/generators/PHPythia8/PHPythia8.cc +++ b/generators/PHPythia8/PHPythia8.cc @@ -285,6 +285,7 @@ int PHPythia8::process_event(PHCompositeNode * /*topNode*/) if (!success) { std::cout << "PHPythia8::process_event - Failed to add event to HepMC record!" << std::endl; + std::cout.copyfmt(old_state); // restore state to saved state return Fun4AllReturnCodes::ABORTRUN; } From 99b5ed4a7777366a35aa162f080cd2e03780fad8 Mon Sep 17 00:00:00 2001 From: mchiu-bnl Date: Thu, 15 Jan 2026 23:28:33 -0500 Subject: [PATCH 068/393] abort events with any mbd packet empty --- offline/packages/mbd/MbdCalib.cc | 2 +- offline/packages/mbd/MbdEvent.cc | 26 ++++++++++++++++++-------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/offline/packages/mbd/MbdCalib.cc b/offline/packages/mbd/MbdCalib.cc index 22b1e9930d..0b02908adb 100644 --- a/offline/packages/mbd/MbdCalib.cc +++ b/offline/packages/mbd/MbdCalib.cc @@ -1331,7 +1331,7 @@ int MbdCalib::Download_TimeRMS(const std::string& dbase_location) if ( _trms_y[0].empty() ) { - std::cout << PHWHERE << ", ERROR, unknown file type, " << dbase_location << std::endl; + std::cout << PHWHERE << ", WARNING, trms calib missing " << dbase_location << std::endl; _status = -1; return _status; // file not found } diff --git a/offline/packages/mbd/MbdEvent.cc b/offline/packages/mbd/MbdEvent.cc index 9b68641cbd..cdab537f45 100644 --- a/offline/packages/mbd/MbdEvent.cc +++ b/offline/packages/mbd/MbdEvent.cc @@ -451,6 +451,7 @@ int MbdEvent::SetRawData(std::array< CaloPacket *,2> &dstp, MbdRawContainer *bbc if (dstp[ipkt]) { _nsamples = dstp[ipkt]->iValue(0, "SAMPLES"); + { static bool printcount{true}; if ( printcount && Verbosity() > 0) @@ -460,6 +461,13 @@ int MbdEvent::SetRawData(std::array< CaloPacket *,2> &dstp, MbdRawContainer *bbc } } + // skip empty packets, corrupt event + if ( _nsamples == 0 ) + { + std::cout << PHWHERE << " ERROR, evt " << m_evt << " no samples in Packet " << pktid << std::endl; + return Fun4AllReturnCodes::ABORTEVENT; + } + m_xmitclocks[ipkt] = static_cast(dstp[ipkt]->iValue(0, "CLOCK")); m_femclocks[ipkt][0] = static_cast(dstp[ipkt]->iValue(0, "FEMCLOCK")); @@ -556,7 +564,6 @@ int MbdEvent::SetRawData(Event *event, MbdRawContainer *bbcraws, MbdPmtContainer // int flag_err = 0; Packet *p[2]{nullptr}; - int tot_nsamples{0}; for (int ipkt = 0; ipkt < 2; ipkt++) { int pktid = 1001 + ipkt; // packet id @@ -574,7 +581,7 @@ int MbdEvent::SetRawData(Event *event, MbdRawContainer *bbcraws, MbdPmtContainer if (p[ipkt]) { _nsamples = p[ipkt]->iValue(0, "SAMPLES"); - tot_nsamples += _nsamples; + { static int counter = 0; if ( counter<1 ) @@ -584,6 +591,15 @@ int MbdEvent::SetRawData(Event *event, MbdRawContainer *bbcraws, MbdPmtContainer counter++; } + // If packets are missing, stop processing event + if ( _nsamples == 0 ) + { + std::cout << PHWHERE << " ERROR, skipping evt " << m_evt << " nsamples = 0 " << pktid << std::endl; + delete p[ipkt]; + p[ipkt] = nullptr; + return Fun4AllReturnCodes::ABORTEVENT; + } + m_xmitclocks[ipkt] = static_cast(p[ipkt]->iValue(0, "CLOCK")); m_femclocks[ipkt][0] = static_cast(p[ipkt]->iValue(0, "FEMCLOCK")); @@ -628,12 +644,6 @@ int MbdEvent::SetRawData(Event *event, MbdRawContainer *bbcraws, MbdPmtContainer } } - // If packets are missing, stop processing - if ( tot_nsamples == 0 ) - { - return -1002; - } - // Fill MbdRawContainer int status = ProcessPackets(bbcraws); if ( _fitsonly ) From 8cbb1765262ad38a115da7eb771819a1fb82cc37 Mon Sep 17 00:00:00 2001 From: Michael Peters Date: Fri, 16 Jan 2026 00:37:54 -0500 Subject: [PATCH 069/393] coderabbit and clang-tidy fixes --- calibrations/tpc/dEdx/GlobaldEdxFitter.cc | 346 +++++++++++++++++++++ calibrations/tpc/dEdx/GlobaldEdxFitter.h | 353 +--------------------- calibrations/tpc/dEdx/Makefile.am | 3 +- calibrations/tpc/dEdx/bethe_bloch.h | 40 +-- calibrations/tpc/dEdx/dEdxFitter.cc | 61 ++-- calibrations/tpc/dEdx/dEdxFitter.h | 2 +- calibrations/tpc/dEdx/test_sample_size.C | 22 +- 7 files changed, 433 insertions(+), 394 deletions(-) create mode 100644 calibrations/tpc/dEdx/GlobaldEdxFitter.cc diff --git a/calibrations/tpc/dEdx/GlobaldEdxFitter.cc b/calibrations/tpc/dEdx/GlobaldEdxFitter.cc new file mode 100644 index 0000000000..8fa5045cba --- /dev/null +++ b/calibrations/tpc/dEdx/GlobaldEdxFitter.cc @@ -0,0 +1,346 @@ +#include "GlobaldEdxFitter.h" + +#include "bethe_bloch.h" +#include "TF1.h" +#include "TF2.h" +#include "TF3.h" +#include "TChain.h" +#include "TGraph.h" +#include "Math/Minimizer.h" +#include "Math/Functor.h" +#include "Math/Factory.h" + +void GlobaldEdxFitter::processResidualData(const std::string& infile, size_t ntracks, size_t skip) +{ + std::unique_ptr t = std::make_unique(); + t->Add((infile+"?#residualtree").c_str()); +// TFile* f = TFile::Open(infile.c_str()); +// TTree* t = (TTree*)f->Get("residualtree"); + + float px; + float py; + float pz; + float dedx; + float eta; + int nmaps; + int nintt; + int ntpc; + float dcaxy; + + t->SetBranchAddress("px",&px); + t->SetBranchAddress("py",&py); + t->SetBranchAddress("pz",&pz); + t->SetBranchAddress("dedx",&dedx); + t->SetBranchAddress("eta",&eta); + t->SetBranchAddress("nmaps",&nmaps); + t->SetBranchAddress("nintt",&nintt); + t->SetBranchAddress("ntpc",&ntpc); + t->SetBranchAddress("dcaxy",&dcaxy); + + size_t total_entries = t->GetEntriesFast(); + + for(size_t entry=skip; entry<(skip+ntracks); entry++) + { + if(entry==total_entries) + { + break; + } + if(entry % 1000 == 0) + { + std::cout << entry << std::endl; + } + t->GetEntry(entry); + if(nmaps>0 && nintt>0 && fabs(eta)<1. && dcaxy<0.5 && ntpc>30) + { + p.push_back(sqrt(px*px+py*py+pz*pz)); + dEdx.push_back(dedx); + } + } + std::cout << "number of good tracks: " << p.size() << std::endl; + //f->Close(); +} + +void GlobaldEdxFitter::addTrack(double trk_dEdx, double trk_p) +{ + dEdx.push_back(trk_dEdx); + p.push_back(trk_p); +} + +double GlobaldEdxFitter::get_fitquality_new(double A) +{ + //double chi2 = 0.; + //double ndf = -1.; + + double pi_chi2 = 0.; + double K_chi2 = 0.; + double p_chi2 = 0.; + double d_chi2 = 0.; + double pi_ndf = -1.; + double K_ndf = -1.; + double p_ndf = -1.; + double d_ndf = -1.; + + for(size_t i=0; i GlobaldEdxFitter::get_betagamma(double A) +{ + std::vector betagamma; + for(size_t i=0; iGetMinimumXYZ(minA,minB,minC); + delete f; + return std::make_tuple(minA,minB,minC); +*/ + ROOT::Math::Minimizer* minimizer = ROOT::Math::Factory::CreateMinimizer("Minuit2"); + minimizer->SetMaxFunctionCalls(1000000); + minimizer->SetMaxIterations(10000); + minimizer->SetTolerance(0.1); + minimizer->SetPrintLevel(1); + ROOT::Math::Functor f(this,&GlobaldEdxFitter::get_fitquality_functor,1); + double step[1] = {.01}; + double variable[1] = {20.}; + minimizer->SetFunction(f); + minimizer->SetVariable(0,"A",variable[0],step[0]); + minimizer->Minimize(); + const double *xs = minimizer->X(); + delete minimizer; + return xs[0]; +} + +double GlobaldEdxFitter::get_minimum() +{ + TF1* f = create_TF1("temp"); + f->SetNpx(1000); + double minX = f->GetMinimumX(); + delete f; + return minX; +} + +std::pair GlobaldEdxFitter::get_minimum_ZS() +{ + TF2* f = create_TF2("temp"); + double minX; + double minY; + f->GetMinimumXY(minX,minY); + delete f; + return std::make_pair(minX,minY); +} + +TGraph* GlobaldEdxFitter::graph_vsbetagamma(double A) +{ + std::vector betagamma = get_betagamma(A); + TGraph* g = new TGraph(dEdx.size(),betagamma.data(),dEdx.data()); + return g; +} + +TGraph* GlobaldEdxFitter::graph_vsp() +{ + TGraph* g = new TGraph(dEdx.size(),p.data(),dEdx.data()); + return g; +} diff --git a/calibrations/tpc/dEdx/GlobaldEdxFitter.h b/calibrations/tpc/dEdx/GlobaldEdxFitter.h index 267e30f0a4..122ec94769 100644 --- a/calibrations/tpc/dEdx/GlobaldEdxFitter.h +++ b/calibrations/tpc/dEdx/GlobaldEdxFitter.h @@ -11,11 +11,6 @@ #include "Math/Functor.h" #include "Math/Factory.h" -const double m_pi = 0.1396; // GeV -const double m_K = 0.4937; // GeV -const double m_p = 0.9382; // GeV -const double m_d = 1.876; // GeV - class GlobaldEdxFitter { public: @@ -24,9 +19,9 @@ class GlobaldEdxFitter min_norm = xmin; max_norm = xmax; }; - void processResidualData(size_t ntracks = 200000, - size_t skip = 0, - std::string infile="/sphenix/tg/tg01/hf/mjpeters/run53877_tracks/track_output_53877*.root_resid.root"); + void processResidualData(const std::string& infile, + size_t ntracks = 200000, + size_t skip = 0); void addTrack(double trk_dEdx, double trk_p); size_t getNtracks() { @@ -35,9 +30,9 @@ class GlobaldEdxFitter double get_fitquality(double norm, double ZS_loss = 0.); double get_fitquality_new(double A); - TF1* create_TF1(std::string name); - TF2* create_TF2(std::string name); - TF3* create_TF3_new(std::string name); + TF1* create_TF1(const std::string& name); + TF2* create_TF2(const std::string& name); + TF3* create_TF3_new(const std::string& name); double get_minimum(); double get_minimum_new(); std::pair get_minimum_ZS(); @@ -52,7 +47,6 @@ class GlobaldEdxFitter { p.clear(); dEdx.clear(); - betagamma.clear(); } std::vector get_betagamma(double A); TGraph* graph_vsbetagamma(double A); @@ -60,13 +54,12 @@ class GlobaldEdxFitter private: std::vector p; std::vector dEdx; - std::vector betagamma; double get_fitquality_functor(const double* x); - double get_fitquality_wrapper(double* x, double* p); - double get_fitquality_wrapper_ZS(double* x, double* p); - double get_fitquality_wrapper_new(double* x, double* p); + double get_fitquality_wrapper(double* x, double* par); + double get_fitquality_wrapper_ZS(double* x, double* par); + double get_fitquality_wrapper_new(double* x, double* par); double min_norm = 10.; double max_norm = 50.; double min_ZS = 0.; @@ -75,330 +68,4 @@ class GlobaldEdxFitter double max_B = 12.; }; -void GlobaldEdxFitter::processResidualData(size_t ntracks, size_t skip, std::string infile) -{ - std::unique_ptr t = std::make_unique(); - t->Add((infile+"?#residualtree").c_str()); -// TFile* f = TFile::Open(infile.c_str()); -// TTree* t = (TTree*)f->Get("residualtree"); - - float px; - float py; - float pz; - float dedx; - float eta; - int nmaps; - int nintt; - int ntpc; - float dcaxy; - - t->SetBranchAddress("px",&px); - t->SetBranchAddress("py",&py); - t->SetBranchAddress("pz",&pz); - t->SetBranchAddress("dedx",&dedx); - t->SetBranchAddress("eta",&eta); - t->SetBranchAddress("nmaps",&nmaps); - t->SetBranchAddress("nintt",&nintt); - t->SetBranchAddress("ntpc",&ntpc); - t->SetBranchAddress("dcaxy",&dcaxy); - - for(size_t entry=skip; entry<(skip+ntracks); entry++) - { - //if(entry==t->GetEntries()-1) break; - if(entry % 1000 == 0) std::cout << entry << std::endl; - t->GetEntry(entry); - if(nmaps>0 && nintt>0 && fabs(eta)<1. && dcaxy<0.5 && ntpc>30) - { - p.push_back(sqrt(px*px+py*py+pz*pz)); - dEdx.push_back(dedx); - } - } - std::cout << "number of good tracks: " << p.size() << std::endl; - //f->Close(); -} - -void GlobaldEdxFitter::addTrack(double trk_dEdx, double trk_p) -{ - dEdx.push_back(trk_dEdx); - p.push_back(trk_p); -} - -double GlobaldEdxFitter::get_fitquality_new(double A) -{ - double chi2 = 0.; - double ndf = -1.; - - double pi_chi2 = 0.; - double K_chi2 = 0.; - double p_chi2 = 0.; - double d_chi2 = 0.; - double pi_ndf = -1.; - double K_ndf = -1.; - double p_ndf = -1.; - double d_ndf = -1.; - - for(size_t i=0; i GlobaldEdxFitter::get_betagamma(double A) -{ - std::vector betagamma; - for(size_t i=0; iGetMinimumXYZ(minA,minB,minC); - delete f; - return std::make_tuple(minA,minB,minC); -*/ - ROOT::Math::Minimizer* minimizer = ROOT::Math::Factory::CreateMinimizer("Minuit2"); - minimizer->SetMaxFunctionCalls(1000000); - minimizer->SetMaxIterations(10000); - minimizer->SetTolerance(0.1); - minimizer->SetPrintLevel(1); - ROOT::Math::Functor f(this,&GlobaldEdxFitter::get_fitquality_functor,1); - double step[1] = {.01}; - double variable[1] = {20.}; - minimizer->SetFunction(f); - minimizer->SetVariable(0,"A",variable[0],step[0]); - minimizer->Minimize(); - const double *xs = minimizer->X(); - return xs[0]; -} - -double GlobaldEdxFitter::get_minimum() -{ - TF1* f = create_TF1("temp"); - f->SetNpx(1000); - double minX = f->GetMinimumX(); - delete f; - return minX; -} - -std::pair GlobaldEdxFitter::get_minimum_ZS() -{ - TF2* f = create_TF2("temp"); - double minX; - double minY; - f->GetMinimumXY(minX,minY); - delete f; - return std::make_pair(minX,minY); -} - -TGraph* GlobaldEdxFitter::graph_vsbetagamma(double A) -{ - std::vector betagamma = get_betagamma(A); - TGraph* g = new TGraph(dEdx.size(),betagamma.data(),dEdx.data()); - return g; -} - -TGraph* GlobaldEdxFitter::graph_vsp() -{ - TGraph* g = new TGraph(dEdx.size(),p.data(),dEdx.data()); - return g; -} - -#endif +#endif // GLOBALDEDXFITTER_H diff --git a/calibrations/tpc/dEdx/Makefile.am b/calibrations/tpc/dEdx/Makefile.am index 03dda87d60..e057d9dffe 100644 --- a/calibrations/tpc/dEdx/Makefile.am +++ b/calibrations/tpc/dEdx/Makefile.am @@ -19,7 +19,8 @@ lib_LTLIBRARIES = \ libdedxfitter.la libdedxfitter_la_SOURCES = \ - dEdxFitter.cc + dEdxFitter.cc \ + GlobaldEdxFitter.cc libdedxfitter_la_LIBADD = \ -lphool \ diff --git a/calibrations/tpc/dEdx/bethe_bloch.h b/calibrations/tpc/dEdx/bethe_bloch.h index 3b134224ee..9bbb6e1962 100644 --- a/calibrations/tpc/dEdx/bethe_bloch.h +++ b/calibrations/tpc/dEdx/bethe_bloch.h @@ -1,7 +1,7 @@ #ifndef BETHE_BLOCH_H #define BETHE_BLOCH_H -#include "TMath.h" +#include namespace dedx_constants { @@ -31,21 +31,21 @@ namespace dedx_constants // Bethe-Bloch fit function, vs. betagamma // A = normalization constant, equal to (ADC conversion)*4pi*n*Z^2*e^4/(m_e*c^2*4pi*epsilon_0^2) // B = A*(ln(2*m_e/I)-1) - (zero-suppression loss factor) -const double bethe_bloch_new(const double betagamma, const double A, const double B, const double C) +inline const double bethe_bloch_new(const double betagamma, const double A, const double B, const double C) { const double beta = betagamma/sqrt(1.+betagamma*betagamma); return A/(beta*beta)*TMath::Log(betagamma) + A/(beta*beta)*B - A - C; } -const double bethe_bloch_new_2D(const double betagamma, const double A, const double B) +inline const double bethe_bloch_new_2D(const double betagamma, const double A, const double B) { const double beta = betagamma/sqrt(1.+betagamma*betagamma); return A/(beta*beta)*(2.*TMath::Log(2.*dedx_constants::m_e/dedx_constants::sphenix_I * betagamma) - beta*beta) - B; } -const double bethe_bloch_new_1D(const double betagamma, const double A) +inline const double bethe_bloch_new_1D(const double betagamma, const double A) { const double beta = betagamma/sqrt(1.+betagamma*betagamma); @@ -53,7 +53,7 @@ const double bethe_bloch_new_1D(const double betagamma, const double A) } // dE/dx for one gas species, up to normalization -const double bethe_bloch_species(const double betagamma, const double I) +inline const double bethe_bloch_species(const double betagamma, const double I) { const double m_e = 511e3; // eV @@ -63,14 +63,14 @@ const double bethe_bloch_species(const double betagamma, const double I) } // dE/dx for TPC gas mixture, up to normalization -const double bethe_bloch_total(const double betagamma) +inline const double bethe_bloch_total(const double betagamma) { return dedx_constants::ar_frac * bethe_bloch_species(betagamma,dedx_constants::ar_I) + dedx_constants::cf4_frac * bethe_bloch_species(betagamma,dedx_constants::cf4_I) + dedx_constants::isobutane_frac * bethe_bloch_species(betagamma,dedx_constants::isobutane_I); } -Double_t bethe_bloch_new_wrapper(Double_t* x, Double_t* par) +inline Double_t bethe_bloch_new_wrapper(Double_t* x, Double_t* par) { Double_t betagamma = x[0]; Double_t A = par[0]; @@ -80,7 +80,7 @@ Double_t bethe_bloch_new_wrapper(Double_t* x, Double_t* par) return bethe_bloch_new(betagamma,A,B,C); } -Double_t bethe_bloch_new_2D_wrapper(Double_t* x, Double_t* par) +inline Double_t bethe_bloch_new_2D_wrapper(Double_t* x, Double_t* par) { Double_t betagamma = x[0]; Double_t A = par[0]; @@ -89,7 +89,7 @@ Double_t bethe_bloch_new_2D_wrapper(Double_t* x, Double_t* par) return bethe_bloch_new_2D(betagamma,A,B); } -Double_t bethe_bloch_new_1D_wrapper(Double_t* x, Double_t* par) +inline Double_t bethe_bloch_new_1D_wrapper(Double_t* x, Double_t* par) { Double_t betagamma = x[0]; Double_t A = par[0]; @@ -98,7 +98,7 @@ Double_t bethe_bloch_new_1D_wrapper(Double_t* x, Double_t* par) } // wrapper function for TF1 constructor, for fitting -Double_t bethe_bloch_wrapper(Double_t* ln_bg, Double_t* par) +inline Double_t bethe_bloch_wrapper(Double_t* ln_bg, Double_t* par) { Double_t betagamma = exp(ln_bg[0]); @@ -107,7 +107,7 @@ Double_t bethe_bloch_wrapper(Double_t* ln_bg, Double_t* par) return norm * bethe_bloch_total(betagamma); } -Double_t bethe_bloch_vs_p_wrapper(Double_t* x, Double_t* par) +inline Double_t bethe_bloch_vs_p_wrapper(Double_t* x, Double_t* par) { Double_t p = x[0]; Double_t norm = par[0]; @@ -116,7 +116,7 @@ Double_t bethe_bloch_vs_p_wrapper(Double_t* x, Double_t* par) return norm * bethe_bloch_total(fabs(p)/m); } -Double_t bethe_bloch_vs_logp_wrapper(Double_t* x, Double_t* par) +inline Double_t bethe_bloch_vs_logp_wrapper(Double_t* x, Double_t* par) { Double_t p = pow(10.,x[0]); Double_t norm = par[0]; @@ -125,7 +125,7 @@ Double_t bethe_bloch_vs_logp_wrapper(Double_t* x, Double_t* par) return norm * bethe_bloch_total(fabs(p)/m); } -Double_t bethe_bloch_vs_p_wrapper_ZS(Double_t* x, Double_t* par) +inline Double_t bethe_bloch_vs_p_wrapper_ZS(Double_t* x, Double_t* par) { Double_t p = x[0]; Double_t norm = par[0]; @@ -135,7 +135,7 @@ Double_t bethe_bloch_vs_p_wrapper_ZS(Double_t* x, Double_t* par) return norm * bethe_bloch_total(fabs(p)/m) - ZS_loss; } -Double_t bethe_bloch_vs_p_wrapper_new(Double_t* x, Double_t* par) +inline Double_t bethe_bloch_vs_p_wrapper_new(Double_t* x, Double_t* par) { Double_t p = x[0]; Double_t A = par[0]; @@ -146,7 +146,7 @@ Double_t bethe_bloch_vs_p_wrapper_new(Double_t* x, Double_t* par) return bethe_bloch_new(fabs(p)/m,A,B,C); } -Double_t bethe_bloch_vs_p_wrapper_new_2D(Double_t* x, Double_t* par) +inline Double_t bethe_bloch_vs_p_wrapper_new_2D(Double_t* x, Double_t* par) { Double_t p = x[0]; Double_t A = par[0]; @@ -156,7 +156,7 @@ Double_t bethe_bloch_vs_p_wrapper_new_2D(Double_t* x, Double_t* par) return bethe_bloch_new_2D(fabs(p)/m,A,B); } -Double_t bethe_bloch_vs_p_wrapper_new_1D(Double_t* x, Double_t* par) +inline Double_t bethe_bloch_vs_p_wrapper_new_1D(Double_t* x, Double_t* par) { Double_t p = x[0]; Double_t A = par[0]; @@ -165,7 +165,7 @@ Double_t bethe_bloch_vs_p_wrapper_new_1D(Double_t* x, Double_t* par) return bethe_bloch_new_1D(fabs(p)/m,A); } -Double_t bethe_bloch_vs_logp_wrapper_ZS(Double_t* x, Double_t* par) +inline Double_t bethe_bloch_vs_logp_wrapper_ZS(Double_t* x, Double_t* par) { Double_t p = pow(10.,x[0]); Double_t norm = par[0]; @@ -175,7 +175,7 @@ Double_t bethe_bloch_vs_logp_wrapper_ZS(Double_t* x, Double_t* par) return norm * bethe_bloch_total(fabs(p)/m) - ZS_loss; } -Double_t bethe_bloch_vs_logp_wrapper_new(Double_t* x, Double_t* par) +inline Double_t bethe_bloch_vs_logp_wrapper_new(Double_t* x, Double_t* par) { Double_t p = pow(10.,x[0]); Double_t A = par[0]; @@ -186,7 +186,7 @@ Double_t bethe_bloch_vs_logp_wrapper_new(Double_t* x, Double_t* par) return bethe_bloch_new(fabs(p)/m,A,B,C); } -Double_t bethe_bloch_vs_logp_wrapper_new_1D(Double_t* x, Double_t* par) +inline Double_t bethe_bloch_vs_logp_wrapper_new_1D(Double_t* x, Double_t* par) { Double_t p = pow(10.,x[0]); Double_t A = par[0]; @@ -197,7 +197,7 @@ Double_t bethe_bloch_vs_logp_wrapper_new_1D(Double_t* x, Double_t* par) // ratio of dE/dx between two particle species at the same momentum // (useful for dE/dx peak fits) -const double dedx_ratio(const double p, const double m1, const double m2) +inline const double dedx_ratio(const double p, const double m1, const double m2) { const double betagamma1 = fabs(p)/m1; const double betagamma2 = fabs(p)/m2; diff --git a/calibrations/tpc/dEdx/dEdxFitter.cc b/calibrations/tpc/dEdx/dEdxFitter.cc index 01c867f601..0f03bae44e 100644 --- a/calibrations/tpc/dEdx/dEdxFitter.cc +++ b/calibrations/tpc/dEdx/dEdxFitter.cc @@ -31,7 +31,10 @@ int dEdxFitter::InitRun(PHCompositeNode *topNode) int dEdxFitter::process_event(PHCompositeNode *topNode) { _event++; - if(_event%1000==0) std::cout << PHWHERE << "Events processed: " << _event << std::endl; + if(_event%1000==0) + { + std::cout << PHWHERE << "Events processed: " << _event << std::endl; + } GetNodes(topNode); @@ -52,10 +55,16 @@ void dEdxFitter::process_tracks(PHCompositeNode *topNode) for(const auto &[key, track] : *_trackmap) { - if(!track) continue; + if(!track) + { + continue; + } double trackID = track->get_id(); - if(Verbosity()>1) std::cout << "track ID " << trackID << std::endl; + if(Verbosity()>1) + { + std::cout << "track ID " << trackID << std::endl; + } if(std::isnan(track->get_x()) || std::isnan(track->get_y()) || std::isnan(track->get_z()) || @@ -72,7 +81,10 @@ void dEdxFitter::process_tracks(PHCompositeNode *topNode) // ignore TPC-only tracks if(!track->get_silicon_seed()) { - if(Verbosity()>1) std::cout << "TPC-only track, skipping..." << std::endl; + if(Verbosity()>1) + { + std::cout << "TPC-only track, skipping..." << std::endl; + } continue; } @@ -100,22 +112,28 @@ std::tuple dEdxFitter::get_nclus(SvtxTrack* track) int nintt = 0; int ntpc = 0; - for(auto it = track->get_silicon_seed()->begin_cluster_keys(); it != track->get_silicon_seed()->end_cluster_keys(); ++it) + if(track->get_silicon_seed()) { - TrkrDefs::cluskey ckey = *it; - auto trkrid = TrkrDefs::getTrkrId(ckey); - if(trkrid == TrkrDefs::mvtxId) + for(auto it = track->get_silicon_seed()->begin_cluster_keys(); it != track->get_silicon_seed()->end_cluster_keys(); ++it) { - nmaps++; - } - else if(trkrid == TrkrDefs::inttId) - { - nintt++; + TrkrDefs::cluskey ckey = *it; + auto trkrid = TrkrDefs::getTrkrId(ckey); + if(trkrid == TrkrDefs::mvtxId) + { + nmaps++; + } + else if(trkrid == TrkrDefs::inttId) + { + nintt++; + } } } - for(auto it = track->get_tpc_seed()->begin_cluster_keys(); it != track->get_tpc_seed()->end_cluster_keys(); ++it) + if(track->get_tpc_seed()) { - ntpc++; + for(auto it = track->get_tpc_seed()->begin_cluster_keys(); it != track->get_tpc_seed()->end_cluster_keys(); ++it) + { + ntpc++; + } } return std::make_tuple(nmaps,nintt,ntpc); @@ -144,10 +162,8 @@ double dEdxFitter::get_dcaxy(SvtxTrack* track) auto dcapair = TrackAnalysisUtils::get_dca(track,vertex); return dcapair.first.first; } - else - { - return std::numeric_limits::quiet_NaN(); - } + // if no vertex found + return std::numeric_limits::quiet_NaN(); } //___________________________________ @@ -188,7 +204,7 @@ void dEdxFitter::GetNodes(PHCompositeNode *topNode) //______________________________________ int dEdxFitter::End(PHCompositeNode *topNode) { - if(minima.size()==0) + if(minima.empty()) { minima.push_back(fitter->get_minimum()); } @@ -222,7 +238,10 @@ int dEdxFitter::End(PHCompositeNode *topNode) d_band->SetParameter(1,dedx_constants::m_d); d_band->Write(); - if(Verbosity()>0) std::cout << "dEdxFitter extracted minimum: " << avg_minimum << std::endl; + if(Verbosity()>0) + { + std::cout << "dEdxFitter extracted minimum: " << avg_minimum << std::endl; + } return 0; } diff --git a/calibrations/tpc/dEdx/dEdxFitter.h b/calibrations/tpc/dEdx/dEdxFitter.h index ca4fca546d..fda3d7c124 100644 --- a/calibrations/tpc/dEdx/dEdxFitter.h +++ b/calibrations/tpc/dEdx/dEdxFitter.h @@ -56,7 +56,7 @@ class dEdxFitter: public SubsysReco private: //output filename std::string _outfile = "dedx_outfile.root"; - size_t _event; + size_t _event = 0; SvtxTrackMap* _trackmap = nullptr; TrkrClusterContainer* _clustermap = nullptr; diff --git a/calibrations/tpc/dEdx/test_sample_size.C b/calibrations/tpc/dEdx/test_sample_size.C index 30d4b5cb00..df2a39b322 100644 --- a/calibrations/tpc/dEdx/test_sample_size.C +++ b/calibrations/tpc/dEdx/test_sample_size.C @@ -1,8 +1,11 @@ #include "GlobaldEdxFitter.h" -void test_sample_size(std::string infile="/sphenix/tg/tg01/hf/mjpeters/run53877_tracks/track_output_53877_02613_53877-2613.root_resid.root") +#include +#include + +void test_sample_size(const std::string& infile="/sphenix/tg/tg01/hf/mjpeters/run53877_tracks/track_output_53877_*.root") { - std::vector samplesizes = {1000,2000,5000,10000,20000,50000,100000,200000,500000,1000000};//,2000000,5000000}; + std::vector samplesizes = {1000,2000,5000,10000,20000};//,50000,100000,200000,500000,1000000};//,2000000,5000000}; const int n_samples = 20; const float fluctuation_ymin = 5.; @@ -30,18 +33,21 @@ void test_sample_size(std::string infile="/sphenix/tg/tg01/hf/mjpeters/run53877_ fitvalues_all.emplace_back(); gfs.push_back(std::make_unique()); - std::string fluctuation_canvasname = "fluctuations_"+std::to_string((int)floor(samplesizes[i])); - std::string distribution_canvasname = "distributions_"+std::to_string((int)floor(samplesizes[i])); + const std::string& fluctuation_canvasname = "fluctuations_"+std::to_string((int)floor(samplesizes[i])); + const std::string& distribution_canvasname = "distributions_"+std::to_string((int)floor(samplesizes[i])); fluctuations.push_back(new TCanvas(fluctuation_canvasname.c_str(),fluctuation_canvasname.c_str(),600,600)); distributions.push_back(new TCanvas(distribution_canvasname.c_str(),distribution_canvasname.c_str(),600,600)); for(int j=0;jprocessResidualData(floor(samplesizes[i]),j*samplesizes[i]); + gfs[i]->processResidualData(infile,floor(samplesizes[i]),j*samplesizes[i]); double min = gfs[i]->get_minimum(); std::cout << "minimum: " << min << std::endl; fitvalues_all[i].push_back(min); - if(jreset(); + if(jreset(); + } /* tf1s[i]->cd(); TF1* tf1copy = gfs[i]->create_TF1(("ntrk_"+std::to_string(samplesizes[i])).c_str()); @@ -139,7 +145,7 @@ void test_sample_size(std::string infile="/sphenix/tg/tg01/hf/mjpeters/run53877_ gp->Draw("AP"); cbands->SetLogx(); - for(double mass : {m_pi, m_K, m_p, m_d}) + for(double mass : {dedx_constants::m_pi, dedx_constants::m_K, dedx_constants::m_p, dedx_constants::m_d}) { TF1* band = new TF1(("band_"+std::to_string(mass)).c_str(),bethe_bloch_vs_p_wrapper_new_1D,0.,10.,2,1); band->SetParameter(0,best_A); @@ -160,7 +166,7 @@ void test_sample_size(std::string infile="/sphenix/tg/tg01/hf/mjpeters/run53877_ dedx_h->Draw("COLZ"); cb->SetLogz(); - for(float mass : {m_pi, m_K, m_p, m_d}) + for(double mass : {dedx_constants::m_pi, dedx_constants::m_K, dedx_constants::m_p, dedx_constants::m_d}) { TF1* band = new TF1(("band_"+std::to_string(mass)).c_str(),bethe_bloch_vs_logp_wrapper_new_1D,-1.,5.,2,1); band->SetParameter(0,best_A); From d1152d0f8d158c3f7abd88006dfda222a3c0ffc3 Mon Sep 17 00:00:00 2001 From: rosstom Date: Fri, 16 Jan 2026 19:28:46 -0500 Subject: [PATCH 070/393] New QA module to make cluster-state residual plots --- offline/QA/Tracking/Makefile.am | 2 + .../QA/Tracking/StateClusterResidualsQA.cc | 245 ++++++++++++++++++ offline/QA/Tracking/StateClusterResidualsQA.h | 127 +++++++++ 3 files changed, 374 insertions(+) create mode 100644 offline/QA/Tracking/StateClusterResidualsQA.cc create mode 100644 offline/QA/Tracking/StateClusterResidualsQA.h diff --git a/offline/QA/Tracking/Makefile.am b/offline/QA/Tracking/Makefile.am index f5d87546f1..75cbdf164b 100644 --- a/offline/QA/Tracking/Makefile.am +++ b/offline/QA/Tracking/Makefile.am @@ -17,6 +17,7 @@ pkginclude_HEADERS = \ TpcSeedsQA.h \ TpcSiliconQA.h \ SiliconSeedsQA.h \ + StateClusterResidualsQA.h \ MicromegasClusterQA.h \ CosmicTrackQA.h \ TrackFittingQA.h \ @@ -32,6 +33,7 @@ libtrackingqa_la_SOURCES = \ TpcSeedsQA.cc \ TpcSiliconQA.cc \ SiliconSeedsQA.cc \ + StateClusterResidualsQA.cc \ MicromegasClusterQA.cc \ CosmicTrackQA.cc \ TrackFittingQA.cc \ diff --git a/offline/QA/Tracking/StateClusterResidualsQA.cc b/offline/QA/Tracking/StateClusterResidualsQA.cc new file mode 100644 index 0000000000..b09662ded0 --- /dev/null +++ b/offline/QA/Tracking/StateClusterResidualsQA.cc @@ -0,0 +1,245 @@ +#include "StateClusterResidualsQA.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include + +namespace +{ + template + inline T square (T const& t) { return t * t; } + + template + class range_adaptor + { + public: + explicit range_adaptor( + T const& begin, + T const& end) + : m_begin(begin) + , m_end(end) + { + } + T const& begin() { return m_begin; } + T const& end() { return m_end; } + + private: + T m_begin; + T m_end; + }; +} // namespace + +StateClusterResidualsQA::StateClusterResidualsQA(const std::string& name) + : SubsysReco(name) +{ +} + +int StateClusterResidualsQA::InitRun( + PHCompositeNode* top_node) +{ + createHistos(); + + // F4A will not actually ABORTRUN unless that return code is issued here + auto* track_map = findNode::getClass(top_node, m_track_map_node_name); + if (!track_map) + { + std::cout + << PHWHERE << "\n" + << "\tCould not get track map:\n" + << "\t\"" << m_track_map_node_name << "\"\n" + << "\tAborting\n" + << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + auto* cluster_map = findNode::getClass(top_node, m_clusterContainerName); + if (!cluster_map) + { + std::cout + << PHWHERE << "\n" + << "\tCould not get cluster map:\n" + << "\t\"" << m_clusterContainerName << "\"\n" + << "\tAborting\n" + << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + auto *geometry = findNode::getClass(top_node, "ActsGeometry"); + if (!geometry) + { + std::cout + << PHWHERE << "\n" + << "\tCould not get ActsGeometry:\n" + << "\t\"" << "ActsGeometry" << "\"\n" + << "\tAborting\n" + << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + auto* hm = QAHistManagerDef::getHistoManager(); + if (!hm) + { + std::cout + << PHWHERE << "\n" + << "\tCould not get QAHistManager\n" + << "\tAborting\n" + << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + for (const auto& cfg : m_pending) + { + m_histograms_x.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_x")))); + m_histograms_y.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_y")))); + m_histograms_z.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_z")))); + } + + return Fun4AllReturnCodes::EVENT_OK; +} + +int StateClusterResidualsQA::process_event(PHCompositeNode* top_node) +{ + auto* track_map = findNode::getClass(top_node, m_track_map_node_name); + auto *cluster_map = findNode::getClass(top_node, m_clusterContainerName); + auto *geometry = findNode::getClass(top_node, "ActsGeometry"); + + for (auto const& [idkey, track] : *track_map) + { + if (!track) + { + continue; + } + + // count states + std::map counters = { + {TrkrDefs::mvtxId, 0}, + {TrkrDefs::inttId, 0}, + {TrkrDefs::tpcId, 0}, + {TrkrDefs::micromegasId, 0}, + }; + + for (auto const& [path_length, state] : range_adaptor(track->begin_states(), track->end_states())) + { + // There is an additional state representing the vertex at the beginning of the map, + // but getTrkrId will return 0 for its corresponding cluster + // Identify it as having path_length identically equal to 0 + if (path_length == 0) { continue; } + + auto trkr_id = static_cast(TrkrDefs::getTrkrId(state->get_cluskey())); + auto itr = counters.find(trkr_id); + if (itr == counters.end()) { continue; } + ++itr->second; + } + + float track_eta = track->get_eta(); + float track_phi = track->get_phi(); + float track_pt = track->get_pt(); + int h = 0; + for (const auto& cfg : m_pending) + { + if (cfg.charge != 0) + { + if ((cfg.charge < 0) && track->get_positive_charge()) + { + continue; + } + else if ((cfg.charge > 0) && !(track->get_positive_charge())) + { + continue; + } + } + if (cfg.min_mvtx_clusters <= counters[TrkrDefs::mvtxId] && cfg.max_mvtx_clusters >= counters[TrkrDefs::mvtxId] + && cfg.min_intt_clusters <= counters[TrkrDefs::inttId] && cfg.max_intt_clusters >= counters[TrkrDefs::inttId] + && cfg.min_tpc_clusters <= counters[TrkrDefs::tpcId] && cfg.max_tpc_clusters >= counters[TrkrDefs::tpcId] + && cfg.phi_min <= track_phi && cfg.phi_max >= track_phi + && cfg.eta_min <= track_eta && cfg.eta_max >= track_eta + && cfg.pt_min <= track_pt && cfg.pt_max >= track_pt) + { + for (auto const& [path_length, state] : range_adaptor(track->begin_states(), track->end_states())) + { + if (path_length == 0) { continue; } + + auto *cluster = cluster_map->findCluster(state->get_cluskey()); + float state_x = state->get_x(); + float state_y = state->get_y(); + float state_z = state->get_z(); + Acts::Vector3 glob = geometry->getGlobalPosition(state->get_cluskey(), cluster); + float cluster_x = glob.x(); + float cluster_y = glob.y(); + float cluster_z = glob.z(); + if (cluster) + { + m_histograms_x[h]->Fill(state_x - cluster_x); + m_histograms_y[h]->Fill(state_y - cluster_y); + m_histograms_z[h]->Fill(state_z - cluster_z); + } + } + } + ++h; + } + } + + return Fun4AllReturnCodes::EVENT_OK; +} + +void StateClusterResidualsQA::createHistos() +{ + auto *hm = QAHistManagerDef::getHistoManager(); + assert(hm); + + for (const auto& cfg : m_pending) + { + TH1F* h_new_x = new TH1F( + (cfg.name + "_x").c_str(), + ";State-Cluster X Residual [cm];Entries", + m_nBins, m_xrange.first, m_xrange.second); + h_new_x->SetMarkerColor(kBlue); + h_new_x->SetLineColor(kBlue); + hm->registerHisto(h_new_x); + TH1F* h_new_y = new TH1F( + (cfg.name + "_y").c_str(), + ";State-Cluster Y Residual [cm];Entries", + m_nBins, m_yrange.first, m_yrange.second); + h_new_y->SetMarkerColor(kBlue); + h_new_y->SetLineColor(kBlue); + hm->registerHisto(h_new_y); + TH1F* h_new_z = new TH1F( + (cfg.name + "_z").c_str(), + ";State-Cluster Z Residual [cm];Entries", + m_nBins, m_zrange.first, m_zrange.second); + h_new_z->SetMarkerColor(kBlue); + h_new_z->SetLineColor(kBlue); + hm->registerHisto(h_new_z); + } +} + +int StateClusterResidualsQA::EndRun(const int /*unused*/) +{ + auto *hm = QAHistManagerDef::getHistoManager(); + assert(hm); + + return Fun4AllReturnCodes::EVENT_OK; +} diff --git a/offline/QA/Tracking/StateClusterResidualsQA.h b/offline/QA/Tracking/StateClusterResidualsQA.h new file mode 100644 index 0000000000..739c816609 --- /dev/null +++ b/offline/QA/Tracking/StateClusterResidualsQA.h @@ -0,0 +1,127 @@ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef STATECLUSTERRESIDUALSQA_H +#define STATECLUSTERRESIDUALSQA_H + +#include + +#include +#include +#include +#include +#include + +class PHCompositeNode; +class TH1; + +struct ResidualHistConfig +{ + std::string name = "h_StateClusterResidualsQA_"; + std::string title = ";Residual [cm];Entries"; + + int min_mvtx_clusters = 0; + int max_mvtx_clusters = 3; + int min_intt_clusters = 0; + int max_intt_clusters = 4; + int min_tpc_clusters = 0; + int max_tpc_clusters = 48; + + float phi_min = -M_PI; + float phi_max = M_PI; + float eta_min = -1.1; + float eta_max = 1.1; + + float pt_min = 0.0; + float pt_max = FLT_MAX; + + int charge = 0; +}; + +class StateClusterResidualsQA : public SubsysReco +{ + public: + StateClusterResidualsQA(const std::string& name = "StateClusterResidualsQA"); + ~StateClusterResidualsQA() override = default; + + /// sets the name of node to retrieve the track map from (default member value is "SvtxTrackMap") + void set_track_map_name(std::string const& track_map_node_name) { m_track_map_node_name = track_map_node_name; } + + StateClusterResidualsQA& addHistogram(const std::string& name) + { + ResidualHistConfig cfg; + cfg.name += name; + m_pending.push_back(cfg); + return *this; + } + StateClusterResidualsQA& setNMvtx(int min, int max) + { + m_pending.back().min_mvtx_clusters = min; + m_pending.back().max_mvtx_clusters = max; + return *this; + } + StateClusterResidualsQA& setNIntt(int min, int max) + { + m_pending.back().min_intt_clusters = min; + m_pending.back().max_intt_clusters = max; + return *this; + } + StateClusterResidualsQA& setNTpc(int min, int max) + { + m_pending.back().min_tpc_clusters = min; + m_pending.back().max_tpc_clusters = max; + return *this; + } + StateClusterResidualsQA& setPhiRange(float min, float max) + { + m_pending.back().phi_min = min; + m_pending.back().phi_max = max; + return *this; + } + StateClusterResidualsQA& setEtaRange(float min, float max) + { + m_pending.back().eta_min = min; + m_pending.back().eta_max = max; + return *this; + } + StateClusterResidualsQA& setPtRange(float min, float max) + { + m_pending.back().pt_min = min; + m_pending.back().pt_max = max; + return *this; + } + StateClusterResidualsQA& setPositiveTracks() + { + m_pending.back().charge = 1; + return *this; + } + StateClusterResidualsQA& setNegativeTracks() + { + m_pending.back().charge = -1; + return *this; + } + + void createHistos(); + + int InitRun(PHCompositeNode*) override; + + int process_event(PHCompositeNode*) override; + + int EndRun(const int runnumber) override; + + private: + std::vector m_pending; + + std::string m_track_map_node_name = "SvtxTrackMap"; + std::string m_clusterContainerName = "TRKR_CLUSTER"; + + int m_nBins = 50; + std::pair m_xrange {-0.5,0.5}; + std::pair m_yrange {-0.5,0.5}; + std::pair m_zrange {-0.5,0.5}; + + std::vector m_histograms_x{}; + std::vector m_histograms_y{}; + std::vector m_histograms_z{}; +}; + +#endif // TRACKFITTINGQA_H From 6c11c5d5a51c7dcb4eb0ff7fcf70a64280d90d90 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Sat, 17 Jan 2026 10:25:15 -0500 Subject: [PATCH 071/393] clang-tidy --- offline/QA/Tracking/StateClusterResidualsQA.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/QA/Tracking/StateClusterResidualsQA.cc b/offline/QA/Tracking/StateClusterResidualsQA.cc index b09662ded0..1ca70dc294 100644 --- a/offline/QA/Tracking/StateClusterResidualsQA.cc +++ b/offline/QA/Tracking/StateClusterResidualsQA.cc @@ -166,7 +166,7 @@ int StateClusterResidualsQA::process_event(PHCompositeNode* top_node) { continue; } - else if ((cfg.charge > 0) && !(track->get_positive_charge())) + if ((cfg.charge > 0) && !(track->get_positive_charge())) { continue; } From ec8e8a691db902592cb26a76e72f9cc1916f7ceb Mon Sep 17 00:00:00 2001 From: cdean-github Date: Sat, 17 Jan 2026 15:16:31 -0500 Subject: [PATCH 072/393] CD: Stop KFP from aborting events --- offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc index 38b60d55ba..8c049f30d6 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc @@ -148,7 +148,7 @@ int KFParticle_sPHENIX::process_event(PHCompositeNode *topNode) { std::cout << "KFParticle: Event skipped as there are no tracks" << std::endl; } - return Fun4AllReturnCodes::ABORTEVENT; + return Fun4AllReturnCodes::EVENT_OK; } if (!m_use_fake_pv) @@ -162,7 +162,7 @@ int KFParticle_sPHENIX::process_event(PHCompositeNode *topNode) { std::cout << "KFParticle: Event skipped as there are no vertices" << std::endl; } - return Fun4AllReturnCodes::ABORTEVENT; + return Fun4AllReturnCodes::EVENT_OK; } } else @@ -174,10 +174,9 @@ int KFParticle_sPHENIX::process_event(PHCompositeNode *topNode) { std::cout << "KFParticle: Event skipped as there are no vertices" << std::endl; } - return Fun4AllReturnCodes::ABORTEVENT; + return Fun4AllReturnCodes::EVENT_OK; } } - } createDecay(topNode, mother, vertex_kfparticle, daughters, intermediates, nPVs); From 68b618fe99354a605ee4e6b198babd5b47b88f5d Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Sat, 17 Jan 2026 15:54:48 -0500 Subject: [PATCH 073/393] add flag to prune all seeds --- .../packages/trackreco/DSTClusterPruning.cc | 33 +++++++++++++++++++ .../packages/trackreco/DSTClusterPruning.h | 9 +++++ 2 files changed, 42 insertions(+) diff --git a/offline/packages/trackreco/DSTClusterPruning.cc b/offline/packages/trackreco/DSTClusterPruning.cc index 15bfe547ca..6314bf50b2 100644 --- a/offline/packages/trackreco/DSTClusterPruning.cc +++ b/offline/packages/trackreco/DSTClusterPruning.cc @@ -177,6 +177,39 @@ void DSTClusterPruning::prune_clusters() } return; } + if(m_pruneAllSeeds) + { + for(const auto& container : {m_tpc_track_seed_container, m_silicon_track_seed_container}) + { + for (const auto& trackseed : *container) + { + if (!trackseed) + { + std::cout << "No TrackSeed" << std::endl; + continue; + } + + for (auto key_iter = trackseed->begin_cluster_keys(); key_iter != trackseed->end_cluster_keys(); ++key_iter) + { + const auto& cluster_key = *key_iter; + auto cluster = m_cluster_map->findCluster(cluster_key); + if (!cluster) + { + std::cout << "DSTClusterPruning::evaluate_tracks - unable to find cluster for key " << cluster_key << std::endl; + continue; + } + if (!m_reduced_cluster_map->findCluster(cluster_key)) + { + m_cluster = new TrkrClusterv5(); + m_cluster->CopyFrom(cluster); + m_reduced_cluster_map->addClusterSpecifyKey(cluster_key, m_cluster); + } + } + } + } + return; + } + for (const auto& trackseed : *m_track_seed_container) { if (!trackseed) diff --git a/offline/packages/trackreco/DSTClusterPruning.h b/offline/packages/trackreco/DSTClusterPruning.h index c9ec35ea53..5fa2ff9b4f 100644 --- a/offline/packages/trackreco/DSTClusterPruning.h +++ b/offline/packages/trackreco/DSTClusterPruning.h @@ -52,6 +52,12 @@ class DSTClusterPruning : public SubsysReco //! end of processing //int End(PHCompositeNode*) override; + //! dump all clusters on all seeds out + void pruneAllSeeds() + { + m_pruneAllSeeds = true; + } + private: //! load nodes int load_nodes(PHCompositeNode*); @@ -68,6 +74,9 @@ class DSTClusterPruning : public SubsysReco TrackSeedContainer* m_tpc_track_seed_container = nullptr; TrackSeedContainer* m_silicon_track_seed_container = nullptr; +//! set to true if you want to dump out all clusters on all silicon +//! and all tpc seeds individually + bool m_pruneAllSeeds = false; //@} // debugging helpers From c12d8ae33e888639e86a279ec961839332280af3 Mon Sep 17 00:00:00 2001 From: "Blair D. Seidlitz" Date: Sat, 17 Jan 2026 18:52:34 -0500 Subject: [PATCH 074/393] adding more calo embedding tools --- .../CaloEmbedding/CombineTowerInfo.cc | 99 +++++++++++++++++++ .../packages/CaloEmbedding/CombineTowerInfo.h | 39 ++++++++ .../packages/CaloEmbedding/CopyIODataNodes.cc | 64 ++++++++++++ .../packages/CaloEmbedding/CopyIODataNodes.h | 13 +++ 4 files changed, 215 insertions(+) create mode 100644 offline/packages/CaloEmbedding/CombineTowerInfo.cc create mode 100644 offline/packages/CaloEmbedding/CombineTowerInfo.h diff --git a/offline/packages/CaloEmbedding/CombineTowerInfo.cc b/offline/packages/CaloEmbedding/CombineTowerInfo.cc new file mode 100644 index 0000000000..3e5150d194 --- /dev/null +++ b/offline/packages/CaloEmbedding/CombineTowerInfo.cc @@ -0,0 +1,99 @@ +#include "CombineTowerInfo.h" + +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + +//____________________________________________________________________________ +CombineTowerInfo::CombineTowerInfo(const std::string& name) + : SubsysReco(name) +{ +} + +//____________________________________________________________________________ +int CombineTowerInfo::InitRun(PHCompositeNode* topNode) +{ + if (m_inputNodeA.empty() || m_inputNodeB.empty() || m_outputNode.empty()) + { + throw std::runtime_error("CombineTowerInfo: input/output node names not set"); + } + + CreateNodes(topNode); + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________ +void CombineTowerInfo::CreateNodes(PHCompositeNode* topNode) +{ + PHNodeIterator iter(topNode); + PHCompositeNode* dstNode = + dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); + + if (!dstNode) + { + throw std::runtime_error("CombineTowerInfo: DST node not found"); + } + + PHCompositeNode *DetNode = dynamic_cast(iter.findFirst("PHCompositeNode", m_detector)); + + m_towersA = findNode::getClass(topNode, m_inputNodeA); + m_towersB = findNode::getClass(topNode, m_inputNodeB); + + if (!m_towersB) + { + std::cout << "CombineTowerInfo: " <(dstNode, m_outputNode); + if (!m_towersOut) + { + m_towersOut = + dynamic_cast(m_towersA->CloneMe()); + + auto* node = new PHIODataNode( + m_towersOut, m_outputNode, "PHObject"); + + DetNode->addNode(node); + } + + if (m_towersA->size() != m_towersB->size()) + { + throw std::runtime_error("CombineTowerInfo: input containers have different sizes"); + } +} + +//____________________________________________________________________________ +int CombineTowerInfo::process_event(PHCompositeNode* /*topNode*/) +{ + const unsigned int ntowers = m_towersA->size(); + + for (unsigned int ich = 0; ich < ntowers; ++ich) + { + TowerInfo* towerA = m_towersA->get_tower_at_channel(ich); + TowerInfo* towerB = m_towersB->get_tower_at_channel(ich); + TowerInfo* towerO = m_towersOut->get_tower_at_channel(ich); + + towerO->copy_tower(towerA); + + const float e_sum = towerA->get_energy() + towerB->get_energy(); + towerO->set_energy(e_sum); + } + + return Fun4AllReturnCodes::EVENT_OK; +} + diff --git a/offline/packages/CaloEmbedding/CombineTowerInfo.h b/offline/packages/CaloEmbedding/CombineTowerInfo.h new file mode 100644 index 0000000000..ab96a918e6 --- /dev/null +++ b/offline/packages/CaloEmbedding/CombineTowerInfo.h @@ -0,0 +1,39 @@ +#ifndef COMBINETOWERINFO_H +#define COMBINETOWERINFO_H + +#include + +#include + +class PHCompositeNode; +class TowerInfoContainer; + +class CombineTowerInfo : public SubsysReco +{ + public: + explicit CombineTowerInfo(const std::string& name = "CombineTowerInfo"); + ~CombineTowerInfo() override = default; + + int InitRun(PHCompositeNode* topNode) override; + int process_event(PHCompositeNode* topNode) override; + + void set_inputNodeA(const std::string& name) { m_inputNodeA = name; } + void set_inputNodeB(const std::string& name) { m_inputNodeB = name; } + void set_outputNode(const std::string& name) { m_outputNode = name; } + void set_detector(const std::string& name) { m_detector = name; } + + private: + void CreateNodes(PHCompositeNode* topNode); + + std::string m_inputNodeA; + std::string m_inputNodeB; + std::string m_outputNode; + std::string m_detector; + + TowerInfoContainer* m_towersA{nullptr}; + TowerInfoContainer* m_towersB{nullptr}; + TowerInfoContainer* m_towersOut{nullptr}; +}; + +#endif + diff --git a/offline/packages/CaloEmbedding/CopyIODataNodes.cc b/offline/packages/CaloEmbedding/CopyIODataNodes.cc index 0d4d4536ff..08428dccfe 100644 --- a/offline/packages/CaloEmbedding/CopyIODataNodes.cc +++ b/offline/packages/CaloEmbedding/CopyIODataNodes.cc @@ -7,6 +7,9 @@ #include +#include +#include + #include #include @@ -57,6 +60,10 @@ int CopyIODataNodes::InitRun(PHCompositeNode *topNode) { CreateSyncObject(topNode, se->topNode()); } + if (m_CopyTowerInfoFlag) + { + CreateTowerInfo(topNode, se->topNode()); + } return Fun4AllReturnCodes::EVENT_OK; } @@ -89,6 +96,10 @@ int CopyIODataNodes::process_event(PHCompositeNode *topNode) { CopySyncObject(topNode, se->topNode()); } + if (m_CopyTowerInfoFlag) + { + CopyTowerInfo(topNode, se->topNode()); + } return Fun4AllReturnCodes::EVENT_OK; } @@ -293,6 +304,29 @@ void CopyIODataNodes::CopyMinimumBiasInfo(PHCompositeNode *from_topNode, PHCompo return; } +void CopyIODataNodes::CopyTowerInfo(PHCompositeNode *from_topNode, PHCompositeNode *to_topNode) +{ + TowerInfoContainer *from_towerInfo = findNode::getClass(from_topNode, from_towerInfo_name); + TowerInfoContainer *to_towerInfo = findNode::getClass( to_topNode, to_towerInfo_name); + unsigned int ntowers = from_towerInfo->size(); + for (unsigned int ch = 0; ch < ntowers; ++ch) + { + TowerInfo *from_tow = from_towerInfo->get_tower_at_channel(ch); + to_towerInfo->get_tower_at_channel(ch)->copy_tower(from_tow); + } + + if (Verbosity() > 0) + { + std::cout << "From TowerInfoContainer identify()" << std::endl; + from_towerInfo->identify(); + std::cout << "To TowerInfoCOntainer identify()" << std::endl; + to_towerInfo->identify(); + } + + return; +} + + void CopyIODataNodes::CreateMbdOut(PHCompositeNode *from_topNode, PHCompositeNode *to_topNode) { @@ -330,6 +364,36 @@ void CopyIODataNodes::CreateMbdOut(PHCompositeNode *from_topNode, PHCompositeNod } +void CopyIODataNodes::CreateTowerInfo(PHCompositeNode *from_topNode, PHCompositeNode *to_topNode) +{ + std::cout << "copying tower info" << std::endl; + TowerInfoContainer *from_towerInfo = findNode::getClass(from_topNode, from_towerInfo_name); + if (!from_towerInfo) + { + std::cout << "Could not locate TowerInfoContainer on " << from_topNode->getName() << std::endl; + m_CopyTowerInfoFlag = false; + return; + } + TowerInfoContainer *to_towerInfo = findNode::getClass(to_topNode, to_towerInfo_name); + if (!to_towerInfo) + { + PHNodeIterator iter(to_topNode); + PHCompositeNode *dstNode = dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); + if (!dstNode) + { + dstNode = new PHCompositeNode("DST"); + to_topNode->addNode(dstNode); + } + to_towerInfo = dynamic_cast(from_towerInfo->CloneMe()); + PHIODataNode *newNode = new PHIODataNode(to_towerInfo, to_towerInfo_name, "PHObject"); + dstNode->addNode(newNode); + } + return; +} + + + + void CopyIODataNodes::CopyMbdOut(PHCompositeNode *from_topNode, PHCompositeNode *to_topNode) { MbdOut *from_mbdout = findNode::getClass(from_topNode, "MbdOut"); diff --git a/offline/packages/CaloEmbedding/CopyIODataNodes.h b/offline/packages/CaloEmbedding/CopyIODataNodes.h index 08626bdafb..a6ac065a60 100644 --- a/offline/packages/CaloEmbedding/CopyIODataNodes.h +++ b/offline/packages/CaloEmbedding/CopyIODataNodes.h @@ -35,6 +35,13 @@ class CopyIODataNodes : public SubsysReco void CopyMbdOut(bool flag = true) { m_CopyMbdOutFlag = flag; } void CopyRunHeader(bool flag = true) { m_CopyRunHeaderFlag = flag; } void CopySyncObject(bool flag = true) { m_CopySyncObjectFlag = flag; } + void set_CopyTowerInfo(std::string set_from_towerInfo_name,std::string set_to_towerInfo_name) + { + from_towerInfo_name = set_from_towerInfo_name; + to_towerInfo_name = set_to_towerInfo_name; + m_CopyTowerInfoFlag = true; + return; + } private: void CreateCentralityInfo(PHCompositeNode *from_topNode, PHCompositeNode *to_topNode); @@ -56,6 +63,8 @@ class CopyIODataNodes : public SubsysReco void CreateSyncObject(PHCompositeNode *from_topNode, PHCompositeNode *to_topNode); void CopySyncObject(PHCompositeNode *from_topNode, PHCompositeNode *to_topNode); + void CopyTowerInfo(PHCompositeNode *from_topNode, PHCompositeNode *to_topNode); + void CreateTowerInfo(PHCompositeNode *from_topNode, PHCompositeNode *to_topNode); bool m_CopyCentralityInfoFlag = true; bool m_CopyEventHeaderFlag = true; @@ -64,6 +73,10 @@ class CopyIODataNodes : public SubsysReco bool m_CopyMbdOutFlag = true; bool m_CopyRunHeaderFlag = true; bool m_CopySyncObjectFlag = true; + bool m_CopyTowerInfoFlag = false; + + std::string from_towerInfo_name = {}; + std::string to_towerInfo_name = {}; }; #endif // COPYIODATANODES_H From f4e898fee68b747ea56efb42ca2ee44a20b35546 Mon Sep 17 00:00:00 2001 From: "Blair D. Seidlitz" Date: Sat, 17 Jan 2026 18:54:15 -0500 Subject: [PATCH 075/393] adding makefile update --- offline/packages/CaloEmbedding/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/offline/packages/CaloEmbedding/Makefile.am b/offline/packages/CaloEmbedding/Makefile.am index 9731b33cb8..f9dd1faa22 100644 --- a/offline/packages/CaloEmbedding/Makefile.am +++ b/offline/packages/CaloEmbedding/Makefile.am @@ -13,6 +13,7 @@ AM_LDFLAGS = \ pkginclude_HEADERS = \ caloTowerEmbed.h \ CopyIODataNodes.h \ + CombineTowerInfo.h \ HepMCCollisionVertex.h lib_LTLIBRARIES = \ @@ -21,6 +22,7 @@ lib_LTLIBRARIES = \ libCaloEmbedding_la_SOURCES = \ caloTowerEmbed.cc \ CopyIODataNodes.cc \ + CombineTowerInfo.cc \ HepMCCollisionVertex.cc libCaloEmbedding_la_LIBADD = \ From 61ecab4cbfa7b23ed2a5736ab43dbb9a32e54c8c Mon Sep 17 00:00:00 2001 From: "Blair D. Seidlitz" Date: Sat, 17 Jan 2026 18:56:10 -0500 Subject: [PATCH 076/393] extra feat in triggerskimmer --- .../packages/Skimmers/Trigger/TriggerDSTSkimmer.cc | 12 +++++++++++- .../packages/Skimmers/Trigger/TriggerDSTSkimmer.h | 12 ++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/offline/packages/Skimmers/Trigger/TriggerDSTSkimmer.cc b/offline/packages/Skimmers/Trigger/TriggerDSTSkimmer.cc index b519fd472e..224d172a24 100644 --- a/offline/packages/Skimmers/Trigger/TriggerDSTSkimmer.cc +++ b/offline/packages/Skimmers/Trigger/TriggerDSTSkimmer.cc @@ -20,6 +20,12 @@ TriggerDSTSkimmer::TriggerDSTSkimmer(const std::string &name) //____________________________________________________________________________.. int TriggerDSTSkimmer::process_event(PHCompositeNode *topNode) { + + if ((accepted_events >= max_accept) && use_max_accept) + { + return Fun4AllReturnCodes::ABORTEVENT; + } + if (Verbosity() > 0) { if (ievent % 1000 == 0) @@ -45,7 +51,7 @@ int TriggerDSTSkimmer::process_event(PHCompositeNode *topNode) if (n_trigger_index != 0) { bool trigger_fired = false; - Gl1Packet *_gl1PacketInfo = findNode::getClass(topNode, "GL1Packet"); + Gl1Packet *_gl1PacketInfo = findNode::getClass(topNode, 14001); int gl1_trigger_vector_scaled[64] = {0}; if (_gl1PacketInfo) { @@ -61,6 +67,7 @@ int TriggerDSTSkimmer::process_event(PHCompositeNode *topNode) std::cout << "TriggerDSTSkimmer::process_event - Error - Can't find Trigger Node Gl1Packet therefore no selection can be made" << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } + for (int it = 0; it < n_trigger_index; ++it) { if (gl1_trigger_vector_scaled[m_trigger_index[it]] == 1) @@ -74,5 +81,8 @@ int TriggerDSTSkimmer::process_event(PHCompositeNode *topNode) return Fun4AllReturnCodes::ABORTEVENT; } } + + accepted_events++; + return Fun4AllReturnCodes::EVENT_OK; } diff --git a/offline/packages/Skimmers/Trigger/TriggerDSTSkimmer.h b/offline/packages/Skimmers/Trigger/TriggerDSTSkimmer.h index dfb2c47a7c..9919df06b7 100644 --- a/offline/packages/Skimmers/Trigger/TriggerDSTSkimmer.h +++ b/offline/packages/Skimmers/Trigger/TriggerDSTSkimmer.h @@ -22,10 +22,22 @@ class TriggerDSTSkimmer : public SubsysReco void SetTrigger(std::vector &trigger_vector) {m_trigger_index = trigger_vector;} + void set_accept_max(int max_events) + { + use_max_accept = true; + max_accept = max_events; + return; + } + private: std::vector m_trigger_index{10}; int ievent{0}; + + int accepted_events{0}; + int max_accept{0}; + bool use_max_accept{false}; + }; #endif // JETDSTSKIMMER_H From ad7235ea509154e911069064771aa383d4052a90 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Sat, 17 Jan 2026 20:31:42 -0500 Subject: [PATCH 077/393] clang-tidy --- offline/packages/trackreco/DSTClusterPruning.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/trackreco/DSTClusterPruning.cc b/offline/packages/trackreco/DSTClusterPruning.cc index 6314bf50b2..36bbe4fd0f 100644 --- a/offline/packages/trackreco/DSTClusterPruning.cc +++ b/offline/packages/trackreco/DSTClusterPruning.cc @@ -192,7 +192,7 @@ void DSTClusterPruning::prune_clusters() for (auto key_iter = trackseed->begin_cluster_keys(); key_iter != trackseed->end_cluster_keys(); ++key_iter) { const auto& cluster_key = *key_iter; - auto cluster = m_cluster_map->findCluster(cluster_key); + auto *cluster = m_cluster_map->findCluster(cluster_key); if (!cluster) { std::cout << "DSTClusterPruning::evaluate_tracks - unable to find cluster for key " << cluster_key << std::endl; From 2963c36785cc61b40722e0139177340f09977c7a Mon Sep 17 00:00:00 2001 From: Hao-Ren Jheng Date: Sun, 18 Jan 2026 12:42:50 -0500 Subject: [PATCH 078/393] use short int for vertex beam crossing --- offline/packages/globalvertex/MbdVertex.h | 4 ++-- offline/packages/globalvertex/MbdVertexv2.h | 6 +++--- offline/packages/globalvertex/SvtxVertex.h | 3 +++ offline/packages/globalvertex/SvtxVertex_v2.h | 6 +++--- offline/packages/globalvertex/Vertex.h | 4 ++-- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/offline/packages/globalvertex/MbdVertex.h b/offline/packages/globalvertex/MbdVertex.h index 6d0900b768..bda5c74597 100644 --- a/offline/packages/globalvertex/MbdVertex.h +++ b/offline/packages/globalvertex/MbdVertex.h @@ -36,8 +36,8 @@ class MbdVertex : public Vertex virtual float get_z_err() const override { return std::numeric_limits::quiet_NaN(); } virtual void set_z_err(float) override {} - virtual unsigned int get_beam_crossing() const override { return std::numeric_limits::max(); } - virtual void set_beam_crossing(unsigned int) override {} + virtual short int get_beam_crossing() const override { return std::numeric_limits::max(); } + virtual void set_beam_crossing(short int) override {} virtual void set_bbc_ns(int, int, float, float) override {} virtual int get_bbc_npmt(int) const override { return std::numeric_limits::max(); } diff --git a/offline/packages/globalvertex/MbdVertexv2.h b/offline/packages/globalvertex/MbdVertexv2.h index bee34059e4..d0aac0f70b 100644 --- a/offline/packages/globalvertex/MbdVertexv2.h +++ b/offline/packages/globalvertex/MbdVertexv2.h @@ -44,12 +44,12 @@ class MbdVertexv2 : public MbdVertex float get_position(unsigned int coor) const override; - unsigned int get_beam_crossing() const override { return _bco; } - void set_beam_crossing(unsigned int bco) override { _bco = bco; } + short int get_beam_crossing() const override { return _bco; } + void set_beam_crossing(short int bco) override { _bco = bco; } private: unsigned int _id{std::numeric_limits::max()}; //< unique identifier within container - unsigned int _bco{std::numeric_limits::max()}; //< global bco + short int _bco{std::numeric_limits::max()}; //< global bco float _t{std::numeric_limits::quiet_NaN()}; //< collision time float _t_err{std::numeric_limits::quiet_NaN()}; //< collision time uncertainty float _z{std::numeric_limits::quiet_NaN()}; //< collision position z diff --git a/offline/packages/globalvertex/SvtxVertex.h b/offline/packages/globalvertex/SvtxVertex.h index cd9c77454c..5006784f55 100644 --- a/offline/packages/globalvertex/SvtxVertex.h +++ b/offline/packages/globalvertex/SvtxVertex.h @@ -56,6 +56,9 @@ class SvtxVertex : public Vertex virtual float get_error(unsigned int, unsigned int) const override { return std::numeric_limits::quiet_NaN(); } virtual void set_error(unsigned int, unsigned int, float) override {} + virtual short int get_beam_crossing() const override { return std::numeric_limits::max(); } + virtual void set_beam_crossing(short int) override {} + // // associated track ids methods // diff --git a/offline/packages/globalvertex/SvtxVertex_v2.h b/offline/packages/globalvertex/SvtxVertex_v2.h index 24ccbfc0ca..d1bf04e0b4 100644 --- a/offline/packages/globalvertex/SvtxVertex_v2.h +++ b/offline/packages/globalvertex/SvtxVertex_v2.h @@ -54,8 +54,8 @@ class SvtxVertex_v2 : public SvtxVertex float get_error(unsigned int i, unsigned int j) const override; //< get vertex error covar void set_error(unsigned int i, unsigned int j, float value) override; //< set vertex error covar - unsigned int get_beam_crossing() const override { return _beamcrossing; } - void set_beam_crossing(unsigned int cross) override { _beamcrossing = cross; } + short int get_beam_crossing() const override { return _beamcrossing; } + void set_beam_crossing(short int cross) override { _beamcrossing = cross; } // // associated track ids methods @@ -82,7 +82,7 @@ class SvtxVertex_v2 : public SvtxVertex unsigned int _ndof{std::numeric_limits::max()}; //< degrees of freedom float _err[6]{}; //< error covariance matrix (packed storage) (+/- cm^2) std::set _track_ids; //< list of track ids - unsigned int _beamcrossing{std::numeric_limits::max()}; + short int _beamcrossing{std::numeric_limits::max()}; ClassDefOverride(SvtxVertex_v2, 2); }; diff --git a/offline/packages/globalvertex/Vertex.h b/offline/packages/globalvertex/Vertex.h index 7bbfa5f381..e475bfb95d 100644 --- a/offline/packages/globalvertex/Vertex.h +++ b/offline/packages/globalvertex/Vertex.h @@ -62,8 +62,8 @@ class Vertex : public PHObject virtual void set_error(unsigned int /*i*/, unsigned int /*j*/, float /*value*/) {} // beam crossing methods - virtual unsigned int get_beam_crossing() const { return std::numeric_limits::max(); } - virtual void set_beam_crossing(unsigned int) {} + virtual short int get_beam_crossing() const { return std::numeric_limits::max(); } + virtual void set_beam_crossing(short int) {} // bbcvertex methods virtual void set_bbc_ns(int, int, float, float) {} From 6242823fcc23e82feae15083c5a113101ffa731e Mon Sep 17 00:00:00 2001 From: "Blair D. Seidlitz" Date: Sun, 18 Jan 2026 15:06:15 -0500 Subject: [PATCH 079/393] add const ref --- offline/packages/CaloEmbedding/CopyIODataNodes.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/CaloEmbedding/CopyIODataNodes.h b/offline/packages/CaloEmbedding/CopyIODataNodes.h index a6ac065a60..5045792a2d 100644 --- a/offline/packages/CaloEmbedding/CopyIODataNodes.h +++ b/offline/packages/CaloEmbedding/CopyIODataNodes.h @@ -35,7 +35,7 @@ class CopyIODataNodes : public SubsysReco void CopyMbdOut(bool flag = true) { m_CopyMbdOutFlag = flag; } void CopyRunHeader(bool flag = true) { m_CopyRunHeaderFlag = flag; } void CopySyncObject(bool flag = true) { m_CopySyncObjectFlag = flag; } - void set_CopyTowerInfo(std::string set_from_towerInfo_name,std::string set_to_towerInfo_name) + void set_CopyTowerInfo(const std::string& set_from_towerInfo_name,const std::string& set_to_towerInfo_name) { from_towerInfo_name = set_from_towerInfo_name; to_towerInfo_name = set_to_towerInfo_name; From 2601ddcfccca596143f646f252303cd904a81c4a Mon Sep 17 00:00:00 2001 From: JAEBEOm PARK Date: Mon, 19 Jan 2026 09:47:25 -0500 Subject: [PATCH 080/393] minor fix for event skipping --- .../fun4allraw/SingleTriggeredInput.cc | 99 ++++++++++++++++++- .../fun4allraw/SingleTriggeredInput.h | 7 +- 2 files changed, 97 insertions(+), 9 deletions(-) diff --git a/offline/framework/fun4allraw/SingleTriggeredInput.cc b/offline/framework/fun4allraw/SingleTriggeredInput.cc index 3bb6b30a2b..80e9f49a64 100644 --- a/offline/framework/fun4allraw/SingleTriggeredInput.cc +++ b/offline/framework/fun4allraw/SingleTriggeredInput.cc @@ -352,6 +352,12 @@ int SingleTriggeredInput::FillEventVector() m_bclkarray_map[pid][0] = tmp; m_bclkdiffarray_map[pid].fill(std::numeric_limits::max()); + static bool firstclockarray=true; + if(firstclockarray){ + std::cout << "first clock call pid " << pid << " m_bclkarray_map[pid][0] : " << m_bclkarray_map[pid][0] << std::endl; + firstclockarray=false; + } + if ( representative_pid == -1 ) { representative_pid = pid; @@ -368,12 +374,17 @@ int SingleTriggeredInput::FillEventVector() while (i < pooldepth) { Event* evt{nullptr}; + bool skiptrace = false; if (this != Gl1Input()) { auto* gl1 = dynamic_cast(Gl1Input()); if (gl1) { int nskip = gl1->GetGl1SkipArray()[i]; + if(nskip >0) + { + skiptrace = true; + } while (nskip > 0) { @@ -391,6 +402,7 @@ int SingleTriggeredInput::FillEventVector() if (skip_evt->getEvtType() != DATAEVENT) { + delete skip_evt; continue; } @@ -412,14 +424,91 @@ int SingleTriggeredInput::FillEventVector() { if (Verbosity() > 0) { - std::cout << Name() << ": Early stop of SEB skip after " << (gl1->GetGl1SkipArray()[i] - nskip) << " from intial " << gl1->GetGl1SkipArray()[i] << " events." << std::endl; + std::cout << Name() << ": Early stop in pool " << i << " of SEB skip after " << (gl1->GetGl1SkipArray()[i] - nskip) << " from intial " << gl1->GetGl1SkipArray()[i] << " events. gl1diff vs sebdiff : " << gl1_diff << " vs " << seb_diff << std::endl; } evt = skip_evt; + skiptrace = false; break; } delete skip_evt; nskip--; } + + if(skiptrace) + { + evt = GetEventIterator()->getNextEvent(); + while (!evt) + { + fileclose(); + if (OpenNextFile() == InputFileHandlerReturnCodes::FAILURE) + { + FilesDone(1); + return -1; + } + evt = GetEventIterator()->getNextEvent(); + } + if (evt->getEvtType() != DATAEVENT) + { + if (Verbosity() > 0) + { + std::cout << Name() << " dropping non data event: " << evt->getEvtSequence() << std::endl; + } + delete evt; + continue; + } + + Packet* pkt = evt->getPacket(representative_pid); + if (!pkt) + { + std::cout << "representative packet invalid inside skiptrace.. continuing.." << std::endl; + continue; + } + FillPacketClock(evt, pkt, i); + uint64_t seb_diff = m_bclkdiffarray_map[representative_pid][i]; + int gl1pid = Gl1Input()->m_bclkdiffarray_map.begin()->first; + uint64_t gl1_diff = gl1->m_bclkdiffarray_map[gl1pid][i]; + + bool clockconsistency=true; + if (seb_diff != gl1_diff) + { + clockconsistency=false; + int clockconstcount = 0; + while(!clockconsistency && clockconstcount<5) + { + std::cout << Name() << ": Still inconsistent clock diff after Gl1 drop. gl1diff vs sebdiff : " << gl1_diff << " vs " << seb_diff << std::endl; + delete pkt; + delete evt; + evt = GetEventIterator()->getNextEvent(); + while (!evt) + { + fileclose(); + if (OpenNextFile() == InputFileHandlerReturnCodes::FAILURE) + { + FilesDone(1); + return -1; + } + evt = GetEventIterator()->getNextEvent(); + } + pkt = evt->getPacket(representative_pid); + if (!pkt) + { + std::cout << "representative packet invalid inside skiptrace.. continuing.." << std::endl; + continue; + } + + FillPacketClock(evt, pkt, i); + uint64_t seb_diff_next = m_bclkdiffarray_map[representative_pid][i]; + uint64_t gl1_diff_next = gl1->m_bclkdiffarray_map[gl1pid][i]; + std::cout << "seb_diff_next : " << seb_diff_next << " , gl1_diff_next : " << gl1_diff_next << std::endl; + if(seb_diff_next == gl1_diff_next) + { + clockconsistency=true; + std::cout << Name() << " : recovered by additional skip in skiptrace" << std::endl; + } + clockconstcount++; + } + } + } } } @@ -485,14 +574,16 @@ int SingleTriggeredInput::FillEventVector() } FillPacketClock(thisevt, pkt, i); m_PacketEventDeque[pid].push_back(thisevt); + delete pkt; - + if (representative_pid == -1 && m_PacketShiftOffset[pid] == 0) { representative_pid = pid; } } i++; + eventcounter++; } size_t minSize = pooldepth; @@ -1116,16 +1207,15 @@ int SingleTriggeredInput::ReadEvent() [](const std::pair& p) { return p.second == 0; }); std::set events_to_delete; - for (auto& [pid, dq] : m_PacketEventDeque) { if(m_PacketAlignmentProblem[pid]) { continue; } + Event* evt = dq.front(); Packet* packet = evt->getPacket(pid); - int packet_id = packet->getIdentifier(); if (packet_id != pid) { @@ -1137,7 +1227,6 @@ int SingleTriggeredInput::ReadEvent() CaloPacket *newhit = findNode::getClass(m_topNode, packet_id); newhit->Reset(); - if (m_DitchPackets.contains(packet_id) && m_DitchPackets[packet_id].contains(0)) { newhit->setStatus(OfflinePacket::PACKET_DROPPED); diff --git a/offline/framework/fun4allraw/SingleTriggeredInput.h b/offline/framework/fun4allraw/SingleTriggeredInput.h index 088be73bef..d7d825b02a 100644 --- a/offline/framework/fun4allraw/SingleTriggeredInput.h +++ b/offline/framework/fun4allraw/SingleTriggeredInput.h @@ -34,9 +34,6 @@ class SingleTriggeredInput : public Fun4AllBase, public InputFileHandler virtual void FillPool(); virtual void RunNumber(const int runno) { m_RunNumber = runno; } virtual int RunNumber() const { return m_RunNumber; } - virtual void EventNumber(const int i) { m_EventNumber = i; } - virtual int EventNumber() const { return m_EventNumber; } - virtual int EventsInThisFile() const { return m_EventsThisFile; } virtual int fileopen(const std::string &filename) override; virtual int fileclose() override; virtual int AllDone() const { return m_AllDone; } @@ -45,6 +42,8 @@ class SingleTriggeredInput : public Fun4AllBase, public InputFileHandler virtual void FilesDone(const int i) { m_FilesDone = i; } virtual void EventAlignmentProblem(const int i) { m_EventAlignmentProblem = i; } virtual int EventAlignmentProblem() const { return m_EventAlignmentProblem; } + virtual void EventNumber(const int i) { m_EventNumber = i; } + virtual int EventNumber() const { return m_EventNumber; } virtual void CreateDSTNodes(Event *evt); // these ones are used directly by the derived classes, maybe later // move to cleaner accessors @@ -94,7 +93,6 @@ class SingleTriggeredInput : public Fun4AllBase, public InputFileHandler int m_AllDone{0}; uint64_t m_Event{0}; int m_EventNumber{0}; - int m_EventsThisFile{0}; int m_EventAlignmentProblem{0}; int m_FilesDone{0}; int m_LastEvent{std::numeric_limits::max()}; @@ -114,6 +112,7 @@ class SingleTriggeredInput : public Fun4AllBase, public InputFileHandler std::map m_PacketAlignmentProblem; std::map m_PrevPoolLastDiffBad; std::map m_PreviousValidBCOMap; + long long eventcounter{0}; }; #endif From 6caf8c95c3dbef1a1f984d1264131bb0c5b22bfe Mon Sep 17 00:00:00 2001 From: Jin Huang Date: Mon, 19 Jan 2026 13:49:08 -0500 Subject: [PATCH 081/393] Add workflow to fix EOF newlines in docstring PRs This workflow fixes missing final newlines in CodeRabbit docstring pull requests by checking the relevant files and appending a newline if necessary. --- .../fix-eof-newline-coderabbit-docstrings.yml | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 .github/workflows/fix-eof-newline-coderabbit-docstrings.yml diff --git a/.github/workflows/fix-eof-newline-coderabbit-docstrings.yml b/.github/workflows/fix-eof-newline-coderabbit-docstrings.yml new file mode 100644 index 0000000000..75d43e65e5 --- /dev/null +++ b/.github/workflows/fix-eof-newline-coderabbit-docstrings.yml @@ -0,0 +1,106 @@ +name: Fix missing final newline (CodeRabbit docstring PRs) + +on: + pull_request_target: + types: [opened, synchronize, reopened] + +permissions: + contents: write + pull-requests: read + +jobs: + fix_eof_newline: + runs-on: ubuntu-latest + steps: + - name: Guard - only CodeRabbit docstring PRs from same repo + id: guard + shell: bash + run: | + set -euo pipefail + + AUTHOR='${{ github.event.pull_request.user.login }}' + BASE_REPO='${{ github.event.pull_request.base.repo.full_name }}' + HEAD_REPO='${{ github.event.pull_request.head.repo.full_name }}' + TITLE='${{ github.event.pull_request.title }}' + + if [[ "$AUTHOR" != "coderabbitai[bot]" ]]; then + echo "run=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + + # Safety: only push to branches within the same repo + if [[ "$BASE_REPO" != "$HEAD_REPO" ]]; then + echo "run=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + + # only run for docstring PRs + if ! echo "$TITLE" | grep -qi "docstring"; then + echo "run=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + + echo "run=true" >> "$GITHUB_OUTPUT" + + - name: Checkout PR head + if: steps.guard.outputs.run == 'true' + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.ref }} + repository: ${{ github.event.pull_request.head.repo.full_name }} + fetch-depth: 0 + + - name: Append final newline when missing (changed files only) + if: steps.guard.outputs.run == 'true' + shell: bash + run: | + set -euo pipefail + + BASE_SHA="${{ github.event.pull_request.base.sha }}" + HEAD_SHA="${{ github.event.pull_request.head.sha }}" + + files=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA" -- \ + '*.C' '*.c' '*.cc' '*.cpp' '*.cxx' '*.h' '*.hh' '*.hpp' '*.hxx' || true) + + if [[ -z "${files}" ]]; then + echo "No relevant files changed." + exit 0 + fi + + changed=0 + for f in $files; do + [[ -f "$f" ]] || continue + + # For non-empty files: ensure last byte is '\n' + if [[ -s "$f" ]]; then + last_byte="$(tail -c 1 "$f" || true)" + if [[ "$last_byte" != $'\n' ]]; then + printf '\n' >> "$f" + echo "Fixed EOF newline: $f" + changed=1 + fi + fi + done + + if [[ "$changed" -eq 0 ]]; then + echo "All files already end with a newline." + exit 0 + fi + + git status --porcelain + git add -A + + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + git commit -m "Fix missing final newline in docstring PR" + + - name: Push fix commit back to PR branch + if: steps.guard.outputs.run == 'true' + shell: bash + run: | + set -euo pipefail + # If no commit was created, pushing will fail; so only push if HEAD is ahead. + if git rev-parse HEAD~1 >/dev/null 2>&1; then + git push origin "HEAD:${{ github.event.pull_request.head.ref }}" + fi From 57a9dd2851c2a1e8a786d54258851b94feb2a060 Mon Sep 17 00:00:00 2001 From: "Blair D. Seidlitz" Date: Mon, 19 Jan 2026 15:04:19 -0500 Subject: [PATCH 082/393] changing ADC threshold for time calib --- offline/QA/Calorimeters/CaloValid.cc | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/offline/QA/Calorimeters/CaloValid.cc b/offline/QA/Calorimeters/CaloValid.cc index 19c834bdab..ab2f355c59 100644 --- a/offline/QA/Calorimeters/CaloValid.cc +++ b/offline/QA/Calorimeters/CaloValid.cc @@ -176,7 +176,8 @@ int CaloValid::process_towers(PHCompositeNode* topNode) float ihcaldownscale; float ohcaldownscale; float mbddownscale; - float adc_threshold; + float adc_threshold_hcal; + float adc_threshold_emcal; float emcal_hit_threshold; float emcal_highhit_threshold; float ohcal_hit_threshold; @@ -190,7 +191,8 @@ int CaloValid::process_towers(PHCompositeNode* topNode) ihcaldownscale = 55000. / 300.; ohcaldownscale = 265000. / 600.; mbddownscale = 2800.0; - adc_threshold = 15.; + adc_threshold_hcal = 30; + adc_threshold_emcal = 70; emcal_hit_threshold = 0.5; // GeV ohcal_hit_threshold = 0.5; @@ -206,7 +208,8 @@ int CaloValid::process_towers(PHCompositeNode* topNode) ihcaldownscale = 4000. / 300.; ohcaldownscale = 25000. / 600.; mbddownscale = 200.0; - adc_threshold = 100.; + adc_threshold_hcal = 30; + adc_threshold_emcal = 70; emcal_hit_threshold = 0.5; // GeV ohcal_hit_threshold = 0.5; @@ -528,7 +531,7 @@ int CaloValid::process_towers(PHCompositeNode* topNode) } float raw_energy = tower->get_energy(); - if (raw_energy > adc_threshold) + if (raw_energy > adc_threshold_emcal) { h_cemc_etaphi_fracHitADC->Fill(ieta, iphi, 1); h_cemc_etaphi_time_raw->Fill(ieta, iphi, raw_time); @@ -558,7 +561,7 @@ int CaloValid::process_towers(PHCompositeNode* topNode) } float raw_energy = tower->get_energy(); - if (raw_energy > adc_threshold) + if (raw_energy > adc_threshold_hcal) { h_ohcal_etaphi_time_raw->Fill(ieta, iphi, raw_time); h_ohcal_etaphi_fracHitADC->Fill(ieta, iphi, 1); @@ -588,7 +591,7 @@ int CaloValid::process_towers(PHCompositeNode* topNode) } float raw_energy = tower->get_energy(); - if (raw_energy > adc_threshold) + if (raw_energy > adc_threshold_hcal) { h_ihcal_etaphi_time_raw->Fill(ieta, iphi, raw_time); h_ihcal_etaphi_fracHitADC->Fill(ieta, iphi, 1); From d50b1e1c04631a0bfe6f3bded4f54a8d353b4291 Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Mon, 19 Jan 2026 20:10:30 +0000 Subject: [PATCH 083/393] =?UTF-8?q?=F0=9F=93=9D=20Add=20docstrings=20to=20?= =?UTF-8?q?`embed`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Docstrings generation was requested by @blackcathj. * https://github.com/sPHENIX-Collaboration/coresoftware/pull/4125#issuecomment-3769948215 The following files were modified: * `offline/QA/Calorimeters/CaloValid.cc` --- offline/QA/Calorimeters/CaloValid.cc | 31 +++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/offline/QA/Calorimeters/CaloValid.cc b/offline/QA/Calorimeters/CaloValid.cc index 19c834bdab..dcd3674503 100644 --- a/offline/QA/Calorimeters/CaloValid.cc +++ b/offline/QA/Calorimeters/CaloValid.cc @@ -142,6 +142,20 @@ int CaloValid::process_event(PHCompositeNode* topNode) return Fun4AllReturnCodes::EVENT_OK; } +/** + * @brief Process event towers, triggers, MBD, and clusters to populate QA histograms. + * + * Reads event header, vertex, trigger (GL1), calibrated and raw tower containers for + * CEMC/HCAL (inner/outer), MBD PMTs, and CEMC clusters; computes per-detector totals, + * downscaled correlations, per-channel and per-tower QA, pi0 candidate invariant masses, + * and trigger/alignment summaries, then fills the corresponding histograms and profiles. + * + * @param topNode Top-level PHCompositeNode containing event data (towers, clusters, + * trigger/GL1 packets, vertex map, and MBD PMTs). + * @return Fun4AllReturnCodes::EVENT_OK on success; may return other Fun4All return codes + * or 0 on error conditions encountered while processing nodes. + * + */ int CaloValid::process_towers(PHCompositeNode* topNode) { //---------------------------Event header--------------------------------// @@ -176,7 +190,8 @@ int CaloValid::process_towers(PHCompositeNode* topNode) float ihcaldownscale; float ohcaldownscale; float mbddownscale; - float adc_threshold; + float adc_threshold_hcal; + float adc_threshold_emcal; float emcal_hit_threshold; float emcal_highhit_threshold; float ohcal_hit_threshold; @@ -190,7 +205,8 @@ int CaloValid::process_towers(PHCompositeNode* topNode) ihcaldownscale = 55000. / 300.; ohcaldownscale = 265000. / 600.; mbddownscale = 2800.0; - adc_threshold = 15.; + adc_threshold_hcal = 30; + adc_threshold_emcal = 70; emcal_hit_threshold = 0.5; // GeV ohcal_hit_threshold = 0.5; @@ -206,7 +222,8 @@ int CaloValid::process_towers(PHCompositeNode* topNode) ihcaldownscale = 4000. / 300.; ohcaldownscale = 25000. / 600.; mbddownscale = 200.0; - adc_threshold = 100.; + adc_threshold_hcal = 30; + adc_threshold_emcal = 70; emcal_hit_threshold = 0.5; // GeV ohcal_hit_threshold = 0.5; @@ -528,7 +545,7 @@ int CaloValid::process_towers(PHCompositeNode* topNode) } float raw_energy = tower->get_energy(); - if (raw_energy > adc_threshold) + if (raw_energy > adc_threshold_emcal) { h_cemc_etaphi_fracHitADC->Fill(ieta, iphi, 1); h_cemc_etaphi_time_raw->Fill(ieta, iphi, raw_time); @@ -558,7 +575,7 @@ int CaloValid::process_towers(PHCompositeNode* topNode) } float raw_energy = tower->get_energy(); - if (raw_energy > adc_threshold) + if (raw_energy > adc_threshold_hcal) { h_ohcal_etaphi_time_raw->Fill(ieta, iphi, raw_time); h_ohcal_etaphi_fracHitADC->Fill(ieta, iphi, 1); @@ -588,7 +605,7 @@ int CaloValid::process_towers(PHCompositeNode* topNode) } float raw_energy = tower->get_energy(); - if (raw_energy > adc_threshold) + if (raw_energy > adc_threshold_hcal) { h_ihcal_etaphi_time_raw->Fill(ieta, iphi, raw_time); h_ihcal_etaphi_fracHitADC->Fill(ieta, iphi, 1); @@ -1301,4 +1318,4 @@ void CaloValid::createHistos() } hm->registerHisto(h_triggerVec); hm->registerHisto(pr_ldClus_trig); -} +} \ No newline at end of file From 0e1aa45113e0f01ec9abc6397dc2b846d349ea5e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 19 Jan 2026 20:10:47 +0000 Subject: [PATCH 084/393] Fix missing final newline in docstring PR --- offline/QA/Calorimeters/CaloValid.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/QA/Calorimeters/CaloValid.cc b/offline/QA/Calorimeters/CaloValid.cc index dcd3674503..c51f75c200 100644 --- a/offline/QA/Calorimeters/CaloValid.cc +++ b/offline/QA/Calorimeters/CaloValid.cc @@ -1318,4 +1318,4 @@ void CaloValid::createHistos() } hm->registerHisto(h_triggerVec); hm->registerHisto(pr_ldClus_trig); -} \ No newline at end of file +} From 147009b249d97bd8d5ef7d60f25800e833763e49 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Tue, 20 Jan 2026 09:45:44 -0500 Subject: [PATCH 085/393] add api to reject clusters on edge, reject clusters with edge>0 --- offline/packages/trackreco/MakeSourceLinks.cc | 482 ++++++++++-------- offline/packages/trackreco/MakeSourceLinks.h | 56 +- offline/packages/trackreco/PHActsTrkFitter.cc | 2 + offline/packages/trackreco/PHActsTrkFitter.h | 3 +- 4 files changed, 291 insertions(+), 252 deletions(-) diff --git a/offline/packages/trackreco/MakeSourceLinks.cc b/offline/packages/trackreco/MakeSourceLinks.cc index efbbe92853..5bb00293a9 100644 --- a/offline/packages/trackreco/MakeSourceLinks.cc +++ b/offline/packages/trackreco/MakeSourceLinks.cc @@ -1,13 +1,12 @@ #include "MakeSourceLinks.h" -#include +#include +#include #include #include #include -#include #include #include -#include #include #include @@ -16,8 +15,8 @@ #include #include -#include #include +#include #include @@ -29,26 +28,25 @@ namespace { - template + template inline T square(const T& x) { return x * x; } - [[maybe_unused]] std::ostream& operator << (std::ostream& out, const Acts::Vector3& v ) + [[maybe_unused]] std::ostream& operator<<(std::ostream& out, const Acts::Vector3& v) { out << "(" << v.x() << ", " << v.y() << ", " << v.z() << ")"; return out; } - - [[maybe_unused]] std::ostream& operator << (std::ostream& out, const Acts::Vector2& v ) + [[maybe_unused]] std::ostream& operator<<(std::ostream& out, const Acts::Vector2& v) { out << "(" << v.x() << ", " << v.y() << ")"; return out; } -} +} // namespace void MakeSourceLinks::initialize(PHG4TpcGeomContainer* cellgeo) { @@ -57,30 +55,33 @@ void MakeSourceLinks::initialize(PHG4TpcGeomContainer* cellgeo) { _clusterMover.initialize_geometry(cellgeo); } - } - //___________________________________________________________________________________ +//___________________________________________________________________________________ SourceLinkVec MakeSourceLinks::getSourceLinks( - TrackSeed* track, - ActsTrackFittingAlgorithm::MeasurementContainer& measurements, - TrkrClusterContainer* clusterContainer, - ActsGeometry* tGeometry, - const TpcGlobalPositionWrapper& globalPositionWrapper, - alignmentTransformationContainer* transformMapTransient, - std::set< Acts::GeometryIdentifier>& transient_id_set, - short int crossing - ) + TrackSeed* track, + ActsTrackFittingAlgorithm::MeasurementContainer& measurements, + TrkrClusterContainer* clusterContainer, + ActsGeometry* tGeometry, + const TpcGlobalPositionWrapper& globalPositionWrapper, + alignmentTransformationContainer* transformMapTransient, + std::set& transient_id_set, + short int crossing) { - if(m_verbosity > 1) { std::cout << "Entering MakeSourceLinks::getSourceLinks " << std::endl; } + if (m_verbosity > 1) + { + std::cout << "Entering MakeSourceLinks::getSourceLinks " << std::endl; + } SourceLinkVec sourcelinks; if (m_pp_mode && crossing == SHRT_MAX) { // Need to skip this in the pp case, for AuAu it should not happen - if(m_verbosity > 1) - { std::cout << "Seed has no crossing, and in pp mode: skip this seed" << std::endl; } + if (m_verbosity > 1) + { + std::cout << "Seed has no crossing, and in pp mode: skip this seed" << std::endl; + } return sourcelinks; } @@ -98,82 +99,88 @@ SourceLinkVec MakeSourceLinks::getSourceLinks( auto key = *clusIter; auto cluster = clusterContainer->findCluster(key); if (!cluster) + { + if (m_verbosity > 0) { - if (m_verbosity > 0) - {std::cout << "MakeSourceLinks: Failed to get cluster with key " << key << " for track seed" << std::endl;} - continue; + std::cout << "MakeSourceLinks: Failed to get cluster with key " << key << " for track seed" << std::endl; } - else - if(m_verbosity > 0) - {std::cout << "MakeSourceLinks: Found cluster with key " << key << " for track seed " << std::endl;} - + continue; + } + else if (m_verbosity > 0) + { + std::cout << "MakeSourceLinks: Found cluster with key " << key << " for track seed " << std::endl; + } + /// Make a safety check for clusters that couldn't be attached to a surface auto surf = tGeometry->maps().getSurface(key, cluster); if (!surf) - { - continue; - } - + { + continue; + } + const unsigned int trkrid = TrkrDefs::getTrkrId(key); const unsigned int clus_layer = TrkrDefs::getLayer(key); - if(m_verbosity > 1) { std::cout << " Cluster key " << key << " layer " << clus_layer << " trkrid " << trkrid << " crossing " << crossing << std::endl; } + if (m_verbosity > 1) + { + std::cout << " Cluster key " << key << " layer " << clus_layer << " trkrid " << trkrid << " crossing " << crossing << std::endl; + } // For the TPC, cluster z has to be corrected for the crossing z offset, distortion, and TOF z offset // we do this by modifying the fake surface transform, to move the cluster to the corrected position if (trkrid == TrkrDefs::tpcId) { - Acts::Vector3 global = globalPositionWrapper.getGlobalPositionDistortionCorrected(key, cluster, crossing ); + Acts::Vector3 global = globalPositionWrapper.getGlobalPositionDistortionCorrected(key, cluster, crossing); Acts::Vector3 nominal_global_in = tGeometry->getGlobalPosition(key, cluster); Acts::Vector3 global_in = tGeometry->getGlobalPosition(key, cluster); // The wrapper returns the global position corrected for distortion and the cluster crossing z offset // The cluster z crossing correction has to be applied to the nominal global position (global_in) - double cluster_crossing_corrected_z= TpcClusterZCrossingCorrection::correctZ(global_in.z(), TpcDefs::getSide(key), crossing); - double crossing_correction = cluster_crossing_corrected_z - global_in.z(); + double cluster_crossing_corrected_z = TpcClusterZCrossingCorrection::correctZ(global_in.z(), TpcDefs::getSide(key), crossing); + double crossing_correction = cluster_crossing_corrected_z - global_in.z(); global_in.z() = cluster_crossing_corrected_z; - - if(m_verbosity > 2) + + if (m_verbosity > 2) { - unsigned int this_layer = TrkrDefs::getLayer(key); - unsigned int this_side = TpcDefs::getSide(key); - if(this_layer == 28) - { - std::cout << " crossing " << crossing << " layer " << this_layer << " side " << this_side << " clusterkey " << key << std::endl - << " nominal global_in " << nominal_global_in(0) << " " << nominal_global_in(1) << " " << nominal_global_in(2) - << " global_in " << global_in(0) << " " << global_in(1) << " " << global_in(2) - << " corr glob " << global(0) << " " << global(1) << " " << global(2) << std::endl - << " distortion " << global(0)-global_in(0) << " " - << global(1) - global_in(1) << " " << global(2) - global_in(2) - << " cluster crossing z correction " << crossing_correction - << std::endl; - } + unsigned int this_layer = TrkrDefs::getLayer(key); + unsigned int this_side = TpcDefs::getSide(key); + if (this_layer == 28) + { + std::cout << " crossing " << crossing << " layer " << this_layer << " side " << this_side << " clusterkey " << key << std::endl + << " nominal global_in " << nominal_global_in(0) << " " << nominal_global_in(1) << " " << nominal_global_in(2) + << " global_in " << global_in(0) << " " << global_in(1) << " " << global_in(2) + << " corr glob " << global(0) << " " << global(1) << " " << global(2) << std::endl + << " distortion " << global(0) - global_in(0) << " " + << global(1) - global_in(1) << " " << global(2) - global_in(2) + << " cluster crossing z correction " << crossing_correction + << std::endl; + } } - + // Make an afine transform that implements the distortion correction as a translation - auto correction_translation = (global - global_in)*Acts::UnitConstants::cm; - Acts::Vector3 correction_rotation(0,0,0); // null rotation + auto correction_translation = (global - global_in) * Acts::UnitConstants::cm; + Acts::Vector3 correction_rotation(0, 0, 0); // null rotation Acts::Transform3 tcorr = tGeometry->makeAffineTransform(correction_rotation, correction_translation); auto this_surf = tGeometry->maps().getSurface(key, cluster); Acts::GeometryIdentifier id = this_surf->geometryId(); auto check_cluster = clusterContainer->findCluster(key); - Acts::Vector2 check_local2d = tGeometry->getLocalCoords(key, check_cluster) * Acts::UnitConstants::cm; // need mm - Acts::Vector3 check_local3d (check_local2d(0), check_local2d(1), 0); + Acts::Vector2 check_local2d = tGeometry->getLocalCoords(key, check_cluster) * Acts::UnitConstants::cm; // need mm + Acts::Vector3 check_local3d(check_local2d(0), check_local2d(1), 0); Acts::GeometryContext temp_transient_geocontext; - temp_transient_geocontext = transformMapTransient; - Acts::Vector3 check_before_pos_surf = this_surf->localToGlobal( temp_transient_geocontext, - check_local2d, - Acts::Vector3(1,1,1)); - if(m_verbosity > 2) - { - unsigned int this_layer = TrkrDefs::getLayer(key); - if(this_layer == 28) - { - std::cout << "Check global from transient transform BEFORE via surface method " << check_before_pos_surf(0)/10.0 << " " - << " " << check_before_pos_surf(1)/10.0 << " " << check_before_pos_surf(2)/10.0 << std::endl; - } - } - + temp_transient_geocontext = transformMapTransient; + Acts::Vector3 check_before_pos_surf = this_surf->localToGlobal(temp_transient_geocontext, + check_local2d, + Acts::Vector3(1, 1, 1)); + if (m_verbosity > 2) + { + unsigned int this_layer = TrkrDefs::getLayer(key); + if (this_layer == 28) + { + std::cout << "Check global from transient transform BEFORE via surface method " << check_before_pos_surf(0) / 10.0 << " " + << " " << check_before_pos_surf(1) / 10.0 << " " << check_before_pos_surf(2) / 10.0 << std::endl; + } + } + // replace the the default alignment transform with the corrected one auto ctxt = tGeometry->geometry().getGeoContext(); alignmentTransformationContainer* transformMap = ctxt.get(); @@ -181,18 +188,18 @@ SourceLinkVec MakeSourceLinks::getSourceLinks( transformMapTransient->replaceTransform(id, corrected_transform); transient_id_set.insert(id); - Acts::Vector3 check_after_pos_surf = this_surf->localToGlobal( temp_transient_geocontext, - check_local2d, - Acts::Vector3(1,1,1)); - if(m_verbosity > 2) - { - unsigned int this_layer = TrkrDefs::getLayer(key); - if(this_layer == 28) - { - std::cout << "Check global from transient transform AFTER via surface method " << check_after_pos_surf(0)/10.0 << " " - << " " << check_after_pos_surf(1)/10.0 << " " << check_after_pos_surf(2)/10.0 << std::endl; - } - } + Acts::Vector3 check_after_pos_surf = this_surf->localToGlobal(temp_transient_geocontext, + check_local2d, + Acts::Vector3(1, 1, 1)); + if (m_verbosity > 2) + { + unsigned int this_layer = TrkrDefs::getLayer(key); + if (this_layer == 28) + { + std::cout << "Check global from transient transform AFTER via surface method " << check_after_pos_surf(0) / 10.0 << " " + << " " << check_after_pos_surf(1) / 10.0 << " " << check_after_pos_surf(2) / 10.0 << std::endl; + } + } } // end TPC specific treatment // corrected TPC transforms are installed, capture the cluster key @@ -201,128 +208,143 @@ SourceLinkVec MakeSourceLinks::getSourceLinks( } // end loop over clusters here Acts::GeometryContext transient_geocontext; - transient_geocontext = transformMapTransient; + transient_geocontext = transformMapTransient; // loop over cluster_vec and make source links - for(auto& cluskey : cluster_vec) + for (auto& cluskey : cluster_vec) + { + if (m_ignoreLayer.contains(TrkrDefs::getLayer(cluskey))) { - if (m_ignoreLayer.contains(TrkrDefs::getLayer(cluskey))) - { - if (m_verbosity > 3) - { - std::cout << PHWHERE << "skipping cluster in layer " - << (unsigned int) TrkrDefs::getLayer(cluskey) << std::endl; - } - continue; - } - - // get local coordinates (TPC time needs conversion to cm) - auto cluster = clusterContainer->findCluster(cluskey); - Acts::Vector2 localPos = tGeometry->getLocalCoords(cluskey, cluster, crossing); // cm - - Surface surf = tGeometry->maps().getSurface(cluskey, cluster); - - Acts::ActsVector<2> loc; - loc[Acts::eBoundLoc0] = localPos(0) * Acts::UnitConstants::cm; // mm - loc[Acts::eBoundLoc1] = localPos(1) * Acts::UnitConstants::cm; - - std::array indices = - {Acts::BoundIndices::eBoundLoc0, Acts::BoundIndices::eBoundLoc1}; - Acts::ActsSquareMatrix<2> cov = Acts::ActsSquareMatrix<2>::Zero(); - - // get errors - Acts::Vector3 global = tGeometry->getGlobalPosition(cluskey, cluster); - double clusRadius = sqrt(global[0] * global[0] + global[1] * global[1]); - auto para_errors = _ClusErrPara.get_clusterv5_modified_error(cluster, clusRadius, cluskey); - cov(Acts::eBoundLoc0, Acts::eBoundLoc0) = para_errors.first * Acts::UnitConstants::cm2; - cov(Acts::eBoundLoc0, Acts::eBoundLoc1) = 0; - cov(Acts::eBoundLoc1, Acts::eBoundLoc0) = 0; - cov(Acts::eBoundLoc1, Acts::eBoundLoc1) = para_errors.second * Acts::UnitConstants::cm2; - - ActsSourceLink::Index index = measurements.size(); - - SourceLink sl(surf->geometryId(), index, cluskey); - Acts::SourceLink actsSL{sl}; - Acts::Measurement meas(actsSL, indices, loc, cov); if (m_verbosity > 3) - { - unsigned int this_layer = TrkrDefs::getLayer(cluskey); - if (this_layer == 28) - { - std::cout << "source link in layer " << this_layer << " for cluskey " << cluskey << " is " << sl.index() << ", loc : " - << loc.transpose() << std::endl - << ", cov : " << cov.transpose() << std::endl - << " geo id " << sl.geometryId() << std::endl; - std::cout << "Surface original transform: " << std::endl; - surf.get()->toStream(tGeometry->geometry().getGeoContext(), std::cout); - std::cout << std::endl << "Surface transient transform: " << std::endl; - surf.get()->toStream(transient_geocontext, std::cout); - std::cout << std::endl; - std::cout << "Corrected surface transform:" << std::endl; - std::cout << transformMapTransient->getTransform(surf->geometryId()).matrix() << std::endl; - std::cout << "Cluster error " << cluster->getRPhiError() << " , " << cluster->getZError() << std::endl; - std::cout << "For key " << cluskey << " with local pos " << std::endl - << localPos(0) << ", " << localPos(1) - << std::endl << std::endl; - } + { + std::cout << PHWHERE << "skipping cluster in layer " + << (unsigned int) TrkrDefs::getLayer(cluskey) << std::endl; + } + continue; + } + + // get local coordinates (TPC time needs conversion to cm) + auto cluster = clusterContainer->findCluster(cluskey); + if(TrkrDefs::getTrkrId(cluskey) == TrkrDefs::TrkrId::tpcId) + { + if(cluster->getEdge() > m_cluster_edge_rejection) + { + continue; + } } + Acts::Vector2 localPos = tGeometry->getLocalCoords(cluskey, cluster, crossing); // cm + + Surface surf = tGeometry->maps().getSurface(cluskey, cluster); + + Acts::ActsVector<2> loc; + loc[Acts::eBoundLoc0] = localPos(0) * Acts::UnitConstants::cm; // mm + loc[Acts::eBoundLoc1] = localPos(1) * Acts::UnitConstants::cm; + + std::array indices = + {Acts::BoundIndices::eBoundLoc0, Acts::BoundIndices::eBoundLoc1}; + Acts::ActsSquareMatrix<2> cov = Acts::ActsSquareMatrix<2>::Zero(); + + // get errors + Acts::Vector3 global = tGeometry->getGlobalPosition(cluskey, cluster); + double clusRadius = sqrt(global[0] * global[0] + global[1] * global[1]); + auto para_errors = _ClusErrPara.get_clusterv5_modified_error(cluster, clusRadius, cluskey); + cov(Acts::eBoundLoc0, Acts::eBoundLoc0) = para_errors.first * Acts::UnitConstants::cm2; + cov(Acts::eBoundLoc0, Acts::eBoundLoc1) = 0; + cov(Acts::eBoundLoc1, Acts::eBoundLoc0) = 0; + cov(Acts::eBoundLoc1, Acts::eBoundLoc1) = para_errors.second * Acts::UnitConstants::cm2; + + ActsSourceLink::Index index = measurements.size(); - sourcelinks.push_back(actsSL); - measurements.push_back(meas); + SourceLink sl(surf->geometryId(), index, cluskey); + Acts::SourceLink actsSL{sl}; + Acts::Measurement meas(actsSL, indices, loc, cov); + if (m_verbosity > 3) + { + unsigned int this_layer = TrkrDefs::getLayer(cluskey); + if (this_layer == 28) + { + std::cout << "source link in layer " << this_layer << " for cluskey " << cluskey << " is " << sl.index() << ", loc : " + << loc.transpose() << std::endl + << ", cov : " << cov.transpose() << std::endl + << " geo id " << sl.geometryId() << std::endl; + std::cout << "Surface original transform: " << std::endl; + surf.get()->toStream(tGeometry->geometry().getGeoContext(), std::cout); + std::cout << std::endl + << "Surface transient transform: " << std::endl; + surf.get()->toStream(transient_geocontext, std::cout); + std::cout << std::endl; + std::cout << "Corrected surface transform:" << std::endl; + std::cout << transformMapTransient->getTransform(surf->geometryId()).matrix() << std::endl; + std::cout << "Cluster error " << cluster->getRPhiError() << " , " << cluster->getZError() << std::endl; + std::cout << "For key " << cluskey << " with local pos " << std::endl + << localPos(0) << ", " << localPos(1) + << std::endl + << std::endl; + } } + sourcelinks.push_back(actsSL); + measurements.push_back(meas); + } + SLTrackTimer.stop(); auto SLTime = SLTrackTimer.get_accumulated_time(); if (m_verbosity > 1) - { - std::cout << "PHActsTrkFitter Source Links generation time: " + { + std::cout << "PHActsTrkFitter Source Links generation time: " << SLTime << std::endl; - } + } return sourcelinks; } void MakeSourceLinks::resetTransientTransformMap( - alignmentTransformationContainer* transformMapTransient, - std::set< Acts::GeometryIdentifier>& transient_id_set, - ActsGeometry* tGeometry ) + alignmentTransformationContainer* transformMapTransient, + std::set& transient_id_set, + ActsGeometry* tGeometry) { - if(m_verbosity > 2) { std::cout << "Resetting TransientTransformMap with transient_id_set size " << transient_id_set.size() << std::endl; } + if (m_verbosity > 2) + { + std::cout << "Resetting TransientTransformMap with transient_id_set size " << transient_id_set.size() << std::endl; + } // loop over modifiedTransformSet and replace transient elements modified for the last track with the default transforms - for(auto& id : transient_id_set) - { - auto ctxt = tGeometry->geometry().getGeoContext(); - alignmentTransformationContainer* transformMap = ctxt.get(); - auto transform = transformMap->getTransform(id); - transformMapTransient->replaceTransform(id, transform); - // std::cout << "replaced transform for id " << id << std::endl; - } + for (auto& id : transient_id_set) + { + auto ctxt = tGeometry->geometry().getGeoContext(); + alignmentTransformationContainer* transformMap = ctxt.get(); + auto transform = transformMap->getTransform(id); + transformMapTransient->replaceTransform(id, transform); + // std::cout << "replaced transform for id " << id << std::endl; + } transient_id_set.clear(); } - //___________________________________________________________________________________ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( - TrackSeed* track, - ActsTrackFittingAlgorithm::MeasurementContainer& measurements, - TrkrClusterContainer* clusterContainer, - ActsGeometry* tGeometry, - const TpcGlobalPositionWrapper& globalPositionWrapper, - short int crossing - ) + TrackSeed* track, + ActsTrackFittingAlgorithm::MeasurementContainer& measurements, + TrkrClusterContainer* clusterContainer, + ActsGeometry* tGeometry, + const TpcGlobalPositionWrapper& globalPositionWrapper, + short int crossing) { - if(m_verbosity > 1) { std::cout << "Entering MakeSourceLinks::getSourceLinksClusterMover for seed " - << " with crossing " << crossing - << std::endl; } + if (m_verbosity > 1) + { + std::cout << "Entering MakeSourceLinks::getSourceLinksClusterMover for seed " + << " with crossing " << crossing + << std::endl; + } SourceLinkVec sourcelinks; if (m_pp_mode && crossing == SHRT_MAX) { // Need to skip this in the pp case, for AuAu it should not happen - if(m_verbosity > 1) - { std::cout << "Seed has no crossing, and in pp mode: skip this seed" << std::endl; } + if (m_verbosity > 1) + { + std::cout << "Seed has no crossing, and in pp mode: skip this seed" << std::endl; + } return sourcelinks; } @@ -343,9 +365,13 @@ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( if (!cluster) { if (m_verbosity > 0) - {std::cout << "Failed to get cluster with key " << key << " for track " << track << std::endl;} + { + std::cout << "Failed to get cluster with key " << key << " for track " << track << std::endl; + } else - {std::cout << "PHActsTrkFitter :: Key: " << key << " for track " << track << std::endl;} + { + std::cout << "PHActsTrkFitter :: Key: " << key << " for track " << track << std::endl; + } continue; } @@ -359,36 +385,39 @@ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( const unsigned int trkrid = TrkrDefs::getTrkrId(key); - if(m_verbosity > 1) { std::cout << " Cluster key " << key << " trkrid " << trkrid << " crossing " << crossing << std::endl; } + if (m_verbosity > 1) + { + std::cout << " Cluster key " << key << " trkrid " << trkrid << " crossing " << crossing << std::endl; + } // For the TPC, cluster z has to be corrected for the crossing z offset, distortion, and TOF z offset // we do this locally here and do not modify the cluster, since the cluster may be associated with multiple silicon tracks - const Acts::Vector3 global = globalPositionWrapper.getGlobalPositionDistortionCorrected(key, cluster, crossing ); + const Acts::Vector3 global = globalPositionWrapper.getGlobalPositionDistortionCorrected(key, cluster, crossing); if (trkrid == TrkrDefs::tpcId) { - if(m_verbosity > 2) - { - unsigned int this_layer = TrkrDefs::getLayer(key); - if(this_layer == 28) - { - unsigned int this_side = TpcDefs::getSide(key); - Acts::Vector3 nominal_global_in = tGeometry->getGlobalPosition(key, cluster); - Acts::Vector3 global_in = tGeometry->getGlobalPosition(key, cluster); - double cluster_crossing_corrected_z= TpcClusterZCrossingCorrection::correctZ(global_in.z(), TpcDefs::getSide(key), crossing); - double crossing_correction = cluster_crossing_corrected_z - global_in.z(); - global_in.z() = cluster_crossing_corrected_z; - - std::cout << " crossing " << crossing << " layer " << this_layer << " side " << this_side << " clusterkey " << key << std::endl - << " nominal global_in " << nominal_global_in(0) << " " << nominal_global_in(1) << " " << nominal_global_in(2) << std::endl - << " global_in " << global_in(0) << " " << global_in(1) << " " << global_in(2) << std::endl - << " corr glob " << global(0) << " " << global(1) << " " << global(2) << std::endl - << " distortion " << global(0)-global_in(0) << " " - << global(1) - global_in(1) << " " << global(2) - global_in(2) - << " cluster crossing z correction " << crossing_correction - << std::endl; - } - } + if (m_verbosity > 2) + { + unsigned int this_layer = TrkrDefs::getLayer(key); + if (this_layer == 28) + { + unsigned int this_side = TpcDefs::getSide(key); + Acts::Vector3 nominal_global_in = tGeometry->getGlobalPosition(key, cluster); + Acts::Vector3 global_in = tGeometry->getGlobalPosition(key, cluster); + double cluster_crossing_corrected_z = TpcClusterZCrossingCorrection::correctZ(global_in.z(), TpcDefs::getSide(key), crossing); + double crossing_correction = cluster_crossing_corrected_z - global_in.z(); + global_in.z() = cluster_crossing_corrected_z; + + std::cout << " crossing " << crossing << " layer " << this_layer << " side " << this_side << " clusterkey " << key << std::endl + << " nominal global_in " << nominal_global_in(0) << " " << nominal_global_in(1) << " " << nominal_global_in(2) << std::endl + << " global_in " << global_in(0) << " " << global_in(1) << " " << global_in(2) << std::endl + << " corr glob " << global(0) << " " << global(1) << " " << global(2) << std::endl + << " distortion " << global(0) - global_in(0) << " " + << global(1) - global_in(1) << " " << global(2) - global_in(2) + << " cluster crossing z correction " << crossing_correction + << std::endl; + } + } } // add the global positions to a vector to give to the cluster mover @@ -405,10 +434,10 @@ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( } // loop over global positions returned by cluster mover - for(auto&& [cluskey, global] : global_moved) + for (auto&& [cluskey, global] : global_moved) { // std::cout << "Global moved: " << global.x() << " " << global.y() << " " << global.z() << std::endl; - + if (m_ignoreLayer.contains(TrkrDefs::getLayer(cluskey))) { if (m_verbosity > 3) @@ -421,19 +450,24 @@ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( auto cluster = clusterContainer->findCluster(cluskey); Surface surf = tGeometry->maps().getSurface(cluskey, cluster); - if(std::isnan(global.x()) || std::isnan(global.y())) + if (std::isnan(global.x()) || std::isnan(global.y())) { std::cout << "MakeSourceLinks::getSourceLinksClusterMover - invalid position" - << " key: " << cluskey - << " layer: " << (int)TrkrDefs::getLayer(cluskey) - << " position: " << global - << std::endl; + << " key: " << cluskey + << " layer: " << (int) TrkrDefs::getLayer(cluskey) + << " position: " << global + << std::endl; } // if this is a TPC cluster, the crossing correction may have moved it across the central membrane, check the surface auto trkrid = TrkrDefs::getTrkrId(cluskey); if (trkrid == TrkrDefs::tpcId) { + if (cluster->getEdge() > m_cluster_edge_rejection) + { + continue; + } + TrkrDefs::hitsetkey hitsetkey = TrkrDefs::getHitSetKeyFromClusKey(cluskey); TrkrDefs::subsurfkey new_subsurfkey = 0; surf = tGeometry->get_tpc_surface_from_coords(hitsetkey, global, new_subsurfkey); @@ -441,7 +475,10 @@ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( if (!surf) { - if(m_verbosity > 2) { std::cout << "MakeSourceLinks::getSourceLinksClusterMover - Failed to find surface for cluskey " << cluskey << std::endl; } + if (m_verbosity > 2) + { + std::cout << "MakeSourceLinks::getSourceLinksClusterMover - Failed to find surface for cluskey " << cluskey << std::endl; + } continue; } @@ -449,7 +486,7 @@ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( Acts::Vector2 localPos; global *= Acts::UnitConstants::cm; // we want mm for transformations - Acts::Vector3 normal = surf->normal(tGeometry->geometry().getGeoContext(),Acts::Vector3(1,1,1), Acts::Vector3(1,1,1)); + Acts::Vector3 normal = surf->normal(tGeometry->geometry().getGeoContext(), Acts::Vector3(1, 1, 1), Acts::Vector3(1, 1, 1)); auto local = surf->globalToLocal(tGeometry->geometry().getGeoContext(), global, normal); if (local.ok()) @@ -458,11 +495,14 @@ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( } else { - if(m_verbosity > 2) { std::cout << "MakeSourceLinks::getSourceLinksClusterMover - Taking manual calculation for global to local " << std::endl; } + if (m_verbosity > 2) + { + std::cout << "MakeSourceLinks::getSourceLinksClusterMover - Taking manual calculation for global to local " << std::endl; + } /// otherwise take the manual calculation for the TPC // doing it this way just avoids the bounds check that occurs in the surface class method - Acts::Vector3 loct = surf->transform(tGeometry->geometry().getGeoContext()).inverse() * global ; // global is in mm + Acts::Vector3 loct = surf->transform(tGeometry->geometry().getGeoContext()).inverse() * global; // global is in mm loct /= Acts::UnitConstants::cm; localPos(0) = loct(0); @@ -474,22 +514,22 @@ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( std::cout << "MakeSourceLinks::getSourceLinksClusterMover - Cluster " << cluskey << " cluster global after mover: " << global << std::endl; std::cout << "MakeSourceLinks::getSourceLinksClusterMover - stored: cluster local X " << cluster->getLocalX() << " cluster local Y " << cluster->getLocalY() << std::endl; - const Acts::Vector2 localTest = tGeometry->getLocalCoords(cluskey, cluster); // cm + const Acts::Vector2 localTest = tGeometry->getLocalCoords(cluskey, cluster); // cm std::cout << "MakeSourceLinks::getSourceLinksClusterMover - localTest from getLocalCoords: " << localTest << std::endl; std::cout << "MakeSourceLinks::getSourceLinksClusterMover - new from inverse transform of cluster global after mover: " << std::endl; - const Acts::Vector3 globalTest = surf->localToGlobal(tGeometry->geometry().getGeoContext(), localTest*Acts::UnitConstants::cm, normal); - std::cout << "MakeSourceLinks::getSourceLinksClusterMover - global from localTest: " << Acts::Vector3(globalTest/Acts::UnitConstants::cm) << std::endl; + const Acts::Vector3 globalTest = surf->localToGlobal(tGeometry->geometry().getGeoContext(), localTest * Acts::UnitConstants::cm, normal); + std::cout << "MakeSourceLinks::getSourceLinksClusterMover - global from localTest: " << Acts::Vector3(globalTest / Acts::UnitConstants::cm) << std::endl; - const Acts::Vector3 globalNew = surf->localToGlobal(tGeometry->geometry().getGeoContext(), localPos*Acts::UnitConstants::cm, normal); - std::cout << "MakeSourceLinks::getSourceLinksClusterMover - global from new local: " << Acts::Vector3(globalNew/Acts::UnitConstants::cm) << std::endl; + const Acts::Vector3 globalNew = surf->localToGlobal(tGeometry->geometry().getGeoContext(), localPos * Acts::UnitConstants::cm, normal); + std::cout << "MakeSourceLinks::getSourceLinksClusterMover - global from new local: " << Acts::Vector3(globalNew / Acts::UnitConstants::cm) << std::endl; } Acts::ActsVector<2> loc; loc[Acts::eBoundLoc0] = localPos(0) * Acts::UnitConstants::cm; loc[Acts::eBoundLoc1] = localPos(1) * Acts::UnitConstants::cm; std::array indices = - {Acts::BoundIndices::eBoundLoc0, Acts::BoundIndices::eBoundLoc1}; + {Acts::BoundIndices::eBoundLoc0, Acts::BoundIndices::eBoundLoc1}; Acts::ActsSquareMatrix<2> cov = Acts::ActsSquareMatrix<2>::Zero(); @@ -501,7 +541,7 @@ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( cov(Acts::eBoundLoc1, Acts::eBoundLoc1) = para_errors.second * Acts::UnitConstants::cm2; ActsSourceLink::Index index = measurements.size(); - + SourceLink sl(surf->geometryId(), index, cluskey); Acts::SourceLink actsSL{sl}; Acts::Measurement meas(actsSL, indices, loc, cov); @@ -528,9 +568,9 @@ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( auto SLTime = SLTrackTimer.get_accumulated_time(); if (m_verbosity > 1) - { - std::cout << "PHMakeSourceLinks::getSourceLinksClusterMover - ActsTrkFitter Source Links generation time: " + { + std::cout << "PHMakeSourceLinks::getSourceLinksClusterMover - ActsTrkFitter Source Links generation time: " << SLTime << std::endl; - } + } return sourcelinks; } diff --git a/offline/packages/trackreco/MakeSourceLinks.h b/offline/packages/trackreco/MakeSourceLinks.h index 8acf4f8272..c0d5a31683 100644 --- a/offline/packages/trackreco/MakeSourceLinks.h +++ b/offline/packages/trackreco/MakeSourceLinks.h @@ -1,17 +1,17 @@ #ifndef TRACKRECO_MAKESOURCELINKS_H #define TRACKRECO_MAKESOURCELINKS_H -#include #include #include -#include #include +#include +#include #include /// Acts includes to create all necessary definitions -#include #include +#include #include @@ -40,51 +40,47 @@ class TrackSeed; class MakeSourceLinks { public: - MakeSourceLinks() = default; + MakeSourceLinks() = default; - void initialize(PHG4TpcGeomContainer* cellgeo); + void initialize(PHG4TpcGeomContainer* cellgeo); - void setVerbosity(int verbosity) {m_verbosity = verbosity;} - - void set_pp_mode(bool ispp) { m_pp_mode = ispp; } + void setVerbosity(int verbosity) { m_verbosity = verbosity; } + void set_pp_mode(bool ispp) { m_pp_mode = ispp; } + void set_cluster_edge_rejection(int edge) { m_cluster_edge_rejection = edge; } void ignoreLayer(int layer) { m_ignoreLayer.insert(layer); } SourceLinkVec getSourceLinks( - TrackSeed* /*seed*/, - ActsTrackFittingAlgorithm::MeasurementContainer& /*measurements*/, - TrkrClusterContainer* /*clusters*/, - ActsGeometry* /*geometry*/, - const TpcGlobalPositionWrapper& /*globalpositionWrapper*/, - alignmentTransformationContainer* /*transformMapTransient*/, - std::set< Acts::GeometryIdentifier>& /*transient_id_set*/, - short int /*crossing*/); + TrackSeed* /*seed*/, + ActsTrackFittingAlgorithm::MeasurementContainer& /*measurements*/, + TrkrClusterContainer* /*clusters*/, + ActsGeometry* /*geometry*/, + const TpcGlobalPositionWrapper& /*globalpositionWrapper*/, + alignmentTransformationContainer* /*transformMapTransient*/, + std::set& /*transient_id_set*/, + short int /*crossing*/); void resetTransientTransformMap( - alignmentTransformationContainer* /*transformMapTransient*/, - std::set< Acts::GeometryIdentifier>& /*transient_id_set*/, - ActsGeometry* /*tGeometry*/ ); + alignmentTransformationContainer* /*transformMapTransient*/, + std::set& /*transient_id_set*/, + ActsGeometry* /*tGeometry*/); SourceLinkVec getSourceLinksClusterMover( - TrackSeed* /*seed*/, - ActsTrackFittingAlgorithm::MeasurementContainer& /*measurements*/, - TrkrClusterContainer* /*clusters*/, - ActsGeometry* /*geometry*/, - const TpcGlobalPositionWrapper& /*globalpositionWrapper*/, - short int crossing - ); + TrackSeed* /*seed*/, + ActsTrackFittingAlgorithm::MeasurementContainer& /*measurements*/, + TrkrClusterContainer* /*clusters*/, + ActsGeometry* /*geometry*/, + const TpcGlobalPositionWrapper& /*globalpositionWrapper*/, + short int crossing); private: int m_verbosity = 0; bool m_pp_mode = false; std::set m_ignoreLayer; - + int m_cluster_edge_rejection = 0; TpcClusterMover _clusterMover; ClusterErrorPara _ClusErrPara; - - }; - #endif diff --git a/offline/packages/trackreco/PHActsTrkFitter.cc b/offline/packages/trackreco/PHActsTrkFitter.cc index 2ca1426301..5a92307b81 100644 --- a/offline/packages/trackreco/PHActsTrkFitter.cc +++ b/offline/packages/trackreco/PHActsTrkFitter.cc @@ -145,6 +145,7 @@ int PHActsTrkFitter::InitRun(PHCompositeNode* topNode) chi2Cuts.insert(std::make_pair(14, 9)); chi2Cuts.insert(std::make_pair(16, 4)); m_outlierFinder.chi2Cuts = chi2Cuts; + if (m_useOutlierFinder) { m_outlierFinder.m_tGeometry = m_tGeometry; @@ -439,6 +440,7 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) makeSourceLinks.initialize(_tpccellgeo); makeSourceLinks.setVerbosity(Verbosity()); makeSourceLinks.set_pp_mode(m_pp_mode); + makeSourceLinks.set_cluster_edge_rejection(m_cluster_edge_rejection); for (const auto& layer : m_ignoreLayer) { makeSourceLinks.ignoreLayer(layer); diff --git a/offline/packages/trackreco/PHActsTrkFitter.h b/offline/packages/trackreco/PHActsTrkFitter.h index cca5095c79..09a8ab9d1d 100644 --- a/offline/packages/trackreco/PHActsTrkFitter.h +++ b/offline/packages/trackreco/PHActsTrkFitter.h @@ -144,7 +144,7 @@ class PHActsTrkFitter : public SubsysReco void ignoreLayer(int layer) { m_ignoreLayer.insert(layer); } void setTrkrClusterContainerName(const std::string& name) { m_clusterContainerName = name; } void setDirectNavigation(bool flag) { m_directNavigation = flag; } - + void setClusterEdgeRejection(int edge ) { m_cluster_edge_rejection = edge; } private: /// Get all the nodes int getNodes(PHCompositeNode* topNode); @@ -244,6 +244,7 @@ class PHActsTrkFitter : public SubsysReco // name of TRKR_CLUSTER container std::string m_clusterContainerName = "TRKR_CLUSTER"; + int m_cluster_edge_rejection = 0; //!@name evaluator //@{ bool m_actsEvaluator = false; From febf1e238dcb3500c420e031ca61d3eee43297db Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 20 Jan 2026 12:40:07 -0500 Subject: [PATCH 086/393] Add type 38: 60GeV jets --- offline/framework/frog/CreateFileList.pl | 32 +++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/offline/framework/frog/CreateFileList.pl b/offline/framework/frog/CreateFileList.pl index 19b552b764..19456cbc09 100755 --- a/offline/framework/frog/CreateFileList.pl +++ b/offline/framework/frog/CreateFileList.pl @@ -75,7 +75,8 @@ "34" => "JS pythia8 Jet ptmin = 50GeV", "35" => "JS pythia8 Jet ptmin = 70GeV", "36" => "JS pythia8 Jet ptmin = 5GeV", - "37" => "hijing O+O (0-15fm)" + "37" => "hijing O+O (0-15fm)", + "38" => "JS pythia8 Jet ptmin = 60GeV", ); my %pileupdesc = ( @@ -941,6 +942,35 @@ $pileupstring = $AuAu_pileupstring; &commonfiletypes(); } + elsif ($prodtype == 38) + { + $embedok = 1; + $filenamestring = "pythia8_Jet60"; + if (! defined $nopileup) + { + if (defined $embed) + { + if ($embed eq "pau") + { + $filenamestring = sprintf("%s_sHijing_pAu_0_10fm%s",$filenamestring, $pAu_pileupstring); + } + elsif ($embed eq "central") + { + $filenamestring = sprintf("%s_sHijing_0_488fm%s",$filenamestring, $AuAu_pileupstring); + } + else + { + $filenamestring = sprintf("%s_sHijing_0_20fm%s",$filenamestring, $AuAu_pileupstring); + } + } + else + { + $filenamestring = sprintf("%s%s",$filenamestring,$pp_pileupstring); + } + } + $pileupstring = $pp_pileupstring; + &commonfiletypes(); + } else { From 6ce581e35841fffaf9e131986ede27c969427ed3 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Tue, 20 Jan 2026 13:46:11 -0500 Subject: [PATCH 087/393] clang-tidy and clang-format --- offline/packages/trackreco/MakeSourceLinks.cc | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/offline/packages/trackreco/MakeSourceLinks.cc b/offline/packages/trackreco/MakeSourceLinks.cc index 5bb00293a9..f9038d182e 100644 --- a/offline/packages/trackreco/MakeSourceLinks.cc +++ b/offline/packages/trackreco/MakeSourceLinks.cc @@ -97,7 +97,7 @@ SourceLinkVec MakeSourceLinks::getSourceLinks( ++clusIter) { auto key = *clusIter; - auto cluster = clusterContainer->findCluster(key); + auto* cluster = clusterContainer->findCluster(key); if (!cluster) { if (m_verbosity > 0) @@ -106,7 +106,7 @@ SourceLinkVec MakeSourceLinks::getSourceLinks( } continue; } - else if (m_verbosity > 0) + if (m_verbosity > 0) { std::cout << "MakeSourceLinks: Found cluster with key " << key << " for track seed " << std::endl; } @@ -163,7 +163,7 @@ SourceLinkVec MakeSourceLinks::getSourceLinks( auto this_surf = tGeometry->maps().getSurface(key, cluster); Acts::GeometryIdentifier id = this_surf->geometryId(); - auto check_cluster = clusterContainer->findCluster(key); + auto* check_cluster = clusterContainer->findCluster(key); Acts::Vector2 check_local2d = tGeometry->getLocalCoords(key, check_cluster) * Acts::UnitConstants::cm; // need mm Acts::Vector3 check_local3d(check_local2d(0), check_local2d(1), 0); Acts::GeometryContext temp_transient_geocontext; @@ -224,10 +224,10 @@ SourceLinkVec MakeSourceLinks::getSourceLinks( } // get local coordinates (TPC time needs conversion to cm) - auto cluster = clusterContainer->findCluster(cluskey); - if(TrkrDefs::getTrkrId(cluskey) == TrkrDefs::TrkrId::tpcId) + auto* cluster = clusterContainer->findCluster(cluskey); + if (TrkrDefs::getTrkrId(cluskey) == TrkrDefs::TrkrId::tpcId) { - if(cluster->getEdge() > m_cluster_edge_rejection) + if (cluster->getEdge() > m_cluster_edge_rejection) { continue; } @@ -247,7 +247,7 @@ SourceLinkVec MakeSourceLinks::getSourceLinks( // get errors Acts::Vector3 global = tGeometry->getGlobalPosition(cluskey, cluster); double clusRadius = sqrt(global[0] * global[0] + global[1] * global[1]); - auto para_errors = _ClusErrPara.get_clusterv5_modified_error(cluster, clusRadius, cluskey); + auto para_errors = ClusterErrorPara::get_clusterv5_modified_error(cluster, clusRadius, cluskey); cov(Acts::eBoundLoc0, Acts::eBoundLoc0) = para_errors.first * Acts::UnitConstants::cm2; cov(Acts::eBoundLoc0, Acts::eBoundLoc1) = 0; cov(Acts::eBoundLoc1, Acts::eBoundLoc0) = 0; @@ -284,7 +284,7 @@ SourceLinkVec MakeSourceLinks::getSourceLinks( } sourcelinks.push_back(actsSL); - measurements.push_back(meas); + measurements.emplace_back(meas); } SLTrackTimer.stop(); @@ -301,7 +301,7 @@ SourceLinkVec MakeSourceLinks::getSourceLinks( void MakeSourceLinks::resetTransientTransformMap( alignmentTransformationContainer* transformMapTransient, std::set& transient_id_set, - ActsGeometry* tGeometry) + ActsGeometry* tGeometry) const { if (m_verbosity > 2) { @@ -309,7 +309,7 @@ void MakeSourceLinks::resetTransientTransformMap( } // loop over modifiedTransformSet and replace transient elements modified for the last track with the default transforms - for (auto& id : transient_id_set) + for (const auto& id : transient_id_set) { auto ctxt = tGeometry->geometry().getGeoContext(); alignmentTransformationContainer* transformMap = ctxt.get(); @@ -361,7 +361,7 @@ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( ++clusIter) { auto key = *clusIter; - auto cluster = clusterContainer->findCluster(key); + auto* cluster = clusterContainer->findCluster(key); if (!cluster) { if (m_verbosity > 0) @@ -421,7 +421,7 @@ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( } // add the global positions to a vector to give to the cluster mover - global_raw.emplace_back(std::make_pair(key, global)); + global_raw.emplace_back(key, global); } // end loop over clusters here @@ -448,7 +448,7 @@ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( continue; } - auto cluster = clusterContainer->findCluster(cluskey); + auto* cluster = clusterContainer->findCluster(cluskey); Surface surf = tGeometry->maps().getSurface(cluskey, cluster); if (std::isnan(global.x()) || std::isnan(global.y())) { @@ -464,10 +464,10 @@ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( if (trkrid == TrkrDefs::tpcId) { if (cluster->getEdge() > m_cluster_edge_rejection) - { - continue; - } - + { + continue; + } + TrkrDefs::hitsetkey hitsetkey = TrkrDefs::getHitSetKeyFromClusKey(cluskey); TrkrDefs::subsurfkey new_subsurfkey = 0; surf = tGeometry->get_tpc_surface_from_coords(hitsetkey, global, new_subsurfkey); @@ -534,7 +534,7 @@ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( Acts::ActsSquareMatrix<2> cov = Acts::ActsSquareMatrix<2>::Zero(); double clusRadius = sqrt(global[0] * global[0] + global[1] * global[1]); - auto para_errors = _ClusErrPara.get_clusterv5_modified_error(cluster, clusRadius, cluskey); + auto para_errors = ClusterErrorPara::get_clusterv5_modified_error(cluster, clusRadius, cluskey); cov(Acts::eBoundLoc0, Acts::eBoundLoc0) = para_errors.first * Acts::UnitConstants::cm2; cov(Acts::eBoundLoc0, Acts::eBoundLoc1) = 0; cov(Acts::eBoundLoc1, Acts::eBoundLoc0) = 0; @@ -561,7 +561,7 @@ SourceLinkVec MakeSourceLinks::getSourceLinksClusterMover( } sourcelinks.push_back(actsSL); - measurements.push_back(meas); + measurements.emplace_back(meas); } SLTrackTimer.stop(); From 435537f4adb086205857a252f97ee8911af17037 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Tue, 20 Jan 2026 13:47:27 -0500 Subject: [PATCH 088/393] clang-tidy --- offline/packages/trackreco/MakeSourceLinks.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/trackreco/MakeSourceLinks.h b/offline/packages/trackreco/MakeSourceLinks.h index c0d5a31683..d22acc4881 100644 --- a/offline/packages/trackreco/MakeSourceLinks.h +++ b/offline/packages/trackreco/MakeSourceLinks.h @@ -63,7 +63,7 @@ class MakeSourceLinks void resetTransientTransformMap( alignmentTransformationContainer* /*transformMapTransient*/, std::set& /*transient_id_set*/, - ActsGeometry* /*tGeometry*/); + ActsGeometry* /*tGeometry*/) const; SourceLinkVec getSourceLinksClusterMover( TrackSeed* /*seed*/, From 7c3201954d3f506ad240cb3af4004d9e3e31be08 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Tue, 20 Jan 2026 13:48:10 -0500 Subject: [PATCH 089/393] take first and last cluster in charge sign determination --- offline/packages/trackbase_historic/TrackSeedHelper.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/offline/packages/trackbase_historic/TrackSeedHelper.cc b/offline/packages/trackbase_historic/TrackSeedHelper.cc index 99a9198811..0fba4fb80a 100644 --- a/offline/packages/trackbase_historic/TrackSeedHelper.cc +++ b/offline/packages/trackbase_historic/TrackSeedHelper.cc @@ -142,8 +142,8 @@ void TrackSeedHelper::circleFitByTaubin( float qOverR = 1./r; /// Set the charge - const auto& firstpos = positions_2d.at(0); - const auto& secondpos = positions_2d.at(1); + const auto& firstpos = *(positions_2d.begin()); + const auto& secondpos = *(positions_2d.rbegin()); const auto firstphi = atan2(firstpos.second, firstpos.first); const auto secondphi = atan2(secondpos.second, secondpos.first); From 300975c3c0c3f9a96bbd5051993ec45743bd067f Mon Sep 17 00:00:00 2001 From: silas-gross Date: Tue, 20 Jan 2026 16:22:26 -0500 Subject: [PATCH 090/393] moved the ngood nevts to public variables to allow for better usage --- generators/Herwig/HepMCTrigger/HepMCJetTrigger.h | 4 ++-- generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/generators/Herwig/HepMCTrigger/HepMCJetTrigger.h b/generators/Herwig/HepMCTrigger/HepMCJetTrigger.h index 67a1a4fbe5..74ee855493 100644 --- a/generators/Herwig/HepMCTrigger/HepMCJetTrigger.h +++ b/generators/Herwig/HepMCTrigger/HepMCJetTrigger.h @@ -47,6 +47,8 @@ class HepMCJetTrigger : public SubsysReco /// Called at the end of all processing. /// Reset + int n_evts{0}; + int n_good{0}; private: bool isGoodEvent(HepMC::GenEvent* e1); @@ -54,8 +56,6 @@ class HepMCJetTrigger : public SubsysReco int jetsAboveThreshold(const std::vector& jets) const; float threshold{0.}; int goal_event_number{1000}; - int n_evts{0}; - int n_good{0}; bool set_event_limit{false}; }; diff --git a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h index 1b77724c0a..4900bad5ad 100644 --- a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h +++ b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h @@ -29,6 +29,8 @@ class HepMCParticleTrigger : public SubsysReco This is where you do the real work. */ int process_event(PHCompositeNode* topNode) override; + int n_evts{0}; + int n_good{0}; /// Clean up internals after each event. @@ -76,8 +78,6 @@ class HepMCParticleTrigger : public SubsysReco bool m_doStableParticleOnly{true}; float threshold{0.}; int goal_event_number{1000}; - int n_evts{0}; - int n_good{0}; bool set_event_limit{false}; float _theEtaHigh{1.1}; From 2f01ab562a041546fab06579c672cbacb2734568 Mon Sep 17 00:00:00 2001 From: Shuonli Date: Tue, 20 Jan 2026 18:09:41 -0500 Subject: [PATCH 091/393] add functional fit --- offline/packages/CaloReco/CaloTowerBuilder.cc | 9 + offline/packages/CaloReco/CaloTowerBuilder.h | 29 ++ .../packages/CaloReco/CaloWaveformFitting.cc | 252 ++++++++++++++++++ .../packages/CaloReco/CaloWaveformFitting.h | 44 +++ .../CaloReco/CaloWaveformProcessing.cc | 17 ++ .../CaloReco/CaloWaveformProcessing.h | 30 +++ 6 files changed, 381 insertions(+) diff --git a/offline/packages/CaloReco/CaloTowerBuilder.cc b/offline/packages/CaloReco/CaloTowerBuilder.cc index 632cd8161d..a84706599d 100644 --- a/offline/packages/CaloReco/CaloTowerBuilder.cc +++ b/offline/packages/CaloReco/CaloTowerBuilder.cc @@ -75,6 +75,14 @@ int CaloTowerBuilder::InitRun(PHCompositeNode *topNode) WaveformProcessing->set_bitFlipRecovery(m_dobitfliprecovery); } + // Set functional fit parameters + if (_processingtype == CaloWaveformProcessing::FUNCFIT) + { + WaveformProcessing->set_funcfit_type(m_funcfit_type); + WaveformProcessing->set_powerlaw_params(m_powerlaw_power, m_powerlaw_decay); + WaveformProcessing->set_doubleexp_params(m_doubleexp_power, m_doubleexp_peaktime1, m_doubleexp_peaktime2, m_doubleexp_ratio); + } + if (m_dettype == CaloTowerDefs::CEMC) { m_detector = "CEMC"; @@ -476,6 +484,7 @@ int CaloTowerBuilder::process_event(PHCompositeNode *topNode) towerinfo->set_pedestal(processed_waveforms.at(idx).at(2)); towerinfo->set_chi2(processed_waveforms.at(idx).at(3)); bool SZS = isSZS(processed_waveforms.at(idx).at(1), processed_waveforms.at(idx).at(3)); + if (processed_waveforms.at(idx).at(4) == 0) { towerinfo->set_isRecovered(false); diff --git a/offline/packages/CaloReco/CaloTowerBuilder.h b/offline/packages/CaloReco/CaloTowerBuilder.h index cb22806903..0fc5694638 100644 --- a/offline/packages/CaloReco/CaloTowerBuilder.h +++ b/offline/packages/CaloReco/CaloTowerBuilder.h @@ -94,6 +94,26 @@ class CaloTowerBuilder : public SubsysReco m_dobitfliprecovery = dobitfliprecovery; } + // Functional fit options: 0 = PowerLawExp, 1 = PowerLawDoubleExp + void set_funcfit_type(int type) + { + m_funcfit_type = type; + } + + void set_powerlaw_params(double power, double decay) + { + m_powerlaw_power = power; + m_powerlaw_decay = decay; + } + + void set_doubleexp_params(double power, double peaktime1, double peaktime2, double ratio) + { + m_doubleexp_power = power; + m_doubleexp_peaktime1 = peaktime1; + m_doubleexp_peaktime2 = peaktime2; + m_doubleexp_ratio = ratio; + } + void set_tbt_softwarezerosuppression(const std::string &url) { m_zsURL = url; @@ -150,6 +170,15 @@ class CaloTowerBuilder : public SubsysReco std::string m_directURL; std::string m_zsURL; std::string m_zs_fieldname{"zs_threshold"}; + + // Functional fit parameters + int m_funcfit_type{1}; // 0 = PowerLawExp, 1 = PowerLawDoubleExp + double m_powerlaw_power{4.0}; + double m_powerlaw_decay{1.5}; + double m_doubleexp_power{2.0}; + double m_doubleexp_peaktime1{5.0}; + double m_doubleexp_peaktime2{5.0}; + double m_doubleexp_ratio{0.3}; }; #endif // CALOTOWERBUILDER_H diff --git a/offline/packages/CaloReco/CaloWaveformFitting.cc b/offline/packages/CaloReco/CaloWaveformFitting.cc index f5163275a0..e84ec84874 100644 --- a/offline/packages/CaloReco/CaloWaveformFitting.cc +++ b/offline/packages/CaloReco/CaloWaveformFitting.cc @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -619,3 +620,254 @@ float CaloWaveformFitting::psinc(float time, std::vector &vec_signal_samp return sum; } + +double CaloWaveformFitting::SignalShape_PowerLawExp(double *x, double *par) +{ + // par[0]: Amplitude + // par[1]: Sample Start (t0) + // par[2]: Power + // par[3]: Decay + // par[4]: Pedestal + double pedestal = par[4]; + if (x[0] < par[1]) + { + return pedestal; + } + double signal = par[0] * pow((x[0] - par[1]), par[2]) * exp(-(x[0] - par[1]) * par[3]); + return pedestal + signal; +} + +double CaloWaveformFitting::SignalShape_PowerLawDoubleExp(double *x, double *par) +{ + // par[0]: Amplitude + // par[1]: Sample Start (t0) + // par[2]: Power + // par[3]: Peak Time 1 + // par[4]: Pedestal + // par[5]: Amplitude ratio + // par[6]: Peak Time 2 + double pedestal = par[4]; + if (x[0] < par[1]) + { + return pedestal; + } + double signal = par[0] * pow((x[0] - par[1]), par[2]) * + (((1.0 - par[5]) / pow(par[3], par[2]) * exp(par[2])) * + exp(-(x[0] - par[1]) * (par[2] / par[3])) + + (par[5] / pow(par[6], par[2]) * exp(par[2])) * + exp(-(x[0] - par[1]) * (par[2] / par[6]))); + return pedestal + signal; +} + +std::vector> CaloWaveformFitting::calo_processing_funcfit(const std::vector> &chnlvector) +{ + std::vector> fit_values; + int nchnls = chnlvector.size(); + + for (int m = 0; m < nchnls; m++) + { + const std::vector &v = chnlvector.at(m); + int nsamples = v.size(); + + float amp = 0; + float time = 0; + float ped = 0; + float chi2 = std::numeric_limits::quiet_NaN(); + + // Handle zero-suppressed samples (2-sample case) + if (nsamples == _nzerosuppresssamples) + { + amp = v.at(1) - v.at(0); + time = std::numeric_limits::quiet_NaN(); + ped = v.at(0); + if (v.at(0) != 0 && v.at(1) == 0) + { + chi2 = 1000000; + } + fit_values.push_back({amp, time, ped, chi2, 0}); + continue; + } + + // Find peak position and estimate pedestal + float maxheight = 0; + int maxbin = 0; + for (int i = 0; i < nsamples; i++) + { + if (v.at(i) > maxheight) + { + maxheight = v.at(i); + maxbin = i; + } + } + + float pedestal = 1500; + if (maxbin > 4) + { + pedestal = 0.5 * (v.at(maxbin - 4) + v.at(maxbin - 5)); + } + else if (maxbin > 3) + { + pedestal = v.at(maxbin - 4); + } + else + { + pedestal = 0.5 * (v.at(nsamples - 3) + v.at(nsamples - 2)); + } + + // Software zero suppression check + if ((_bdosoftwarezerosuppression && v.at(6) - v.at(0) < _nsoftwarezerosuppression) || + (_maxsoftwarezerosuppression && maxheight - pedestal < _nsoftwarezerosuppression)) + { + amp = v.at(6) - v.at(0); + time = std::numeric_limits::quiet_NaN(); + ped = v.at(0); + if (v.at(0) != 0 && v.at(1) == 0) + { + chi2 = 1000000; + } + fit_values.push_back({amp, time, ped, chi2, 0}); + continue; + } + + // Create histogram for fitting + TH1F h("h_funcfit", "", nsamples, -0.5, nsamples - 0.5); + int ndata = 0; + for (int i = 0; i < nsamples; ++i) + { + if ((v.at(i) == 16383) && _handleSaturation) + { + continue; + } + h.SetBinContent(i + 1, v.at(i)); + h.SetBinError(i + 1, 1); + ndata++; + } + + // If too many saturated, use all data + if (ndata < (nsamples - 4)) + { + ndata = nsamples; + for (int i = 0; i < nsamples; ++i) + { + h.SetBinContent(i + 1, v.at(i)); + h.SetBinError(i + 1, 1); + } + } + + double fit_amp = 0; + double fit_time = 0; + double fit_ped = 0; + double chi2val = 0; + int npar = 0; + + if (m_funcfit_type == POWERLAWEXP) + { + // Create fit function with 5 parameters + TF1 f("f_powerlaw", SignalShape_PowerLawExp, 0, nsamples, 5); + npar = 5; + + // Set initial parameters + double risetime = m_powerlaw_power / m_powerlaw_decay; + double par[5]; + par[0] = maxheight - pedestal; // Amplitude + par[1] = maxbin - risetime; // t0 + if (par[1] < 0) + { + par[1] = 0; + } + par[2] = m_powerlaw_power; // Power + par[3] = m_powerlaw_decay; // Decay + par[4] = pedestal; // Pedestal + + f.SetParameters(par); + f.SetParLimits(0, (maxheight - pedestal) * 0.5, (maxheight - pedestal) * 10); + f.SetParLimits(1, 0, nsamples); + f.SetParLimits(2, 0, 10.0); + f.SetParLimits(3, 0, 10.0); + f.SetParLimits(4, pedestal - std::abs(maxheight - pedestal), pedestal + std::abs(maxheight - pedestal)); + + // Perform fit + h.Fit(&f, "QRN0W", "", 0, nsamples); + + // Calculate peak amplitude and time from fit parameters + // Peak height is (p0 * Power(p2/p3, p2)) / exp(p2) + fit_amp = (f.GetParameter(0) * pow(f.GetParameter(2) / f.GetParameter(3), f.GetParameter(2))) / exp(f.GetParameter(2)); + // Peak time is t0 + power/decay + fit_time = f.GetParameter(1) + f.GetParameter(2) / f.GetParameter(3); + fit_ped = f.GetParameter(4); + + // Calculate chi2 + for (int i = 0; i < nsamples; i++) + { + if (h.GetBinContent(i + 1) > 0) + { + double diff = h.GetBinContent(i + 1) - f.Eval(i); + chi2val += diff * diff; + } + } + } + else // POWERLAWDOUBLEEXP + { + // Create fit function with 7 parameters + TF1 f("f_doubleexp", SignalShape_PowerLawDoubleExp, 0, nsamples, 7); + npar = 7; + + // Set initial parameters + double risetime = 2.0; + double par[7]; + par[0] = (maxheight - pedestal) * 0.7; // Amplitude + par[1] = maxbin - risetime; // t0 + if (par[1] < 0) + { + par[1] = 0; + } + par[2] = m_doubleexp_power; // Power + par[3] = m_doubleexp_peaktime1; // Peak Time 1 + par[4] = pedestal; // Pedestal + par[5] = m_doubleexp_ratio; // Amplitude ratio + par[6] = m_doubleexp_peaktime2; // Peak Time 2 + + f.SetParameters(par); + f.SetParLimits(0, (maxheight - pedestal) * -1.5, (maxheight - pedestal) * 1.5); + f.SetParLimits(1, maxbin - 3 * risetime, maxbin + risetime); + f.SetParLimits(2, 1, 5.0); + f.SetParLimits(3, risetime * 0.5, risetime * 4); + f.SetParLimits(4, pedestal - std::abs(maxheight - pedestal), pedestal + std::abs(maxheight - pedestal)); + f.SetParLimits(5, 0, 1); + f.SetParLimits(6, risetime * 0.5, risetime * 4); + + // Perform fit + h.Fit(&f, "QRN0W", "", 0, nsamples); + + // Find peak by evaluating the function + double peakpos1 = f.GetParameter(3); + double peakpos2 = f.GetParameter(6); + double max_peakpos = f.GetParameter(1) + (peakpos1 > peakpos2 ? peakpos1 : peakpos2); + if (max_peakpos > nsamples - 1) + { + max_peakpos = nsamples - 1; + } + + fit_time = f.GetMaximumX(f.GetParameter(1), max_peakpos); + fit_amp = f.Eval(fit_time) - f.GetParameter(4); + fit_ped = f.GetParameter(4); + + // Calculate chi2 + for (int i = 0; i < nsamples; i++) + { + if (h.GetBinContent(i + 1) > 0) + { + double diff = h.GetBinContent(i + 1) - f.Eval(i); + chi2val += diff * diff; + } + } + } + + chi2val /= (ndata - npar); // divide by ndf + + fit_values.push_back({static_cast(fit_amp), static_cast(fit_time), + static_cast(fit_ped), static_cast(chi2val), 0}); + } + + return fit_values; +} diff --git a/offline/packages/CaloReco/CaloWaveformFitting.h b/offline/packages/CaloReco/CaloWaveformFitting.h index 1a9f887305..fcc6783d67 100644 --- a/offline/packages/CaloReco/CaloWaveformFitting.h +++ b/offline/packages/CaloReco/CaloWaveformFitting.h @@ -9,6 +9,12 @@ class TProfile; class CaloWaveformFitting { public: + enum FuncFitType + { + POWERLAWEXP = 0, + POWERLAWDOUBLEEXP = 1, + }; + CaloWaveformFitting() = default; ~CaloWaveformFitting(); @@ -61,9 +67,34 @@ class CaloWaveformFitting std::vector> calo_processing_templatefit(std::vector> chnlvector); static std::vector> calo_processing_fast(const std::vector> &chnlvector); std::vector> calo_processing_nyquist(const std::vector> &chnlvector); + std::vector> calo_processing_funcfit(const std::vector> &chnlvector); void initialize_processing(const std::string &templatefile); + // Power-law fit function: amplitude * (x-t0)^power * exp(-(x-t0)*decay) + pedestal + static double SignalShape_PowerLawExp(double *x, double *par); + // Double exponential power-law fit function + static double SignalShape_PowerLawDoubleExp(double *x, double *par); + + void set_funcfit_type(FuncFitType type) + { + m_funcfit_type = type; + } + + void set_powerlaw_params(double power, double decay) + { + m_powerlaw_power = power; + m_powerlaw_decay = decay; + } + + void set_doubleexp_params(double power, double peaktime1, double peaktime2, double ratio) + { + m_doubleexp_power = power; + m_doubleexp_peaktime1 = peaktime1; + m_doubleexp_peaktime2 = peaktime2; + m_doubleexp_ratio = ratio; + } + private: static void FastMax(float x0, float x1, float x2, float y0, float y1, float y2, float &xmax, float &ymax); std::vector NyquistInterpolation(std::vector &vec_signal_samples); @@ -97,5 +128,18 @@ class CaloWaveformFitting std::string url_template; std::string url_onnx; std::string m_model_name; + + // Functional fit type selector + FuncFitType m_funcfit_type{POWERLAWEXP}; + + // Power-law fit parameters + double m_powerlaw_power{4.0}; + double m_powerlaw_decay{1.5}; + + // Double exponential fit parameters + double m_doubleexp_power{2.0}; + double m_doubleexp_peaktime1{5.0}; + double m_doubleexp_peaktime2{5.0}; + double m_doubleexp_ratio{0.3}; }; #endif diff --git a/offline/packages/CaloReco/CaloWaveformProcessing.cc b/offline/packages/CaloReco/CaloWaveformProcessing.cc index 4e51f71f45..3954cd608e 100644 --- a/offline/packages/CaloReco/CaloWaveformProcessing.cc +++ b/offline/packages/CaloReco/CaloWaveformProcessing.cc @@ -65,6 +65,19 @@ void CaloWaveformProcessing::initialize_processing() m_Fitter = new CaloWaveformFitting(); m_Fitter->initialize_processing(url_template); } + else if (m_processingtype == CaloWaveformProcessing::FUNCFIT) + { + m_Fitter = new CaloWaveformFitting(); + // Set functional fit type and parameters + m_Fitter->set_funcfit_type(static_cast(_funcfit_type)); + m_Fitter->set_powerlaw_params(_powerlaw_power, _powerlaw_decay); + m_Fitter->set_doubleexp_params(_doubleexp_power, _doubleexp_peaktime1, _doubleexp_peaktime2, _doubleexp_ratio); + if (_bdosoftwarezerosuppression) + { + m_Fitter->set_softwarezerosuppression(_bdosoftwarezerosuppression, _nsoftwarezerosuppression); + } + m_Fitter->set_handleSaturation(true); + } } std::vector> CaloWaveformProcessing::process_waveform(std::vector> waveformvector) @@ -91,6 +104,10 @@ std::vector> CaloWaveformProcessing::process_waveform(std::ve { fitresults = m_Fitter->calo_processing_nyquist(waveformvector); } + if (m_processingtype == CaloWaveformProcessing::FUNCFIT) + { + fitresults = m_Fitter->calo_processing_funcfit(waveformvector); + } return fitresults; } diff --git a/offline/packages/CaloReco/CaloWaveformProcessing.h b/offline/packages/CaloReco/CaloWaveformProcessing.h index 8a5a5bbbe6..1ffa7aa265 100644 --- a/offline/packages/CaloReco/CaloWaveformProcessing.h +++ b/offline/packages/CaloReco/CaloWaveformProcessing.h @@ -20,6 +20,7 @@ class CaloWaveformProcessing : public SubsysReco FAST = 3, NYQUIST = 4, TEMPLATE_NOSAT = 5, + FUNCFIT = 6, }; CaloWaveformProcessing() = default; @@ -75,6 +76,26 @@ class CaloWaveformProcessing : public SubsysReco _dobitfliprecovery = dobitfliprecovery; } + // Functional fit options: 0 = PowerLawExp, 1 = PowerLawDoubleExp + void set_funcfit_type(int type) + { + _funcfit_type = type; + } + + void set_powerlaw_params(double power, double decay) + { + _powerlaw_power = power; + _powerlaw_decay = decay; + } + + void set_doubleexp_params(double power, double peaktime1, double peaktime2, double ratio) + { + _doubleexp_power = power; + _doubleexp_peaktime1 = peaktime1; + _doubleexp_peaktime2 = peaktime2; + _doubleexp_ratio = ratio; + } + std::vector> process_waveform(std::vector> waveformvector); std::vector> calo_processing_ONNX(const std::vector> &chnlvector); @@ -108,6 +129,15 @@ class CaloWaveformProcessing : public SubsysReco std::string m_model_name{"CEMC_ONNX"}; std::array m_Onnx_factor{std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}; std::array m_Onnx_offset{std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}; + + // Functional fit parameters + int _funcfit_type{0}; // 0 = PowerLawExp, 1 = PowerLawDoubleExp + double _powerlaw_power{4.0}; + double _powerlaw_decay{1.5}; + double _doubleexp_power{2.0}; + double _doubleexp_peaktime1{5.0}; + double _doubleexp_peaktime2{5.0}; + double _doubleexp_ratio{0.3}; }; #endif From 5334735d2a18c44a0d1737216fcf1cdb1d36e4fb Mon Sep 17 00:00:00 2001 From: Shuonli <71942661+Shuonli@users.noreply.github.com> Date: Tue, 20 Jan 2026 19:09:37 -0500 Subject: [PATCH 092/393] Update offline/packages/CaloReco/CaloWaveformFitting.cc Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- offline/packages/CaloReco/CaloWaveformFitting.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/offline/packages/CaloReco/CaloWaveformFitting.cc b/offline/packages/CaloReco/CaloWaveformFitting.cc index e84ec84874..fb793bb4eb 100644 --- a/offline/packages/CaloReco/CaloWaveformFitting.cc +++ b/offline/packages/CaloReco/CaloWaveformFitting.cc @@ -863,7 +863,15 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con } } - chi2val /= (ndata - npar); // divide by ndf + int ndf = ndata - npar; + if (ndf > 0) + { + chi2val /= ndf; + } + else + { + chi2val = std::numeric_limits::quiet_NaN(); + } fit_values.push_back({static_cast(fit_amp), static_cast(fit_time), static_cast(fit_ped), static_cast(chi2val), 0}); From 0296552dac10e4de6182cf5c8138940d1297436e Mon Sep 17 00:00:00 2001 From: Michael Peters Date: Tue, 20 Jan 2026 22:37:26 -0500 Subject: [PATCH 093/393] clang-tidy fixes --- calibrations/tpc/dEdx/GlobaldEdxFitter.cc | 20 +++++------ calibrations/tpc/dEdx/GlobaldEdxFitter.h | 8 ++--- calibrations/tpc/dEdx/bethe_bloch.h | 44 +++++++++++------------ calibrations/tpc/dEdx/dEdxFitter.cc | 18 +++++----- calibrations/tpc/dEdx/dEdxFitter.h | 26 ++++++++------ calibrations/tpc/dEdx/test_sample_size.C | 23 ++++++++---- 6 files changed, 77 insertions(+), 62 deletions(-) diff --git a/calibrations/tpc/dEdx/GlobaldEdxFitter.cc b/calibrations/tpc/dEdx/GlobaldEdxFitter.cc index 8fa5045cba..1cefa44dcd 100644 --- a/calibrations/tpc/dEdx/GlobaldEdxFitter.cc +++ b/calibrations/tpc/dEdx/GlobaldEdxFitter.cc @@ -50,9 +50,9 @@ void GlobaldEdxFitter::processResidualData(const std::string& infile, size_t ntr std::cout << entry << std::endl; } t->GetEntry(entry); - if(nmaps>0 && nintt>0 && fabs(eta)<1. && dcaxy<0.5 && ntpc>30) + if(nmaps>0 && nintt>0 && std::fabs(eta)<1. && dcaxy<0.5 && ntpc>30) { - p.push_back(sqrt(px*px+py*py+pz*pz)); + p.push_back(std::sqrt(px*px+py*py+pz*pz)); dEdx.push_back(dedx); } } @@ -172,28 +172,28 @@ double GlobaldEdxFitter::get_fitquality(double norm, double ZS_loss) if(pi_dist @@ -31,21 +31,21 @@ namespace dedx_constants // Bethe-Bloch fit function, vs. betagamma // A = normalization constant, equal to (ADC conversion)*4pi*n*Z^2*e^4/(m_e*c^2*4pi*epsilon_0^2) // B = A*(ln(2*m_e/I)-1) - (zero-suppression loss factor) -inline const double bethe_bloch_new(const double betagamma, const double A, const double B, const double C) +inline double bethe_bloch_new(const double betagamma, const double A, const double B, const double C) { const double beta = betagamma/sqrt(1.+betagamma*betagamma); return A/(beta*beta)*TMath::Log(betagamma) + A/(beta*beta)*B - A - C; } -inline const double bethe_bloch_new_2D(const double betagamma, const double A, const double B) +inline double bethe_bloch_new_2D(const double betagamma, const double A, const double B) { const double beta = betagamma/sqrt(1.+betagamma*betagamma); return A/(beta*beta)*(2.*TMath::Log(2.*dedx_constants::m_e/dedx_constants::sphenix_I * betagamma) - beta*beta) - B; } -inline const double bethe_bloch_new_1D(const double betagamma, const double A) +inline double bethe_bloch_new_1D(const double betagamma, const double A) { const double beta = betagamma/sqrt(1.+betagamma*betagamma); @@ -53,7 +53,7 @@ inline const double bethe_bloch_new_1D(const double betagamma, const double A) } // dE/dx for one gas species, up to normalization -inline const double bethe_bloch_species(const double betagamma, const double I) +inline double bethe_bloch_species(const double betagamma, const double I) { const double m_e = 511e3; // eV @@ -63,14 +63,14 @@ inline const double bethe_bloch_species(const double betagamma, const double I) } // dE/dx for TPC gas mixture, up to normalization -inline const double bethe_bloch_total(const double betagamma) +inline double bethe_bloch_total(const double betagamma) { return dedx_constants::ar_frac * bethe_bloch_species(betagamma,dedx_constants::ar_I) + dedx_constants::cf4_frac * bethe_bloch_species(betagamma,dedx_constants::cf4_I) + dedx_constants::isobutane_frac * bethe_bloch_species(betagamma,dedx_constants::isobutane_I); } -inline Double_t bethe_bloch_new_wrapper(Double_t* x, Double_t* par) +inline Double_t bethe_bloch_new_wrapper(const Double_t* const x, const Double_t* const par) { Double_t betagamma = x[0]; Double_t A = par[0]; @@ -80,7 +80,7 @@ inline Double_t bethe_bloch_new_wrapper(Double_t* x, Double_t* par) return bethe_bloch_new(betagamma,A,B,C); } -inline Double_t bethe_bloch_new_2D_wrapper(Double_t* x, Double_t* par) +inline Double_t bethe_bloch_new_2D_wrapper(const Double_t* const x, const Double_t* const par) { Double_t betagamma = x[0]; Double_t A = par[0]; @@ -89,7 +89,7 @@ inline Double_t bethe_bloch_new_2D_wrapper(Double_t* x, Double_t* par) return bethe_bloch_new_2D(betagamma,A,B); } -inline Double_t bethe_bloch_new_1D_wrapper(Double_t* x, Double_t* par) +inline Double_t bethe_bloch_new_1D_wrapper(const Double_t* const x, const Double_t* const par) { Double_t betagamma = x[0]; Double_t A = par[0]; @@ -98,7 +98,7 @@ inline Double_t bethe_bloch_new_1D_wrapper(Double_t* x, Double_t* par) } // wrapper function for TF1 constructor, for fitting -inline Double_t bethe_bloch_wrapper(Double_t* ln_bg, Double_t* par) +inline Double_t bethe_bloch_wrapper(const Double_t* const ln_bg, const Double_t* const par) { Double_t betagamma = exp(ln_bg[0]); @@ -107,7 +107,7 @@ inline Double_t bethe_bloch_wrapper(Double_t* ln_bg, Double_t* par) return norm * bethe_bloch_total(betagamma); } -inline Double_t bethe_bloch_vs_p_wrapper(Double_t* x, Double_t* par) +inline Double_t bethe_bloch_vs_p_wrapper(const Double_t* const x, const Double_t* const par) { Double_t p = x[0]; Double_t norm = par[0]; @@ -116,7 +116,7 @@ inline Double_t bethe_bloch_vs_p_wrapper(Double_t* x, Double_t* par) return norm * bethe_bloch_total(fabs(p)/m); } -inline Double_t bethe_bloch_vs_logp_wrapper(Double_t* x, Double_t* par) +inline Double_t bethe_bloch_vs_logp_wrapper(const Double_t* const x, const Double_t* const par) { Double_t p = pow(10.,x[0]); Double_t norm = par[0]; @@ -125,7 +125,7 @@ inline Double_t bethe_bloch_vs_logp_wrapper(Double_t* x, Double_t* par) return norm * bethe_bloch_total(fabs(p)/m); } -inline Double_t bethe_bloch_vs_p_wrapper_ZS(Double_t* x, Double_t* par) +inline Double_t bethe_bloch_vs_p_wrapper_ZS(const Double_t* const x, const Double_t* const par) { Double_t p = x[0]; Double_t norm = par[0]; @@ -135,7 +135,7 @@ inline Double_t bethe_bloch_vs_p_wrapper_ZS(Double_t* x, Double_t* par) return norm * bethe_bloch_total(fabs(p)/m) - ZS_loss; } -inline Double_t bethe_bloch_vs_p_wrapper_new(Double_t* x, Double_t* par) +inline Double_t bethe_bloch_vs_p_wrapper_new(const Double_t* const x, const Double_t* const par) { Double_t p = x[0]; Double_t A = par[0]; @@ -146,7 +146,7 @@ inline Double_t bethe_bloch_vs_p_wrapper_new(Double_t* x, Double_t* par) return bethe_bloch_new(fabs(p)/m,A,B,C); } -inline Double_t bethe_bloch_vs_p_wrapper_new_2D(Double_t* x, Double_t* par) +inline Double_t bethe_bloch_vs_p_wrapper_new_2D(const Double_t* const x, const Double_t* const par) { Double_t p = x[0]; Double_t A = par[0]; @@ -156,7 +156,7 @@ inline Double_t bethe_bloch_vs_p_wrapper_new_2D(Double_t* x, Double_t* par) return bethe_bloch_new_2D(fabs(p)/m,A,B); } -inline Double_t bethe_bloch_vs_p_wrapper_new_1D(Double_t* x, Double_t* par) +inline Double_t bethe_bloch_vs_p_wrapper_new_1D(const Double_t* const x, const Double_t* const par) { Double_t p = x[0]; Double_t A = par[0]; @@ -165,7 +165,7 @@ inline Double_t bethe_bloch_vs_p_wrapper_new_1D(Double_t* x, Double_t* par) return bethe_bloch_new_1D(fabs(p)/m,A); } -inline Double_t bethe_bloch_vs_logp_wrapper_ZS(Double_t* x, Double_t* par) +inline Double_t bethe_bloch_vs_logp_wrapper_ZS(const Double_t* const x, const Double_t* const par) { Double_t p = pow(10.,x[0]); Double_t norm = par[0]; @@ -175,7 +175,7 @@ inline Double_t bethe_bloch_vs_logp_wrapper_ZS(Double_t* x, Double_t* par) return norm * bethe_bloch_total(fabs(p)/m) - ZS_loss; } -inline Double_t bethe_bloch_vs_logp_wrapper_new(Double_t* x, Double_t* par) +inline Double_t bethe_bloch_vs_logp_wrapper_new(const Double_t* const x, const Double_t* const par) { Double_t p = pow(10.,x[0]); Double_t A = par[0]; @@ -186,7 +186,7 @@ inline Double_t bethe_bloch_vs_logp_wrapper_new(Double_t* x, Double_t* par) return bethe_bloch_new(fabs(p)/m,A,B,C); } -inline Double_t bethe_bloch_vs_logp_wrapper_new_1D(Double_t* x, Double_t* par) +inline Double_t bethe_bloch_vs_logp_wrapper_new_1D(const Double_t* const x, const Double_t* const par) { Double_t p = pow(10.,x[0]); Double_t A = par[0]; @@ -197,7 +197,7 @@ inline Double_t bethe_bloch_vs_logp_wrapper_new_1D(Double_t* x, Double_t* par) // ratio of dE/dx between two particle species at the same momentum // (useful for dE/dx peak fits) -inline const double dedx_ratio(const double p, const double m1, const double m2) +inline double dedx_ratio(const double p, const double m1, const double m2) { const double betagamma1 = fabs(p)/m1; const double betagamma2 = fabs(p)/m2; @@ -205,4 +205,4 @@ inline const double dedx_ratio(const double p, const double m1, const double m2) return bethe_bloch_total(betagamma1)/bethe_bloch_total(betagamma2); } -#endif // BETHE_BLOCH_H +#endif // BETHE_BLOCH_H_ diff --git a/calibrations/tpc/dEdx/dEdxFitter.cc b/calibrations/tpc/dEdx/dEdxFitter.cc index 0f03bae44e..e46004624a 100644 --- a/calibrations/tpc/dEdx/dEdxFitter.cc +++ b/calibrations/tpc/dEdx/dEdxFitter.cc @@ -18,10 +18,10 @@ dEdxFitter::dEdxFitter(const std::string &name): } //___________________________________ -int dEdxFitter::InitRun(PHCompositeNode *topNode) +int dEdxFitter::InitRun(PHCompositeNode * /*topNode*/) { std::cout << PHWHERE << " Opening file " << _outfile << std::endl; - PHTFileServer::get().open( _outfile, "RECREATE"); + outf = new TFile( _outfile.c_str(), "RECREATE"); return 0; } @@ -44,13 +44,13 @@ int dEdxFitter::process_event(PHCompositeNode *topNode) std::cout << "event " << _event << std::endl; } - process_tracks(topNode); + process_tracks(); return 0; } //_____________________________________ -void dEdxFitter::process_tracks(PHCompositeNode *topNode) +void dEdxFitter::process_tracks() { for(const auto &[key, track] : *_trackmap) @@ -93,7 +93,7 @@ void dEdxFitter::process_tracks(PHCompositeNode *topNode) int nintt = std::get<1>(nclus); int ntpc = std::get<2>(nclus); - if(nmaps>=nmaps_cut && nintt>=nintt_cut && ntpc>=ntpc_cut && fabs(track->get_eta())=nmaps_cut && nintt>=nintt_cut && ntpc>=ntpc_cut && std::fabs(track->get_eta())addTrack(get_dedx(track),track->get_p()); } @@ -202,15 +202,13 @@ void dEdxFitter::GetNodes(PHCompositeNode *topNode) } //______________________________________ -int dEdxFitter::End(PHCompositeNode *topNode) +int dEdxFitter::End(PHCompositeNode * /*topNode*/) { if(minima.empty()) { minima.push_back(fitter->get_minimum()); } - PHTFileServer::get().cd( _outfile ); - double avg_minimum = 0.; for(double m : minima) { @@ -218,6 +216,8 @@ int dEdxFitter::End(PHCompositeNode *topNode) } avg_minimum /= (double)minima.size(); + outf->cd(); + TF1* pi_band = new TF1("pi_band","bethe_bloch_new_1D(fabs(x)/[1],[0])"); pi_band->SetParameter(0,avg_minimum); pi_band->SetParameter(1,dedx_constants::m_pi); @@ -243,5 +243,7 @@ int dEdxFitter::End(PHCompositeNode *topNode) std::cout << "dEdxFitter extracted minimum: " << avg_minimum << std::endl; } + outf->Close(); + return 0; } diff --git a/calibrations/tpc/dEdx/dEdxFitter.h b/calibrations/tpc/dEdx/dEdxFitter.h index fda3d7c124..0dc4da0f0c 100644 --- a/calibrations/tpc/dEdx/dEdxFitter.h +++ b/calibrations/tpc/dEdx/dEdxFitter.h @@ -1,5 +1,5 @@ -#ifndef __DEDXFITTER_H__ -#define __DEDXFITTER_H__ +#ifndef DEDXFITTER_H_ +#define DEDXFITTER_H_ #include #include @@ -20,20 +20,25 @@ class dEdxFitter: public SubsysReco { public: //Default constructor - dEdxFitter(const std::string &name="dEdxFitter"); + explicit dEdxFitter(const std::string &name="dEdxFitter"); //Initialization, called for initialization - int InitRun(PHCompositeNode *); + int InitRun(PHCompositeNode * /*topNode*/) override; //Process Event, called for each event - int process_event(PHCompositeNode *); + int process_event(PHCompositeNode *topNode) override; //End, write and close files - int End(PHCompositeNode *); + int End(PHCompositeNode * /*topNode*/) override; //Change output filename void set_filename(const char* file) - { if(file) _outfile = file; } + { + if(file) + { + _outfile = file; + } + } void set_nmaps_cut(int nmaps) { nmaps_cut = nmaps; } @@ -56,6 +61,7 @@ class dEdxFitter: public SubsysReco private: //output filename std::string _outfile = "dedx_outfile.root"; + TFile* outf = nullptr; size_t _event = 0; SvtxTrackMap* _trackmap = nullptr; @@ -65,9 +71,9 @@ class dEdxFitter: public SubsysReco SvtxVertexMap* _vertexmap = nullptr; //Get all the nodes - void GetNodes(PHCompositeNode *); + void GetNodes(PHCompositeNode * /*topNode*/); - void process_tracks(PHCompositeNode *); + void process_tracks(); int nmaps_cut = 1; int nintt_cut = 1; @@ -85,4 +91,4 @@ class dEdxFitter: public SubsysReco }; -#endif //* __DEDXFITTER_H__ *// +#endif //* DEDXFITTER_H_ *// diff --git a/calibrations/tpc/dEdx/test_sample_size.C b/calibrations/tpc/dEdx/test_sample_size.C index df2a39b322..8464aba486 100644 --- a/calibrations/tpc/dEdx/test_sample_size.C +++ b/calibrations/tpc/dEdx/test_sample_size.C @@ -1,7 +1,13 @@ #include "GlobaldEdxFitter.h" #include +#include +#include +#include +#include + #include +#include void test_sample_size(const std::string& infile="/sphenix/tg/tg01/hf/mjpeters/run53877_tracks/track_output_53877_*.root") { @@ -14,9 +20,6 @@ void test_sample_size(const std::string& infile="/sphenix/tg/tg01/hf/mjpeters/ru const float distribution_xmin = 5.; const float distribution_xmax = 26.; - - EColor base_color = kRed; - std::vector> fitvalues_all; std::vector fitvalues_avg; std::vector fitvalues_stdev; @@ -102,7 +105,7 @@ void test_sample_size(const std::string& infile="/sphenix/tg/tg01/hf/mjpeters/ru stdev += pow(fitvalues_all[i][j]-avg,2.); } stdev /= (float)n_samples; - stdev = sqrt(stdev); + stdev = std::sqrt(stdev); fitvalues_avg.push_back(avg); fitvalues_stdev.push_back(stdev); @@ -181,11 +184,17 @@ void test_sample_size(const std::string& infile="/sphenix/tg/tg01/hf/mjpeters/ru } TFile* fout = new TFile("dedxfitvals.root","RECREATE"); - for(auto& c : fluctuations) c->Write(); - for(auto& c : distributions) c->Write(); + for(auto& c : fluctuations) + { + c->Write(); + } + for(auto& c : distributions) + { + c->Write(); + } cg->Write(); cbg->Write(); cbands->Write(); cb->Write(); - + fout->Close(); } From db1ed97bfdb779c337d2f911b048296bf622cf2a Mon Sep 17 00:00:00 2001 From: Shuonli Date: Tue, 20 Jan 2026 23:08:17 -0500 Subject: [PATCH 094/393] change default --- offline/packages/CaloReco/CaloWaveformProcessing.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/CaloReco/CaloWaveformProcessing.h b/offline/packages/CaloReco/CaloWaveformProcessing.h index 1ffa7aa265..b657459d6c 100644 --- a/offline/packages/CaloReco/CaloWaveformProcessing.h +++ b/offline/packages/CaloReco/CaloWaveformProcessing.h @@ -131,7 +131,7 @@ class CaloWaveformProcessing : public SubsysReco std::array m_Onnx_offset{std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}; // Functional fit parameters - int _funcfit_type{0}; // 0 = PowerLawExp, 1 = PowerLawDoubleExp + int _funcfit_type{1}; // 0 = PowerLawExp, 1 = PowerLawDoubleExp double _powerlaw_power{4.0}; double _powerlaw_decay{1.5}; double _doubleexp_power{2.0}; From 0d8b5fc4fd281a852503bb9c20df765a061945b6 Mon Sep 17 00:00:00 2001 From: Shuonli Date: Tue, 20 Jan 2026 23:39:00 -0500 Subject: [PATCH 095/393] clang tidy --- .../packages/CaloReco/CaloWaveformFitting.cc | 19 +++++-------------- .../CaloReco/CaloWaveformProcessing.cc | 2 +- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/offline/packages/CaloReco/CaloWaveformFitting.cc b/offline/packages/CaloReco/CaloWaveformFitting.cc index fb793bb4eb..266072dfbe 100644 --- a/offline/packages/CaloReco/CaloWaveformFitting.cc +++ b/offline/packages/CaloReco/CaloWaveformFitting.cc @@ -22,7 +22,7 @@ #include #include -static ROOT::TThreadExecutor *t = new ROOT::TThreadExecutor(1);// NOLINT(misc-use-anonymous-namespace) +static ROOT::TThreadExecutor *t = new ROOT::TThreadExecutor(1); // NOLINT(misc-use-anonymous-namespace) double CaloWaveformFitting::template_function(double *x, double *par) { Double_t v1 = (par[0] * h_template->Interpolate(x[0] - par[1])) + par[2]; @@ -771,10 +771,7 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con double par[5]; par[0] = maxheight - pedestal; // Amplitude par[1] = maxbin - risetime; // t0 - if (par[1] < 0) - { - par[1] = 0; - } + par[1] = std::max(par[1], 0); par[2] = m_powerlaw_power; // Power par[3] = m_powerlaw_decay; // Decay par[4] = pedestal; // Pedestal @@ -816,11 +813,8 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con double risetime = 2.0; double par[7]; par[0] = (maxheight - pedestal) * 0.7; // Amplitude - par[1] = maxbin - risetime; // t0 - if (par[1] < 0) - { - par[1] = 0; - } + par[1] = maxbin - risetime; // t0 + par[1] = std::max(par[1], 0); par[2] = m_doubleexp_power; // Power par[3] = m_doubleexp_peaktime1; // Peak Time 1 par[4] = pedestal; // Pedestal @@ -843,10 +837,7 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con double peakpos1 = f.GetParameter(3); double peakpos2 = f.GetParameter(6); double max_peakpos = f.GetParameter(1) + (peakpos1 > peakpos2 ? peakpos1 : peakpos2); - if (max_peakpos > nsamples - 1) - { - max_peakpos = nsamples - 1; - } + max_peakpos = std::min(max_peakpos, nsamples - 1); fit_time = f.GetMaximumX(f.GetParameter(1), max_peakpos); fit_amp = f.Eval(fit_time) - f.GetParameter(4); diff --git a/offline/packages/CaloReco/CaloWaveformProcessing.cc b/offline/packages/CaloReco/CaloWaveformProcessing.cc index 3954cd608e..057e427627 100644 --- a/offline/packages/CaloReco/CaloWaveformProcessing.cc +++ b/offline/packages/CaloReco/CaloWaveformProcessing.cc @@ -186,7 +186,7 @@ std::vector> CaloWaveformProcessing::calo_processing_ONNX(con { // downstream onnx does not have a static input vector API, // so we need to make a copy - std::vector vtmp(v); //NOLINT(performance-unnecessary-copy-initialization) + std::vector vtmp(v); // NOLINT(performance-unnecessary-copy-initialization) val = onnxInference(onnxmodule, vtmp, 1, onnxlib::n_input, onnxlib::n_output); unsigned int nvals = val.size(); for (unsigned int i = 0; i < nvals; i++) From 47d0f386183507d42c2bd37a2751c83b354d73b5 Mon Sep 17 00:00:00 2001 From: Shuonli Date: Wed, 21 Jan 2026 10:43:48 -0500 Subject: [PATCH 096/393] make default consistant --- offline/packages/CaloReco/CaloWaveformFitting.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/CaloReco/CaloWaveformFitting.h b/offline/packages/CaloReco/CaloWaveformFitting.h index fcc6783d67..648d6ab0fa 100644 --- a/offline/packages/CaloReco/CaloWaveformFitting.h +++ b/offline/packages/CaloReco/CaloWaveformFitting.h @@ -130,7 +130,7 @@ class CaloWaveformFitting std::string m_model_name; // Functional fit type selector - FuncFitType m_funcfit_type{POWERLAWEXP}; + FuncFitType m_funcfit_type{POWERLAWDOUBLEEXP}; // Power-law fit parameters double m_powerlaw_power{4.0}; From 74e453377053707818b5e21f0cbaf433349be06b Mon Sep 17 00:00:00 2001 From: silas-gross Date: Wed, 21 Jan 2026 13:30:49 -0500 Subject: [PATCH 097/393] Allowed for access to n_good and n_evts while keeping the variables private --- generators/Herwig/HepMCTrigger/HepMCJetTrigger.h | 6 ++++-- generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/generators/Herwig/HepMCTrigger/HepMCJetTrigger.h b/generators/Herwig/HepMCTrigger/HepMCJetTrigger.h index 74ee855493..0917e42cdc 100644 --- a/generators/Herwig/HepMCTrigger/HepMCJetTrigger.h +++ b/generators/Herwig/HepMCTrigger/HepMCJetTrigger.h @@ -47,8 +47,8 @@ class HepMCJetTrigger : public SubsysReco /// Called at the end of all processing. /// Reset - int n_evts{0}; - int n_good{0}; + int getNevts(){return this->n_evts;} + int getNgood(){return this->n_good;} private: bool isGoodEvent(HepMC::GenEvent* e1); @@ -57,6 +57,8 @@ class HepMCJetTrigger : public SubsysReco float threshold{0.}; int goal_event_number{1000}; bool set_event_limit{false}; + int n_evts{0}; + int n_good{0}; }; #endif // HEPMCJETTRIGGER_H diff --git a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h index 4900bad5ad..e0494cb3e7 100644 --- a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h +++ b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h @@ -29,8 +29,6 @@ class HepMCParticleTrigger : public SubsysReco This is where you do the real work. */ int process_event(PHCompositeNode* topNode) override; - int n_evts{0}; - int n_good{0}; /// Clean up internals after each event. @@ -68,6 +66,8 @@ class HepMCParticleTrigger : public SubsysReco void SetPzHighLow(double, double); void SetStableParticleOnly(bool b) { m_doStableParticleOnly = b; } + int getNevts(){return this->n_evts;} + int getNgood(){return this->n_good;} private: bool isGoodEvent(HepMC::GenEvent* e1); @@ -79,6 +79,8 @@ class HepMCParticleTrigger : public SubsysReco float threshold{0.}; int goal_event_number{1000}; bool set_event_limit{false}; + int n_evts{0}; + int n_good{0}; float _theEtaHigh{1.1}; float _theEtaLow{-1.1}; From b56ed66c1776e7b31936c2b5a5da349ceab6df0b Mon Sep 17 00:00:00 2001 From: silas-gross Date: Wed, 21 Jan 2026 16:16:17 -0500 Subject: [PATCH 098/393] event counter was in the wrong place --- generators/Herwig/HepMCTrigger/HepMCJetTrigger.cc | 2 +- generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/generators/Herwig/HepMCTrigger/HepMCJetTrigger.cc b/generators/Herwig/HepMCTrigger/HepMCJetTrigger.cc index 792720a962..506799c874 100644 --- a/generators/Herwig/HepMCTrigger/HepMCJetTrigger.cc +++ b/generators/Herwig/HepMCTrigger/HepMCJetTrigger.cc @@ -31,7 +31,6 @@ HepMCJetTrigger::HepMCJetTrigger(float trigger_thresh, int n_incom, bool up_lim, int HepMCJetTrigger::process_event(PHCompositeNode* topNode) { // std::cout << "HepMCJetTrigger::process_event(PHCompositeNode *topNode) Processing Event" << std::endl; - n_evts++; if (this->set_event_limit == true) { // needed to keep all HepMC output at the same number of events if (n_good >= this->goal_event_number) @@ -39,6 +38,7 @@ int HepMCJetTrigger::process_event(PHCompositeNode* topNode) return Fun4AllReturnCodes::ABORTEVENT; } } + n_evts++; PHHepMCGenEventMap* phg = findNode::getClass(topNode, "PHHepMCGenEventMap"); if (!phg) { diff --git a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc index fe1193cba0..81d594e528 100644 --- a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc +++ b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc @@ -68,7 +68,6 @@ HepMCParticleTrigger::HepMCParticleTrigger(float trigger_thresh, int n_incom, bo int HepMCParticleTrigger::process_event(PHCompositeNode* topNode) { // std::cout << "HepMCParticleTrigger::process_event(PHCompositeNode *topNode) Processing Event" << std::endl; - n_evts++; if (this->set_event_limit == true) { // needed to keep all HepMC output at the same number of events if (n_good >= this->goal_event_number) @@ -76,6 +75,7 @@ int HepMCParticleTrigger::process_event(PHCompositeNode* topNode) return Fun4AllReturnCodes::ABORTEVENT; } } + n_evts++; bool good_event{false}; PHHepMCGenEventMap* phg = findNode::getClass(topNode, "PHHepMCGenEventMap"); if (!phg) From 9a19bb92da1535491aeb611f05c6161932b82d11 Mon Sep 17 00:00:00 2001 From: Michael Peters Date: Wed, 21 Jan 2026 22:25:40 -0500 Subject: [PATCH 099/393] cppcheck fix --- calibrations/tpc/dEdx/dEdxFitter.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/calibrations/tpc/dEdx/dEdxFitter.cc b/calibrations/tpc/dEdx/dEdxFitter.cc index e46004624a..4277d3f059 100644 --- a/calibrations/tpc/dEdx/dEdxFitter.cc +++ b/calibrations/tpc/dEdx/dEdxFitter.cc @@ -11,10 +11,10 @@ //____________________________________ dEdxFitter::dEdxFitter(const std::string &name): - SubsysReco(name) + SubsysReco(name), + fitter(std::make_unique()) { //initialize - fitter = std::make_unique(); } //___________________________________ From d9bda1e7d5934eecebd02594e0d4454300f5b404 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Thu, 22 Jan 2026 12:17:46 -0500 Subject: [PATCH 100/393] fix pileup handling for oo in CreateFileList.pl --- offline/framework/frog/CreateFileList.pl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/offline/framework/frog/CreateFileList.pl b/offline/framework/frog/CreateFileList.pl index 19456cbc09..7e87a97278 100755 --- a/offline/framework/frog/CreateFileList.pl +++ b/offline/framework/frog/CreateFileList.pl @@ -149,6 +149,7 @@ my $AuAu_pileupstring; my $pp_pileupstring; my $pAu_pileupstring; +my $OO_pileupstring; my $pileupstring; if (! defined $runnumber && $#newargs >= 0) @@ -169,6 +170,7 @@ } my $pAu_bkgpileup = sprintf("_bkg_0_20fm"); my $AuAu_bkgpileup = sprintf("_bkg_0_10fm"); +my $OO_bkgpileup = sprintf("_bkg_0_15fm"); if ($pileup == 1) { $AuAu_pileupstring = sprintf("_50kHz%s",$AuAu_bkgpileup); @@ -194,12 +196,14 @@ else { $pp_pileupstring = sprintf("_%dkHz",$pileup); - $AuAu_pileupstring = sprintf("_%dkHz%s",$AuAu_bkgpileup); + $AuAu_pileupstring = sprintf("_%dkHz%s",$pileup, $AuAu_bkgpileup); + $OO_pileupstring = sprintf("_%dkHz%s",$pileup,$ OO_bkgpileup); } if (defined $nobkgpileup) { $pp_pileupstring = sprintf(""); $AuAu_pileupstring = sprintf(""); + $OO_pileupstring = sprintf(""); } my $embedok = 0; @@ -936,7 +940,7 @@ } else { - $filenamestring = sprintf("sHijing_OO_0_15fm%s",$AuAu_pileupstring); + $filenamestring = sprintf("sHijing_OO_0_15fm%s",$OO_pileupstring); } $notlike{$filenamestring} = ["pythia8" ,"single", "special"]; $pileupstring = $AuAu_pileupstring; From 45f47ca1d3d1268874fcc86e76782200a2880e7b Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Thu, 22 Jan 2026 12:26:17 -0500 Subject: [PATCH 101/393] fix typo --- offline/framework/frog/CreateFileList.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/framework/frog/CreateFileList.pl b/offline/framework/frog/CreateFileList.pl index 7e87a97278..1f71d9897f 100755 --- a/offline/framework/frog/CreateFileList.pl +++ b/offline/framework/frog/CreateFileList.pl @@ -197,7 +197,7 @@ { $pp_pileupstring = sprintf("_%dkHz",$pileup); $AuAu_pileupstring = sprintf("_%dkHz%s",$pileup, $AuAu_bkgpileup); - $OO_pileupstring = sprintf("_%dkHz%s",$pileup,$ OO_bkgpileup); + $OO_pileupstring = sprintf("_%dkHz%s",$pileup,$OO_bkgpileup); } if (defined $nobkgpileup) { From 0efe275ed4d914af0f2d2b14031c29fa75a56cba Mon Sep 17 00:00:00 2001 From: Anthony Denis Frawley Date: Thu, 22 Jan 2026 13:40:37 -0500 Subject: [PATCH 102/393] Several updates: Add clusterlayer to clustertree, calculate cluster phi relative to beamspot, circle uses MVTX barrel center and not zero, changes strobe check to +/- 1, reduce MVTX cluster requirement to 2. --- .../TrackingDiagnostics/TrackResiduals.cc | 1 + .../trackreco/PHActsSiliconSeeding.cc | 75 +++++++++++++++---- .../packages/trackreco/PHActsSiliconSeeding.h | 21 ++++++ .../packages/trackreco/PHSimpleVertexFinder.h | 2 +- 4 files changed, 82 insertions(+), 17 deletions(-) diff --git a/offline/packages/TrackingDiagnostics/TrackResiduals.cc b/offline/packages/TrackingDiagnostics/TrackResiduals.cc index 894dfb4d3c..d029ded711 100644 --- a/offline/packages/TrackingDiagnostics/TrackResiduals.cc +++ b/offline/packages/TrackingDiagnostics/TrackResiduals.cc @@ -1728,6 +1728,7 @@ void TrackResiduals::createBranches() m_clustree->Branch("timebucket", &m_timebucket, "m_timebucket/I"); m_clustree->Branch("segtype", &m_segtype, "m_segtype/I"); m_clustree->Branch("tile", &m_tileid, "m_tileid/I"); + m_clustree->Branch("layer", &m_scluslayer, "m_scluslayer/I"); m_tree = new TTree("residualtree", "A tree with track, cluster, and state info"); m_tree->Branch("run", &m_runnumber, "m_runnumber/I"); diff --git a/offline/packages/trackreco/PHActsSiliconSeeding.cc b/offline/packages/trackreco/PHActsSiliconSeeding.cc index d4741a2ca9..e7a8cde39d 100644 --- a/offline/packages/trackreco/PHActsSiliconSeeding.cc +++ b/offline/packages/trackreco/PHActsSiliconSeeding.cc @@ -818,10 +818,12 @@ std::vector PHActsSiliconSeeding::findMatches( float avgtriplety = 0; for (auto& pos : clusters) { - avgtripletx += std::cos(std::atan2(pos(1), pos(0))); - avgtriplety += std::sin(std::atan2(pos(1), pos(0))); + + avgtripletx += std::cos(getPhiFromBeamSpot(pos(1), pos(0))); + avgtriplety += std::sin(getPhiFromBeamSpot(pos(1), pos(0))); } - float avgtripletphi = std::atan2(avgtriplety, avgtripletx); + float avgtripletphi = getPhiFromBeamSpot(avgtriplety, avgtripletx); + std::vector dummykeys = keys; std::vector dummyclusters = clusters; @@ -889,6 +891,9 @@ std::vector PHActsSiliconSeeding::findMatches( // get an estimate of the phi of the track at this layer // to know which hitsetkeys to look at float layerradius = 0; + float x0 = 0.0; + float y0 = 0.0; + if (layer > 2) { layerradius = m_geomContainerIntt->GetLayerGeom(layer)->get_radius(); @@ -896,12 +901,21 @@ std::vector PHActsSiliconSeeding::findMatches( else { layerradius = m_geomContainerMvtx->GetLayerGeom(layer)->get_radius(); + x0 = m_mvtx_x0; + y0 = m_mvtx_y0; } + float xfitradius_moved = fitpars[1] - x0; + float yfitradius_moved = fitpars[1] - y0; const auto [xplus, yplus, xminus, yminus] = TrackFitUtils::circle_circle_intersection(layerradius, fitpars[0], - fitpars[1], fitpars[2]); - - float approximate_phi1 = atan2(yplus, xplus); - float approximate_phi2 = atan2(yminus, xminus); + xfitradius_moved, yfitradius_moved); + float xp = xplus + x0; + float xm = xminus + x0; + float yp = yplus + y0; + float ym = yminus + y0; + + + float approximate_phi1 = getPhiFromBeamSpot(yp, xp); + float approximate_phi2 = getPhiFromBeamSpot(ym, xm); float approximatephi = approximate_phi1; if (std::fabs(normPhi2Pi(approximate_phi2 - avgtripletphi)) < std::fabs(normPhi2Pi(approximate_phi1 - avgtripletphi))) { @@ -911,7 +925,7 @@ std::vector PHActsSiliconSeeding::findMatches( { auto surf = m_tGeometry->maps().getSiliconSurface(hitsetkey); auto surfcenter = surf->center(m_tGeometry->geometry().geoContext); - float surfphi = atan2(surfcenter.y(), surfcenter.x()); + float surfphi = getPhiFromBeamSpot(surfcenter.y(), surfcenter.x()); float dphi = normPhi2Pi(approximatephi - surfphi); /// Check that the projection is within some reasonable amount of the segment @@ -1141,10 +1155,11 @@ std::vector> PHActsSiliconSeeding::iterateLayers( float avgtriplety = 0; for (const auto& pos : positions) { - avgtripletx += std::cos(std::atan2(pos(1), pos(0))); - avgtriplety += std::sin(std::atan2(pos(1), pos(0))); + avgtripletx += std::cos(getPhiFromBeamSpot(pos(1), pos(0))); + avgtriplety += std::sin(getPhiFromBeamSpot(pos(1), pos(0))); } - float avgtripletphi = std::atan2(avgtriplety, avgtripletx); + + float avgtripletphi = getPhiFromBeamSpot(avgtriplety, avgtripletx); int layer34timebucket = std::numeric_limits::max(); for (const auto& key : keys) @@ -1155,13 +1170,31 @@ std::vector> PHActsSiliconSeeding::iterateLayers( } } + // move the fitted circle center the negative of the MVTX center position + float x0 = 0.0; // cm + float y0 = 0.0; for (int layer = startLayer; layer < endLayer; ++layer) { float layerradius = m_geomContainerIntt->GetLayerGeom(layer)->get_radius(); - const auto [xplus, yplus, xminus, yminus] = TrackFitUtils::circle_circle_intersection(layerradius, fitpars[0], fitpars[1], fitpars[2]); + //const auto [xplus, yplus, xminus, yminus] = TrackFitUtils::circle_circle_intersection(layerradius, fitpars[0], fitpars[1], fitpars[2]); + + if(layer < 3) + { + x0 = m_mvtx_x0; + y0 = m_mvtx_y0; + } - float approximate_phi1 = atan2(yplus, xplus); - float approximate_phi2 = atan2(yminus, xminus); + float xfitradius_moved = fitpars[1] - x0; + float yfitradius_moved = fitpars[2] - y0; + + const auto [xplus, yplus, xminus, yminus] = TrackFitUtils::circle_circle_intersection(layerradius, fitpars[0], xfitradius_moved, yfitradius_moved); + + float xp = xplus + x0; + float xm = xminus + x0; + float yp = yplus + y0; + float ym = yminus + y0; + float approximate_phi1 = getPhiFromBeamSpot(yp, xp); + float approximate_phi2 = getPhiFromBeamSpot(ym, xm); float approximatephi = approximate_phi1; if (std::fabs(normPhi2Pi(approximate_phi2 - avgtripletphi)) < std::fabs(normPhi2Pi(approximate_phi1 - avgtripletphi))) { @@ -1171,7 +1204,7 @@ std::vector> PHActsSiliconSeeding::iterateLayers( { auto surf = m_tGeometry->maps().getSiliconSurface(hitsetkey); auto surfcenter = surf->center(m_tGeometry->geometry().geoContext); - float surfphi = atan2(surfcenter.y(), surfcenter.x()); + float surfphi = getPhiFromBeamSpot(surfcenter.y(), surfcenter.x()); if(Verbosity() > 5) { std::cout << "approximate phis " << approximate_phi1 << " " << approximate_phi2 << " using " << approximatephi @@ -1404,7 +1437,8 @@ std::vector PHActsSiliconSeeding::getSiliconSpacePoints(Acts: if (det == TrkrDefs::TrkrId::mvtxId) { auto strobeId = MvtxDefs::getStrobeId(hitsetkey); - if (strobeId != strobe) + //if (strobeId != strobe) + if (abs(strobeId - strobe) > 1) { continue; } @@ -1713,6 +1747,15 @@ double PHActsSiliconSeeding::normPhi2Pi(const double phi) return returnPhi; } +float PHActsSiliconSeeding::getPhiFromBeamSpot(float clusy, float clusx) +{ + // Calculate the phi value for (clusx, clusy) relative to the beam spot (x,y) position + + float phirel = std::atan2(clusy - m_beamSpoty, clusx - m_beamSpotx); + + return phirel; +} + void PHActsSiliconSeeding::largeGridSpacing(const bool spacing) { if (!spacing) diff --git a/offline/packages/trackreco/PHActsSiliconSeeding.h b/offline/packages/trackreco/PHActsSiliconSeeding.h index ea3fe2c1ad..f37937903b 100644 --- a/offline/packages/trackreco/PHActsSiliconSeeding.h +++ b/offline/packages/trackreco/PHActsSiliconSeeding.h @@ -176,6 +176,16 @@ class PHActsSiliconSeeding : public SubsysReco { m_minSeedPt = pt; } + void set_mvtxCenterXY(const float X, const float Y) + { + m_mvtx_x0 = X; + m_mvtx_y0 = Y; + } + void set_beamSpotXY(const float X, const float Y) + { + m_beamSpotx = X; + m_beamSpoty = Y; + } /// A function to run the seeder with large (true) /// or small (false) grid spacing @@ -243,6 +253,8 @@ class PHActsSiliconSeeding : public SubsysReco short int getCrossingIntt(TrackSeed &si_track); std::vector getInttCrossings(TrackSeed &si_track); + float getPhiFromBeamSpot(float clusy, float clusx); + void createHistograms(); void writeHistograms(); double normPhi2Pi(const double phi); @@ -354,6 +366,15 @@ class PHActsSiliconSeeding : public SubsysReco float m_inttzSearchWin = 2.0; // default to one strip width double m_mvtxrPhiSearchWin = 0.2; float m_mvtxzSearchWin = 0.5; + + // collision point in sPHENIX coordinates, from vertex finder (pp run 3) + float m_beamSpotx = -0.072; // cm + float m_beamSpoty = 0.141; // cm + + // center of MVTX barrel in sPHENIX coordinates - default is for Run 3 pp + float m_mvtx_x0 = 0.6; // cm + float m_mvtx_y0 = -0.1; + /// Whether or not to use truth clusters in hit lookup bool m_useTruthClusters = false; diff --git a/offline/packages/trackreco/PHSimpleVertexFinder.h b/offline/packages/trackreco/PHSimpleVertexFinder.h index 6915693c4b..de5cff940b 100644 --- a/offline/packages/trackreco/PHSimpleVertexFinder.h +++ b/offline/packages/trackreco/PHSimpleVertexFinder.h @@ -91,7 +91,7 @@ class PHSimpleVertexFinder : public SubsysReco double _beamline_y_cut_hi = 0.2; double _qual_cut = 10.0; bool _require_mvtx = true; - unsigned int _nmvtx_required = 3; + unsigned int _nmvtx_required = 2; double _track_pt_cut = 0.0; double _outlier_cut = 0.015; From 3fa48da17176b340a61716e6a0ab2aa69ea4894d Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Thu, 22 Jan 2026 17:18:18 -0500 Subject: [PATCH 103/393] DetermineTowerBackground - Add Psi2 Safety Check - Ensure Psi2 from EventplaneinfoMap is finite and not NaN which can corrupt downstream calculations. --- .../jetbackground/DetermineTowerBackground.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/offline/packages/jetbackground/DetermineTowerBackground.cc b/offline/packages/jetbackground/DetermineTowerBackground.cc index c359b6914c..78a930a8a0 100644 --- a/offline/packages/jetbackground/DetermineTowerBackground.cc +++ b/offline/packages/jetbackground/DetermineTowerBackground.cc @@ -610,6 +610,17 @@ int DetermineTowerBackground::process_event(PHCompositeNode *topNode) _is_flow_failure = true; _Psi2 = 0; } + + // Safety check + if (!std::isfinite(_Psi2)) + { + if (Verbosity() > 0) + { + std::cout << "DetermineTowerBackground::process_event: WARNING Psi2 is non-finite (NaN or Inf), setting Psi2 = 0." << std::endl; + } + _is_flow_failure = true; + _Psi2 = 0; + } if (Verbosity() > 0) { From 80be7af4900f3dd4828a4c2df4697d30395804c2 Mon Sep 17 00:00:00 2001 From: Anthony Denis Frawley Date: Fri, 23 Jan 2026 14:38:39 -0500 Subject: [PATCH 104/393] Bug fix. --- offline/packages/trackreco/PHActsSiliconSeeding.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/offline/packages/trackreco/PHActsSiliconSeeding.cc b/offline/packages/trackreco/PHActsSiliconSeeding.cc index e7a8cde39d..fb1c4b6de9 100644 --- a/offline/packages/trackreco/PHActsSiliconSeeding.cc +++ b/offline/packages/trackreco/PHActsSiliconSeeding.cc @@ -905,7 +905,7 @@ std::vector PHActsSiliconSeeding::findMatches( y0 = m_mvtx_y0; } float xfitradius_moved = fitpars[1] - x0; - float yfitradius_moved = fitpars[1] - y0; + float yfitradius_moved = fitpars[2] - y0; const auto [xplus, yplus, xminus, yminus] = TrackFitUtils::circle_circle_intersection(layerradius, fitpars[0], xfitradius_moved, yfitradius_moved); float xp = xplus + x0; @@ -1176,8 +1176,6 @@ std::vector> PHActsSiliconSeeding::iterateLayers( for (int layer = startLayer; layer < endLayer; ++layer) { float layerradius = m_geomContainerIntt->GetLayerGeom(layer)->get_radius(); - //const auto [xplus, yplus, xminus, yminus] = TrackFitUtils::circle_circle_intersection(layerradius, fitpars[0], fitpars[1], fitpars[2]); - if(layer < 3) { x0 = m_mvtx_x0; From 79a16396e0af741d3aeb53e96dd05c79f4993f3e Mon Sep 17 00:00:00 2001 From: Michael Peters Date: Fri, 23 Jan 2026 18:24:47 -0500 Subject: [PATCH 105/393] Adds local PID parametrization file option to KFParticle_sPHENIX --- .../KFParticle_sPHENIX/KFParticle_Tools.cc | 36 +++++++++++++++---- .../KFParticle_sPHENIX/KFParticle_Tools.h | 2 ++ .../KFParticle_sPHENIX/KFParticle_sPHENIX.h | 4 +++ 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc b/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc index b319af5b56..14958f22c9 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc @@ -1184,7 +1184,16 @@ float KFParticle_Tools::get_dEdx(PHCompositeNode *topNode, const KFParticle &dau void KFParticle_Tools::init_dEdx_fits() { - std::string dedx_fitparams = CDBInterface::instance()->getUrl("TPC_DEDX_FITPARAM"); + std::string dedx_fitparams; + if (m_use_local_PID_file) + { + dedx_fitparams = m_local_PID_filename; + } + else + { + dedx_fitparams = CDBInterface::instance()->getUrl("TPC_DEDX_FITPARAM"); + } + TFile *filefit = TFile::Open(dedx_fitparams.c_str()); if (!filefit->IsOpen()) @@ -1193,12 +1202,25 @@ void KFParticle_Tools::init_dEdx_fits() return; } - filefit->GetObject("f_piband", f_pion_plus); - filefit->GetObject("f_Kband", f_kaon_plus); - filefit->GetObject("f_pband", f_proton_plus); - filefit->GetObject("f_piminus_band", f_pion_minus); - filefit->GetObject("f_Kminus_band", f_kaon_minus); - filefit->GetObject("f_pbar_band", f_proton_minus); + if (m_use_local_PID_file) + { + // new method is independent of charge + filefit->GetObject("pi_band",f_pion_plus); + filefit->GetObject("K_band",f_kaon_plus); + filefit->GetObject("p_band",f_proton_plus); + filefit->GetObject("pi_band",f_pion_minus); + filefit->GetObject("K_band",f_kaon_minus); + filefit->GetObject("p_band",f_proton_minus); + } + else + { + filefit->GetObject("f_piband", f_pion_plus); + filefit->GetObject("f_Kband", f_kaon_plus); + filefit->GetObject("f_pband", f_proton_plus); + filefit->GetObject("f_piminus_band", f_pion_minus); + filefit->GetObject("f_Kminus_band", f_kaon_minus); + filefit->GetObject("f_pbar_band", f_proton_minus); + } pidMap.insert(std::pair(-11, f_pion_plus)); pidMap.insert(std::pair(211, f_pion_plus)); diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.h b/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.h index 4e722a15db..126c331c13 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.h +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.h @@ -149,6 +149,8 @@ class KFParticle_Tools : protected KFParticle_MVA std::vector m_intermediate_vertex_volume; bool m_use_PID{false}; + bool m_use_local_PID_file{false}; + std::string m_local_PID_filename = ""; float m_dEdx_band_width{0.2}; // Fraction of expected dE/dx TF1 *f_pion_plus{nullptr}; diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h index 64fc3f37bb..e537d63dd4 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h @@ -394,6 +394,10 @@ class KFParticle_sPHENIX : public SubsysReco, public KFParticle_nTuple, public K void selectMotherByMassError(bool select = true) { m_select_by_mass_error = select; } void usePID(bool use = true){ m_use_PID = use; } + + void useLocalPIDFile(bool use = false){ m_use_local_PID_file = use; } + + void setLocalPIDFilename(std::string name){ m_local_PID_filename = name; } void setPIDacceptFraction(float frac = 0.2){ m_dEdx_band_width = frac; } From dc058d601aed5d41569bea1123e05ead6b675b80 Mon Sep 17 00:00:00 2001 From: Shuonli Date: Sat, 24 Jan 2026 14:20:23 -0500 Subject: [PATCH 106/393] key the vertex using both position and process id --- .../g4main/PHG4TruthTrackingAction.cc | 35 ++++++++++++------- .../g4main/PHG4TruthTrackingAction.h | 5 ++- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/simulation/g4simulation/g4main/PHG4TruthTrackingAction.cc b/simulation/g4simulation/g4main/PHG4TruthTrackingAction.cc index 4db6ecbd51..da01d9d5e3 100644 --- a/simulation/g4simulation/g4main/PHG4TruthTrackingAction.cc +++ b/simulation/g4simulation/g4main/PHG4TruthTrackingAction.cc @@ -308,20 +308,27 @@ PHG4Particle* PHG4TruthTrackingAction::AddParticle(PHG4TruthInfoContainer& truth PHG4VtxPoint* PHG4TruthTrackingAction::AddVertex(PHG4TruthInfoContainer& truth, const G4Track& track) { G4ThreeVector v = track.GetVertexPosition(); + + // Get G4Track creator process FIRST (needed for vertex map key) + const auto* const g4Process = track.GetCreatorProcess(); + // Convert G4 Process to MC process + const auto process = PHG4ProcessMapPhysics::Instance().GetMCProcess(g4Process); + int vtxindex = (track.GetParentID() == 0 ? truth.maxvtxindex() + 1 : truth.minvtxindex() - 1); - auto [iter, inserted] = m_VertexMap.insert(std::make_pair(v, vtxindex)); + // Use (position, process) as key to distinguish vertices at same location but different processes + // This is important for cases like K0 -> K0_S/K0_L mixing where particles are produced + // at the same position but by different physics processes + auto key = std::make_pair(v, process); + auto [iter, inserted] = m_VertexMap.insert(std::make_pair(key, vtxindex)); // If could not add a unique vertex => return the existing one if (!inserted) { return truth.GetVtxMap().find(iter->second)->second; } - // get G4Track creator process - const auto* const g4Process = track.GetCreatorProcess(); - // convert G4 Process to MC process - const auto process = PHG4ProcessMapPhysics::Instance().GetMCProcess(g4Process); - // otherwise, create and add a new one + + // Create and add a new vertex PHG4VtxPoint* vtxpt = new PHG4VtxPointv2(v[0] / cm, v[1] / cm, v[2] / cm, track.GetGlobalTime() / ns, vtxindex, process); return truth.AddVertex(vtxindex, vtxpt)->second; @@ -346,13 +353,15 @@ bool PHG4TruthTrackingAction::issPHENIXPrimary(PHG4TruthInfoContainer& truth, PH // check the production process // if not decay or primary, then it is not a primary // debug print for pid, track id, parent id, and process - /* - std::cout << "PHG4TruthTrackingAction::issPHENIXPrimary - checking particle with track id " << particle->get_track_id() - << ", pid: " << pdgid - << ", parent id: " << particle->get_parent_id() - << ", process: " << process - << std::endl; - */ + // if (pdgid == 311 || pdgid == 130 || pdgid == 310) + //{ + // std::cout << "PHG4TruthTrackingAction::issPHENIXPrimary - checking particle with track id " << particle->get_track_id() + // << ", pid: " << pdgid + // << ", parent id: " << particle->get_parent_id() + // << ", process: " << process + // << std::endl; + //} + if (!(process == PHG4MCProcess::kPPrimary || process == PHG4MCProcess::kPDecay) && particle->get_parent_id()) // all primary particles seems to have unkown process id { return false; diff --git a/simulation/g4simulation/g4main/PHG4TruthTrackingAction.h b/simulation/g4simulation/g4main/PHG4TruthTrackingAction.h index 5ad050c898..8025d7c9bb 100644 --- a/simulation/g4simulation/g4main/PHG4TruthTrackingAction.h +++ b/simulation/g4simulation/g4main/PHG4TruthTrackingAction.h @@ -4,10 +4,12 @@ #define G4MAIN_PHG4TRUTHTRACKINGACTION_H #include "PHG4TrackingAction.h" +#include "PHG4MCProcessDefs.h" #include #include +#include #include class G4Track; @@ -37,7 +39,8 @@ class PHG4TruthTrackingAction : public PHG4TrackingAction int ResetEvent(PHCompositeNode*) override; private: - std::map m_VertexMap; + // Key is (position, process) to distinguish vertices at the same location but different processes + std::map, int> m_VertexMap; //! pointer to the "owning" event action PHG4TruthEventAction* m_EventAction; From 4a03dcf163dccb67645ec0f28dfd05efc19b6aae Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Sat, 24 Jan 2026 18:45:44 -0500 Subject: [PATCH 107/393] this package uses openmp, clang needs -fopenmp to link this --- calibrations/tpc/dEdx/Makefile.am | 4 ++-- calibrations/tpc/dEdx/configure.ac | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/calibrations/tpc/dEdx/Makefile.am b/calibrations/tpc/dEdx/Makefile.am index e057d9dffe..e91bd83664 100644 --- a/calibrations/tpc/dEdx/Makefile.am +++ b/calibrations/tpc/dEdx/Makefile.am @@ -2,7 +2,7 @@ AUTOMAKE_OPTIONS = foreign AM_CPPFLAGS = \ -I$(includedir) \ - -I$(OFFLINE_MAIN)/include \ + -isystem$(OFFLINE_MAIN)/include \ -isystem$(ROOTSYS)/include AM_LDFLAGS = \ @@ -14,7 +14,7 @@ pkginclude_HEADERS = \ dEdxFitter.h \ GlobaldEdxFitter.h \ bethe_bloch.h - + lib_LTLIBRARIES = \ libdedxfitter.la diff --git a/calibrations/tpc/dEdx/configure.ac b/calibrations/tpc/dEdx/configure.ac index aed59969a8..eae253f50e 100644 --- a/calibrations/tpc/dEdx/configure.ac +++ b/calibrations/tpc/dEdx/configure.ac @@ -6,10 +6,10 @@ AC_PROG_CXX(CC g++) LT_INIT([disable-static]) -dnl no point in suppressing warnings people should -dnl at least see them, so here we go for g++: -Wall +dnl enable more warnings and make them fatal +dnl this package needs openmp which requires -fopenmp for clang if test $ac_cv_prog_gxx = yes; then - CXXFLAGS="$CXXFLAGS -Wall -Werror" + CXXFLAGS="$CXXFLAGS -fopenmp -Wall -Wshadow -Wextra -Werror" fi AC_CONFIG_FILES([Makefile]) From 66a0623afdcaf2e26ded719457ef85d44604426b Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Sun, 25 Jan 2026 20:32:32 -0500 Subject: [PATCH 108/393] trigger jenkins From 8213894265f6042d88ac26f4536868fd97d5db83 Mon Sep 17 00:00:00 2001 From: Shuonli Date: Mon, 26 Jan 2026 01:42:07 -0500 Subject: [PATCH 109/393] empty commit to trigger checks From fdfe0bee75e98d0b6a3e59918774f51456982c13 Mon Sep 17 00:00:00 2001 From: Hugo Pereira Da Costa Date: Mon, 26 Jan 2026 10:56:38 -0500 Subject: [PATCH 110/393] Fixed library dependency (libtrack_reco -> libtrackbase_historic). This allows to remove openmp configuration flag, introduced in https://github.com/sPHENIX-Collaboration/coresoftware/pull/4139 --- calibrations/tpc/dEdx/Makefile.am | 2 +- calibrations/tpc/dEdx/configure.ac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/calibrations/tpc/dEdx/Makefile.am b/calibrations/tpc/dEdx/Makefile.am index e91bd83664..d0eeaa9c5a 100644 --- a/calibrations/tpc/dEdx/Makefile.am +++ b/calibrations/tpc/dEdx/Makefile.am @@ -26,8 +26,8 @@ libdedxfitter_la_LIBADD = \ -lphool \ -ltrack_io \ -lg4detectors \ + -ltrackbase_historic \ -ltrackbase_historic_io \ - -ltrack_reco \ -lglobalvertex \ -lSubsysReco diff --git a/calibrations/tpc/dEdx/configure.ac b/calibrations/tpc/dEdx/configure.ac index eae253f50e..efef9411e9 100644 --- a/calibrations/tpc/dEdx/configure.ac +++ b/calibrations/tpc/dEdx/configure.ac @@ -9,7 +9,7 @@ LT_INIT([disable-static]) dnl enable more warnings and make them fatal dnl this package needs openmp which requires -fopenmp for clang if test $ac_cv_prog_gxx = yes; then - CXXFLAGS="$CXXFLAGS -fopenmp -Wall -Wshadow -Wextra -Werror" + CXXFLAGS="$CXXFLAGS -Wall -Wshadow -Wextra -Werror" fi AC_CONFIG_FILES([Makefile]) From a95f3ef6e0ad56c46905dddf0aa3632b68a51096 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Mon, 26 Jan 2026 14:48:07 -0500 Subject: [PATCH 111/393] modify seed merger to just remove duplicates --- .../packages/trackreco/PHSiliconSeedMerger.cc | 45 ++++++++++++++++--- .../packages/trackreco/PHSiliconSeedMerger.h | 4 +- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/offline/packages/trackreco/PHSiliconSeedMerger.cc b/offline/packages/trackreco/PHSiliconSeedMerger.cc index 16c0848456..943873950d 100644 --- a/offline/packages/trackreco/PHSiliconSeedMerger.cc +++ b/offline/packages/trackreco/PHSiliconSeedMerger.cc @@ -74,7 +74,10 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) { continue; } + if(TrkrDefs::getTrkrId(ckey) == TrkrDefs::TrkrId::mvtxId) + { track1Strobe = MvtxDefs::getStrobeId(ckey); + } mvtx1Keys.insert(ckey); } @@ -110,7 +113,10 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) continue; } mvtx2Keys.insert(ckey); + if(TrkrDefs::getTrkrId(ckey) == TrkrDefs::TrkrId::mvtxId) + { track2Strobe = MvtxDefs::getStrobeId(ckey); + } } std::vector intersection; @@ -120,9 +126,8 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) mvtx2Keys.end(), std::back_inserter(intersection)); - /// If we have two clusters in common in the triplet, it is likely - /// from the same track - if (intersection.size() > m_clusterOverlap && track1Strobe == track2Strobe) + /// If the intersection fully encompasses one of the tracks, it is completely duplicated + if (intersection.size() == mvtx1Keys.size() || intersection.size() == mvtx2Keys.size()) { if (Verbosity() > 2) { @@ -143,9 +148,35 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) } } - for (auto& key : mvtx2Keys) + /// one of the tracks is encompassed in the other. Take the larger one + std::set keysToKeep; + if(mvtx1Keys.size() >= mvtx2Keys.size()) + { + keysToKeep = mvtx1Keys; + if(track1Strobe == track2Strobe && m_mergeSeeds) + { + keysToKeep.insert(mvtx2Keys.begin(), mvtx2Keys.end()); + } + matches.insert(std::make_pair(track1ID, mvtx1Keys)); + seedsToDelete.insert(track2ID); + if(Verbosity() > 2) + { + std::cout << " will delete seed " << track2ID << std::endl; + } + } + else { - mvtx1Keys.insert(key); + keysToKeep = mvtx2Keys; + if (track1Strobe == track2Strobe && m_mergeSeeds) + { + keysToKeep.insert(mvtx1Keys.begin(), mvtx1Keys.end()); + } + matches.insert(std::make_pair(track2ID, mvtx2Keys)); + seedsToDelete.insert(track1ID); + if(Verbosity() > 2) + { + std::cout << " will delete seed " << track1ID << std::endl; + } } if (Verbosity() > 2) @@ -179,7 +210,9 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) { track->insert_cluster_key(key); if (Verbosity() > 2) + { std::cout << "adding " << key << std::endl; + } } } } @@ -197,7 +230,7 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) { for (const auto& seed : *m_siliconTracks) { - if (!seed) continue; + if (!seed){ continue; } seed->identify(); } } diff --git a/offline/packages/trackreco/PHSiliconSeedMerger.h b/offline/packages/trackreco/PHSiliconSeedMerger.h index b8227cd581..802c610e60 100644 --- a/offline/packages/trackreco/PHSiliconSeedMerger.h +++ b/offline/packages/trackreco/PHSiliconSeedMerger.h @@ -28,6 +28,7 @@ class PHSiliconSeedMerger : public SubsysReco void trackMapName(const std::string &name) { m_trackMapName = name; } void clusterOverlap(const unsigned int nclusters) { m_clusterOverlap = nclusters; } void searchIntt() { m_mvtxOnly = false; } + void mergeSeeds() { m_mergeSeeds = true; } private: int getNodes(PHCompositeNode *topNode); @@ -35,7 +36,8 @@ class PHSiliconSeedMerger : public SubsysReco TrackSeedContainer *m_siliconTracks{nullptr}; std::string m_trackMapName{"SiliconTrackSeedContainer"}; unsigned int m_clusterOverlap{1}; - bool m_mvtxOnly{true}; + bool m_mergeSeeds{false}; + bool m_mvtxOnly{false}; }; #endif // PHSILICONSEEDMERGER_H From 3d56c1866aef3f47e04379671e9e9ebbef1445b9 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Mon, 26 Jan 2026 14:50:18 -0500 Subject: [PATCH 112/393] clang tidy and format --- .../packages/trackreco/PHSiliconSeedMerger.cc | 55 +++++++++---------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/offline/packages/trackreco/PHSiliconSeedMerger.cc b/offline/packages/trackreco/PHSiliconSeedMerger.cc index 943873950d..fea5a7f447 100644 --- a/offline/packages/trackreco/PHSiliconSeedMerger.cc +++ b/offline/packages/trackreco/PHSiliconSeedMerger.cc @@ -14,8 +14,6 @@ #include #include -#include - //____________________________________________________________________________.. PHSiliconSeedMerger::PHSiliconSeedMerger(const std::string& name) : SubsysReco(name) @@ -23,12 +21,10 @@ PHSiliconSeedMerger::PHSiliconSeedMerger(const std::string& name) } //____________________________________________________________________________.. -PHSiliconSeedMerger::~PHSiliconSeedMerger() -{ -} +PHSiliconSeedMerger::~PHSiliconSeedMerger() = default; //____________________________________________________________________________.. -int PHSiliconSeedMerger::Init(PHCompositeNode*) +int PHSiliconSeedMerger::Init(PHCompositeNode* /*unused*/) { return Fun4AllReturnCodes::EVENT_OK; } @@ -41,7 +37,7 @@ int PHSiliconSeedMerger::InitRun(PHCompositeNode* topNode) } //____________________________________________________________________________.. -int PHSiliconSeedMerger::process_event(PHCompositeNode*) +int PHSiliconSeedMerger::process_event(PHCompositeNode* /*unused*/) { std::multimap> matches; std::set seedsToDelete; @@ -57,7 +53,7 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) { TrackSeed* track1 = m_siliconTracks->get(track1ID); - if (seedsToDelete.find(track1ID) != seedsToDelete.end()) + if (seedsToDelete.contains(track1ID)) { continue; } @@ -74,9 +70,9 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) { continue; } - if(TrkrDefs::getTrkrId(ckey) == TrkrDefs::TrkrId::mvtxId) + if (TrkrDefs::getTrkrId(ckey) == TrkrDefs::TrkrId::mvtxId) { - track1Strobe = MvtxDefs::getStrobeId(ckey); + track1Strobe = MvtxDefs::getStrobeId(ckey); } mvtx1Keys.insert(ckey); } @@ -113,9 +109,9 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) continue; } mvtx2Keys.insert(ckey); - if(TrkrDefs::getTrkrId(ckey) == TrkrDefs::TrkrId::mvtxId) + if (TrkrDefs::getTrkrId(ckey) == TrkrDefs::TrkrId::mvtxId) { - track2Strobe = MvtxDefs::getStrobeId(ckey); + track2Strobe = MvtxDefs::getStrobeId(ckey); } } @@ -132,12 +128,12 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) if (Verbosity() > 2) { std::cout << "Track " << track1ID << " keys " << std::endl; - for (auto& key : mvtx1Keys) + for (const auto& key : mvtx1Keys) { std::cout << " ckey: " << key << std::endl; } std::cout << "Track " << track2ID << " keys " << std::endl; - for (auto& key : mvtx2Keys) + for (const auto& key : mvtx2Keys) { std::cout << " ckey: " << key << std::endl; } @@ -150,16 +146,16 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) /// one of the tracks is encompassed in the other. Take the larger one std::set keysToKeep; - if(mvtx1Keys.size() >= mvtx2Keys.size()) + if (mvtx1Keys.size() >= mvtx2Keys.size()) { keysToKeep = mvtx1Keys; - if(track1Strobe == track2Strobe && m_mergeSeeds) - { - keysToKeep.insert(mvtx2Keys.begin(), mvtx2Keys.end()); - } + if (track1Strobe == track2Strobe && m_mergeSeeds) + { + keysToKeep.insert(mvtx2Keys.begin(), mvtx2Keys.end()); + } matches.insert(std::make_pair(track1ID, mvtx1Keys)); seedsToDelete.insert(track2ID); - if(Verbosity() > 2) + if (Verbosity() > 2) { std::cout << " will delete seed " << track2ID << std::endl; } @@ -173,7 +169,7 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) } matches.insert(std::make_pair(track2ID, mvtx2Keys)); seedsToDelete.insert(track1ID); - if(Verbosity() > 2) + if (Verbosity() > 2) { std::cout << " will delete seed " << track1ID << std::endl; } @@ -182,7 +178,7 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) if (Verbosity() > 2) { std::cout << "Match IDed" << std::endl; - for (auto& key : mvtx1Keys) + for (const auto& key : mvtx1Keys) { std::cout << " total track keys " << key << std::endl; } @@ -197,14 +193,14 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) for (const auto& [trackKey, mvtxKeys] : matches) { - auto track = m_siliconTracks->get(trackKey); + auto* track = m_siliconTracks->get(trackKey); if (Verbosity() > 2) { std::cout << "original track: " << std::endl; track->identify(); } - for (auto& key : mvtxKeys) + for (const auto& key : mvtxKeys) { if (track->find_cluster_key(key) == track->end_cluster_keys()) { @@ -230,7 +226,10 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) { for (const auto& seed : *m_siliconTracks) { - if (!seed){ continue; } + if (!seed) + { + continue; + } seed->identify(); } } @@ -239,20 +238,20 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) } //____________________________________________________________________________.. -int PHSiliconSeedMerger::ResetEvent(PHCompositeNode*) +int PHSiliconSeedMerger::ResetEvent(PHCompositeNode* /*unused*/) { return Fun4AllReturnCodes::EVENT_OK; } //____________________________________________________________________________.. -int PHSiliconSeedMerger::End(PHCompositeNode*) +int PHSiliconSeedMerger::End(PHCompositeNode* /*unused*/) { return Fun4AllReturnCodes::EVENT_OK; } int PHSiliconSeedMerger::getNodes(PHCompositeNode* topNode) { - m_siliconTracks = findNode::getClass(topNode, m_trackMapName.c_str()); + m_siliconTracks = findNode::getClass(topNode, m_trackMapName); if (!m_siliconTracks) { std::cout << PHWHERE << "No silicon track container, can't merge seeds" From 7ef17b304a8cc118b706b3e9e58388bb61964e4d Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Tue, 27 Jan 2026 03:23:10 +0000 Subject: [PATCH 113/393] =?UTF-8?q?=F0=9F=93=9D=20Add=20docstrings=20to=20?= =?UTF-8?q?`silicon=5Fduplicate=5Fremoval`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Docstrings generation was requested by @blackcathj. * https://github.com/sPHENIX-Collaboration/coresoftware/pull/4141#issuecomment-3801456929 The following files were modified: * `offline/packages/trackreco/PHSiliconSeedMerger.cc` * `offline/packages/trackreco/PHSiliconSeedMerger.h` --- .../packages/trackreco/PHSiliconSeedMerger.cc | 154 ++++++++++++++---- .../packages/trackreco/PHSiliconSeedMerger.h | 46 +++++- 2 files changed, 161 insertions(+), 39 deletions(-) diff --git a/offline/packages/trackreco/PHSiliconSeedMerger.cc b/offline/packages/trackreco/PHSiliconSeedMerger.cc index 16c0848456..4d5dfcf676 100644 --- a/offline/packages/trackreco/PHSiliconSeedMerger.cc +++ b/offline/packages/trackreco/PHSiliconSeedMerger.cc @@ -1,4 +1,3 @@ - #include "PHSiliconSeedMerger.h" #include @@ -14,34 +13,67 @@ #include #include -#include - -//____________________________________________________________________________.. +/** + * @brief Construct a PHSiliconSeedMerger with the given subsystem name. + * + * Initializes the PHSiliconSeedMerger and forwards the provided subsystem + * name to the base SubsysReco constructor. + * + * @param name Subsystem name used to register this module in the node tree. + */ PHSiliconSeedMerger::PHSiliconSeedMerger(const std::string& name) : SubsysReco(name) { } -//____________________________________________________________________________.. -PHSiliconSeedMerger::~PHSiliconSeedMerger() -{ -} +/** + * @brief Default destructor for PHSiliconSeedMerger. + * + * Performs default cleanup of the merger object and its owned resources. + */ +PHSiliconSeedMerger::~PHSiliconSeedMerger() = default; -//____________________________________________________________________________.. -int PHSiliconSeedMerger::Init(PHCompositeNode*) +/** + * @brief Perform module initialization (no operation required). + * + * This implementation does not perform any setup and always succeeds. + * + * @return int `EVENT_OK` indicating initialization succeeded. + */ +int PHSiliconSeedMerger::Init(PHCompositeNode* /*unused*/) { return Fun4AllReturnCodes::EVENT_OK; } -//____________________________________________________________________________.. +/** + * @brief Initializes run-time resources by retrieving required nodes. + * + * Calls getNodes(topNode) to locate and cache containers needed for processing this run. + * + * @param topNode Root of the node tree from which required nodes are retrieved. + * @return int `EVENT_OK` on success, `ABORTEVENT` or another non-zero code on failure. + */ int PHSiliconSeedMerger::InitRun(PHCompositeNode* topNode) { int ret = getNodes(topNode); return ret; } -//____________________________________________________________________________.. -int PHSiliconSeedMerger::process_event(PHCompositeNode*) +/** + * @brief Merge overlapping silicon seed tracks by consolidating MVTX cluster keys. + * + * Detects seeds whose MVTX cluster key sets fully overlap (one set equals the + * intersection) and treats one seed as a duplicate of the other. The merger + * preserves the seed with the larger MVTX key set; if both seeds share the + * same MVTX strobe and seed merging is enabled, the smaller seed's MVTX keys + * are merged into the preserved seed. After consolidation, duplicate seeds are + * erased from the silicon track container and preserved seeds are updated to + * include any newly merged MVTX cluster keys. + * + * @return Fun4AllReturnCodes::EVENT_OK on successful processing. + * + */ +int PHSiliconSeedMerger::process_event(PHCompositeNode* /*unused*/) { std::multimap> matches; std::set seedsToDelete; @@ -57,7 +89,7 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) { TrackSeed* track1 = m_siliconTracks->get(track1ID); - if (seedsToDelete.find(track1ID) != seedsToDelete.end()) + if (seedsToDelete.contains(track1ID)) { continue; } @@ -74,7 +106,10 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) { continue; } - track1Strobe = MvtxDefs::getStrobeId(ckey); + if (TrkrDefs::getTrkrId(ckey) == TrkrDefs::TrkrId::mvtxId) + { + track1Strobe = MvtxDefs::getStrobeId(ckey); + } mvtx1Keys.insert(ckey); } @@ -110,7 +145,10 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) continue; } mvtx2Keys.insert(ckey); - track2Strobe = MvtxDefs::getStrobeId(ckey); + if (TrkrDefs::getTrkrId(ckey) == TrkrDefs::TrkrId::mvtxId) + { + track2Strobe = MvtxDefs::getStrobeId(ckey); + } } std::vector intersection; @@ -120,19 +158,18 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) mvtx2Keys.end(), std::back_inserter(intersection)); - /// If we have two clusters in common in the triplet, it is likely - /// from the same track - if (intersection.size() > m_clusterOverlap && track1Strobe == track2Strobe) + /// If the intersection fully encompasses one of the tracks, it is completely duplicated + if (intersection.size() == mvtx1Keys.size() || intersection.size() == mvtx2Keys.size()) { if (Verbosity() > 2) { std::cout << "Track " << track1ID << " keys " << std::endl; - for (auto& key : mvtx1Keys) + for (const auto& key : mvtx1Keys) { std::cout << " ckey: " << key << std::endl; } std::cout << "Track " << track2ID << " keys " << std::endl; - for (auto& key : mvtx2Keys) + for (const auto& key : mvtx2Keys) { std::cout << " ckey: " << key << std::endl; } @@ -143,15 +180,41 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) } } - for (auto& key : mvtx2Keys) + /// one of the tracks is encompassed in the other. Take the larger one + std::set keysToKeep; + if (mvtx1Keys.size() >= mvtx2Keys.size()) { - mvtx1Keys.insert(key); + keysToKeep = mvtx1Keys; + if (track1Strobe == track2Strobe && m_mergeSeeds) + { + keysToKeep.insert(mvtx2Keys.begin(), mvtx2Keys.end()); + } + matches.insert(std::make_pair(track1ID, mvtx1Keys)); + seedsToDelete.insert(track2ID); + if (Verbosity() > 2) + { + std::cout << " will delete seed " << track2ID << std::endl; + } + } + else + { + keysToKeep = mvtx2Keys; + if (track1Strobe == track2Strobe && m_mergeSeeds) + { + keysToKeep.insert(mvtx1Keys.begin(), mvtx1Keys.end()); + } + matches.insert(std::make_pair(track2ID, mvtx2Keys)); + seedsToDelete.insert(track1ID); + if (Verbosity() > 2) + { + std::cout << " will delete seed " << track1ID << std::endl; + } } if (Verbosity() > 2) { std::cout << "Match IDed" << std::endl; - for (auto& key : mvtx1Keys) + for (const auto& key : mvtx1Keys) { std::cout << " total track keys " << key << std::endl; } @@ -166,20 +229,22 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) for (const auto& [trackKey, mvtxKeys] : matches) { - auto track = m_siliconTracks->get(trackKey); + auto* track = m_siliconTracks->get(trackKey); if (Verbosity() > 2) { std::cout << "original track: " << std::endl; track->identify(); } - for (auto& key : mvtxKeys) + for (const auto& key : mvtxKeys) { if (track->find_cluster_key(key) == track->end_cluster_keys()) { track->insert_cluster_key(key); if (Verbosity() > 2) + { std::cout << "adding " << key << std::endl; + } } } } @@ -197,7 +262,10 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) { for (const auto& seed : *m_siliconTracks) { - if (!seed) continue; + if (!seed) + { + continue; + } seed->identify(); } } @@ -205,21 +273,41 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode*) return Fun4AllReturnCodes::EVENT_OK; } -//____________________________________________________________________________.. -int PHSiliconSeedMerger::ResetEvent(PHCompositeNode*) +/** + * @brief Reset per-event state for the merger. + * + * This implementation performs no per-event cleanup and always reports success. + * + * @return Integer status code: `Fun4AllReturnCodes::EVENT_OK`. + */ +int PHSiliconSeedMerger::ResetEvent(PHCompositeNode* /*unused*/) { return Fun4AllReturnCodes::EVENT_OK; } -//____________________________________________________________________________.. -int PHSiliconSeedMerger::End(PHCompositeNode*) +/** + * @brief Perform end-of-run shutdown for the silicon seed merger. + * + * @return int EVENT_OK on successful completion. + */ +int PHSiliconSeedMerger::End(PHCompositeNode* /*unused*/) { return Fun4AllReturnCodes::EVENT_OK; } +/** + * @brief Retrieve required nodes from the top-level node tree and validate availability. + * + * Locates the silicon TrackSeedContainer using m_trackMapName and stores it in + * m_siliconTracks. If the container is not found, the function logs an error + * message and signals an abort for the current event. + * + * @param topNode Root node used to search for the TrackSeedContainer. + * @return int Fun4AllReturnCodes::EVENT_OK on success, Fun4AllReturnCodes::ABORTEVENT if the silicon TrackSeedContainer is not present. + */ int PHSiliconSeedMerger::getNodes(PHCompositeNode* topNode) { - m_siliconTracks = findNode::getClass(topNode, m_trackMapName.c_str()); + m_siliconTracks = findNode::getClass(topNode, m_trackMapName); if (!m_siliconTracks) { std::cout << PHWHERE << "No silicon track container, can't merge seeds" @@ -228,4 +316,4 @@ int PHSiliconSeedMerger::getNodes(PHCompositeNode* topNode) } return Fun4AllReturnCodes::EVENT_OK; -} +} \ No newline at end of file diff --git a/offline/packages/trackreco/PHSiliconSeedMerger.h b/offline/packages/trackreco/PHSiliconSeedMerger.h index b8227cd581..afef3571a5 100644 --- a/offline/packages/trackreco/PHSiliconSeedMerger.h +++ b/offline/packages/trackreco/PHSiliconSeedMerger.h @@ -25,17 +25,51 @@ class PHSiliconSeedMerger : public SubsysReco int ResetEvent(PHCompositeNode *topNode) override; int End(PHCompositeNode *topNode) override; - void trackMapName(const std::string &name) { m_trackMapName = name; } - void clusterOverlap(const unsigned int nclusters) { m_clusterOverlap = nclusters; } - void searchIntt() { m_mvtxOnly = false; } + /** + * Set the name of the track seed container to use when retrieving silicon tracks. + * + * @param name Name of the TrackSeedContainer node (defaults to "SiliconTrackSeedContainer"). + */ +void trackMapName(const std::string &name) { m_trackMapName = name; } + /** + * Set the maximum number of overlapping clusters considered during seed merging. + * @param nclusters Maximum number of clusters that may overlap (overlap threshold). + */ +void clusterOverlap(const unsigned int nclusters) { m_clusterOverlap = nclusters; } + /** + * @brief Allow seed searches to include the INTT detector. + * + * Configure the merger to include INTT seeds in subsequent processing by disabling the MVTX-only restriction. + */ +void searchIntt() { m_mvtxOnly = false; } + /** + * Enable merging of silicon seed tracks during event processing. + * + * When enabled, the module will merge overlapping silicon seed tracks where applicable. + */ +void mergeSeeds() { m_mergeSeeds = true; } private: int getNodes(PHCompositeNode *topNode); TrackSeedContainer *m_siliconTracks{nullptr}; std::string m_trackMapName{"SiliconTrackSeedContainer"}; - unsigned int m_clusterOverlap{1}; - bool m_mvtxOnly{true}; + /** + * Minimum number of clusters that must be shared between two silicon track seeds + * for them to be considered overlapping. + * + * Defaults to 1. + */ +unsigned int m_clusterOverlap{1}; + bool m_mergeSeeds{false}; + /** + * Restrict seed processing to the MVTX detector only. + * + * When set to `true`, operations that iterate or merge silicon seed tracks + * will be limited to seeds originating from the MVTX vertex detector. + * When `false`, seeds from other silicon detectors are included. + */ +bool m_mvtxOnly{false}; }; -#endif // PHSILICONSEEDMERGER_H +#endif // PHSILICONSEEDMERGER_H \ No newline at end of file From e53dbd487446eb28b5ca682cae7cff2ac762cd2b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 27 Jan 2026 03:23:27 +0000 Subject: [PATCH 114/393] Fix missing final newline in docstring PR --- offline/packages/trackreco/PHSiliconSeedMerger.cc | 2 +- offline/packages/trackreco/PHSiliconSeedMerger.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/offline/packages/trackreco/PHSiliconSeedMerger.cc b/offline/packages/trackreco/PHSiliconSeedMerger.cc index 4d5dfcf676..8edb5816c3 100644 --- a/offline/packages/trackreco/PHSiliconSeedMerger.cc +++ b/offline/packages/trackreco/PHSiliconSeedMerger.cc @@ -316,4 +316,4 @@ int PHSiliconSeedMerger::getNodes(PHCompositeNode* topNode) } return Fun4AllReturnCodes::EVENT_OK; -} \ No newline at end of file +} diff --git a/offline/packages/trackreco/PHSiliconSeedMerger.h b/offline/packages/trackreco/PHSiliconSeedMerger.h index afef3571a5..7ab50a44df 100644 --- a/offline/packages/trackreco/PHSiliconSeedMerger.h +++ b/offline/packages/trackreco/PHSiliconSeedMerger.h @@ -72,4 +72,4 @@ unsigned int m_clusterOverlap{1}; bool m_mvtxOnly{false}; }; -#endif // PHSILICONSEEDMERGER_H \ No newline at end of file +#endif // PHSILICONSEEDMERGER_H From 9ced97a03a5fb410bab67df8bc8f4a59009ca164 Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Mon, 26 Jan 2026 22:47:58 -0500 Subject: [PATCH 115/393] Combined North-South Q-vector Calibration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactor the QVecCalib and QVecCDB modules to support a third "Combined NS" calibration slot. This update ensures that the combined North-South event plane is derived from individually recentered sub-detectors and then flattened as a single entity, significantly improving event plane resolution and flatness. Changes to QVecCalib: - Calibration Logic: Implemented a "Best of Both Worlds" approach where North and South vectors are recentered individually to preserve natural multiplicity weighting before being summed to form the NS vector. - Flattening Procedure: Added logic to calculate a unique flattening matrix for the combined NS vector, ensuring its final distribution is circular (⟨Qx2​⟩/⟨Qy2​⟩=1 and ⟨Qx​Qy​⟩=0). - Memory Optimization: Simplified the CorrectionData struct by removing intermediate second-moment storage (avg_Q_xx, avg_Q_yy, avg_Q_xy), utilizing local variables during matrix computation instead. - Histogram Refactoring: Replaced high-memory TH3 histograms with a suite of TH2 histograms (Psi_S, Psi_N, Psi_NS) to track event plane angles against centrality. Changes to QVecCDB: - Database Schema: Expanded the m_correction_data array and the SEPD_EventPlaneCalib payload to include the 3rd calibration slot for the NS detector. - IO Updates: Updated load_correction_data and write_cdb_EventPlane to process and commit the NS-specific 2nd moments (xx, yy, xy) to the Calibration Database (CDB). Technical Notes: - Satisfies the requirement that the NS combination treats the sum of recentered sub-detectors as a distinct third detector for whitening. - Prevents the resolution degradation caused by equal-weighting individually flattened sub-detectors. --- .../sepd/sepd_eventplanecalib/QVecCDB.cc | 17 ++ .../sepd/sepd_eventplanecalib/QVecCDB.h | 4 +- .../sepd/sepd_eventplanecalib/QVecCalib.cc | 216 ++++++++++++------ .../sepd/sepd_eventplanecalib/QVecCalib.h | 40 ++-- .../sepd/sepd_eventplanecalib/QVecDefs.h | 3 +- 5 files changed, 190 insertions(+), 90 deletions(-) diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecCDB.cc b/calibrations/sepd/sepd_eventplanecalib/QVecCDB.cc index 96e18d1ffe..b18bf4c345 100644 --- a/calibrations/sepd/sepd_eventplanecalib/QVecCDB.cc +++ b/calibrations/sepd/sepd_eventplanecalib/QVecCDB.cc @@ -68,6 +68,11 @@ void QVecCDB::load_correction_data(size_t h_idx) auto pN_yy = load_and_clone(QVecShared::get_hist_name("N", "yy", n)); auto pN_xy = load_and_clone(QVecShared::get_hist_name("N", "xy", n)); + // Load NS flattening terms + auto pNS_xx = load_and_clone(QVecShared::get_hist_name("NS", "xx", n)); + auto pNS_yy = load_and_clone(QVecShared::get_hist_name("NS", "yy", n)); + auto pNS_xy = load_and_clone(QVecShared::get_hist_name("NS", "xy", n)); + for (size_t cent_bin = 0; cent_bin < m_cent_bins; ++cent_bin) { int bin = static_cast(cent_bin) + 1; // ROOT bins start at 1 @@ -85,6 +90,12 @@ void QVecCDB::load_correction_data(size_t h_idx) dataN.avg_Q_xx = pN_xx->GetBinContent(bin); dataN.avg_Q_yy = pN_yy->GetBinContent(bin); dataN.avg_Q_xy = pN_xy->GetBinContent(bin); + + // North South + auto& dataNS = getData(h_idx, cent_bin, QVecShared::Subdetector::NS); + dataNS.avg_Q_xx = pNS_xx->GetBinContent(bin); + dataNS.avg_Q_yy = pNS_yy->GetBinContent(bin); + dataNS.avg_Q_xy = pNS_xy->GetBinContent(bin); } } @@ -168,6 +179,7 @@ void QVecCDB::write_cdb_EventPlane(const std::string &output_dir) // Access data references to clean up the calls const auto& S = getData(h_idx, cent_bin, QVecShared::Subdetector::S); const auto& N = getData(h_idx, cent_bin, QVecShared::Subdetector::N); + const auto& NS = getData(h_idx, cent_bin, QVecShared::Subdetector::NS); // South cdbttree->SetDoubleValue(key, field("S", "x"), S.avg_Q.x); @@ -182,6 +194,11 @@ void QVecCDB::write_cdb_EventPlane(const std::string &output_dir) cdbttree->SetDoubleValue(key, field("N", "xx"), N.avg_Q_xx); cdbttree->SetDoubleValue(key, field("N", "yy"), N.avg_Q_yy); cdbttree->SetDoubleValue(key, field("N", "xy"), N.avg_Q_xy); + + // North South + cdbttree->SetDoubleValue(key, field("NS", "xx"), NS.avg_Q_xx); + cdbttree->SetDoubleValue(key, field("NS", "yy"), NS.avg_Q_yy); + cdbttree->SetDoubleValue(key, field("NS", "xy"), NS.avg_Q_xy); } } diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecCDB.h b/calibrations/sepd/sepd_eventplanecalib/QVecCDB.h index 1840b2b52b..54b9b37901 100644 --- a/calibrations/sepd/sepd_eventplanecalib/QVecCDB.h +++ b/calibrations/sepd/sepd_eventplanecalib/QVecCDB.h @@ -56,8 +56,8 @@ class QVecCDB // Holds all correction data // key: [Harmonic][Cent][Subdetector] // Harmonics {2,3,4} -> 3 elements - // Subdetectors {S,N} -> 2 elements - std::array, m_cent_bins>, m_harmonics.size()> m_correction_data; + // Subdetectors {S,N,NS} -> 3 elements + std::array, m_cent_bins>, m_harmonics.size()> m_correction_data; // --- Member Variables --- std::string m_input_file; diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc index afa9eb8ed8..2148124032 100644 --- a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc +++ b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc @@ -305,10 +305,6 @@ void QVecCalib::process_bad_channels(TFile* file) void QVecCalib::init_hists() { - unsigned int bins_Q = 100; - double Q_low = -1; - double Q_high = 1; - unsigned int bins_psi = 126; double psi_low = -std::numbers::pi; double psi_high = std::numbers::pi; @@ -328,25 +324,17 @@ void QVecCalib::init_hists() // n = 2, 3, 4, etc. for (int n : m_harmonics) { - std::string psi_hist_name = std::format("h3_sEPD_Psi_{}", n); - std::string psi_hist_title = std::format("sEPD #Psi (Order {0}): |z| < 10 cm and MB; {0}#Psi^{{S}}_{{{0}}}; {0}#Psi^{{N}}_{{{0}}}; Centrality [%]", n); - - if (m_pass == Pass::ComputeRecentering) - { - psi_hist_name = std::format("h3_sEPD_Psi_{}", n); - } - - if (m_pass == Pass::ApplyRecentering) - { - psi_hist_name = std::format("h3_sEPD_Psi_{}_corr", n); - } + std::string name_S = std::format("h2_sEPD_Psi_S_{}{}", n, pass_suffix); + std::string name_N = std::format("h2_sEPD_Psi_N_{}{}", n, pass_suffix); + std::string name_NS = std::format("h2_sEPD_Psi_NS_{}{}", n, pass_suffix); - if (m_pass == Pass::ApplyFlattening) - { - psi_hist_name = std::format("h3_sEPD_Psi_{}_corr2", n); - } + std::string title_S = std::format("sEPD South #Psi (Order {0}); Centrality [%]; {0}#Psi^{{S}}_{{{0}}}", n); + std::string title_N = std::format("sEPD North #Psi (Order {0}); Centrality [%]; {0}#Psi^{{N}}_{{{0}}}", n); + std::string title_NS = std::format("sEPD North South #Psi (Order {0}); Centrality [%]; {0}#Psi^{{NS}}_{{{0}}}", n); - m_hists3D[psi_hist_name] = std::make_unique(psi_hist_name.c_str(), psi_hist_title.c_str(), bins_psi, psi_low, psi_high, bins_psi, psi_low, psi_high, m_cent_bins, m_cent_low, m_cent_high); + m_hists2D[name_S] = std::make_unique(name_S.c_str(), title_S.c_str(), m_cent_bins, m_cent_low, m_cent_high, bins_psi, psi_low, psi_high); + m_hists2D[name_N] = std::make_unique(name_N.c_str(), title_N.c_str(), m_cent_bins, m_cent_low, m_cent_high, bins_psi, psi_low, psi_high); + m_hists2D[name_NS] = std::make_unique(name_NS.c_str(), title_NS.c_str(), m_cent_bins, m_cent_low, m_cent_high, bins_psi, psi_low, psi_high); // South, North for (auto det : m_subdetectors) @@ -354,14 +342,6 @@ void QVecCalib::init_hists() std::string det_str = (det == QVecShared::Subdetector::S) ? "S" : "N"; std::string det_name = (det == QVecShared::Subdetector::S) ? "South" : "North"; - if (m_pass == Pass::ComputeRecentering) - { - std::string q_hist_name = std::format("h3_sEPD_Q_{}_{}", det_str, n); - std::string q_hist_title = std::format("sEPD {} Q (Order {}): |z| < 10 cm and MB; Q_{{x}}; Q_{{y}}; Centrality [%]", det_name, n); - m_hists3D[q_hist_name] = std::make_unique(q_hist_name.c_str(), q_hist_title.c_str(), - bins_Q, Q_low, Q_high, bins_Q, Q_low, Q_high, m_cent_bins, m_cent_low, m_cent_high); - } - std::string q_avg_sq_cross_name; std::string q_avg_sq_cross_title = std::format("sEPD {0}; Centrality [%]; ", det_name, n); @@ -418,6 +398,31 @@ void QVecCalib::init_hists() } } } + + // Init for Combined NS Histograms + if (m_pass == Pass::ApplyRecentering || m_pass == Pass::ApplyFlattening) + { + std::string det_str = "NS"; + + // Initialize 2nd Moment Profiles for NS (needed to compute flattening) + for (const auto* comp : {"xx", "yy", "xy"}) + { + std::string name = QVecShared::get_hist_name(det_str, comp, n); + std::string title = std::format("sEPD NS; Centrality [%]; ", n, comp); + m_profiles[name] = std::make_unique(name.c_str(), title.c_str(), m_cent_bins, m_cent_low, m_cent_high); + } + + // Initialize Validation Profiles (Flattened NS) + if (m_pass == Pass::ApplyFlattening) + { + for (const auto* comp : {"xx", "yy", "xy"}) + { + std::string name = QVecShared::get_hist_name(det_str, comp, n, "_corr"); + std::string title = std::format("sEPD NS Corrected; Centrality [%]; ", n, comp); + m_profiles[name] = std::make_unique(name.c_str(), title.c_str(), m_cent_bins, m_cent_low, m_cent_high); + } + } + } } } @@ -425,15 +430,16 @@ void QVecCalib::process_averages(double cent, QVecShared::QVec q_S, QVecShared:: { double psi_S = std::atan2(q_S.y, q_S.x); double psi_N = std::atan2(q_N.y, q_N.x); + double psi_NS = std::atan2(q_S.y + q_N.y, q_S.x + q_N.x); h.S_x_avg->Fill(cent, q_S.x); h.S_y_avg->Fill(cent, q_S.y); h.N_x_avg->Fill(cent, q_N.x); h.N_y_avg->Fill(cent, q_N.y); - h.Q_S->Fill(q_S.x, q_S.y, cent); - h.Q_N->Fill(q_N.x, q_N.y, cent); - h.Psi->Fill(psi_S, psi_N, cent); + h.Psi_S->Fill(cent, psi_S); + h.Psi_N->Fill(cent, psi_N); + h.Psi_NS->Fill(cent, psi_NS); } void QVecCalib::process_recentering(double cent, size_t h_idx, QVecShared::QVec q_S, QVecShared::QVec q_N, const RecenterHists& h) @@ -448,8 +454,13 @@ void QVecCalib::process_recentering(double cent, size_t h_idx, QVecShared::QVec QVecShared::QVec q_S_corr = {q_S.x - Q_S_x_avg, q_S.y - Q_S_y_avg}; QVecShared::QVec q_N_corr = {q_N.x - Q_N_x_avg, q_N.y - Q_N_y_avg}; + // Construct Combined Recentered Vector + // We use the sum of the individually recentered vectors + QVecShared::QVec q_NS_corr = {q_S_corr.x + q_N_corr.x, q_S_corr.y + q_N_corr.y}; + double psi_S_corr = std::atan2(q_S_corr.y, q_S_corr.x); double psi_N_corr = std::atan2(q_N_corr.y, q_N_corr.x); + double psi_NS_corr = std::atan2(q_NS_corr.y, q_NS_corr.x); h.S_x_corr_avg->Fill(cent, q_S_corr.x); h.S_y_corr_avg->Fill(cent, q_S_corr.y); @@ -463,7 +474,13 @@ void QVecCalib::process_recentering(double cent, size_t h_idx, QVecShared::QVec h.N_yy_avg->Fill(cent, q_N_corr.y * q_N_corr.y); h.N_xy_avg->Fill(cent, q_N_corr.x * q_N_corr.y); - h.Psi_corr->Fill(psi_S_corr, psi_N_corr, cent); + h.NS_xx_avg->Fill(cent, q_NS_corr.x * q_NS_corr.x); + h.NS_yy_avg->Fill(cent, q_NS_corr.y * q_NS_corr.y); + h.NS_xy_avg->Fill(cent, q_NS_corr.x * q_NS_corr.y); + + h.Psi_S_corr->Fill(cent, psi_S_corr); + h.Psi_N_corr->Fill(cent, psi_N_corr); + h.Psi_NS_corr->Fill(cent, psi_NS_corr); } void QVecCalib::process_flattening(double cent, size_t h_idx, QVecShared::QVec q_S, QVecShared::QVec q_N, const FlatteningHists& h) @@ -478,19 +495,28 @@ void QVecCalib::process_flattening(double cent, size_t h_idx, QVecShared::QVec q QVecShared::QVec q_S_corr = {q_S.x - Q_S_x_avg, q_S.y - Q_S_y_avg}; QVecShared::QVec q_N_corr = {q_N.x - Q_N_x_avg, q_N.y - Q_N_y_avg}; + // Construct Combined Recentered Vector + QVecShared::QVec q_NS_corr = {q_S_corr.x + q_N_corr.x, q_S_corr.y + q_N_corr.y}; + const auto& X_S = m_correction_data[cent_bin][h_idx][0].X_matrix; const auto& X_N = m_correction_data[cent_bin][h_idx][1].X_matrix; + const auto& X_NS = m_correction_data[cent_bin][h_idx][IDX_NS].X_matrix; double Q_S_x_corr2 = X_S[0][0] * q_S_corr.x + X_S[0][1] * q_S_corr.y; double Q_S_y_corr2 = X_S[1][0] * q_S_corr.x + X_S[1][1] * q_S_corr.y; double Q_N_x_corr2 = X_N[0][0] * q_N_corr.x + X_N[0][1] * q_N_corr.y; double Q_N_y_corr2 = X_N[1][0] * q_N_corr.x + X_N[1][1] * q_N_corr.y; + double Q_NS_x_corr2 = X_NS[0][0] * q_NS_corr.x + X_NS[0][1] * q_NS_corr.y; + double Q_NS_y_corr2 = X_NS[1][0] * q_NS_corr.x + X_NS[1][1] * q_NS_corr.y; + QVecShared::QVec q_S_corr2 = {Q_S_x_corr2, Q_S_y_corr2}; QVecShared::QVec q_N_corr2 = {Q_N_x_corr2, Q_N_y_corr2}; + QVecShared::QVec q_NS_corr2 = {Q_NS_x_corr2, Q_NS_y_corr2}; double psi_S = std::atan2(q_S_corr2.y, q_S_corr2.x); double psi_N = std::atan2(q_N_corr2.y, q_N_corr2.x); + double psi_NS = std::atan2(q_NS_corr2.y, q_NS_corr2.x); h.S_x_corr2_avg->Fill(cent, q_S_corr2.x); h.S_y_corr2_avg->Fill(cent, q_S_corr2.y); @@ -504,7 +530,13 @@ void QVecCalib::process_flattening(double cent, size_t h_idx, QVecShared::QVec q h.N_yy_corr_avg->Fill(cent, q_N_corr2.y * q_N_corr2.y); h.N_xy_corr_avg->Fill(cent, q_N_corr2.x * q_N_corr2.y); - h.Psi_corr2->Fill(psi_S, psi_N, cent); + h.NS_xx_corr_avg->Fill(cent, q_NS_corr2.x * q_NS_corr2.x); + h.NS_yy_corr_avg->Fill(cent, q_NS_corr2.y * q_NS_corr2.y); + h.NS_xy_corr_avg->Fill(cent, q_NS_corr2.x * q_NS_corr2.y); + + h.Psi_S_corr2->Fill(cent, psi_S); + h.Psi_N_corr2->Fill(cent, psi_N); + h.Psi_NS_corr2->Fill(cent, psi_NS); } void QVecCalib::compute_averages(size_t cent_bin, int h_idx) @@ -598,12 +630,16 @@ void QVecCalib::compute_recentering(size_t cent_bin, int h_idx) double Q_N_yy_avg = m_profiles[N_yy_avg_name]->GetBinContent(bin); double Q_N_xy_avg = m_profiles[N_xy_avg_name]->GetBinContent(bin); - m_correction_data[cent_bin][h_idx][0].avg_Q_xx = Q_S_xx_avg; - m_correction_data[cent_bin][h_idx][0].avg_Q_yy = Q_S_yy_avg; - m_correction_data[cent_bin][h_idx][0].avg_Q_xy = Q_S_xy_avg; - m_correction_data[cent_bin][h_idx][1].avg_Q_xx = Q_N_xx_avg; - m_correction_data[cent_bin][h_idx][1].avg_Q_yy = Q_N_yy_avg; - m_correction_data[cent_bin][h_idx][1].avg_Q_xy = Q_N_xy_avg; + // -- Compute NS Matrix -- + std::string NS_xx_avg_name = QVecShared::get_hist_name("NS", "xx", n); + std::string NS_yy_avg_name = QVecShared::get_hist_name("NS", "yy", n); + std::string NS_xy_avg_name = QVecShared::get_hist_name("NS", "xy", n); + + double Q_NS_xx_avg = m_profiles[NS_xx_avg_name]->GetBinContent(bin); + double Q_NS_yy_avg = m_profiles[NS_yy_avg_name]->GetBinContent(bin); + double Q_NS_xy_avg = m_profiles[NS_xy_avg_name]->GetBinContent(bin); + + m_correction_data[cent_bin][h_idx][IDX_NS].X_matrix = calculate_flattening_matrix(Q_NS_xx_avg, Q_NS_yy_avg, Q_NS_xy_avg, n, cent_bin, "NS"); for (size_t det_idx = 0; det_idx < 2; ++det_idx) { @@ -625,8 +661,10 @@ void QVecCalib::compute_recentering(size_t cent_bin, int h_idx) "Q_N_y_corr_avg: {:13.10f}, " "Q_S_xx_avg / Q_S_yy_avg: {:13.10f}, " "Q_N_xx_avg / Q_N_yy_avg: {:13.10f}, " + "Q_NS_xx_avg / Q_NS_yy_avg: {:13.10f}, " "Q_S_xy_avg: {:13.10f}, " - "Q_N_xy_avg: {:13.10f}\n", + "Q_N_xy_avg: {:13.10f}, " + "Q_NS_xy_avg: {:13.10f}\n", cent_bin, n, Q_S_x_corr_avg, @@ -635,8 +673,10 @@ void QVecCalib::compute_recentering(size_t cent_bin, int h_idx) Q_N_y_corr_avg, Q_S_xx_avg / Q_S_yy_avg, Q_N_xx_avg / Q_N_yy_avg, + Q_NS_xx_avg / Q_NS_yy_avg, Q_S_xy_avg, - Q_N_xy_avg); + Q_N_xy_avg, + Q_NS_xy_avg); } void QVecCalib::print_flattening(size_t cent_bin, int n) const @@ -653,6 +693,10 @@ void QVecCalib::print_flattening(size_t cent_bin, int n) const std::string N_yy_corr_avg_name = QVecShared::get_hist_name("N", "yy", n, "_corr"); std::string N_xy_corr_avg_name = QVecShared::get_hist_name("N", "xy", n, "_corr"); + std::string NS_xx_corr_avg_name = QVecShared::get_hist_name("NS", "xx", n, "_corr"); + std::string NS_yy_corr_avg_name = QVecShared::get_hist_name("NS", "yy", n, "_corr"); + std::string NS_xy_corr_avg_name = QVecShared::get_hist_name("NS", "xy", n, "_corr"); + int bin = static_cast(cent_bin + 1); double Q_S_x_corr2_avg = m_profiles.at(S_x_corr2_avg_name)->GetBinContent(bin); @@ -667,6 +711,10 @@ void QVecCalib::print_flattening(size_t cent_bin, int n) const double Q_N_yy_corr_avg = m_profiles.at(N_yy_corr_avg_name)->GetBinContent(bin); double Q_N_xy_corr_avg = m_profiles.at(N_xy_corr_avg_name)->GetBinContent(bin); + double Q_NS_xx_corr_avg = m_profiles.at(NS_xx_corr_avg_name)->GetBinContent(bin); + double Q_NS_yy_corr_avg = m_profiles.at(NS_yy_corr_avg_name)->GetBinContent(bin); + double Q_NS_xy_corr_avg = m_profiles.at(NS_xy_corr_avg_name)->GetBinContent(bin); + std::cout << std::format( "Centrality Bin: {}, " "Harmonic: {}, " @@ -676,8 +724,10 @@ void QVecCalib::print_flattening(size_t cent_bin, int n) const "Q_N_y_corr2_avg: {:13.10f}, " "Q_S_xx_corr_avg / Q_S_yy_corr_avg: {:13.10f}, " "Q_N_xx_corr_avg / Q_N_yy_corr_avg: {:13.10f}, " + "Q_NS_xx_corr_avg / Q_NS_yy_corr_avg: {:13.10f}, " "Q_S_xy_corr_avg: {:13.10f}, " - "Q_N_xy_corr_avg: {:13.10f}\n", + "Q_N_xy_corr_avg: {:13.10f}, " + "Q_NS_xy_corr_avg: {:13.10f}\n", cent_bin, n, Q_S_x_corr2_avg, @@ -686,8 +736,10 @@ void QVecCalib::print_flattening(size_t cent_bin, int n) const Q_N_y_corr2_avg, Q_S_xx_corr_avg / Q_S_yy_corr_avg, Q_N_xx_corr_avg / Q_N_yy_corr_avg, + Q_NS_xx_corr_avg / Q_NS_yy_corr_avg, Q_S_xy_corr_avg, - Q_N_xy_corr_avg); + Q_N_xy_corr_avg, + Q_NS_xy_corr_avg); } std::vector QVecCalib::prepare_average_hists() @@ -701,9 +753,9 @@ std::vector QVecCalib::prepare_average_hists() std::string N_x_avg_name = QVecShared::get_hist_name("N", "x", n); std::string N_y_avg_name = QVecShared::get_hist_name("N", "y", n); - std::string hist_Q_S_name = std::format("h3_sEPD_Q_S_{}", n); - std::string hist_Q_N_name = std::format("h3_sEPD_Q_N_{}", n); - std::string psi_Q_name = std::format("h3_sEPD_Psi_{}", n); + std::string psi_S_name = std::format("h2_sEPD_Psi_S_{}", n); + std::string psi_N_name = std::format("h2_sEPD_Psi_N_{}", n); + std::string psi_NS_name = std::format("h2_sEPD_Psi_NS_{}", n); AverageHists h; @@ -712,10 +764,9 @@ std::vector QVecCalib::prepare_average_hists() h.N_x_avg = m_profiles.at(N_x_avg_name).get(); h.N_y_avg = m_profiles.at(N_y_avg_name).get(); - h.Q_S = m_hists3D.at(hist_Q_S_name).get(); - h.Q_N = m_hists3D.at(hist_Q_N_name).get(); - - h.Psi = m_hists3D.at(psi_Q_name).get(); + h.Psi_S = m_hists2D.at(psi_S_name).get(); + h.Psi_N = m_hists2D.at(psi_N_name).get(); + h.Psi_NS = m_hists2D.at(psi_NS_name).get(); hists_cache.push_back(h); } @@ -800,7 +851,13 @@ std::vector QVecCalib::prepare_recenter_hists() std::string N_yy_avg_name = QVecShared::get_hist_name("N", "yy", n); std::string N_xy_avg_name = QVecShared::get_hist_name("N", "xy", n); - std::string psi_Q_corr_name = std::format("h3_sEPD_Psi_{}_corr", n); + std::string NS_xx_avg_name = QVecShared::get_hist_name("NS", "xx", n); + std::string NS_yy_avg_name = QVecShared::get_hist_name("NS", "yy", n); + std::string NS_xy_avg_name = QVecShared::get_hist_name("NS", "xy", n); + + std::string psi_S_name = std::format("h2_sEPD_Psi_S_{}_corr", n); + std::string psi_N_name = std::format("h2_sEPD_Psi_N_{}_corr", n); + std::string psi_NS_name = std::format("h2_sEPD_Psi_NS_{}_corr", n); RecenterHists h; @@ -816,7 +873,13 @@ std::vector QVecCalib::prepare_recenter_hists() h.N_yy_avg = m_profiles.at(N_yy_avg_name).get(); h.N_xy_avg = m_profiles.at(N_xy_avg_name).get(); - h.Psi_corr = m_hists3D.at(psi_Q_corr_name).get(); + h.NS_xx_avg = m_profiles.at(NS_xx_avg_name).get(); + h.NS_yy_avg = m_profiles.at(NS_yy_avg_name).get(); + h.NS_xy_avg = m_profiles.at(NS_xy_avg_name).get(); + + h.Psi_S_corr = m_hists2D.at(psi_S_name).get(); + h.Psi_N_corr = m_hists2D.at(psi_N_name).get(); + h.Psi_NS_corr = m_hists2D.at(psi_NS_name).get(); hists_cache.push_back(h); } @@ -842,7 +905,13 @@ std::vector QVecCalib::prepare_flattening_hists() std::string N_yy_corr_avg_name = QVecShared::get_hist_name("N", "yy", n, "_corr"); std::string N_xy_corr_avg_name = QVecShared::get_hist_name("N", "xy", n, "_corr"); - std::string psi_Q_corr2_name = std::format("h3_sEPD_Psi_{}_corr2", n); + std::string NS_xx_corr_avg_name = QVecShared::get_hist_name("NS", "xx", n, "_corr"); + std::string NS_yy_corr_avg_name = QVecShared::get_hist_name("NS", "yy", n, "_corr"); + std::string NS_xy_corr_avg_name = QVecShared::get_hist_name("NS", "xy", n, "_corr"); + + std::string psi_S_name = std::format("h2_sEPD_Psi_S_{}_corr2", n); + std::string psi_N_name = std::format("h2_sEPD_Psi_N_{}_corr2", n); + std::string psi_NS_name = std::format("h2_sEPD_Psi_NS_{}_corr2", n); FlatteningHists h; @@ -859,7 +928,13 @@ std::vector QVecCalib::prepare_flattening_hists() h.N_yy_corr_avg = m_profiles.at(N_yy_corr_avg_name).get(); h.N_xy_corr_avg = m_profiles.at(N_xy_corr_avg_name).get(); - h.Psi_corr2 = m_hists3D.at(psi_Q_corr2_name).get(); + h.NS_xx_corr_avg = m_profiles.at(NS_xx_corr_avg_name).get(); + h.NS_yy_corr_avg = m_profiles.at(NS_yy_corr_avg_name).get(); + h.NS_xy_corr_avg = m_profiles.at(NS_xy_corr_avg_name).get(); + + h.Psi_S_corr2 = m_hists2D.at(psi_S_name).get(); + h.Psi_N_corr2 = m_hists2D.at(psi_N_name).get(); + h.Psi_NS_corr2 = m_hists2D.at(psi_NS_name).get(); hists_cache.push_back(h); } @@ -1047,15 +1122,11 @@ void QVecCalib::load_correction_data() std::string N_x_avg_name = QVecShared::get_hist_name("N", "x", n); std::string N_y_avg_name = QVecShared::get_hist_name("N", "y", n); - std::string psi_hist_name = std::format("h3_sEPD_Psi_{}", n); - m_profiles[S_x_avg_name] = load_and_clone(file.get(), S_x_avg_name); m_profiles[S_y_avg_name] = load_and_clone(file.get(), S_y_avg_name); m_profiles[N_x_avg_name] = load_and_clone(file.get(), N_x_avg_name); m_profiles[N_y_avg_name] = load_and_clone(file.get(), N_y_avg_name); - m_hists3D[psi_hist_name] = load_and_clone(file.get(), psi_hist_name); - std::string S_xx_avg_name = QVecShared::get_hist_name("S", "xx", n); std::string S_yy_avg_name = QVecShared::get_hist_name("S", "yy", n); std::string S_xy_avg_name = QVecShared::get_hist_name("S", "xy", n); @@ -1063,18 +1134,23 @@ void QVecCalib::load_correction_data() std::string N_yy_avg_name = QVecShared::get_hist_name("N", "yy", n); std::string N_xy_avg_name = QVecShared::get_hist_name("N", "xy", n); - std::string psi_corr_hist_name = std::format("h3_sEPD_Psi_{}_corr", n); + std::string NS_xx_avg_name = QVecShared::get_hist_name("NS", "xx", n); + std::string NS_yy_avg_name = QVecShared::get_hist_name("NS", "yy", n); + std::string NS_xy_avg_name = QVecShared::get_hist_name("NS", "xy", n); if(m_pass == Pass::ApplyFlattening) { m_profiles[S_xx_avg_name] = load_and_clone(file.get(), S_xx_avg_name); m_profiles[S_yy_avg_name] = load_and_clone(file.get(), S_yy_avg_name); m_profiles[S_xy_avg_name] = load_and_clone(file.get(), S_xy_avg_name); + m_profiles[N_xx_avg_name] = load_and_clone(file.get(), N_xx_avg_name); m_profiles[N_yy_avg_name] = load_and_clone(file.get(), N_yy_avg_name); m_profiles[N_xy_avg_name] = load_and_clone(file.get(), N_xy_avg_name); - m_hists3D[psi_corr_hist_name] = load_and_clone(file.get(), psi_corr_hist_name); + m_profiles[NS_xx_avg_name] = load_and_clone(file.get(), NS_xx_avg_name); + m_profiles[NS_yy_avg_name] = load_and_clone(file.get(), NS_yy_avg_name); + m_profiles[NS_xy_avg_name] = load_and_clone(file.get(), NS_xy_avg_name); } size_t south_idx = static_cast(QVecShared::Subdetector::S); @@ -1098,19 +1174,18 @@ void QVecCalib::load_correction_data() double Q_S_xx_avg = m_profiles[S_xx_avg_name]->GetBinContent(bin); double Q_S_yy_avg = m_profiles[S_yy_avg_name]->GetBinContent(bin); double Q_S_xy_avg = m_profiles[S_xy_avg_name]->GetBinContent(bin); + double Q_N_xx_avg = m_profiles[N_xx_avg_name]->GetBinContent(bin); double Q_N_yy_avg = m_profiles[N_yy_avg_name]->GetBinContent(bin); double Q_N_xy_avg = m_profiles[N_xy_avg_name]->GetBinContent(bin); - // Flattening Params - m_correction_data[cent_bin][h_idx][south_idx].avg_Q_xx = Q_S_xx_avg; - m_correction_data[cent_bin][h_idx][south_idx].avg_Q_yy = Q_S_yy_avg; - m_correction_data[cent_bin][h_idx][south_idx].avg_Q_xy = Q_S_xy_avg; + double Q_NS_xx_avg = m_profiles[NS_xx_avg_name]->GetBinContent(bin); + double Q_NS_yy_avg = m_profiles[NS_yy_avg_name]->GetBinContent(bin); + double Q_NS_xy_avg = m_profiles[NS_xy_avg_name]->GetBinContent(bin); - m_correction_data[cent_bin][h_idx][north_idx].avg_Q_xx = Q_N_xx_avg; - m_correction_data[cent_bin][h_idx][north_idx].avg_Q_yy = Q_N_yy_avg; - m_correction_data[cent_bin][h_idx][north_idx].avg_Q_xy = Q_N_xy_avg; + m_correction_data[cent_bin][h_idx][IDX_NS].X_matrix = calculate_flattening_matrix(Q_NS_xx_avg, Q_NS_yy_avg, Q_NS_xy_avg, n, cent_bin, "NS"); + // Flattening Params for (size_t det_idx = 0; det_idx < 2; ++det_idx) { double xx = (det_idx == 0) ? Q_S_xx_avg : Q_N_xx_avg; @@ -1156,11 +1231,6 @@ void QVecCalib::save_results() const std::cout << std::format("Saving 2D: {}\n", name); hist->Write(); } - for (const auto& [name, hist] : m_hists3D) - { - std::cout << std::format("Saving 3D: {}\n", name); - hist->Write(); - } for (const auto& [name, hist] : m_profiles) { std::cout << std::format("Saving Profile: {}\n", name); diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.h b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.h index 7317ae1488..a10c3e14f9 100644 --- a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.h +++ b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.h @@ -11,7 +11,6 @@ #include #include #include -#include #include // ==================================================================== @@ -68,8 +67,9 @@ class QVecCalib private: - struct CorrectionData : public QVecShared::CorrectionMoments + struct CorrectionData { + QVecShared::QVec avg_Q{}; std::array, 2> X_matrix{}; }; @@ -81,8 +81,10 @@ class QVecCalib // Holds all correction data // key: [Cent][Harmonic][Subdetector] // Harmonics {2,3,4} -> 3 elements - // Subdetectors {S,N} -> 2 elements - std::array, m_harmonics.size()>, m_cent_bins> m_correction_data; + // Subdetectors {S,N,NS} -> 3 elements + std::array, m_harmonics.size()>, m_cent_bins> m_correction_data; + + static constexpr size_t IDX_NS = 2; // Store harmonic orders and subdetectors for easy iteration static constexpr std::array m_subdetectors = {QVecShared::Subdetector::S, QVecShared::Subdetector::N}; @@ -121,10 +123,9 @@ class QVecCalib TProfile* N_x_avg{nullptr}; TProfile* N_y_avg{nullptr}; - TH3* Q_S{nullptr}; - TH3* Q_N{nullptr}; - - TH3* Psi{nullptr}; + TH2* Psi_S{nullptr}; + TH2* Psi_N{nullptr}; + TH2* Psi_NS{nullptr}; }; struct RecenterHists @@ -141,7 +142,13 @@ class QVecCalib TProfile* N_yy_avg{nullptr}; TProfile* N_xy_avg{nullptr}; - TH3* Psi_corr{nullptr}; + TProfile* NS_xx_avg{nullptr}; + TProfile* NS_yy_avg{nullptr}; + TProfile* NS_xy_avg{nullptr}; + + TH2* Psi_S_corr{nullptr}; + TH2* Psi_N_corr{nullptr}; + TH2* Psi_NS_corr{nullptr}; }; struct FlatteningHists @@ -159,7 +166,13 @@ class QVecCalib TProfile* N_yy_corr_avg{nullptr}; TProfile* N_xy_corr_avg{nullptr}; - TH3* Psi_corr2{nullptr}; + TProfile* NS_xx_corr_avg{nullptr}; + TProfile* NS_yy_corr_avg{nullptr}; + TProfile* NS_xy_corr_avg{nullptr}; + + TH2* Psi_S_corr2{nullptr}; + TH2* Psi_N_corr2{nullptr}; + TH2* Psi_NS_corr2{nullptr}; }; // --- Member Variables --- @@ -177,7 +190,6 @@ class QVecCalib // Hists std::map> m_hists1D; std::map> m_hists2D; - std::map> m_hists3D; std::map> m_profiles; // sEPD Bad Channels @@ -216,7 +228,7 @@ class QVecCalib * @brief Safely retrieves a ROOT object from a file and returns a managed unique_ptr. * * Performs a dynamic_cast to verify the requested type T and Clones the object * to ensure it remains valid after the source file is closed. - * * @tparam T The ROOT class type (e.g., TProfile, TH3). + * * @tparam T The ROOT class type (e.g., TProfile). * @param file Pointer to the source TFile. * @param name The name of the object within the file. * @return std::unique_ptr A managed pointer to the cloned object. @@ -265,8 +277,8 @@ class QVecCalib /** * @brief Finalizes the analysis by writing all histograms to the output ROOT file. - * * Creates the output directory if it does not exist and ensures all 1D, 2D, - * 3D histograms and TProfiles are safely persisted to disk. + * * Creates the output directory if it does not exist and ensures all 1D, 2D + * and TProfiles are safely persisted to disk. */ void save_results() const; diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h b/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h index f74c62f574..bea362b661 100644 --- a/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h +++ b/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h @@ -14,7 +14,8 @@ namespace QVecShared enum class Subdetector { S, // South - N // North + N, // North + NS // North South }; enum class QComponent From c38e2000cb52d9d00fe8eee961b398aff745a349 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Tue, 27 Jan 2026 09:52:12 -0500 Subject: [PATCH 116/393] trigger jenkins From 9d25f5e0f5fed1f09fa66ac3d5f0b1b0c6c38081 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Tue, 27 Jan 2026 09:59:41 -0500 Subject: [PATCH 117/393] trigger jenkins From 5e38c107eb93abe133ef477bc60ab25b3848b1a6 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Tue, 27 Jan 2026 10:00:49 -0500 Subject: [PATCH 118/393] trigger jenkins From 382455af6c7c081ff2c7e7d01139b608921922ba Mon Sep 17 00:00:00 2001 From: mchiu-bnl Date: Tue, 27 Jan 2026 12:14:18 -0500 Subject: [PATCH 119/393] added mbd_status calib, overlapping waveforms (pileup) fit --- offline/packages/mbd/MbdCalib.cc | 120 ++++++++++++++++++++++ offline/packages/mbd/MbdCalib.h | 8 ++ offline/packages/mbd/MbdEvent.cc | 29 ++++-- offline/packages/mbd/MbdEvent.h | 7 +- offline/packages/mbd/MbdSig.cc | 164 ++++++++++++++++++++++++++----- offline/packages/mbd/MbdSig.h | 11 ++- 6 files changed, 301 insertions(+), 38 deletions(-) diff --git a/offline/packages/mbd/MbdCalib.cc b/offline/packages/mbd/MbdCalib.cc index 0b02908adb..1367b375c8 100644 --- a/offline/packages/mbd/MbdCalib.cc +++ b/offline/packages/mbd/MbdCalib.cc @@ -86,6 +86,13 @@ int MbdCalib::Download_All() } Download_SampMax(sampmax_url); + std::string status_url = _cdb->getUrl("MBD_STATUS"); + if (Verbosity() > 0) + { + std::cout << "status_url " << status_url << std::endl; + } + Download_Status(status_url); + if ( !_rawdstflag ) { std::string ped_url = _cdb->getUrl("MBD_PED"); @@ -176,6 +183,9 @@ int MbdCalib::Download_All() std::string sampmax_file = bbc_caldir + "/mbd_sampmax.calib"; Download_SampMax(sampmax_file); + std::string status_file = bbc_caldir + "/mbd_status.calib"; + Download_Status(status_file); + if ( !_rawdstflag ) { std::string ped_file = bbc_caldir + "/mbd_ped.calib"; @@ -688,6 +698,70 @@ int MbdCalib::Download_SampMax(const std::string& dbase_location) return 1; } +int MbdCalib::Download_Status(const std::string& dbase_location) +{ + // Reset All Values + _mbdstatus.fill(-1); + + TString dbase_file = dbase_location; + +#ifndef ONLINE + if (dbase_file.EndsWith(".root")) // read from database + { + CDBTTree* cdbttree = new CDBTTree(dbase_location); + cdbttree->LoadCalibrations(); + + for (int ifeech = 0; ifeech < MbdDefs::MBD_N_FEECH; ifeech++) + { + _mbdstatus[ifeech] = cdbttree->GetIntValue(ifeech, "status"); + if (Verbosity() > 0) + { + if (ifeech < 5 || ifeech >= MbdDefs::MBD_N_FEECH - 5) + { + std::cout << ifeech << "\t" << _mbdstatus[ifeech] << std::endl; + } + } + } + delete cdbttree; + } +#endif + + if (dbase_file.EndsWith(".calib")) // read from text file + { + std::ifstream infile(dbase_location); + if (!infile.is_open()) + { + std::cout << PHWHERE << "unable to open " << dbase_location << std::endl; + _status = -3; + return _status; + } + + int feech = -1; + while (infile >> feech) + { + infile >> _mbdstatus[feech]; + if (Verbosity() > 0) + { + if (feech < 5 || feech >= MbdDefs::MBD_N_FEECH - 5) + { + std::cout << "status\t" << feech << "\t" << _mbdstatus[feech] << std::endl; + } + } + } + infile.close(); + } + + + if ( _mbdstatus[0] == -1 ) + { + std::cout << PHWHERE << ", WARNING, sampmax calib missing, " << dbase_location << std::endl; + _status = -1; + return _status; // file not found + } + + return 1; +} + int MbdCalib::Download_Shapes(const std::string& dbase_location) { // Verbosity(100); @@ -1591,6 +1665,52 @@ int MbdCalib::Write_SampMax(const std::string& dbfile) return 1; } +#ifndef ONLINE +int MbdCalib::Write_CDB_Status(const std::string& dbfile) +{ + CDBTTree* cdbttree{ nullptr }; + + std::cout << "Creating " << dbfile << std::endl; + cdbttree = new CDBTTree( dbfile ); + cdbttree->SetSingleIntValue("version", 1); + cdbttree->CommitSingle(); + + std::cout << "STATUS" << std::endl; + for (size_t ifeech = 0; ifeech < _mbdstatus.size(); ifeech++) + { + // store in a CDBTree + cdbttree->SetIntValue(ifeech, "status", _mbdstatus[ifeech]); + + if (ifeech < 12 || ifeech >= MbdDefs::MBD_N_FEECH - 5) + { + std::cout << ifeech << "\t" << std::hex << cdbttree->GetIntValue(ifeech, "status") << std::dec << std::endl; + } + } + + cdbttree->Commit(); + // cdbttree->Print(); + + // for now we create the tree after reading it + cdbttree->WriteCDBTTree(); + delete cdbttree; + + return 1; +} +#endif + +int MbdCalib::Write_Status(const std::string& dbfile) +{ + std::ofstream cal_file; + cal_file.open(dbfile); + for (int ifeech = 0; ifeech < MbdDefs::MBD_N_FEECH; ifeech++) + { + cal_file << ifeech << "\t0x" << std::hex << _mbdstatus[ifeech] << std::dec << std::endl; + } + cal_file.close(); + + return 1; +} + #ifndef ONLINE int MbdCalib::Write_CDB_TTT0(const std::string& dbfile) { diff --git a/offline/packages/mbd/MbdCalib.h b/offline/packages/mbd/MbdCalib.h index 6d7208f631..1f450cb5be 100644 --- a/offline/packages/mbd/MbdCalib.h +++ b/offline/packages/mbd/MbdCalib.h @@ -37,6 +37,7 @@ class MbdCalib float get_ped(const int ifeech) const { return _pedmean[ifeech]; } float get_pedrms(const int ifeech) const { return _pedsigma[ifeech]; } int get_sampmax(const int ifeech) const { return _sampmax[ifeech]; } + int get_status(const int ifeech) const { return _mbdstatus[ifeech]; } float get_tcorr(const int ifeech, const int tdc) const { if (tdc<0) { @@ -108,6 +109,7 @@ class MbdCalib TGraph *get_lut_graph(const int pmtch, std::string_view type); void set_sampmax(const int ifeech, const int val) { _sampmax[ifeech] = val; } + void set_status(const int ifeech, const int val) { _mbdstatus[ifeech] = val; } void set_ped(const int ifeech, const float m, const float merr, const float s, const float serr); void set_tt0(const int ipmt, const float t0) { _ttfit_t0mean[ipmt] = t0; } void set_tq0(const int ipmt, const float t0) { _tqfit_t0mean[ipmt] = t0; } @@ -118,6 +120,7 @@ class MbdCalib int Download_T0Corr(const std::string& dbase_location); int Download_Ped(const std::string& dbase_location); int Download_SampMax(const std::string& dbase_location); + int Download_Status(const std::string& dbase_location); int Download_Shapes(const std::string& dbase_location); int Download_TimeCorr(const std::string& dbase_location); int Download_SlewCorr(const std::string& dbase_location); @@ -128,6 +131,7 @@ class MbdCalib #ifndef ONLINE int Write_CDB_SampMax(const std::string& dbfile); + int Write_CDB_Status(const std::string& dbfile); int Write_CDB_TTT0(const std::string& dbfile); int Write_CDB_TQT0(const std::string& dbfile); int Write_CDB_T0Corr(const std::string& dbfile); @@ -143,6 +147,7 @@ class MbdCalib #endif int Write_SampMax(const std::string& dbfile); + int Write_Status(const std::string& dbfile); int Write_TQT0(const std::string& dbfile); int Write_TTT0(const std::string& dbfile); int Write_T0Corr(const std::string& dbfile); @@ -231,6 +236,9 @@ class MbdCalib // SampMax (Peak of waveform) std::array _sampmax{}; + // Status (MBD Channel Status) + std::array _mbdstatus{}; + // Pileup waveform correction std::array _pileup_p0{}; std::array _pileup_p0err{}; diff --git a/offline/packages/mbd/MbdEvent.cc b/offline/packages/mbd/MbdEvent.cc index cdab537f45..04287aae2c 100644 --- a/offline/packages/mbd/MbdEvent.cc +++ b/offline/packages/mbd/MbdEvent.cc @@ -361,6 +361,22 @@ int MbdEvent::End() orig_dir->cd(); } + // Write out MbdSig eval histograms + if ( _doeval ) + { + TDirectory *orig_dir = gDirectory; + + TString savefname = "mbdeval_"; savefname += _runnum; savefname += ".root"; + _evalfile = std::make_unique(savefname,"RECREATE"); + + for (auto & sig : _mbdsig) + { + sig.WriteChi2Hist(); + } + + orig_dir->cd(); + } + return 1; } @@ -741,11 +757,6 @@ int MbdEvent::ProcessPackets(MbdRawContainer *bbcraws) // calpass 2, uncal_mbd. template fit. make sure qgain = 1, tq_t0 = 0 - // In Run 1 (runs before 40000), we didn't set hardware thresholds, and instead set a software threshold of 0.25 - if ( ((m_ampl[ifeech] < (_mbdcal->get_qgain(pmtch) * 0.25)) && (_runnum < 40000)) || std::fabs(_mbdcal->get_tq0(pmtch))>100. ) - { - m_qtdc[pmtch] = std::numeric_limits::quiet_NaN(); - } } } @@ -799,6 +810,12 @@ int MbdEvent::ProcessRawContainer(MbdRawContainer *bbcraws, MbdPmtContainer *bbc m_pmttq[pmtch] = bbcraws->get_pmt(pmtch)->get_qtdc(); + // In Run 1 (runs before 40000), we didn't set hardware thresholds, and instead set a software threshold of 0.25 + if ( ((bbcraws->get_pmt(pmtch)->get_adc() < (_mbdcal->get_qgain(pmtch) * 0.25)) && (_runnum < 40000)) || std::fabs(_mbdcal->get_tq0(pmtch))>100. ) + { + m_qtdc[pmtch] = std::numeric_limits::quiet_NaN(); + } + if ( !std::isnan(m_pmttq[pmtch]) ) { m_pmttq[pmtch] -= (_mbdcal->get_sampmax(ifeech) - 2); @@ -809,7 +826,7 @@ int MbdEvent::ProcessRawContainer(MbdRawContainer *bbcraws, MbdPmtContainer *bbc // if ( arm==1 ) std::cout << "hit_times " << ifeech << "\t" << setw(10) << m_pmttq[pmtch] << "\t" << board << "\t" << TRIG_SAMP[board] << std::endl; // if tt is bad, use tq - if ( std::fabs(_mbdcal->get_tt0(pmtch))>100. ) + if ( _mbdcal->get_status(ifeech-8)>0 ) { m_pmttt[pmtch] = m_pmttq[pmtch]; } diff --git a/offline/packages/mbd/MbdEvent.h b/offline/packages/mbd/MbdEvent.h index ede1670171..5abd48aeae 100644 --- a/offline/packages/mbd/MbdEvent.h +++ b/offline/packages/mbd/MbdEvent.h @@ -74,6 +74,7 @@ class MbdEvent void set_EventNumber(int ievt) { m_evt = ievt; } void set_debug(const int d) { _debug = d; } + void set_doeval(const int d) { _doeval = d; } MbdSig *GetSig(const int ipmt) { return &_mbdsig[ipmt]; } @@ -196,12 +197,14 @@ class MbdEvent // debug stuff TCanvas *ac{nullptr}; // for plots used during debugging void PlotDebug(); + int _doeval{0}; + std::unique_ptr _evalfile{nullptr}; std::unique_ptr _synctfile{nullptr}; TTree *_syncttree{nullptr}; Double_t _refz{ std::numeric_limits::quiet_NaN() }; - std::vector bbevt; + std::vector bbevt; std::vector bbclk; - std::vector mybbz; + std::vector mybbz; std::vector bco; std::vector intz; std::vector bbz; diff --git a/offline/packages/mbd/MbdSig.cc b/offline/packages/mbd/MbdSig.cc index ae1f821a4e..72438e4046 100644 --- a/offline/packages/mbd/MbdSig.cc +++ b/offline/packages/mbd/MbdSig.cc @@ -74,10 +74,13 @@ void MbdSig::Init() ped_tail = new TF1("ped_tail","[0]+[1]*exp(-[2]*x)",0,2); ped_tail->SetLineColor(2); - // uncomment this to write out waveforms from events that have pileup from prev. crossing + name = "h_chi2ndf"; name += _ch; + h_chi2ndf = new TH1F(name,name,2000,0,100); + + // uncomment this to write out waveforms from events that have pileup from prev. crossing or next crossing /* name = "mbdsig"; name += _ch; name += ".txt"; - _pileupfile = new ofstream(name); + _pileupfile = new std::ofstream(name); */ } @@ -251,6 +254,7 @@ void MbdSig::SetXY(const Float_t* x, const Float_t* y, const int invert) { gRawPulse->Draw("ap"); gRawPulse->GetHistogram()->SetTitle(gRawPulse->GetName()); + gPad->SetGridx(1); gPad->SetGridy(1); PadUpdate(); } @@ -412,6 +416,11 @@ Double_t MbdSig::GetSplineAmpl() return f_ampl; } +void MbdSig::WriteChi2Hist() +{ + h_chi2ndf->Write(); +} + void MbdSig::WritePedHist() { hPed0->Write(); @@ -619,6 +628,7 @@ int MbdSig::CalcEventPed0_PreSamp(const int presample, const int nsamps) //std::cout << PHWHERE << std::endl; gRawPulse->Fit( ped_fcn, "RNQ" ); + /* double chi2ndf = ped_fcn->GetChisquare()/ped_fcn->GetNDF(); if ( _pileupfile != nullptr && chi2ndf > 4.0 ) { @@ -629,6 +639,7 @@ int MbdSig::CalcEventPed0_PreSamp(const int presample, const int nsamps) } *_pileupfile << std::endl; } + */ } double chi2 = ped_fcn->GetChisquare(); @@ -988,6 +999,12 @@ void MbdSig::PadUpdate() const } } +Double_t MbdSig::TwoTemplateFcn(const Double_t* x, const Double_t* par) +{ + Double_t f = TemplateFcn(x,par) + TemplateFcn(x,par+2); + return f; +} + Double_t MbdSig::TemplateFcn(const Double_t* x, const Double_t* par) { // par[0] is the amplitude (relative to the spline amplitude) @@ -1106,8 +1123,13 @@ Double_t MbdSig::TemplateFcn(const Double_t* x, const Double_t* par) int MbdSig::FitTemplate( const Int_t sampmax ) { //std::cout << PHWHERE << std::endl; //chiu - //_verbose = 100; // uncomment to see fits - //_verbose = 12; // don't see pedestal fits + /* + if ( _evt_counter==2142 && _ch==92 ) + { + _verbose = 100; // uncomment to see fits + //_verbose = 12; // don't see pedestal fits + } + */ // Check if channel is empty if (gSubPulse->GetN() == 0) @@ -1124,22 +1146,22 @@ int MbdSig::FitTemplate( const Int_t sampmax ) int nsaturated = 0; for (int ipt=0; ipt 16370. ) + if ( rawsamps[ipt] > 16370. ) // don't trust adc near edge { nsaturated++; } } /* - if ( nsaturated>2 && _ch==185 ) + //if ( nsaturated>2 && _ch==185 ) + if ( nsaturated>2 ) { _verbose = 12; } */ - if (_verbose > 0) { - std::cout << "Fitting ch " << _ch << std::endl; + std::cout << "Fitting ch sampmax " << _ch << "\t" << sampmax << std::endl; } // Get x and y of maximum @@ -1147,7 +1169,17 @@ int MbdSig::FitTemplate( const Int_t sampmax ) Double_t ymax{0.}; if ( sampmax>=0 ) { - gSubPulse->GetPoint(sampmax, x_at_max, ymax); + for (int isamp=sampmax-1; isamp<=sampmax+1; isamp++) + { + double adcval = gSubPulse->GetPointY(isamp); + if ( adcval>ymax ) + { + ymax = adcval; + x_at_max = isamp; + } + } + + //gSubPulse->GetPoint(sampmax, x_at_max, ymax); if ( nsaturated<=3 ) { x_at_max -= 2.0; @@ -1176,6 +1208,7 @@ int MbdSig::FitTemplate( const Int_t sampmax ) gSubPulse->Draw("ap"); gSubPulse->GetHistogram()->SetTitle(gSubPulse->GetName()); gPad->SetGridy(1); + gPad->SetGridx(1); PadUpdate(); } @@ -1184,23 +1217,15 @@ int MbdSig::FitTemplate( const Int_t sampmax ) } template_fcn->SetParameters(ymax, x_at_max); - // template_fcn->SetParLimits(1, fit_min_time, fit_max_time); - // template_fcn->SetParLimits(1, 3, 15); - // template_fcn->SetRange(template_min_xrange,template_max_xrange); if ( nsaturated<=3 ) { - template_fcn->SetRange(0, _nsamples); + template_fcn->SetRange(0, x_at_max+4.2); } else { template_fcn->SetRange(0, sampmax + nsaturated - 0.5); } - if ( gSubPulse->GetN()==0 )//chiu - { - std::cout << PHWHERE << " gSubPulse 0" << std::endl; - } - if (_verbose == 0) { //std::cout << PHWHERE << std::endl; @@ -1214,24 +1239,88 @@ int MbdSig::FitTemplate( const Int_t sampmax ) gSubPulse->GetHistogram()->SetTitle(gSubPulse->GetName()); gPad->SetGridy(1); PadUpdate(); - //std::cout << "doing fit2 " << _verbose << std::endl; - //std::cout << "doing fit3 " << _verbose << std::endl; //gSubPulse->Print("ALL"); } // Get fit parameters f_ampl = template_fcn->GetParameter(0); f_time = template_fcn->GetParameter(1); - if ( f_time<0. || f_time>_nsamples ) + f_chi2 = template_fcn->GetChisquare(); + f_ndf = template_fcn->GetNDF(); + + // Good fit + if ( (f_chi2/f_ndf) < 5. && f_ndf>6. ) { + h_chi2ndf->Fill( f_chi2/f_ndf ); + _verbose = 0; + return 1; + } + + // fit was out of time, likely from pileup, try two waveforms + if ( (f_time<(sampmax-2.5) || f_time>sampmax) && (nsaturated<=3) ) + { + //_verbose = 100; //chiu + + if ( _verbose ) + { + std::cout << "BADTIME " << _evt_counter << "\t" << _ch << "\t" << sampmax << "\t" << f_ampl << "\t" << f_time << std::endl; + gSubPulse->Draw("ap"); + template_fcn->Draw("same"); + PadUpdate(); + } + + twotemplate_fcn->SetParameters(ymax,x_at_max,ymax,10); + twotemplate_fcn->SetRange(0,_nsamples); + + if (_verbose == 0) + { + gSubPulse->Fit(twotemplate_fcn, "RNQ"); + } + else + { + std::cout << "doing fit1 " << x_at_max << "\t" << ymax << std::endl; + gSubPulse->Fit(twotemplate_fcn, "R"); + gSubPulse->Draw("ap"); + gSubPulse->GetHistogram()->SetTitle(gSubPulse->GetName()); + gPad->SetGridy(1); + PadUpdate(); + //gSubPulse->Print("ALL"); + } + + //PadUpdate(); + + // Get fit parameters + f_ampl = template_fcn->GetParameter(0); + f_time = template_fcn->GetParameter(1); + f_chi2 = template_fcn->GetChisquare(); + f_ndf = template_fcn->GetNDF(); + + // Good fit + if ( (f_chi2/f_ndf) < 5. && f_ndf>6. ) + { + h_chi2ndf->Fill( f_chi2/f_ndf ); + _verbose = 0; + return 1; + } + } + + + /* chiu + if ( f_time<0. || f_time>9 ) + { + _verbose = 100; f_time = _nsamples*0.5; // bad fit last time } + */ // refit with new range to exclude after-pulses - template_fcn->SetParameters( f_ampl, f_time ); + template_fcn->SetParameters(ymax, x_at_max); + //template_fcn->SetParameters( f_ampl, f_time ); + if ( nsaturated<=3 ) { - template_fcn->SetRange( 0., f_time+4.0 ); + template_fcn->SetRange(0, x_at_max+4.2); + //template_fcn->SetRange( 0., f_time+4.0 ); } else { @@ -1242,16 +1331,16 @@ int MbdSig::FitTemplate( const Int_t sampmax ) { //std::cout << PHWHERE << std::endl; int fit_status = gSubPulse->Fit(template_fcn, "RNQ"); - if ( fit_status<0 ) + if ( fit_status<0 && _verbose>0 ) { std::cout << PHWHERE << "\t" << fit_status << std::endl; gSubPulse->Print("ALL"); gSubPulse->Draw("ap"); gSubPulse->Fit(template_fcn, "R"); - std::cout << "ampl time before refit " << f_ampl << "\t" << f_time << std::endl; + std::cout << "ampl time before refit " << _ch << "\t" << f_ampl << "\t" << f_time << std::endl; f_ampl = template_fcn->GetParameter(0); f_time = template_fcn->GetParameter(1); - std::cout << "ampl time after refit " << f_ampl << "\t" << f_time << std::endl; + std::cout << "ampl time after refit " << _ch << "\t" << f_ampl << "\t" << f_time << std::endl; PadUpdate(); std::string junk; std::cin >> junk; @@ -1269,6 +1358,18 @@ int MbdSig::FitTemplate( const Int_t sampmax ) f_ampl = template_fcn->GetParameter(0); f_time = template_fcn->GetParameter(1); + f_chi2 = template_fcn->GetChisquare(); + f_ndf = template_fcn->GetNDF(); + + h_chi2ndf->Fill( f_chi2/f_ndf ); + + /* + if ( (f_chi2/f_ndf) > 100. ) //chiu + { + std::cout << "very bad chi2ndf after refit " << f_ampl << "\t" << f_time << "\t" << f_chi2/f_ndf << std::endl; + //_verbose = 100; + } + */ //if ( f_time<0 || f_time>30 ) //if ( (_ch==185||_ch==155||_ch==249) && (fabs(f_ampl) > 44000.) ) @@ -1282,6 +1383,7 @@ int MbdSig::FitTemplate( const Int_t sampmax ) std::cout << " " << template_fcn->GetChisquare()/template_fcn->GetNDF() << std::endl; gSubPulse->Draw("ap"); gSubPulse->GetHistogram()->SetTitle(gSubPulse->GetName()); + gPad->SetGridx(1); gPad->SetGridy(1); template_fcn->SetLineColor(4); template_fcn->Draw("same"); @@ -1323,6 +1425,16 @@ int MbdSig::SetTemplate(const std::vector& shape, const std::vectorSetParName(1, "time"); SetTemplateSize(900, 1000, -10., 20.); + name = "twotemplate_fcn"; + name += _ch; + twotemplate_fcn = new TF1(name, this, &MbdSig::TwoTemplateFcn, 0, _nsamples, 4, "MbdSig", "TwoTemplateFcn"); + twotemplate_fcn->SetLineColor(3); + twotemplate_fcn->SetParameters(1, 6, 1,8); + twotemplate_fcn->SetParName(0, "ampl"); + twotemplate_fcn->SetParName(1, "time"); + twotemplate_fcn->SetParName(2, "ampl2"); + twotemplate_fcn->SetParName(3, "time2"); + if (_verbose) { std::cout << "SHAPE " << _ch << std::endl; diff --git a/offline/packages/mbd/MbdSig.h b/offline/packages/mbd/MbdSig.h index e933f33392..a3ee986c33 100644 --- a/offline/packages/mbd/MbdSig.h +++ b/offline/packages/mbd/MbdSig.h @@ -111,10 +111,12 @@ class MbdSig // Double_t FitPulse(); void SetTimeOffset(const Double_t o) { f_time_offset = o; } Double_t TemplateFcn(const Double_t *x, const Double_t *par); + Double_t TwoTemplateFcn(const Double_t *x, const Double_t *par); TF1 *GetTemplateFcn() { return template_fcn; } void SetMinMaxFitTime(const Double_t mintime, const Double_t maxtime); void WritePedHist(); + void WriteChi2Hist(); void DrawWaveform(); /// Draw Subtracted Waveform void PadUpdate() const; @@ -144,6 +146,9 @@ class MbdSig Double_t f_integral{0.}; /** integral */ + Double_t f_chi2{0.}; + Double_t f_ndf{0.}; + TH1 *hRawPulse{nullptr}; //! TH1 *hSubPulse{nullptr}; //! TH1 *hpulse{nullptr}; //! @@ -182,19 +187,17 @@ class MbdSig Int_t template_npointsy{0}; Double_t template_begintime{0.}; Double_t template_endtime{0.}; - // Double_t template_min_good_amplitude{20.}; //! for template, in original units of waveform data - // Double_t template_max_good_amplitude{4080.}; //! for template, in original units of waveform data - // Double_t template_min_xrange{0.}; //! for template, in original units of waveform data - // Double_t template_max_xrange{0.}; //! for template, in original units of waveform data std::vector template_y; std::vector template_yrms; TF1 *template_fcn{nullptr}; + TF1 *twotemplate_fcn{nullptr}; Double_t fit_min_time{}; //! min time for fit, in original units of waveform data Double_t fit_max_time{}; //! max time for fit, in original units of waveform data std::ofstream *_pileupfile{nullptr}; // for writing out waveforms from prev. crossing pileup // use for calibrating out the tail from these events + TH1 *h_chi2ndf{nullptr}; //! for eval int _verbose{0}; }; From d7dc7f81f699f3c8861376349b808df1a972e55e Mon Sep 17 00:00:00 2001 From: mchiu-bnl Date: Tue, 27 Jan 2026 13:01:38 -0500 Subject: [PATCH 120/393] rabbit fixes --- offline/packages/mbd/MbdCalib.cc | 4 ++-- offline/packages/mbd/MbdSig.cc | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/offline/packages/mbd/MbdCalib.cc b/offline/packages/mbd/MbdCalib.cc index 1367b375c8..e76763c9b7 100644 --- a/offline/packages/mbd/MbdCalib.cc +++ b/offline/packages/mbd/MbdCalib.cc @@ -1683,7 +1683,7 @@ int MbdCalib::Write_CDB_Status(const std::string& dbfile) if (ifeech < 12 || ifeech >= MbdDefs::MBD_N_FEECH - 5) { - std::cout << ifeech << "\t" << std::hex << cdbttree->GetIntValue(ifeech, "status") << std::dec << std::endl; + std::cout << ifeech << "\t" << cdbttree->GetIntValue(ifeech, "status") << std::endl; } } @@ -1704,7 +1704,7 @@ int MbdCalib::Write_Status(const std::string& dbfile) cal_file.open(dbfile); for (int ifeech = 0; ifeech < MbdDefs::MBD_N_FEECH; ifeech++) { - cal_file << ifeech << "\t0x" << std::hex << _mbdstatus[ifeech] << std::dec << std::endl; + cal_file << ifeech << "\t" << _mbdstatus[ifeech] << std::endl; } cal_file.close(); diff --git a/offline/packages/mbd/MbdSig.cc b/offline/packages/mbd/MbdSig.cc index 72438e4046..65359d197a 100644 --- a/offline/packages/mbd/MbdSig.cc +++ b/offline/packages/mbd/MbdSig.cc @@ -145,8 +145,10 @@ MbdSig::~MbdSig() delete hAmpl; delete hTime; delete template_fcn; + delete twotemplate_fcn; delete ped_fcn; delete ped_tail; + delete h_chi2ndf; } void MbdSig::SetEventPed0PreSamp(const Int_t presample, const Int_t nsamps, const int max_samp) @@ -1167,10 +1169,14 @@ int MbdSig::FitTemplate( const Int_t sampmax ) // Get x and y of maximum Double_t x_at_max{-1.}; Double_t ymax{0.}; - if ( sampmax>=0 ) + if ( sampmax>0 ) { for (int isamp=sampmax-1; isamp<=sampmax+1; isamp++) { + if ( (isamp>=gSubPulse->GetN()) ) + { + continue; + } double adcval = gSubPulse->GetPointY(isamp); if ( adcval>ymax ) { From 49276961b21d048882ceefa3a4e6e48d2fd49cee Mon Sep 17 00:00:00 2001 From: mchiu-bnl Date: Tue, 27 Jan 2026 13:48:27 -0500 Subject: [PATCH 121/393] rabbit fixes part deux, plus added fiteval --- offline/packages/mbd/MbdCalib.cc | 8 +++++++- offline/packages/mbd/MbdEvent.cc | 6 ++++-- offline/packages/mbd/MbdReco.cc | 1 + offline/packages/mbd/MbdReco.h | 6 ++++-- offline/packages/mbd/MbdSig.cc | 8 ++++---- 5 files changed, 20 insertions(+), 9 deletions(-) diff --git a/offline/packages/mbd/MbdCalib.cc b/offline/packages/mbd/MbdCalib.cc index e76763c9b7..0ce5b4cd32 100644 --- a/offline/packages/mbd/MbdCalib.cc +++ b/offline/packages/mbd/MbdCalib.cc @@ -739,6 +739,12 @@ int MbdCalib::Download_Status(const std::string& dbase_location) int feech = -1; while (infile >> feech) { + if (feech < 0 || feech >= MbdDefs::MBD_N_FEECH) + { + std::cout << "ERROR, invalid FEECH " << feech << " in MBD status calibration" << std::endl; + _status = -4; + return _status; + } infile >> _mbdstatus[feech]; if (Verbosity() > 0) { @@ -750,7 +756,7 @@ int MbdCalib::Download_Status(const std::string& dbase_location) } infile.close(); } - + if ( _mbdstatus[0] == -1 ) { diff --git a/offline/packages/mbd/MbdEvent.cc b/offline/packages/mbd/MbdEvent.cc index 04287aae2c..ed5047f2a8 100644 --- a/offline/packages/mbd/MbdEvent.cc +++ b/offline/packages/mbd/MbdEvent.cc @@ -35,6 +35,7 @@ #include #include #include +#include MbdEvent::MbdEvent(const int cal_pass, const bool proc_charge) : _nsamples(MbdDefs::MAX_SAMPLES), @@ -366,8 +367,9 @@ int MbdEvent::End() { TDirectory *orig_dir = gDirectory; - TString savefname = "mbdeval_"; savefname += _runnum; savefname += ".root"; - _evalfile = std::make_unique(savefname,"RECREATE"); + // _doeval is overloaded with segment_number+1 + std::string savefname = std::format("mbdfiteval_{:08}-{:05}.root",_runnum,_doeval-1); + _evalfile = std::make_unique(savefname.c_str(),"RECREATE"); for (auto & sig : _mbdsig) { diff --git a/offline/packages/mbd/MbdReco.cc b/offline/packages/mbd/MbdReco.cc index 004e191e78..5b070929ac 100644 --- a/offline/packages/mbd/MbdReco.cc +++ b/offline/packages/mbd/MbdReco.cc @@ -65,6 +65,7 @@ int MbdReco::InitRun(PHCompositeNode *topNode) m_mbdevent->SetSim(_simflag); m_mbdevent->SetRawDstFlag(_rawdstflag); m_mbdevent->SetFitsOnly(_fitsonly); + m_mbdevent->set_doeval(_fiteval); m_mbdevent->InitRun(); return ret; diff --git a/offline/packages/mbd/MbdReco.h b/offline/packages/mbd/MbdReco.h index 6e00de68f3..eced3b89e9 100644 --- a/offline/packages/mbd/MbdReco.h +++ b/offline/packages/mbd/MbdReco.h @@ -34,10 +34,11 @@ class MbdReco : public SubsysReco int process_event(PHCompositeNode *topNode) override; int End(PHCompositeNode *topNode) override; - void DoOnlyFits() { _fitsonly = 1; } + void DoOnlyFits() { _fitsonly = 1; } + void DoFitEval(const int s) { _fiteval = s; } void SetCalPass(const int calpass) { _calpass = calpass; } void SetProcChargeCh(const bool s) { _always_process_charge = s; } - void SetMbdTrigOnly(const int m) { _mbdonly = m; } + void SetMbdTrigOnly(const int m) { _mbdonly = m; } private: int createNodes(PHCompositeNode *topNode); @@ -48,6 +49,7 @@ class MbdReco : public SubsysReco int _mbdonly{0}; // only use mbd triggers int _rawdstflag{0}; // dst with raw container int _fitsonly{0}; // stop reco after waveform fits (for DST_CALOFIT pass) + int _fiteval{0}; // overload with segment+1 float m_tres = 0.05; std::unique_ptr m_gaussian = nullptr; diff --git a/offline/packages/mbd/MbdSig.cc b/offline/packages/mbd/MbdSig.cc index 65359d197a..1118ba2e60 100644 --- a/offline/packages/mbd/MbdSig.cc +++ b/offline/packages/mbd/MbdSig.cc @@ -1296,10 +1296,10 @@ int MbdSig::FitTemplate( const Int_t sampmax ) //PadUpdate(); // Get fit parameters - f_ampl = template_fcn->GetParameter(0); - f_time = template_fcn->GetParameter(1); - f_chi2 = template_fcn->GetChisquare(); - f_ndf = template_fcn->GetNDF(); + f_ampl = twotemplate_fcn->GetParameter(0); + f_time = twotemplate_fcn->GetParameter(1); + f_chi2 = twotemplate_fcn->GetChisquare(); + f_ndf = twotemplate_fcn->GetNDF(); // Good fit if ( (f_chi2/f_ndf) < 5. && f_ndf>6. ) From 5c8076fe632e6fd3735b9c93724c4a899513327f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 27 Jan 2026 19:40:29 +0000 Subject: [PATCH 122/393] Fix missing final newline in docstring PR --- offline/packages/trackreco/PHSiliconSeedMerger.cc | 1 + offline/packages/trackreco/PHSiliconSeedMerger.h | 1 + 2 files changed, 2 insertions(+) diff --git a/offline/packages/trackreco/PHSiliconSeedMerger.cc b/offline/packages/trackreco/PHSiliconSeedMerger.cc index 8edb5816c3..6e012a606d 100644 --- a/offline/packages/trackreco/PHSiliconSeedMerger.cc +++ b/offline/packages/trackreco/PHSiliconSeedMerger.cc @@ -317,3 +317,4 @@ int PHSiliconSeedMerger::getNodes(PHCompositeNode* topNode) return Fun4AllReturnCodes::EVENT_OK; } + diff --git a/offline/packages/trackreco/PHSiliconSeedMerger.h b/offline/packages/trackreco/PHSiliconSeedMerger.h index 7ab50a44df..54d4758739 100644 --- a/offline/packages/trackreco/PHSiliconSeedMerger.h +++ b/offline/packages/trackreco/PHSiliconSeedMerger.h @@ -73,3 +73,4 @@ bool m_mvtxOnly{false}; }; #endif // PHSILICONSEEDMERGER_H + From 924e18e72bca44b23c29afe36fd47b143a238d52 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 27 Jan 2026 19:44:56 +0000 Subject: [PATCH 123/393] Fix missing final newline in docstring PR --- offline/packages/trackreco/PHSiliconSeedMerger.cc | 1 + offline/packages/trackreco/PHSiliconSeedMerger.h | 1 + 2 files changed, 2 insertions(+) diff --git a/offline/packages/trackreco/PHSiliconSeedMerger.cc b/offline/packages/trackreco/PHSiliconSeedMerger.cc index 6e012a606d..263fdd6b35 100644 --- a/offline/packages/trackreco/PHSiliconSeedMerger.cc +++ b/offline/packages/trackreco/PHSiliconSeedMerger.cc @@ -318,3 +318,4 @@ int PHSiliconSeedMerger::getNodes(PHCompositeNode* topNode) return Fun4AllReturnCodes::EVENT_OK; } + diff --git a/offline/packages/trackreco/PHSiliconSeedMerger.h b/offline/packages/trackreco/PHSiliconSeedMerger.h index db80f35259..fcd741e688 100644 --- a/offline/packages/trackreco/PHSiliconSeedMerger.h +++ b/offline/packages/trackreco/PHSiliconSeedMerger.h @@ -74,3 +74,4 @@ bool m_mvtxOnly{false}; #endif // PHSILICONSEEDMERGER_H + From 34a2897407c7c5b732feb420a7a3eb76a3fc1af4 Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Tue, 27 Jan 2026 22:17:55 +0000 Subject: [PATCH 124/393] =?UTF-8?q?=F0=9F=93=9D=20Add=20docstrings=20to=20?= =?UTF-8?q?`function=5Ffit`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Docstrings generation was requested by @pinkenburg. * https://github.com/sPHENIX-Collaboration/coresoftware/pull/4138#issuecomment-3795382670 The following files were modified: * `simulation/g4simulation/g4main/PHG4TruthTrackingAction.cc` * `simulation/g4simulation/g4main/PHG4TruthTrackingAction.h` --- .../g4main/PHG4TruthTrackingAction.cc | 25 +++++++- .../g4main/PHG4TruthTrackingAction.h | 64 ++++++++++++++++++- 2 files changed, 87 insertions(+), 2 deletions(-) diff --git a/simulation/g4simulation/g4main/PHG4TruthTrackingAction.cc b/simulation/g4simulation/g4main/PHG4TruthTrackingAction.cc index da01d9d5e3..330167495d 100644 --- a/simulation/g4simulation/g4main/PHG4TruthTrackingAction.cc +++ b/simulation/g4simulation/g4main/PHG4TruthTrackingAction.cc @@ -305,6 +305,17 @@ PHG4Particle* PHG4TruthTrackingAction::AddParticle(PHG4TruthInfoContainer& truth return truth.AddParticle(trackid, ti)->second; } +/** + * @brief Create or retrieve a truth vertex for a Geant4 track keyed by position and production process. + * + * Uses the track vertex position combined with the mapped MC production process to look up an existing + * vertex or create a new PHG4VtxPoint and register it in the truth container. The vertex index is chosen + * positive for primary tracks and negative for secondaries. + * + * @param truth Container in which to find or register the vertex. + * @param track Geant4 track whose production vertex and creator process determine the vertex key. + * @return PHG4VtxPoint* Pointer to the vertex instance stored in the truth container. + */ PHG4VtxPoint* PHG4TruthTrackingAction::AddVertex(PHG4TruthInfoContainer& truth, const G4Track& track) { G4ThreeVector v = track.GetVertexPosition(); @@ -334,6 +345,18 @@ PHG4VtxPoint* PHG4TruthTrackingAction::AddVertex(PHG4TruthInfoContainer& truth, return truth.AddVertex(vtxindex, vtxpt)->second; } +/** + * @brief Determine whether a PHG4Particle should be considered an sPHENIX primary. + * + * Evaluates the particle's production vertex, PDG id longevity, and ancestry to decide + * if it originates as an sPHENIX primary (produced as a primary or from a decay and + * having no long-lived ancestor produced by material interactions). + * + * @param truth Truth container used to look up particle parents and production vertices. + * @param particle Particle to evaluate. + * @return true if the particle is classified as an sPHENIX primary, `false` otherwise. + * + */ bool PHG4TruthTrackingAction::issPHENIXPrimary(PHG4TruthInfoContainer& truth, PHG4Particle* particle) const { PHG4VtxPoint* vtx = truth.GetVtx(particle->get_vtx_id()); @@ -453,4 +476,4 @@ bool PHG4TruthTrackingAction::isLongLived(int pid) const default: return false; } -} +} \ No newline at end of file diff --git a/simulation/g4simulation/g4main/PHG4TruthTrackingAction.h b/simulation/g4simulation/g4main/PHG4TruthTrackingAction.h index 8025d7c9bb..0602025889 100644 --- a/simulation/g4simulation/g4main/PHG4TruthTrackingAction.h +++ b/simulation/g4simulation/g4main/PHG4TruthTrackingAction.h @@ -19,6 +19,68 @@ class PHG4TruthEventAction; class PHG4Particle; class PHG4VtxPoint; +/** + * Construct a PHG4TruthTrackingAction associated with an event action. + * @param eventAction Pointer to the owning PHG4TruthEventAction used to record per-event truth information. + */ + +/** + * Destroy the PHG4TruthTrackingAction. + */ + +/** + * Handle actions to perform before Geant4 begins tracking a G4 track. + * @param track The Geant4 track about to be processed. + */ + +/** + * Handle actions to perform after Geant4 finishes tracking a G4 track. + * @param track The Geant4 track that has just been processed. + */ + +/** + * Set required node/interface pointers from the given top-level node. + * @param topNode Pointer to the PHCompositeNode root from which required I/O nodes are retrieved. + * @returns Zero on success, non-zero on failure. + */ + +/** + * Reset per-event state using nodes found under the given composite node. + * @param topNode Pointer to the PHCompositeNode for the current event. + * @returns Zero on success, non-zero on failure. + */ + +/** + * Create or update a truth particle entry corresponding to the provided Geant4 track. + * @param truth Container to which the particle entry will be added or updated. + * @param track Geant4 track from which particle information is derived. + * @returns Pointer to the created or updated PHG4Particle. + */ + +/** + * Create or update a truth vertex entry corresponding to the provided Geant4 track. + * @param truth Container to which the vertex entry will be added or updated. + * @param track Geant4 track whose production point will be recorded as a vertex. + * @returns Pointer to the created or updated PHG4VtxPoint. + */ + +/** + * Determine whether a particle type is considered long-lived for truth-building. + * @param pid Particle PDG identifier. + * @returns `true` if the particle with the given PDG id is treated as long-lived, `false` otherwise. + */ + +/** + * Determine whether a particle should be flagged as an sPHENIX primary. + * @param truth Truth information container used to evaluate primary status. + * @param particle Particle to evaluate. + * @returns `true` if the particle is considered an sPHENIX primary, `false` otherwise. + */ + +/** + * Update the internal upstream G4 particle stack when processing a new Geant4 track. + * @param track Geant4 track used to update parent/ancestor particle bookkeeping. + */ class PHG4TruthTrackingAction : public PHG4TrackingAction { public: @@ -73,4 +135,4 @@ class PHG4TruthTrackingAction : public PHG4TrackingAction ///@} }; -#endif +#endif \ No newline at end of file From a9adfb154472086a9ee43dbcbe047ff1ce48c84e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 27 Jan 2026 22:18:12 +0000 Subject: [PATCH 125/393] Fix missing final newline in docstring PR --- simulation/g4simulation/g4main/PHG4TruthTrackingAction.cc | 2 +- simulation/g4simulation/g4main/PHG4TruthTrackingAction.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/simulation/g4simulation/g4main/PHG4TruthTrackingAction.cc b/simulation/g4simulation/g4main/PHG4TruthTrackingAction.cc index 330167495d..614712d4d3 100644 --- a/simulation/g4simulation/g4main/PHG4TruthTrackingAction.cc +++ b/simulation/g4simulation/g4main/PHG4TruthTrackingAction.cc @@ -476,4 +476,4 @@ bool PHG4TruthTrackingAction::isLongLived(int pid) const default: return false; } -} \ No newline at end of file +} diff --git a/simulation/g4simulation/g4main/PHG4TruthTrackingAction.h b/simulation/g4simulation/g4main/PHG4TruthTrackingAction.h index 0602025889..99e0c4669e 100644 --- a/simulation/g4simulation/g4main/PHG4TruthTrackingAction.h +++ b/simulation/g4simulation/g4main/PHG4TruthTrackingAction.h @@ -135,4 +135,4 @@ class PHG4TruthTrackingAction : public PHG4TrackingAction ///@} }; -#endif \ No newline at end of file +#endif From f493c6eb0512565fb0ba363549ac1d5e89814e21 Mon Sep 17 00:00:00 2001 From: mchiu-bnl Date: Tue, 27 Jan 2026 22:01:06 -0500 Subject: [PATCH 126/393] aborts run if calibration is missing for doing fits --- offline/packages/mbd/MbdCalib.cc | 25 +++++++++++++++++++++++++ offline/packages/mbd/MbdEvent.cc | 14 ++++++++++---- offline/packages/mbd/MbdReco.cc | 7 ++++++- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/offline/packages/mbd/MbdCalib.cc b/offline/packages/mbd/MbdCalib.cc index 0ce5b4cd32..a6e5c773b1 100644 --- a/offline/packages/mbd/MbdCalib.cc +++ b/offline/packages/mbd/MbdCalib.cc @@ -80,6 +80,11 @@ int MbdCalib::Download_All() if (!_rc->FlagExist("MBD_CALDIR")) { std::string sampmax_url = _cdb->getUrl("MBD_SAMPMAX"); + if ( sampmax_url.empty() ) + { + std::cerr << "ERROR, MBD_SAMPMAX missing" << std::endl; + return -1; + } if (Verbosity() > 0) { std::cout << "sampmax_url " << sampmax_url << std::endl; @@ -87,6 +92,11 @@ int MbdCalib::Download_All() Download_SampMax(sampmax_url); std::string status_url = _cdb->getUrl("MBD_STATUS"); + if ( status_url.empty() ) + { + std::cerr << "ERROR, MBD_STATUS missing" << std::endl; + return -1; + } if (Verbosity() > 0) { std::cout << "status_url " << status_url << std::endl; @@ -96,6 +106,11 @@ int MbdCalib::Download_All() if ( !_rawdstflag ) { std::string ped_url = _cdb->getUrl("MBD_PED"); + if ( ped_url.empty() ) + { + std::cerr << "ERROR, MBD_PED missing" << std::endl; + return -1; + } if (Verbosity() > 0) { std::cout << "ped_url " << ped_url << std::endl; @@ -104,6 +119,11 @@ int MbdCalib::Download_All() std::string pileup_url = _cdb->getUrl("MBD_PILEUP"); + if ( pileup_url.empty() ) + { + std::cerr << "ERROR, MBD_PILEUP missing" << std::endl; + return -1; + } if (Verbosity() > 0) { std::cout << "pileup_url " << pileup_url << std::endl; @@ -113,6 +133,11 @@ int MbdCalib::Download_All() if (do_templatefit) { std::string shape_url = _cdb->getUrl("MBD_SHAPES"); + if ( shape_url.empty() ) + { + std::cerr << "ERROR, MBD_SHAPES missing" << std::endl; + return -1; + } if (Verbosity() > 0) { std::cout << "shape_url " << shape_url << std::endl; diff --git a/offline/packages/mbd/MbdEvent.cc b/offline/packages/mbd/MbdEvent.cc index ed5047f2a8..0ed3886a60 100644 --- a/offline/packages/mbd/MbdEvent.cc +++ b/offline/packages/mbd/MbdEvent.cc @@ -151,7 +151,11 @@ int MbdEvent::InitRun() _mbdcal->SetRawDstFlag( _rawdstflag ); _mbdcal->SetFitsOnly( _fitsonly ); - _mbdcal->Download_All(); + int status = _mbdcal->Download_All(); + if ( status == -1 ) + { + return Fun4AllReturnCodes::ABORTRUN; + } if ( _simflag == 0 ) // do following for real data { @@ -810,12 +814,14 @@ int MbdEvent::ProcessRawContainer(MbdRawContainer *bbcraws, MbdPmtContainer *bbc // or have time channels marked as bad // or have always_process_charge set to 1 (useful for threshold studies) - m_pmttq[pmtch] = bbcraws->get_pmt(pmtch)->get_qtdc(); - // In Run 1 (runs before 40000), we didn't set hardware thresholds, and instead set a software threshold of 0.25 if ( ((bbcraws->get_pmt(pmtch)->get_adc() < (_mbdcal->get_qgain(pmtch) * 0.25)) && (_runnum < 40000)) || std::fabs(_mbdcal->get_tq0(pmtch))>100. ) { - m_qtdc[pmtch] = std::numeric_limits::quiet_NaN(); + m_pmttq[pmtch] = std::numeric_limits::quiet_NaN(); + } + else + { + m_pmttq[pmtch] = bbcraws->get_pmt(pmtch)->get_qtdc(); } if ( !std::isnan(m_pmttq[pmtch]) ) diff --git a/offline/packages/mbd/MbdReco.cc b/offline/packages/mbd/MbdReco.cc index 5b070929ac..26f53ba70c 100644 --- a/offline/packages/mbd/MbdReco.cc +++ b/offline/packages/mbd/MbdReco.cc @@ -61,12 +61,17 @@ int MbdReco::InitRun(PHCompositeNode *topNode) } int ret = getNodes(topNode); + if ( ret != Fun4AllReturnCodes::EVENT_OK ) + { + return ret; + } m_mbdevent->SetSim(_simflag); m_mbdevent->SetRawDstFlag(_rawdstflag); m_mbdevent->SetFitsOnly(_fitsonly); m_mbdevent->set_doeval(_fiteval); - m_mbdevent->InitRun(); + + ret = m_mbdevent->InitRun(); return ret; } From 8bc0f1f7ceaa9e5342674eca1691d8db28bc0628 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Wed, 28 Jan 2026 09:06:19 -0500 Subject: [PATCH 127/393] make function const --- offline/packages/trackreco/PHActsSiliconSeeding.cc | 2 +- offline/packages/trackreco/PHActsSiliconSeeding.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/offline/packages/trackreco/PHActsSiliconSeeding.cc b/offline/packages/trackreco/PHActsSiliconSeeding.cc index fb1c4b6de9..aba61d0943 100644 --- a/offline/packages/trackreco/PHActsSiliconSeeding.cc +++ b/offline/packages/trackreco/PHActsSiliconSeeding.cc @@ -1745,7 +1745,7 @@ double PHActsSiliconSeeding::normPhi2Pi(const double phi) return returnPhi; } -float PHActsSiliconSeeding::getPhiFromBeamSpot(float clusy, float clusx) +float PHActsSiliconSeeding::getPhiFromBeamSpot(float clusy, float clusx) const { // Calculate the phi value for (clusx, clusy) relative to the beam spot (x,y) position diff --git a/offline/packages/trackreco/PHActsSiliconSeeding.h b/offline/packages/trackreco/PHActsSiliconSeeding.h index f37937903b..506f9c225c 100644 --- a/offline/packages/trackreco/PHActsSiliconSeeding.h +++ b/offline/packages/trackreco/PHActsSiliconSeeding.h @@ -253,7 +253,7 @@ class PHActsSiliconSeeding : public SubsysReco short int getCrossingIntt(TrackSeed &si_track); std::vector getInttCrossings(TrackSeed &si_track); - float getPhiFromBeamSpot(float clusy, float clusx); + float getPhiFromBeamSpot(float clusy, float clusx) const; void createHistograms(); void writeHistograms(); From 8fb707e05cbc56c6c6f81f8b83a5b6ecbf6c15d0 Mon Sep 17 00:00:00 2001 From: Hao-Ren Jheng Date: Wed, 28 Jan 2026 11:35:59 -0500 Subject: [PATCH 128/393] Revert "use short int for vertex beam crossing" This reverts commit 2963c36785cc61b40722e0139177340f09977c7a. --- offline/packages/globalvertex/MbdVertex.h | 4 ++-- offline/packages/globalvertex/MbdVertexv2.h | 6 +++--- offline/packages/globalvertex/SvtxVertex.h | 3 --- offline/packages/globalvertex/SvtxVertex_v2.h | 6 +++--- offline/packages/globalvertex/Vertex.h | 4 ++-- 5 files changed, 10 insertions(+), 13 deletions(-) diff --git a/offline/packages/globalvertex/MbdVertex.h b/offline/packages/globalvertex/MbdVertex.h index bda5c74597..6d0900b768 100644 --- a/offline/packages/globalvertex/MbdVertex.h +++ b/offline/packages/globalvertex/MbdVertex.h @@ -36,8 +36,8 @@ class MbdVertex : public Vertex virtual float get_z_err() const override { return std::numeric_limits::quiet_NaN(); } virtual void set_z_err(float) override {} - virtual short int get_beam_crossing() const override { return std::numeric_limits::max(); } - virtual void set_beam_crossing(short int) override {} + virtual unsigned int get_beam_crossing() const override { return std::numeric_limits::max(); } + virtual void set_beam_crossing(unsigned int) override {} virtual void set_bbc_ns(int, int, float, float) override {} virtual int get_bbc_npmt(int) const override { return std::numeric_limits::max(); } diff --git a/offline/packages/globalvertex/MbdVertexv2.h b/offline/packages/globalvertex/MbdVertexv2.h index d0aac0f70b..bee34059e4 100644 --- a/offline/packages/globalvertex/MbdVertexv2.h +++ b/offline/packages/globalvertex/MbdVertexv2.h @@ -44,12 +44,12 @@ class MbdVertexv2 : public MbdVertex float get_position(unsigned int coor) const override; - short int get_beam_crossing() const override { return _bco; } - void set_beam_crossing(short int bco) override { _bco = bco; } + unsigned int get_beam_crossing() const override { return _bco; } + void set_beam_crossing(unsigned int bco) override { _bco = bco; } private: unsigned int _id{std::numeric_limits::max()}; //< unique identifier within container - short int _bco{std::numeric_limits::max()}; //< global bco + unsigned int _bco{std::numeric_limits::max()}; //< global bco float _t{std::numeric_limits::quiet_NaN()}; //< collision time float _t_err{std::numeric_limits::quiet_NaN()}; //< collision time uncertainty float _z{std::numeric_limits::quiet_NaN()}; //< collision position z diff --git a/offline/packages/globalvertex/SvtxVertex.h b/offline/packages/globalvertex/SvtxVertex.h index 5006784f55..cd9c77454c 100644 --- a/offline/packages/globalvertex/SvtxVertex.h +++ b/offline/packages/globalvertex/SvtxVertex.h @@ -56,9 +56,6 @@ class SvtxVertex : public Vertex virtual float get_error(unsigned int, unsigned int) const override { return std::numeric_limits::quiet_NaN(); } virtual void set_error(unsigned int, unsigned int, float) override {} - virtual short int get_beam_crossing() const override { return std::numeric_limits::max(); } - virtual void set_beam_crossing(short int) override {} - // // associated track ids methods // diff --git a/offline/packages/globalvertex/SvtxVertex_v2.h b/offline/packages/globalvertex/SvtxVertex_v2.h index d1bf04e0b4..24ccbfc0ca 100644 --- a/offline/packages/globalvertex/SvtxVertex_v2.h +++ b/offline/packages/globalvertex/SvtxVertex_v2.h @@ -54,8 +54,8 @@ class SvtxVertex_v2 : public SvtxVertex float get_error(unsigned int i, unsigned int j) const override; //< get vertex error covar void set_error(unsigned int i, unsigned int j, float value) override; //< set vertex error covar - short int get_beam_crossing() const override { return _beamcrossing; } - void set_beam_crossing(short int cross) override { _beamcrossing = cross; } + unsigned int get_beam_crossing() const override { return _beamcrossing; } + void set_beam_crossing(unsigned int cross) override { _beamcrossing = cross; } // // associated track ids methods @@ -82,7 +82,7 @@ class SvtxVertex_v2 : public SvtxVertex unsigned int _ndof{std::numeric_limits::max()}; //< degrees of freedom float _err[6]{}; //< error covariance matrix (packed storage) (+/- cm^2) std::set _track_ids; //< list of track ids - short int _beamcrossing{std::numeric_limits::max()}; + unsigned int _beamcrossing{std::numeric_limits::max()}; ClassDefOverride(SvtxVertex_v2, 2); }; diff --git a/offline/packages/globalvertex/Vertex.h b/offline/packages/globalvertex/Vertex.h index e475bfb95d..7bbfa5f381 100644 --- a/offline/packages/globalvertex/Vertex.h +++ b/offline/packages/globalvertex/Vertex.h @@ -62,8 +62,8 @@ class Vertex : public PHObject virtual void set_error(unsigned int /*i*/, unsigned int /*j*/, float /*value*/) {} // beam crossing methods - virtual short int get_beam_crossing() const { return std::numeric_limits::max(); } - virtual void set_beam_crossing(short int) {} + virtual unsigned int get_beam_crossing() const { return std::numeric_limits::max(); } + virtual void set_beam_crossing(unsigned int) {} // bbcvertex methods virtual void set_bbc_ns(int, int, float, float) {} From 71c84483e3f9a8c8153b4767cdbe3d90313b8064 Mon Sep 17 00:00:00 2001 From: Anthony Denis Frawley Date: Wed, 28 Jan 2026 14:12:00 -0500 Subject: [PATCH 129/393] Coderabbit was correct, bug fix. --- offline/packages/trackreco/PHActsSiliconSeeding.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/offline/packages/trackreco/PHActsSiliconSeeding.cc b/offline/packages/trackreco/PHActsSiliconSeeding.cc index fb1c4b6de9..c7f44d396b 100644 --- a/offline/packages/trackreco/PHActsSiliconSeeding.cc +++ b/offline/packages/trackreco/PHActsSiliconSeeding.cc @@ -822,7 +822,8 @@ std::vector PHActsSiliconSeeding::findMatches( avgtripletx += std::cos(getPhiFromBeamSpot(pos(1), pos(0))); avgtriplety += std::sin(getPhiFromBeamSpot(pos(1), pos(0))); } - float avgtripletphi = getPhiFromBeamSpot(avgtriplety, avgtripletx); + + float avgtripletphi = std::atan2(avgtriplety, avgtripletx); std::vector dummykeys = keys; std::vector dummyclusters = clusters; @@ -1159,7 +1160,7 @@ std::vector> PHActsSiliconSeeding::iterateLayers( avgtriplety += std::sin(getPhiFromBeamSpot(pos(1), pos(0))); } - float avgtripletphi = getPhiFromBeamSpot(avgtriplety, avgtripletx); + float avgtripletphi = std::atan2(avgtriplety, avgtripletx); int layer34timebucket = std::numeric_limits::max(); for (const auto& key : keys) From 918880db72cf231d36fa2d565849075c4353c76d Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Wed, 28 Jan 2026 15:52:43 -0500 Subject: [PATCH 130/393] CaloValid - O+O Update - Updated downscale factors for the calorimeters and mbd by the ratio of nucleons: OO / AuAu - Add "OO" as a m_species option - Updated RunnumberRange to place temporary first and last for OO as well as update the last runnumber for proton+proton. --- offline/QA/Calorimeters/CaloValid.cc | 28 ++++++++++++++++++++++++ offline/framework/phool/RunnumberRange.h | 4 +++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/offline/QA/Calorimeters/CaloValid.cc b/offline/QA/Calorimeters/CaloValid.cc index c51f75c200..54598ceaf0 100644 --- a/offline/QA/Calorimeters/CaloValid.cc +++ b/offline/QA/Calorimeters/CaloValid.cc @@ -117,6 +117,14 @@ int CaloValid::InitRun(PHCompositeNode* topNode) std::cout << "This run is from Run-3 Au+Au.\n"; } } + else if (runnumber >= RunnumberRange::RUN3OO_FIRST && runnumber <= RunnumberRange::RUN3OO_LAST) + { + m_species = "OO"; + if (Verbosity() > 0) + { + std::cout << "This run is from Run-3 O+O.\n"; + } + } else { if (Verbosity() > 0) @@ -216,6 +224,26 @@ int CaloValid::process_towers(PHCompositeNode* topNode) ohcal_highhit_threshold = 3.0; ihcal_highhit_threshold = 3.0; } + else if (m_species == "OO") + { + // Scale by the ratio of nucleons: OO/AuAu + float scale_factor = 16. / 197.; + + emcaldownscale = (1350000. / 800.) * scale_factor; + ihcaldownscale = (55000. / 300.) * scale_factor; + ohcaldownscale = (265000. / 600.) * scale_factor; + mbddownscale = 2800.0 * scale_factor; + adc_threshold_hcal = 30; + adc_threshold_emcal = 70; + + emcal_hit_threshold = 0.5; // GeV + ohcal_hit_threshold = 0.5; + ihcal_hit_threshold = 0.25; + + emcal_highhit_threshold = 3.0; + ohcal_highhit_threshold = 3.0; + ihcal_highhit_threshold = 3.0; + } else { emcaldownscale = 100000. / 800.; diff --git a/offline/framework/phool/RunnumberRange.h b/offline/framework/phool/RunnumberRange.h index a9a860e583..5d14a79350 100644 --- a/offline/framework/phool/RunnumberRange.h +++ b/offline/framework/phool/RunnumberRange.h @@ -12,7 +12,9 @@ namespace RunnumberRange static const int RUN3AUAU_FIRST = 66457; static const int RUN3AUAU_LAST = 78954; static const int RUN3PP_FIRST = 79146; // first beam data - static const int RUN3PP_LAST = 100000; + static const int RUN3PP_LAST = 81668; + static const int RUN3OO_FIRST = 82300; // TEMP (to be updated once OO starts) + static const int RUN3OO_LAST = 200000; } #endif From 3c966d3934fc23cb1be61bef7171d51167de2140 Mon Sep 17 00:00:00 2001 From: Hao-Ren Jheng Date: Wed, 28 Jan 2026 17:52:24 -0500 Subject: [PATCH 131/393] New version of SvtxVertex, MbdVertex, and GlovalVertex to use short instead of unsigned int --- offline/packages/globalvertex/GlobalVertex.h | 4 +- .../packages/globalvertex/GlobalVertexv2.h | 37 ++- .../packages/globalvertex/GlobalVertexv3.cc | 231 ++++++++++++++++++ .../packages/globalvertex/GlobalVertexv3.h | 73 ++++++ .../globalvertex/GlobalVertexv3LinkDef.h | 5 + offline/packages/globalvertex/Makefile.am | 9 + offline/packages/globalvertex/MbdVertex.h | 8 +- offline/packages/globalvertex/MbdVertexv2.h | 50 +++- offline/packages/globalvertex/MbdVertexv3.cc | 60 +++++ offline/packages/globalvertex/MbdVertexv3.h | 60 +++++ .../globalvertex/MbdVertexv3LinkDef.h | 5 + offline/packages/globalvertex/SvtxVertex_v2.h | 48 +++- .../packages/globalvertex/SvtxVertex_v3.cc | 113 +++++++++ offline/packages/globalvertex/SvtxVertex_v3.h | 89 +++++++ .../globalvertex/SvtxVertex_v3LinkDef.h | 5 + offline/packages/globalvertex/Vertex.h | 4 +- 16 files changed, 788 insertions(+), 13 deletions(-) create mode 100644 offline/packages/globalvertex/GlobalVertexv3.cc create mode 100644 offline/packages/globalvertex/GlobalVertexv3.h create mode 100644 offline/packages/globalvertex/GlobalVertexv3LinkDef.h create mode 100644 offline/packages/globalvertex/MbdVertexv3.cc create mode 100644 offline/packages/globalvertex/MbdVertexv3.h create mode 100644 offline/packages/globalvertex/MbdVertexv3LinkDef.h create mode 100644 offline/packages/globalvertex/SvtxVertex_v3.cc create mode 100644 offline/packages/globalvertex/SvtxVertex_v3.h create mode 100644 offline/packages/globalvertex/SvtxVertex_v3LinkDef.h diff --git a/offline/packages/globalvertex/GlobalVertex.h b/offline/packages/globalvertex/GlobalVertex.h index 2a42abbba6..3124cea282 100644 --- a/offline/packages/globalvertex/GlobalVertex.h +++ b/offline/packages/globalvertex/GlobalVertex.h @@ -78,8 +78,8 @@ class GlobalVertex : public PHObject virtual float get_error(unsigned int /*i*/, unsigned int /*j*/) const { return std::numeric_limits::quiet_NaN(); } virtual void set_error(unsigned int /*i*/, unsigned int /*j*/, float /*value*/) { return; } - virtual unsigned int get_beam_crossing() const { return std::numeric_limits::max(); } - virtual void set_beam_crossing(unsigned int) { return; } + virtual short int get_beam_crossing() const { return std::numeric_limits::max(); } + virtual void set_beam_crossing(short int) { return; } virtual bool empty_vtxs() const { return true; } virtual size_t size_vtxs() const { return 0; } diff --git a/offline/packages/globalvertex/GlobalVertexv2.h b/offline/packages/globalvertex/GlobalVertexv2.h index 06a4d637f0..4c7a077df7 100644 --- a/offline/packages/globalvertex/GlobalVertexv2.h +++ b/offline/packages/globalvertex/GlobalVertexv2.h @@ -29,8 +29,22 @@ class GlobalVertexv2 : public GlobalVertex unsigned int get_id() const override { return _id; } void set_id(unsigned int id) override { _id = id; } - unsigned int get_beam_crossing() const override { return _bco; } - void set_beam_crossing(unsigned int bco) override { _bco = bco; } + short int get_beam_crossing() const override + { + return rollover_from_unsignedint(_bco); + } + + void set_beam_crossing(short int bco) override + { + if (bco == short_int_max) + { + _bco = std::numeric_limits::max(); + return; + } + + const short int bco_ro = rollover_short(bco); + _bco = static_cast(bco_ro); + } float get_t() const override; float get_t_err() const override; @@ -65,6 +79,25 @@ class GlobalVertexv2 : public GlobalVertex GlobalVertex::VertexIter end_vertexes() override { return _vtxs.end(); } private: + static constexpr short int short_int_max = std::numeric_limits::max(); + + static short int rollover_short(short int bco) + { + if (bco == short_int_max) return short_int_max; + if (bco >= 0) return bco; + return static_cast(static_cast(short_int_max) + static_cast(bco)); + } + + static short int rollover_from_unsignedint(unsigned int bco) + { + if (bco == std::numeric_limits::max()) return short_int_max; + if (bco <= static_cast(short_int_max)) return static_cast(bco); + + const short int bco_ro = static_cast(static_cast(bco)); + if (bco_ro >= 0) return bco_ro; + return rollover_short(bco_ro); + } + unsigned int _id{std::numeric_limits::max()}; unsigned int _bco{std::numeric_limits::max()}; //< global bco std::map _vtxs; //< list of vtxs diff --git a/offline/packages/globalvertex/GlobalVertexv3.cc b/offline/packages/globalvertex/GlobalVertexv3.cc new file mode 100644 index 0000000000..1504a7cd3d --- /dev/null +++ b/offline/packages/globalvertex/GlobalVertexv3.cc @@ -0,0 +1,231 @@ +#include "GlobalVertexv3.h" + +#include + +GlobalVertexv3::GlobalVertexv3(const unsigned int id) + : _id(id) +{ +} + +GlobalVertexv3::~GlobalVertexv3() +{ + GlobalVertexv3::Reset(); +} + +void GlobalVertexv3::Reset() +{ + for (auto& _vtx : _vtxs) + { + for (const auto* vertex : _vtx.second) + { + delete vertex; + } + } + _vtxs.clear(); +} + +void GlobalVertexv3::identify(std::ostream& os) const +{ + os << "---GlobalVertexv3-----------------------" << std::endl; + + os << " list of vtx ids: " << std::endl; + for (ConstVertexIter iter = begin_vertexes(); iter != end_vertexes(); ++iter) + { + os << " Vertex type " << iter->first << " has " << iter->second.size() + << " vertices associated to it" << std::endl; + for (const auto& vertex : iter->second) + { + vertex->identify(); + } + } + + os << "-----------------------------------------------" << std::endl; +} + +int GlobalVertexv3::isValid() const +{ + if (_vtxs.empty()) + { + return 0; + } + return 1; +} + +void GlobalVertexv3::insert_vtx(GlobalVertex::VTXTYPE type, const Vertex* vertex) +{ + auto it = _vtxs.find(type); + if (it == _vtxs.end()) + { + VertexVector vector; + vector.push_back(vertex); + _vtxs.insert(std::make_pair(type, vector)); + return; + } + + it->second.push_back(vertex); +} + +void GlobalVertexv3::clone_insert_vtx(GlobalVertex::VTXTYPE type, const Vertex* vertex) +{ + auto it = _vtxs.find(type); + Vertex* clone = dynamic_cast(vertex->CloneMe()); + if (it == _vtxs.end()) + { + VertexVector vector; + vector.push_back(clone); + _vtxs.insert(std::make_pair(type, vector)); + return; + } + + it->second.push_back(clone); +} + +size_t GlobalVertexv3::count_vtxs(GlobalVertex::VTXTYPE type) const +{ + auto it = _vtxs.find(type); + if (it == _vtxs.end()) + { + return 0; + } + + return it->second.size(); +} + +float GlobalVertexv3::get_t() const +{ + auto it = _vtxs.find(GlobalVertex::VTXTYPE::MBD); + if (it == _vtxs.end()) + { + return std::numeric_limits::quiet_NaN(); + } + + return it->second[0]->get_t(); +} + +float GlobalVertexv3::get_t_err() const +{ + auto it = _vtxs.find(GlobalVertex::VTXTYPE::MBD); + if (it == _vtxs.end()) + { + return std::numeric_limits::quiet_NaN(); + } + + return it->second[0]->get_t_err(); +} + +float GlobalVertexv3::get_x() const { return get_position(0); } +float GlobalVertexv3::get_y() const { return get_position(1); } +float GlobalVertexv3::get_z() const { return get_position(2); } + +float GlobalVertexv3::get_position(unsigned int coor) const +{ + auto svtxit = _vtxs.find(GlobalVertex::VTXTYPE::SVTX); + if (svtxit == _vtxs.end()) + { + auto mbdit = _vtxs.find(GlobalVertex::VTXTYPE::MBD); + if (mbdit == _vtxs.end()) + { + auto caloit = _vtxs.find(GlobalVertex::VTXTYPE::CALO); + if (caloit == _vtxs.end()) + { + return std::numeric_limits::quiet_NaN(); + } + return caloit->second[0]->get_position(coor); + } + return mbdit->second[0]->get_position(coor); + } + + GlobalVertex::VertexVector trackvertices = svtxit->second; + size_t mosttracks = 0; + float pos = std::numeric_limits::quiet_NaN(); + for (const auto* vertex : trackvertices) + { + if (vertex->size_tracks() > mosttracks) + { + mosttracks = vertex->size_tracks(); + pos = vertex->get_position(coor); + } + } + + return pos; +} + +float GlobalVertexv3::get_chisq() const +{ + auto svtxit = _vtxs.find(GlobalVertex::VTXTYPE::SVTX); + if (svtxit == _vtxs.end()) + { + return std::numeric_limits::quiet_NaN(); + } + + GlobalVertex::VertexVector trackvertices = svtxit->second; + size_t mosttracks = 0; + float chisq = std::numeric_limits::quiet_NaN(); + for (const auto* vertex : trackvertices) + { + if (vertex->size_tracks() > mosttracks) + { + mosttracks = vertex->size_tracks(); + chisq = vertex->get_chisq(); + } + } + + return chisq; +} + +unsigned int GlobalVertexv3::get_ndof() const +{ + auto svtxit = _vtxs.find(GlobalVertex::VTXTYPE::SVTX); + if (svtxit == _vtxs.end()) + { + return std::numeric_limits::max(); + } + + GlobalVertex::VertexVector trackvertices = svtxit->second; + size_t mosttracks = 0; + unsigned int ndf = std::numeric_limits::max(); + for (const auto* vertex : trackvertices) + { + if (vertex->size_tracks() > mosttracks) + { + mosttracks = vertex->size_tracks(); + ndf = vertex->get_ndof(); + } + } + + return ndf; +} + +float GlobalVertexv3::get_error(unsigned int i, unsigned int j) const +{ + auto svtxit = _vtxs.find(GlobalVertex::VTXTYPE::SVTX); + if (svtxit == _vtxs.end()) + { + auto mbdit = _vtxs.find(GlobalVertex::VTXTYPE::MBD); + if (mbdit == _vtxs.end()) + { + return std::numeric_limits::quiet_NaN(); + } + // MBD only has z error defined + if (i == 2 && j == 2) + { + return mbdit->second[0]->get_z_err(); + } + + return std::numeric_limits::quiet_NaN(); + } + + GlobalVertex::VertexVector trackvertices = svtxit->second; + size_t mosttracks = 0; + float err = std::numeric_limits::quiet_NaN(); + for (const auto* vertex : trackvertices) + { + if (vertex->size_tracks() > mosttracks) + { + mosttracks = vertex->size_tracks(); + err = vertex->get_error(i, j); + } + } + + return err; +} diff --git a/offline/packages/globalvertex/GlobalVertexv3.h b/offline/packages/globalvertex/GlobalVertexv3.h new file mode 100644 index 0000000000..c89e51e5c9 --- /dev/null +++ b/offline/packages/globalvertex/GlobalVertexv3.h @@ -0,0 +1,73 @@ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef GLOBALVERTEX_GLOBALVERTEXV3_H +#define GLOBALVERTEX_GLOBALVERTEXV3_H + +#include "GlobalVertex.h" + +#include // for size_t +#include +#include +#include + +class PHObject; + +class GlobalVertexv3 : public GlobalVertex +{ + public: + GlobalVertexv3() = default; + GlobalVertexv3(const unsigned int id); + ~GlobalVertexv3() override; + + // PHObject virtual overloads + void identify(std::ostream& os = std::cout) const override; + void Reset() override; + int isValid() const override; + PHObject* CloneMe() const override { return new GlobalVertexv3(*this); } + + unsigned int get_id() const override { return _id; } + void set_id(unsigned int id) override { _id = id; } + + short int get_beam_crossing() const override { return _bco; } + void set_beam_crossing(short int bco) override { _bco = bco; } + + float get_t() const override; + float get_t_err() const override; + float get_x() const override; + float get_y() const override; + float get_z() const override; + float get_chisq() const override; + unsigned int get_ndof() const override; + float get_position(unsigned int coor) const override; + float get_error(unsigned int i, unsigned int j) const override; + + // + // associated vertex methods + // + bool empty_vtxs() const override { return _vtxs.empty(); } + size_t size_vtxs() const override { return _vtxs.size(); } + size_t count_vtxs(GlobalVertex::VTXTYPE type) const override; + + void clear_vtxs() override { _vtxs.clear(); } + void insert_vtx(GlobalVertex::VTXTYPE type, const Vertex* vertex) override; + void clone_insert_vtx(GlobalVertex::VTXTYPE type, const Vertex* vertex) override; + size_t erase_vtxs(GlobalVertex::VTXTYPE type) override { return _vtxs.erase(type); } + void erase_vtxs(GlobalVertex::VertexIter iter) override { _vtxs.erase(iter); } + + GlobalVertex::ConstVertexIter begin_vertexes() const override { return _vtxs.begin(); } + GlobalVertex::ConstVertexIter find_vertexes(GlobalVertex::VTXTYPE type) const override { return _vtxs.find(type); } + GlobalVertex::ConstVertexIter end_vertexes() const override { return _vtxs.end(); } + + GlobalVertex::VertexIter begin_vertexes() override { return _vtxs.begin(); } + GlobalVertex::VertexIter find_vertexes(GlobalVertex::VTXTYPE type) override { return _vtxs.find(type); } + GlobalVertex::VertexIter end_vertexes() override { return _vtxs.end(); } + + private: + unsigned int _id{std::numeric_limits::max()}; + short int _bco{std::numeric_limits::max()}; //< global bco (signed short) + std::map _vtxs; //< list of vtxs + + ClassDefOverride(GlobalVertexv3, 3); +}; + +#endif diff --git a/offline/packages/globalvertex/GlobalVertexv3LinkDef.h b/offline/packages/globalvertex/GlobalVertexv3LinkDef.h new file mode 100644 index 0000000000..8cd2f1abf7 --- /dev/null +++ b/offline/packages/globalvertex/GlobalVertexv3LinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class GlobalVertexv3 + ; + +#endif /* __CINT__ */ diff --git a/offline/packages/globalvertex/Makefile.am b/offline/packages/globalvertex/Makefile.am index 5cedef884d..0ff0587389 100644 --- a/offline/packages/globalvertex/Makefile.am +++ b/offline/packages/globalvertex/Makefile.am @@ -30,17 +30,20 @@ pkginclude_HEADERS = \ GlobalVertex.h \ GlobalVertexv1.h \ GlobalVertexv2.h \ + GlobalVertexv3.h \ GlobalVertexMap.h \ GlobalVertexMapv1.h \ GlobalVertexReco.h \ MbdVertex.h \ MbdVertexv1.h \ MbdVertexv2.h \ + MbdVertexv3.h \ MbdVertexMap.h \ MbdVertexMapv1.h \ SvtxVertex.h \ SvtxVertex_v1.h \ SvtxVertex_v2.h \ + SvtxVertex_v3.h \ SvtxVertexMap.h \ SvtxVertexMap_v1.h \ TruthVertex.h \ @@ -57,16 +60,19 @@ ROOTDICTS = \ GlobalVertex_Dict.cc \ GlobalVertexv1_Dict.cc \ GlobalVertexv2_Dict.cc \ + GlobalVertexv3_Dict.cc \ GlobalVertexMap_Dict.cc \ GlobalVertexMapv1_Dict.cc \ MbdVertex_Dict.cc \ MbdVertexv1_Dict.cc \ MbdVertexv2_Dict.cc \ + MbdVertexv3_Dict.cc \ MbdVertexMap_Dict.cc \ MbdVertexMapv1_Dict.cc \ SvtxVertex_Dict.cc \ SvtxVertex_v1_Dict.cc \ SvtxVertex_v2_Dict.cc \ + SvtxVertex_v3_Dict.cc \ SvtxVertexMap_Dict.cc \ SvtxVertexMap_v1_Dict.cc \ TruthVertex_Dict.cc \ @@ -87,15 +93,18 @@ libglobalvertex_io_la_SOURCES = \ GlobalVertex.cc \ GlobalVertexv1.cc \ GlobalVertexv2.cc \ + GlobalVertexv3.cc \ GlobalVertexMap.cc \ GlobalVertexMapv1.cc \ MbdVertexv1.cc \ MbdVertexv2.cc \ + MbdVertexv3.cc \ MbdVertexMap.cc \ MbdVertexMapv1.cc \ SvtxVertex.cc \ SvtxVertex_v1.cc \ SvtxVertex_v2.cc \ + SvtxVertex_v3.cc \ SvtxVertexMap.cc \ SvtxVertexMap_v1.cc \ TruthVertex.cc \ diff --git a/offline/packages/globalvertex/MbdVertex.h b/offline/packages/globalvertex/MbdVertex.h index 6d0900b768..ed8d18e1d8 100644 --- a/offline/packages/globalvertex/MbdVertex.h +++ b/offline/packages/globalvertex/MbdVertex.h @@ -36,8 +36,12 @@ class MbdVertex : public Vertex virtual float get_z_err() const override { return std::numeric_limits::quiet_NaN(); } virtual void set_z_err(float) override {} - virtual unsigned int get_beam_crossing() const override { return std::numeric_limits::max(); } - virtual void set_beam_crossing(unsigned int) override {} + virtual short int get_beam_crossing() const override + { + return std::numeric_limits::max(); + } + virtual void set_beam_crossing(short int) override {} + virtual void set_bbc_ns(int, int, float, float) override {} virtual int get_bbc_npmt(int) const override { return std::numeric_limits::max(); } diff --git a/offline/packages/globalvertex/MbdVertexv2.h b/offline/packages/globalvertex/MbdVertexv2.h index bee34059e4..3b3482ed4f 100644 --- a/offline/packages/globalvertex/MbdVertexv2.h +++ b/offline/packages/globalvertex/MbdVertexv2.h @@ -44,12 +44,56 @@ class MbdVertexv2 : public MbdVertex float get_position(unsigned int coor) const override; - unsigned int get_beam_crossing() const override { return _bco; } - void set_beam_crossing(unsigned int bco) override { _bco = bco; } + short int get_beam_crossing() const override + { + return rollover_from_unsignedint(_bco); + } + void set_beam_crossing(short int bco) override + { + if (bco == short_int_max) + { + _bco = std::numeric_limits::max(); + return; + } + + const short int bco_ro = rollover_short(bco); + _bco = static_cast(bco_ro); + } private: + static constexpr short int short_int_max = std::numeric_limits::max(); // 32767 + + static short int rollover_short(short int bco) + { + if (bco == short_int_max) return short_int_max; + if (bco >= 0) return bco; + + const int bco_ro = static_cast(short_int_max) + static_cast(bco); // bco negative + return static_cast(bco_ro); + } + + static short int rollover_from_unsignedint(unsigned int bco) + { + // if unsigned int max, return short int max + if (bco == std::numeric_limits::max()) + { + return short_int_max; + } + + // common case: [0, 32767] + if (bco <= static_cast(short_int_max)) + { + return static_cast(bco); + } + + const short int bco_ro = static_cast(static_cast(bco)); + if (bco_ro >= 0) return bco_ro; + + return rollover_short(bco_ro); + } + unsigned int _id{std::numeric_limits::max()}; //< unique identifier within container - unsigned int _bco{std::numeric_limits::max()}; //< global bco + unsigned int _bco{std::numeric_limits::max()}; //< global bco (legacy storage) float _t{std::numeric_limits::quiet_NaN()}; //< collision time float _t_err{std::numeric_limits::quiet_NaN()}; //< collision time uncertainty float _z{std::numeric_limits::quiet_NaN()}; //< collision position z diff --git a/offline/packages/globalvertex/MbdVertexv3.cc b/offline/packages/globalvertex/MbdVertexv3.cc new file mode 100644 index 0000000000..9c76f521a3 --- /dev/null +++ b/offline/packages/globalvertex/MbdVertexv3.cc @@ -0,0 +1,60 @@ +#include "MbdVertexv3.h" + +#include +#include + +void MbdVertexv3::identify(std::ostream& os) const +{ + os << "---MbdVertexv3--------------------------------" << std::endl; + os << "vertexid: " << get_id() << std::endl; + os << " t = " << get_t() << " +/- " << get_t_err() << std::endl; + os << " z = " << get_z() << " +/- " << get_z_err() << std::endl; + os << " bco = " << get_beam_crossing() << std::endl; + os << "-----------------------------------------------" << std::endl; + + return; +} + +int MbdVertexv3::isValid() const +{ + if (_id == std::numeric_limits::max()) + { + return 0; + } + if (std::isnan(_t)) + { + return 0; + } + if (std::isnan(_t_err)) + { + return 0; + } + if (std::isnan(_z)) + { + return 0; + } + if (std::isnan(_z_err)) + { + return 0; + } + + return 1; +} + +float MbdVertexv3::get_position(unsigned int coor) const +{ + if (coor == 0) + { + return get_x(); + } + if (coor == 1) + { + return get_y(); + } + if (coor == 2) + { + return get_z(); + } + + return std::numeric_limits::quiet_NaN(); +} diff --git a/offline/packages/globalvertex/MbdVertexv3.h b/offline/packages/globalvertex/MbdVertexv3.h new file mode 100644 index 0000000000..7d59c82d79 --- /dev/null +++ b/offline/packages/globalvertex/MbdVertexv3.h @@ -0,0 +1,60 @@ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef GLOBALVERTEX_MBDVERTEXV3_H +#define GLOBALVERTEX_MBDVERTEXV3_H + +#include "MbdVertex.h" + +#include +#include + +class MbdVertexv3 : public MbdVertex +{ + public: + MbdVertexv3() = default; + ~MbdVertexv3() override = default; + + // PHObject virtual overloads + void identify(std::ostream& os = std::cout) const override; + void Reset() override { *this = MbdVertexv3(); } + int isValid() const override; + PHObject* CloneMe() const override { return new MbdVertexv3(*this); } + + // vertex info + unsigned int get_id() const override { return _id; } + void set_id(unsigned int id) override { _id = id; } + + float get_t() const override { return _t; } + void set_t(float t) override { _t = t; } + + float get_t_err() const override { return _t_err; } + void set_t_err(float t_err) override { _t_err = t_err; } + + // Return 0 for now, can implement beam spot + float get_x() const override { return 0; } + float get_y() const override { return 0; } + + float get_z() const override { return _z; } + void set_z(float z) override { _z = z; } + + float get_z_err() const override { return _z_err; } + void set_z_err(float z_err) override { _z_err = z_err; } + + float get_position(unsigned int coor) const override; + + // beam crossing methods (v3: native signed short storage) + short int get_beam_crossing() const override { return _bco; } + void set_beam_crossing(short int bco) override { _bco = bco; } + + private: + unsigned int _id{std::numeric_limits::max()}; //< unique identifier within container + short int _bco{std::numeric_limits::max()}; //< global bco (signed short) + float _t{std::numeric_limits::quiet_NaN()}; //< collision time + float _t_err{std::numeric_limits::quiet_NaN()}; //< collision time uncertainty + float _z{std::numeric_limits::quiet_NaN()}; //< collision position z + float _z_err{std::numeric_limits::quiet_NaN()}; //< collision position z uncertainty + + ClassDefOverride(MbdVertexv3, 1); +}; + +#endif diff --git a/offline/packages/globalvertex/MbdVertexv3LinkDef.h b/offline/packages/globalvertex/MbdVertexv3LinkDef.h new file mode 100644 index 0000000000..b55e4bf42d --- /dev/null +++ b/offline/packages/globalvertex/MbdVertexv3LinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class MbdVertexv3 + ; + +#endif /* __CINT__ */ diff --git a/offline/packages/globalvertex/SvtxVertex_v2.h b/offline/packages/globalvertex/SvtxVertex_v2.h index 24ccbfc0ca..32d19eda66 100644 --- a/offline/packages/globalvertex/SvtxVertex_v2.h +++ b/offline/packages/globalvertex/SvtxVertex_v2.h @@ -54,8 +54,21 @@ class SvtxVertex_v2 : public SvtxVertex float get_error(unsigned int i, unsigned int j) const override; //< get vertex error covar void set_error(unsigned int i, unsigned int j, float value) override; //< set vertex error covar - unsigned int get_beam_crossing() const override { return _beamcrossing; } - void set_beam_crossing(unsigned int cross) override { _beamcrossing = cross; } + short int get_beam_crossing() const override + { + return rollover_from_unsignedint(_beamcrossing); + } + void set_beam_crossing(short int cross) override + { + if (cross == short_int_max) + { + _beamcrossing = std::numeric_limits::max(); + return; + } + + const short int cross_ro = rollover_short(cross); + _beamcrossing = static_cast(cross_ro); + } // // associated track ids methods @@ -73,6 +86,37 @@ class SvtxVertex_v2 : public SvtxVertex TrackIter end_tracks() override { return _track_ids.end(); } private: + static constexpr short int short_int_max = std::numeric_limits::max(); // 32767 + // for unsigned int to short int conversion (rollover) + static short int rollover_short(short int cross) + { + if (cross == short_int_max) return short_int_max; + if (cross >= 0) return cross; + + const int cross_ro = static_cast(short_int_max) + static_cast(cross); // cross negative + return static_cast(cross_ro); + } + + static short int rollover_from_unsignedint(unsigned int cross) + { + // if unsigned int max, return short int max + if (cross == std::numeric_limits::max()) + { + return short_int_max; + } + + // Common case: [0, 32767] + if (cross <= static_cast(short_int_max)) + { + return static_cast(cross); + } + + const short int cross_ro = static_cast(static_cast(cross)); + if (cross_ro >= 0) return cross_ro; + + return rollover_short(cross_ro); + } + unsigned int covar_index(unsigned int i, unsigned int j) const; unsigned int _id{std::numeric_limits::max()}; //< unique identifier within container diff --git a/offline/packages/globalvertex/SvtxVertex_v3.cc b/offline/packages/globalvertex/SvtxVertex_v3.cc new file mode 100644 index 0000000000..731a2c841f --- /dev/null +++ b/offline/packages/globalvertex/SvtxVertex_v3.cc @@ -0,0 +1,113 @@ +#include "SvtxVertex_v3.h" + +#include +#include +#include +#include // for swap + +SvtxVertex_v3::SvtxVertex_v3() +{ + std::fill(std::begin(_pos), std::end(_pos), std::numeric_limits::quiet_NaN()); + std::fill(std::begin(_err), std::end(_err), std::numeric_limits::quiet_NaN()); +} + +void SvtxVertex_v3::identify(std::ostream& os) const +{ + os << "---SvtxVertex_v3--------------------" << std::endl; + os << "vertexid: " << get_id() << std::endl; + + os << " t0 = " << get_t() << std::endl; + os << " beam crossing = " << get_beam_crossing() << std::endl; + os << " (x,y,z) = (" << get_position(0); + os << ", " << get_position(1) << ", "; + os << get_position(2) << ") cm" << std::endl; + + os << " chisq = " << get_chisq() << ", "; + os << " ndof = " << get_ndof() << std::endl; + + os << " ( "; + os << get_error(0, 0) << " , "; + os << get_error(0, 1) << " , "; + os << get_error(0, 2) << " )" << std::endl; + os << " err = ( "; + os << get_error(1, 0) << " , "; + os << get_error(1, 1) << " , "; + os << get_error(1, 2) << " )" << std::endl; + os << " ( "; + os << get_error(2, 0) << " , "; + os << get_error(2, 1) << " , "; + os << get_error(2, 2) << " )" << std::endl; + + os << " list of tracks ids: "; + for (ConstTrackIter iter = begin_tracks(); iter != end_tracks(); ++iter) + { + os << *iter << " "; + } + os << std::endl; + os << "-----------------------------------------------" << std::endl; + + return; +} + +int SvtxVertex_v3::isValid() const +{ + if (_id == std::numeric_limits::max()) + { + return 0; + } + if (std::isnan(_t0)) + { + return 0; + } + if (std::isnan(_chisq)) + { + return 0; + } + if (_ndof == std::numeric_limits::max()) + { + return 0; + } + + for (float _po : _pos) + { + if (std::isnan(_po)) + { + return 0; + } + } + for (int j = 0; j < 3; ++j) + { + for (int i = j; i < 3; ++i) + { + if (std::isnan(get_error(i, j))) + { + return 0; + } + } + } + if (_track_ids.empty()) + { + return 0; + } + return 1; +} + +void SvtxVertex_v3::set_error(unsigned int i, unsigned int j, float value) +{ + _err[covar_index(i, j)] = value; + return; +} + +float SvtxVertex_v3::get_error(unsigned int i, unsigned int j) const +{ + return _err[covar_index(i, j)]; +} + +unsigned int SvtxVertex_v3::covar_index(unsigned int i, unsigned int j) const +{ + if (i > j) + { + std::swap(i, j); + } + return i + 1 + (j + 1) * (j) / 2 - 1; +} diff --git a/offline/packages/globalvertex/SvtxVertex_v3.h b/offline/packages/globalvertex/SvtxVertex_v3.h new file mode 100644 index 0000000000..74a75d90ea --- /dev/null +++ b/offline/packages/globalvertex/SvtxVertex_v3.h @@ -0,0 +1,89 @@ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef GLOBALVERTEX_SVTXVERTEXV3_H +#define GLOBALVERTEX_SVTXVERTEXV3_H + +#include "SvtxVertex.h" + +#include // for size_t +#include +#include +#include + +class PHObject; + +class SvtxVertex_v3 : public SvtxVertex +{ + public: + SvtxVertex_v3(); + ~SvtxVertex_v3() override {} + + // PHObject virtual overloads + void identify(std::ostream& os = std::cout) const override; + void Reset() override { *this = SvtxVertex_v3(); } + int isValid() const override; + PHObject* CloneMe() const override { return new SvtxVertex_v3(*this); } + + // vertex info + unsigned int get_id() const override { return _id; } + void set_id(unsigned int id) override { _id = id; } + + float get_t() const override { return _t0; } + void set_t(float t0) override { _t0 = t0; } + + float get_x() const override { return _pos[0]; } + void set_x(float x) override { _pos[0] = x; } + + float get_y() const override { return _pos[1]; } + void set_y(float y) override { _pos[1] = y; } + + float get_z() const override { return _pos[2]; } + void set_z(float z) override { _pos[2] = z; } + + float get_chisq() const override { return _chisq; } + void set_chisq(float chisq) override { _chisq = chisq; } + + unsigned int get_ndof() const override { return _ndof; } + void set_ndof(unsigned int ndof) override { _ndof = ndof; } + + float get_position(unsigned int coor) const override { return _pos[coor]; } + void set_position(unsigned int coor, float xi) override { _pos[coor] = xi; } + + float get_error(unsigned int i, unsigned int j) const override; //< get vertex error covar + void set_error(unsigned int i, unsigned int j, float value) override; //< set vertex error covar + + // v3 uses signed short + short int get_beam_crossing() const override { return _beamcrossing; } + void set_beam_crossing(short int cross) override { _beamcrossing = cross; } + + // + // associated track ids methods + // + void clear_tracks() override { _track_ids.clear(); } + bool empty_tracks() override { return _track_ids.empty(); } + size_t size_tracks() const override { return _track_ids.size(); } + void insert_track(unsigned int trackid) override { _track_ids.insert(trackid); } + size_t erase_track(unsigned int trackid) override { return _track_ids.erase(trackid); } + ConstTrackIter begin_tracks() const override { return _track_ids.begin(); } + ConstTrackIter find_track(unsigned int trackid) const override { return _track_ids.find(trackid); } + ConstTrackIter end_tracks() const override { return _track_ids.end(); } + TrackIter begin_tracks() override { return _track_ids.begin(); } + TrackIter find_track(unsigned int trackid) override { return _track_ids.find(trackid); } + TrackIter end_tracks() override { return _track_ids.end(); } + + private: + unsigned int covar_index(unsigned int i, unsigned int j) const; + + unsigned int _id{std::numeric_limits::max()}; //< unique identifier within container + float _t0{std::numeric_limits::quiet_NaN()}; //< collision time + float _pos[3]{}; //< collision position x,y,z + float _chisq{std::numeric_limits::quiet_NaN()}; //< vertex fit chisq + unsigned int _ndof{std::numeric_limits::max()}; //< degrees of freedom + float _err[6]{}; //< error covariance matrix (packed storage) (+/- cm^2) + std::set _track_ids; //< list of track ids + short int _beamcrossing{std::numeric_limits::max()}; + + ClassDefOverride(SvtxVertex_v3, 3); +}; + +#endif diff --git a/offline/packages/globalvertex/SvtxVertex_v3LinkDef.h b/offline/packages/globalvertex/SvtxVertex_v3LinkDef.h new file mode 100644 index 0000000000..7b6506845d --- /dev/null +++ b/offline/packages/globalvertex/SvtxVertex_v3LinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class SvtxVertex_v3 + ; + +#endif /* __CINT__ */ diff --git a/offline/packages/globalvertex/Vertex.h b/offline/packages/globalvertex/Vertex.h index 7bbfa5f381..e475bfb95d 100644 --- a/offline/packages/globalvertex/Vertex.h +++ b/offline/packages/globalvertex/Vertex.h @@ -62,8 +62,8 @@ class Vertex : public PHObject virtual void set_error(unsigned int /*i*/, unsigned int /*j*/, float /*value*/) {} // beam crossing methods - virtual unsigned int get_beam_crossing() const { return std::numeric_limits::max(); } - virtual void set_beam_crossing(unsigned int) {} + virtual short int get_beam_crossing() const { return std::numeric_limits::max(); } + virtual void set_beam_crossing(short int) {} // bbcvertex methods virtual void set_bbc_ns(int, int, float, float) {} From 4814fd2321bcdd15089fcfc46565ba9e425759b6 Mon Sep 17 00:00:00 2001 From: mchiu-bnl Date: Wed, 28 Jan 2026 21:48:29 -0500 Subject: [PATCH 132/393] remove need for status calib - defaults to all good --- offline/packages/mbd/MbdCalib.cc | 10 +++++----- offline/packages/mbd/MbdEvent.cc | 17 +++++++++++++---- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/offline/packages/mbd/MbdCalib.cc b/offline/packages/mbd/MbdCalib.cc index a6e5c773b1..6cc02b0692 100644 --- a/offline/packages/mbd/MbdCalib.cc +++ b/offline/packages/mbd/MbdCalib.cc @@ -92,16 +92,15 @@ int MbdCalib::Download_All() Download_SampMax(sampmax_url); std::string status_url = _cdb->getUrl("MBD_STATUS"); - if ( status_url.empty() ) + if ( ! status_url.empty() ) { - std::cerr << "ERROR, MBD_STATUS missing" << std::endl; - return -1; + // if this doesn't exist, the status is assumed to be all good + Download_Status(status_url); } if (Verbosity() > 0) { std::cout << "status_url " << status_url << std::endl; } - Download_Status(status_url); if ( !_rawdstflag ) { @@ -785,7 +784,7 @@ int MbdCalib::Download_Status(const std::string& dbase_location) if ( _mbdstatus[0] == -1 ) { - std::cout << PHWHERE << ", WARNING, sampmax calib missing, " << dbase_location << std::endl; + std::cout << PHWHERE << ", WARNING, status calib seems bad, " << dbase_location << std::endl; _status = -1; return _status; // file not found } @@ -2504,6 +2503,7 @@ void MbdCalib::Reset() Reset_Thresholds(); _sampmax.fill(-1); + _mbdstatus.fill(0); } void MbdCalib::set_ped(const int ifeech, const float m, const float merr, const float s, const float serr) diff --git a/offline/packages/mbd/MbdEvent.cc b/offline/packages/mbd/MbdEvent.cc index 0ed3886a60..b8782b8044 100644 --- a/offline/packages/mbd/MbdEvent.cc +++ b/offline/packages/mbd/MbdEvent.cc @@ -419,7 +419,13 @@ void MbdEvent::Clear() bool MbdEvent::isbadtch(const int ipmtch) { - return std::fabs(_mbdcal->get_tt0(ipmtch))>100.; + int feech = _mbdgeom->get_feech(ipmtch,0); + if ( _mbdcal->get_status(feech) > 0 ) + { + return true; + } + + return false; } @@ -687,6 +693,7 @@ int MbdEvent::ProcessPackets(MbdRawContainer *bbcraws) { std::cout << __FILE__ << ":" << __LINE__ << " ERROR, xmitclocks don't agree, evt " << m_evt << std::endl; } + /* // format changed in run2024, need to update check for (auto &femclock : femclocks) @@ -731,15 +738,14 @@ int MbdEvent::ProcessPackets(MbdRawContainer *bbcraws) { m_ttdc[pmtch] = _mbdsig[ifeech].MBDTDC(_mbdcal->get_sampmax(ifeech)); - if ( m_ttdc[pmtch] < 40. || std::isnan(m_ttdc[pmtch]) || isbadtch(pmtch) ) + if ( m_ttdc[pmtch] < 40. || std::isnan(m_ttdc[pmtch]) ) { m_ttdc[pmtch] = std::numeric_limits::quiet_NaN(); // no hit } } - else if ( type == 1 && (!std::isnan(m_ttdc[pmtch]) || isbadtch(pmtch) || _always_process_charge ) ) + else if ( type == 1 && (!std::isnan(m_ttdc[pmtch]) || _always_process_charge ) ) { // we process charge channels which have good time hit - // or have time channels marked as bad // or have always_process_charge set to 1 (useful for threshold studies) // Use dCFD method to seed time in charge channels (or as primary if not fitting template) @@ -753,10 +759,12 @@ int MbdEvent::ProcessPackets(MbdRawContainer *bbcraws) //std::cout << "fittemplate" << std::endl; _mbdsig[ifeech].FitTemplate( _mbdcal->get_sampmax(ifeech) ); + /* if ( _verbose ) { std::cout << "tt " << ifeech << " " << pmtch << " " << m_pmttt[pmtch] << std::endl; } + */ m_qtdc[pmtch] = _mbdsig[ifeech].GetTime(); // in units of sample number m_ampl[ifeech] = _mbdsig[ifeech].GetAmpl(); // in units of adc } @@ -797,6 +805,7 @@ int MbdEvent::ProcessRawContainer(MbdRawContainer *bbcraws, MbdPmtContainer *bbc { if ( std::isnan(bbcraws->get_pmt(pmtch)->get_ttdc()) || isbadtch(pmtch) ) { + // time channel has no hit or is marked as bad m_pmttt[pmtch] = std::numeric_limits::quiet_NaN(); // no hit } else From d87e7150086359696e27c54635f97e2394d255ad Mon Sep 17 00:00:00 2001 From: Hao-Ren Jheng Date: Thu, 29 Jan 2026 09:52:11 -0500 Subject: [PATCH 133/393] update to v3 --- .../packages/globalvertex/GlobalVertexReco.cc | 16 ++++++++-------- offline/packages/jetbase/TowerJetInput.cc | 2 +- offline/packages/mbd/MbdReco.cc | 4 ++-- .../packages/trackreco/PHSimpleVertexFinder.cc | 4 ++-- offline/packages/trackreco/WeightedFitter.cc | 2 +- .../g4simulation/g4bbc/MbdVertexFastSimReco.cc | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/offline/packages/globalvertex/GlobalVertexReco.cc b/offline/packages/globalvertex/GlobalVertexReco.cc index 4f50bbc1b6..73681759cc 100644 --- a/offline/packages/globalvertex/GlobalVertexReco.cc +++ b/offline/packages/globalvertex/GlobalVertexReco.cc @@ -3,7 +3,7 @@ //#include "GlobalVertex.h" // for GlobalVertex, GlobalVe... #include "GlobalVertexMap.h" // for GlobalVertexMap #include "GlobalVertexMapv1.h" -#include "GlobalVertexv2.h" +#include "GlobalVertexv3.h" #include "MbdVertex.h" #include "MbdVertexMap.h" #include "CaloVertex.h" @@ -140,7 +140,7 @@ int GlobalVertexReco::process_event(PHCompositeNode *topNode) } // we have a matching pair - GlobalVertex *vertex = new GlobalVertexv2(); + GlobalVertex *vertex = new GlobalVertexv3(); vertex->set_id(globalmap->size()); vertex->clone_insert_vtx(GlobalVertex::SVTX, svtx); @@ -193,7 +193,7 @@ int GlobalVertexReco::process_event(PHCompositeNode *topNode) } // we have a standalone SVTX vertex - GlobalVertex *vertex = new GlobalVertexv2(); + GlobalVertex *vertex = new GlobalVertexv3(); vertex->set_id(globalmap->size()); @@ -243,7 +243,7 @@ int GlobalVertexReco::process_event(PHCompositeNode *topNode) continue; } - GlobalVertex *vertex = new GlobalVertexv2(); + GlobalVertex *vertex = new GlobalVertexv3(); vertex->set_id(globalmap->size()); vertex->clone_insert_vtx(GlobalVertex::MBD, mbd); @@ -282,7 +282,7 @@ int GlobalVertexReco::process_event(PHCompositeNode *topNode) continue; } - GlobalVertex *vertex = new GlobalVertexv2(); + GlobalVertex *vertex = new GlobalVertexv3(); vertex->set_id(globalmap->size()); vertex->clone_insert_vtx(GlobalVertex::CALO, calo); @@ -337,7 +337,7 @@ int GlobalVertexReco::process_event(PHCompositeNode *topNode) continue; } - GlobalVertex *vertex = new GlobalVertexv2(); + GlobalVertex *vertex = new GlobalVertexv3(); vertex->set_id(globalmap->size()); vertex->clone_insert_vtx(GlobalVertex::CALO, calo); @@ -354,7 +354,7 @@ int GlobalVertexReco::process_event(PHCompositeNode *topNode) } else { - GlobalVertex *vertex = new GlobalVertexv2(); + GlobalVertex *vertex = new GlobalVertexv3(); vertex->set_id(globalmap->size()); vertex->clone_insert_vtx(GlobalVertex::MBD, mbd); @@ -393,7 +393,7 @@ int GlobalVertexReco::process_event(PHCompositeNode *topNode) tvertex->set_t(0); tvertex->set_t_err(0); // 0.1 - GlobalVertex *vertex = new GlobalVertexv2(); + GlobalVertex *vertex = new GlobalVertexv3(); vertex->clone_insert_vtx(GlobalVertex::TRUTH, tvertex); globalmap->insert(vertex); if (truthmap) diff --git a/offline/packages/jetbase/TowerJetInput.cc b/offline/packages/jetbase/TowerJetInput.cc index f58249ad04..052a6c1828 100644 --- a/offline/packages/jetbase/TowerJetInput.cc +++ b/offline/packages/jetbase/TowerJetInput.cc @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include diff --git a/offline/packages/mbd/MbdReco.cc b/offline/packages/mbd/MbdReco.cc index 004e191e78..a2801f41f9 100644 --- a/offline/packages/mbd/MbdReco.cc +++ b/offline/packages/mbd/MbdReco.cc @@ -7,7 +7,7 @@ #include "MbdPmtSimContainerV1.h" #include -#include +#include #include @@ -172,7 +172,7 @@ int MbdReco::process_event(PHCompositeNode *topNode) // For multiple global vertex if (m_mbdevent->get_bbcn(0) > 0 && m_mbdevent->get_bbcn(1) > 0 && _calpass==0 ) { - auto *vertex = new MbdVertexv2(); + auto *vertex = new MbdVertexv3(); vertex->set_t(m_mbdevent->get_bbct0()); vertex->set_z(m_mbdevent->get_bbcz()); vertex->set_z_err(0.6); diff --git a/offline/packages/trackreco/PHSimpleVertexFinder.cc b/offline/packages/trackreco/PHSimpleVertexFinder.cc index 3d3e4a9fda..5f9340d8f6 100644 --- a/offline/packages/trackreco/PHSimpleVertexFinder.cc +++ b/offline/packages/trackreco/PHSimpleVertexFinder.cc @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include @@ -263,7 +263,7 @@ int PHSimpleVertexFinder::process_event(PHCompositeNode * /*topNode*/) { unsigned int thisid = it + vertex_id; // the address of the vertex in the event - auto svtxVertex = std::make_unique(); + auto svtxVertex = std::make_unique(); svtxVertex->set_chisq(0.0); svtxVertex->set_ndof(0); diff --git a/offline/packages/trackreco/WeightedFitter.cc b/offline/packages/trackreco/WeightedFitter.cc index af7677f5b8..e35919c479 100644 --- a/offline/packages/trackreco/WeightedFitter.cc +++ b/offline/packages/trackreco/WeightedFitter.cc @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include diff --git a/simulation/g4simulation/g4bbc/MbdVertexFastSimReco.cc b/simulation/g4simulation/g4bbc/MbdVertexFastSimReco.cc index 45458b9b49..97f801771c 100644 --- a/simulation/g4simulation/g4bbc/MbdVertexFastSimReco.cc +++ b/simulation/g4simulation/g4bbc/MbdVertexFastSimReco.cc @@ -2,7 +2,7 @@ #include "MbdVertexFastSimReco.h" #include -#include +#include #include #include @@ -95,7 +95,7 @@ int MbdVertexFastSimReco::process_event(PHCompositeNode *topNode) return Fun4AllReturnCodes::EVENT_OK; } - MbdVertex *vertex = new MbdVertexv2(); + MbdVertex *vertex = new MbdVertexv3(); if (m_T_Smear >= 0.0) { From 6946cba0986c7c4f5a458562a5aedc9cf5cf1380 Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Thu, 29 Jan 2026 14:53:47 +0000 Subject: [PATCH 134/393] =?UTF-8?q?=F0=9F=93=9D=20Add=20docstrings=20to=20?= =?UTF-8?q?`CaloValid-OO-update`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Docstrings generation was requested by @pinkenburg. * https://github.com/sPHENIX-Collaboration/coresoftware/pull/4145#issuecomment-3813903526 The following files were modified: * `offline/QA/Calorimeters/CaloValid.cc` * `offline/framework/phool/RunnumberRange.h` --- offline/QA/Calorimeters/CaloValid.cc | 20 ++++++++++++++++++-- offline/framework/phool/RunnumberRange.h | 20 ++++++++++++++++++-- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/offline/QA/Calorimeters/CaloValid.cc b/offline/QA/Calorimeters/CaloValid.cc index 54598ceaf0..655fa8903e 100644 --- a/offline/QA/Calorimeters/CaloValid.cc +++ b/offline/QA/Calorimeters/CaloValid.cc @@ -84,7 +84,23 @@ int CaloValid::Init(PHCompositeNode* /*unused*/) return Fun4AllReturnCodes::EVENT_OK; } -// Note: InitRun cannot be made static as it modifies member variable m_species +/** + * @brief Determine the collision species for the current run and set m_species. + * + * Reads the RunHeader from the provided node tree, inspects the run number, and sets + * the member variable `m_species` to one of the recognized values ("pp", "AuAu", "OO"). + * If the run number does not match any known range or the RunHeader is missing, + * `m_species` remains unchanged (default behavior uses "pp" elsewhere) and a diagnostic + * message may be printed depending on verbosity. + * + * Recognized mappings: + * - RUN2PP_* -> "pp" + * - RUN2AUAU_* or RUN3AUAU_* -> "AuAu" + * - RUN3OO_* -> "OO" + * + * @param topNode Top-level node of the event tree used to locate the RunHeader. + * @return int EVENT_OK on success. + */ int CaloValid::InitRun(PHCompositeNode* topNode) { RunHeader* runhdr = findNode::getClass(topNode, "RunHeader"); @@ -1346,4 +1362,4 @@ void CaloValid::createHistos() } hm->registerHisto(h_triggerVec); hm->registerHisto(pr_ldClus_trig); -} +} \ No newline at end of file diff --git a/offline/framework/phool/RunnumberRange.h b/offline/framework/phool/RunnumberRange.h index 5d14a79350..7d942ca791 100644 --- a/offline/framework/phool/RunnumberRange.h +++ b/offline/framework/phool/RunnumberRange.h @@ -1,7 +1,23 @@ #ifndef PHOOL_RUNNUMBERRANGE_H #define PHOOL_RUNNUMBERRANGE_H -// first and last physics run +/** + * Defines run-number range constants and special run markers used to identify physics data-taking periods. + * + * Each constant names the first or last run number (or a special marker) for a given data-taking period. + * + * @var RUN2PP_FIRST First Run 2 proton-proton physics run. + * @var RUN2PP_LAST Last Run 2 proton-proton physics run. + * @var RUN2AUAU_FIRST First Run 2 Au+Au (heavy-ion) physics run. + * @var RUN2AUAU_LAST Last Run 2 Au+Au (heavy-ion) physics run. + * @var RUN3_TPCFW_CLOCK_CHANGE Run 3 marker for the TPC Forward clock change. + * @var RUN3AUAU_FIRST First Run 3 Au+Au (heavy-ion) physics run. + * @var RUN3AUAU_LAST Last Run 3 Au+Au (heavy-ion) physics run. + * @var RUN3PP_FIRST First Run 3 proton-proton (beam) physics run. + * @var RUN3PP_LAST Last Run 3 proton-proton physics run. + * @var RUN3OO_FIRST Temporary placeholder for the first Run 3 OO run (to be updated once OO starts). + * @var RUN3OO_LAST Temporary upper bound for Run 3 OO runs. + */ namespace RunnumberRange { static const int RUN2PP_FIRST = 47286; @@ -17,4 +33,4 @@ namespace RunnumberRange static const int RUN3OO_LAST = 200000; } -#endif +#endif \ No newline at end of file From 72f7c46d28be735247d81cb0e1bfd45a206e44bb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 29 Jan 2026 14:54:05 +0000 Subject: [PATCH 135/393] Fix missing final newline in docstring PR --- offline/QA/Calorimeters/CaloValid.cc | 2 +- offline/framework/phool/RunnumberRange.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/offline/QA/Calorimeters/CaloValid.cc b/offline/QA/Calorimeters/CaloValid.cc index 655fa8903e..fe815df37f 100644 --- a/offline/QA/Calorimeters/CaloValid.cc +++ b/offline/QA/Calorimeters/CaloValid.cc @@ -1362,4 +1362,4 @@ void CaloValid::createHistos() } hm->registerHisto(h_triggerVec); hm->registerHisto(pr_ldClus_trig); -} \ No newline at end of file +} diff --git a/offline/framework/phool/RunnumberRange.h b/offline/framework/phool/RunnumberRange.h index 7d942ca791..2c809f2fb9 100644 --- a/offline/framework/phool/RunnumberRange.h +++ b/offline/framework/phool/RunnumberRange.h @@ -33,4 +33,4 @@ namespace RunnumberRange static const int RUN3OO_LAST = 200000; } -#endif \ No newline at end of file +#endif From 9bb1cc1a382444b80f1086e1c204166e2312c995 Mon Sep 17 00:00:00 2001 From: rosstom Date: Thu, 29 Jan 2026 19:53:11 -0500 Subject: [PATCH 136/393] Increased Cluster State Residual QA capabilites --- .../QA/Tracking/StateClusterResidualsQA.cc | 205 +++++++++++++++--- offline/QA/Tracking/StateClusterResidualsQA.h | 60 ++++- 2 files changed, 235 insertions(+), 30 deletions(-) diff --git a/offline/QA/Tracking/StateClusterResidualsQA.cc b/offline/QA/Tracking/StateClusterResidualsQA.cc index b09662ded0..828c662d34 100644 --- a/offline/QA/Tracking/StateClusterResidualsQA.cc +++ b/offline/QA/Tracking/StateClusterResidualsQA.cc @@ -24,6 +24,7 @@ #include #include +#include #include @@ -112,9 +113,32 @@ int StateClusterResidualsQA::InitRun( for (const auto& cfg : m_pending) { - m_histograms_x.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_x")))); - m_histograms_y.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_y")))); - m_histograms_z.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_z")))); + if (m_use_local_coords) + { + m_histograms_x.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_local_rphi")))); + m_histograms_y.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_local_z")))); + m_histograms_layer_x.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_local_layer_rphi")))); + m_histograms_layer_y.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_local_layer_z")))); + m_histograms_phi_x.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_local_phi_rphi")))); + m_histograms_phi_y.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_local_phi_z")))); + m_histograms_eta_x.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_local_eta_rphi")))); + m_histograms_eta_y.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_local_eta_z")))); + } + else + { + m_histograms_x.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_x")))); + m_histograms_y.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_y")))); + m_histograms_z.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_z")))); + m_histograms_layer_x.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_layer_x")))); + m_histograms_layer_y.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_layer_y")))); + m_histograms_layer_z.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_layer_z")))); + m_histograms_phi_x.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_phi_x")))); + m_histograms_phi_y.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_phi_y")))); + m_histograms_phi_z.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_phi_z")))); + m_histograms_eta_x.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_eta_x")))); + m_histograms_eta_y.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_eta_y")))); + m_histograms_eta_z.push_back(dynamic_cast(hm->getHisto(std::string(cfg.name + "_eta_z")))); + } } return Fun4AllReturnCodes::EVENT_OK; @@ -181,20 +205,52 @@ int StateClusterResidualsQA::process_event(PHCompositeNode* top_node) for (auto const& [path_length, state] : range_adaptor(track->begin_states(), track->end_states())) { if (path_length == 0) { continue; } - + auto *cluster = cluster_map->findCluster(state->get_cluskey()); - float state_x = state->get_x(); - float state_y = state->get_y(); - float state_z = state->get_z(); - Acts::Vector3 glob = geometry->getGlobalPosition(state->get_cluskey(), cluster); - float cluster_x = glob.x(); - float cluster_y = glob.y(); - float cluster_z = glob.z(); - if (cluster) + if (!cluster) + { + continue; + } + + float state_x, state_y, state_z; + float cluster_x, cluster_y, cluster_z; + if (m_use_local_coords == true) { + state_x = state->get_localX(); + state_y = state->get_localY(); + Acts::Vector2 loc = geometry->getLocalCoords(state->get_cluskey(), cluster); + cluster_x = loc.x(); + cluster_y = loc.y(); + m_histograms_x[h]->Fill(state_x - cluster_x); + m_histograms_y[h]->Fill(state_y - cluster_y); + m_histograms_layer_x[h]->Fill(TrkrDefs::getLayer(state->get_cluskey()), state_x - cluster_x); + m_histograms_layer_y[h]->Fill(TrkrDefs::getLayer(state->get_cluskey()), state_y - cluster_y); + m_histograms_phi_x[h]->Fill(state->get_phi(), state_x - cluster_x); + m_histograms_phi_y[h]->Fill(state->get_phi(), state_y - cluster_y); + m_histograms_eta_x[h]->Fill(state->get_eta(), state_x - cluster_x); + m_histograms_eta_y[h]->Fill(state->get_eta(), state_y - cluster_y); + } + else + { + state_x = state->get_x(); + state_y = state->get_y(); + state_z = state->get_z(); + Acts::Vector3 glob = geometry->getGlobalPosition(state->get_cluskey(), cluster); + cluster_x = glob.x(); + cluster_y = glob.y(); + cluster_z = glob.z(); m_histograms_x[h]->Fill(state_x - cluster_x); m_histograms_y[h]->Fill(state_y - cluster_y); m_histograms_z[h]->Fill(state_z - cluster_z); + m_histograms_layer_x[h]->Fill(TrkrDefs::getLayer(state->get_cluskey()), state_x - cluster_x); + m_histograms_layer_y[h]->Fill(TrkrDefs::getLayer(state->get_cluskey()), state_y - cluster_y); + m_histograms_layer_z[h]->Fill(TrkrDefs::getLayer(state->get_cluskey()), state_z - cluster_z); + m_histograms_phi_x[h]->Fill(state->get_phi(), state_x - cluster_x); + m_histograms_phi_y[h]->Fill(state->get_phi(), state_y - cluster_y); + m_histograms_phi_z[h]->Fill(state->get_phi(), state_z - cluster_z); + m_histograms_eta_x[h]->Fill(state->get_eta(), state_x - cluster_x); + m_histograms_eta_y[h]->Fill(state->get_eta(), state_y - cluster_y); + m_histograms_eta_z[h]->Fill(state->get_eta(), state_z - cluster_z); } } } @@ -212,27 +268,122 @@ void StateClusterResidualsQA::createHistos() for (const auto& cfg : m_pending) { - TH1F* h_new_x = new TH1F( + if (m_use_local_coords) + { + TH1F* h_new_x = new TH1F( + (cfg.name + "_local_rphi").c_str(), + ";State-Cluster Local r#phi Residual [cm];Entries", + m_nBins, cfg.rphi_local_lower, cfg.rphi_local_upper); + h_new_x->SetMarkerColor(kBlue); + h_new_x->SetLineColor(kBlue); + hm->registerHisto(h_new_x); + TH1F* h_new_y = new TH1F( + (cfg.name + "_local_z").c_str(), + ";State-Cluster Local Z Residual [cm];Entries", + m_nBins, cfg.z_local_lower, cfg.z_local_upper); + h_new_y->SetMarkerColor(kBlue); + h_new_y->SetLineColor(kBlue); + hm->registerHisto(h_new_y); + TH2F* h_new_layer_x = new TH2F( + (cfg.name + "_local_layer_rphi").c_str(), + ";Layer Number;State-Cluster Local r#phi Residual [cm]", + 60, -0.5, 59.5, m_nBins, cfg.rphi_local_lower, cfg.rphi_local_upper); + hm->registerHisto(h_new_layer_x); + TH2F* h_new_layer_y = new TH2F( + (cfg.name + "_local_layer_z").c_str(), + ";Layer Number;State-Cluster Local Z Residual [cm]", + 60, -0.5, 59.5, m_nBins, cfg.z_local_lower, cfg.z_local_upper); + hm->registerHisto(h_new_layer_y); + TH2F* h_new_phi_x = new TH2F( + (cfg.name + "_local_phi_rphi").c_str(), + ";#phi [rad];State-Cluster Local r#phi Residual [cm]", + 50, -3.2, 3.2, m_nBins, cfg.rphi_local_lower, cfg.rphi_local_upper); + hm->registerHisto(h_new_phi_x); + TH2F* h_new_phi_y = new TH2F( + (cfg.name + "_local_phi_z").c_str(), + ";#phi [rad];State-Cluster Local Z Residual [cm]", + 50, -3.2, 3.2, m_nBins, cfg.z_local_lower, cfg.z_local_upper); + hm->registerHisto(h_new_phi_y); + TH2F* h_new_eta_x = new TH2F( + (cfg.name + "_local_eta_rphi").c_str(), + ";#eta;State-Cluster Local r#phi Residual [cm]", + 50, -1.1, 1.1, m_nBins, cfg.rphi_local_lower, cfg.rphi_local_upper); + hm->registerHisto(h_new_eta_x); + TH2F* h_new_eta_y = new TH2F( + (cfg.name + "_local_eta_z").c_str(), + ";#eta;State-Cluster Local Z Residual [cm]", + 50, -1.1, 1.1, m_nBins, cfg.z_local_lower, cfg.z_local_upper); + hm->registerHisto(h_new_eta_y); + } + else + { + TH1F* h_new_x = new TH1F( (cfg.name + "_x").c_str(), ";State-Cluster X Residual [cm];Entries", - m_nBins, m_xrange.first, m_xrange.second); - h_new_x->SetMarkerColor(kBlue); - h_new_x->SetLineColor(kBlue); - hm->registerHisto(h_new_x); - TH1F* h_new_y = new TH1F( + m_nBins, cfg.x_lower, cfg.x_upper); + h_new_x->SetMarkerColor(kBlue); + h_new_x->SetLineColor(kBlue); + hm->registerHisto(h_new_x); + TH1F* h_new_y = new TH1F( (cfg.name + "_y").c_str(), ";State-Cluster Y Residual [cm];Entries", - m_nBins, m_yrange.first, m_yrange.second); - h_new_y->SetMarkerColor(kBlue); - h_new_y->SetLineColor(kBlue); - hm->registerHisto(h_new_y); - TH1F* h_new_z = new TH1F( + m_nBins, cfg.y_lower, cfg.y_upper); + h_new_y->SetMarkerColor(kBlue); + h_new_y->SetLineColor(kBlue); + hm->registerHisto(h_new_y); + TH1F* h_new_z = new TH1F( (cfg.name + "_z").c_str(), ";State-Cluster Z Residual [cm];Entries", - m_nBins, m_zrange.first, m_zrange.second); - h_new_z->SetMarkerColor(kBlue); - h_new_z->SetLineColor(kBlue); - hm->registerHisto(h_new_z); + m_nBins, cfg.z_lower, cfg.z_upper); + h_new_z->SetMarkerColor(kBlue); + h_new_z->SetLineColor(kBlue); + hm->registerHisto(h_new_z); + TH2F* h_new_layer_x = new TH2F( + (cfg.name + "_layer_x").c_str(), + ";Layer Number;State-Cluster Local X Residual [cm]", + 60, -0.5, 59.5, m_nBins, cfg.x_lower, cfg.x_upper); + hm->registerHisto(h_new_layer_x); + TH2F* h_new_layer_y = new TH2F( + (cfg.name + "_layer_y").c_str(), + ";Layer Number;State-Cluster Local Y Residual [cm]", + 60, -0.5, 59.5, m_nBins, cfg.y_lower, cfg.y_upper); + hm->registerHisto(h_new_layer_y); + TH2F* h_new_layer_z = new TH2F( + (cfg.name + "_layer_z").c_str(), + ";Layer Number;State-Cluster Local Z Residual [cm]", + 60, -0.5, 59.5, m_nBins, cfg.z_lower, cfg.z_upper); + hm->registerHisto(h_new_layer_z); + TH2F* h_new_phi_x = new TH2F( + (cfg.name + "_phi_x").c_str(), + ";#phi [rad];State-Cluster Local X Residual [cm]", + 50, -3.2, 3.2, m_nBins, cfg.x_lower, cfg.x_upper); + hm->registerHisto(h_new_phi_x); + TH2F* h_new_phi_y = new TH2F( + (cfg.name + "_phi_y").c_str(), + ";#phi [rad];State-Cluster Local Y Residual [cm]", + 50, -3.2, 3.2, m_nBins, cfg.y_lower, cfg.y_upper); + hm->registerHisto(h_new_phi_y); + TH2F* h_new_phi_z = new TH2F( + (cfg.name + "_phi_z").c_str(), + ";#phi [rad];State-Cluster Local Z Residual [cm]", + 50, -3.2, 3.2, m_nBins, cfg.z_lower, cfg.z_upper); + hm->registerHisto(h_new_phi_z); + TH2F* h_new_eta_x = new TH2F( + (cfg.name + "_eta_x").c_str(), + ";#eta;State-Cluster Local X Residual [cm]", + 50, -1.1, 1.1, m_nBins, cfg.x_lower, cfg.x_upper); + hm->registerHisto(h_new_eta_x); + TH2F* h_new_eta_y = new TH2F( + (cfg.name + "_eta_y").c_str(), + ";#eta;State-Cluster Local Y Residual [cm]", + 50, -1.1, 1.1, m_nBins, cfg.y_lower, cfg.y_upper); + hm->registerHisto(h_new_eta_y); + TH2F* h_new_eta_z = new TH2F( + (cfg.name + "_eta_z").c_str(), + ";#eta;State-Cluster Local Z Residual [cm]", + 50, -1.1, 1.1, m_nBins, cfg.z_lower, cfg.z_upper); + hm->registerHisto(h_new_eta_z); + } } } diff --git a/offline/QA/Tracking/StateClusterResidualsQA.h b/offline/QA/Tracking/StateClusterResidualsQA.h index 739c816609..ddde8032cc 100644 --- a/offline/QA/Tracking/StateClusterResidualsQA.h +++ b/offline/QA/Tracking/StateClusterResidualsQA.h @@ -13,6 +13,7 @@ class PHCompositeNode; class TH1; +class TH2; struct ResidualHistConfig { @@ -35,6 +36,17 @@ struct ResidualHistConfig float pt_max = FLT_MAX; int charge = 0; + + float rphi_local_lower = -0.5; + float rphi_local_upper = 0.5; + float z_local_lower = -0.5; + float z_local_upper = 0.5; + float x_lower = -0.5; + float x_upper = 0.5; + float y_lower = -0.5; + float y_upper = 0.5; + float z_lower = -0.5; + float z_upper = 0.5; }; class StateClusterResidualsQA : public SubsysReco @@ -89,6 +101,36 @@ class StateClusterResidualsQA : public SubsysReco m_pending.back().pt_max = max; return *this; } + StateClusterResidualsQA& setXRange(float min, float max) + { + m_pending.back().x_lower = min; + m_pending.back().x_upper = max; + return *this; + } + StateClusterResidualsQA& setYRange(float min, float max) + { + m_pending.back().y_lower = min; + m_pending.back().y_upper = max; + return *this; + } + StateClusterResidualsQA& setZRange(float min, float max) + { + m_pending.back().z_lower = min; + m_pending.back().z_upper = max; + return *this; + } + StateClusterResidualsQA& setLocalRphiRange(float min, float max) + { + m_pending.back().rphi_local_lower = min; + m_pending.back().rphi_local_upper = max; + return *this; + } + StateClusterResidualsQA& setLocalZRange(float min, float max) + { + m_pending.back().z_local_lower = min; + m_pending.back().z_local_upper = max; + return *this; + } StateClusterResidualsQA& setPositiveTracks() { m_pending.back().charge = 1; @@ -99,6 +141,11 @@ class StateClusterResidualsQA : public SubsysReco m_pending.back().charge = -1; return *this; } + + void setUseLocalCoords() + { + m_use_local_coords = true; + } void createHistos(); @@ -115,13 +162,20 @@ class StateClusterResidualsQA : public SubsysReco std::string m_clusterContainerName = "TRKR_CLUSTER"; int m_nBins = 50; - std::pair m_xrange {-0.5,0.5}; - std::pair m_yrange {-0.5,0.5}; - std::pair m_zrange {-0.5,0.5}; + bool m_use_local_coords = false; std::vector m_histograms_x{}; std::vector m_histograms_y{}; std::vector m_histograms_z{}; + std::vector m_histograms_layer_x{}; + std::vector m_histograms_layer_y{}; + std::vector m_histograms_layer_z{}; + std::vector m_histograms_phi_x{}; + std::vector m_histograms_phi_y{}; + std::vector m_histograms_phi_z{}; + std::vector m_histograms_eta_x{}; + std::vector m_histograms_eta_y{}; + std::vector m_histograms_eta_z{}; }; #endif // TRACKFITTINGQA_H From 3ab3316d1593fc99b5e70a704614c0e95b743eaf Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Fri, 30 Jan 2026 09:39:48 -0500 Subject: [PATCH 137/393] do not abort for missing trms calib --- offline/packages/mbd/MbdCalib.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/offline/packages/mbd/MbdCalib.cc b/offline/packages/mbd/MbdCalib.cc index 6cc02b0692..1217ebc782 100644 --- a/offline/packages/mbd/MbdCalib.cc +++ b/offline/packages/mbd/MbdCalib.cc @@ -1329,7 +1329,6 @@ int MbdCalib::Download_TimeRMS(const std::string& dbase_location) trms.clear(); } std::fill(_trms_npts.begin(), _trms_npts.end(), 0); - TString dbase_file = dbase_location; #ifndef ONLINE @@ -1436,8 +1435,9 @@ int MbdCalib::Download_TimeRMS(const std::string& dbase_location) if ( _trms_y[0].empty() ) { std::cout << PHWHERE << ", WARNING, trms calib missing " << dbase_location << std::endl; - _status = -1; - return _status; // file not found +// _status = -1; +// return _status; // file not found + return 0; } // Now we interpolate the trms From c09d98c9ad2981c0452b7e446276304f7e26d7cb Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Fri, 30 Jan 2026 16:51:05 -0500 Subject: [PATCH 138/393] Code Review Fixes Addresses Major Issues: - Guard cd against failure to prevent silent misbehavior. - std::stoll can throw if events argument is non-numeric; exception is unhandled. - std::stoi can throw if runnumber argument is non-numeric; exception is unhandled. - Guard zero/NaN sigma before z-score calculations. - Validate pass before casting to Pass to avoid silent no-op runs. --- .../sepd/sepd_eventplanecalib/GenQVecCDB.cc | 29 +++++++++---- .../sepd/sepd_eventplanecalib/GenQVecCalib.cc | 11 +++-- .../sepd/sepd_eventplanecalib/Makefile.am | 2 - .../sepd/sepd_eventplanecalib/QVecCDB.cc | 4 +- .../sepd/sepd_eventplanecalib/QVecCalib.cc | 42 +++++++++++-------- .../sepd/sepd_eventplanecalib/QVecCalib.h | 27 +++++++++--- .../sepd/sepd_eventplanecalib/QVecDefs.h | 9 ++++ .../sepd/sepd_eventplanecalib/autogen.sh | 4 +- .../sepd/sepd_eventplanecalib/sEPD_TreeGen.cc | 9 ++-- .../sepd/sepd_eventplanecalib/sEPD_TreeGen.h | 4 +- 10 files changed, 95 insertions(+), 46 deletions(-) mode change 100644 => 100755 calibrations/sepd/sepd_eventplanecalib/autogen.sh diff --git a/calibrations/sepd/sepd_eventplanecalib/GenQVecCDB.cc b/calibrations/sepd/sepd_eventplanecalib/GenQVecCDB.cc index 7118d71b99..324f774950 100644 --- a/calibrations/sepd/sepd_eventplanecalib/GenQVecCDB.cc +++ b/calibrations/sepd/sepd_eventplanecalib/GenQVecCDB.cc @@ -14,23 +14,34 @@ int main(int argc, const char* const argv[]) } const std::string &input_file = args[1]; - int runnumber = std::stoi(args[2]); const std::string output_dir = (args.size() >= 4) ? args[3] : "."; const std::string cdb_tag = (args.size() >= 5) ? args[4] : "new_newcdbtag_v008"; - std::cout << std::format("{:#<20}\n", ""); - std::cout << std::format("Analysis Params\n"); - std::cout << std::format("Input File: {}\n", input_file); - std::cout << std::format("Run: {}\n", runnumber); - std::cout << std::format("Output Dir: {}\n", output_dir); - std::cout << std::format("CDB Tag: {}\n", cdb_tag); - std::cout << std::format("{:#<20}\n", ""); - try { + int runnumber = std::stoi(args[2]); + + std::cout << std::format("{:#<20}\n", ""); + std::cout << std::format("Analysis Params\n"); + std::cout << std::format("Input File: {}\n", input_file); + std::cout << std::format("Run: {}\n", runnumber); + std::cout << std::format("Output Dir: {}\n", output_dir); + std::cout << std::format("CDB Tag: {}\n", cdb_tag); + std::cout << std::format("{:#<20}\n", ""); + QVecCDB analysis(input_file, runnumber, output_dir, cdb_tag); analysis.run(); } + catch (const std::invalid_argument& e) + { + std::cout << "Error: runnumber must be an integer: " << args[2] << std::endl; + return 1; + } + catch (const std::out_of_range& e) + { + std::cout << "Error: runnumber is out of range for an integer." << std::endl; + return 1; + } catch (const std::exception& e) { std::cout << "An exception occurred: " << e.what() << std::endl; diff --git a/calibrations/sepd/sepd_eventplanecalib/GenQVecCalib.cc b/calibrations/sepd/sepd_eventplanecalib/GenQVecCalib.cc index 67ec64fbeb..0dd1fa1fbe 100644 --- a/calibrations/sepd/sepd_eventplanecalib/GenQVecCalib.cc +++ b/calibrations/sepd/sepd_eventplanecalib/GenQVecCalib.cc @@ -15,9 +15,8 @@ int main(int argc, const char* const argv[]) const std::string &input_file = args[1]; const std::string &input_hist = args[2]; const std::string &input_Q_calib = args[3]; - const std::string &pass_str = (argc >= 5) ? args[4] : "ComputeRecentering"; // Default to the first pass - long long events = (argc >= 6) ? std::stoll(args[5]) : 0; - std::string output_dir = (argc >= 7) ? args[6] : "."; + const std::string &pass_str = (args.size() >= 5) ? args[4] : "ComputeRecentering"; // Default to the first pass + std::string output_dir = (args.size() >= 7) ? args[6] : "."; const std::map pass_map = { {"ComputeRecentering", QVecCalib::Pass::ComputeRecentering}, @@ -39,9 +38,15 @@ int main(int argc, const char* const argv[]) try { + long long events = (args.size() >= 6) ? std::stoll(args[5]) : 0; QVecCalib analysis(input_file, input_hist, input_Q_calib, static_cast(pass), events, output_dir); analysis.run(); } + catch (const std::invalid_argument& e) + { + std::cout << "Error: events must be an integer" << std::endl; + return 1; + } catch (const std::exception& e) { std::cout << "An exception occurred: " << e.what() << std::endl; diff --git a/calibrations/sepd/sepd_eventplanecalib/Makefile.am b/calibrations/sepd/sepd_eventplanecalib/Makefile.am index f1da8a7800..145947f5e7 100644 --- a/calibrations/sepd/sepd_eventplanecalib/Makefile.am +++ b/calibrations/sepd/sepd_eventplanecalib/Makefile.am @@ -42,11 +42,9 @@ libsepd_eventplanecalib_la_LIBADD = \ -lepd_io GenQVecCalib_SOURCES = GenQVecCalib.cc -# GenQVecCalib_CXXFLAGS = -fsanitize=address GenQVecCalib_LDADD = libsepd_eventplanecalib.la GenQVecCDB_SOURCES = GenQVecCDB.cc -# GenQVecCDB_CXXFLAGS = -fsanitize=address GenQVecCDB_LDADD = libsepd_eventplanecalib.la BUILT_SOURCES = testexternals.cc diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecCDB.cc b/calibrations/sepd/sepd_eventplanecalib/QVecCDB.cc index b18bf4c345..4719821868 100644 --- a/calibrations/sepd/sepd_eventplanecalib/QVecCDB.cc +++ b/calibrations/sepd/sepd_eventplanecalib/QVecCDB.cc @@ -135,13 +135,13 @@ void QVecCDB::write_cdb_BadTowers(const std::string &output_dir) float sigma = 0; // Hot - if (status == 2) + if (status == static_cast(QVecShared::ChannelStatus::Hot)) { sigma = SIGMA_HOT; } // Cold - else if (status == 3) + else if (status == static_cast(QVecShared::ChannelStatus::Cold)) { sigma = SIGMA_COLD; } diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc index 2148124032..b8c26dab28 100644 --- a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc +++ b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc @@ -165,6 +165,11 @@ void QVecCalib::process_sEPD_event_thresholds(TFile* file) hSEPD_Charge_Min->Fill(cent, charge_low); hSEPD_Charge_Max->Fill(cent, charge_high); + if (sigma == 0) + { + continue; + } + for (int x = 1; x <= binsx; ++x) { double charge = h2SEPD_Charge->GetXaxis()->GetBinCenter(x); @@ -192,7 +197,6 @@ void QVecCalib::process_bad_channels(TFile* file) auto* hSEPD_Charge = dynamic_cast(hist); - int sepd_channels = 744; int rbins = 16; int bins_charge = 40; @@ -216,7 +220,7 @@ void QVecCalib::process_bad_channels(TFile* file) rbins, -0.5, rbins - 0.5, bins_charge, 0, bins_charge); - m_profiles["h_sEPD_Bad_Channels"] = std::make_unique("h_sEPD_Bad_Channels", "sEPD Bad Channels; Channel; Status", sepd_channels, -0.5, sepd_channels-0.5); + m_profiles["h_sEPD_Bad_Channels"] = std::make_unique("h_sEPD_Bad_Channels", "sEPD Bad Channels; Channel; Status", QVecShared::sepd_channels, -0.5, QVecShared::sepd_channels-0.5); auto* h2S = m_hists2D["h2SEPD_South_Charge_rbin"].get(); auto* h2N = m_hists2D["h2SEPD_North_Charge_rbin"].get(); @@ -226,7 +230,7 @@ void QVecCalib::process_bad_channels(TFile* file) auto* hBad = m_profiles["h_sEPD_Bad_Channels"].get(); - for (int channel = 0; channel < sepd_channels; ++channel) + for (int channel = 0; channel < QVecShared::sepd_channels; ++channel) { unsigned int key = TowerInfoDefs::encode_epd(static_cast(channel)); int rbin = static_cast(TowerInfoDefs::get_epd_rbin(key)); @@ -246,7 +250,7 @@ void QVecCalib::process_bad_channels(TFile* file) int ctr_hot = 0; int ctr_cold = 0; - for (int channel = 0; channel < sepd_channels; ++channel) + for (int channel = 0; channel < QVecShared::sepd_channels; ++channel) { unsigned int key = TowerInfoDefs::encode_epd(static_cast(channel)); int rbin = static_cast(TowerInfoDefs::get_epd_rbin(key)); @@ -258,7 +262,12 @@ void QVecCalib::process_bad_channels(TFile* file) double charge = hSEPD_Charge->GetBinContent(channel + 1); double mean_charge = hprof->GetBinContent(rbin + 1); double sigma = hprof->GetBinError(rbin + 1); - double zscore = (charge - mean_charge) / sigma; + double zscore = 0.0; + + if (sigma > 0) + { + zscore = (charge - mean_charge) / sigma; + } if (charge < m_sEPD_min_avg_charge_threshold || std::fabs(zscore) > m_sEPD_sigma_threshold) { @@ -271,21 +280,21 @@ void QVecCalib::process_bad_channels(TFile* file) if (charge == 0) { type = "Dead"; - status_fill = 1; + status_fill = static_cast(QVecShared::ChannelStatus::Dead); ++ctr_dead; } // hot channel else if (zscore > m_sEPD_sigma_threshold) { type = "Hot"; - status_fill = 2; + status_fill = static_cast(QVecShared::ChannelStatus::Hot); ++ctr_hot; } // cold channel else { type = "Cold"; - status_fill = 3; + status_fill = static_cast(QVecShared::ChannelStatus::Cold); ++ctr_cold; } @@ -426,7 +435,7 @@ void QVecCalib::init_hists() } } -void QVecCalib::process_averages(double cent, QVecShared::QVec q_S, QVecShared::QVec q_N, const AverageHists& h) +void QVecCalib::process_averages(double cent, const QVecShared::QVec& q_S, const QVecShared::QVec& q_N, const AverageHists& h) { double psi_S = std::atan2(q_S.y, q_S.x); double psi_N = std::atan2(q_N.y, q_N.x); @@ -442,7 +451,7 @@ void QVecCalib::process_averages(double cent, QVecShared::QVec q_S, QVecShared:: h.Psi_NS->Fill(cent, psi_NS); } -void QVecCalib::process_recentering(double cent, size_t h_idx, QVecShared::QVec q_S, QVecShared::QVec q_N, const RecenterHists& h) +void QVecCalib::process_recentering(double cent, size_t h_idx, const QVecShared::QVec& q_S, const QVecShared::QVec& q_N, const RecenterHists& h) { size_t cent_bin = static_cast(m_hists1D["h_Cent"]->FindBin(cent) - 1); @@ -483,7 +492,7 @@ void QVecCalib::process_recentering(double cent, size_t h_idx, QVecShared::QVec h.Psi_NS_corr->Fill(cent, psi_NS_corr); } -void QVecCalib::process_flattening(double cent, size_t h_idx, QVecShared::QVec q_S, QVecShared::QVec q_N, const FlatteningHists& h) +void QVecCalib::process_flattening(double cent, size_t h_idx, const QVecShared::QVec& q_S, const QVecShared::QVec& q_N, const FlatteningHists& h) { size_t cent_bin = static_cast(m_hists1D["h_Cent"]->FindBin(cent) - 1); @@ -993,18 +1002,17 @@ void QVecCalib::run_event_loop() m_chain->GetEntry(i); m_event_data.reset(); - if (i % 10000 == 0) + if (i % PROGRESS_REPORT_INTERVAL == 0) { - std::cout << std::format("Processing {}/{}: {:.2f} %", i, n_entries, static_cast(i) * 100. / static_cast(n_entries)) << std::endl; + std::cout << std::format("Processing {}/{}: {:.2f} %", i, n_entries, static_cast(i) / n_entries * 100.) << std::endl; } double cent = m_event_data.event_centrality; - // Identify Centrality Bin - size_t cent_bin = static_cast(m_hists1D["h_Cent"]->FindBin(cent) - 1); + int cent_bin_int = m_hists1D["h_Cent"]->FindBin(cent) - 1; // ensure centrality is valid - if (cent_bin >= m_cent_bins) + if (cent_bin_int < 0 || static_cast(cent_bin_int) >= m_cent_bins) { std::cout << std::format("Weird Centrality: {}, Skipping Event: {}\n", cent, m_event_data.event_id); ++ctr["invalid_cent_bin"]; @@ -1059,7 +1067,7 @@ void QVecCalib::run_event_loop() std::cout << "Skipped Event Types\n"; for (const auto& [name, events] : ctr) { - std::cout << std::format("{}: {}, {:.2f} %\n", name, events, events * 100. / static_cast(n_entries)); + std::cout << std::format("{}: {}, {:.2f} %\n", name, events, static_cast(events) / n_entries * 100.); } // --------------- diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.h b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.h index a10c3e14f9..7a70cfb03e 100644 --- a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.h +++ b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.h @@ -19,6 +19,7 @@ #include #include #include +#include /** * @class QVecCalib @@ -43,7 +44,7 @@ class QVecCalib : m_input_file(std::move(input_file)) , m_input_hist(std::move(input_hist)) , m_input_Q_calib(std::move(input_Q_calib)) - , m_pass(static_cast(pass)) + , m_pass(validate_pass(pass)) , m_events_to_process(events) , m_output_dir(std::move(output_dir)) { @@ -66,6 +67,20 @@ class QVecCalib }; private: + static Pass validate_pass(int pass) + { + switch (pass) + { + case 0: + return Pass::ComputeRecentering; + case 1: + return Pass::ApplyRecentering; + case 2: + return Pass::ApplyFlattening; + default: + throw std::invalid_argument("Invalid pass value"); + } + } struct CorrectionData { @@ -78,6 +93,8 @@ class QVecCalib double m_cent_low = -0.5; double m_cent_high = 79.5; + static constexpr int PROGRESS_REPORT_INTERVAL = 10000; + // Holds all correction data // key: [Cent][Harmonic][Subdetector] // Harmonics {2,3,4} -> 3 elements @@ -183,7 +200,7 @@ class QVecCalib std::string m_input_file; std::string m_input_hist; std::string m_input_Q_calib; - Pass m_pass{0}; + Pass m_pass{Pass::ComputeRecentering}; long long m_events_to_process; std::string m_output_dir; @@ -289,7 +306,7 @@ class QVecCalib * @param q_N The North arm normalized Q-vector. * @param h Reference to the cache of profiles for the first pass. */ - static void process_averages(double cent, QVecShared::QVec q_S, QVecShared::QVec q_N, const AverageHists& h); + static void process_averages(double cent, const QVecShared::QVec& q_S, const QVecShared::QVec& q_N, const AverageHists& h); /** * @brief Applies re-centering offsets and fills profiles for second-moment calculation. @@ -299,7 +316,7 @@ class QVecCalib * @param q_N The North arm normalized Q-vector. * @param h Reference to the cache of profiles for the second pass. */ - void process_recentering(double cent, size_t h_idx, QVecShared::QVec q_S, QVecShared::QVec q_N, const RecenterHists& h); + void process_recentering(double cent, size_t h_idx, const QVecShared::QVec& q_S, const QVecShared::QVec& q_N, const RecenterHists& h); /** * @brief Applies the full correction (re-centering + flattening) for validation. @@ -309,7 +326,7 @@ class QVecCalib * @param q_N The North arm normalized Q-vector. * @param h Reference to the cache of profiles for the third pass. */ - void process_flattening(double cent, size_t h_idx, QVecShared::QVec q_S, QVecShared::QVec q_N, const FlatteningHists& h); + void process_flattening(double cent, size_t h_idx, const QVecShared::QVec& q_S, const QVecShared::QVec& q_N, const FlatteningHists& h); /** * @brief Calculates the 2x2 anisotropy correction (whitening) matrix. diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h b/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h index bea362b661..0b42e1f105 100644 --- a/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h +++ b/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h @@ -10,6 +10,15 @@ namespace QVecShared { static constexpr size_t CENT_BINS = 8; static constexpr std::array HARMONICS = {2, 3, 4}; + static constexpr int sepd_channels = 744; + + enum class ChannelStatus : int + { + Good = 0, + Dead = 1, + Hot = 2, + Cold = 3 + }; enum class Subdetector { diff --git a/calibrations/sepd/sepd_eventplanecalib/autogen.sh b/calibrations/sepd/sepd_eventplanecalib/autogen.sh old mode 100644 new mode 100755 index dea267bbfd..18aced5f8f --- a/calibrations/sepd/sepd_eventplanecalib/autogen.sh +++ b/calibrations/sepd/sepd_eventplanecalib/autogen.sh @@ -2,7 +2,7 @@ srcdir=`dirname $0` test -z "$srcdir" && srcdir=. -(cd $srcdir; aclocal -I ${OFFLINE_MAIN}/share;\ -libtoolize --force; automake -a --add-missing; autoconf) +(cd "$srcdir" || exit 1; aclocal -I "${OFFLINE_MAIN}/share" && +libtoolize --force && automake -a --add-missing && autoconf) $srcdir/configure "$@" diff --git a/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc b/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc index be03589d40..7b5c3867a9 100644 --- a/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc +++ b/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc @@ -1,4 +1,5 @@ #include "sEPD_TreeGen.h" +#include "QVecDefs.h" // -- c++ #include @@ -52,7 +53,7 @@ int sEPD_TreeGen::Init([[maybe_unused]] PHCompositeNode *topNode) double centrality_low{-0.5}; double centrality_high{79.5}; - hSEPD_Charge = std::make_unique("hSEPD_Charge", "|z| < 10 cm and MB; Channel; Avg Charge", m_sepd_channels, 0, m_sepd_channels); + hSEPD_Charge = std::make_unique("hSEPD_Charge", "|z| < 10 cm and MB; Channel; Avg Charge", QVecShared::sepd_channels, 0, QVecShared::sepd_channels); hSEPD_Charge->Sumw2(); h2SEPD_totalcharge_centrality = std::make_unique("h2SEPD_totalcharge_centrality", "|z| < 10 cm and MB; sEPD Total Charge; Centrality [%]", bins_sepd_totalcharge, sepd_totalcharge_low, sepd_totalcharge_high, bins_centrality, centrality_low, centrality_high); @@ -166,11 +167,11 @@ int sEPD_TreeGen::process_sEPD(PHCompositeNode *topNode) // sepd unsigned int sepd_channels = towerinfosEPD->size(); - if(sepd_channels != m_sepd_channels) + if(sepd_channels != QVecShared::sepd_channels) { if (Verbosity() > 2) { - std::cout << "Event: " << m_data.event_id << ", SEPD Channels = " << sepd_channels << " != " << m_sepd_channels << std::endl; + std::cout << "Event: " << m_data.event_id << ", SEPD Channels = " << sepd_channels << " != " << QVecShared::sepd_channels << std::endl; } return Fun4AllReturnCodes::ABORTEVENT; } @@ -220,7 +221,7 @@ int sEPD_TreeGen::process_event(PHCompositeNode *topNode) m_data.event_id = eventInfo->get_EvtSequence(); - if (Verbosity() > 1 && m_event % 20 == 0) + if (Verbosity() > 1 && m_event % PROGRESS_PRINT_INTERVAL == 0) { std::cout << "Progress: " << m_event << ", Global: " << m_data.event_id << std::endl; } diff --git a/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.h b/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.h index 225e62cc8f..57436314fb 100644 --- a/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.h +++ b/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.h @@ -99,7 +99,7 @@ class sEPD_TreeGen : public SubsysReco */ void set_sepd_charge_threshold(double charge_min) { - m_cuts.m_sepd_charge_min= charge_min; + m_cuts.m_sepd_charge_min = charge_min; } /** @@ -139,7 +139,7 @@ class sEPD_TreeGen : public SubsysReco std::string m_outfile_name{"test.root"}; std::string m_outtree_name{"tree.root"}; - static constexpr int m_sepd_channels = 744; + static constexpr int PROGRESS_PRINT_INTERVAL = 20; // Cuts struct Cuts From 32892881d48e294245287b22dd09eb0befc05375 Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Fri, 30 Jan 2026 17:41:14 -0500 Subject: [PATCH 139/393] Code Review Fixes 2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses Major Issues: - Type truncation: GetXmin()/GetXmax() return Double_t, stored as int. - Sigma guard placed after Fill — degenerate thresholds when sigma is zero. - Differentiate “already exists” from directory-creation failure. - Guard against null TowerInfo* to avoid crashes. The get_tower_at_channel() method returns. --- calibrations/sepd/sepd_eventplanecalib/QVecCDB.cc | 7 ++++++- .../sepd/sepd_eventplanecalib/QVecCalib.cc | 15 ++++++++------- .../sepd/sepd_eventplanecalib/sEPD_TreeGen.cc | 9 +++++++++ 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecCDB.cc b/calibrations/sepd/sepd_eventplanecalib/QVecCDB.cc index 4719821868..ef284faa9d 100644 --- a/calibrations/sepd/sepd_eventplanecalib/QVecCDB.cc +++ b/calibrations/sepd/sepd_eventplanecalib/QVecCDB.cc @@ -103,10 +103,15 @@ void QVecCDB::write_cdb() { std::string output_dir = std::format("{}/{}", m_output_dir, m_runnumber); - if (std::filesystem::create_directories(output_dir)) + std::error_code ec; + if (std::filesystem::create_directories(output_dir, ec)) { std::cout << std::format("Success: Directory {} created.\n", output_dir); } + else if (ec) + { + throw std::runtime_error(std::format("Failed to create directory {}: {}", output_dir, ec.message())); + } else { std::cout << std::format("Info: Directory {} already exists.\n", output_dir); diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc index b8c26dab28..02a13c896b 100644 --- a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc +++ b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc @@ -145,8 +145,8 @@ void QVecCalib::process_sEPD_event_thresholds(TFile* file) int binsx = h2SEPD_Charge->GetNbinsX(); int binsy = h2SEPD_Charge->GetNbinsY(); - int ymin = h2SEPD_Charge->GetYaxis()->GetXmin(); - int ymax = h2SEPD_Charge->GetYaxis()->GetXmax(); + double ymin = h2SEPD_Charge->GetYaxis()->GetXmin(); + double ymax = h2SEPD_Charge->GetYaxis()->GetXmax(); m_profiles["hSEPD_Charge_Min"] = std::make_unique("hSEPD_Charge_Min", "; Centrality [%]; sEPD Total Charge", binsy, ymin, ymax); m_profiles["hSEPD_Charge_Max"] = std::make_unique("hSEPD_Charge_Max", "; Centrality [%]; sEPD Total Charge", binsy, ymin, ymax); @@ -159,17 +159,18 @@ void QVecCalib::process_sEPD_event_thresholds(TFile* file) double cent = h2SEPD_Charge_py->GetBinCenter(y); double mean = h2SEPD_Charge_py->GetBinContent(y); double sigma = h2SEPD_Charge_py->GetBinError(y); - double charge_low = mean - m_sEPD_sigma_threshold * sigma; - double charge_high = mean + m_sEPD_sigma_threshold * sigma; - - hSEPD_Charge_Min->Fill(cent, charge_low); - hSEPD_Charge_Max->Fill(cent, charge_high); if (sigma == 0) { continue; } + double charge_low = mean - m_sEPD_sigma_threshold * sigma; + double charge_high = mean + m_sEPD_sigma_threshold * sigma; + + hSEPD_Charge_Min->Fill(cent, charge_low); + hSEPD_Charge_Max->Fill(cent, charge_high); + for (int x = 1; x <= binsx; ++x) { double charge = h2SEPD_Charge->GetXaxis()->GetBinCenter(x); diff --git a/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc b/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc index 7b5c3867a9..2f333b78f3 100644 --- a/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc +++ b/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc @@ -184,6 +184,15 @@ int sEPD_TreeGen::process_sEPD(PHCompositeNode *topNode) TowerInfo *tower = towerinfosEPD->get_tower_at_channel(channel); + if (!tower) + { + if (Verbosity() > 2) + { + std::cout << PHWHERE << "Null SEPD tower at channel " << channel << std::endl; + } + continue; + } + double charge = tower->get_energy(); bool isZS = tower->get_isZS(); double phi = epdgeom->get_phi(key); From 89bb30bbe4ce00b5112f95e5534d047dda8cfc01 Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Fri, 30 Jan 2026 18:05:18 -0500 Subject: [PATCH 140/393] Code Review Fixes 3 Addresses Major Issues: - Potential undefined behavior from unchecked cast; memory leak from ProfileY. - Memory leak from ProfileX calls. - Output file creation not validated. - Add guard to prevent histogram and tree filename collision. - Add error checking for TFile creation before writing. --- .../sepd/sepd_eventplanecalib/QVecCalib.cc | 23 ++++++++++++++----- .../sepd/sepd_eventplanecalib/sEPD_TreeGen.cc | 14 +++++++++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc index 02a13c896b..762588a0da 100644 --- a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc +++ b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc @@ -135,13 +135,19 @@ void QVecCalib::process_sEPD_event_thresholds(TFile* file) throw std::runtime_error(std::format("Cannot find hist: {}", sepd_totalcharge_centrality)); } - m_hists2D["h2SEPD_Charge"] = std::unique_ptr(static_cast(hist->Clone("h2SEPD_Charge"))); - m_hists2D["h2SEPD_Chargev2"] = std::unique_ptr(static_cast(hist->Clone("h2SEPD_Chargev2"))); + auto* h2_check = dynamic_cast(hist); + if (!h2_check) + { + throw std::runtime_error(std::format("Histogram '{}' is not a TH2", sepd_totalcharge_centrality)); + } + + m_hists2D["h2SEPD_Charge"] = std::unique_ptr(static_cast(h2_check->Clone("h2SEPD_Charge"))); + m_hists2D["h2SEPD_Chargev2"] = std::unique_ptr(static_cast(h2_check->Clone("h2SEPD_Chargev2"))); auto* h2SEPD_Charge = m_hists2D["h2SEPD_Charge"].get(); auto* h2SEPD_Chargev2 = m_hists2D["h2SEPD_Chargev2"].get(); - auto* h2SEPD_Charge_py = h2SEPD_Charge->ProfileY("h2SEPD_Charge_py", 1, -1, "s"); + std::unique_ptr h2SEPD_Charge_py(h2SEPD_Charge->ProfileY("h2SEPD_Charge_py", 1, -1, "s")); int binsx = h2SEPD_Charge->GetNbinsX(); int binsy = h2SEPD_Charge->GetNbinsY(); @@ -244,8 +250,8 @@ void QVecCalib::process_bad_channels(TFile* file) h2->Fill(rbin, avg_charge); } - auto* hSpx = h2S->ProfileX("hSpx", 2, -1, "s"); - auto* hNpx = h2N->ProfileX("hNpx", 2, -1, "s"); + std::unique_ptr hSpx(h2S->ProfileX("hSpx", 2, -1, "s")); + std::unique_ptr hNpx(h2N->ProfileX("hNpx", 2, -1, "s")); int ctr_dead = 0; int ctr_hot = 0; @@ -258,7 +264,7 @@ void QVecCalib::process_bad_channels(TFile* file) unsigned int arm = TowerInfoDefs::get_epd_arm(key); auto* h2 = (arm == 0) ? h2Sv2 : h2Nv2; - auto* hprof = (arm == 0) ? hSpx : hNpx; + auto* hprof = (arm == 0) ? hSpx.get() : hNpx.get(); double charge = hSEPD_Charge->GetBinContent(channel + 1); double mean_charge = hprof->GetBinContent(rbin + 1); @@ -1230,6 +1236,11 @@ void QVecCalib::save_results() const auto output_file = std::make_unique(output_filename.c_str(), "RECREATE"); + if (!output_file || output_file->IsZombie()) + { + throw std::runtime_error(std::format("Failed to create output file: {}", output_filename)); + } + for (const auto& [name, hist] : m_hists1D) { std::cout << std::format("Saving 1D: {}\n", name); diff --git a/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc b/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc index 2f333b78f3..38c9a25c18 100644 --- a/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc +++ b/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc @@ -42,6 +42,13 @@ sEPD_TreeGen::sEPD_TreeGen(const std::string &name) //____________________________________________________________________________.. int sEPD_TreeGen::Init([[maybe_unused]] PHCompositeNode *topNode) { + // Early guard against filename collision + if (m_outfile_name == m_outtree_name) + { + std::cout << PHWHERE << " Error: Histogram filename and Tree filename are identical: " << m_outfile_name << ". This will cause data loss." << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + Fun4AllServer *se = Fun4AllServer::instance(); se->Print("NODETREE"); @@ -59,6 +66,13 @@ int sEPD_TreeGen::Init([[maybe_unused]] PHCompositeNode *topNode) h2SEPD_totalcharge_centrality = std::make_unique("h2SEPD_totalcharge_centrality", "|z| < 10 cm and MB; sEPD Total Charge; Centrality [%]", bins_sepd_totalcharge, sepd_totalcharge_low, sepd_totalcharge_high, bins_centrality, centrality_low, centrality_high); m_output = std::make_unique(m_outtree_name.c_str(), "recreate"); + + if (!m_output || m_output->IsZombie()) + { + std::cout << PHWHERE << "Failed to open tree output file: " << m_outtree_name << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + m_output->cd(); // TTree From 5a30bf17e5be129d13c314818e7238da22084f35 Mon Sep 17 00:00:00 2001 From: mchiu-bnl Date: Fri, 30 Jan 2026 18:09:09 -0500 Subject: [PATCH 141/393] doesn't try to download sampmax calibs etc for sims --- offline/packages/mbd/MbdCalib.cc | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/offline/packages/mbd/MbdCalib.cc b/offline/packages/mbd/MbdCalib.cc index 1217ebc782..8f2245d1ca 100644 --- a/offline/packages/mbd/MbdCalib.cc +++ b/offline/packages/mbd/MbdCalib.cc @@ -2080,6 +2080,35 @@ int MbdCalib::Write_CDB_TimeCorr(const std::string& dbfile) } #endif +int MbdCalib::Write_TimeCorr(const std::string& dbfile) +{ + std::ofstream cal_timecorr_file; + cal_timecorr_file.open(dbfile); + for (int ifeech = 0; ifeech < MbdDefs::MBD_N_FEECH; ifeech++) + { + if ( _mbdgeom->get_type(ifeech) == 1 ) + { + continue; // skip q-channels + } + cal_timecorr_file << ifeech << "\t" << _tcorr_npts[ifeech] << "\t" << _tcorr_minrange[ifeech] << "\t" << _tcorr_maxrange[ifeech] << std::endl; + for (int ipt=0; ipt<_tcorr_npts[ifeech]; ipt++) + { + cal_timecorr_file << _tcorr_y[ifeech][ipt]; + if ( ipt%10 == 9 ) + { + cal_timecorr_file << std::endl; + } + else + { + cal_timecorr_file << " "; + } + } + } + cal_timecorr_file.close(); + + return 1; +} + #ifndef ONLINE int MbdCalib::Write_CDB_SlewCorr(const std::string& dbfile) { From 2d1a74a2ea14888af525b3dd549015ca127684e2 Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Fri, 30 Jan 2026 18:14:07 -0500 Subject: [PATCH 142/393] Code Review Fixes 4 Addresses Major Issues: - Missing null check after dynamic_cast. --- calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc index 762588a0da..b2a4a97e55 100644 --- a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc +++ b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc @@ -204,6 +204,11 @@ void QVecCalib::process_bad_channels(TFile* file) auto* hSEPD_Charge = dynamic_cast(hist); + if (!hSEPD_Charge) + { + throw std::runtime_error(std::format("Histogram '{}' is not a TH1", sepd_charge_hist)); + } + int rbins = 16; int bins_charge = 40; From fde222e972808184602e8af9ca51cef370d1286c Mon Sep 17 00:00:00 2001 From: mchiu-bnl Date: Fri, 30 Jan 2026 18:21:03 -0500 Subject: [PATCH 143/393] fixed rabbit error --- offline/packages/mbd/MbdCalib.cc | 5 +++ offline/packages/mbd/MbdCalib.h | 1 + offline/packages/mbd/MbdEvent.cc | 75 ++++++++++++++++++-------------- 3 files changed, 49 insertions(+), 32 deletions(-) diff --git a/offline/packages/mbd/MbdCalib.cc b/offline/packages/mbd/MbdCalib.cc index 8f2245d1ca..946b9658db 100644 --- a/offline/packages/mbd/MbdCalib.cc +++ b/offline/packages/mbd/MbdCalib.cc @@ -2084,6 +2084,11 @@ int MbdCalib::Write_TimeCorr(const std::string& dbfile) { std::ofstream cal_timecorr_file; cal_timecorr_file.open(dbfile); + if (!cal_timecorr_file.is_open()) + { + std::cout << PHWHERE << "unable to open " << dbfile << std::endl; + return -1; + } for (int ifeech = 0; ifeech < MbdDefs::MBD_N_FEECH; ifeech++) { if ( _mbdgeom->get_type(ifeech) == 1 ) diff --git a/offline/packages/mbd/MbdCalib.h b/offline/packages/mbd/MbdCalib.h index 1f450cb5be..49129ac749 100644 --- a/offline/packages/mbd/MbdCalib.h +++ b/offline/packages/mbd/MbdCalib.h @@ -152,6 +152,7 @@ class MbdCalib int Write_TTT0(const std::string& dbfile); int Write_T0Corr(const std::string& dbfile); int Write_Ped(const std::string& dbfile); + int Write_TimeCorr(const std::string& dbfile); int Write_Gains(const std::string& dbfile); int Write_Pileup(const std::string& dbfile); int Write_Thresholds(const std::string& dbfile); diff --git a/offline/packages/mbd/MbdEvent.cc b/offline/packages/mbd/MbdEvent.cc index b8782b8044..72cecb212d 100644 --- a/offline/packages/mbd/MbdEvent.cc +++ b/offline/packages/mbd/MbdEvent.cc @@ -151,14 +151,16 @@ int MbdEvent::InitRun() _mbdcal->SetRawDstFlag( _rawdstflag ); _mbdcal->SetFitsOnly( _fitsonly ); - int status = _mbdcal->Download_All(); - if ( status == -1 ) - { - return Fun4AllReturnCodes::ABORTRUN; - } if ( _simflag == 0 ) // do following for real data { + // Download calibrations + int status = _mbdcal->Download_All(); + if ( status == -1 ) + { + return Fun4AllReturnCodes::ABORTRUN; + } + // load pass1 calibs from local file for calpass2+ if ( _calpass>1 ) { @@ -180,35 +182,36 @@ int MbdEvent::InitRun() _calib_done = 0; std::cout << PHWHERE << ",no sampmax calib, determining it on the fly using first " << _no_sampmax << " evts." << std::endl; } - } - - // Init parameters of the signal processing - for (int ifeech = 0; ifeech < MbdDefs::BBC_N_FEECH; ifeech++) - { - _mbdsig[ifeech].SetCalib(_mbdcal); - // Do evt-by-evt pedestal using sample range below - if ( _calpass==1 || _is_online || _no_sampmax>0 ) - { - _mbdsig[ifeech].SetEventPed0Range(0,1); - } - else + // Init parameters of the signal processing + for (int ifeech = 0; ifeech < MbdDefs::BBC_N_FEECH; ifeech++) { - const int presamp = 5; // start from 5 samples before sampmax - const int nsamps = -1; // use all to sample 0 - _mbdsig[ifeech].SetEventPed0PreSamp(presamp, nsamps, _mbdcal->get_sampmax(ifeech)); - } + _mbdsig[ifeech].SetCalib(_mbdcal); - // Read in template if specified - if ( do_templatefit && _mbdgeom->get_type(ifeech)==1 ) - { - // std::cout << PHWHERE << "Reading template " << ifeech << std::endl; - // std::cout << "SIZES0 " << _mbdcal->get_shape(ifeech).size() << std::endl; - // Should set template size automatically here - _mbdsig[ifeech].SetTemplate(_mbdcal->get_shape(ifeech), _mbdcal->get_sherr(ifeech)); - _mbdsig[ifeech].SetMinMaxFitTime(_mbdcal->get_sampmax(ifeech) - 2 - 3, _mbdcal->get_sampmax(ifeech) - 2 + 3); - //_mbdsig[ifeech].SetMinMaxFitTime( 0, 31 ); + // Do evt-by-evt pedestal using sample range below + if ( _calpass==1 || _is_online || _no_sampmax>0 ) + { + _mbdsig[ifeech].SetEventPed0Range(0,1); + } + else + { + const int presamp = 5; // start from 5 samples before sampmax + const int nsamps = -1; // use all to sample 0 + _mbdsig[ifeech].SetEventPed0PreSamp(presamp, nsamps, _mbdcal->get_sampmax(ifeech)); + } + + // Read in template if specified + if ( do_templatefit && _mbdgeom->get_type(ifeech)==1 ) + { + // std::cout << PHWHERE << "Reading template " << ifeech << std::endl; + // std::cout << "SIZES0 " << _mbdcal->get_shape(ifeech).size() << std::endl; + // Should set template size automatically here + _mbdsig[ifeech].SetTemplate(_mbdcal->get_shape(ifeech), _mbdcal->get_sherr(ifeech)); + _mbdsig[ifeech].SetMinMaxFitTime(_mbdcal->get_sampmax(ifeech) - 2 - 3, _mbdcal->get_sampmax(ifeech) - 2 + 3); + //_mbdsig[ifeech].SetMinMaxFitTime( 0, 31 ); + } } + } if ( _calpass > 0 ) @@ -816,6 +819,16 @@ int MbdEvent::ProcessRawContainer(MbdRawContainer *bbcraws, MbdPmtContainer *bbc m_pmttt[pmtch] -= _mbdcal->get_tt0(pmtch); } + /* + if ( !std::isnan(m_pmttt[pmtch]) ) + { + std::cout << "pmttt " << m_evt << "\t" << pmtch << "\t" << m_pmttt[pmtch] << "\t" + << bbcraws->get_pmt(pmtch)->get_ttdc() << "\t" + << _mbdcal->get_tcorr(ifeech,bbcraws->get_pmt(pmtch)->get_ttdc()) << "\t" + << _mbdcal->get_tt0(pmtch) << std::endl; + } + */ + } else if ( type == 1 && (!std::isnan(bbcraws->get_pmt(pmtch)->get_ttdc()) || isbadtch(pmtch) || _always_process_charge ) ) { @@ -840,7 +853,6 @@ int MbdEvent::ProcessRawContainer(MbdRawContainer *bbcraws, MbdPmtContainer *bbc m_pmttq[pmtch] = m_pmttq[pmtch] - _mbdcal->get_tq0(pmtch); // if ( m_pmttq[pmtch]<-50. && ifeech==255 ) std::cout << "hit_times " << ifeech << "\t" << m_pmttq[pmtch] << std::endl; - // if ( arm==1 ) std::cout << "hit_times " << ifeech << "\t" << setw(10) << m_pmttq[pmtch] << "\t" << board << "\t" << TRIG_SAMP[board] << std::endl; // if tt is bad, use tq if ( _mbdcal->get_status(ifeech-8)>0 ) @@ -850,7 +862,6 @@ int MbdEvent::ProcessRawContainer(MbdRawContainer *bbcraws, MbdPmtContainer *bbc else { // we have a good tt ch. correct for slew if there is a hit - //if ( ifeech==0 ) std::cout << "applying scorr" << std::endl; if ( !std::isnan(m_pmttt[pmtch]) ) { m_pmttt[pmtch] -= _mbdcal->get_scorr(ifeech-8,bbcraws->get_pmt(pmtch)->get_adc()); From 18821af5218bafe61ebabdf447fc29defec31d1f Mon Sep 17 00:00:00 2001 From: rosstom Date: Fri, 30 Jan 2026 19:32:34 -0500 Subject: [PATCH 144/393] Fixing clang tidy issue and TH2 typo --- offline/QA/Tracking/StateClusterResidualsQA.cc | 8 ++++++-- offline/QA/Tracking/StateClusterResidualsQA.h | 12 ++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/offline/QA/Tracking/StateClusterResidualsQA.cc b/offline/QA/Tracking/StateClusterResidualsQA.cc index d92f45a425..d2239ede5d 100644 --- a/offline/QA/Tracking/StateClusterResidualsQA.cc +++ b/offline/QA/Tracking/StateClusterResidualsQA.cc @@ -212,8 +212,12 @@ int StateClusterResidualsQA::process_event(PHCompositeNode* top_node) continue; } - float state_x, state_y, state_z; - float cluster_x, cluster_y, cluster_z; + float state_x; + float state_y; + float state_z; + float cluster_x; + float cluster_y; + float cluster_z; if (m_use_local_coords == true) { state_x = state->get_localX(); diff --git a/offline/QA/Tracking/StateClusterResidualsQA.h b/offline/QA/Tracking/StateClusterResidualsQA.h index ddde8032cc..587178ef9b 100644 --- a/offline/QA/Tracking/StateClusterResidualsQA.h +++ b/offline/QA/Tracking/StateClusterResidualsQA.h @@ -170,12 +170,12 @@ class StateClusterResidualsQA : public SubsysReco std::vector m_histograms_layer_x{}; std::vector m_histograms_layer_y{}; std::vector m_histograms_layer_z{}; - std::vector m_histograms_phi_x{}; - std::vector m_histograms_phi_y{}; - std::vector m_histograms_phi_z{}; - std::vector m_histograms_eta_x{}; - std::vector m_histograms_eta_y{}; - std::vector m_histograms_eta_z{}; + std::vector m_histograms_phi_x{}; + std::vector m_histograms_phi_y{}; + std::vector m_histograms_phi_z{}; + std::vector m_histograms_eta_x{}; + std::vector m_histograms_eta_y{}; + std::vector m_histograms_eta_z{}; }; #endif // TRACKFITTINGQA_H From 317ac39a05d64991eaf3a97102600fde88653bca Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Sat, 31 Jan 2026 18:39:11 -0500 Subject: [PATCH 145/393] suppress clang-tidywarnings for ActsPropagator.cc --- offline/packages/trackreco/ActsPropagator.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/offline/packages/trackreco/ActsPropagator.cc b/offline/packages/trackreco/ActsPropagator.cc index 8cd4942ea4..2578f05e61 100644 --- a/offline/packages/trackreco/ActsPropagator.cc +++ b/offline/packages/trackreco/ActsPropagator.cc @@ -48,7 +48,7 @@ ActsPropagator::makeTrackParams(SvtxTrackState* state, Acts::BoundSquareMatrix cov = transformer.rotateSvtxTrackCovToActs(state); return ActsTrackFittingAlgorithm::TrackParameters::create( - surf, + surf, // NOLINT (performance-unnecessary-value-param) m_geometry->geometry().getGeoContext(), actsFourPos, momentum, trackCharge / momentum.norm(), @@ -98,7 +98,8 @@ ActsPropagator::BTPPairResult ActsPropagator::propagateTrack(const Acts::BoundTrackParameters& params, const unsigned int sphenixLayer) { - unsigned int actsvolume, actslayer; + unsigned int actsvolume; + unsigned int actslayer; if (!checkLayer(sphenixLayer, actsvolume, actslayer) || !m_geometry) { return Acts::Result::failure(std::error_code(0, std::generic_category())); @@ -125,7 +126,7 @@ ActsPropagator::propagateTrack(const Acts::BoundTrackParameters& params, if (result.ok()) { - auto finalparams = *result.value().endParameters; + auto finalparams = *result.value().endParameters; // NOLINT(bugprone-unchecked-optional-access) auto pathlength = result.value().pathLength; auto pair = std::make_pair(pathlength, finalparams); @@ -154,7 +155,7 @@ ActsPropagator::propagateTrack(const Acts::BoundTrackParameters& params, if (result.ok()) { - auto finalparams = *result.value().endParameters; + auto finalparams = *result.value().endParameters; // NOLINT(bugprone-unchecked-optional-access) auto pathlength = result.value().pathLength; auto pair = std::make_pair(pathlength, finalparams); @@ -183,7 +184,7 @@ ActsPropagator::propagateTrackFast(const Acts::BoundTrackParameters& params, if (result.ok()) { - auto finalparams = *result.value().endParameters; + auto finalparams = *result.value().endParameters; // NOLINT(bugprone-unchecked-optional-access) auto pathlength = result.value().pathLength; auto pair = std::make_pair(pathlength, finalparams); From 467d93ef75da30a9f631a19300e796cf7c0672fe Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Sat, 31 Jan 2026 18:45:00 -0500 Subject: [PATCH 146/393] prevent misleading printout --- generators/PHPythia8/PHPythia8.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/generators/PHPythia8/PHPythia8.cc b/generators/PHPythia8/PHPythia8.cc index 58b1f67e5d..ab059542b4 100644 --- a/generators/PHPythia8/PHPythia8.cc +++ b/generators/PHPythia8/PHPythia8.cc @@ -176,7 +176,7 @@ int PHPythia8::read_config(const std::string &cfg_file) if (Verbosity() >= VERBOSITY_SOME) { - std::cout << "PHPythia8::read_config - Reading " << m_ConfigFileName << std::endl; + std::cout << Name() << " PHPythia8::read_config - Reading " << m_ConfigFileName << std::endl; } std::ifstream infile(m_ConfigFileName); @@ -201,7 +201,7 @@ int PHPythia8::process_event(PHCompositeNode * /*topNode*/) { if (Verbosity() >= VERBOSITY_MORE) { - std::cout << "PHPythia8::process_event - event: " << m_EventCount << std::endl; + std::cout << Name() << " PHPythia8::process_event - event: " << m_EventCount << std::endl; } bool passedGen = false; @@ -248,7 +248,7 @@ int PHPythia8::process_event(PHCompositeNode * /*topNode*/) andScoreKeeper &= trigResult; } - if (Verbosity() >= VERBOSITY_EVEN_MORE && !passedTrigger) + if (Verbosity() >= VERBOSITY_EVEN_MORE && !passedTrigger && !andScoreKeeper) { std::cout << "PHPythia8::process_event - failed trigger: " << m_RegisteredTrigger->GetName() << std::endl; From be6271bccf3b767e0e3317bffc1484afef64c241 Mon Sep 17 00:00:00 2001 From: mchiu-bnl Date: Sun, 1 Feb 2026 09:41:11 -0500 Subject: [PATCH 147/393] undo checks for existence of calibs - this breaks ability to calc these on the fly --- offline/packages/mbd/MbdCalib.cc | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/offline/packages/mbd/MbdCalib.cc b/offline/packages/mbd/MbdCalib.cc index 946b9658db..e1faec09b8 100644 --- a/offline/packages/mbd/MbdCalib.cc +++ b/offline/packages/mbd/MbdCalib.cc @@ -80,11 +80,6 @@ int MbdCalib::Download_All() if (!_rc->FlagExist("MBD_CALDIR")) { std::string sampmax_url = _cdb->getUrl("MBD_SAMPMAX"); - if ( sampmax_url.empty() ) - { - std::cerr << "ERROR, MBD_SAMPMAX missing" << std::endl; - return -1; - } if (Verbosity() > 0) { std::cout << "sampmax_url " << sampmax_url << std::endl; @@ -105,18 +100,12 @@ int MbdCalib::Download_All() if ( !_rawdstflag ) { std::string ped_url = _cdb->getUrl("MBD_PED"); - if ( ped_url.empty() ) - { - std::cerr << "ERROR, MBD_PED missing" << std::endl; - return -1; - } if (Verbosity() > 0) { std::cout << "ped_url " << ped_url << std::endl; } Download_Ped(ped_url); - std::string pileup_url = _cdb->getUrl("MBD_PILEUP"); if ( pileup_url.empty() ) { @@ -128,6 +117,7 @@ int MbdCalib::Download_All() std::cout << "pileup_url " << pileup_url << std::endl; } Download_Pileup(pileup_url); + if (do_templatefit) { @@ -651,8 +641,6 @@ int MbdCalib::Download_Ped(const std::string& dbase_location) if ( std::isnan(_pedmean[0]) ) { std::cout << PHWHERE << ", WARNING, ped calib missing, " << dbase_location << std::endl; - _status = -1; - return _status; } return 1; @@ -715,8 +703,6 @@ int MbdCalib::Download_SampMax(const std::string& dbase_location) if ( _sampmax[0] == -1 ) { std::cout << PHWHERE << ", WARNING, sampmax calib missing, " << dbase_location << std::endl; - _status = -1; - return _status; // file not found } return 1; @@ -781,14 +767,6 @@ int MbdCalib::Download_Status(const std::string& dbase_location) infile.close(); } - - if ( _mbdstatus[0] == -1 ) - { - std::cout << PHWHERE << ", WARNING, status calib seems bad, " << dbase_location << std::endl; - _status = -1; - return _status; // file not found - } - return 1; } From 278cf7399958ccde29102c461c49a212b972a31b Mon Sep 17 00:00:00 2001 From: mchiu-bnl Date: Sun, 1 Feb 2026 09:47:31 -0500 Subject: [PATCH 148/393] undo checks for existence of calibs - this breaks ability to calc these on the fly --- offline/packages/mbd/MbdCalib.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/offline/packages/mbd/MbdCalib.cc b/offline/packages/mbd/MbdCalib.cc index e1faec09b8..3ebe139ffb 100644 --- a/offline/packages/mbd/MbdCalib.cc +++ b/offline/packages/mbd/MbdCalib.cc @@ -106,6 +106,7 @@ int MbdCalib::Download_All() } Download_Ped(ped_url); + std::string pileup_url = _cdb->getUrl("MBD_PILEUP"); if ( pileup_url.empty() ) { @@ -117,7 +118,6 @@ int MbdCalib::Download_All() std::cout << "pileup_url " << pileup_url << std::endl; } Download_Pileup(pileup_url); - if (do_templatefit) { @@ -767,6 +767,14 @@ int MbdCalib::Download_Status(const std::string& dbase_location) infile.close(); } + + if ( _mbdstatus[0] == -1 ) + { + std::cout << PHWHERE << ", WARNING, status calib seems bad, " << dbase_location << std::endl; + _status = -1; + return _status; // file not found + } + return 1; } From 09d7e633aa063a50e94c38d66d23856c6c346812 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Sun, 1 Feb 2026 21:49:58 -0500 Subject: [PATCH 149/393] expand crossing range --- offline/QA/Tracking/SiliconSeedsQA.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/QA/Tracking/SiliconSeedsQA.cc b/offline/QA/Tracking/SiliconSeedsQA.cc index 14a9feeaed..012caf26ff 100644 --- a/offline/QA/Tracking/SiliconSeedsQA.cc +++ b/offline/QA/Tracking/SiliconSeedsQA.cc @@ -248,7 +248,7 @@ void SiliconSeedsQA::createHistos() } { - h_trackcrossing = new TH1F(std::string(getHistoPrefix() + "trackcrossing").c_str(), "Track beam bunch crossing;Track crossing;Entries", 110, -10, 100); + h_trackcrossing = new TH1F(std::string(getHistoPrefix() + "trackcrossing").c_str(), "Track beam bunch crossing;Track crossing;Entries", 1000, -200, 800); hm->registerHisto(h_trackcrossing); } From 479fedcf8483db511b9df38fd5be20aee0c66473 Mon Sep 17 00:00:00 2001 From: Michael Peters Date: Mon, 2 Feb 2026 00:41:25 -0500 Subject: [PATCH 150/393] TrkrNtuplizer hit analysis and PID fixes --- .../TrackingDiagnostics/TrkrNtuplizer.cc | 85 ++++++++++++++++--- .../TrackingDiagnostics/TrkrNtuplizer.h | 2 + 2 files changed, 77 insertions(+), 10 deletions(-) diff --git a/offline/packages/TrackingDiagnostics/TrkrNtuplizer.cc b/offline/packages/TrackingDiagnostics/TrkrNtuplizer.cc index 6ee6d35395..abc91cbf52 100644 --- a/offline/packages/TrackingDiagnostics/TrkrNtuplizer.cc +++ b/offline/packages/TrackingDiagnostics/TrkrNtuplizer.cc @@ -31,10 +31,15 @@ #include #include +#include + +#include + #include #include #include +#include #include @@ -158,6 +163,7 @@ enum n_hit // NOLINT(readability-enum-initial-value, performance-enum-size) nhitcellID, nhitecell, nhitphibin, + nhitzbin, nhittbin, nhitphi, nhitr, @@ -330,7 +336,7 @@ int TrkrNtuplizer::Init(PHCompositeNode* /*unused*/) std::string str_vertex = {"vertexID:vx:vy:vz:ntracks:chi2:ndof"}; std::string str_event = {"event:seed:run:seg:job"}; - std::string str_hit = {"hitID:e:adc:layer:phielem:zelem:cellID:ecell:phibin:tbin:phi:r:x:y:z"}; + std::string str_hit = {"hitID:e:adc:layer:phielem:zelem:cellID:ecell:phibin:zbin:tbin:phi:r:x:y:z"}; std::string str_cluster = {"locx:locy:x:y:z:r:phi:eta:theta:phibin:tbin:fee:chan:sampa:ex:ey:ez:ephi:pez:pephi:e:adc:maxadc:thick:afac:bfac:dcal:layer:phielem:zelem:size:phisize:zsize:pedge:redge:ovlp:trackID:niter"}; std::string str_seed = {"seedID:siter:spt:sptot:seta:sphi:syxint:srzint:sxyslope:srzslope:sX0:sY0:sdZ0:sR0:scharge:sdedx:spidedx:skdedx:sprdedx:sn1pix:snsil:sntpc:snhits"}; std::string str_residual = {"alpha:beta:resphio:resphi:resz"}; @@ -560,6 +566,13 @@ int TrkrNtuplizer::InitRun(PHCompositeNode* topNode) } AdcClockPeriod = geom->GetFirstLayerCellGeom()->get_zstep(); + _inttGeom = findNode::getClass(topNode, "CYLINDERGEOM_INTT"); + if (_do_hit_eval && !_inttGeom) + { + std::cout << PHWHERE << "ERROR: Can't find node CYLINDERGEOM_INTT" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + // Create Fee Map auto* geom_container = findNode::getClass(topNode, "TPCGEOMCONTAINER"); { @@ -1464,6 +1477,11 @@ void TrkrNtuplizer::fillOutputNtuples(PHCompositeNode* topNode) fx_hit[n_hit::nhitphielem] = -666; fx_hit[n_hit::nhitzelem] = -666; + if (layer_local < 3) + { + fx_hit[n_hit::nhitphielem] = MvtxDefs::getStaveId(hitset_key); + fx_hit[n_hit::nhitzelem] = MvtxDefs::getChipId(hitset_key); + } if (layer_local >= 3 && layer_local < 7) { fx_hit[n_hit::nhitphielem] = InttDefs::getLadderPhiId(hitset_key); @@ -1485,18 +1503,65 @@ void TrkrNtuplizer::fillOutputNtuples(PHCompositeNode* topNode) } } */ - fx_hit[n_hit::nhitphielem] = TpcDefs::getSectorId(hitset_key); - fx_hit[n_hit::nhitzelem] = TpcDefs::getSide(hitset_key); + //fx_hit[n_hit::nhitphielem] = TpcDefs::getSectorId(hitset_key); + //fx_hit[n_hit::nhitzelem] = TpcDefs::getSide(hitset_key); fx_hit[n_hit::nhitcellID] = 0; fx_hit[n_hit::nhitecell] = hit->getAdc(); fx_hit[n_hit::nhitphibin] = std::numeric_limits::quiet_NaN(); fx_hit[n_hit::nhittbin] = std::numeric_limits::quiet_NaN(); + fx_hit[n_hit::nhitzbin] = std::numeric_limits::quiet_NaN(); fx_hit[n_hit::nhitphi] = std::numeric_limits::quiet_NaN(); fx_hit[n_hit::nhitr] = std::numeric_limits::quiet_NaN(); fx_hit[n_hit::nhitx] = std::numeric_limits::quiet_NaN(); fx_hit[n_hit::nhity] = std::numeric_limits::quiet_NaN(); fx_hit[n_hit::nhitz] = std::numeric_limits::quiet_NaN(); + if (layer_local < _nlayers_maps) + { + int row = MvtxDefs::getRow(hit_key); + int col = MvtxDefs::getCol(hit_key); + + float localX = std::numeric_limits::quiet_NaN(); + float localZ = std::numeric_limits::quiet_NaN(); + SegmentationAlpide::detectorToLocal(row,col,localX,localZ); + Acts::Vector2 local(localX * Acts::UnitConstants::cm, localZ * Acts::UnitConstants::cm); + + const auto& surface = m_tGeometry->maps().getSiliconSurface(hitset_key); + auto glob = surface->localToGlobal(m_tGeometry->geometry().getGeoContext(), local, Acts::Vector3()); + + fx_hit[n_hit::nhitphibin] = row; + fx_hit[n_hit::nhitzbin] = col; + fx_hit[n_hit::nhittbin] = MvtxDefs::getStrobeId(hitset_key); + fx_hit[n_hit::nhitx] = glob.x() / Acts::UnitConstants::cm; + fx_hit[n_hit::nhity] = glob.y() / Acts::UnitConstants::cm; + fx_hit[n_hit::nhitz] = glob.z() / Acts::UnitConstants::cm; + fx_hit[n_hit::nhitr] = sqrt(glob.x()*glob.x()+glob.y()*glob.y()) / Acts::UnitConstants::cm; + fx_hit[n_hit::nhitphi] = atan2(glob.y(),glob.x()); + } + + if (layer_local >= _nlayers_maps && layer_local < _nlayers_intt) + { + int row = InttDefs::getRow(hit_key); + int col = InttDefs::getCol(hit_key); + + CylinderGeomIntt* intt_cylinder = dynamic_cast(_inttGeom->GetLayerGeom(layer_local)); + double localcoords[3]; + intt_cylinder->find_strip_center_localcoords(InttDefs::getLadderZId(hitset_key),row,col,localcoords); + + Acts::Vector2 local(localcoords[1]*Acts::UnitConstants::cm,localcoords[2]*Acts::UnitConstants::cm); + const auto& surface = m_tGeometry->maps().getSiliconSurface(hitset_key); + auto glob = surface->localToGlobal(m_tGeometry->geometry().getGeoContext(), local, Acts::Vector3()); + + fx_hit[n_hit::nhitphibin] = row; + fx_hit[n_hit::nhitzbin] = col; + fx_hit[n_hit::nhittbin] = InttDefs::getTimeBucketId(hitset_key); + fx_hit[n_hit::nhitx] = glob.x() / Acts::UnitConstants::cm; + fx_hit[n_hit::nhity] = glob.y() / Acts::UnitConstants::cm; + fx_hit[n_hit::nhitz] = glob.z() / Acts::UnitConstants::cm; + fx_hit[n_hit::nhitr] = sqrt(glob.x()*glob.x()+glob.y()*glob.y()) / Acts::UnitConstants::cm; + fx_hit[n_hit::nhitphi] = atan2(glob.y(),glob.x()); + } + if (layer_local >= _nlayers_maps + _nlayers_intt && layer_local < _nlayers_maps + _nlayers_intt + _nlayers_tpc) { PHG4TpcGeom* GeoLayer_local = _geom_container->GetLayerCellGeom(layer_local); @@ -1618,7 +1683,7 @@ void TrkrNtuplizer::fillOutputNtuples(PHCompositeNode* topNode) } TrackSeedContainer* _tpc_seeds = findNode::getClass(topNode, "TpcTrackSeedContainer"); - if (!_tpc_seeds) + if (!_tpc_seeds && _do_tpcseed_eval) { std::cout << PHWHERE << " ERROR: Can't find " << "TpcTrackSeedContainer" << std::endl; @@ -1737,9 +1802,9 @@ void TrkrNtuplizer::fillOutputNtuples(PHCompositeNode* topNode) } else { - pidedx = f_pion_minus->Eval(tptot); - kdedx = f_kaon_minus->Eval(tptot); - prdedx = f_proton_plus->Eval(tptot); + pidedx = f_pion_minus->Eval(-tptot); + kdedx = f_kaon_minus->Eval(-tptot); + prdedx = f_proton_minus->Eval(-tptot); } float n1pix = get_n1pix(tpcseed); float fx_seed[n_seed::seedsize] = {(float) trackID, 0, tpt, tptot, teta, tphi, xyint, rzint, xyslope, rzslope, tX0, tY0, tZ0, R0, charge, dedx, pidedx, kdedx, prdedx, n1pix, nsil_local, ntpc_local, nhits_local}; @@ -1933,9 +1998,9 @@ void TrkrNtuplizer::FillTrack(float fX[50], SvtxTrack* track, GlobalVertexMap* v } else { - fX[n_track::ntrknpidedx] = f_pion_minus->Eval(trptot); - fX[n_track::ntrknkdedx] = f_kaon_minus->Eval(trptot); - fX[n_track::ntrknprdedx] = f_proton_minus->Eval(trptot); + fX[n_track::ntrknpidedx] = f_pion_minus->Eval(-trptot); + fX[n_track::ntrknkdedx] = f_kaon_minus->Eval(-trptot); + fX[n_track::ntrknprdedx] = f_proton_minus->Eval(-trptot); } for (SvtxTrack::ConstClusterKeyIter iter_local = tpcseed->begin_cluster_keys(); diff --git a/offline/packages/TrackingDiagnostics/TrkrNtuplizer.h b/offline/packages/TrackingDiagnostics/TrkrNtuplizer.h index 4e9df30628..ac341f1a45 100644 --- a/offline/packages/TrackingDiagnostics/TrkrNtuplizer.h +++ b/offline/packages/TrackingDiagnostics/TrkrNtuplizer.h @@ -35,6 +35,7 @@ class SvtxVertexMap; class TrkrClusterContainer; class ActsGeometry; class PHG4TpcGeomContainer; +class PHG4CylinderGeomContainer; class GlobalVertexMap; // class ClusterErrorPara; @@ -157,6 +158,7 @@ class TrkrNtuplizer : public SubsysReco SvtxTrackMap *_trackmap{nullptr}; ActsGeometry *_tgeometry{nullptr}; PHG4TpcGeomContainer *_geom_container{nullptr}; + PHG4CylinderGeomContainer *_inttGeom{nullptr}; float m_ZDC_coincidence{0}; float m_mbd_rate{0}; float m_rawzdc{0}; From 8b00901783e04541fc5b4985b04f84646bba71a6 Mon Sep 17 00:00:00 2001 From: Michael Peters Date: Mon, 2 Feb 2026 02:30:58 -0500 Subject: [PATCH 151/393] reverse commit mixup --- .../KFParticle_sPHENIX/KFParticle_Tools.cc | 36 ++++--------------- .../KFParticle_sPHENIX/KFParticle_Tools.h | 2 -- .../KFParticle_sPHENIX/KFParticle_sPHENIX.h | 4 --- 3 files changed, 7 insertions(+), 35 deletions(-) diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc b/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc index 14958f22c9..b319af5b56 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc @@ -1184,16 +1184,7 @@ float KFParticle_Tools::get_dEdx(PHCompositeNode *topNode, const KFParticle &dau void KFParticle_Tools::init_dEdx_fits() { - std::string dedx_fitparams; - if (m_use_local_PID_file) - { - dedx_fitparams = m_local_PID_filename; - } - else - { - dedx_fitparams = CDBInterface::instance()->getUrl("TPC_DEDX_FITPARAM"); - } - + std::string dedx_fitparams = CDBInterface::instance()->getUrl("TPC_DEDX_FITPARAM"); TFile *filefit = TFile::Open(dedx_fitparams.c_str()); if (!filefit->IsOpen()) @@ -1202,25 +1193,12 @@ void KFParticle_Tools::init_dEdx_fits() return; } - if (m_use_local_PID_file) - { - // new method is independent of charge - filefit->GetObject("pi_band",f_pion_plus); - filefit->GetObject("K_band",f_kaon_plus); - filefit->GetObject("p_band",f_proton_plus); - filefit->GetObject("pi_band",f_pion_minus); - filefit->GetObject("K_band",f_kaon_minus); - filefit->GetObject("p_band",f_proton_minus); - } - else - { - filefit->GetObject("f_piband", f_pion_plus); - filefit->GetObject("f_Kband", f_kaon_plus); - filefit->GetObject("f_pband", f_proton_plus); - filefit->GetObject("f_piminus_band", f_pion_minus); - filefit->GetObject("f_Kminus_band", f_kaon_minus); - filefit->GetObject("f_pbar_band", f_proton_minus); - } + filefit->GetObject("f_piband", f_pion_plus); + filefit->GetObject("f_Kband", f_kaon_plus); + filefit->GetObject("f_pband", f_proton_plus); + filefit->GetObject("f_piminus_band", f_pion_minus); + filefit->GetObject("f_Kminus_band", f_kaon_minus); + filefit->GetObject("f_pbar_band", f_proton_minus); pidMap.insert(std::pair(-11, f_pion_plus)); pidMap.insert(std::pair(211, f_pion_plus)); diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.h b/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.h index 126c331c13..4e722a15db 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.h +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.h @@ -149,8 +149,6 @@ class KFParticle_Tools : protected KFParticle_MVA std::vector m_intermediate_vertex_volume; bool m_use_PID{false}; - bool m_use_local_PID_file{false}; - std::string m_local_PID_filename = ""; float m_dEdx_band_width{0.2}; // Fraction of expected dE/dx TF1 *f_pion_plus{nullptr}; diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h index e537d63dd4..64fc3f37bb 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h @@ -394,10 +394,6 @@ class KFParticle_sPHENIX : public SubsysReco, public KFParticle_nTuple, public K void selectMotherByMassError(bool select = true) { m_select_by_mass_error = select; } void usePID(bool use = true){ m_use_PID = use; } - - void useLocalPIDFile(bool use = false){ m_use_local_PID_file = use; } - - void setLocalPIDFilename(std::string name){ m_local_PID_filename = name; } void setPIDacceptFraction(float frac = 0.2){ m_dEdx_band_width = frac; } From 18e35f21f40b773a7548a45714447db6670c23bd Mon Sep 17 00:00:00 2001 From: "Blair D. Seidlitz" Date: Mon, 2 Feb 2026 11:25:53 -0500 Subject: [PATCH 152/393] Adding fermi-exp for ZDC --- .../packages/CaloReco/CaloWaveformFitting.cc | 77 ++++++++++++++++++- .../packages/CaloReco/CaloWaveformFitting.h | 2 + .../CaloReco/CaloWaveformProcessing.cc | 1 + .../CaloReco/CaloWaveformProcessing.h | 2 +- 4 files changed, 80 insertions(+), 2 deletions(-) diff --git a/offline/packages/CaloReco/CaloWaveformFitting.cc b/offline/packages/CaloReco/CaloWaveformFitting.cc index 266072dfbe..c0117c51af 100644 --- a/offline/packages/CaloReco/CaloWaveformFitting.cc +++ b/offline/packages/CaloReco/CaloWaveformFitting.cc @@ -659,6 +659,42 @@ double CaloWaveformFitting::SignalShape_PowerLawDoubleExp(double *x, double *par return pedestal + signal; } + +double CaloWaveformFitting::SignalShape_FermiExp(double *x, double *par) +{ + // par[0]: Amplitude + // par[1]: Midpoint (t0) + // par[2]: Rise width (w) + // par[3]: Decay time (tau) + // par[4]: Pedestal + + double tt = x[0]; + double A = par[0]; + double t0 = par[1]; + double w = par[2]; + double tau = par[3]; + double ped = par[4]; + + // Protect against bad values + if (w <= 0 || tau <= 0) + return ped; + + // Fermi turn-on + double fermi = 1.0 / (1.0 + exp(-(tt - t0) / w)); + + // Exponential decay (starts at t0) + double expo = exp(-(tt - t0) / tau); + + // Suppress before turn-on + if (tt < t0) + expo = 1.0; // flat before midpoint + + double signal = A * fermi * expo; + + return ped + signal; +} + + std::vector> CaloWaveformFitting::calo_processing_funcfit(const std::vector> &chnlvector) { std::vector> fit_values; @@ -803,7 +839,7 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con } } } - else // POWERLAWDOUBLEEXP + else if(m_funcfit_type == POWERLAWDOUBLEEXP) // POWERLAWDOUBLEEXP { // Create fit function with 7 parameters TF1 f("f_doubleexp", SignalShape_PowerLawDoubleExp, 0, nsamples, 7); @@ -853,6 +889,45 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con } } } + else if(m_funcfit_type == FERMIEXP) // POWERLAWDOUBLEEXP + { + TF1 f("f_fermiexp", SignalShape_FermiExp, 0, nsamples, 5); + npar = 5; + + // Set initial parameters + double par[5]; + par[0] = maxheight - pedestal; // Amplitude + par[1] = maxbin ; // t0 + par[2] = 1.0; + par[3] = 2.0; // Peak Time 1 + par[4] = pedestal; // Pedestal + + f.SetParameters(par); + f.SetParLimits(0, maxheight-pedestal, 3*(maxheight-pedestal)); + f.SetParLimits(1, maxbin-1, maxbin); + f.SetParLimits(2, 0.025, 5.0); + f.SetParLimits(3, 0.5, 5.0); + f.SetParLimits(4, pedestal-500, pedestal+500); + + f.FixParameter(2, 0.10); // width + + // Perform fit + h.Fit(&f, "QRN0W", "", 0, nsamples); + + fit_time = f.GetParameter(1); + fit_amp = f.GetParameter(0); + fit_ped = f.GetParameter(4); + + // Calculate chi2 + for (int i = 0; i < nsamples; i++) + { + if (h.GetBinContent(i + 1) > 0) + { + double diff = h.GetBinContent(i + 1) - f.Eval(i); + chi2val += diff * diff; + } + } + } int ndf = ndata - npar; if (ndf > 0) diff --git a/offline/packages/CaloReco/CaloWaveformFitting.h b/offline/packages/CaloReco/CaloWaveformFitting.h index 648d6ab0fa..1064dcd68e 100644 --- a/offline/packages/CaloReco/CaloWaveformFitting.h +++ b/offline/packages/CaloReco/CaloWaveformFitting.h @@ -13,6 +13,7 @@ class CaloWaveformFitting { POWERLAWEXP = 0, POWERLAWDOUBLEEXP = 1, + FERMIEXP = 2, }; CaloWaveformFitting() = default; @@ -75,6 +76,7 @@ class CaloWaveformFitting static double SignalShape_PowerLawExp(double *x, double *par); // Double exponential power-law fit function static double SignalShape_PowerLawDoubleExp(double *x, double *par); + static double SignalShape_FermiExp(double *x, double *par); void set_funcfit_type(FuncFitType type) { diff --git a/offline/packages/CaloReco/CaloWaveformProcessing.cc b/offline/packages/CaloReco/CaloWaveformProcessing.cc index 057e427627..2ffe1d4277 100644 --- a/offline/packages/CaloReco/CaloWaveformProcessing.cc +++ b/offline/packages/CaloReco/CaloWaveformProcessing.cc @@ -31,6 +31,7 @@ void CaloWaveformProcessing::initialize_processing() { std::string calibrations_repo_template = std::string(calibrationsroot) + "/WaveformProcessing/templates/" + m_template_input_file; url_template = CDBInterface::instance()->getUrl(m_template_name, calibrations_repo_template); + url_template = "/sphenix/u/bseidlitz/work/zdcStuff/templateFile.root"; m_Fitter = new CaloWaveformFitting(); m_Fitter->initialize_processing(url_template); if (m_processingtype == CaloWaveformProcessing::TEMPLATE_NOSAT) diff --git a/offline/packages/CaloReco/CaloWaveformProcessing.h b/offline/packages/CaloReco/CaloWaveformProcessing.h index b657459d6c..608811a5e6 100644 --- a/offline/packages/CaloReco/CaloWaveformProcessing.h +++ b/offline/packages/CaloReco/CaloWaveformProcessing.h @@ -116,7 +116,7 @@ class CaloWaveformProcessing : public SubsysReco bool _bdosoftwarezerosuppression{false}; bool _dobitfliprecovery{false}; - std::string m_template_input_file; + std::string m_template_input_file = "testbeam_cemc_template.root"; std::string url_template; std::string m_template_name{"NONE"}; From 0b26d1890b69c537c0be708da91bfe2497996df8 Mon Sep 17 00:00:00 2001 From: Ishan Goel Date: Mon, 2 Feb 2026 13:46:05 -0500 Subject: [PATCH 153/393] To include the dead/hot counters inside the edge counter as well as allowing people to use dead/hot maps both in simulation and data. --- offline/packages/tpc/TpcClusterizer.cc | 164 +++++++++++++++++++++++-- offline/packages/tpc/TpcClusterizer.h | 35 +++++- 2 files changed, 183 insertions(+), 16 deletions(-) diff --git a/offline/packages/tpc/TpcClusterizer.cc b/offline/packages/tpc/TpcClusterizer.cc index c0137613f5..28c203553b 100644 --- a/offline/packages/tpc/TpcClusterizer.cc +++ b/offline/packages/tpc/TpcClusterizer.cc @@ -35,6 +35,9 @@ #include #include +#include +#include + #include #include // for PHIODataNode #include // for PHNode @@ -118,6 +121,13 @@ namespace unsigned short maxHalfSizeT = 0; unsigned short maxHalfSizePhi = 0; double m_tdriftmax = 0; + + // --- new members for dead/hot map --- + hitMaskTpc *deadMap = nullptr; + hitMaskTpc *hotMap = nullptr; + bool maskDead = false; + bool maskHot = false; + std::vector association_vector; std::vector cluster_vector; std::vector v_hits; @@ -360,7 +370,7 @@ namespace int is_hit_isolated(int iphi, int it, int NPhiBinsMax, int NTBinsMax, const std::vector> &adcval) { // check isolated hits - // const int NPhiBinsMax = (int) my_data.phibins; + // const int NPhiBinsMax = (int) my_data.phibins; // const int NTBinsMax = (int) my_data.tbins; int isosum = 0; @@ -484,6 +494,7 @@ namespace int tbinlo = 666666; int clus_size = ihit_list.size(); int max_adc = 0; + if (clus_size <= my_data.min_clus_size) { return; @@ -513,7 +524,7 @@ namespace training_hits->v_adc.fill(0); } - // std::cout << "process list" << std::endl; + // std::cout << "process list" << std::endl; std::vector hitkeyvec; // keep track of the hit locations in a given cluster @@ -592,6 +603,46 @@ namespace return; // skip obvious noise "clusters" } + TrkrDefs::hitsetkey tpcHitSetKey = TpcDefs::genHitSetKey(my_data.layer, my_data.sector, my_data.side); + + // --- Dead channels --- + if (my_data.maskDead && my_data.deadMap->count(tpcHitSetKey)) + { + const auto &deadvec = (*my_data.deadMap)[tpcHitSetKey]; + + for (const auto &deadkey : deadvec) + { + int dphi = TpcDefs::getPad(deadkey); + + bool touch = (dphi == phibinlo - 1 || dphi == phibinhi + 1); + + if (touch) + { + nedge++; + continue; + } + } + } + + // --- Hot channels --- + if (my_data.maskHot && my_data.hotMap->count(tpcHitSetKey)) + { + const auto &hotvec = (*my_data.hotMap)[tpcHitSetKey]; + + for (const auto &hotkey : hotvec) + { + int hphi = TpcDefs::getPad(hotkey); + + bool touch = (hphi == phibinlo -1 || hphi == phibinhi + 1); + + if (touch) + { + nedge++; + continue; + } + } + } + // This is the global position double clusiphi = iphi_sum / adc_sum; double clusphi = my_data.layergeom->get_phi(clusiphi, my_data.side); @@ -612,7 +663,7 @@ namespace const double t_cov = t2_sum / adc_sum - square(clust); // Get the surface key to find the surface from the - TrkrDefs::hitsetkey tpcHitSetKey = TpcDefs::genHitSetKey(my_data.layer, my_data.sector, my_data.side); + // TrkrDefs::hitsetkey tpcHitSetKey = TpcDefs::genHitSetKey(my_data.layer, my_data.sector, my_data.side); Acts::Vector3 global(clusx, clusy, clusz); TrkrDefs::subsurfkey subsurfkey = 0; @@ -784,7 +835,34 @@ namespace tbinmax -= etacut; } } - // std::cout << PHWHERE << " maxz " << maxz << " tbinmin " << tbinmin << " tbinmax " << tbinmax << std::endl; + // std::cout << PHWHERE << " maxz " << maxz << " tbinmin " << tbinmin << " tbinmax " << tbinmax << std::endl; + + TrkrDefs::hitsetkey tpcHitSetKey = + TpcDefs::genHitSetKey(my_data->layer, my_data->sector, my_data->side); + + // Helper function to check if a pad is masked + auto is_pad_masked = [&](int abs_pad) -> bool + { + if (my_data->maskDead && my_data->deadMap->count(tpcHitSetKey)) + { + const auto &deadvec = (*my_data->deadMap)[tpcHitSetKey]; + for (const auto &deadkey : deadvec) + { + if (TpcDefs::getPad(deadkey) == abs_pad) + return true; + } + } + if (my_data->maskHot && my_data->hotMap->count(tpcHitSetKey)) + { + const auto &hotvec = (*my_data->hotMap)[tpcHitSetKey]; + for (const auto &hotkey : hotvec) + { + if (TpcDefs::getPad(hotkey) == abs_pad) + return true; + } + } + return false; + }; if (my_data->hitset != nullptr) { @@ -821,21 +899,16 @@ namespace { continue; } + if (is_pad_masked(phibin + phioffset)) + { + continue; + } float_t fadc = (hitr->second->getAdc()) - pedestal; // proper int rounding +0.5 unsigned short adc = 0; if (fadc > 0) { adc = (unsigned short) fadc; } - if (phibin >= phibins) - { - continue; - } - if (tbin >= tbins) - { - continue; // tbin is unsigned int, <0 cannot happen - } - if (adc > 0) { if (adc > (my_data->seed_threshold)) @@ -877,6 +950,11 @@ namespace { unsigned short val = (*(hitset->getHits(nphi)))[nt]; + if (is_pad_masked(nphi + phioffset)) + { + pindex++; + continue; + } if (val == 0) { pindex++; @@ -1038,6 +1116,7 @@ namespace */ // pthread_exit(nullptr); } + void *ProcessSector(void *threadarg) { auto *my_data = static_cast(threadarg); @@ -1211,6 +1290,15 @@ int TpcClusterizer::InitRun(PHCompositeNode *topNode) auto *g3 = static_cast (geom->GetLayerCellGeom(40)); // cast because << not in the base class std::cout << *g3 << std::endl; + if (m_maskDeadChannels) + { + makeChannelMask(m_deadChannelMap, m_deadChannelMapName, "TotalDeadChannels"); + } + if (m_maskHotChannels) + { + makeChannelMask(m_hotChannelMap, m_hotChannelMapName, "TotalHotChannels"); + } + return Fun4AllReturnCodes::EVENT_OK; } @@ -1397,6 +1485,13 @@ int TpcClusterizer::process_event(PHCompositeNode *topNode) thread_pair.data.min_err_squared = min_err_squared; thread_pair.data.min_clus_size = min_clus_size; thread_pair.data.min_adc_sum = min_adc_sum; + + // --- pass dead/hot map info --- + thread_pair.data.deadMap = &m_deadChannelMap; + thread_pair.data.hotMap = &m_hotChannelMap; + thread_pair.data.maskDead = m_maskDeadChannels; + thread_pair.data.maskHot = m_maskHotChannels; + unsigned short NPhiBins = (unsigned short) layergeom->get_phibins(); unsigned short NPhiBinsSector = NPhiBins / 12; unsigned short NTBins = 0; @@ -1517,6 +1612,12 @@ int TpcClusterizer::process_event(PHCompositeNode *topNode) thread_pair.data.maxHalfSizePhi = MaxClusterHalfSizePhi; thread_pair.data.verbosity = Verbosity(); + // --- pass dead/hot map info --- + thread_pair.data.deadMap = &m_deadChannelMap; + thread_pair.data.hotMap = &m_hotChannelMap; + thread_pair.data.maskDead = m_maskDeadChannels; + thread_pair.data.maskHot = m_maskHotChannels; + unsigned short NPhiBins = (unsigned short) layergeom->get_phibins(); unsigned short NPhiBinsSector = NPhiBins / 12; unsigned short NTBins = (unsigned short) layergeom->get_zbins(); @@ -1702,3 +1803,40 @@ int TpcClusterizer::End(PHCompositeNode * /*topNode*/) { return Fun4AllReturnCodes::EVENT_OK; } + +void TpcClusterizer::makeChannelMask(hitMaskTpc &aMask, const std::string &dbName, const std::string &totalChannelsToMask) +{ + CDBTTree *cdbttree; + if (m_maskFromFile) + { + cdbttree = new CDBTTree(dbName); + } + else // mask using CDB TTree, default + { + std::string database = CDBInterface::instance()->getUrl(dbName); + cdbttree = new CDBTTree(database); + } + + std::cout << "Masking TPC Channel Map: " << dbName << std::endl; + + int NChan = -1; + NChan = cdbttree->GetSingleIntValue(totalChannelsToMask); + + for (int i = 0; i < NChan; i++) + { + int Layer = cdbttree->GetIntValue(i, "layer"); + int Sector = cdbttree->GetIntValue(i, "sector"); + int Side = cdbttree->GetIntValue(i, "side"); + int Pad = cdbttree->GetIntValue(i, "pad"); + if (Verbosity() > VERBOSITY_A_LOT) + { + std::cout << dbName << ": Will mask layer: " << Layer << ", sector: " << Sector << ", side: " << Side << ", Pad: " << Pad << std::endl; + } + + TrkrDefs::hitsetkey DeadChannelHitKey = TpcDefs::genHitSetKey(Layer, Sector, Side); + TrkrDefs::hitkey DeadHitKey = TpcDefs::genHitKey((unsigned int) Pad, 0); + aMask[DeadChannelHitKey].push_back(DeadHitKey); + } + + delete cdbttree; +} diff --git a/offline/packages/tpc/TpcClusterizer.h b/offline/packages/tpc/TpcClusterizer.h index e7dd61f0bc..6ec5c18b1c 100644 --- a/offline/packages/tpc/TpcClusterizer.h +++ b/offline/packages/tpc/TpcClusterizer.h @@ -9,6 +9,8 @@ #include #include +typedef std::map> hitMaskTpc; + class ClusHitsVerbosev1; class PHCompositeNode; class TrkrHitSet; @@ -69,13 +71,31 @@ class TpcClusterizer : public SubsysReco set_max_cluster_half_size_z(20); set_fixed_window(3); }; - + ClusHitsVerbosev1 *mClusHitsVerbose{nullptr}; - + + void SetMaskChannelsFromFile() + { + m_maskFromFile = true; + } + + void SetDeadChannelMapName(const std::string& dcmap) + { + m_maskDeadChannels = true; + m_deadChannelMapName = dcmap; + } + void SetHotChannelMapName(const std::string& hmap) + { + m_maskHotChannels = true; + m_hotChannelMapName = hmap; + } + private: bool is_in_sector_boundary(int phibin, int sector, PHG4TpcGeom *layergeom) const; bool record_ClusHitsVerbose{false}; + void makeChannelMask(hitMaskTpc& aMask, const std::string& dbName, const std::string& totalChannelsToMask); + TrkrHitSetContainer *m_hits = nullptr; RawHitSetContainer *m_rawhits = nullptr; TrkrClusterContainer *m_clusterlist = nullptr; @@ -105,8 +125,17 @@ class TpcClusterizer : public SubsysReco double m_tdriftmax = 0; double AdcClockPeriod = 53.0; // ns double NZBinsSide = 249; - + TrainingHitsContainer *m_training; + + hitMaskTpc m_deadChannelMap; + hitMaskTpc m_hotChannelMap; + + bool m_maskDeadChannels {false}; + bool m_maskHotChannels {false}; + bool m_maskFromFile {false}; + std::string m_deadChannelMapName; + std::string m_hotChannelMapName; }; #endif From 80ba49aca3ed8cee96d1b890d98ad5b813e36b54 Mon Sep 17 00:00:00 2001 From: Ishan Goel Date: Mon, 2 Feb 2026 14:20:38 -0500 Subject: [PATCH 154/393] Some additional fix --- offline/packages/tpc/TpcClusterizer.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/offline/packages/tpc/TpcClusterizer.cc b/offline/packages/tpc/TpcClusterizer.cc index 28c203553b..881bc7f681 100644 --- a/offline/packages/tpc/TpcClusterizer.cc +++ b/offline/packages/tpc/TpcClusterizer.cc @@ -1292,10 +1292,12 @@ int TpcClusterizer::InitRun(PHCompositeNode *topNode) if (m_maskDeadChannels) { + m_deadChannelMap.clear(); makeChannelMask(m_deadChannelMap, m_deadChannelMapName, "TotalDeadChannels"); } if (m_maskHotChannels) { + m_hotChannelMap.clear(); makeChannelMask(m_hotChannelMap, m_hotChannelMapName, "TotalHotChannels"); } From 89b1112e5c1f9451deeda5caea5f54c6686d1da2 Mon Sep 17 00:00:00 2001 From: "Blair D. Seidlitz" Date: Mon, 2 Feb 2026 19:27:49 -0500 Subject: [PATCH 155/393] clean up --- .../packages/CaloReco/CaloWaveformFitting.cc | 27 +++++++++---------- .../CaloReco/CaloWaveformProcessing.cc | 1 - .../CaloReco/CaloWaveformProcessing.h | 2 +- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/offline/packages/CaloReco/CaloWaveformFitting.cc b/offline/packages/CaloReco/CaloWaveformFitting.cc index c0117c51af..3d2223abab 100644 --- a/offline/packages/CaloReco/CaloWaveformFitting.cc +++ b/offline/packages/CaloReco/CaloWaveformFitting.cc @@ -675,19 +675,19 @@ double CaloWaveformFitting::SignalShape_FermiExp(double *x, double *par) double tau = par[3]; double ped = par[4]; - // Protect against bad values if (w <= 0 || tau <= 0) + { return ped; + } - // Fermi turn-on double fermi = 1.0 / (1.0 + exp(-(tt - t0) / w)); - // Exponential decay (starts at t0) double expo = exp(-(tt - t0) / tau); - // Suppress before turn-on if (tt < t0) - expo = 1.0; // flat before midpoint + { + expo = 1.0; + } double signal = A * fermi * expo; @@ -896,22 +896,21 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con // Set initial parameters double par[5]; - par[0] = maxheight - pedestal; // Amplitude - par[1] = maxbin ; // t0 - par[2] = 1.0; - par[3] = 2.0; // Peak Time 1 - par[4] = pedestal; // Pedestal + par[0] = maxheight - pedestal; // Amplitude + par[1] = maxbin ; // t0 + par[2] = 1.0; // width + par[3] = 2.0; // Peak Time 1 + par[4] = pedestal; // Pedestal f.SetParameters(par); f.SetParLimits(0, maxheight-pedestal, 3*(maxheight-pedestal)); f.SetParLimits(1, maxbin-1, maxbin); - f.SetParLimits(2, 0.025, 5.0); - f.SetParLimits(3, 0.5, 5.0); + f.SetParLimits(2, 0.025, 2.0); + f.SetParLimits(3, 0.5, 4.0); f.SetParLimits(4, pedestal-500, pedestal+500); - f.FixParameter(2, 0.10); // width + f.FixParameter(2, 0.2); - // Perform fit h.Fit(&f, "QRN0W", "", 0, nsamples); fit_time = f.GetParameter(1); diff --git a/offline/packages/CaloReco/CaloWaveformProcessing.cc b/offline/packages/CaloReco/CaloWaveformProcessing.cc index 2ffe1d4277..057e427627 100644 --- a/offline/packages/CaloReco/CaloWaveformProcessing.cc +++ b/offline/packages/CaloReco/CaloWaveformProcessing.cc @@ -31,7 +31,6 @@ void CaloWaveformProcessing::initialize_processing() { std::string calibrations_repo_template = std::string(calibrationsroot) + "/WaveformProcessing/templates/" + m_template_input_file; url_template = CDBInterface::instance()->getUrl(m_template_name, calibrations_repo_template); - url_template = "/sphenix/u/bseidlitz/work/zdcStuff/templateFile.root"; m_Fitter = new CaloWaveformFitting(); m_Fitter->initialize_processing(url_template); if (m_processingtype == CaloWaveformProcessing::TEMPLATE_NOSAT) diff --git a/offline/packages/CaloReco/CaloWaveformProcessing.h b/offline/packages/CaloReco/CaloWaveformProcessing.h index 608811a5e6..b657459d6c 100644 --- a/offline/packages/CaloReco/CaloWaveformProcessing.h +++ b/offline/packages/CaloReco/CaloWaveformProcessing.h @@ -116,7 +116,7 @@ class CaloWaveformProcessing : public SubsysReco bool _bdosoftwarezerosuppression{false}; bool _dobitfliprecovery{false}; - std::string m_template_input_file = "testbeam_cemc_template.root"; + std::string m_template_input_file; std::string url_template; std::string m_template_name{"NONE"}; From eb15d524f286b41c660ce963c28171ad2f8d5940 Mon Sep 17 00:00:00 2001 From: Anthony Denis Frawley Date: Tue, 3 Feb 2026 13:13:08 -0500 Subject: [PATCH 156/393] Christof's new error parameterization. --- .../packages/trackbase/ClusterErrorPara.cc | 138 +++++++++++++++++- offline/packages/trackbase/ClusterErrorPara.h | 2 + 2 files changed, 135 insertions(+), 5 deletions(-) diff --git a/offline/packages/trackbase/ClusterErrorPara.cc b/offline/packages/trackbase/ClusterErrorPara.cc index cb62ed10f5..67ce0e2b9e 100644 --- a/offline/packages/trackbase/ClusterErrorPara.cc +++ b/offline/packages/trackbase/ClusterErrorPara.cc @@ -18,10 +18,18 @@ namespace { return x * x; } + } // namespace ClusterErrorPara::ClusterErrorPara() { + /* + ftpcR1 = new TF1("ftpcR1", "pol2", 0, 10); + ftpcR1->SetParameter(0, 3.206); + ftpcR1->SetParameter(1, -0.252); + ftpcR1->SetParameter(2, 0.007); + */ + f0 = new TF1("f0", "pol1", 0, 10); f0->SetParameter(0, 0.0163943); f0->SetParameter(1, 0.0192931); @@ -482,7 +490,7 @@ ClusterErrorPara::error_t ClusterErrorPara::get_clusterv5_modified_error(TrkrClu double zerror = cluster->getZError(); if (TrkrDefs::getTrkrId(key) == TrkrDefs::tpcId) { - if (layer == 7 || layer == 22 || layer == 23 || layer == 38 || layer == 39) + if (layer == 7 || layer == 22 || layer == 23 || layer == 38 || layer == 39 || layer == 54) { phierror *= 4; zerror *= 4; @@ -495,21 +503,141 @@ ClusterErrorPara::error_t ClusterErrorPara::get_clusterv5_modified_error(TrkrClu { phierror *= 2; } - if (cluster->getPhiSize() == 1) - { - phierror *= 10; + if(layer>=7&&layer<=(7+48)){ + //Set phi error + if (cluster->getPhiSize() == 1) + { + phierror *= 1.0; + } + if (cluster->getPhiSize() == 2) + { + phierror*=3.15; + } + if (cluster->getPhiSize() == 3) + { + phierror *=3.5; + } + if (cluster->getPhiSize() >3) + { + phierror *= 4; + } + //Set Z Error + if (cluster->getZSize() == 1){ + zerror*=1.0; + } + if (cluster->getZSize() == 2){ + if(layer>=7&&layer<=(7+16)){ + zerror*=7; + } + if(layer>=(7+16)&&layer<=(7+32)){ + zerror*=4.5; + } + if(layer>=(7+32)&&layer<=(7+48)){ + zerror*=4.5; + } + + } + if ((cluster->getZSize() == 3) || (cluster->getZSize() == 4)){ + if(layer>=7&&layer<=(7+16)){ + zerror*=7; + } + if(layer>=(7+16)&&layer<=(7+32)){ + zerror*=5; + } + if(layer>=(7+32)&&layer<=(7+48)){ + zerror*=5; + } + // zerror*=6; + } + if (cluster->getZSize() >5){ + if(layer>=7&&layer<=(7+16)){ + zerror*=20; + } + if(layer>=(7+16)&&layer<=(7+32)){ + zerror*=6; + } + if(layer>=(7+32)&&layer<=(7+48)){ + zerror*=7; + } + } + TF1 ftpcR1("ftpcR1", "pol2", 0, 60); + ftpcR1.SetParameter(0, 3.206); + ftpcR1.SetParameter(1, -0.252); + ftpcR1.SetParameter(2, 0.007); + + TF1 ftpcR2("ftpcR2", "pol2", 0, 60); + ftpcR2.SetParameter(0, 4.48); + ftpcR2.SetParameter(1, -0.226); + ftpcR2.SetParameter(2, 0.00362); + + TF1 ftpcR3("ftpcR3", "pol2", 0, 60); + ftpcR3.SetParameter(0, 14.8112); + ftpcR3.SetParameter(1, -0.577); + ftpcR3.SetParameter(2, 0.00605); + + if(layer>=7&&layer<=(7+16)){ + phierror*= ftpcR1.Eval(layer); + } + if(layer>=(7+16)&&layer<=(7+32)){ + phierror*= ftpcR2.Eval(layer); + } + if(layer>=(7+32)&&layer<=(7+48)){ + phierror*= ftpcR3.Eval(layer); + } + ftpcR2.SetParameter(0, 5.593); + ftpcR2.SetParameter(1, -0.2458); + ftpcR2.SetParameter(2, 0.00333455); + + ftpcR3.SetParameter(0, 5.6964); + ftpcR3.SetParameter(1, -0.21338); + ftpcR3.SetParameter(2, 0.002502); + + if(layer>=(7+16)&&layer<=(7+32)){ + zerror*= ftpcR2.Eval(layer); + } + if(layer>=(7+32)&&layer<=(7+48)){ + zerror*= ftpcR3.Eval(layer); + } + + } - if (cluster->getPhiSize() >= 5) + /* if (cluster->getPhiSize() >= 5) { phierror *= 10; } + + if(layer>=7){ + } + phierror = std::min(phierror, 0.1); if (phierror < 0.0005) { phierror = 0.1; } + */ + } + + if (TrkrDefs::getTrkrId(key) == TrkrDefs::mvtxId){ + phierror*=2; + zerror*=2; + } + + if (TrkrDefs::getTrkrId(key) == TrkrDefs::inttId){ + phierror*=9; + if (cluster->getPhiSize() == 1){ + phierror *= 1.25; + } + if (cluster->getPhiSize() == 2){ + phierror *= 2.25; + } + if(layer==3||layer==4) + phierror*=0.8; + if(layer==5||layer==6) + phierror*=1.2; } + + return std::make_pair(square(phierror), square(zerror)); } diff --git a/offline/packages/trackbase/ClusterErrorPara.h b/offline/packages/trackbase/ClusterErrorPara.h index b125858217..902a749f1b 100644 --- a/offline/packages/trackbase/ClusterErrorPara.h +++ b/offline/packages/trackbase/ClusterErrorPara.h @@ -17,6 +17,7 @@ class ClusterErrorPara virtual ~ClusterErrorPara() { + //delete ftpcR1; delete f0; delete f1; delete f2; @@ -71,6 +72,7 @@ class ClusterErrorPara double tpc_z_error(int layer, double beta, TrkrCluster *cluster); private: + // TF1 *ftpcR1 {nullptr}; TF1 *f0 {nullptr}; TF1 *f1 {nullptr}; TF1 *f2 {nullptr}; From 1922e63257fea90ba637d514c35633cefa57b11e Mon Sep 17 00:00:00 2001 From: Daniel J Lis Date: Tue, 3 Feb 2026 13:14:23 -0500 Subject: [PATCH 157/393] add fiber unpacking in JET trigger that matches what the firmware does... --- offline/packages/trigger/CaloTriggerEmulator.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/offline/packages/trigger/CaloTriggerEmulator.cc b/offline/packages/trigger/CaloTriggerEmulator.cc index eaf00e4f33..9397288033 100644 --- a/offline/packages/trigger/CaloTriggerEmulator.cc +++ b/offline/packages/trigger/CaloTriggerEmulator.cc @@ -1767,8 +1767,17 @@ int CaloTriggerEmulator::process_organizer() } TriggerDefs::TriggerSumKey jet_skey = (*iter_sum).first; - - TriggerDefs::TriggerSumKey hcal_skey = TriggerDefs::getTriggerSumKey(TriggerDefs::TriggerId::jetTId, TriggerDefs::GetDetectorId("HCAL"), TriggerDefs::GetPrimitiveId("JET"), TriggerDefs::getPrimitiveLocId_from_TriggerPrimKey(jet_pkey), TriggerDefs::getSumLocId(jet_skey)); + uint16_t jet_sum_loc = TriggerDefs::getSumLocId(jet_skey); + uint16_t jet_prim_loc = TriggerDefs::getPrimitiveLocId_from_TriggerSumKey(jet_skey); + if (jet_prim_loc >= 12) + { + uint16_t sumeta = TriggerDefs::getSumEtaId(jet_skey); + uint16_t sumphi = TriggerDefs::getSumPhiId(jet_skey); + jet_sum_loc = sumphi%2 + sumeta*2; + } + TriggerDefs::TriggerSumKey hcal_skey = TriggerDefs::getTriggerSumKey(TriggerDefs::TriggerId::jetTId, TriggerDefs::GetDetectorId("HCAL"), TriggerDefs::GetPrimitiveId("JET"), TriggerDefs::getPrimitiveLocId_from_TriggerPrimKey(jet_pkey), jet_sum_loc); + + TriggerDefs::TriggerSumKey emcal_skey = TriggerDefs::getTriggerSumKey(TriggerDefs::TriggerId::jetTId, TriggerDefs::GetDetectorId("EMCAL"), TriggerDefs::GetPrimitiveId("JET"), TriggerDefs::getPrimitiveLocId_from_TriggerPrimKey(jet_pkey), TriggerDefs::getSumLocId(jet_skey)); int i = 0; From e9df8c5a0596e8ec88f973d6f414f880a05e901c Mon Sep 17 00:00:00 2001 From: Daniel J Lis Date: Tue, 3 Feb 2026 14:08:09 -0500 Subject: [PATCH 158/393] add enum for species in MinBiasClassifier --- .../packages/trigger/MinimumBiasClassifier.cc | 33 ++++++++++++++++--- .../packages/trigger/MinimumBiasClassifier.h | 12 +++++++ offline/packages/trigger/MinimumBiasInfo.h | 8 +++++ 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/offline/packages/trigger/MinimumBiasClassifier.cc b/offline/packages/trigger/MinimumBiasClassifier.cc index b9e7f18460..db3acba38e 100644 --- a/offline/packages/trigger/MinimumBiasClassifier.cc +++ b/offline/packages/trigger/MinimumBiasClassifier.cc @@ -39,6 +39,29 @@ int MinimumBiasClassifier::InitRun(PHCompositeNode *topNode) { std::cout << __FILE__ << " :: " << __FUNCTION__ << std::endl; } + + if (m_species == MinimumBiasInfo::SPECIES::AUAU) + { + m_useZDC = true; + m_max_charge_cut = 2100; + m_box_cut = true; + m_hit_cut = 2; + } + if (m_species == MinimumBiasInfo::SPECIES::OO) + { + m_useZDC = false; + m_max_charge_cut = 300; + m_box_cut = false; + m_hit_cut = 1; + } + if (m_species == MinimumBiasInfo::SPECIES::PP) + { + m_useZDC = false; + m_max_charge_cut = 300; + m_box_cut = false; + m_hit_cut = 1; + } + CDBInterface *m_cdb = CDBInterface::instance(); std::string centscale_url = m_cdb->getUrl("CentralityScale"); @@ -132,7 +155,7 @@ int MinimumBiasClassifier::FillMinimumBiasInfo() { std::cout << "Getting ZDC" << std::endl; } - if (!m_issim) + if (!m_issim && !m_useZDC) { if (!m_zdcinfo) { @@ -169,7 +192,7 @@ int MinimumBiasClassifier::FillMinimumBiasInfo() } // MBD Background cut - if (m_mbd_charge_sum[1] < m_mbd_north_cut && m_mbd_charge_sum[0] > m_mbd_south_cut && minbiascheck) + if (m_box_cut && m_mbd_charge_sum[1] < m_mbd_north_cut && m_mbd_charge_sum[0] > m_mbd_south_cut && minbiascheck) { minbiascheck = false; // m_mb_info->setIsAuAuMinimumBias(false); @@ -179,13 +202,13 @@ int MinimumBiasClassifier::FillMinimumBiasInfo() // Mbd two hit requirement and ZDC energy sum coincidence requirement for (int iside = 0; iside < 2; iside++) { - if (m_mbd_hit[iside] < 2 && minbiascheck) + if (m_mbd_hit[iside] < m_hit_cut && minbiascheck) { minbiascheck = false; // m_mb_info->setIsAuAuMinimumBias(false); // return Fun4AllReturnCodes::EVENT_OK; } - if (!m_issim) + if (!m_issim && m_useZDC) { if (m_zdcinfo->get_zdc_energy(iside) <= m_zdc_cut && minbiascheck) { @@ -195,7 +218,7 @@ int MinimumBiasClassifier::FillMinimumBiasInfo() } } } - if ((m_mbd_charge_sum[0] + m_mbd_charge_sum[1]) > 2100 && minbiascheck) + if ((m_mbd_charge_sum[0] + m_mbd_charge_sum[1]) > m_max_charge_cut && minbiascheck) { minbiascheck = false; // m_mb_info->setIsAuAuMinimumBias(false); diff --git a/offline/packages/trigger/MinimumBiasClassifier.h b/offline/packages/trigger/MinimumBiasClassifier.h index f84add84f8..5f32c10a62 100644 --- a/offline/packages/trigger/MinimumBiasClassifier.h +++ b/offline/packages/trigger/MinimumBiasClassifier.h @@ -8,6 +8,7 @@ #include #include +#include "MinimumBiasInfo.h" // Forward declarations class MinimumBiasInfo; @@ -21,6 +22,8 @@ class MinimumBiasClassifier : public SubsysReco { public: //! constructor + + explicit MinimumBiasClassifier(const std::string &name = "MinimumBiasClassifier"); //! destructor @@ -56,8 +59,17 @@ class MinimumBiasClassifier : public SubsysReco } void setIsSim(const bool sim) { m_issim = sim; } + void setSpecies(MinimumBiasInfo::SPECIES spec) { m_species = spec; }; + private: bool m_issim{false}; + bool m_useZDC{true}; + bool m_box_cut{true}; + int m_hit_cut{2}; + double m_max_charge_cut{2100}; + + MinimumBiasInfo::SPECIES m_species{MinimumBiasInfo::SPECIES::AUAU}; + float getVertexScale(); std::string m_dbfilename; diff --git a/offline/packages/trigger/MinimumBiasInfo.h b/offline/packages/trigger/MinimumBiasInfo.h index 8cd8472e87..94f38b1a8d 100644 --- a/offline/packages/trigger/MinimumBiasInfo.h +++ b/offline/packages/trigger/MinimumBiasInfo.h @@ -6,6 +6,14 @@ class MinimumBiasInfo : public PHObject { public: + + enum SPECIES + { + AUAU = 0, + OO = 1, + PP = 2 + }; + ~MinimumBiasInfo() override {}; void identify(std::ostream &os = std::cout) const override { os << "MinimumBiasInfo base class" << std::endl; }; From 90f4f0103389d1b0b1931f3846bc61c98b593b8c Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Wed, 4 Feb 2026 13:30:02 -0500 Subject: [PATCH 159/393] add root i/o object --- .../sepd_eventplanecalib/EventPlaneData.cc | 9 ++++ .../sepd_eventplanecalib/EventPlaneData.h | 44 +++++++++++++++++++ .../EventPlaneDataLinkDef.h | 5 +++ .../sepd/sepd_eventplanecalib/Makefile.am | 17 ++++++- .../sepd/sepd_eventplanecalib/configure.ac | 3 ++ 5 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 calibrations/sepd/sepd_eventplanecalib/EventPlaneData.cc create mode 100644 calibrations/sepd/sepd_eventplanecalib/EventPlaneData.h create mode 100644 calibrations/sepd/sepd_eventplanecalib/EventPlaneDataLinkDef.h diff --git a/calibrations/sepd/sepd_eventplanecalib/EventPlaneData.cc b/calibrations/sepd/sepd_eventplanecalib/EventPlaneData.cc new file mode 100644 index 0000000000..67223236eb --- /dev/null +++ b/calibrations/sepd/sepd_eventplanecalib/EventPlaneData.cc @@ -0,0 +1,9 @@ +#include "EventPlaneData.h" + +EventPlaneData::EventPlaneData() +{ + sepd_charge.fill(0); + sepd_phi.fill(0); +} + + diff --git a/calibrations/sepd/sepd_eventplanecalib/EventPlaneData.h b/calibrations/sepd/sepd_eventplanecalib/EventPlaneData.h new file mode 100644 index 0000000000..b68fdfb5ff --- /dev/null +++ b/calibrations/sepd/sepd_eventplanecalib/EventPlaneData.h @@ -0,0 +1,44 @@ +#ifndef SEPD_EVENTPLANECALIB_EVENTPLANEDATA_H +#define SEPD_EVENTPLANECALIB_EVENTPLANEDATA_H + +#include + +#include +#include + +class EventPlaneData : public PHObject +{ + public: + EventPlaneData(); + ~EventPlaneData() override = default; + + void Reset() override {*this = EventPlaneData();} // check if this works + // this should be in an sepd define (e.g. ../../../offline/packages/epd/EPDDefs.h) + static constexpr int SEPD_CHANNELS = 744; + void set_event_id(int id) {event_id = id;} + int get_event_id() const {return event_id;} + + void set_event_zvertex(double vtx) {event_zvertex = vtx;} + double get_event_zvertex() const {return event_zvertex;} + + void set_sepd_totalcharge(double chg) {sepd_totalcharge = chg;} + double get_sepd_totalcharge() const {return sepd_totalcharge;} + + void set_sepd_charge(int channel, double chg) {sepd_charge[channel] = chg;} + double get_sepd_charge(int channel) const {return sepd_charge[channel];} + + void set_sepd_phi(int channel, double phi) {sepd_phi[channel] = phi;} + double get_sepd_phi(int channel) const {return sepd_phi[channel];} + + private: + int event_id {0}; + double event_zvertex {std::numeric_limits::quiet_NaN()}; + double event_centrality{std::numeric_limits::quiet_NaN()}; + double sepd_totalcharge{std::numeric_limits::quiet_NaN()}; + + std::array sepd_charge {}; + std::array sepd_phi {}; + ClassDefOverride(EventPlaneData, 1); +}; + +#endif diff --git a/calibrations/sepd/sepd_eventplanecalib/EventPlaneDataLinkDef.h b/calibrations/sepd/sepd_eventplanecalib/EventPlaneDataLinkDef.h new file mode 100644 index 0000000000..9c56106475 --- /dev/null +++ b/calibrations/sepd/sepd_eventplanecalib/EventPlaneDataLinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class EventPlaneData + ; + +#endif /* __CINT__ */ diff --git a/calibrations/sepd/sepd_eventplanecalib/Makefile.am b/calibrations/sepd/sepd_eventplanecalib/Makefile.am index 145947f5e7..3576435566 100644 --- a/calibrations/sepd/sepd_eventplanecalib/Makefile.am +++ b/calibrations/sepd/sepd_eventplanecalib/Makefile.am @@ -6,8 +6,8 @@ bin_PROGRAMS = \ AM_CPPFLAGS = \ -I$(includedir) \ - -I$(OFFLINE_MAIN)/include \ - -I$(ROOTSYS)/include + -isystem$(OFFLINE_MAIN)/include \ + -isystem$(ROOTSYS)/include AM_LDFLAGS = \ -L$(libdir) \ @@ -24,7 +24,13 @@ pkginclude_HEADERS = \ lib_LTLIBRARIES = \ libsepd_eventplanecalib.la +ROOTDICTS = \ + EventPlaneData_Dict.cc + +# EventPlaneData is a locally used root i/o object - no need to create an io library libsepd_eventplanecalib_la_SOURCES = \ + $(ROOTDICTS) \ + EventPlaneData.cc \ sEPD_TreeGen.cc \ QVecCalib.cc \ QVecCDB.cc @@ -47,6 +53,13 @@ GenQVecCalib_LDADD = libsepd_eventplanecalib.la GenQVecCDB_SOURCES = GenQVecCDB.cc GenQVecCDB_LDADD = libsepd_eventplanecalib.la +# Rule for generating table CINT dictionaries. +%_Dict.cc: %.h %LinkDef.h + rootcint -f $@ @CINTDEFS@ $(DEFAULT_INCLUDES) $(AM_CPPFLAGS) $^ + +#just to get the dependency +%_Dict_rdict.pcm: %_Dict.cc ; + BUILT_SOURCES = testexternals.cc noinst_PROGRAMS = \ diff --git a/calibrations/sepd/sepd_eventplanecalib/configure.ac b/calibrations/sepd/sepd_eventplanecalib/configure.ac index 4abe4ad0ce..5fcb1af63a 100644 --- a/calibrations/sepd/sepd_eventplanecalib/configure.ac +++ b/calibrations/sepd/sepd_eventplanecalib/configure.ac @@ -12,5 +12,8 @@ if test $ac_cv_prog_gxx = yes; then CXXFLAGS="$CXXFLAGS -Wshadow -Wall -Wextra -Werror" fi +CINTDEFS=" -noIncludePaths -inlineInputHeader " +AC_SUBST(CINTDEFS) + AC_CONFIG_FILES([Makefile]) AC_OUTPUT From 505d785b74c1efdbb25133d74a7c0b3de7e4fae1 Mon Sep 17 00:00:00 2001 From: Ishan Goel Date: Wed, 4 Feb 2026 13:30:49 -0500 Subject: [PATCH 160/393] New changes --- offline/packages/tpc/TpcClusterizer.cc | 103 ++++++++++++++----------- offline/packages/tpc/TpcClusterizer.h | 11 +-- 2 files changed, 65 insertions(+), 49 deletions(-) diff --git a/offline/packages/tpc/TpcClusterizer.cc b/offline/packages/tpc/TpcClusterizer.cc index 881bc7f681..5be76aca3e 100644 --- a/offline/packages/tpc/TpcClusterizer.cc +++ b/offline/packages/tpc/TpcClusterizer.cc @@ -61,6 +61,7 @@ #include #include // for pair #include +#include // Terra incognita.... #include @@ -123,8 +124,8 @@ namespace double m_tdriftmax = 0; // --- new members for dead/hot map --- - hitMaskTpc *deadMap = nullptr; - hitMaskTpc *hotMap = nullptr; + hitMaskTpcSet *deadMap = nullptr; + hitMaskTpcSet *hotMap = nullptr; bool maskDead = false; bool maskHot = false; @@ -605,43 +606,53 @@ namespace TrkrDefs::hitsetkey tpcHitSetKey = TpcDefs::genHitSetKey(my_data.layer, my_data.sector, my_data.side); + // pads just outside the cluster in phi + const int left_pad = phibinlo - 1; + const int right_pad = phibinhi + 1; + // --- Dead channels --- - if (my_data.maskDead && my_data.deadMap->count(tpcHitSetKey)) + if (my_data.maskDead) + { + auto it = my_data.deadMap->find(tpcHitSetKey); + if (it != my_data.deadMap->end()) { - const auto &deadvec = (*my_data.deadMap)[tpcHitSetKey]; - - for (const auto &deadkey : deadvec) - { - int dphi = TpcDefs::getPad(deadkey); + const auto &deadset = it->second; - bool touch = (dphi == phibinlo - 1 || dphi == phibinhi + 1); + if (left_pad >= 0 && + deadset.count(TpcDefs::genHitKey(left_pad, 0))) + { + nedge++; + } - if (touch) - { - nedge++; - continue; - } - } + if (right_pad < my_data.phibins && + deadset.count(TpcDefs::genHitKey(right_pad, 0))) + { + nedge++; + } } + } // --- Hot channels --- - if (my_data.maskHot && my_data.hotMap->count(tpcHitSetKey)) + if (my_data.maskHot) + { + auto it = my_data.hotMap->find(tpcHitSetKey); + if (it != my_data.hotMap->end()) { - const auto &hotvec = (*my_data.hotMap)[tpcHitSetKey]; - - for (const auto &hotkey : hotvec) - { - int hphi = TpcDefs::getPad(hotkey); + const auto &hotset = it->second; - bool touch = (hphi == phibinlo -1 || hphi == phibinhi + 1); + if (left_pad >= 0 && + hotset.count(TpcDefs::genHitKey(left_pad, 0))) + { + nedge++; + } - if (touch) - { - nedge++; - continue; - } - } + if (right_pad < my_data.phibins && + hotset.count(TpcDefs::genHitKey(right_pad, 0))) + { + nedge++; + } } + } // This is the global position double clusiphi = iphi_sum / adc_sum; @@ -843,24 +854,28 @@ namespace // Helper function to check if a pad is masked auto is_pad_masked = [&](int abs_pad) -> bool { - if (my_data->maskDead && my_data->deadMap->count(tpcHitSetKey)) + TrkrDefs::hitkey key = TpcDefs::genHitKey(abs_pad, 0); + + if (my_data->maskDead) + { + auto it = my_data->deadMap->find(tpcHitSetKey); + if (it != my_data->deadMap->end() && + it->second.count(key)) { - const auto &deadvec = (*my_data->deadMap)[tpcHitSetKey]; - for (const auto &deadkey : deadvec) - { - if (TpcDefs::getPad(deadkey) == abs_pad) - return true; - } + return true; } - if (my_data->maskHot && my_data->hotMap->count(tpcHitSetKey)) + } + + if (my_data->maskHot) + { + auto it = my_data->hotMap->find(tpcHitSetKey); + if (it != my_data->hotMap->end() && + it->second.count(key)) { - const auto &hotvec = (*my_data->hotMap)[tpcHitSetKey]; - for (const auto &hotkey : hotvec) - { - if (TpcDefs::getPad(hotkey) == abs_pad) - return true; - } + return true; } + } + return false; }; @@ -1806,7 +1821,7 @@ int TpcClusterizer::End(PHCompositeNode * /*topNode*/) return Fun4AllReturnCodes::EVENT_OK; } -void TpcClusterizer::makeChannelMask(hitMaskTpc &aMask, const std::string &dbName, const std::string &totalChannelsToMask) +void TpcClusterizer::makeChannelMask(hitMaskTpcSet &aMask, const std::string &dbName, const std::string &totalChannelsToMask) { CDBTTree *cdbttree; if (m_maskFromFile) @@ -1837,7 +1852,7 @@ void TpcClusterizer::makeChannelMask(hitMaskTpc &aMask, const std::string &dbNam TrkrDefs::hitsetkey DeadChannelHitKey = TpcDefs::genHitSetKey(Layer, Sector, Side); TrkrDefs::hitkey DeadHitKey = TpcDefs::genHitKey((unsigned int) Pad, 0); - aMask[DeadChannelHitKey].push_back(DeadHitKey); + aMask[DeadChannelHitKey].insert(DeadHitKey); } delete cdbttree; diff --git a/offline/packages/tpc/TpcClusterizer.h b/offline/packages/tpc/TpcClusterizer.h index 6ec5c18b1c..84a58ceca6 100644 --- a/offline/packages/tpc/TpcClusterizer.h +++ b/offline/packages/tpc/TpcClusterizer.h @@ -4,12 +4,13 @@ #include #include #include +#include #include #include -#include +#include -typedef std::map> hitMaskTpc; +typedef std::map> hitMaskTpcSet; class ClusHitsVerbosev1; class PHCompositeNode; @@ -94,7 +95,7 @@ class TpcClusterizer : public SubsysReco bool is_in_sector_boundary(int phibin, int sector, PHG4TpcGeom *layergeom) const; bool record_ClusHitsVerbose{false}; - void makeChannelMask(hitMaskTpc& aMask, const std::string& dbName, const std::string& totalChannelsToMask); + void makeChannelMask(hitMaskTpcSet& aMask, const std::string& dbName, const std::string& totalChannelsToMask); TrkrHitSetContainer *m_hits = nullptr; RawHitSetContainer *m_rawhits = nullptr; @@ -128,8 +129,8 @@ class TpcClusterizer : public SubsysReco TrainingHitsContainer *m_training; - hitMaskTpc m_deadChannelMap; - hitMaskTpc m_hotChannelMap; + hitMaskTpcSet m_deadChannelMap; + hitMaskTpcSet m_hotChannelMap; bool m_maskDeadChannels {false}; bool m_maskHotChannels {false}; From 59ef9fc067e139b916051d8d6a99762825601f6c Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Wed, 4 Feb 2026 13:54:31 -0500 Subject: [PATCH 161/393] add EventPlaneData node --- .../sepd/sepd_eventplanecalib/sEPD_TreeGen.cc | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc b/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc index 38c9a25c18..279577e295 100644 --- a/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc +++ b/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc @@ -1,21 +1,11 @@ #include "sEPD_TreeGen.h" #include "QVecDefs.h" +#include "EventPlaneData.h" // -- c++ #include #include -// -- event -#include - -// -- Fun4All -#include -#include - -// -- Nodes -#include -#include - // -- Calo #include #include @@ -33,6 +23,18 @@ // -- sEPD #include +// -- event +#include + +// -- Fun4All +#include +#include + +// -- Nodes +#include +#include +#include + //____________________________________________________________________________.. sEPD_TreeGen::sEPD_TreeGen(const std::string &name) : SubsysReco(name) @@ -40,7 +42,7 @@ sEPD_TreeGen::sEPD_TreeGen(const std::string &name) } //____________________________________________________________________________.. -int sEPD_TreeGen::Init([[maybe_unused]] PHCompositeNode *topNode) +int sEPD_TreeGen::Init(PHCompositeNode *topNode) { // Early guard against filename collision if (m_outfile_name == m_outtree_name) @@ -85,6 +87,16 @@ int sEPD_TreeGen::Init([[maybe_unused]] PHCompositeNode *topNode) m_tree->Branch("sepd_channel", &m_data.sepd_channel); m_tree->Branch("sepd_charge", &m_data.sepd_charge); m_tree->Branch("sepd_phi", &m_data.sepd_phi); + PHNodeIterator node_itr(topNode); + PHCompositeNode *dstNode = dynamic_cast(node_itr.findFirst("PHCompositeNode", "DST")); + + EventPlaneData *evtdata = findNode::getClass(topNode, "EventPlaneData"); + if (!evtdata) + { + evtdata = new EventPlaneData(); + PHIODataNode *newNode = new PHIODataNode(evtdata, "EventPlaneData", "PHObject"); + dstNode->addNode(newNode); + } return Fun4AllReturnCodes::EVENT_OK; } From f683f68bb17547a627e002e0a380707a17e82ac5 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Wed, 4 Feb 2026 14:36:28 -0500 Subject: [PATCH 162/393] add forgotten pcm file installation --- calibrations/sepd/sepd_eventplanecalib/Makefile.am | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/calibrations/sepd/sepd_eventplanecalib/Makefile.am b/calibrations/sepd/sepd_eventplanecalib/Makefile.am index 3576435566..d09895d691 100644 --- a/calibrations/sepd/sepd_eventplanecalib/Makefile.am +++ b/calibrations/sepd/sepd_eventplanecalib/Makefile.am @@ -27,6 +27,10 @@ lib_LTLIBRARIES = \ ROOTDICTS = \ EventPlaneData_Dict.cc +pcmdir = $(libdir) +# more elegant way to create pcm files (without listing them) +nobase_dist_pcm_DATA = $(ROOTDICTS:.cc=_rdict.pcm) + # EventPlaneData is a locally used root i/o object - no need to create an io library libsepd_eventplanecalib_la_SOURCES = \ $(ROOTDICTS) \ From 1a6a8c0fbfb27ebb550ed507935023139f373dea Mon Sep 17 00:00:00 2001 From: Ishan Goel Date: Wed, 4 Feb 2026 14:47:49 -0500 Subject: [PATCH 163/393] Some more --- offline/packages/tpc/TpcClusterizer.cc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/offline/packages/tpc/TpcClusterizer.cc b/offline/packages/tpc/TpcClusterizer.cc index 5be76aca3e..e9e5d6212e 100644 --- a/offline/packages/tpc/TpcClusterizer.cc +++ b/offline/packages/tpc/TpcClusterizer.cc @@ -619,12 +619,13 @@ namespace const auto &deadset = it->second; if (left_pad >= 0 && + left_pad >= my_data.phioffset && deadset.count(TpcDefs::genHitKey(left_pad, 0))) { nedge++; } - if (right_pad < my_data.phibins && + if (right_pad < (my_data.phibins + my_data.phioffset) && deadset.count(TpcDefs::genHitKey(right_pad, 0))) { nedge++; @@ -641,12 +642,13 @@ namespace const auto &hotset = it->second; if (left_pad >= 0 && + left_pad >= my_data.phioffset && hotset.count(TpcDefs::genHitKey(left_pad, 0))) { nedge++; } - if (right_pad < my_data.phibins && + if (right_pad < (my_data.phibins + my_data.phioffset) && hotset.count(TpcDefs::genHitKey(right_pad, 0))) { nedge++; @@ -1823,15 +1825,15 @@ int TpcClusterizer::End(PHCompositeNode * /*topNode*/) void TpcClusterizer::makeChannelMask(hitMaskTpcSet &aMask, const std::string &dbName, const std::string &totalChannelsToMask) { - CDBTTree *cdbttree; + std::unique_ptr cdbttree; if (m_maskFromFile) { - cdbttree = new CDBTTree(dbName); + cdbttree = std::make_unique(dbName); } else // mask using CDB TTree, default { std::string database = CDBInterface::instance()->getUrl(dbName); - cdbttree = new CDBTTree(database); + cdbttree = std::make_unique(database); } std::cout << "Masking TPC Channel Map: " << dbName << std::endl; @@ -1855,5 +1857,4 @@ void TpcClusterizer::makeChannelMask(hitMaskTpcSet &aMask, const std::string &db aMask[DeadChannelHitKey].insert(DeadHitKey); } - delete cdbttree; } From 86043f34caca553c863a08e21d1be7b52931ca4b Mon Sep 17 00:00:00 2001 From: Ishan Goel Date: Wed, 4 Feb 2026 14:57:30 -0500 Subject: [PATCH 164/393] Another change --- offline/packages/tpc/TpcClusterizer.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/offline/packages/tpc/TpcClusterizer.cc b/offline/packages/tpc/TpcClusterizer.cc index e9e5d6212e..5885f03e2d 100644 --- a/offline/packages/tpc/TpcClusterizer.cc +++ b/offline/packages/tpc/TpcClusterizer.cc @@ -1841,6 +1841,13 @@ void TpcClusterizer::makeChannelMask(hitMaskTpcSet &aMask, const std::string &db int NChan = -1; NChan = cdbttree->GetSingleIntValue(totalChannelsToMask); + if (NChan < 0) + { + std::cout << PHWHERE << "ERROR: Invalid or missing " << totalChannelsToMask + << " for " << dbName << ". Masking disabled for this map." << std::endl; + return; + } + for (int i = 0; i < NChan; i++) { int Layer = cdbttree->GetIntValue(i, "layer"); From 85003e4a20ef8bbcdd0aa6c516e8261c13661dfc Mon Sep 17 00:00:00 2001 From: Ishan Goel Date: Wed, 4 Feb 2026 15:16:11 -0500 Subject: [PATCH 165/393] New --- offline/packages/tpc/TpcClusterizer.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/offline/packages/tpc/TpcClusterizer.cc b/offline/packages/tpc/TpcClusterizer.cc index 5885f03e2d..834491e3b4 100644 --- a/offline/packages/tpc/TpcClusterizer.cc +++ b/offline/packages/tpc/TpcClusterizer.cc @@ -1833,6 +1833,14 @@ void TpcClusterizer::makeChannelMask(hitMaskTpcSet &aMask, const std::string &db else // mask using CDB TTree, default { std::string database = CDBInterface::instance()->getUrl(dbName); + + if (database.empty()) + { + std::cout << PHWHERE << "ERROR: CDB URL not found for " << dbName + << ". Masking disabled for this map." << std::endl; + return; + } + cdbttree = std::make_unique(database); } From 40660d1532e54f5c5aab4a2f86d8510823a25b23 Mon Sep 17 00:00:00 2001 From: Ishan Goel Date: Wed, 4 Feb 2026 15:34:04 -0500 Subject: [PATCH 166/393] More change. --- offline/packages/tpc/TpcClusterizer.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/offline/packages/tpc/TpcClusterizer.cc b/offline/packages/tpc/TpcClusterizer.cc index 834491e3b4..c5334ab6e0 100644 --- a/offline/packages/tpc/TpcClusterizer.cc +++ b/offline/packages/tpc/TpcClusterizer.cc @@ -962,16 +962,16 @@ namespace continue; } - int pindex = 0; + if (is_pad_masked(nphi + phioffset)) + { + continue; + } + + int pindex = 0; for (unsigned int nt = 0; nt < hitset->size(nphi); nt++) { unsigned short val = (*(hitset->getHits(nphi)))[nt]; - if (is_pad_masked(nphi + phioffset)) - { - pindex++; - continue; - } if (val == 0) { pindex++; From 2110245677195fc344372268bc0b40f8947fb239 Mon Sep 17 00:00:00 2001 From: Ishan Goel Date: Wed, 4 Feb 2026 15:40:46 -0500 Subject: [PATCH 167/393] Good --- offline/packages/tpc/TpcClusterizer.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/offline/packages/tpc/TpcClusterizer.cc b/offline/packages/tpc/TpcClusterizer.cc index c5334ab6e0..ef22dea7d0 100644 --- a/offline/packages/tpc/TpcClusterizer.cc +++ b/offline/packages/tpc/TpcClusterizer.cc @@ -52,6 +52,7 @@ #include +#include #include #include #include // for sqrt, cos, sin From 83a66dbe76cb5dcb3eaccbe002fac9f171bd2321 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Wed, 4 Feb 2026 21:29:59 -0500 Subject: [PATCH 168/393] add setter for cluster map name --- .../TrackingDiagnostics/TrackSeedTrackMapConverter.cc | 5 +++-- .../TrackingDiagnostics/TrackSeedTrackMapConverter.h | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/offline/packages/TrackingDiagnostics/TrackSeedTrackMapConverter.cc b/offline/packages/TrackingDiagnostics/TrackSeedTrackMapConverter.cc index 02a10baea3..969e746c82 100644 --- a/offline/packages/TrackingDiagnostics/TrackSeedTrackMapConverter.cc +++ b/offline/packages/TrackingDiagnostics/TrackSeedTrackMapConverter.cc @@ -588,10 +588,11 @@ int TrackSeedTrackMapConverter::getNodes(PHCompositeNode* topNode) std::cout << PHWHERE << "WARNING, TrackSeedTrackMapConverter may seg fault depending on what seeding algorithm this is run after" << std::endl; } - m_clusters = findNode::getClass(topNode, "TRKR_CLUSTER"); + m_clusters = findNode::getClass(topNode, m_clusterMapName); if (!m_clusters) { - std::cout << PHWHERE << " Can't find cluster container, can't continue." + std::cout << PHWHERE << " Can't find cluster container " << m_clusterMapName + << ", can't continue." << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } diff --git a/offline/packages/TrackingDiagnostics/TrackSeedTrackMapConverter.h b/offline/packages/TrackingDiagnostics/TrackSeedTrackMapConverter.h index 1cff3281d7..ef9c48766e 100644 --- a/offline/packages/TrackingDiagnostics/TrackSeedTrackMapConverter.h +++ b/offline/packages/TrackingDiagnostics/TrackSeedTrackMapConverter.h @@ -29,6 +29,7 @@ class TrackSeedTrackMapConverter : public SubsysReco void setFieldMap(const std::string &name) { m_fieldMap = name; } void setTrackMapName(const std::string &name) { m_trackMapName = name; } void setTrackSeedName(const std::string &name) { m_trackSeedName = name; } + void setClusterMapName(const std::string& name) {m_clusterMapName = name; } void cosmics() { m_cosmics = true; } void constField() { m_ConstField = true; } @@ -56,6 +57,7 @@ class TrackSeedTrackMapConverter : public SubsysReco std::string m_fieldMap; std::string m_trackMapName{"SvtxTrackMap"}; std::string m_trackSeedName{"TpcTrackSeedContainer"}; + std::string m_clusterMapName{"TRKR_CLUSTER"}; }; #endif // TRACKSEEDTRACKMAPCONVERTER_H From 6974a5765ea61cd4e88a38b3561e5014376c3543 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Thu, 5 Feb 2026 09:50:11 -0500 Subject: [PATCH 169/393] add diagnostic print out for checking for remaining duplicates --- .../packages/trackreco/PHSiliconSeedMerger.cc | 78 ++++++++++++++++++- 1 file changed, 74 insertions(+), 4 deletions(-) diff --git a/offline/packages/trackreco/PHSiliconSeedMerger.cc b/offline/packages/trackreco/PHSiliconSeedMerger.cc index 263fdd6b35..5e47ebd548 100644 --- a/offline/packages/trackreco/PHSiliconSeedMerger.cc +++ b/offline/packages/trackreco/PHSiliconSeedMerger.cc @@ -88,7 +88,6 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode* /*unused*/) ++track1ID) { TrackSeed* track1 = m_siliconTracks->get(track1ID); - if (seedsToDelete.contains(track1ID)) { continue; @@ -125,7 +124,6 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode* /*unused*/) { continue; } - TrackSeed* track2 = m_siliconTracks->get(track2ID); if (track2 == nullptr) { @@ -260,13 +258,85 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode* /*unused*/) if (Verbosity() > 2) { - for (const auto& seed : *m_siliconTracks) + + for (unsigned int track1ID = 0; + track1ID != m_siliconTracks->size(); + ++track1ID) { + std::set mvtx1Keyscheck; + + TrackSeed* seed = m_siliconTracks->get(track1ID); if (!seed) { continue; } - seed->identify(); + int strobe1 = -9999; + for (auto iter = seed->begin_cluster_keys(); + iter != seed->end_cluster_keys(); + ++iter) + { + mvtx1Keyscheck.insert(*iter); + if( TrkrDefs::getTrkrId(*iter) == TrkrDefs::mvtxId) + { + strobe1 = MvtxDefs::getStrobeId(*iter); + } + } + + + + for (unsigned int track2ID = 0; + track2ID != m_siliconTracks->size(); + ++track2ID) + { + std::set mvtx2Keyscheck; + TrackSeed* seed2 = m_siliconTracks->get(track2ID); + if (!seed2) + { + continue; + } + int strobe2 = -9999; + for (auto iter2 = seed2->begin_cluster_keys(); + iter2 != seed2->end_cluster_keys(); + ++iter2) + { + mvtx2Keyscheck.insert(*iter2); + if (TrkrDefs::getTrkrId(*iter2) == TrkrDefs::mvtxId) + { + strobe2 = MvtxDefs::getStrobeId(*iter2); + } + } + std::vector intersectioncheck; + std::set_intersection(mvtx1Keyscheck.begin(), + mvtx1Keyscheck.end(), + mvtx2Keyscheck.begin(), + mvtx2Keyscheck.end(), + std::back_inserter(intersectioncheck)); + if(track1ID != track2ID) + { + if(intersectioncheck.size() == mvtx1Keyscheck.size() || intersectioncheck.size() == mvtx2Keyscheck.size()) + { + std::cout << "After merge, still have duplicate seeds: " + << " seed1 ID " << track1ID << " strobe " << strobe1 << " nkeys " << mvtx1Keyscheck.size() + << " seed2 ID " << track2ID << " strobe " << strobe2 << " nkeys " << mvtx2Keyscheck.size() + << " intersection size " << intersectioncheck.size() + << std::endl; + std::cout << "seed 1 keys " << std::endl; + std::cout << " "; + for (const auto& key : mvtx1Keyscheck) + { + std::cout << key << ", "; + } + std::cout << std::endl; + std::cout << "seed 2 keys " << std::endl; + std::cout << " "; + for (const auto& key : mvtx2Keyscheck) + { + std::cout << key << ", "; + } + std::cout << std::endl; + } + } + } } } From 56fd8e5dca5f1969a7299c7482f8731f7fa66c68 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Thu, 5 Feb 2026 09:50:26 -0500 Subject: [PATCH 170/393] fix duplicate bug --- offline/packages/trackreco/PHSiliconSeedMerger.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/trackreco/PHSiliconSeedMerger.cc b/offline/packages/trackreco/PHSiliconSeedMerger.cc index 5e47ebd548..c522700ff3 100644 --- a/offline/packages/trackreco/PHSiliconSeedMerger.cc +++ b/offline/packages/trackreco/PHSiliconSeedMerger.cc @@ -220,7 +220,7 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode* /*unused*/) matches.insert(std::make_pair(track1ID, mvtx1Keys)); seedsToDelete.insert(track2ID); - break; + } } } From 77ed93afaafa2f84882b5811d78d4bb6f920ff5f Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Thu, 5 Feb 2026 09:55:01 -0500 Subject: [PATCH 171/393] move diagnostic to function --- .../packages/trackreco/PHSiliconSeedMerger.cc | 106 +++++++++--------- .../packages/trackreco/PHSiliconSeedMerger.h | 5 +- 2 files changed, 57 insertions(+), 54 deletions(-) diff --git a/offline/packages/trackreco/PHSiliconSeedMerger.cc b/offline/packages/trackreco/PHSiliconSeedMerger.cc index c522700ff3..acf6c9f1cd 100644 --- a/offline/packages/trackreco/PHSiliconSeedMerger.cc +++ b/offline/packages/trackreco/PHSiliconSeedMerger.cc @@ -258,8 +258,60 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode* /*unused*/) if (Verbosity() > 2) { + printRemainingDuplicates(); + } + + return Fun4AllReturnCodes::EVENT_OK; +} + +/** + * @brief Reset per-event state for the merger. + * + * This implementation performs no per-event cleanup and always reports success. + * + * @return Integer status code: `Fun4AllReturnCodes::EVENT_OK`. + */ +int PHSiliconSeedMerger::ResetEvent(PHCompositeNode* /*unused*/) +{ + return Fun4AllReturnCodes::EVENT_OK; +} + +/** + * @brief Perform end-of-run shutdown for the silicon seed merger. + * + * @return int EVENT_OK on successful completion. + */ +int PHSiliconSeedMerger::End(PHCompositeNode* /*unused*/) +{ + return Fun4AllReturnCodes::EVENT_OK; +} - for (unsigned int track1ID = 0; +/** + * @brief Retrieve required nodes from the top-level node tree and validate availability. + * + * Locates the silicon TrackSeedContainer using m_trackMapName and stores it in + * m_siliconTracks. If the container is not found, the function logs an error + * message and signals an abort for the current event. + * + * @param topNode Root node used to search for the TrackSeedContainer. + * @return int Fun4AllReturnCodes::EVENT_OK on success, Fun4AllReturnCodes::ABORTEVENT if the silicon TrackSeedContainer is not present. + */ +int PHSiliconSeedMerger::getNodes(PHCompositeNode* topNode) +{ + m_siliconTracks = findNode::getClass(topNode, m_trackMapName); + if (!m_siliconTracks) + { + std::cout << PHWHERE << "No silicon track container, can't merge seeds" + << std::endl; + return Fun4AllReturnCodes::ABORTEVENT; + } + + return Fun4AllReturnCodes::EVENT_OK; +} + +void PHSiliconSeedMerger::printRemainingDuplicates() +{ + for (unsigned int track1ID = 0; track1ID != m_siliconTracks->size(); ++track1ID) { @@ -338,54 +390,4 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode* /*unused*/) } } } - } - - return Fun4AllReturnCodes::EVENT_OK; -} - -/** - * @brief Reset per-event state for the merger. - * - * This implementation performs no per-event cleanup and always reports success. - * - * @return Integer status code: `Fun4AllReturnCodes::EVENT_OK`. - */ -int PHSiliconSeedMerger::ResetEvent(PHCompositeNode* /*unused*/) -{ - return Fun4AllReturnCodes::EVENT_OK; -} - -/** - * @brief Perform end-of-run shutdown for the silicon seed merger. - * - * @return int EVENT_OK on successful completion. - */ -int PHSiliconSeedMerger::End(PHCompositeNode* /*unused*/) -{ - return Fun4AllReturnCodes::EVENT_OK; -} - -/** - * @brief Retrieve required nodes from the top-level node tree and validate availability. - * - * Locates the silicon TrackSeedContainer using m_trackMapName and stores it in - * m_siliconTracks. If the container is not found, the function logs an error - * message and signals an abort for the current event. - * - * @param topNode Root node used to search for the TrackSeedContainer. - * @return int Fun4AllReturnCodes::EVENT_OK on success, Fun4AllReturnCodes::ABORTEVENT if the silicon TrackSeedContainer is not present. - */ -int PHSiliconSeedMerger::getNodes(PHCompositeNode* topNode) -{ - m_siliconTracks = findNode::getClass(topNode, m_trackMapName); - if (!m_siliconTracks) - { - std::cout << PHWHERE << "No silicon track container, can't merge seeds" - << std::endl; - return Fun4AllReturnCodes::ABORTEVENT; - } - - return Fun4AllReturnCodes::EVENT_OK; -} - - +} \ No newline at end of file diff --git a/offline/packages/trackreco/PHSiliconSeedMerger.h b/offline/packages/trackreco/PHSiliconSeedMerger.h index fcd741e688..d3d828d565 100644 --- a/offline/packages/trackreco/PHSiliconSeedMerger.h +++ b/offline/packages/trackreco/PHSiliconSeedMerger.h @@ -51,7 +51,7 @@ void mergeSeeds() { m_mergeSeeds = true; } private: int getNodes(PHCompositeNode *topNode); - + void printRemainingDuplicates(); TrackSeedContainer *m_siliconTracks{nullptr}; std::string m_trackMapName{"SiliconTrackSeedContainer"}; /** @@ -60,7 +60,8 @@ void mergeSeeds() { m_mergeSeeds = true; } * * Defaults to 1. */ -unsigned int m_clusterOverlap{1}; + unsigned int m_clusterOverlap{1}; + bool m_mergeSeeds{false}; /** * Restrict seed processing to the MVTX detector only. From cb381d6853ee81bf7b8d9d25d55aa42596706d1b Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Thu, 5 Feb 2026 10:23:58 -0500 Subject: [PATCH 172/393] fix logic bug noticed by rabbit --- offline/packages/trackreco/PHSiliconSeedMerger.cc | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/offline/packages/trackreco/PHSiliconSeedMerger.cc b/offline/packages/trackreco/PHSiliconSeedMerger.cc index acf6c9f1cd..cd9de3c95c 100644 --- a/offline/packages/trackreco/PHSiliconSeedMerger.cc +++ b/offline/packages/trackreco/PHSiliconSeedMerger.cc @@ -208,19 +208,6 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode* /*unused*/) std::cout << " will delete seed " << track1ID << std::endl; } } - - if (Verbosity() > 2) - { - std::cout << "Match IDed" << std::endl; - for (const auto& key : mvtx1Keys) - { - std::cout << " total track keys " << key << std::endl; - } - } - - matches.insert(std::make_pair(track1ID, mvtx1Keys)); - seedsToDelete.insert(track2ID); - } } } From 932b4105604efb57296653dc8def1a4a30e5bd39 Mon Sep 17 00:00:00 2001 From: bkimelman Date: Thu, 5 Feb 2026 12:21:50 -0500 Subject: [PATCH 173/393] Additional changes to matching and lamination fitting --- .../tpccalib/TpcCentralMembraneMatching.cc | 236 +++++++++++++++++- .../tpccalib/TpcCentralMembraneMatching.h | 15 ++ .../packages/tpccalib/TpcLaminationFitting.cc | 51 +++- .../packages/tpccalib/TpcLaminationFitting.h | 3 + 4 files changed, 285 insertions(+), 20 deletions(-) diff --git a/offline/packages/tpccalib/TpcCentralMembraneMatching.cc b/offline/packages/tpccalib/TpcCentralMembraneMatching.cc index fa73218b7a..2e85f78a0c 100644 --- a/offline/packages/tpccalib/TpcCentralMembraneMatching.cc +++ b/offline/packages/tpccalib/TpcCentralMembraneMatching.cc @@ -981,6 +981,9 @@ int TpcCentralMembraneMatching::getClusterRMatch(double clusterR, int side) //____________________________________________________________________________.. int TpcCentralMembraneMatching::InitRun(PHCompositeNode* topNode) { + + std::cout << "skipOutliers? " << m_skipOutliers << " manualInterp? " << m_manualInterp << std::endl; + if (!m_fieldOn) { m_useHeader = false; @@ -2266,12 +2269,20 @@ int TpcCentralMembraneMatching::process_event(PHCompositeNode* topNode) ckey++; } - + // std::cout << "about to fill fluct hist" << std::endl; for (int s = 0; s < 2; s++) { + /* int N = gr_dR[s]->GetN(); + std::vector dataX(N), dataY(N); + for(int k=0; kGetY()[k]*cos(gr_dR[s]->GetX()[k]); + dataY[k] = gr_dR[s]->GetY()[k]*sin(gr_dR[s]->GetX()[k]); + } + */ bool firstGoodR = false; for (int j = 1; j <= m_dcc_out->m_hDRint[s]->GetNbinsY(); j++) @@ -2297,18 +2308,22 @@ int TpcCentralMembraneMatching::process_event(PHCompositeNode* topNode) { double phiVal = m_dcc_out->m_hDRint[s]->GetXaxis()->GetBinCenter(i); + /* double num_dPhi = 0.0; double num_dR = 0.0; double den = 0.0; double smoothing_parameter = 2.0; + double hX = RVal*cos(phiVal); + double hY = RVal*sin(phiVal); + + + for(int k=0; kGetX()[k]); - double interp_RdPhi = RVal*interp_dPhi; - double interp_dR = RVal - gr_dR[s]->GetY()[k]; - - double distSq = (interp_RdPhi*interp_RdPhi) + (interp_dR*interp_dR); + double dx = hX - dataX[k]; + double dy = hY - dataY[k]; + double distSq = (dx*dx) + (dy*dy); if(distSq > 100.0) continue; @@ -2334,8 +2349,9 @@ int TpcCentralMembraneMatching::process_event(PHCompositeNode* topNode) m_dcc_out->m_hDRint[s]->SetBinContent(i, j, num_dR / den); m_dcc_out->m_hDPint[s]->SetBinContent(i, j, RVal*(num_dPhi / den)); } - //m_dcc_out->m_hDRint[s]->SetBinContent(i, j, gr_dR[s]->Interpolate(phiVal,RVal)); - //m_dcc_out->m_hDPint[s]->SetBinContent(i, j, RVal*gr_dPhi[s]->Interpolate(phiVal,RVal)); + */ + m_dcc_out->m_hDRint[s]->SetBinContent(i, j, gr_dR[s]->Interpolate(phiVal,RVal)); + m_dcc_out->m_hDPint[s]->SetBinContent(i, j, RVal*gr_dPhi[s]->Interpolate(phiVal,RVal)); } } } @@ -2427,15 +2443,146 @@ int TpcCentralMembraneMatching::End(PHCompositeNode* /*topNode*/) } } + for(int s=0; s<2; s++) + { + gr_dR_toInterp[s] = (TGraph2D*)gr_dR[s]->Clone(); + gr_dPhi_toInterp[s] = (TGraph2D*)gr_dPhi[s]->Clone(); + } + + //figure out anomolous points to skip and make list + std::vector pointsToSkip[2]; + if(m_skipOutliers) + { + for(int s=0; s<2; s++) + { + std::vector peakBins; + std::vector peakVals; + TH1D *hPeaks = new TH1D("hPeaks","",500,26,80); + int N = gr_dR[s]->GetN(); + + //Make R histogram + for(int i=0; iFill(gr_dR[s]->GetY()[i]); + } + + int bc = 0; + int pbc = 0; + //loop over and find peaks by identifying hist bins where content is higher than adjacent bins + for(int i=1; i<=500; i++) + { + bc = hPeaks->GetBinContent(i); + if(bc > 10 && bc > pbc) + { + if(peakBins.size() == 0 || i > peakBins[peakBins.size()-1] + 1) + { + peakBins.push_back(i); + } + else + { + peakBins[peakBins.size()-1] = i; + } + } + pbc = bc; + } + + //Convert bins to R values, but if two bins are closer than 0.5 cm, pick the one with the largest bin content + for(int i=0; i<(int)peakBins.size(); i++) + { + if(i<(int)peakBins.size()-1 && hPeaks->GetBinCenter(peakBins[i+1]) - hPeaks->GetBinCenter(peakBins[i]) < 0.5) + { + peakVals.push_back((hPeaks->GetBinContent(peakBins[i]) > hPeaks->GetBinContent(peakBins[i+1]) ? hPeaks->GetBinCenter(peakBins[i]) : hPeaks->GetBinCenter(peakBins[i+1]))); + i++; + } + else + { + peakVals.push_back(hPeaks->GetBinCenter(peakBins[i])); + } + } + + std::vector mu; + std::vector sig; + + //fit each peak with a gaussian to get mean and sigma + TF1 *f1 = new TF1("f1","gaus(0)",26,80); + for(int i=0; i<(int)peakVals.size(); i++) + { + f1->SetParameters(hPeaks->GetBinContent(hPeaks->FindBin(peakVals[i])),peakVals[i],0.2); + if(i == 0) hPeaks->Fit(f1,"Q","",peakVals[i]-0.5,(peakVals[i]+peakVals[i+1])/2); + else if (i<(int)peakVals.size()-1) hPeaks->Fit(f1,"Q","",(peakVals[i-1]+peakVals[i])/2,(peakVals[i]+peakVals[i+1])/2); + else hPeaks->Fit(f1,"Q","",(peakVals[i-1]+peakVals[i])/2,peakVals[i]+1); + mu.push_back(f1->GetParameter(1)); + sig.push_back(f1->GetParameter(2)); + } + + //for each point in histogram, identify if within 3 sigma from mean of any of the peaks + //if not within 3 sigma from any of them, add to list of points to skip + for(int i=0; iGetY()[i]; + if(RVal_gr > mu[j] - 3*sig[j] && RVal_gr < mu[j] + 3*sig[j]) + { + good = true; + break; + } + } + if(!good) + { + pointsToSkip[s].push_back(i); + } + } + } + } + for (int s = 0; s < 2; s++) { - bool firstGoodR = false; + int N = gr_dR[s]->GetN(); + std::vector dataX(N), dataY(N); + double minR = 99.0; + double maxR = 0.0; + + if(m_skipOutliers) + { + int N_toInterp = (int)gr_dR_toInterp[s]->GetN(); + for(int i=N_toInterp-1; i>=0; i--) + { + for(int j=0; j<(int)pointsToSkip[s].size(); j++) + { + if(i == pointsToSkip[s][j]) + { + gr_dR_toInterp[s]->RemovePoint(i); + gr_dPhi_toInterp[s]->RemovePoint(i); + gr_points[s]->RemovePoint(i); + break; + } + } + } + } + + for(int k=0; kGetY()[k]; + + dataX[k] = RVal*cos(gr_dR[s]->GetX()[k]); + dataY[k] = RVal*sin(gr_dR[s]->GetX()[k]); + + if(RVal < minR) minR = RVal; + if(RVal > maxR) maxR = RVal; + } + + //bool firstGoodR = false; for (int j = 1; j <= m_dcc_out_aggregated->m_hDRint[s]->GetNbinsY(); j++) { double RVal = m_dcc_out_aggregated->m_hDRint[s]->GetYaxis()->GetBinCenter(j); double Rlow = m_dcc_out_aggregated->m_hDRint[s]->GetYaxis()->GetBinLowEdge(j); double Rhigh = m_dcc_out_aggregated->m_hDRint[s]->GetYaxis()->GetBinLowEdge(j + 1); + + if(Rhigh < minR || Rlow > maxR) continue; + /* if (!firstGoodR) { for (int p = 0; p < gr_dR[s]->GetN(); p++) @@ -2448,14 +2595,76 @@ int TpcCentralMembraneMatching::End(PHCompositeNode* /*topNode*/) } continue; } + */ for (int i = 2; i <= m_dcc_out_aggregated->m_hDRint[s]->GetNbinsX() - 1; i++) { double phiVal = m_dcc_out_aggregated->m_hDRint[s]->GetXaxis()->GetBinCenter(i); - m_dcc_out_aggregated->m_hDRint[s]->SetBinContent(i, j, gr_dR[s]->Interpolate(phiVal, RVal)); - m_dcc_out_aggregated->m_hDPint[s]->SetBinContent(i, j, RVal * gr_dPhi[s]->Interpolate(phiVal, RVal)); - } + if(m_manualInterp) + { + double num_dPhi = 0.0; + double num_dR = 0.0; + double den = 0.0; + double smoothing_parameter = 2.0; + + double hX = RVal*cos(phiVal); + double hY = RVal*sin(phiVal); + + for(int k=0; k 100.0) continue; + + if(distSq < 1e-9) + { + num_dPhi = gr_dPhi[s]->GetZ()[k]; + num_dR = gr_dR[s]->GetZ()[k]; + + den = 1.0; + + break; + } + + double weight = 1.0 / pow(distSq, smoothing_parameter / 2.0); + num_dPhi += weight * gr_dPhi[s]->GetZ()[k]; + num_dR += weight * gr_dR[s]->GetZ()[k]; + den += weight; + } + + if(den > 0.0) + { + m_dcc_out_aggregated->m_hDRint[s]->SetBinContent(i, j, num_dR / den); + m_dcc_out_aggregated->m_hDPint[s]->SetBinContent(i, j, RVal*(num_dPhi / den)); + } + } + else + { + m_dcc_out_aggregated->m_hDRint[s]->SetBinContent(i, j, gr_dR_toInterp[s]->Interpolate(phiVal,RVal)); + m_dcc_out_aggregated->m_hDPint[s]->SetBinContent(i, j, RVal*gr_dPhi_toInterp[s]->Interpolate(phiVal,RVal)); + } + } } } @@ -2480,6 +2689,9 @@ int TpcCentralMembraneMatching::End(PHCompositeNode* /*topNode*/) gr_points[i]->Write(std::format("gr_points_{}z", (i == 1 ? "pos" : "neg")).c_str()); gr_dR[i]->Write(std::format("gr_dr_{}z", (i == 1 ? "pos" : "neg")).c_str()); gr_dPhi[i]->Write(std::format("gr_dPhi_{}z", (i == 1 ? "pos" : "neg")).c_str()); + + gr_dR_toInterp[i]->Write(std::format("gr_dr_toInterp_{}z", (i == 1 ? "pos" : "neg")).c_str()); + gr_dPhi_toInterp[i]->Write(std::format("gr_dPhi_toInterp_{}z", (i == 1 ? "pos" : "neg")).c_str()); } } diff --git a/offline/packages/tpccalib/TpcCentralMembraneMatching.h b/offline/packages/tpccalib/TpcCentralMembraneMatching.h index f55bfe3a0e..2c2bce46b8 100644 --- a/offline/packages/tpccalib/TpcCentralMembraneMatching.h +++ b/offline/packages/tpccalib/TpcCentralMembraneMatching.h @@ -103,6 +103,16 @@ class TpcCentralMembraneMatching : public SubsysReco m_totalDistMode = totalDistMode; } + void set_skipOutliers(bool skipOutliers) + { + m_skipOutliers = skipOutliers; + } + + void set_manualInterp(bool manualInterp) + { + m_manualInterp = manualInterp; + } + void set_event_sequence(int seq) { m_event_sequence = seq; @@ -281,6 +291,9 @@ class TpcCentralMembraneMatching : public SubsysReco TGraph2D *gr_dPhi[2]{nullptr, nullptr}; TGraph *gr_points[2]{nullptr, nullptr}; + TGraph2D *gr_dR_toInterp[2]{nullptr, nullptr}; + TGraph2D *gr_dPhi_toInterp[2]{nullptr, nullptr}; + /// phi cut for matching clusters to pad /** TODO: this will need to be adjusted to match beam-induced time averaged distortions */ double m_phi_cut{0.025}; @@ -387,6 +400,8 @@ class TpcCentralMembraneMatching : public SubsysReco bool m_fieldOn{true}; bool m_doFancy{false}; bool m_doHadd{false}; + bool m_skipOutliers{false}; + bool m_manualInterp{false}; std::vector m_reco_RPeaks[2]; double m_m[2]{}; diff --git a/offline/packages/tpccalib/TpcLaminationFitting.cc b/offline/packages/tpccalib/TpcLaminationFitting.cc index ee23e9d0db..acf2604125 100644 --- a/offline/packages/tpccalib/TpcLaminationFitting.cc +++ b/offline/packages/tpccalib/TpcLaminationFitting.cc @@ -33,6 +33,10 @@ #include #include +#include +#include + + #include #include #include @@ -61,6 +65,8 @@ int TpcLaminationFitting::InitRun(PHCompositeNode *topNode) m_hPetal[s] = new TH2D((boost::format("hPetal_%s") %(s == 1 ? "North" : "South")).str().c_str(), (boost::format("TPC %s;#phi;R [cm]") %(s == 1 ? "North" : "South")).str().c_str(), 500, m_phiModMin[s], m_phiModMax[s], 500, 30, 80); m_parameterScan[s] = new TH2D((boost::format("parameterScan_%s") %(s == 1 ? "North" : "South")).str().c_str(), (boost::format("TPC %s Lamination Parameter Scan;m;B") %(s == 1 ? "North" : "South")).str().c_str(), 41, -0.0205, 0.0205, 49, -3.0625, 3.0625); + //m_parameterScan[s] = new TH2D((boost::format("parameterScan_%s") %(s == 1 ? "North" : "South")).str().c_str(), (boost::format("TPC %s Lamination Parameter Scan;m;B") %(s == 1 ? "North" : "South")).str().c_str(), 101, -0.101, 0.101, 101, -10.1, 10.1); + //m_parameterScan[s] = new TH2D((boost::format("parameterScan_%s") %(s == 1 ? "North" : "South")).str().c_str(), (boost::format("TPC %s Lamination Parameter Scan;A (asymptote);C (decay constant)") %(s == 1 ? "North" : "South")).str().c_str(), 101, -1.005, 0.005, 101, -0.0025, 0.5025); for (int l = 0; l < 18; l++) { @@ -329,6 +335,7 @@ int TpcLaminationFitting::GetNodes(PHCompositeNode *topNode) m_laminationTree->Branch("C_err",&m_C_err); m_laminationTree->Branch("distanceToFit",&m_dist); m_laminationTree->Branch("nBinsFit",&m_nBins); + m_laminationTree->Branch("RMSE",&m_rmse); return Fun4AllReturnCodes::EVENT_OK; @@ -632,6 +639,9 @@ int TpcLaminationFitting::fitLaminations() int nBinsUsed = 0; int nBinsUsed_R_lt_45 = 0; + double wc = 0.0; + double c = 0.0; + for (int i = 1; i <= m_hLamination[l][s]->GetNbinsX(); i++) { double R = m_hLamination[l][s]->GetXaxis()->GetBinCenter(i); @@ -663,10 +673,25 @@ int TpcLaminationFitting::fitLaminations() break; } } + for(int j=0; j<= nBinAvg; j++) + { + if(m_hLamination[l][s]->GetBinContent(i,funcBin + j) > 0) + { + wc += m_hLamination[l][s]->GetBinContent(i,funcBin + j) * pow(j,2); + c += m_hLamination[l][s]->GetBinContent(i,funcBin + j); + } + if(j != 0 && m_hLamination[l][s]->GetBinContent(i,funcBin - j) > 0) + { + wc += m_hLamination[l][s]->GetBinContent(i,funcBin - j) * pow(j,2); + c += m_hLamination[l][s]->GetBinContent(i,funcBin - j); + } + } } m_distanceToFit[l][s] = distToFunc / nBinsUsed; m_nBinsFit[l][s] = nBinsUsed; + if(c>0) m_fitRMSE[l][s] = sqrt(wc / c); + else m_fitRMSE[l][s] = -999; if (nBinsUsed < 10 || distToFunc / nBinsUsed > 1.0 || nBinsUsed_R_lt_45 < 5) { m_laminationGoodFit[l][s] = false; @@ -800,14 +825,16 @@ int TpcLaminationFitting::doGlobalRMatching(int side) std::vector distortedPhi; TF1 *tmpLamFit = (TF1*)m_fLamination[0][side]->Clone(); + double meanB = 0.0; + if(m_fieldOff) { tmpLamFit->SetParameters(0.0, 0.0); + meanB = -999.99; } else { double meanA = 0.0; - double meanB = 0.0; double meanC = 0.0; double meanOffset = 0.0; int nGoodFits = 0; @@ -854,16 +881,21 @@ int TpcLaminationFitting::doGlobalRMatching(int side) double maxSum = 0.0; double best_m = 0.0; double best_b = 0.0; - int mStep = 0; - int bStep = 0; - for(double m = -0.02; m<=0.02; m+=0.001) + //int mStep = 0; + //int bStep = 0; + //for(double m = -0.02; m<=0.02; m+=0.001) + for(int xbin=1; xbin<=m_parameterScan[side]->GetNbinsX(); xbin++) { - for(double b=-3.0; b<=3.0; b+=0.125) + double m = m_parameterScan[side]->GetXaxis()->GetBinCenter(xbin); + //for(double b=-3.0; b<=3.0; b+=0.125) + for(int ybin=1; ybin<=m_parameterScan[side]->GetNbinsY(); ybin++) { + double b = m_parameterScan[side]->GetYaxis()->GetBinCenter(ybin); double sum = 0.0; for(int i=0; i<(int)m_truthR[side].size(); i++) { double distortedTruthR = (m_truthR[side][i] + b)/(1.0 - m); + //double distortedTruthR = boost::math::lambert_w0(-m*b*exp(meanB-m_truthR[side][i]-m))/b + m_truthR[side][i] + m; int binR = m_hPetal[side]->GetYaxis()->FindBin(distortedTruthR); int binPhi = m_hPetal[side]->GetXaxis()->FindBin(distortedPhi[i]); for(int j=-2; j<=2; j++) @@ -885,7 +917,7 @@ int TpcLaminationFitting::doGlobalRMatching(int side) } } } - std::cout << "working on side " << side << " m step " << mStep << " b step " << bStep << " with m = " << m << " and b = " << b << " with sum = " << sum << std::endl; + std::cout << "working on side " << side << " m step " << xbin-1 << " b step " << ybin-1 << " with m = " << m << " and b = " << b << " with sum = " << sum << std::endl; m_parameterScan[side]->Fill(m, b, sum); @@ -895,9 +927,9 @@ int TpcLaminationFitting::doGlobalRMatching(int side) best_m = m; best_b = b; } - bStep++; + //bStep++; } - mStep++; + //mStep++; } std::cout << "Best R distortion for side " << side << " is m = " << best_m << " and b = " << best_b << " with sum of " << maxSum << std::endl; @@ -1021,6 +1053,7 @@ int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) pars->AddText((boost::format("#phi_{offset}=%.3f#pm %.3f") %m_fLamination[l][s]->GetParameter(0) %m_fLamination[l][s]->GetParError(0)).str().c_str()); pars->AddText((boost::format("Distance to line=%.2f") %m_distanceToFit[l][s]).str().c_str()); pars->AddText((boost::format("Number of Bins used=%d") %m_nBinsFit[l][s]).str().c_str()); + pars->AddText((boost::format("WRMSE=%.2f") %m_fitRMSE[l][s]).str().c_str()); } else { @@ -1033,6 +1066,7 @@ int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) pars->AddText((boost::format("C=%.3f#pm %.3f") %m_fLamination[l][s]->GetParameter(2) %m_fLamination[l][s]->GetParError(2)).str().c_str()); pars->AddText((boost::format("Distance to line=%.2f") %m_distanceToFit[l][s]).str().c_str()); pars->AddText((boost::format("Number of Bins used=%d") %m_nBinsFit[l][s]).str().c_str()); + pars->AddText((boost::format("WRMSE=%.2f") %m_fitRMSE[l][s]).str().c_str()); } pars->Draw("same"); c1->SaveAs(m_QAFileName.c_str()); @@ -1135,6 +1169,7 @@ int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) } m_dist = m_distanceToFit[l][s]; m_nBins = m_nBinsFit[l][s]; + m_rmse = m_fitRMSE[l][s]; m_laminationTree->Fill(); } } diff --git a/offline/packages/tpccalib/TpcLaminationFitting.h b/offline/packages/tpccalib/TpcLaminationFitting.h index a44160ca02..44e8b56868 100644 --- a/offline/packages/tpccalib/TpcLaminationFitting.h +++ b/offline/packages/tpccalib/TpcLaminationFitting.h @@ -89,6 +89,8 @@ class TpcLaminationFitting : public SubsysReco bool m_laminationGoodFit[18][2]{{false}}; double m_distanceToFit[18][2]{{0.0}}; int m_nBinsFit[18][2]{{0}}; + double m_fitRMSE[18][2]{{0.0}}; + TH2 *m_hPetal[2]{nullptr}; TGraph *m_bestRMatch[2]{nullptr}; @@ -129,6 +131,7 @@ class TpcLaminationFitting : public SubsysReco double m_B_err{0}; double m_C_err{0}; double m_dist{0}; + double m_rmse{}; int m_nBins{0}; int m_phibins{80}; From 5acea88d0f9f20b2724c96a30a3a57bc4d2668b4 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Thu, 5 Feb 2026 12:33:46 -0500 Subject: [PATCH 174/393] fix merge seeds keys --- offline/packages/trackreco/PHSiliconSeedMerger.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/offline/packages/trackreco/PHSiliconSeedMerger.cc b/offline/packages/trackreco/PHSiliconSeedMerger.cc index cd9de3c95c..c49c522420 100644 --- a/offline/packages/trackreco/PHSiliconSeedMerger.cc +++ b/offline/packages/trackreco/PHSiliconSeedMerger.cc @@ -187,7 +187,7 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode* /*unused*/) { keysToKeep.insert(mvtx2Keys.begin(), mvtx2Keys.end()); } - matches.insert(std::make_pair(track1ID, mvtx1Keys)); + matches.insert(std::make_pair(track1ID, keysToKeep)); seedsToDelete.insert(track2ID); if (Verbosity() > 2) { @@ -201,7 +201,7 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode* /*unused*/) { keysToKeep.insert(mvtx1Keys.begin(), mvtx1Keys.end()); } - matches.insert(std::make_pair(track2ID, mvtx2Keys)); + matches.insert(std::make_pair(track2ID, keysToKeep)); seedsToDelete.insert(track1ID); if (Verbosity() > 2) { @@ -211,7 +211,9 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode* /*unused*/) } } } - + + if (m_mergeSeeds) + { for (const auto& [trackKey, mvtxKeys] : matches) { auto* track = m_siliconTracks->get(trackKey); @@ -233,7 +235,7 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode* /*unused*/) } } } - + } for (const auto& key : seedsToDelete) { if (Verbosity() > 2) From 756f1ffafab76a35c4c7a7d2f5a4e0af89a2576d Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Thu, 5 Feb 2026 12:34:46 -0500 Subject: [PATCH 175/393] clang-format --- .../packages/trackreco/PHSiliconSeedMerger.cc | 148 +++++++++--------- .../packages/trackreco/PHSiliconSeedMerger.h | 64 ++++---- 2 files changed, 104 insertions(+), 108 deletions(-) diff --git a/offline/packages/trackreco/PHSiliconSeedMerger.cc b/offline/packages/trackreco/PHSiliconSeedMerger.cc index c49c522420..c2e2d3e9b4 100644 --- a/offline/packages/trackreco/PHSiliconSeedMerger.cc +++ b/offline/packages/trackreco/PHSiliconSeedMerger.cc @@ -211,31 +211,31 @@ int PHSiliconSeedMerger::process_event(PHCompositeNode* /*unused*/) } } } - + if (m_mergeSeeds) { - for (const auto& [trackKey, mvtxKeys] : matches) - { - auto* track = m_siliconTracks->get(trackKey); - if (Verbosity() > 2) + for (const auto& [trackKey, mvtxKeys] : matches) { - std::cout << "original track: " << std::endl; - track->identify(); - } + auto* track = m_siliconTracks->get(trackKey); + if (Verbosity() > 2) + { + std::cout << "original track: " << std::endl; + track->identify(); + } - for (const auto& key : mvtxKeys) - { - if (track->find_cluster_key(key) == track->end_cluster_keys()) + for (const auto& key : mvtxKeys) { - track->insert_cluster_key(key); - if (Verbosity() > 2) + if (track->find_cluster_key(key) == track->end_cluster_keys()) { - std::cout << "adding " << key << std::endl; + track->insert_cluster_key(key); + if (Verbosity() > 2) + { + std::cout << "adding " << key << std::endl; + } } } } } - } for (const auto& key : seedsToDelete) { if (Verbosity() > 2) @@ -301,82 +301,80 @@ int PHSiliconSeedMerger::getNodes(PHCompositeNode* topNode) void PHSiliconSeedMerger::printRemainingDuplicates() { for (unsigned int track1ID = 0; - track1ID != m_siliconTracks->size(); - ++track1ID) + track1ID != m_siliconTracks->size(); + ++track1ID) + { + std::set mvtx1Keyscheck; + + TrackSeed* seed = m_siliconTracks->get(track1ID); + if (!seed) { - std::set mvtx1Keyscheck; + continue; + } + int strobe1 = -9999; + for (auto iter = seed->begin_cluster_keys(); + iter != seed->end_cluster_keys(); + ++iter) + { + mvtx1Keyscheck.insert(*iter); + if (TrkrDefs::getTrkrId(*iter) == TrkrDefs::mvtxId) + { + strobe1 = MvtxDefs::getStrobeId(*iter); + } + } - TrackSeed* seed = m_siliconTracks->get(track1ID); - if (!seed) + for (unsigned int track2ID = 0; + track2ID != m_siliconTracks->size(); + ++track2ID) + { + std::set mvtx2Keyscheck; + TrackSeed* seed2 = m_siliconTracks->get(track2ID); + if (!seed2) { continue; } - int strobe1 = -9999; - for (auto iter = seed->begin_cluster_keys(); - iter != seed->end_cluster_keys(); - ++iter) + int strobe2 = -9999; + for (auto iter2 = seed2->begin_cluster_keys(); + iter2 != seed2->end_cluster_keys(); + ++iter2) { - mvtx1Keyscheck.insert(*iter); - if( TrkrDefs::getTrkrId(*iter) == TrkrDefs::mvtxId) + mvtx2Keyscheck.insert(*iter2); + if (TrkrDefs::getTrkrId(*iter2) == TrkrDefs::mvtxId) { - strobe1 = MvtxDefs::getStrobeId(*iter); + strobe2 = MvtxDefs::getStrobeId(*iter2); } } - - - - for (unsigned int track2ID = 0; - track2ID != m_siliconTracks->size(); - ++track2ID) + std::vector intersectioncheck; + std::set_intersection(mvtx1Keyscheck.begin(), + mvtx1Keyscheck.end(), + mvtx2Keyscheck.begin(), + mvtx2Keyscheck.end(), + std::back_inserter(intersectioncheck)); + if (track1ID != track2ID) { - std::set mvtx2Keyscheck; - TrackSeed* seed2 = m_siliconTracks->get(track2ID); - if (!seed2) - { - continue; - } - int strobe2 = -9999; - for (auto iter2 = seed2->begin_cluster_keys(); - iter2 != seed2->end_cluster_keys(); - ++iter2) + if (intersectioncheck.size() == mvtx1Keyscheck.size() || intersectioncheck.size() == mvtx2Keyscheck.size()) { - mvtx2Keyscheck.insert(*iter2); - if (TrkrDefs::getTrkrId(*iter2) == TrkrDefs::mvtxId) + std::cout << "After merge, still have duplicate seeds: " + << " seed1 ID " << track1ID << " strobe " << strobe1 << " nkeys " << mvtx1Keyscheck.size() + << " seed2 ID " << track2ID << " strobe " << strobe2 << " nkeys " << mvtx2Keyscheck.size() + << " intersection size " << intersectioncheck.size() + << std::endl; + std::cout << "seed 1 keys " << std::endl; + std::cout << " "; + for (const auto& key : mvtx1Keyscheck) { - strobe2 = MvtxDefs::getStrobeId(*iter2); + std::cout << key << ", "; } - } - std::vector intersectioncheck; - std::set_intersection(mvtx1Keyscheck.begin(), - mvtx1Keyscheck.end(), - mvtx2Keyscheck.begin(), - mvtx2Keyscheck.end(), - std::back_inserter(intersectioncheck)); - if(track1ID != track2ID) - { - if(intersectioncheck.size() == mvtx1Keyscheck.size() || intersectioncheck.size() == mvtx2Keyscheck.size()) + std::cout << std::endl; + std::cout << "seed 2 keys " << std::endl; + std::cout << " "; + for (const auto& key : mvtx2Keyscheck) { - std::cout << "After merge, still have duplicate seeds: " - << " seed1 ID " << track1ID << " strobe " << strobe1 << " nkeys " << mvtx1Keyscheck.size() - << " seed2 ID " << track2ID << " strobe " << strobe2 << " nkeys " << mvtx2Keyscheck.size() - << " intersection size " << intersectioncheck.size() - << std::endl; - std::cout << "seed 1 keys " << std::endl; - std::cout << " "; - for (const auto& key : mvtx1Keyscheck) - { - std::cout << key << ", "; - } - std::cout << std::endl; - std::cout << "seed 2 keys " << std::endl; - std::cout << " "; - for (const auto& key : mvtx2Keyscheck) - { - std::cout << key << ", "; - } - std::cout << std::endl; + std::cout << key << ", "; } + std::cout << std::endl; } } } + } } \ No newline at end of file diff --git a/offline/packages/trackreco/PHSiliconSeedMerger.h b/offline/packages/trackreco/PHSiliconSeedMerger.h index d3d828d565..b07551977d 100644 --- a/offline/packages/trackreco/PHSiliconSeedMerger.h +++ b/offline/packages/trackreco/PHSiliconSeedMerger.h @@ -26,28 +26,28 @@ class PHSiliconSeedMerger : public SubsysReco int End(PHCompositeNode *topNode) override; /** - * Set the name of the track seed container to use when retrieving silicon tracks. - * - * @param name Name of the TrackSeedContainer node (defaults to "SiliconTrackSeedContainer"). - */ -void trackMapName(const std::string &name) { m_trackMapName = name; } + * Set the name of the track seed container to use when retrieving silicon tracks. + * + * @param name Name of the TrackSeedContainer node (defaults to "SiliconTrackSeedContainer"). + */ + void trackMapName(const std::string &name) { m_trackMapName = name; } /** - * Set the maximum number of overlapping clusters considered during seed merging. - * @param nclusters Maximum number of clusters that may overlap (overlap threshold). - */ -void clusterOverlap(const unsigned int nclusters) { m_clusterOverlap = nclusters; } + * Set the maximum number of overlapping clusters considered during seed merging. + * @param nclusters Maximum number of clusters that may overlap (overlap threshold). + */ + void clusterOverlap(const unsigned int nclusters) { m_clusterOverlap = nclusters; } /** - * @brief Allow merging searches to include the INTT detector. - * - * Configure the merger to include INTT clusters in subsequent processing by disabling the MVTX-only restriction. - */ -void searchIntt() { m_mvtxOnly = false; } + * @brief Allow merging searches to include the INTT detector. + * + * Configure the merger to include INTT clusters in subsequent processing by disabling the MVTX-only restriction. + */ + void searchIntt() { m_mvtxOnly = false; } /** - * Enable merging of silicon seed tracks during event processing. - * - * When enabled, the module will merge overlapping silicon seed tracks where applicable. - */ -void mergeSeeds() { m_mergeSeeds = true; } + * Enable merging of silicon seed tracks during event processing. + * + * When enabled, the module will merge overlapping silicon seed tracks where applicable. + */ + void mergeSeeds() { m_mergeSeeds = true; } private: int getNodes(PHCompositeNode *topNode); @@ -55,24 +55,22 @@ void mergeSeeds() { m_mergeSeeds = true; } TrackSeedContainer *m_siliconTracks{nullptr}; std::string m_trackMapName{"SiliconTrackSeedContainer"}; /** - * Minimum number of clusters that must be shared between two silicon track seeds - * for them to be considered overlapping. - * - * Defaults to 1. - */ + * Minimum number of clusters that must be shared between two silicon track seeds + * for them to be considered overlapping. + * + * Defaults to 1. + */ unsigned int m_clusterOverlap{1}; bool m_mergeSeeds{false}; /** - * Restrict seed processing to the MVTX detector only. - * - * When set to `true`, operations that iterate or merge silicon seed tracks - * will be limited to clusters originating from the MVTX vertex detector. - * When `false`, clusters from other silicon detectors are included. - */ -bool m_mvtxOnly{false}; + * Restrict seed processing to the MVTX detector only. + * + * When set to `true`, operations that iterate or merge silicon seed tracks + * will be limited to clusters originating from the MVTX vertex detector. + * When `false`, clusters from other silicon detectors are included. + */ + bool m_mvtxOnly{false}; }; #endif // PHSILICONSEEDMERGER_H - - From a0c4f0024bf1d9fc1f5e4874d3f99283fe073c03 Mon Sep 17 00:00:00 2001 From: Ishan Goel Date: Thu, 5 Feb 2026 13:36:26 -0500 Subject: [PATCH 176/393] Final Change (Hopefully) --- offline/packages/tpc/TpcClusterizer.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/offline/packages/tpc/TpcClusterizer.cc b/offline/packages/tpc/TpcClusterizer.cc index ef22dea7d0..24405c8df4 100644 --- a/offline/packages/tpc/TpcClusterizer.cc +++ b/offline/packages/tpc/TpcClusterizer.cc @@ -621,13 +621,13 @@ namespace if (left_pad >= 0 && left_pad >= my_data.phioffset && - deadset.count(TpcDefs::genHitKey(left_pad, 0))) + deadset.contains(TpcDefs::genHitKey(left_pad, 0))) { nedge++; } if (right_pad < (my_data.phibins + my_data.phioffset) && - deadset.count(TpcDefs::genHitKey(right_pad, 0))) + deadset.contains(TpcDefs::genHitKey(right_pad, 0))) { nedge++; } @@ -644,13 +644,13 @@ namespace if (left_pad >= 0 && left_pad >= my_data.phioffset && - hotset.count(TpcDefs::genHitKey(left_pad, 0))) + hotset.contains(TpcDefs::genHitKey(left_pad, 0))) { nedge++; } if (right_pad < (my_data.phibins + my_data.phioffset) && - hotset.count(TpcDefs::genHitKey(right_pad, 0))) + hotset.contains(TpcDefs::genHitKey(right_pad, 0))) { nedge++; } @@ -863,7 +863,7 @@ namespace { auto it = my_data->deadMap->find(tpcHitSetKey); if (it != my_data->deadMap->end() && - it->second.count(key)) + it->second.contains(key)) { return true; } @@ -873,7 +873,7 @@ namespace { auto it = my_data->hotMap->find(tpcHitSetKey); if (it != my_data->hotMap->end() && - it->second.count(key)) + it->second.contains(key)) { return true; } From 062f669b7a372955653d0c982d4c9e045c72eed7 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Thu, 5 Feb 2026 14:10:43 -0500 Subject: [PATCH 177/393] move OnCal to Fun4Cal --- calibrations/framework/fun4cal/CalReco.cc | 48 + calibrations/framework/fun4cal/CalReco.h | 59 + .../framework/fun4cal/Fun4CalDBCodes.h | 19 + .../framework/fun4cal/Fun4CalHistoBinDefs.h | 16 + .../framework/fun4cal/Fun4CalServer.cc | 2439 +++++++++++++++++ .../framework/fun4cal/Fun4CalServer.h | 140 + calibrations/framework/fun4cal/Makefile.am | 48 + calibrations/framework/fun4cal/autogen.sh | 8 + calibrations/framework/fun4cal/configure.ac | 16 + 9 files changed, 2793 insertions(+) create mode 100644 calibrations/framework/fun4cal/CalReco.cc create mode 100644 calibrations/framework/fun4cal/CalReco.h create mode 100644 calibrations/framework/fun4cal/Fun4CalDBCodes.h create mode 100644 calibrations/framework/fun4cal/Fun4CalHistoBinDefs.h create mode 100644 calibrations/framework/fun4cal/Fun4CalServer.cc create mode 100644 calibrations/framework/fun4cal/Fun4CalServer.h create mode 100644 calibrations/framework/fun4cal/Makefile.am create mode 100755 calibrations/framework/fun4cal/autogen.sh create mode 100644 calibrations/framework/fun4cal/configure.ac diff --git a/calibrations/framework/fun4cal/CalReco.cc b/calibrations/framework/fun4cal/CalReco.cc new file mode 100644 index 0000000000..46ad141654 --- /dev/null +++ b/calibrations/framework/fun4cal/CalReco.cc @@ -0,0 +1,48 @@ +#include "CalReco.h" + +#include // for SubsysReco + +#include // for PHWHERE + +#include + +CalReco::CalReco(const std::string &Name) + : SubsysReco(Name) +{ +} + +int CalReco::process_event(PHCompositeNode * /*topNode*/) +{ + std::cout << "process_event(PHCompositeNode *topNode) not implemented by daughter class: " << Name() << std::endl; + return -1; +} + +int CalReco::End(PHCompositeNode * /*topNode*/) +{ + std::cout << "EndOfAnalysis not implemented by subsystem!" << std::endl; + std::cout << "Use this signal for computing your calibrations and commit." << std::endl; + std::cout << "Dont do these operations at EndOfRun since subsystems may be feeded events from different runs." << std::endl; + std::cout << "The number of events is the real parameter here, not the runnumber." << std::endl; + return 0; +} + +void CalReco::AddComment(const std::string &adcom) +{ + if (m_Comment.empty()) + { + m_Comment = adcom; + } + else + { + m_Comment += ":"; + m_Comment += adcom; + } + return; +} + +int CalReco::CopyTables(const int /*FromRun*/, const int /*ToRun*/, const int /*commit*/) const +{ + std::cout << PHWHERE << " CopyTables not implemented" << std::endl + << "this calibrator cannot copy its own tables" << std::endl; + return -1; +} diff --git a/calibrations/framework/fun4cal/CalReco.h b/calibrations/framework/fun4cal/CalReco.h new file mode 100644 index 0000000000..e2ba725884 --- /dev/null +++ b/calibrations/framework/fun4cal/CalReco.h @@ -0,0 +1,59 @@ +#ifndef FUN4CAL_CALRECO_H +#define FUN4CAL_CALRECO_H + +#include +#include +#include +#include // for pair +#include + +class CalReco : public SubsysReco +{ + public: + ~CalReco() override = default; + + // These might be overwritten by everyone... + int process_event(PHCompositeNode *topNode) override; + int End(PHCompositeNode *topNode) override = 0; // Here you analyze and commit (if committing flag is set) + + // Thsse control committing to the database... + virtual void CommitToPdbCal(const int value) = 0; // Set the flag for whether EndOfAnalysis will commit or not + virtual int VerificationOK() const = 0; // Tell us whether the new calib is close enough to the old one + virtual int CommitedToPdbCalOK() const = 0; // Tell us whether committing was successful by re-reading the data + + // commit without verification, needed for bootstrap calib + // which is too different from previous calibs (e.g. begin of new Run) + virtual void CommitNoVerify(const int) { return; } + + // These default behaviors from SubsysReco base class + virtual void identify(std::ostream &out = std::cout) const { out << Name() << std::endl; } + virtual int BeginRun(const int) { return 0; } + int EndRun(const int) override { return 0; } + int Reset(PHCompositeNode * /*topNode*/) override { return 0; } + int ResetEvent(PHCompositeNode * /*topNode*/) override { return 0; } + virtual void DumpCalib() const { return; } + + unsigned int AllDone() const { return alldone; } + void AllDone(const int i) { alldone = i; } + void AddComment(const std::string &adcom); + const std::string &Comment() const { return m_Comment; } + int GetPdbCalTables(std::vector &vec) const + { + vec = pdbcaltables; + return 0; + } + virtual int CopyTables(const int FromRun, const int ToRun, const int commit) const; + virtual int CreateCalibration(const int /*runnumber*/, const std::string & /*what*/, std::string & /*comment*/, const int /*commit*/) { return -1; } + virtual std::vector GetLocalFileList() const { return localfilelist; } + + protected: + CalReco(const std::string &Name); // so noone can call it from outside + unsigned int alldone{0}; + std::string m_Comment; + std::vector pdbcaltables; + std::vector pdbcalclasses; + std::vector > bankids; + std::vector localfilelist; +}; + +#endif /* CALRECO_CALRECO_H */ diff --git a/calibrations/framework/fun4cal/Fun4CalDBCodes.h b/calibrations/framework/fun4cal/Fun4CalDBCodes.h new file mode 100644 index 0000000000..7964f6679c --- /dev/null +++ b/calibrations/framework/fun4cal/Fun4CalDBCodes.h @@ -0,0 +1,19 @@ +#ifndef FUN4CAL_FUN4CALDBCODES_H +#define FUN4CAL_FUN4CALDBCODES_H + +namespace Fun4CalDBCodes +{ + enum + { + INIT = -2, + STARTED = -1, + FAILED = 0, + SUCCESS = 1, + COPIEDPREVIOUS = 2, + COPIEDLATER = 3, + COVERED = 4, + SUBSYSTEM = 5 + }; +} + +#endif diff --git a/calibrations/framework/fun4cal/Fun4CalHistoBinDefs.h b/calibrations/framework/fun4cal/Fun4CalHistoBinDefs.h new file mode 100644 index 0000000000..36c62bd3ec --- /dev/null +++ b/calibrations/framework/fun4cal/Fun4CalHistoBinDefs.h @@ -0,0 +1,16 @@ +#ifndef FUN4CAL_FUN4CALHISTOBINDEFS_H +#define FUN4CAL_FUN4CALHISTOBINDEFS_H + +namespace Fun4CalHistoBinDefs +{ + enum + { + FIRSTRUNBIN = 1, + LASTRUNBIN, + BORTIMEBIN, + EORTIMEBIN, + LASTBINPLUSONE + }; +}; + +#endif /* FUN4CAL_FUN4CALHISTOBINDEFS_H */ diff --git a/calibrations/framework/fun4cal/Fun4CalServer.cc b/calibrations/framework/fun4cal/Fun4CalServer.cc new file mode 100644 index 0000000000..5f9ec55b05 --- /dev/null +++ b/calibrations/framework/fun4cal/Fun4CalServer.cc @@ -0,0 +1,2439 @@ +#include "Fun4CalServer.h" +#include "CalReco.h" +#include "Fun4CalDBCodes.h" +#include "Fun4CalHistoBinDefs.h" + +#include +#include +#include // for Fun4AllServer, Fun4AllServe... +#include +#include +#include // for SubsysReco + +#include +#include // for PHTimeStamp, operator<< +#include +#include + +#include + +#include // for Stat_t +#include // for TDirectoryAtomicAdapter +#include +#include +#include // for TNamed +#include +#include // for TString + +// odbc++ classes +#include +#include +#include +#include +#include +#include // for Statement +#include // for SQLException, Timestamp + +#include +#include +#include // for tolower +#include +#include // for strcmp +#include +#include // for reverse_iterator +#include +#include +#include +#include // for pair + +namespace +{ + const std::string cvstag = "OnCalv86"; + + odbc::Connection *DBconnection{nullptr}; +} // namespace + +Fun4CalServer *Fun4CalServer::instance() +{ + if (__instance) + { + Fun4CalServer *oncal = dynamic_cast(__instance); + return oncal; + } + __instance = new Fun4CalServer(); + Fun4CalServer *oncal = dynamic_cast(__instance); + return oncal; +} + +//--------------------------------------------------------------------- + +Fun4CalServer::Fun4CalServer(const std::string &name) + : Fun4AllServer(name) + , Fun4CalServerVars(new TH1D("Fun4CalServerVars", "Fun4CalServerVars", Fun4CalHistoBinDefs::LASTBINPLUSONE, -0.5, (int) (Fun4CalHistoBinDefs::LASTBINPLUSONE) -0.5)) +{ + beginTimeStamp.setTics(0); + endTimeStamp.setTics(0); + + Fun4AllServer::registerHisto(Fun4CalServerVars); + return; +} +//--------------------------------------------------------------------- + +Fun4CalServer::~Fun4CalServer() +{ + delete DBconnection; + return; +} +//--------------------------------------------------------------------- + +PHTimeStamp * +Fun4CalServer::GetEndValidityTS() +{ + if (endTimeStamp.getTics()) + { + PHTimeStamp *ts = new PHTimeStamp(endTimeStamp); + return ts; + } + + std::cout << PHWHERE << "Screwup - the end validity time is not set" << std::endl; + exit(1); +} +//--------------------------------------------------------------------- + +PHTimeStamp *Fun4CalServer::GetBeginValidityTS() +{ + if (beginTimeStamp.getTics()) + { + PHTimeStamp *ts = new PHTimeStamp(beginTimeStamp); + return ts; + } + + std::cout << PHWHERE << "Screwup - the begin validity time is not set" << std::endl; + exit(1); +} +//--------------------------------------------------------------------- + +void Fun4CalServer::dumpHistos() +{ + std::ostringstream filename; + std::string fileprefix = "./"; + + if (getenv("ONCAL_SAVEDIR")) + { + fileprefix = getenv("ONCAL_SAVEDIR"); + fileprefix += "/"; + } + + int compress = 3; + std::map >::const_iterator iter; + // std::map::const_iterator hiter; + TH1 *histo; + std::set::const_iterator siter; + for (iter = calibratorhistomap.begin(); iter != calibratorhistomap.end(); ++iter) + { + filename.str(""); + filename << fileprefix << "Run_" + << RunNumber() + << "_" << iter->first << ".root"; + TFile *hfile = new TFile(filename.str().c_str(), "RECREATE", + "Created by Online Calibrator", compress); + std::cout << "Fun4CalServer::dumpHistos() Output root file: " << filename.str() << std::endl; + for (siter = (iter->second).begin(); siter != (iter->second).end(); ++siter) + { + histo = dynamic_cast(getHisto(*siter)); + if (histo) + { + histo->Write(); + } + else + { + std::cout << PHWHERE << "Histogram " + << *siter << " not found, will not be saved in " + << filename.str() << std::endl; + } + } + hfile->Close(); + + delete hfile; + } + return; +} + +void Fun4CalServer::registerHisto(TH1 *h1d, CalReco *Calibrator, const int replace) +{ + if (Calibrator) + { + std::string calibratorname = Calibrator->Name(); + std::map >::iterator iter; + iter = calibratorhistomap.find(calibratorname); + if (iter != calibratorhistomap.end()) + { + (iter->second).insert(h1d->GetName()); + } + else + { + std::set newset; + newset.insert(h1d->GetName()); + newset.insert("Fun4CalServerVars"); + calibratorhistomap[calibratorname] = newset; + } + } + Fun4AllServer::registerHisto(h1d, replace); + return; +} + +void Fun4CalServer::unregisterHisto(const std::string &calibratorname) +{ + calibratorhistomap.erase(calibratorname); + return; +} + +int Fun4CalServer::process_event() +{ + Fun4AllServer::process_event(); + int i = 0; + nEvents++; + if ((nEvents % eventcheckfrequency) == 0) // check every 1000 events + { + std::cout << nEvents << " events, testing" << std::endl; + unsigned int j = 0; + unsigned int ical = 0; + std::vector >::const_iterator iter; + for (iter = Subsystems.begin(); iter != Subsystems.end(); ++iter) + { + CalReco *oncal = dynamic_cast(iter->first); + if (oncal) + { + ical++; + std::cout << "Name: " << oncal->Name() + << " is " << oncal->AllDone() << std::endl; + j += oncal->AllDone(); + } + } + if (j == ical) + { + std::cout << "Everyone is done after " + << nEvents << " Events" << std::endl; + i = 1; + } + } + return i; +} + +int Fun4CalServer::BeginRun(const int runno) +{ + if (runno <= 0) + { + std::cout << PHWHERE << "Invalid Run Number: " << runno << std::endl; + exit(1); + } + FillRunListFromFileList(); + recoConsts *rc = recoConsts::instance(); + // we stick to the first runnumber, but after inheriting from + // Fun4All we get a EndRun/BeginRun when the run number changes + // so we have to catch this here + if (RunNumber() != 0) + { + rc->set_IntFlag("RUNNUMBER", RunNumber()); // set rc flag back to previous run + analysed_runs.push_back(runno); + return 0; + } + RunNumber(runno); + std::vector >::iterator iter; + // copy the subsys reco pointers to another set for + // easier search (we only need the pointers to find + // the subsystems with special timestamp/runnumber needs + std::set NeedOtherTimeStamp; + std::map >::const_iterator miter; + std::set::const_iterator siter; + for (miter = requiredCalibrators.begin(); + miter != requiredCalibrators.end(); ++miter) + { + for (siter = miter->second.begin(); siter != miter->second.end(); ++siter) + { + NeedOtherTimeStamp.insert(*siter); + } + } + + int iret; + int i = 0; + int oncalrun = runno; + int fun4allrun = runno; + + RunToTime *runTime = RunToTime::instance(); + PHTimeStamp *ts = runTime->getBeginTime(fun4allrun); + PHTimeStamp OnCalBORTimeStamp = *ts; + PHTimeStamp Fun4AllBORTimeStamp(OnCalBORTimeStamp); + delete ts; + if (!requiredCalibrators.empty()) + { + fun4allrun = FindClosestCalibratedRun(runno); + ts = runTime->getBeginTime(fun4allrun); + Fun4AllBORTimeStamp = *ts; + delete ts; + } + + // we have to do the same TDirectory games as in the Init methods + // save the current dir, cd to the subsystem name dir (which was + // created in init) call the InitRun of the module and cd back + + gROOT->cd(default_Tdirectory.c_str()); + std::string currdir = gDirectory->GetPath(); + std::set droplist; + for (iter = Subsystems.begin(); iter != Subsystems.end(); ++iter) + { + std::ostringstream newdirname; + newdirname << (*iter).second->getName() << "/" << (*iter).first->Name(); + if (!gROOT->cd(newdirname.str().c_str())) + { + std::cout << PHWHERE << "Unexpected TDirectory Problem cd'ing to " + << (*iter).second->getName() + << " - send e-mail to off-l with your macro" << std::endl; + exit(1); + } + CalReco *oncal = dynamic_cast((*iter).first); + if (oncal) + { + std::string table = "CalReco"; + table += (*iter).first->Name(); + check_create_subsystable(table); + insertRunNumInDB(table, runNum); + std::string calibname = (*iter).first->Name(); + add_calibrator_to_statustable(calibname); + std::set::const_iterator runiter; + int calibstatus = GetCalibStatus(calibname, runNum); + if (calibstatus > 0 && testmode == 0) + { + std::cout << calibname << " already ran for run " << runNum << std::endl; + droplist.insert(calibname); + unregisterSubsystem(oncal); + unregisterHisto(calibname); + } + else + { + std::ostringstream stringarg; + stringarg << Fun4CalDBCodes::STARTED; + for (runiter = runlist.begin(); runiter != runlist.end(); ++runiter) + { + updateDB(successTable, calibname, stringarg.str(), *runiter); + } + } + } + if (NeedOtherTimeStamp.contains((*iter).first)) + { + std::cout << "changing timestamp for " << (*iter).first->Name() << std::endl; + rc->set_IntFlag("RUNNUMBER", fun4allrun); + // rc->set_TimeStamp(Fun4AllBORTimeStamp); + } + else + { + rc->set_IntFlag("RUNNUMBER", oncalrun); + // rc->set_TimeStamp(CalRecoBORTimeStamp); + } + if (!droplist.contains((*iter).first->Name())) + { + iret = (*iter).first->InitRun(TopNode); + if (iret == Fun4AllReturnCodes::ABORTRUN) + { + std::cout << PHWHERE << "Module " << (*iter).first->Name() << " issued Abort Run, exiting" << std::endl; + exit(-1); + } + i += iret; + } + } + gROOT->cd(currdir.c_str()); + + rc->set_IntFlag("RUNNUMBER", oncalrun); + // rc->set_TimeStamp(CalRecoBORTimeStamp); + if (Fun4CalServerVars->GetBinContent(Fun4CalHistoBinDefs::FIRSTRUNBIN) == 0) + { + Fun4CalServerVars->SetBinContent(Fun4CalHistoBinDefs::FIRSTRUNBIN, runno); + Fun4CalServerVars->SetBinContent(Fun4CalHistoBinDefs::BORTIMEBIN, (Stat_t) OnCalBORTimeStamp.getTics()); + } + Fun4CalServerVars->SetBinContent(Fun4CalHistoBinDefs::LASTRUNBIN, (Stat_t) runno); + ts = runTime->getEndTime(runno); + if (ts) + { + Fun4CalServerVars->SetBinContent(Fun4CalHistoBinDefs::EORTIMEBIN, (Stat_t) ts->getTics()); + delete ts; + } + + // disconnect from DB to save resources on DB machine + // PdbCal leaves the DB connection open (PdbCal will reconnect without + // problem if neccessary) + DisconnectDB(); + // finally drop calibrators which have run already from module list + unregisterSubsystemsNow(); + return i; +} + +int Fun4CalServer::End() +{ + if (nEvents == 0) + { + std::cout << "No Events read, you probably gave me an empty filelist" << std::endl; + return -1; + } + int i = 0; + std::vector >::iterator iter; + gROOT->cd(default_Tdirectory.c_str()); + std::string currdir = gDirectory->GetPath(); + + for (iter = Subsystems.begin(); iter != Subsystems.end(); ++iter) + { + std::ostringstream newdirname; + newdirname << (*iter).second->getName() << "/" << (*iter).first->Name(); + if (!gROOT->cd(newdirname.str().c_str())) + { + std::cout << PHWHERE << "Unexpected TDirectory Problem cd'ing to " + << (*iter).second->getName() + << " - send e-mail to off-l with your macro" << std::endl; + exit(1); + } + else + { + if (Verbosity() > 2) + { + std::cout << "End: cded to " << newdirname.str().c_str() << std::endl; + } + } + i += (*iter).first->End((*iter).second); + } + + gROOT->cd(default_Tdirectory.c_str()); + currdir = gDirectory->GetPath(); + for (iter = Subsystems.begin(); iter != Subsystems.end(); ++iter) + { + CalReco *oncal = dynamic_cast((*iter).first); + if (!oncal) + { + continue; + } + std::ostringstream newdirname; + newdirname << (*iter).second->getName() << "/" << (*iter).first->Name(); + if (!gROOT->cd(newdirname.str().c_str())) + { + std::cout << PHWHERE << "Unexpected TDirectory Problem cd'ing to " + << (*iter).second->getName() + << " - send e-mail to off-l with your macro" << std::endl; + exit(1); + } + + std::string CalibratorName = oncal->Name(); + + int verificationstatus = oncal->VerificationOK(); + int databasecommitstatus = oncal->CommitedToPdbCalOK(); + + // report success database the status of the calibration + if (recordDB) + { + std::string table = "CalReco"; + table += CalibratorName; + + std::ostringstream stringarg; + if (databasecommitstatus == Fun4CalDBCodes::SUCCESS) + { + stringarg << Fun4CalDBCodes::COVERED; + } + else + { + stringarg << Fun4CalDBCodes::FAILED; + } + std::set::const_iterator runiter; + for (runiter = runlist.begin(); runiter != runlist.end(); ++runiter) + { + updateDB(successTable, CalibratorName, stringarg.str(), *runiter); + } + // update the first run which was used in the calibration + // with the real status + updateDB(successTable, CalibratorName, databasecommitstatus); + + stringarg.str(""); + stringarg << databasecommitstatus; + updateDB(table, "committed", stringarg.str(), RunNumber()); + + stringarg.str(""); + stringarg << verificationstatus; + updateDB(table, "verified", stringarg.str(), RunNumber()); + + odbc::Timestamp stp(time(nullptr)); + updateDB(table, "date", stp.toString(), RunNumber()); + updateDB(table, "comment", oncal->Comment(), RunNumber()); + time_t beginticks = beginTimeStamp.getTics(); + stringarg.str(""); + stringarg << beginticks; + updateDB(table, "startvaltime", stringarg.str(), RunNumber()); + stp.setTime(beginticks); + updateDB(table, "begintime", stp.toString(), RunNumber()); + time_t endticks = endTimeStamp.getTics(); + stringarg.str(""); + stringarg << endticks; + updateDB(table, "endvaltime", stringarg.str(), RunNumber()); + stp.setTime(endticks); + updateDB(table, "endtime", stp.toString(), RunNumber()); + + std::string filelist; + for (Fun4AllSyncManager *sync : SyncManagers) + { + for (Fun4AllInputManager *inmgr : sync->GetInputManagers()) + { + for (const std::string &infile : inmgr->GetFileOpenedList()) + { + filelist += (infile).substr(((infile).find_last_of('/') + 1), (infile).size()); + filelist += " "; // this needs to be stripped again for last entry + } + } + } + filelist.pop_back(); // strip empty space at end from loop + std::cout << "FileList: " << filelist << std::endl; + updateDB(table, "files", filelist, RunNumber()); + updateDB(table, "cvstag", cvstag, RunNumber()); + } + + std::cout << "SERVER SUMMARY: " << oncal->Name() << " " + << (verificationstatus == 1 ? "Verification: SUCCESS " : "Verification: FAILURE ") + << (databasecommitstatus == 1 ? "DB commit: SUCCESS " : "DB commit: FAILURE ") + << std::endl; + + printStamps(); + } + gROOT->cd(currdir.c_str()); + dumpHistos(); // save the histograms in files + return i; +} +//--------------------------------------------------------------------- + +void Fun4CalServer::Print(const std::string &what) const +{ + Fun4AllServer::Print(what); + if (what == "ALL" || what == "CALIBRATOR") + { + // loop over the map and print out the content + // (name and location in memory) + + std::cout << "--------------------------------------" << std::endl + << std::endl; + std::cout << "List of Calibrators in Fun4CalServer:" << std::endl; + + std::vector >::const_iterator miter; + for (miter = Subsystems.begin(); + miter != Subsystems.end(); ++miter) + { + CalReco *oncal = dynamic_cast((*miter).first); + if (oncal) + { + std::cout << oncal->Name() << std::endl; + } + } + std::cout << std::endl; + } + if (what == "ALL" || what == "REQUIRED") + { + // loop over the map and print out the content + // (name and location in memory) + + std::cout << "--------------------------------------" << std::endl + << std::endl; + std::cout << "List of required Calibrations in Fun4CalServer:" << std::endl; + + std::map >::const_iterator iter; + std::set::const_iterator siter; + for (iter = requiredCalibrators.begin(); + iter != requiredCalibrators.end(); ++iter) + { + std::cout << iter->first << " calibrations are needed by " << std::endl; + for (siter = iter->second.begin(); siter != iter->second.end(); ++siter) + { + std::cout << (*siter)->Name() << std::endl; + } + } + std::cout << std::endl; + } + if (what == "ALL" || what == "FILES") + { + std::cout << "--------------------------------------" << std::endl + << std::endl; + std::cout << "List of PRDF Files in Fun4CalServer:" << std::endl; + for (Fun4AllSyncManager *sync : SyncManagers) + { + for (Fun4AllInputManager *inmgr : sync->GetInputManagers()) + { + for (const std::string &infile : inmgr->GetFileList()) + { + std::cout << "File: " << infile << std::endl; + } + } + } + } + if (what == "ALL" || what == "RUNS") + { + std::cout << "--------------------------------------" << std::endl + << std::endl; + std::cout << "List of Run Numbers in Fun4CalServer:" << std::endl; + std::set::const_iterator liter; + for (liter = runlist.begin(); liter != runlist.end(); ++liter) + { + std::cout << "Run : " << *liter << std::endl; + } + } + + return; +} + +void Fun4CalServer::printStamps() +{ + std::cout << std::endl + << std::endl; + std::cout << "*******************************************" << std::endl; + std::cout << "* VALIDITY RANGE FOR THIS CALIBRATION *" << std::endl; + std::cout << "* *" << std::endl; + std::cout << "* Used Run : "; + std::cout << runNum << std::endl; + std::cout << std::endl; + std::cout << "* Begin Valid : "; + beginTimeStamp.print(); + std::cout << std::endl; + std::cout << "* End Valid : "; + endTimeStamp.print(); + std::cout << std::endl; + std::cout << "* *" << std::endl; + std::cout << "*******************************************" << std::endl; + std::cout << std::endl + << std::endl + << std::endl; +} + +//--------------------------------------------------------------------- + +void Fun4CalServer::RunNumber(const int runnum) +{ + runNum = runnum; + SetBorTime(runnum); + if (recordDB) + { + std::set::const_iterator runiter; + time_t beginrunticks; + time_t endrunticks; + std::ostringstream stringarg; + odbc::Timestamp stp; + for (runiter = runlist.begin(); runiter != runlist.end(); ++runiter) + { + insertRunNumInDB(successTable, *runiter); + GetRunTimeTicks(*runiter, beginrunticks, endrunticks); + stringarg.str(""); + stringarg << beginrunticks; + updateDB(successTable, "startvaltime", stringarg.str(), *runiter); + stp.setTime(beginrunticks); + updateDB(successTable, "beginrun", stp.toString(), *runiter); + stringarg.str(""); + stringarg << endrunticks; + updateDB(successTable, "endvaltime", stringarg.str(), *runiter); + stp.setTime(endrunticks); + updateDB(successTable, "endrun", stp.toString(), *runiter); + } + } + if (!runlist.empty()) + { + SetEorTime(*runlist.rbegin()); + } + return; +} + +//--------------------------------------------------------------------- + +bool Fun4CalServer::connectDB() +{ + if (DBconnection) + { + return true; + } + + bool failure = true; + int countdown = 10; + while (failure && countdown > 0) + { + failure = false; + try + { + DBconnection = + odbc::DriverManager::getConnection(database, "phnxrc", ""); + } + catch (odbc::SQLException &e) + { + std::cout << "Cannot connect to " << database.c_str() << std::endl; + std::cout << e.getMessage() << std::endl; + std::cout << "countdown: " << countdown << std::endl; + countdown--; + failure = true; + sleep(100); // try again in 100 secs + } + } + if (failure) + { + std::cout << "could not connect to DB after 10 tries in 1000 secs, giving up" << std::endl; + exit(-1); + } + std::cout << "connected to " << database.c_str() << " database." << std::endl; + return true; +} +//--------------------------------------------------------------------- + +int Fun4CalServer::DisconnectDB() +{ + delete DBconnection; + DBconnection = nullptr; + return 0; +} +//--------------------------------------------------------------------- + +bool Fun4CalServer::insertRunNumInDB(const std::string &DBtable, const int runno) +{ + if (findRunNumInDB(DBtable, runno)) + { + return true; + } + + std::cout << "new row will be created in DB for run " << runno << std::endl; + + odbc::Statement *statement = nullptr; + statement = DBconnection->createStatement(); + std::ostringstream cmd; + cmd << "INSERT INTO " + << DBtable + << " (runnumber) VALUES (" + << runno << ")"; + + if (Verbosity() == 1) + { + std::cout << "in function Fun4CalServer::insertRunNumInDB() ... "; + std::cout << "executing SQL statements ..." << std::endl; + std::cout << cmd.str() << std::endl; + } + + try + { + statement->executeUpdate(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << e.getMessage() << std::endl; + return false; + } + + return true; +} + +//--------------------------------------------------------------------- + +bool Fun4CalServer::findRunNumInDB(const std::string &DBtable, const int runno) +{ + if (!DBconnection) + { + connectDB(); + } + odbc::Statement *statement = nullptr; + odbc::ResultSet *rs = nullptr; + std::ostringstream cmd; + cmd << "SELECT runnumber FROM " + << DBtable + << " WHERE runnumber = " + << runno; + + statement = DBconnection->createStatement(); + + if (Verbosity() == 1) + { + std::cout << "in function Fun4CalServer::findRunNumInDB() "; + std::cout << "executing SQL statement ..." << std::endl + << cmd.str() << std::endl; + } + + try + { + rs = statement->executeQuery(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << PHWHERE << " exception caught: " << e.getMessage() << std::endl; + return false; + } + + int entry = 0; + if (rs->next()) + { + try + { + entry = rs->getInt("runnumber"); + } + catch (odbc::SQLException &e) + { + std::cout << PHWHERE << " exception caught: " << e.getMessage() << std::endl; + return false; + } + } + else + { + return false; + } + std::cout << "run number " << entry << " already exists in DB" << std::endl; + return true; +} + +bool Fun4CalServer::updateDBRunRange(const std::string &table, const std::string &column, const int entry, const int firstrun, const int lastrun) +{ + if (!DBconnection) + { + connectDB(); + } + + odbc::Statement *statement = nullptr; + + std::string command = "UPDATE "; + command += table; + command += " SET "; + command += column; + command += " = "; + command += std::to_string(entry); + command += " WHERE runnumber >= "; + command += std::to_string(firstrun); + command += " and runnumber <= "; + command += std::to_string(lastrun); + + if (Verbosity() == 1) + { + std::cout << "in function Fun4CalServer::updateDB() ... "; + std::cout << "executin SQL statement ... " << std::endl; + std::cout << command << std::endl; + } + statement = DBconnection->createStatement(); + + try + { + statement->executeUpdate(command); + } + catch (odbc::SQLException &e) + { + std::cout << e.getMessage() << std::endl; + return false; + } + + return true; +} + +//--------------------------------------------------------------------- + +bool Fun4CalServer::updateDB(const std::string &table, const std::string &column, int entry) +{ + if (!DBconnection) + { + connectDB(); + } + + odbc::Statement *statement = nullptr; + + TString command = "UPDATE "; + command += table; + command += " SET "; + command += column; + command += " = "; + command += entry; + command += " WHERE runnumber = "; + command += runNum; + + if (Verbosity() == 1) + { + std::cout << "in function Fun4CalServer::updateDB() ... "; + std::cout << "executin SQL statement ... " << std::endl; + std::cout << command.Data() << std::endl; + } + statement = DBconnection->createStatement(); + + try + { + statement->executeUpdate(command.Data()); + } + catch (odbc::SQLException &e) + { + std::cout << e.getMessage() << std::endl; + return false; + } + + return true; +} +//--------------------------------------------------------------------- + +bool Fun4CalServer::updateDB(const std::string &table, const std::string &column, bool entry) +{ + if (!DBconnection) + { + connectDB(); + } + odbc::Statement *statement = nullptr; + + TString command = "UPDATE "; + command += table; + command += " set "; + command += column; + command += " = '"; + command += static_cast(entry); + command += "' WHERE runnumber = "; + command += runNum; + + if (Verbosity() == 1) + { + std::cout << "in function Fun4CalServer::updateDB() ... "; + std::cout << "executin SQL statement ... " << std::endl; + std::cout << command.Data() << std::endl; + } + statement = DBconnection->createStatement(); + + try + { + statement->executeUpdate(command.Data()); + } + catch (odbc::SQLException &e) + { + std::cout << e.getMessage() << std::endl; + return false; + } + + return true; +} + +//--------------------------------------------------------------------- + +int Fun4CalServer::updateDB(const std::string &table, const std::string &column, + const time_t ticks) +{ + if (!DBconnection) + { + connectDB(); + } + odbc::Statement *statement = nullptr; + + std::ostringstream cmd; + statement = DBconnection->createStatement(); + cmd << "UPDATE " + << table + << " set " + << column + << " = " + << ticks + << " WHERE runnumber = " + << runNum; + + if (Verbosity() == 1) + { + std::cout << "in function Fun4CalServer::updateDB() ... "; + std::cout << "executin SQL statement ... " << std::endl; + std::cout << cmd.str() << std::endl; + } + + try + { + statement->executeUpdate(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << e.getMessage() << std::endl; + return -1; + } + return 0; +} +//--------------------------------------------------------------------- + +bool Fun4CalServer::updateDB(const std::string &table, const std::string &column, + const std::string &entry, const int runno, const bool append) +{ + if (!DBconnection) + { + connectDB(); + } + + odbc::Statement *statement = nullptr; + + statement = DBconnection->createStatement(); + + std::string comment; + std::ostringstream cmd; + if (append) + { + odbc::ResultSet *rs = nullptr; + std::ostringstream query; + query << "SELECT * FROM " + << table + << " WHERE runnumber = " + << runno; + + try + { + rs = statement->executeQuery(query.str()); + } + catch (odbc::SQLException &e) + { + std::cout << "in function Fun4CalServer::updateDB() ... "; + std::cout << "run number " << runno << "not found in DB" << std::endl; + std::cout << e.getMessage() << std::endl; + } + + rs->next(); + try + { + comment = rs->getString(column); + comment += " "; // add empty space between comments + } + catch (odbc::SQLException &e) + { + std::cout << "in function Fun4CalServer::updateDB() ... " << std::endl; + std::cout << "nothing to append." << std::endl; + std::cout << e.getMessage() << std::endl; + } + delete rs; + } + + comment += entry; + cmd << "UPDATE " + << table + << " set " + << column + << " = '" + << comment + << "' WHERE runnumber = " + << runno; + + if (Verbosity() == 1) + { + std::cout << "in function Fun4CalServer::updateDB() ... "; + std::cout << "executin SQL statement ... " << std::endl; + std::cout << cmd.str() << std::endl; + } + + try + { + statement->executeUpdate(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << e.getMessage() << std::endl; + return false; + } + delete statement; + return true; +} + +//--------------------------------------------------------------------- + +int Fun4CalServer::check_create_subsystable(const std::string &tablename) +{ + if (!connectDB()) + { + std::cout << "could not connect to " << database << std::endl; + return -1; + } + std::vector > calibrator_columns; + std::vector >::const_iterator coliter; + calibrator_columns.emplace_back("runnumber", "int NOT NULL"); + calibrator_columns.emplace_back("verified", "int default -2"); + calibrator_columns.emplace_back("committed", "int default -2"); + calibrator_columns.emplace_back("date", "timestamp(0) with time zone"); + calibrator_columns.emplace_back("comment", "text"); + calibrator_columns.emplace_back("files", "text"); + calibrator_columns.emplace_back("cvstag", "text"); + calibrator_columns.emplace_back("startvaltime", "bigint"); + calibrator_columns.emplace_back("endvaltime", "bigint"); + calibrator_columns.emplace_back("begintime", "timestamp(0) with time zone"); + calibrator_columns.emplace_back("endtime", "timestamp(0) with time zone"); + + odbc::Statement *stmt = DBconnection->createStatement(); + std::ostringstream cmd; + cmd << "SELECT * FROM " << tablename << " LIMIT 1" << std::ends; + odbc::ResultSet *rs = nullptr; + try + { + rs = stmt->executeQuery(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << "Table " << tablename << " does not exist, will create it" << std::endl; + // std::cout << "Message: " << e.getMessage() << std::endl; + } + if (!rs) + { + cmd.str(""); + cmd << "CREATE TABLE " + << tablename + << "("; + for (coliter = calibrator_columns.begin(); coliter != calibrator_columns.end(); ++coliter) + { + cmd << (*coliter).first << " " << (*coliter).second << ", "; + } + + cmd << "primary key(runnumber))"; + stmt->executeUpdate(cmd.str()); + } + else // check if the all columns exist + { + for (coliter = calibrator_columns.begin(); coliter != calibrator_columns.end(); ++coliter) + { + try + { + rs->findColumn((*coliter).first); + } + catch (odbc::SQLException &e) + { + const std::string &exceptionmessage = e.getMessage(); + if (exceptionmessage.find("not found in result set") != std::string::npos) + { + std::cout << "Column " << (*coliter).first << " does not exist in " + << tablename << ", creating it" << std::endl; + cmd.str(""); + cmd << "ALTER TABLE " + << tablename + << " ADD " + << (*coliter).first + << " " + << (*coliter).second; + try + { + odbc::Statement *stmtup = DBconnection->createStatement(); + stmtup->executeUpdate(cmd.str()); + } + catch (odbc::SQLException &e1) + { + std::cout << PHWHERE << " Exception caught: " << e1.getMessage() << std::endl; + } + } + } + } + delete rs; + } + return 0; +} + +int Fun4CalServer::add_calibrator_to_statustable(const std::string &calibratorname) +{ + if (!connectDB()) + { + std::cout << "could not connect to " << database << std::endl; + return -1; + } + if (check_calibrator_in_statustable(calibratorname) == 0) + { + return 0; + } + const std::string &calibname = calibratorname; + odbc::Statement *stmt = DBconnection->createStatement(); + std::ostringstream cmd; + cmd.str(""); + cmd << "ALTER TABLE " << successTable << " ADD COLUMN " + << calibname << " int"; + try + { + stmt->executeUpdate(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << "Message: " << e.getMessage() << std::endl; + std::cout << "cmd: " << cmd.str() << std::endl; + exit(1); + } + cmd.str(""); + cmd << "ALTER TABLE " << successTable << " ALTER COLUMN " + << calibname << " SET DEFAULT " << Fun4CalDBCodes::INIT; + try + { + stmt->executeUpdate(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << "Message: " << e.getMessage() << std::endl; + std::cout << "cmd: " << cmd.str() << std::endl; + exit(1); + } + cmd.str(""); + cmd << "UPDATE " << successTable << " SET " + << calibname << " = " << Fun4CalDBCodes::INIT; + try + { + stmt->executeUpdate(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << "Message: " << e.getMessage() << std::endl; + std::cout << "cmd: " << cmd.str() << std::endl; + exit(1); + } + + return 0; +} + +int Fun4CalServer::check_calibrator_in_statustable(const std::string &calibratorname) +{ + // replace this contraption by this sql command which returns 1 row if column exists + // select * from information_schema.columns where table_name = 'oncal_status' and column_name = 'svxstripdeadmapcal'; + if (!connectDB()) + { + std::cout << "could not connect to " << database << std::endl; + return -1; + } + std::string calibname = calibratorname; + odbc::Statement *stmt = DBconnection->createStatement(); + std::ostringstream cmd; + cmd << "SELECT * FROM " << successTable << " LIMIT 1" << std::ends; + odbc::ResultSet *rs = nullptr; + try + { + rs = stmt->executeQuery(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << "Message: " << e.getMessage() << std::endl; + std::cout << "Table " << successTable << " does not exist, your logic is off" << std::endl; + exit(1); + } + odbc::ResultSetMetaData *meta = rs->getMetaData(); + unsigned int nocolumn = rs->getMetaData()->getColumnCount(); + // column names are lower case only, so convert string to lowercase + // The bizarre cast here is needed for newer gccs + transform(calibname.begin(), calibname.end(), calibname.begin(), (int (*)(int)) tolower); + + for (unsigned int i = 1; i <= nocolumn; i++) + { + if (meta->getColumnName(i) == calibname) + { + if (Verbosity() > 0) + { + std::cout << calibname << " is in " << successTable << std::endl; + } + return 0; + } + } + // if we get here, the calibrator is not yet in the table + delete rs; + return -1; +} + +int Fun4CalServer::check_create_successtable(const std::string &tablename) +{ + if (!connectDB()) + { + std::cout << "could not connect to " << database << std::endl; + return -1; + } + odbc::Statement *stmt = DBconnection->createStatement(); + std::ostringstream cmd; + cmd << "SELECT runnumber FROM " << tablename << " LIMIT 1" << std::ends; + odbc::ResultSet *rs = nullptr; + try + { + rs = stmt->executeQuery(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << "Table " << tablename << " does not exist, will create it" << std::endl; + // std::cout << "Message: " << e.getMessage() << std::endl; + } + if (!rs) + { + cmd.str(""); + cmd << "CREATE TABLE " << tablename << "(runnumber int NOT NULL, " + << "startvaltime bigint, " + << "endvaltime bigint, " + << "beginrun timestamp(0) with time zone, " + << "endrun timestamp(0) with time zone, " + << "comment text, " + << "primary key(runnumber))"; + std::cout << cmd.str() << std::endl; + try + { + stmt->executeUpdate(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << "Error, Message: " << e.getMessage() << std::endl; + // std::cout << "Message: " << e.getMessage() << std::endl; + } + } + return 0; +} + +void Fun4CalServer::recordDataBase(const bool bookkeep) +{ + recordDB = bookkeep; + if (recordDB) + { + check_create_successtable(successTable); + } + return; +} + +void Fun4CalServer::BeginTimeStamp(const PHTimeStamp &TimeStp) +{ + beginTimeStamp = TimeStp; + std::cout << "Fun4CalServer::BeginTimeStamp: Setting BOR TimeStamp to " << beginTimeStamp << std::endl; +} + +void Fun4CalServer::EndTimeStamp(const PHTimeStamp &TimeStp) +{ + endTimeStamp = TimeStp; + std::cout << "Fun4CalServer::EndTimeStamp: Setting EOR TimeStamp to " << endTimeStamp << std::endl; +} + +PHTimeStamp * +Fun4CalServer::GetLastGoodRunTS(CalReco *calibrator, const int irun) +{ + PHTimeStamp *ts = nullptr; + if (!connectDB()) + { + std::cout << "could not connect to " << database << std::endl; + return ts; + } + odbc::Statement *stmt = DBconnection->createStatement(); + std::ostringstream cmd; + std::ostringstream subsystable; + subsystable << "oncal" << calibrator->Name(); + cmd << "SELECT runnumber FROM " << successTable << " where runnumber < " + << irun << " and " + << calibrator->Name() << " > 0 order by runnumber desc limit 1"; + odbc::ResultSet *rs = nullptr; + try + { + rs = stmt->executeQuery(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << "Table " << subsystable.str() << " does not exist" << std::endl; + return ts; + } + if (rs->next()) + { + RunToTime *rt = RunToTime::instance(); + int oldrun = rs->getInt("runnumber"); + ts = rt->getBeginTime(oldrun); + std::cout << "Getting previous good run, current run: " << irun + << ", previous good run: " << oldrun + << " began "; + ts->print(); + std::cout << std::endl; + } + else + { + std::cout << PHWHERE << " No previous good run found for run " << irun << std::endl; + } + delete rs; + return ts; +} + +int Fun4CalServer::SyncCalibTimeStampsToOnCal(const CalReco *calibrator, const int commit) +{ + std::vector caltab; + calibrator->GetPdbCalTables(caltab); + std::vector::const_iterator iter; + for (iter = caltab.begin(); iter != caltab.end(); ++iter) + { + std::cout << "dealing with table: " << *iter << std::endl; + SyncCalibTimeStampsToOnCal(calibrator, *iter, commit); + } + return 0; +} + +int Fun4CalServer::SyncCalibTimeStampsToOnCal(const CalReco *calibrator, const std::string &table, const int commit) +{ + std::string name = calibrator->Name(); + odbc::Connection *con = nullptr; + odbc::Connection *concalib = nullptr; + std::ostringstream cmd; + try + { + con = odbc::DriverManager::getConnection(database, "phnxrc", ""); + } + catch (odbc::SQLException &e) + { + std::cout << "Cannot connect to " << database.c_str() << std::endl; + std::cout << e.getMessage() << std::endl; + return -1; + } + try + { + concalib = odbc::DriverManager::getConnection("oncal", "phnxrc", ""); + } + catch (odbc::SQLException &e) + { + std::cout << "Cannot connect to " + << "oncal" << std::endl; + std::cout << e.getMessage() << std::endl; + return -1; + } + odbc::Statement *stmt = nullptr; + try + { + stmt = con->createStatement(); + } + catch (odbc::SQLException &e) + { + std::cout << "Cannot create statement" << std::endl; + std::cout << e.getMessage() << std::endl; + return -1; + } + + odbc::PreparedStatement *stmt1 = nullptr; + odbc::ResultSet *rs1 = nullptr; + try + { + cmd.str(""); + cmd << "SELECT * from " << table << " where startvaltime = ?"; + stmt1 = concalib->prepareStatement(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << "Cannot create statement" << std::endl; + std::cout << e.getMessage() << std::endl; + return -1; + } + + odbc::PreparedStatement *stmtupd = nullptr; + try + { + cmd.str(""); + cmd << "update " << table << " set endvaltime = ? where startvaltime = ?"; + stmtupd = concalib->prepareStatement(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << "Cannot create statement" << std::endl; + std::cout << e.getMessage() << std::endl; + return -1; + } + + cmd.str(""); + cmd << "select * from " + << successTable + << " where " + << name + << " > 0"; + // << " > 0 and runnumber < 150000"; + odbc::ResultSet *rs = nullptr; + try + { + rs = stmt->executeQuery(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << "Message: " << e.getMessage() << std::endl; + return -1; + } + while (rs->next()) + { + int run = rs->getInt("runnumber"); + int startticks = rs->getLong("startvaltime"); + int endticks = rs->getLong("endvaltime"); + // int status = rs->getInt(name); + // std::cout << "run: " << run + // << ", status: " << status + // << ", startticks: " << startticks + // << ", endticks: " << endticks << std::endl; + stmt1->setInt(1, startticks); + try + { + rs1 = stmt1->executeQuery(); + } + catch (odbc::SQLException &e) + { + std::cout << "Message: " << e.getMessage() << std::endl; + return -1; + } + int ionce = 0; + int isproblem = 0; + int calibendval = 0; + while (rs1->next()) + { + calibendval = rs1->getInt("endvaltime"); + if (endticks != rs1->getInt("endvaltime")) + { + if (!isproblem) + { + std::cout << "endvaltime problem with run " << run << std::endl; + std::cout << "endvaltime from oncal_status: " << endticks << std::endl; + std::cout << "startvaltime from oncal_status: " << startticks << std::endl; + std::cout << "endvaltime from calibrations DB: " << rs1->getInt("endvaltime") << std::endl; + if (endticks < rs1->getInt("endvaltime")) + { + std::cout << "ENDTICKS smaller CALIB" << std::endl; + // return -1; + } + } + isproblem = 1; + } + else + { + if (isproblem) + { + std::cout << "endvaltime changes, check run " << run << std::endl; + // return -1; + } + } + // std::cout << "starttime: " << rs1->getInt("startvaltime") << std::endl; + // std::cout << "endtime: " << rs1->getInt("endvaltime") << std::endl; + ionce++; + } + if (isproblem) + { + std::cout << "Adjusting run " << run << std::endl; + std::cout << "changing endvaltime from " << calibendval + << " to " << endticks << std::endl; + if (commit) + { + stmtupd->setInt(1, endticks); + stmtupd->setInt(2, startticks); + stmtupd->executeUpdate(); + } + } + if (!ionce) + { + std::cout << "Run " << run << " not found" << std::endl; + } + delete rs1; + } + delete rs; + delete con; + delete concalib; + return 0; +} + +int Fun4CalServer::SyncOncalTimeStampsToRunDB(const int commit) +{ + odbc::Connection *con = nullptr; + RunToTime *rt = RunToTime::instance(); + std::ostringstream cmd; + try + { + con = odbc::DriverManager::getConnection(database, "phnxrc", ""); + } + catch (odbc::SQLException &e) + { + std::cout << "Cannot connect to " << database.c_str() << std::endl; + std::cout << e.getMessage() << std::endl; + return -1; + } + odbc::Statement *stmt = nullptr; + try + { + stmt = con->createStatement(); + } + catch (odbc::SQLException &e) + { + std::cout << "Cannot create statement" << std::endl; + std::cout << e.getMessage() << std::endl; + return -1; + } + + odbc::PreparedStatement *stmtupd = nullptr; + try + { + cmd.str(""); + cmd << "UPDATE oncal_status set endvaltime = ? where runnumber = ?"; + stmtupd = con->prepareStatement(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << "Cannot create statement" << std::endl; + std::cout << e.getMessage() << std::endl; + return -1; + } + + cmd.str(""); + cmd << "select * from " + << successTable; //<< " where runnumber > 160000"; + odbc::ResultSet *rs = nullptr; + try + { + rs = stmt->executeQuery(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << "Message: " << e.getMessage() << std::endl; + return -1; + } + while (rs->next()) + { + int run = rs->getInt("runnumber"); + int startticks = rs->getLong("startvaltime"); + int endticks = rs->getLong("endvaltime"); + int rtstartticks = 0; + int rtendticks = 0; + PHTimeStamp *rtstart = rt->getBeginTime(run); + PHTimeStamp *rtend = rt->getEndTime(run); + if (rtstart) + { + rtstartticks = rtstart->getTics(); + delete rtstart; + } + if (rtend) + { + rtendticks = rtend->getTics(); + delete rtend; + } + if (rtstartticks != startticks) + { + std::cout << "Run " << run + << ": Start mismatch, oncal: " << startticks + << ", rt: " << rtstartticks << std::endl; + } + if (rtendticks != endticks) + { + // exclude starttime=endtime in runtotime (some crashed calibrations can do this) + // in this case the calibration adds 1 sec to starttime + if (rtstartticks != rtendticks) + { + std::cout << "Run " << run + << ": End mismatch, oncal: " << endticks + << ", rt: " << rtendticks << std::endl; + if (endticks > rtendticks) + { + std::cout << "BAD: endticks: " << endticks + << ", rtendticks: " << rtendticks + << std::endl; + return -1; + } + if (commit) + { + stmtupd->setLong(1, rtendticks); + stmtupd->setLong(2, run); + stmtupd->executeUpdate(); + } + } + else + { + if (startticks != endticks - 1) + { + std::cout << "Run " << run + << ": Start/End mismatch, Start: " << startticks + << ", End: " << endticks << std::endl; + endticks = startticks + 1; + if (commit) + { + stmtupd->setLong(1, endticks); + stmtupd->setLong(2, run); + stmtupd->executeUpdate(); + } + } + else + { + if (Verbosity() > 0) + { + std::cout << "run " << run << " was twiddled by OnCal" << std::endl; + } + } + } + } + // std::cout << "run: " << run + // << ", status: " << status + // << ", startticks: " << startticks + // << ", endticks: " << endticks << std::endl; + } + delete rs; + delete con; + return 0; +} + +int Fun4CalServer::CopyTables(const CalReco *calibrator, const int FromRun, const int ToRun, const int commit) +{ + int iret = calibrator->CopyTables(FromRun, ToRun, commit); + return iret; +} + +int Fun4CalServer::CreateCalibration(CalReco *calibrator, const int myrunnumber, const std::string &what, const int commit) +{ + int iret = -1; + runNum = myrunnumber; + SetBorTime(myrunnumber); + SetEorTime(myrunnumber); + if (!connectDB()) + { + std::cout << "could not connect to " << database << std::endl; + return -1; + } + add_calibrator_to_statustable(calibrator->Name()); + std::string table = "OnCal"; + table += calibrator->Name(); + check_create_subsystable(table); + odbc::Statement *stmt = DBconnection->createStatement(); + std::ostringstream cmd; + + cmd << "SELECT runnumber FROM " + << successTable << " where runnumber = " + << myrunnumber; + odbc::ResultSet *rs = nullptr; + try + { + rs = stmt->executeQuery(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << "Table " << successTable << " does not exist" << std::endl; + return -1; + } + if (!rs->next()) + { + insertRunNumInDB(successTable, myrunnumber); + } + delete rs; + cmd.str(""); + cmd << "SELECT runnumber FROM " + << successTable << " where runnumber = " + << myrunnumber << " and " + << calibrator->Name() << " <= 0"; + try + { + rs = stmt->executeQuery(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << PHWHERE << " Exception caught, Message: " + << e.getMessage() << std::endl; + return -1; + } + if (rs->next() || testmode) + { + std::string tablecomment = "Subsytem provided"; + iret = calibrator->CreateCalibration(runnumber, what, tablecomment, commit); + if (!iret) + { + std::cout << "Comment: " << tablecomment << std::endl; + std::cout << "updating oncal status tables for " << runnumber << std::endl; + if (commit) + { + CreateCalibrationUpdateStatus(calibrator, table, tablecomment, Fun4CalDBCodes::SUBSYSTEM); + } + } + else + { + std::cout << "Calibratior " << calibrator->Name() << " for run " << runnumber << " failed" << std::endl; + if (commit) + { + CreateCalibrationUpdateStatus(calibrator, table, tablecomment, Fun4CalDBCodes::FAILED); + } + } + } + else + { + std::cout << PHWHERE << " Run " << runnumber << " is already successfully calibrated for " + << calibrator->Name() << std::endl; + } + return iret; +} + +void Fun4CalServer::CreateCalibrationUpdateStatus(CalReco *calibrator, const std::string &table, const std::string &tablecomment, const int dbcode) +{ + updateDB(successTable, calibrator->Name(), dbcode); + insertRunNumInDB(table, RunNumber()); + updateDB(table, "comment", tablecomment, RunNumber(), true); + std::ostringstream stringarg; + stringarg.str(""); + stringarg << calibrator->CommitedToPdbCalOK(); + updateDB(table, "committed", stringarg.str(), RunNumber()); + stringarg.str(""); + stringarg << calibrator->VerificationOK(); + updateDB(table, "verified", stringarg.str(), RunNumber()); + odbc::Timestamp stp(time(nullptr)); + updateDB(table, "date", stp.toString(), RunNumber()); + time_t beginticks = beginTimeStamp.getTics(); + stringarg.str(""); + stringarg << beginticks; + updateDB(table, "startvaltime", stringarg.str(), RunNumber()); + stp.setTime(beginticks); + updateDB(table, "begintime", stp.toString(), RunNumber()); + time_t endticks = endTimeStamp.getTics(); + stringarg.str(""); + stringarg << endticks; + updateDB(table, "endvaltime", stringarg.str(), RunNumber()); + stp.setTime(endticks); + updateDB(table, "endtime", stp.toString(), RunNumber()); + updateDB(table, "cvstag", cvstag, RunNumber()); + std::vector flist = calibrator->GetLocalFileList(); + if (!flist.empty()) + { + std::string filelist; + for (const std::string &infile : flist) + { + filelist += infile; + filelist += " "; + } + filelist.pop_back(); // strip empty space at end from loop + std::cout << "FileList: " << filelist << std::endl; + updateDB(table, "files", filelist, RunNumber()); + } + return; +} + +int Fun4CalServer::ClosestGoodRun(CalReco *calibrator, const int irun, const int previous) +{ + RunToTime *rt = RunToTime::instance(); + PHTimeStamp *ts = rt->getBeginTime(irun); + if (!ts) + { + std::cout << PHWHERE << "Unknown Run " << irun << std::endl; + return -1; + } + int curstart = ts->getTics(); + delete ts; + ts = rt->getEndTime(irun); + int curend = curstart; + if (ts) + { + curend = ts->getTics(); + delete ts; + } + int closestrun = -1; + if (!connectDB()) + { + std::cout << "could not connect to " << database << std::endl; + return -1; + } + odbc::Statement *stmt = DBconnection->createStatement(); + std::ostringstream cmd; + + // look only for runs which were actually successfully calibrated (status = 1) + cmd << "SELECT runnumber,startvaltime,endvaltime FROM " + << successTable << " where runnumber < " + << irun << " and " + << calibrator->Name() << " = 1 order by runnumber desc limit 1"; + odbc::ResultSet *rs = nullptr; + try + { + rs = stmt->executeQuery(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << "Table " << successTable << " does not exist" << std::endl; + return -1; + } + int prevrun = -1; + unsigned int prevend = 0; + if (rs->next()) + { + prevrun = rs->getInt("runnumber"); + unsigned int prevstart = rs->getLong("startvaltime"); + prevend = rs->getLong("endvaltime"); + std::cout << "previous run: " << prevrun + << ", start: " << prevstart + << ", end: " << prevend + << std::endl; + } + else + { + if (Verbosity() > 0) + { + std::cout << PHWHERE << " No previous good run found for run " << irun << std::endl; + } + } + delete rs; + closestrun = prevrun; + if (previous == fetchrun::PREVIOUS) + { + if (Verbosity() > 0) + { + std::cout << "Closest previous run is " << closestrun << std::endl; + } + return closestrun; + } + cmd.str(""); + cmd << "SELECT runnumber,startvaltime,endvaltime FROM " + << successTable << " where runnumber > " + << irun << " and " + << calibrator->Name() << " = 1 order by runnumber asc limit 1"; + try + { + rs = stmt->executeQuery(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << "Table " << successTable << " does not exist" << std::endl; + return -1; + } + int nextrun = -1; + unsigned int nextstart = 0; + if (rs->next()) + { + nextrun = rs->getInt("runnumber"); + nextstart = rs->getLong("startvaltime"); + unsigned int nextend = rs->getLong("endvaltime"); + if (Verbosity() > 0) + { + std::cout << "next run: " << nextrun + << ", start: " << nextstart + << ", end: " << nextend + << std::endl; + } + } + else + { + if (Verbosity() > 0) + { + std::cout << PHWHERE << " No next good run found for run " << irun << std::endl; + } + } + delete rs; + int tdiffprev = curstart - prevend; + int tdiffnext; + if (nextstart > 0) + { + tdiffnext = nextstart - curend; + } + else + { + // just make it larger then previous run time diff + tdiffnext = tdiffprev + 1; + } + if (Verbosity() > 0) + { + std::cout << "diff prev: " << tdiffprev + << ", next: " << tdiffnext + << std::endl; + } + if (tdiffprev < tdiffnext) + { + closestrun = prevrun; + } + else + { + closestrun = nextrun; + } + if (Verbosity() > 0) + { + std::cout << "closest run: " << closestrun << std::endl; + } + return closestrun; +} + +int Fun4CalServer::OverwriteCalibration(CalReco *calibrator, const int runno, const int commit, const int FromRun) +{ + if (FromRun < 0) + { + return -1; + } + int iret = CopyTables(calibrator, FromRun, runno, commit); + return iret; +} + +int Fun4CalServer::FixMissingCalibration(CalReco *calibrator, const int runno, const int commit, const int fromrun) +{ + int iret = -1; + // find this run in oncal_status + if (!connectDB()) + { + std::cout << "could not connect to " << database << std::endl; + return -1; + } + runNum = runno; + odbc::Statement *stmt = DBconnection->createStatement(); + std::ostringstream cmd; + + cmd << "SELECT runnumber FROM " + << successTable << " where runnumber = " + << runno; + odbc::ResultSet *rs = nullptr; + try + { + rs = stmt->executeQuery(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << "Table " << successTable << " does not exist" << std::endl; + return -1; + } + if (!rs->next()) + { + insertRunNumInDB(successTable, runNum); + } + delete rs; + cmd.str(""); + cmd << "SELECT runnumber FROM " + << successTable << " where runnumber = " + << runno << " and " + << calibrator->Name() << " <= 0"; + try + { + rs = stmt->executeQuery(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << PHWHERE << " Exception caught, Message: " + << e.getMessage() << std::endl; + return -1; + } + if (rs->next()) + { + int FromRun; + if (fromrun > 0) + { + FromRun = fromrun; + } + else + { + FromRun = ClosestGoodRun(calibrator, runno); + if (FromRun < 0) + { + std::cout << "ClosestGoodRun returned bad runnumber: " << FromRun << std::endl; + return -1; + } + } + std::cout << "Going to copy calibration for run " << runno + << " from run " << FromRun << std::endl; + + iret = OverwriteCalibration(calibrator, runno, commit, FromRun); + if (!iret) + { + int newstatus = 0; + if (FromRun < runno) + { + newstatus = Fun4CalDBCodes::COPIEDPREVIOUS; + } + else + { + newstatus = Fun4CalDBCodes::COPIEDLATER; + } + std::string table = "OnCal"; + table += calibrator->Name(); + std::ostringstream comment; + comment << " CopiedRun(" << FromRun << ")"; + std::cout << "updating oncal status tables for " << runno << std::endl; + if (commit) + { + updateDB(successTable, calibrator->Name(), newstatus); + insertRunNumInDB(table, runNum); + updateDB(table, "comment", comment.str(), runNum, true); + updateDB(table, "committed", true); + } + } + } + else + { + std::cout << "Run " << runno + << " has a good calibrations, doing nothing" << std::endl; + } + delete rs; + return iret; +} + +int Fun4CalServer::SetBorTime(const int runno) +{ + // recoConsts *rc = recoConsts::instance(); + RunToTime *runTime = RunToTime::instance(); + + PHTimeStamp *BorTimeStp(runTime->getBeginTime(runno)); + if (!BorTimeStp) + { + std::cout << PHWHERE << "Cannot get begin time for run " << runno << std::endl; + std::cout << "Exiting" << std::endl; + exit(1); + } + BeginTimeStamp(*BorTimeStp); + + // enter begin run timestamp into rc flags + PHTimeStamp BeginRunTimeStamp(*BorTimeStp); + // rc->set_TimeStamp(BeginRunTimeStamp); + std::cout << "Fun4CalServer::SetBorTime from RunToTime was found for run : " << runno << " to "; + BeginRunTimeStamp.print(); + std::cout << std::endl; + + delete BorTimeStp; + return 0; +} + +int Fun4CalServer::SetEorTime(const int runno) +{ + // recoConsts *rc = recoConsts::instance(); + RunToTime *runTime = RunToTime::instance(); + + time_t eorticks = 0; + + time_t borticks = 0; //(rc->get_TimeStamp()).getTics(); + PHTimeStamp *EorTimeStp(runTime->getEndTime(runno)); + if (EorTimeStp) + { + eorticks = EorTimeStp->getTics(); + } + else + { + EorTimeStp = new PHTimeStamp(eorticks); + } + // if end of run timestamp missing or smaller-equal borstamp eor = bor+1 sec + if (eorticks <= borticks) + { + eorticks = borticks + 1; + EorTimeStp->setTics(eorticks); + } + EndTimeStamp(*EorTimeStp); + std::cout << "Fun4CalServer::SetEorTime: setting eor time to "; + EorTimeStp->print(); + std::cout << std::endl; + delete EorTimeStp; + return 0; +} + +int Fun4CalServer::GetRunTimeTicks(const int runno, time_t &borticks, time_t &eorticks) +{ + RunToTime *runTime = RunToTime::instance(); + PHTimeStamp *TimeStp(runTime->getBeginTime(runno)); + if (!TimeStp) + { + std::cout << PHWHERE << "Cannot get begin time for run " << runno << std::endl; + std::cout << "Exiting" << std::endl; + exit(1); + } + borticks = TimeStp->getTics(); + delete TimeStp; + TimeStp = runTime->getEndTime(runno); + if (TimeStp) + { + eorticks = TimeStp->getTics(); + delete TimeStp; + } + else + { + eorticks = 0; + } + // if end of run timestamp missing or smaller-equal borstamp eor = bor+1 sec + if (eorticks <= borticks) + { + eorticks = borticks + 1; + } + return 0; +} + +int Fun4CalServer::requiredCalibration(SubsysReco *reco, const std::string &calibratorname) +{ + std::map >::iterator iter; + if (check_calibrator_in_statustable(calibratorname)) + { + std::cout << PHWHERE << " the calibrator " << calibratorname << " is unknown to me" << std::endl; + return -1; + } + iter = requiredCalibrators.find(calibratorname); + if (iter != requiredCalibrators.end()) + { + iter->second.insert(reco); + } + else + { + std::set subsys; + subsys.insert(reco); + requiredCalibrators[calibratorname] = subsys; + } + return 0; +} + +int Fun4CalServer::FindClosestCalibratedRun(const int irun) +{ + RunToTime *rt = RunToTime::instance(); + PHTimeStamp *ts = rt->getBeginTime(irun); + if (!ts) + { + std::cout << PHWHERE << "Unknown Run " << irun << std::endl; + return -1; + } + if (requiredCalibrators.empty()) + { + std::cout << PHWHERE << "No required calibrations given" << std::endl; + return irun; + } + int curstart = ts->getTics(); + delete ts; + ts = rt->getEndTime(irun); + int curend = curstart; + if (ts) + { + curend = ts->getTics(); + delete ts; + } + int closestrun = -1; + if (!connectDB()) + { + std::cout << "could not connect to " << database << std::endl; + return -1; + } + odbc::Statement *stmt = DBconnection->createStatement(); + std::ostringstream cmd; + std::map >::const_iterator iter; + // look only for runs which were actually successfully calibrated (status = 1) + cmd << "SELECT runnumber,startvaltime,endvaltime FROM " + << successTable << " where runnumber <= " + << irun; + for (iter = requiredCalibrators.begin(); iter != requiredCalibrators.end(); ++iter) + { + cmd << " and " << iter->first << " > 0 "; + } + + cmd << " order by runnumber desc limit 1"; + odbc::ResultSet *rs = nullptr; + try + { + rs = stmt->executeQuery(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << "Table " << successTable << " does not exist" << std::endl; + return -1; + } + int prevrun = 0; + unsigned int prevend = 0; + if (rs->next()) + { + prevrun = rs->getInt("runnumber"); + unsigned int prevstart = rs->getLong("startvaltime"); + prevend = rs->getLong("endvaltime"); + if (prevrun != irun) + { + std::cout << "previous run: " << prevrun + << ", start: " << prevstart + << ", end: " << prevend + << std::endl; + } + } + else + { + std::cout << PHWHERE << " No previous good run found for run " << irun << std::endl; + } + delete rs; + // if the current run fullfills requirements return immediately + if (prevrun == irun) + { + std::cout << "closest run with required calibs is current run: " << irun << std::endl; + return irun; + } + cmd.str(""); + cmd << "SELECT runnumber,startvaltime,endvaltime FROM " + << successTable << " where runnumber > " + << irun; + for (iter = requiredCalibrators.begin(); iter != requiredCalibrators.end(); ++iter) + { + cmd << " and " << iter->first << " > 0 "; + } + + cmd << " order by runnumber asc limit 1"; + try + { + rs = stmt->executeQuery(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << "Table " << successTable << " does not exist" << std::endl; + return -1; + } + int nextrun = 0; + unsigned int nextstart = 0; + if (rs->next()) + { + nextrun = rs->getInt("runnumber"); + nextstart = rs->getLong("startvaltime"); + unsigned int nextend = rs->getLong("endvaltime"); + std::cout << "next run: " << nextrun + << ", start: " << nextstart + << ", end: " << nextend + << std::endl; + } + else + { + std::cout << PHWHERE << " No next good run found for run " << irun << std::endl; + } + delete rs; + int tdiffprev = curstart - prevend; + int tdiffnext; + if (nextstart > 0) + { + tdiffnext = nextstart - curend; + } + else + { + // just make it larger then previous run time diff + tdiffnext = tdiffprev + 1; + } + if (tdiffprev < tdiffnext) + { + closestrun = prevrun; + } + else + { + closestrun = nextrun; + } + std::cout << "closest run with required calibs: " << closestrun << std::endl; + return closestrun; +} + +int Fun4CalServer::FillRunListFromFileList() +{ + for (Fun4AllSyncManager *sync : SyncManagers) + { + for (Fun4AllInputManager *inmgr : sync->GetInputManagers()) + { + for (const std::string &infile : inmgr->GetFileList()) + { + std::pair runseg = Fun4AllUtils::GetRunSegment(infile); + runlist.insert(runseg.first); + } + } + } + return 0; +} + +int Fun4CalServer::AdjustRichTimeStampForMultipleRuns() +{ + int firstrun = *runlist.begin(); + int lastrun = *runlist.rbegin(); + time_t dummy; + time_t beginticks; + time_t endticks; + std::string table = "OnCalRichCal"; + check_create_subsystable(table); + GetRunTimeTicks(firstrun, beginticks, dummy); + GetRunTimeTicks(lastrun, dummy, endticks); + std::ostringstream stringarg; + stringarg << Fun4CalDBCodes::COVERED; + // std::set::const_iterator runiter; + /* + for (runiter = runlist.begin(); runiter != runlist.end(); runiter++) + { + updateDB(successTable, "RichCal", stringarg.str(), *runiter); + } + stringarg.str(""); + stringarg << Fun4CalDBCodes::SUCCESS; + + updateDB(successTable, "RichCal", stringarg.str(), firstrun); + */ + odbc::Timestamp stp; + stringarg.str(""); + stringarg << beginticks; + updateDB(table, "startvaltime", stringarg.str(), firstrun); + stp.setTime(beginticks); + updateDB(table, "begintime", stp.toString(), firstrun); + stringarg.str(""); + stringarg << endticks; + updateDB(table, "endvaltime", stringarg.str(), firstrun); + stp.setTime(endticks); + updateDB(table, "endtime", stp.toString(), firstrun); + /* + std::string tablename = "calibrichadc"; + odbc::Connection *con = 0; + std::ostringstream cmd; + try + { + con = odbc::DriverManager::getConnection("oncal", "phnxrc", ""); + } + catch (odbc::SQLException& e) + { + std::cout << "Cannot connect to " << database.c_str() << std::endl; + std::cout << e.getMessage() << std::endl; + return -1; + } + odbc::Statement *stmt = 0; + odbc::Statement *stmtup = 0; + try + { + stmt = con->createStatement(); + stmtup = con->createStatement(); + } + catch (odbc::SQLException& e) + { + std::cout << "Cannot create statement" << std::endl; + std::cout << e.getMessage() << std::endl; + return -1; + } + + odbc::ResultSet *rs1 = 0; + cmd.str(""); + cmd << "SELECT endvaltime from " << tablename + << " where bankid = 1 and startvaltime = " << beginticks; + std::cout << "sql cmd: " << cmd.str() << std::endl; + try + { + rs1 = stmt->executeQuery(cmd.str()); + } + catch (odbc::SQLException& e) + { + std::cout << "Cannot create statement" << std::endl; + std::cout << e.getMessage() << std::endl; + return -1; + } + if (rs1->next()) + { + std::cout << "Endcaltime: " << rs1->getInt("endvaltime") << std::endl; + std::cout << "future endvaltime: " << endticks << std::endl; + cmd.str(""); + cmd << "Update " << tablename + << " set endvaltime = " << endticks + << " where bankid = 1 and startvaltime = " + << beginticks; + stmtup->executeUpdate(cmd.str()); + + } + else + { + std::cout << "Could not find startvaltime " << beginticks + << "from run " << firstrun << std::endl; + } + + */ + + return 0; +} + +int Fun4CalServer::GetCalibStatus(const std::string &calibname, const int runno) +{ + int iret = -3; + if (!connectDB()) + { + std::cout << "could not connect to " << database << std::endl; + return -4; + } + odbc::Statement *stmt = DBconnection->createStatement(); + std::ostringstream cmd; + + // look only for runs which were actually successfully calibrated (status = 1) + cmd << "SELECT " << calibname << " FROM " + << successTable << " where runnumber = " + << runno; + std::cout << "exec " << cmd.str() << std::endl; + odbc::ResultSet *rs = nullptr; + try + { + rs = stmt->executeQuery(cmd.str()); + } + catch (odbc::SQLException &e) + { + std::cout << "Table " << successTable << " does not exist" << std::endl; + return -5; + } + if (rs->next()) + { + iret = rs->getInt(calibname); + } + else + { + std::cout << PHWHERE << " No calib status for " << calibname + << " for " << runno << std::endl; + } + delete rs; + return iret; +} + +void Fun4CalServer::TestMode(const int i) +{ + const char *logname = getenv("LOGNAME"); + if (logname) + { + if (strcmp(logname, "sphnxpro") == 0 || strcmp(logname, "anatrain") == 0) + { + std::cout << "phnxcal,anatrain account is not allowed to run in testmode" << std::endl; + } + else + { + testmode = i; + } + } + else + { + std::cout << "could not get account via env var LOGNAME, not setting testmode" << std::endl; + } + return; +} diff --git a/calibrations/framework/fun4cal/Fun4CalServer.h b/calibrations/framework/fun4cal/Fun4CalServer.h new file mode 100644 index 0000000000..47e0777ab8 --- /dev/null +++ b/calibrations/framework/fun4cal/Fun4CalServer.h @@ -0,0 +1,140 @@ +#ifndef FUN4CAL_FUN4CALSERVER_H +#define FUN4CAL_FUN4CALSERVER_H + +#include +#include + +#include // for time_t +#include +#include +#include +#include + +class CalReco; +class SubsysReco; +class TH1; + +namespace fetchrun +{ + enum + { + CLOSEST, + PREVIOUS + }; +}; + +class Fun4CalServer : public Fun4AllServer +{ + public: + static Fun4CalServer *instance(); + ~Fun4CalServer() override; + using Fun4AllServer::registerHisto; + void registerHisto(TH1 *h1d, CalReco *Calibrator, const int replace = 0); + void unregisterHisto(const std::string &calibratorname); + void Print(const std::string &what = "ALL") const override; + + void dumpHistos(); + int process_event() override; + int BeginRun(const int runno) override; + int EndRun(const int /*runno*/) override { return 0; } // do not execute EndRun + int End() override; + + PHTimeStamp *GetEndValidityTS(); + + PHTimeStamp *GetBeginValidityTS(); + void printStamps(); + PHTimeStamp *GetLastGoodRunTS(CalReco *calibrator, const int irun); + + void recordDataBase(const bool bookkeep = false); + + // RunNumber() tells the server which run is being analyzed. + // and if recordDB is true, this will insert the run number in + // calprocess_stat table in calBookKeep database. + // All updates are made to the row in the database containing this runNum. + // Note that the run number is the primary key in the tables. + // If calBookKeep database is not to be updated, this function + // should not be called. + void RunNumber(const int runnum); + int RunNumber() const { return runNum; } + + void BeginTimeStamp(const PHTimeStamp &TimeStp); + void EndTimeStamp(const PHTimeStamp &TimeStp); + + int SyncCalibTimeStampsToOnCal(const CalReco *calibrator, const std::string &table, const int commit = 0); + int SyncCalibTimeStampsToOnCal(const CalReco *calibrator, const int commit = 0); + int SyncOncalTimeStampsToRunDB(const int commit = 0); + int ClosestGoodRun(CalReco *calibrator, const int irun, const int previous = fetchrun::CLOSEST); + static int CopyTables(const CalReco *calibrator, const int FromRun, const int ToRun, const int commit = 0); + static int OverwriteCalibration(CalReco *calibrator, const int runno, const int commit = 0, const int fromrun = -1); + int FixMissingCalibration(CalReco *calibrator, const int runno, const int commit = 0, const int fromrun = -1); + + int SetBorTime(const int runno); + int SetEorTime(const int runno); + int requiredCalibration(SubsysReco *reco, const std::string &calibratorname); + int FindClosestCalibratedRun(const int irun); + int FillRunListFromFileList(); + int AdjustRichTimeStampForMultipleRuns(); + int CreateCalibration(CalReco *calibrator, const int myrunnumber, const std::string &what, const int commit = 0); + int GetCalibStatus(const std::string &calibname, const int runno); + static int DisconnectDB(); + void TestMode(const int i = 1); + // need to be able to call this from the outside + bool updateDBRunRange(const std::string &table, const std::string &column, const int entry, const int firstrun, const int lastrun); + void EventCheckFrequency(const unsigned int i) { eventcheckfrequency = i; } + + protected: + //------------------------------------- + // following functions access DB using odbc++ library + // these are designed to insert status in calBookKeep (or success) database. + // setDB() sets the name of the database to connect to. e.g., calibration + // this database should exist in the odbc.ini file. + // void setDB(const char* DBname){database = DBname;} + bool connectDB(); + + // insertRunNumInDB enters the run number in the calBookKeep database. + // All other updates are made to rows in the database containing the runNum. + // This function should be called before any updates are made. + // Returns true on successful DB insert. + bool insertRunNumInDB(const std::string &DBtable, const int runno); + + bool findRunNumInDB(const std::string &DBtable, const int runno); + + // these functions update different columns in the success database tables. + // Ony the row with the run number set by setRunNum() is updated. + + bool updateDB(const std::string &table, const std::string &column, int entry); + bool updateDB(const std::string &table, const std::string &column, bool entry); + bool updateDB(const std::string &table, const std::string &column, const std::string &entry, + const int runno, const bool append = false); + int updateDB(const std::string &table, const std::string &column, const time_t ticks); + + int check_create_subsystable(const std::string &tablename); + int check_create_successtable(const std::string &tablename); + int add_calibrator_to_statustable(const std::string &calibratorname); + int check_calibrator_in_statustable(const std::string &calibratorname); + static int GetRunTimeTicks(const int runno, time_t &borticks, time_t &eorticks); + void CreateCalibrationUpdateStatus(CalReco *calibrator, const std::string &table, const std::string &tablecomment, const int dbcode); + Fun4CalServer(const std::string &name = "Fun4CalServer"); + PHTimeStamp beginTimeStamp; // begin run timestamp of run analysing + PHTimeStamp endTimeStamp; // end run timestamp of run analysing + int testmode{0}; + bool recordDB{false}; + TH1 *Fun4CalServerVars{nullptr}; + std::map Histo; + std::map > calibratorhistomap; + bool SetEndTimeStampByHand{false}; + bool SetBeginTimeStampByHand{false}; + + std::string successTable; + unsigned int runNum{0}; + unsigned int nEvents{0}; + unsigned int eventcheckfrequency{1000}; + std::string database{"calBookKeep"}; // this holds the name of the database + // should be set to calibrations for normal running + std::map > requiredCalibrators; + std::vector analysed_runs; + std::vector inputfilelist; + std::set runlist; +}; + +#endif /* __FUN4CALSERVER_H */ diff --git a/calibrations/framework/fun4cal/Makefile.am b/calibrations/framework/fun4cal/Makefile.am new file mode 100644 index 0000000000..02ad88ff18 --- /dev/null +++ b/calibrations/framework/fun4cal/Makefile.am @@ -0,0 +1,48 @@ +AUTOMAKE_OPTIONS = foreign + +AM_CPPFLAGS = \ + -I$(includedir) \ + -isystem$(OFFLINE_MAIN)/include \ + -isystem$(OPT_SPHENIX)/include \ + -isystem$(ROOTSYS)/include + +lib_LTLIBRARIES = \ + libfun4cal.la + +libfun4cal_la_LIBADD = \ + -L$(libdir) \ + -L$(OFFLINE_MAIN)/lib \ + -L$(OPT_SPHENIX)/lib \ + -lfun4all \ + -lodbc++ \ + -lpdbcalBase \ + -lphool + +pkginclude_HEADERS = \ + Fun4CalDBCodes.h \ + Fun4CalHistoBinDefs.h \ + CalReco.h \ + Fun4CalServer.h + +libfun4cal_la_SOURCES = \ + CalReco.cc \ + Fun4CalServer.cc + +BUILT_SOURCES = \ + testexternals.cc + +noinst_PROGRAMS = \ + testexternals + +testexternals_SOURCES = \ + testexternals.cc + +testexternals_LDADD = \ + libfun4cal.la + +testexternals.cc: + echo "//*** this is a generated file. Do not commit, do not edit" > $@ + echo "int main()" >> $@ + echo "{" >> $@ + echo " return 0;" >> $@ + echo "}" >> $@ diff --git a/calibrations/framework/fun4cal/autogen.sh b/calibrations/framework/fun4cal/autogen.sh new file mode 100755 index 0000000000..dea267bbfd --- /dev/null +++ b/calibrations/framework/fun4cal/autogen.sh @@ -0,0 +1,8 @@ +#!/bin/sh +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +(cd $srcdir; aclocal -I ${OFFLINE_MAIN}/share;\ +libtoolize --force; automake -a --add-missing; autoconf) + +$srcdir/configure "$@" diff --git a/calibrations/framework/fun4cal/configure.ac b/calibrations/framework/fun4cal/configure.ac new file mode 100644 index 0000000000..a665c5357c --- /dev/null +++ b/calibrations/framework/fun4cal/configure.ac @@ -0,0 +1,16 @@ +AC_INIT(fun4cal,[1.00]) +AC_CONFIG_SRCDIR([configure.ac]) + +AM_INIT_AUTOMAKE + +AC_PROG_CXX(CC g++) + +LT_INIT([disable-static]) + +dnl no point in suppressing warnings people should +dnl at least see them, so here we go for g++: -Wall +if test $ac_cv_prog_gxx = yes; then + CXXFLAGS="$CXXFLAGS -Wall -Wextra -Wshadow -Werror" +fi + +AC_OUTPUT(Makefile) From 3e39da384c10824fa0155d6e64f9a013190ea8ba Mon Sep 17 00:00:00 2001 From: Joseph Clement Date: Thu, 5 Feb 2026 15:23:40 -0500 Subject: [PATCH 178/393] Update logic to correct timing cut based on fit to oh fraction vs t distribution. Further commits to come. --- offline/packages/jetbackground/TimingCut.cc | 37 +++++++++++++++++---- offline/packages/jetbackground/TimingCut.h | 23 +++++++++++-- 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/offline/packages/jetbackground/TimingCut.cc b/offline/packages/jetbackground/TimingCut.cc index 69ab008124..81053863f6 100644 --- a/offline/packages/jetbackground/TimingCut.cc +++ b/offline/packages/jetbackground/TimingCut.cc @@ -18,10 +18,11 @@ #include // for pair #include // for vector //____________________________________________________________________________.. -TimingCut::TimingCut(const std::string &jetNodeName, const std::string &name, const bool doAbort) +TimingCut::TimingCut(const std::string &jetNodeName, const std::string &name, const bool doAbort, const std::string &ohTowerName) : SubsysReco(name) , _doAbort(doAbort) , _jetNodeName(jetNodeName) + , _ohTowerName(ohTowerName) , _cutParams(name) { SetDefaultParams(); @@ -57,11 +58,12 @@ int TimingCut::CreateNodeTree(PHCompositeNode *topNode) int TimingCut::process_event(PHCompositeNode *topNode) { JetContainer *jets = findNode::getClass(topNode, _jetNodeName); - if (!jets) + TowerInfoContainer* towersOH = findNode::getClas(topNode, _ohTowerName); + if (!jets || !towersOH) { if (Verbosity() > 0 && !_missingInfoWarningPrinted) { - std::cout << "Missing jets; abort event. Further warnings will be suppressed." << std::endl; + std::cout << "Missing jets or OHCal towers; abort event. Further warnings will be suppressed." << std::endl; } _missingInfoWarningPrinted = true; return Fun4AllReturnCodes::ABORTEVENT; @@ -69,6 +71,8 @@ int TimingCut::process_event(PHCompositeNode *topNode) float maxJetpT = 0; float subJetpT = 0; + float maxJetOHFrac = std::numeric_limits::quiet_NaN(); + float subJetOHFrac = std::numeric_limits::quiet_NaN(); float maxJett = std::numeric_limits::quiet_NaN(); float subJett = std::numeric_limits::quiet_NaN(); float maxJetPhi = std::numeric_limits::quiet_NaN(); @@ -86,12 +90,23 @@ int TimingCut::process_event(PHCompositeNode *topNode) float jetpT = 0; float jett = std::numeric_limits::quiet_NaN(); float jetPhi = std::numeric_limits::quiet_NaN(); + float jetOHFrac = 0; Jet *jet = jets->get_jet(i); if (jet) { jetpT = jet->get_pt(); jett = jet->get_property(Jet::PROPERTY::prop_t); jetPhi = jet->get_phi(); + for(auto comp: jet->get_comp_vec()) + { + if(comp.first == 7 || comp.first == 27) + { + unsigned int channel = comp.second; + TowerInfo* tower = towersOH->get_tower_at_channel(channel); + jetOHFrac += tower->get_energy(); + } + } + jetOHFrac /= jet->get_e(); } else { @@ -104,16 +119,19 @@ int TimingCut::process_event(PHCompositeNode *topNode) subJetpT = maxJetpT; subJett = maxJett; subJetPhi = maxJetPhi; + subJetOHFrac = maxJetOHFrac; } maxJetpT = jetpT; maxJett = jett; maxJetPhi = jetPhi; + maxJetOHFrac = jetOHFrac; } else if (jetpT > subJetpT) { subJetpT = jetpT; subJett = jett; subJetPhi = jetPhi; + subJetOHFrac = jetOHFrac; } } } @@ -126,8 +144,11 @@ int TimingCut::process_event(PHCompositeNode *topNode) return Fun4AllReturnCodes::ABORTEVENT; } - bool passDeltat = Pass_Delta_t(maxJett, subJett, maxJetPhi, subJetPhi); - bool passLeadt = Pass_Lead_t(maxJett); + float corrMaxJett = Correct_Time_Ohfrac(maxJett, maxJetOHFrac); + float corrSubJett = Correct_Time_Ohfrac(subJett, subJetOHFrac); + + bool passDeltat = Pass_Delta_t(corrMaxJett, corrSubJett, maxJetPhi, subJetPhi); + bool passLeadt = Pass_Lead_t(corrMaxJett); MbdOut * mbdout = static_cast(findNode::getClass(topNode,"MbdOut")); float m_mbd_t0 = std::numeric_limits::quiet_NaN(); @@ -157,7 +178,7 @@ int TimingCut::process_event(PHCompositeNode *topNode) bool passMbdt = false; if(!std::isnan(mbd_time)) { - passMbdt = Pass_Mbd_dt(maxJett, mbd_time); + passMbdt = Pass_Mbd_dt(corrMaxJett, mbd_time); } bool failAnyCut = !passDeltat || !passLeadt || !passMbdt; @@ -174,7 +195,11 @@ int TimingCut::process_event(PHCompositeNode *topNode) _cutParams.set_int_param("failAnyTimeCut", failAnyCut); _cutParams.set_double_param("maxJett",maxJett); _cutParams.set_double_param("subJett",subJett); + _cutParams.set_double_param("corrMaxJett",corrMaxJett); + _cutParams.set_double_param("corrSubJett",corrSubJett); _cutParams.set_double_param("mbd_time",mbd_time); + _cutParams.set_double_param("leadOhFrac",maxJetOHFrac); + _cutParams.set_double_param("subOhFrac",subJetOHFrac); _cutParams.set_double_param("dPhi",calc_dphi(maxJetPhi, subJetPhi)); _cutParams.UpdateNodeTree(parNode, "TimingCutParams"); diff --git a/offline/packages/jetbackground/TimingCut.h b/offline/packages/jetbackground/TimingCut.h index 2e426a82da..ad212d1146 100644 --- a/offline/packages/jetbackground/TimingCut.h +++ b/offline/packages/jetbackground/TimingCut.h @@ -7,6 +7,9 @@ #include + +#include +#include #include #include @@ -15,10 +18,16 @@ class PHCompositeNode; class TimingCut : public SubsysReco { public: - explicit TimingCut(const std::string &jetNodeName, const std::string &name = "TimingCutModule", bool doAbort = false); + explicit TimingCut(const std::string &jetNodeName, const std::string &name = "TimingCutModule", bool doAbort = false, const std::string &ohTowerName = "TOWERINFO_CALIB_HCALOUT"); ~TimingCut() override = default; + float Correct_Time_Ohfrac(float t, float ohfrac) + { + float corrt = t + _fitFunc->Eval(ohfrac); + return corrt; + } + float calc_dphi(float maxJetPhi, float subJetPhi) { float dPhi = std::abs(maxJetPhi - subJetPhi); @@ -76,23 +85,31 @@ class TimingCut : public SubsysReco _cutParams.set_int_param("passLeadtCut", 0); _cutParams.set_int_param("passDeltatCut", 0); _cutParams.set_int_param("passMbdDtCut", 0); - _cutParams.set_int_param("failAnyTimeCut",0); + _cutParams.set_int_param("failAnyTimeCut",1); _cutParams.set_double_param("maxJett",9999); _cutParams.set_double_param("subJett",9999); _cutParams.set_double_param("mbd_time",9999); _cutParams.set_double_param("dPhi",9999); + _cutParams.set_double_param("leadOhFrac",-1); + _cutParams.set_double_param("subOhFrac",-1); + _cutParams.set_double_param("corrMaxJett",9999); + _cutParams.set_double_param("corrSubJett",9999); + } private: bool _doAbort; bool _missingInfoWarningPrinted = false; std::string _jetNodeName; + std::string _ohTowerName; PHParameters _cutParams; float _t_width{6.0}; float _dt_width{3.0}; - float _t_shift{2.0}; + float _t_shift{0.0}; float _mbd_dt_width{3.0}; float _min_dphi{3*M_PI/4}; + TFile* _fitFile = nullptr; + TF1* _fitFunc = nullptr; }; #endif From e6b5ace497fbadcce284e31208a59c302fc23e40 Mon Sep 17 00:00:00 2001 From: Michael Peters Date: Thu, 5 Feb 2026 19:00:59 -0500 Subject: [PATCH 179/393] fixed cluster tbin and INTT hit gathering --- .../TrackingDiagnostics/TrkrNtuplizer.cc | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/offline/packages/TrackingDiagnostics/TrkrNtuplizer.cc b/offline/packages/TrackingDiagnostics/TrkrNtuplizer.cc index abc91cbf52..eae111fe10 100644 --- a/offline/packages/TrackingDiagnostics/TrkrNtuplizer.cc +++ b/offline/packages/TrackingDiagnostics/TrkrNtuplizer.cc @@ -854,8 +854,9 @@ ::endl; //-------------------------------------------------- // printOutputInfo(topNode); - /* + ++_ievent; +/* if(m_rawzdc_hist.size()==50){ m_rawzdc_hist.pop(); m_rawmbd_hist.pop(); @@ -866,7 +867,7 @@ ::endl; m_rawmbdlast = m_rawmbd; m_rawmbdv10last = m_rawmbdv10; m_bcolast =m_bco; - */ +*/ return Fun4AllReturnCodes::EVENT_OK; } @@ -1539,7 +1540,7 @@ void TrkrNtuplizer::fillOutputNtuples(PHCompositeNode* topNode) fx_hit[n_hit::nhitphi] = atan2(glob.y(),glob.x()); } - if (layer_local >= _nlayers_maps && layer_local < _nlayers_intt) + if (layer_local >= _nlayers_maps && layer_local < _nlayers_maps + _nlayers_intt) { int row = InttDefs::getRow(hit_key); int col = InttDefs::getCol(hit_key); @@ -2233,10 +2234,20 @@ void TrkrNtuplizer::FillCluster(float fXcluster[n_cluster::clusize], TrkrDefs::c fXcluster[n_cluster::ncludcal] = 1; } } + else if (layer_local < 3) + { + phibin = std::numeric_limits::quiet_NaN(); + tbin = MvtxDefs::getStrobeId(cluster_key); + } + else if (layer_local >= 3 && layer_local < 7) + { + phibin = std::numeric_limits::quiet_NaN(); + tbin = InttDefs::getTimeBucketId(cluster_key); + } else { - phibin = locx; - tbin = locy; + phibin = std::numeric_limits::quiet_NaN(); + tbin = std::numeric_limits::quiet_NaN(); } fXcluster[n_cluster::nclulocx] = locx; fXcluster[n_cluster::nclulocy] = locy; From 804a7fac2232fbb49fabf43a9f97edc23662e693 Mon Sep 17 00:00:00 2001 From: Michael Peters Date: Thu, 5 Feb 2026 23:05:40 -0500 Subject: [PATCH 180/393] KFParticle: added local dE/dx file option, removed condition on import of daughter BCOs --- .../KFParticle_sPHENIX/KFParticle_Tools.cc | 40 +++++++++++++++---- .../KFParticle_sPHENIX/KFParticle_Tools.h | 4 ++ .../KFParticle_sPHENIX/KFParticle_nTuple.cc | 5 ++- .../KFParticle_sPHENIX/KFParticle_sPHENIX.h | 4 ++ 4 files changed, 44 insertions(+), 9 deletions(-) diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc b/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc index b319af5b56..12f6614bc7 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc @@ -1184,7 +1184,18 @@ float KFParticle_Tools::get_dEdx(PHCompositeNode *topNode, const KFParticle &dau void KFParticle_Tools::init_dEdx_fits() { - std::string dedx_fitparams = CDBInterface::instance()->getUrl("TPC_DEDX_FITPARAM"); + std::string dedx_fitparams; + if (m_use_local_PID_file) + { + dedx_fitparams = m_local_PID_filename; + } + else + { + dedx_fitparams = CDBInterface::instance()->getUrl("TPC_DEDX_FITPARAM"); + } + + std::cout << "opening " << dedx_fitparams << std::endl; + TFile *filefit = TFile::Open(dedx_fitparams.c_str()); if (!filefit->IsOpen()) @@ -1193,12 +1204,26 @@ void KFParticle_Tools::init_dEdx_fits() return; } - filefit->GetObject("f_piband", f_pion_plus); - filefit->GetObject("f_Kband", f_kaon_plus); - filefit->GetObject("f_pband", f_proton_plus); - filefit->GetObject("f_piminus_band", f_pion_minus); - filefit->GetObject("f_Kminus_band", f_kaon_minus); - filefit->GetObject("f_pbar_band", f_proton_minus); + if (m_use_local_PID_file) + { + std::cout << "using local" << std::endl; + // new method is independent of charge + filefit->GetObject("pi_band",f_pion_plus); + filefit->GetObject("K_band",f_kaon_plus); + filefit->GetObject("p_band",f_proton_plus); + filefit->GetObject("pi_band",f_pion_minus); + filefit->GetObject("K_band",f_kaon_minus); + filefit->GetObject("p_band",f_proton_minus); + } + else + { + filefit->GetObject("f_piband", f_pion_plus); + filefit->GetObject("f_Kband", f_kaon_plus); + filefit->GetObject("f_pband", f_proton_plus); + filefit->GetObject("f_piminus_band", f_pion_minus); + filefit->GetObject("f_Kminus_band", f_kaon_minus); + filefit->GetObject("f_pbar_band", f_proton_minus); + } pidMap.insert(std::pair(-11, f_pion_plus)); pidMap.insert(std::pair(211, f_pion_plus)); @@ -1212,6 +1237,7 @@ void KFParticle_Tools::init_dEdx_fits() double KFParticle_Tools::get_dEdx_fitValue(float momentum, int PID) { + std::cout << "eval of PID " << PID << " returns " << pidMap[PID]->Eval(momentum) << std::endl; return pidMap[PID]->Eval(momentum); } diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.h b/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.h index 4e722a15db..feabd4aafc 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.h +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.h @@ -27,6 +27,8 @@ #include #include +#include // included here so inline functions are defined on user end + #include #include @@ -149,6 +151,8 @@ class KFParticle_Tools : protected KFParticle_MVA std::vector m_intermediate_vertex_volume; bool m_use_PID{false}; + bool m_use_local_PID_file{false}; + std::string m_local_PID_filename = ""; float m_dEdx_band_width{0.2}; // Fraction of expected dE/dx TF1 *f_pion_plus{nullptr}; diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc b/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc index 1770870bb3..b4659e1b8d 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc @@ -672,7 +672,8 @@ void KFParticle_nTuple::fillBranch(PHCompositeNode* topNode, { gl1packet = findNode::getClass(topNode, "GL1Packet"); } - m_bco = m_trigger_info_available ? gl1packet->lValue(0, "BCO") + m_calculated_daughter_bunch_crossing[0] : 0; + m_bco = gl1packet->lValue(0, "BCO") + m_calculated_daughter_bunch_crossing[0]; + //m_bco = m_trigger_info_available ? gl1packet->lValue(0, "BCO") + m_calculated_daughter_bunch_crossing[0] : 0; } else { @@ -741,4 +742,4 @@ bool KFParticle_nTuple::fillConditionMet() const // if requiring track-calo matching, the match result is returned return isTrackEMCalmatch; -} \ No newline at end of file +} diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h index 64fc3f37bb..d5905d443c 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h @@ -394,6 +394,10 @@ class KFParticle_sPHENIX : public SubsysReco, public KFParticle_nTuple, public K void selectMotherByMassError(bool select = true) { m_select_by_mass_error = select; } void usePID(bool use = true){ m_use_PID = use; } + + void useLocalPIDFile(bool use = true){ m_use_local_PID_file = use; } + + void setLocalPIDFilename(const std::string &filename){ m_local_PID_filename = filename; } void setPIDacceptFraction(float frac = 0.2){ m_dEdx_band_width = frac; } From c37ffe92cbd1700573b83a0814d743489bedb407 Mon Sep 17 00:00:00 2001 From: Michael Peters Date: Thu, 5 Feb 2026 23:12:47 -0500 Subject: [PATCH 181/393] reverse commit mixup --- .../TrackingDiagnostics/TrkrNtuplizer.cc | 21 +++++-------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/offline/packages/TrackingDiagnostics/TrkrNtuplizer.cc b/offline/packages/TrackingDiagnostics/TrkrNtuplizer.cc index eae111fe10..abc91cbf52 100644 --- a/offline/packages/TrackingDiagnostics/TrkrNtuplizer.cc +++ b/offline/packages/TrackingDiagnostics/TrkrNtuplizer.cc @@ -854,9 +854,8 @@ ::endl; //-------------------------------------------------- // printOutputInfo(topNode); - + /* ++_ievent; -/* if(m_rawzdc_hist.size()==50){ m_rawzdc_hist.pop(); m_rawmbd_hist.pop(); @@ -867,7 +866,7 @@ ::endl; m_rawmbdlast = m_rawmbd; m_rawmbdv10last = m_rawmbdv10; m_bcolast =m_bco; -*/ + */ return Fun4AllReturnCodes::EVENT_OK; } @@ -1540,7 +1539,7 @@ void TrkrNtuplizer::fillOutputNtuples(PHCompositeNode* topNode) fx_hit[n_hit::nhitphi] = atan2(glob.y(),glob.x()); } - if (layer_local >= _nlayers_maps && layer_local < _nlayers_maps + _nlayers_intt) + if (layer_local >= _nlayers_maps && layer_local < _nlayers_intt) { int row = InttDefs::getRow(hit_key); int col = InttDefs::getCol(hit_key); @@ -2234,20 +2233,10 @@ void TrkrNtuplizer::FillCluster(float fXcluster[n_cluster::clusize], TrkrDefs::c fXcluster[n_cluster::ncludcal] = 1; } } - else if (layer_local < 3) - { - phibin = std::numeric_limits::quiet_NaN(); - tbin = MvtxDefs::getStrobeId(cluster_key); - } - else if (layer_local >= 3 && layer_local < 7) - { - phibin = std::numeric_limits::quiet_NaN(); - tbin = InttDefs::getTimeBucketId(cluster_key); - } else { - phibin = std::numeric_limits::quiet_NaN(); - tbin = std::numeric_limits::quiet_NaN(); + phibin = locx; + tbin = locy; } fXcluster[n_cluster::nclulocx] = locx; fXcluster[n_cluster::nclulocy] = locy; From 96944238e5e4cb0feddcfce1627e00d20f1f6db8 Mon Sep 17 00:00:00 2001 From: Michael Peters Date: Thu, 5 Feb 2026 23:17:46 -0500 Subject: [PATCH 182/393] cleaned up debug logging --- offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc b/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc index 12f6614bc7..7d48ed6b75 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc @@ -1194,7 +1194,7 @@ void KFParticle_Tools::init_dEdx_fits() dedx_fitparams = CDBInterface::instance()->getUrl("TPC_DEDX_FITPARAM"); } - std::cout << "opening " << dedx_fitparams << std::endl; + std::cout << PHWHERE << " opening " << dedx_fitparams << std::endl; TFile *filefit = TFile::Open(dedx_fitparams.c_str()); @@ -1206,7 +1206,7 @@ void KFParticle_Tools::init_dEdx_fits() if (m_use_local_PID_file) { - std::cout << "using local" << std::endl; + std::cout << PHWHERE << " using local file " << m_local_PID_filename << std::endl; // new method is independent of charge filefit->GetObject("pi_band",f_pion_plus); filefit->GetObject("K_band",f_kaon_plus); @@ -1237,7 +1237,6 @@ void KFParticle_Tools::init_dEdx_fits() double KFParticle_Tools::get_dEdx_fitValue(float momentum, int PID) { - std::cout << "eval of PID " << PID << " returns " << pidMap[PID]->Eval(momentum) << std::endl; return pidMap[PID]->Eval(momentum); } From de58c9b37797b28482b324d0d0518ffc63f990af Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Fri, 6 Feb 2026 10:15:07 -0500 Subject: [PATCH 183/393] add fun4cal --- calibrations/framework/oncal/Makefile.am | 48 - calibrations/framework/oncal/OnCal.cc | 48 - calibrations/framework/oncal/OnCal.h | 59 - calibrations/framework/oncal/OnCalDBCodes.h | 19 - .../framework/oncal/OnCalHistoBinDefs.h | 16 - calibrations/framework/oncal/OnCalServer.cc | 2439 ----------------- calibrations/framework/oncal/OnCalServer.h | 140 - calibrations/framework/oncal/autogen.sh | 8 - calibrations/framework/oncal/configure.ac | 16 - 9 files changed, 2793 deletions(-) delete mode 100644 calibrations/framework/oncal/Makefile.am delete mode 100644 calibrations/framework/oncal/OnCal.cc delete mode 100644 calibrations/framework/oncal/OnCal.h delete mode 100644 calibrations/framework/oncal/OnCalDBCodes.h delete mode 100644 calibrations/framework/oncal/OnCalHistoBinDefs.h delete mode 100644 calibrations/framework/oncal/OnCalServer.cc delete mode 100644 calibrations/framework/oncal/OnCalServer.h delete mode 100755 calibrations/framework/oncal/autogen.sh delete mode 100644 calibrations/framework/oncal/configure.ac diff --git a/calibrations/framework/oncal/Makefile.am b/calibrations/framework/oncal/Makefile.am deleted file mode 100644 index bb0b3674c1..0000000000 --- a/calibrations/framework/oncal/Makefile.am +++ /dev/null @@ -1,48 +0,0 @@ -AUTOMAKE_OPTIONS = foreign - -AM_CPPFLAGS = \ - -I$(includedir) \ - -isystem$(OFFLINE_MAIN)/include \ - -isystem$(OPT_SPHENIX)/include \ - -isystem$(ROOTSYS)/include - -lib_LTLIBRARIES = \ - liboncal.la - -liboncal_la_LIBADD = \ - -L$(libdir) \ - -L$(OFFLINE_MAIN)/lib \ - -L$(OPT_SPHENIX)/lib \ - -lfun4all \ - -lodbc++ \ - -lpdbcalBase \ - -lphool - -pkginclude_HEADERS = \ - OnCalDBCodes.h \ - OnCalHistoBinDefs.h \ - OnCal.h \ - OnCalServer.h - -liboncal_la_SOURCES = \ - OnCal.cc \ - OnCalServer.cc - -BUILT_SOURCES = \ - testexternals.cc - -noinst_PROGRAMS = \ - testexternals - -testexternals_SOURCES = \ - testexternals.cc - -testexternals_LDADD = \ - liboncal.la - -testexternals.cc: - echo "//*** this is a generated file. Do not commit, do not edit" > $@ - echo "int main()" >> $@ - echo "{" >> $@ - echo " return 0;" >> $@ - echo "}" >> $@ diff --git a/calibrations/framework/oncal/OnCal.cc b/calibrations/framework/oncal/OnCal.cc deleted file mode 100644 index ae652adbc8..0000000000 --- a/calibrations/framework/oncal/OnCal.cc +++ /dev/null @@ -1,48 +0,0 @@ -#include "OnCal.h" - -#include // for SubsysReco - -#include // for PHWHERE - -#include - -OnCal::OnCal(const std::string &Name) - : SubsysReco(Name) -{ -} - -int OnCal::process_event(PHCompositeNode * /*topNode*/) -{ - std::cout << "process_event(PHCompositeNode *topNode) not implemented by daughter class: " << Name() << std::endl; - return -1; -} - -int OnCal::End(PHCompositeNode * /*topNode*/) -{ - std::cout << "EndOfAnalysis not implemented by subsystem!" << std::endl; - std::cout << "Use this signal for computing your calibrations and commit." << std::endl; - std::cout << "Dont do these operations at EndOfRun since subsystems may be feeded events from different runs." << std::endl; - std::cout << "The number of events is the real parameter here, not the runnumber." << std::endl; - return 0; -} - -void OnCal::AddComment(const std::string &adcom) -{ - if (m_Comment.empty()) - { - m_Comment = adcom; - } - else - { - m_Comment += ":"; - m_Comment += adcom; - } - return; -} - -int OnCal::CopyTables(const int /*FromRun*/, const int /*ToRun*/, const int /*commit*/) const -{ - std::cout << PHWHERE << " CopyTables not implemented" << std::endl - << "this calibrator cannot copy its own tables" << std::endl; - return -1; -} diff --git a/calibrations/framework/oncal/OnCal.h b/calibrations/framework/oncal/OnCal.h deleted file mode 100644 index 454e240aaa..0000000000 --- a/calibrations/framework/oncal/OnCal.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef ONCAL_ONCAL_H -#define ONCAL_ONCAL_H - -#include -#include -#include -#include // for pair -#include - -class OnCal : public SubsysReco -{ - public: - ~OnCal() override = default; - - // These might be overwritten by everyone... - int process_event(PHCompositeNode *topNode) override; - int End(PHCompositeNode *topNode) override = 0; // Here you analyze and commit (if committing flag is set) - - // Thsse control committing to the database... - virtual void CommitToPdbCal(const int value) = 0; // Set the flag for whether EndOfAnalysis will commit or not - virtual int VerificationOK() const = 0; // Tell us whether the new calib is close enough to the old one - virtual int CommitedToPdbCalOK() const = 0; // Tell us whether committing was successful by re-reading the data - - // commit without verification, needed for bootstrap calib - // which is too different from previous calibs (e.g. begin of new Run) - virtual void CommitNoVerify(const int) { return; } - - // These default behaviors from SubsysReco base class - virtual void identify(std::ostream &out = std::cout) const { out << Name() << std::endl; } - virtual int BeginRun(const int) { return 0; } - int EndRun(const int) override { return 0; } - int Reset(PHCompositeNode * /*topNode*/) override { return 0; } - int ResetEvent(PHCompositeNode * /*topNode*/) override { return 0; } - virtual void DumpCalib() const { return; } - - unsigned int AllDone() const { return alldone; } - void AllDone(const int i) { alldone = i; } - void AddComment(const std::string &adcom); - const std::string &Comment() const { return m_Comment; } - int GetPdbCalTables(std::vector &vec) const - { - vec = pdbcaltables; - return 0; - } - virtual int CopyTables(const int FromRun, const int ToRun, const int commit) const; - virtual int CreateCalibration(const int /*runnumber*/, const std::string & /*what*/, std::string & /*comment*/, const int /*commit*/) { return -1; } - virtual std::vector GetLocalFileList() const { return localfilelist; } - - protected: - OnCal(const std::string &Name); // so noone can call it from outside - unsigned int alldone{0}; - std::string m_Comment; - std::vector pdbcaltables; - std::vector pdbcalclasses; - std::vector > bankids; - std::vector localfilelist; -}; - -#endif /* ONCAL_ONCAL_H */ diff --git a/calibrations/framework/oncal/OnCalDBCodes.h b/calibrations/framework/oncal/OnCalDBCodes.h deleted file mode 100644 index 707c72f859..0000000000 --- a/calibrations/framework/oncal/OnCalDBCodes.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef ONCALDBCODES_H__ -#define ONCALDBCODES_H__ - -namespace OnCalDBCodes -{ - enum - { - INIT = -2, - STARTED = -1, - FAILED = 0, - SUCCESS = 1, - COPIEDPREVIOUS = 2, - COPIEDLATER = 3, - COVERED = 4, - SUBSYSTEM = 5 - }; -} - -#endif diff --git a/calibrations/framework/oncal/OnCalHistoBinDefs.h b/calibrations/framework/oncal/OnCalHistoBinDefs.h deleted file mode 100644 index d030b6dce2..0000000000 --- a/calibrations/framework/oncal/OnCalHistoBinDefs.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __ONCALHISTOBINDEFS_H__ -#define __ONCALHISTOBINDEFS_H__ - -namespace OnCalHistoBinDefs -{ - enum - { - FIRSTRUNBIN = 1, - LASTRUNBIN, - BORTIMEBIN, - EORTIMEBIN, - LASTBINPLUSONE - }; -}; - -#endif /* __ONCALHISTOBINDEFS_H__ */ diff --git a/calibrations/framework/oncal/OnCalServer.cc b/calibrations/framework/oncal/OnCalServer.cc deleted file mode 100644 index 5593b84188..0000000000 --- a/calibrations/framework/oncal/OnCalServer.cc +++ /dev/null @@ -1,2439 +0,0 @@ -#include "OnCalServer.h" -#include "OnCal.h" -#include "OnCalDBCodes.h" -#include "OnCalHistoBinDefs.h" - -#include -#include -#include // for Fun4AllServer, Fun4AllServe... -#include -#include -#include // for SubsysReco - -#include -#include // for PHTimeStamp, operator<< -#include -#include - -#include - -#include // for Stat_t -#include // for TDirectoryAtomicAdapter -#include -#include -#include // for TNamed -#include -#include // for TString - -// odbc++ classes -#include -#include -#include -#include -#include -#include // for Statement -#include // for SQLException, Timestamp - -#include -#include -#include // for tolower -#include -#include // for strcmp -#include -#include // for reverse_iterator -#include -#include -#include -#include // for pair - -namespace -{ - const std::string cvstag = "OnCalv86"; - - odbc::Connection *DBconnection{nullptr}; -} // namespace - -OnCalServer *OnCalServer::instance() -{ - if (__instance) - { - OnCalServer *oncal = dynamic_cast(__instance); - return oncal; - } - __instance = new OnCalServer(); - OnCalServer *oncal = dynamic_cast(__instance); - return oncal; -} - -//--------------------------------------------------------------------- - -OnCalServer::OnCalServer(const std::string &name) - : Fun4AllServer(name) - , OnCalServerVars(new TH1D("OnCalServerVars", "OnCalServerVars", OnCalHistoBinDefs::LASTBINPLUSONE, -0.5, (int) (OnCalHistoBinDefs::LASTBINPLUSONE) -0.5)) -{ - beginTimeStamp.setTics(0); - endTimeStamp.setTics(0); - - Fun4AllServer::registerHisto(OnCalServerVars); - return; -} -//--------------------------------------------------------------------- - -OnCalServer::~OnCalServer() -{ - delete DBconnection; - return; -} -//--------------------------------------------------------------------- - -PHTimeStamp * -OnCalServer::GetEndValidityTS() -{ - if (endTimeStamp.getTics()) - { - PHTimeStamp *ts = new PHTimeStamp(endTimeStamp); - return ts; - } - - std::cout << PHWHERE << "Screwup - the end validity time is not set" << std::endl; - exit(1); -} -//--------------------------------------------------------------------- - -PHTimeStamp *OnCalServer::GetBeginValidityTS() -{ - if (beginTimeStamp.getTics()) - { - PHTimeStamp *ts = new PHTimeStamp(beginTimeStamp); - return ts; - } - - std::cout << PHWHERE << "Screwup - the begin validity time is not set" << std::endl; - exit(1); -} -//--------------------------------------------------------------------- - -void OnCalServer::dumpHistos() -{ - std::ostringstream filename; - std::string fileprefix = "./"; - - if (getenv("ONCAL_SAVEDIR")) - { - fileprefix = getenv("ONCAL_SAVEDIR"); - fileprefix += "/"; - } - - int compress = 3; - std::map >::const_iterator iter; - // std::map::const_iterator hiter; - TH1 *histo; - std::set::const_iterator siter; - for (iter = calibratorhistomap.begin(); iter != calibratorhistomap.end(); ++iter) - { - filename.str(""); - filename << fileprefix << "Run_" - << RunNumber() - << "_" << iter->first << ".root"; - TFile *hfile = new TFile(filename.str().c_str(), "RECREATE", - "Created by Online Calibrator", compress); - std::cout << "OnCalServer::dumpHistos() Output root file: " << filename.str() << std::endl; - for (siter = (iter->second).begin(); siter != (iter->second).end(); ++siter) - { - histo = dynamic_cast(getHisto(*siter)); - if (histo) - { - histo->Write(); - } - else - { - std::cout << PHWHERE << "Histogram " - << *siter << " not found, will not be saved in " - << filename.str() << std::endl; - } - } - hfile->Close(); - - delete hfile; - } - return; -} - -void OnCalServer::registerHisto(TH1 *h1d, OnCal *Calibrator, const int replace) -{ - if (Calibrator) - { - std::string calibratorname = Calibrator->Name(); - std::map >::iterator iter; - iter = calibratorhistomap.find(calibratorname); - if (iter != calibratorhistomap.end()) - { - (iter->second).insert(h1d->GetName()); - } - else - { - std::set newset; - newset.insert(h1d->GetName()); - newset.insert("OnCalServerVars"); - calibratorhistomap[calibratorname] = newset; - } - } - Fun4AllServer::registerHisto(h1d, replace); - return; -} - -void OnCalServer::unregisterHisto(const std::string &calibratorname) -{ - calibratorhistomap.erase(calibratorname); - return; -} - -int OnCalServer::process_event() -{ - Fun4AllServer::process_event(); - int i = 0; - nEvents++; - if ((nEvents % eventcheckfrequency) == 0) // check every 1000 events - { - std::cout << nEvents << " events, testing" << std::endl; - unsigned int j = 0; - unsigned int ical = 0; - std::vector >::const_iterator iter; - for (iter = Subsystems.begin(); iter != Subsystems.end(); ++iter) - { - OnCal *oncal = dynamic_cast(iter->first); - if (oncal) - { - ical++; - std::cout << "Name: " << oncal->Name() - << " is " << oncal->AllDone() << std::endl; - j += oncal->AllDone(); - } - } - if (j == ical) - { - std::cout << "Everyone is done after " - << nEvents << " Events" << std::endl; - i = 1; - } - } - return i; -} - -int OnCalServer::BeginRun(const int runno) -{ - if (runno <= 0) - { - std::cout << PHWHERE << "Invalid Run Number: " << runno << std::endl; - exit(1); - } - FillRunListFromFileList(); - recoConsts *rc = recoConsts::instance(); - // we stick to the first runnumber, but after inheriting from - // Fun4All we get a EndRun/BeginRun when the run number changes - // so we have to catch this here - if (RunNumber() != 0) - { - rc->set_IntFlag("RUNNUMBER", RunNumber()); // set rc flag back to previous run - analysed_runs.push_back(runno); - return 0; - } - RunNumber(runno); - std::vector >::iterator iter; - // copy the subsys reco pointers to another set for - // easier search (we only need the pointers to find - // the subsystems with special timestamp/runnumber needs - std::set NeedOtherTimeStamp; - std::map >::const_iterator miter; - std::set::const_iterator siter; - for (miter = requiredCalibrators.begin(); - miter != requiredCalibrators.end(); ++miter) - { - for (siter = miter->second.begin(); siter != miter->second.end(); ++siter) - { - NeedOtherTimeStamp.insert(*siter); - } - } - - int iret; - int i = 0; - int oncalrun = runno; - int fun4allrun = runno; - - RunToTime *runTime = RunToTime::instance(); - PHTimeStamp *ts = runTime->getBeginTime(fun4allrun); - PHTimeStamp OnCalBORTimeStamp = *ts; - PHTimeStamp Fun4AllBORTimeStamp(OnCalBORTimeStamp); - delete ts; - if (!requiredCalibrators.empty()) - { - fun4allrun = FindClosestCalibratedRun(runno); - ts = runTime->getBeginTime(fun4allrun); - Fun4AllBORTimeStamp = *ts; - delete ts; - } - - // we have to do the same TDirectory games as in the Init methods - // save the current dir, cd to the subsystem name dir (which was - // created in init) call the InitRun of the module and cd back - - gROOT->cd(default_Tdirectory.c_str()); - std::string currdir = gDirectory->GetPath(); - std::set droplist; - for (iter = Subsystems.begin(); iter != Subsystems.end(); ++iter) - { - std::ostringstream newdirname; - newdirname << (*iter).second->getName() << "/" << (*iter).first->Name(); - if (!gROOT->cd(newdirname.str().c_str())) - { - std::cout << PHWHERE << "Unexpected TDirectory Problem cd'ing to " - << (*iter).second->getName() - << " - send e-mail to off-l with your macro" << std::endl; - exit(1); - } - OnCal *oncal = dynamic_cast((*iter).first); - if (oncal) - { - std::string table = "OnCal"; - table += (*iter).first->Name(); - check_create_subsystable(table); - insertRunNumInDB(table, runNum); - std::string calibname = (*iter).first->Name(); - add_calibrator_to_statustable(calibname); - std::set::const_iterator runiter; - int calibstatus = GetCalibStatus(calibname, runNum); - if (calibstatus > 0 && testmode == 0) - { - std::cout << calibname << " already ran for run " << runNum << std::endl; - droplist.insert(calibname); - unregisterSubsystem(oncal); - unregisterHisto(calibname); - } - else - { - std::ostringstream stringarg; - stringarg << OnCalDBCodes::STARTED; - for (runiter = runlist.begin(); runiter != runlist.end(); ++runiter) - { - updateDB(successTable, calibname, stringarg.str(), *runiter); - } - } - } - if (NeedOtherTimeStamp.contains((*iter).first)) - { - std::cout << "changing timestamp for " << (*iter).first->Name() << std::endl; - rc->set_IntFlag("RUNNUMBER", fun4allrun); - // rc->set_TimeStamp(Fun4AllBORTimeStamp); - } - else - { - rc->set_IntFlag("RUNNUMBER", oncalrun); - // rc->set_TimeStamp(OnCalBORTimeStamp); - } - if (!droplist.contains((*iter).first->Name())) - { - iret = (*iter).first->InitRun(TopNode); - if (iret == Fun4AllReturnCodes::ABORTRUN) - { - std::cout << PHWHERE << "Module " << (*iter).first->Name() << " issued Abort Run, exiting" << std::endl; - exit(-1); - } - i += iret; - } - } - gROOT->cd(currdir.c_str()); - - rc->set_IntFlag("RUNNUMBER", oncalrun); - // rc->set_TimeStamp(OnCalBORTimeStamp); - if (OnCalServerVars->GetBinContent(OnCalHistoBinDefs::FIRSTRUNBIN) == 0) - { - OnCalServerVars->SetBinContent(OnCalHistoBinDefs::FIRSTRUNBIN, runno); - OnCalServerVars->SetBinContent(OnCalHistoBinDefs::BORTIMEBIN, (Stat_t) OnCalBORTimeStamp.getTics()); - } - OnCalServerVars->SetBinContent(OnCalHistoBinDefs::LASTRUNBIN, (Stat_t) runno); - ts = runTime->getEndTime(runno); - if (ts) - { - OnCalServerVars->SetBinContent(OnCalHistoBinDefs::EORTIMEBIN, (Stat_t) ts->getTics()); - delete ts; - } - - // disconnect from DB to save resources on DB machine - // PdbCal leaves the DB connection open (PdbCal will reconnect without - // problem if neccessary) - DisconnectDB(); - // finally drop calibrators which have run already from module list - unregisterSubsystemsNow(); - return i; -} - -int OnCalServer::End() -{ - if (nEvents == 0) - { - std::cout << "No Events read, you probably gave me an empty filelist" << std::endl; - return -1; - } - int i = 0; - std::vector >::iterator iter; - gROOT->cd(default_Tdirectory.c_str()); - std::string currdir = gDirectory->GetPath(); - - for (iter = Subsystems.begin(); iter != Subsystems.end(); ++iter) - { - std::ostringstream newdirname; - newdirname << (*iter).second->getName() << "/" << (*iter).first->Name(); - if (!gROOT->cd(newdirname.str().c_str())) - { - std::cout << PHWHERE << "Unexpected TDirectory Problem cd'ing to " - << (*iter).second->getName() - << " - send e-mail to off-l with your macro" << std::endl; - exit(1); - } - else - { - if (Verbosity() > 2) - { - std::cout << "End: cded to " << newdirname.str().c_str() << std::endl; - } - } - i += (*iter).first->End((*iter).second); - } - - gROOT->cd(default_Tdirectory.c_str()); - currdir = gDirectory->GetPath(); - for (iter = Subsystems.begin(); iter != Subsystems.end(); ++iter) - { - OnCal *oncal = dynamic_cast((*iter).first); - if (!oncal) - { - continue; - } - std::ostringstream newdirname; - newdirname << (*iter).second->getName() << "/" << (*iter).first->Name(); - if (!gROOT->cd(newdirname.str().c_str())) - { - std::cout << PHWHERE << "Unexpected TDirectory Problem cd'ing to " - << (*iter).second->getName() - << " - send e-mail to off-l with your macro" << std::endl; - exit(1); - } - - std::string CalibratorName = oncal->Name(); - - int verificationstatus = oncal->VerificationOK(); - int databasecommitstatus = oncal->CommitedToPdbCalOK(); - - // report success database the status of the calibration - if (recordDB) - { - std::string table = "OnCal"; - table += CalibratorName; - - std::ostringstream stringarg; - if (databasecommitstatus == OnCalDBCodes::SUCCESS) - { - stringarg << OnCalDBCodes::COVERED; - } - else - { - stringarg << OnCalDBCodes::FAILED; - } - std::set::const_iterator runiter; - for (runiter = runlist.begin(); runiter != runlist.end(); ++runiter) - { - updateDB(successTable, CalibratorName, stringarg.str(), *runiter); - } - // update the first run which was used in the calibration - // with the real status - updateDB(successTable, CalibratorName, databasecommitstatus); - - stringarg.str(""); - stringarg << databasecommitstatus; - updateDB(table, "committed", stringarg.str(), RunNumber()); - - stringarg.str(""); - stringarg << verificationstatus; - updateDB(table, "verified", stringarg.str(), RunNumber()); - - odbc::Timestamp stp(time(nullptr)); - updateDB(table, "date", stp.toString(), RunNumber()); - updateDB(table, "comment", oncal->Comment(), RunNumber()); - time_t beginticks = beginTimeStamp.getTics(); - stringarg.str(""); - stringarg << beginticks; - updateDB(table, "startvaltime", stringarg.str(), RunNumber()); - stp.setTime(beginticks); - updateDB(table, "begintime", stp.toString(), RunNumber()); - time_t endticks = endTimeStamp.getTics(); - stringarg.str(""); - stringarg << endticks; - updateDB(table, "endvaltime", stringarg.str(), RunNumber()); - stp.setTime(endticks); - updateDB(table, "endtime", stp.toString(), RunNumber()); - - std::string filelist; - for (Fun4AllSyncManager *sync : SyncManagers) - { - for (Fun4AllInputManager *inmgr : sync->GetInputManagers()) - { - for (const std::string &infile : inmgr->GetFileOpenedList()) - { - filelist += (infile).substr(((infile).find_last_of('/') + 1), (infile).size()); - filelist += " "; // this needs to be stripped again for last entry - } - } - } - filelist.pop_back(); // strip empty space at end from loop - std::cout << "FileList: " << filelist << std::endl; - updateDB(table, "files", filelist, RunNumber()); - updateDB(table, "cvstag", cvstag, RunNumber()); - } - - std::cout << "SERVER SUMMARY: " << oncal->Name() << " " - << (verificationstatus == 1 ? "Verification: SUCCESS " : "Verification: FAILURE ") - << (databasecommitstatus == 1 ? "DB commit: SUCCESS " : "DB commit: FAILURE ") - << std::endl; - - printStamps(); - } - gROOT->cd(currdir.c_str()); - dumpHistos(); // save the histograms in files - return i; -} -//--------------------------------------------------------------------- - -void OnCalServer::Print(const std::string &what) const -{ - Fun4AllServer::Print(what); - if (what == "ALL" || what == "CALIBRATOR") - { - // loop over the map and print out the content - // (name and location in memory) - - std::cout << "--------------------------------------" << std::endl - << std::endl; - std::cout << "List of Calibrators in OnCalServer:" << std::endl; - - std::vector >::const_iterator miter; - for (miter = Subsystems.begin(); - miter != Subsystems.end(); ++miter) - { - OnCal *oncal = dynamic_cast((*miter).first); - if (oncal) - { - std::cout << oncal->Name() << std::endl; - } - } - std::cout << std::endl; - } - if (what == "ALL" || what == "REQUIRED") - { - // loop over the map and print out the content - // (name and location in memory) - - std::cout << "--------------------------------------" << std::endl - << std::endl; - std::cout << "List of required Calibrations in OnCalServer:" << std::endl; - - std::map >::const_iterator iter; - std::set::const_iterator siter; - for (iter = requiredCalibrators.begin(); - iter != requiredCalibrators.end(); ++iter) - { - std::cout << iter->first << " calibrations are needed by " << std::endl; - for (siter = iter->second.begin(); siter != iter->second.end(); ++siter) - { - std::cout << (*siter)->Name() << std::endl; - } - } - std::cout << std::endl; - } - if (what == "ALL" || what == "FILES") - { - std::cout << "--------------------------------------" << std::endl - << std::endl; - std::cout << "List of PRDF Files in OnCalServer:" << std::endl; - for (Fun4AllSyncManager *sync : SyncManagers) - { - for (Fun4AllInputManager *inmgr : sync->GetInputManagers()) - { - for (const std::string &infile : inmgr->GetFileList()) - { - std::cout << "File: " << infile << std::endl; - } - } - } - } - if (what == "ALL" || what == "RUNS") - { - std::cout << "--------------------------------------" << std::endl - << std::endl; - std::cout << "List of Run Numbers in OnCalServer:" << std::endl; - std::set::const_iterator liter; - for (liter = runlist.begin(); liter != runlist.end(); ++liter) - { - std::cout << "Run : " << *liter << std::endl; - } - } - - return; -} - -void OnCalServer::printStamps() -{ - std::cout << std::endl - << std::endl; - std::cout << "*******************************************" << std::endl; - std::cout << "* VALIDITY RANGE FOR THIS CALIBRATION *" << std::endl; - std::cout << "* *" << std::endl; - std::cout << "* Used Run : "; - std::cout << runNum << std::endl; - std::cout << std::endl; - std::cout << "* Begin Valid : "; - beginTimeStamp.print(); - std::cout << std::endl; - std::cout << "* End Valid : "; - endTimeStamp.print(); - std::cout << std::endl; - std::cout << "* *" << std::endl; - std::cout << "*******************************************" << std::endl; - std::cout << std::endl - << std::endl - << std::endl; -} - -//--------------------------------------------------------------------- - -void OnCalServer::RunNumber(const int runnum) -{ - runNum = runnum; - SetBorTime(runnum); - if (recordDB) - { - std::set::const_iterator runiter; - time_t beginrunticks; - time_t endrunticks; - std::ostringstream stringarg; - odbc::Timestamp stp; - for (runiter = runlist.begin(); runiter != runlist.end(); ++runiter) - { - insertRunNumInDB(successTable, *runiter); - GetRunTimeTicks(*runiter, beginrunticks, endrunticks); - stringarg.str(""); - stringarg << beginrunticks; - updateDB(successTable, "startvaltime", stringarg.str(), *runiter); - stp.setTime(beginrunticks); - updateDB(successTable, "beginrun", stp.toString(), *runiter); - stringarg.str(""); - stringarg << endrunticks; - updateDB(successTable, "endvaltime", stringarg.str(), *runiter); - stp.setTime(endrunticks); - updateDB(successTable, "endrun", stp.toString(), *runiter); - } - } - if (!runlist.empty()) - { - SetEorTime(*runlist.rbegin()); - } - return; -} - -//--------------------------------------------------------------------- - -bool OnCalServer::connectDB() -{ - if (DBconnection) - { - return true; - } - - bool failure = true; - int countdown = 10; - while (failure && countdown > 0) - { - failure = false; - try - { - DBconnection = - odbc::DriverManager::getConnection(database, "phnxrc", ""); - } - catch (odbc::SQLException &e) - { - std::cout << "Cannot connect to " << database.c_str() << std::endl; - std::cout << e.getMessage() << std::endl; - std::cout << "countdown: " << countdown << std::endl; - countdown--; - failure = true; - sleep(100); // try again in 100 secs - } - } - if (failure) - { - std::cout << "could not connect to DB after 10 tries in 1000 secs, giving up" << std::endl; - exit(-1); - } - std::cout << "connected to " << database.c_str() << " database." << std::endl; - return true; -} -//--------------------------------------------------------------------- - -int OnCalServer::DisconnectDB() -{ - delete DBconnection; - DBconnection = nullptr; - return 0; -} -//--------------------------------------------------------------------- - -bool OnCalServer::insertRunNumInDB(const std::string &DBtable, const int runno) -{ - if (findRunNumInDB(DBtable, runno)) - { - return true; - } - - std::cout << "new row will be created in DB for run " << runno << std::endl; - - odbc::Statement *statement = nullptr; - statement = DBconnection->createStatement(); - std::ostringstream cmd; - cmd << "INSERT INTO " - << DBtable - << " (runnumber) VALUES (" - << runno << ")"; - - if (Verbosity() == 1) - { - std::cout << "in function OnCalServer::insertRunNumInDB() ... "; - std::cout << "executing SQL statements ..." << std::endl; - std::cout << cmd.str() << std::endl; - } - - try - { - statement->executeUpdate(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << e.getMessage() << std::endl; - return false; - } - - return true; -} - -//--------------------------------------------------------------------- - -bool OnCalServer::findRunNumInDB(const std::string &DBtable, const int runno) -{ - if (!DBconnection) - { - connectDB(); - } - odbc::Statement *statement = nullptr; - odbc::ResultSet *rs = nullptr; - std::ostringstream cmd; - cmd << "SELECT runnumber FROM " - << DBtable - << " WHERE runnumber = " - << runno; - - statement = DBconnection->createStatement(); - - if (Verbosity() == 1) - { - std::cout << "in function OnCalServer::findRunNumInDB() "; - std::cout << "executing SQL statement ..." << std::endl - << cmd.str() << std::endl; - } - - try - { - rs = statement->executeQuery(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << PHWHERE << " exception caught: " << e.getMessage() << std::endl; - return false; - } - - int entry = 0; - if (rs->next()) - { - try - { - entry = rs->getInt("runnumber"); - } - catch (odbc::SQLException &e) - { - std::cout << PHWHERE << " exception caught: " << e.getMessage() << std::endl; - return false; - } - } - else - { - return false; - } - std::cout << "run number " << entry << " already exists in DB" << std::endl; - return true; -} - -bool OnCalServer::updateDBRunRange(const std::string &table, const std::string &column, const int entry, const int firstrun, const int lastrun) -{ - if (!DBconnection) - { - connectDB(); - } - - odbc::Statement *statement = nullptr; - - std::string command = "UPDATE "; - command += table; - command += " SET "; - command += column; - command += " = "; - command += std::to_string(entry); - command += " WHERE runnumber >= "; - command += std::to_string(firstrun); - command += " and runnumber <= "; - command += std::to_string(lastrun); - - if (Verbosity() == 1) - { - std::cout << "in function OnCalServer::updateDB() ... "; - std::cout << "executin SQL statement ... " << std::endl; - std::cout << command << std::endl; - } - statement = DBconnection->createStatement(); - - try - { - statement->executeUpdate(command); - } - catch (odbc::SQLException &e) - { - std::cout << e.getMessage() << std::endl; - return false; - } - - return true; -} - -//--------------------------------------------------------------------- - -bool OnCalServer::updateDB(const std::string &table, const std::string &column, int entry) -{ - if (!DBconnection) - { - connectDB(); - } - - odbc::Statement *statement = nullptr; - - TString command = "UPDATE "; - command += table; - command += " SET "; - command += column; - command += " = "; - command += entry; - command += " WHERE runnumber = "; - command += runNum; - - if (Verbosity() == 1) - { - std::cout << "in function OnCalServer::updateDB() ... "; - std::cout << "executin SQL statement ... " << std::endl; - std::cout << command.Data() << std::endl; - } - statement = DBconnection->createStatement(); - - try - { - statement->executeUpdate(command.Data()); - } - catch (odbc::SQLException &e) - { - std::cout << e.getMessage() << std::endl; - return false; - } - - return true; -} -//--------------------------------------------------------------------- - -bool OnCalServer::updateDB(const std::string &table, const std::string &column, bool entry) -{ - if (!DBconnection) - { - connectDB(); - } - odbc::Statement *statement = nullptr; - - TString command = "UPDATE "; - command += table; - command += " set "; - command += column; - command += " = '"; - command += static_cast(entry); - command += "' WHERE runnumber = "; - command += runNum; - - if (Verbosity() == 1) - { - std::cout << "in function OnCalServer::updateDB() ... "; - std::cout << "executin SQL statement ... " << std::endl; - std::cout << command.Data() << std::endl; - } - statement = DBconnection->createStatement(); - - try - { - statement->executeUpdate(command.Data()); - } - catch (odbc::SQLException &e) - { - std::cout << e.getMessage() << std::endl; - return false; - } - - return true; -} - -//--------------------------------------------------------------------- - -int OnCalServer::updateDB(const std::string &table, const std::string &column, - const time_t ticks) -{ - if (!DBconnection) - { - connectDB(); - } - odbc::Statement *statement = nullptr; - - std::ostringstream cmd; - statement = DBconnection->createStatement(); - cmd << "UPDATE " - << table - << " set " - << column - << " = " - << ticks - << " WHERE runnumber = " - << runNum; - - if (Verbosity() == 1) - { - std::cout << "in function OnCalServer::updateDB() ... "; - std::cout << "executin SQL statement ... " << std::endl; - std::cout << cmd.str() << std::endl; - } - - try - { - statement->executeUpdate(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << e.getMessage() << std::endl; - return -1; - } - return 0; -} -//--------------------------------------------------------------------- - -bool OnCalServer::updateDB(const std::string &table, const std::string &column, - const std::string &entry, const int runno, const bool append) -{ - if (!DBconnection) - { - connectDB(); - } - - odbc::Statement *statement = nullptr; - - statement = DBconnection->createStatement(); - - std::string comment; - std::ostringstream cmd; - if (append) - { - odbc::ResultSet *rs = nullptr; - std::ostringstream query; - query << "SELECT * FROM " - << table - << " WHERE runnumber = " - << runno; - - try - { - rs = statement->executeQuery(query.str()); - } - catch (odbc::SQLException &e) - { - std::cout << "in function OnCalServer::updateDB() ... "; - std::cout << "run number " << runno << "not found in DB" << std::endl; - std::cout << e.getMessage() << std::endl; - } - - rs->next(); - try - { - comment = rs->getString(column); - comment += " "; // add empty space between comments - } - catch (odbc::SQLException &e) - { - std::cout << "in function OnCalServer::updateDB() ... " << std::endl; - std::cout << "nothing to append." << std::endl; - std::cout << e.getMessage() << std::endl; - } - delete rs; - } - - comment += entry; - cmd << "UPDATE " - << table - << " set " - << column - << " = '" - << comment - << "' WHERE runnumber = " - << runno; - - if (Verbosity() == 1) - { - std::cout << "in function OnCalServer::updateDB() ... "; - std::cout << "executin SQL statement ... " << std::endl; - std::cout << cmd.str() << std::endl; - } - - try - { - statement->executeUpdate(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << e.getMessage() << std::endl; - return false; - } - delete statement; - return true; -} - -//--------------------------------------------------------------------- - -int OnCalServer::check_create_subsystable(const std::string &tablename) -{ - if (!connectDB()) - { - std::cout << "could not connect to " << database << std::endl; - return -1; - } - std::vector > calibrator_columns; - std::vector >::const_iterator coliter; - calibrator_columns.emplace_back("runnumber", "int NOT NULL"); - calibrator_columns.emplace_back("verified", "int default -2"); - calibrator_columns.emplace_back("committed", "int default -2"); - calibrator_columns.emplace_back("date", "timestamp(0) with time zone"); - calibrator_columns.emplace_back("comment", "text"); - calibrator_columns.emplace_back("files", "text"); - calibrator_columns.emplace_back("cvstag", "text"); - calibrator_columns.emplace_back("startvaltime", "bigint"); - calibrator_columns.emplace_back("endvaltime", "bigint"); - calibrator_columns.emplace_back("begintime", "timestamp(0) with time zone"); - calibrator_columns.emplace_back("endtime", "timestamp(0) with time zone"); - - odbc::Statement *stmt = DBconnection->createStatement(); - std::ostringstream cmd; - cmd << "SELECT * FROM " << tablename << " LIMIT 1" << std::ends; - odbc::ResultSet *rs = nullptr; - try - { - rs = stmt->executeQuery(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << "Table " << tablename << " does not exist, will create it" << std::endl; - // std::cout << "Message: " << e.getMessage() << std::endl; - } - if (!rs) - { - cmd.str(""); - cmd << "CREATE TABLE " - << tablename - << "("; - for (coliter = calibrator_columns.begin(); coliter != calibrator_columns.end(); ++coliter) - { - cmd << (*coliter).first << " " << (*coliter).second << ", "; - } - - cmd << "primary key(runnumber))"; - stmt->executeUpdate(cmd.str()); - } - else // check if the all columns exist - { - for (coliter = calibrator_columns.begin(); coliter != calibrator_columns.end(); ++coliter) - { - try - { - rs->findColumn((*coliter).first); - } - catch (odbc::SQLException &e) - { - const std::string &exceptionmessage = e.getMessage(); - if (exceptionmessage.find("not found in result set") != std::string::npos) - { - std::cout << "Column " << (*coliter).first << " does not exist in " - << tablename << ", creating it" << std::endl; - cmd.str(""); - cmd << "ALTER TABLE " - << tablename - << " ADD " - << (*coliter).first - << " " - << (*coliter).second; - try - { - odbc::Statement *stmtup = DBconnection->createStatement(); - stmtup->executeUpdate(cmd.str()); - } - catch (odbc::SQLException &e1) - { - std::cout << PHWHERE << " Exception caught: " << e1.getMessage() << std::endl; - } - } - } - } - delete rs; - } - return 0; -} - -int OnCalServer::add_calibrator_to_statustable(const std::string &calibratorname) -{ - if (!connectDB()) - { - std::cout << "could not connect to " << database << std::endl; - return -1; - } - if (check_calibrator_in_statustable(calibratorname) == 0) - { - return 0; - } - const std::string &calibname = calibratorname; - odbc::Statement *stmt = DBconnection->createStatement(); - std::ostringstream cmd; - cmd.str(""); - cmd << "ALTER TABLE " << successTable << " ADD COLUMN " - << calibname << " int"; - try - { - stmt->executeUpdate(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << "Message: " << e.getMessage() << std::endl; - std::cout << "cmd: " << cmd.str() << std::endl; - exit(1); - } - cmd.str(""); - cmd << "ALTER TABLE " << successTable << " ALTER COLUMN " - << calibname << " SET DEFAULT " << OnCalDBCodes::INIT; - try - { - stmt->executeUpdate(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << "Message: " << e.getMessage() << std::endl; - std::cout << "cmd: " << cmd.str() << std::endl; - exit(1); - } - cmd.str(""); - cmd << "UPDATE " << successTable << " SET " - << calibname << " = " << OnCalDBCodes::INIT; - try - { - stmt->executeUpdate(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << "Message: " << e.getMessage() << std::endl; - std::cout << "cmd: " << cmd.str() << std::endl; - exit(1); - } - - return 0; -} - -int OnCalServer::check_calibrator_in_statustable(const std::string &calibratorname) -{ - // replace this contraption by this sql command which returns 1 row if column exists - // select * from information_schema.columns where table_name = 'oncal_status' and column_name = 'svxstripdeadmapcal'; - if (!connectDB()) - { - std::cout << "could not connect to " << database << std::endl; - return -1; - } - std::string calibname = calibratorname; - odbc::Statement *stmt = DBconnection->createStatement(); - std::ostringstream cmd; - cmd << "SELECT * FROM " << successTable << " LIMIT 1" << std::ends; - odbc::ResultSet *rs = nullptr; - try - { - rs = stmt->executeQuery(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << "Message: " << e.getMessage() << std::endl; - std::cout << "Table " << successTable << " does not exist, your logic is off" << std::endl; - exit(1); - } - odbc::ResultSetMetaData *meta = rs->getMetaData(); - unsigned int nocolumn = rs->getMetaData()->getColumnCount(); - // column names are lower case only, so convert string to lowercase - // The bizarre cast here is needed for newer gccs - transform(calibname.begin(), calibname.end(), calibname.begin(), (int (*)(int)) tolower); - - for (unsigned int i = 1; i <= nocolumn; i++) - { - if (meta->getColumnName(i) == calibname) - { - if (Verbosity() > 0) - { - std::cout << calibname << " is in " << successTable << std::endl; - } - return 0; - } - } - // if we get here, the calibrator is not yet in the table - delete rs; - return -1; -} - -int OnCalServer::check_create_successtable(const std::string &tablename) -{ - if (!connectDB()) - { - std::cout << "could not connect to " << database << std::endl; - return -1; - } - odbc::Statement *stmt = DBconnection->createStatement(); - std::ostringstream cmd; - cmd << "SELECT runnumber FROM " << tablename << " LIMIT 1" << std::ends; - odbc::ResultSet *rs = nullptr; - try - { - rs = stmt->executeQuery(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << "Table " << tablename << " does not exist, will create it" << std::endl; - // std::cout << "Message: " << e.getMessage() << std::endl; - } - if (!rs) - { - cmd.str(""); - cmd << "CREATE TABLE " << tablename << "(runnumber int NOT NULL, " - << "startvaltime bigint, " - << "endvaltime bigint, " - << "beginrun timestamp(0) with time zone, " - << "endrun timestamp(0) with time zone, " - << "comment text, " - << "primary key(runnumber))"; - std::cout << cmd.str() << std::endl; - try - { - stmt->executeUpdate(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << "Error, Message: " << e.getMessage() << std::endl; - // std::cout << "Message: " << e.getMessage() << std::endl; - } - } - return 0; -} - -void OnCalServer::recordDataBase(const bool bookkeep) -{ - recordDB = bookkeep; - if (recordDB) - { - check_create_successtable(successTable); - } - return; -} - -void OnCalServer::BeginTimeStamp(const PHTimeStamp &TimeStp) -{ - beginTimeStamp = TimeStp; - std::cout << "OnCalServer::BeginTimeStamp: Setting BOR TimeStamp to " << beginTimeStamp << std::endl; -} - -void OnCalServer::EndTimeStamp(const PHTimeStamp &TimeStp) -{ - endTimeStamp = TimeStp; - std::cout << "OnCalServer::EndTimeStamp: Setting EOR TimeStamp to " << endTimeStamp << std::endl; -} - -PHTimeStamp * -OnCalServer::GetLastGoodRunTS(OnCal *calibrator, const int irun) -{ - PHTimeStamp *ts = nullptr; - if (!connectDB()) - { - std::cout << "could not connect to " << database << std::endl; - return ts; - } - odbc::Statement *stmt = DBconnection->createStatement(); - std::ostringstream cmd; - std::ostringstream subsystable; - subsystable << "oncal" << calibrator->Name(); - cmd << "SELECT runnumber FROM " << successTable << " where runnumber < " - << irun << " and " - << calibrator->Name() << " > 0 order by runnumber desc limit 1"; - odbc::ResultSet *rs = nullptr; - try - { - rs = stmt->executeQuery(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << "Table " << subsystable.str() << " does not exist" << std::endl; - return ts; - } - if (rs->next()) - { - RunToTime *rt = RunToTime::instance(); - int oldrun = rs->getInt("runnumber"); - ts = rt->getBeginTime(oldrun); - std::cout << "Getting previous good run, current run: " << irun - << ", previous good run: " << oldrun - << " began "; - ts->print(); - std::cout << std::endl; - } - else - { - std::cout << PHWHERE << " No previous good run found for run " << irun << std::endl; - } - delete rs; - return ts; -} - -int OnCalServer::SyncCalibTimeStampsToOnCal(const OnCal *calibrator, const int commit) -{ - std::vector caltab; - calibrator->GetPdbCalTables(caltab); - std::vector::const_iterator iter; - for (iter = caltab.begin(); iter != caltab.end(); ++iter) - { - std::cout << "dealing with table: " << *iter << std::endl; - SyncCalibTimeStampsToOnCal(calibrator, *iter, commit); - } - return 0; -} - -int OnCalServer::SyncCalibTimeStampsToOnCal(const OnCal *calibrator, const std::string &table, const int commit) -{ - std::string name = calibrator->Name(); - odbc::Connection *con = nullptr; - odbc::Connection *concalib = nullptr; - std::ostringstream cmd; - try - { - con = odbc::DriverManager::getConnection(database, "phnxrc", ""); - } - catch (odbc::SQLException &e) - { - std::cout << "Cannot connect to " << database.c_str() << std::endl; - std::cout << e.getMessage() << std::endl; - return -1; - } - try - { - concalib = odbc::DriverManager::getConnection("oncal", "phnxrc", ""); - } - catch (odbc::SQLException &e) - { - std::cout << "Cannot connect to " - << "oncal" << std::endl; - std::cout << e.getMessage() << std::endl; - return -1; - } - odbc::Statement *stmt = nullptr; - try - { - stmt = con->createStatement(); - } - catch (odbc::SQLException &e) - { - std::cout << "Cannot create statement" << std::endl; - std::cout << e.getMessage() << std::endl; - return -1; - } - - odbc::PreparedStatement *stmt1 = nullptr; - odbc::ResultSet *rs1 = nullptr; - try - { - cmd.str(""); - cmd << "SELECT * from " << table << " where startvaltime = ?"; - stmt1 = concalib->prepareStatement(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << "Cannot create statement" << std::endl; - std::cout << e.getMessage() << std::endl; - return -1; - } - - odbc::PreparedStatement *stmtupd = nullptr; - try - { - cmd.str(""); - cmd << "update " << table << " set endvaltime = ? where startvaltime = ?"; - stmtupd = concalib->prepareStatement(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << "Cannot create statement" << std::endl; - std::cout << e.getMessage() << std::endl; - return -1; - } - - cmd.str(""); - cmd << "select * from " - << successTable - << " where " - << name - << " > 0"; - // << " > 0 and runnumber < 150000"; - odbc::ResultSet *rs = nullptr; - try - { - rs = stmt->executeQuery(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << "Message: " << e.getMessage() << std::endl; - return -1; - } - while (rs->next()) - { - int run = rs->getInt("runnumber"); - int startticks = rs->getLong("startvaltime"); - int endticks = rs->getLong("endvaltime"); - // int status = rs->getInt(name); - // std::cout << "run: " << run - // << ", status: " << status - // << ", startticks: " << startticks - // << ", endticks: " << endticks << std::endl; - stmt1->setInt(1, startticks); - try - { - rs1 = stmt1->executeQuery(); - } - catch (odbc::SQLException &e) - { - std::cout << "Message: " << e.getMessage() << std::endl; - return -1; - } - int ionce = 0; - int isproblem = 0; - int calibendval = 0; - while (rs1->next()) - { - calibendval = rs1->getInt("endvaltime"); - if (endticks != rs1->getInt("endvaltime")) - { - if (!isproblem) - { - std::cout << "endvaltime problem with run " << run << std::endl; - std::cout << "endvaltime from oncal_status: " << endticks << std::endl; - std::cout << "startvaltime from oncal_status: " << startticks << std::endl; - std::cout << "endvaltime from calibrations DB: " << rs1->getInt("endvaltime") << std::endl; - if (endticks < rs1->getInt("endvaltime")) - { - std::cout << "ENDTICKS smaller CALIB" << std::endl; - // return -1; - } - } - isproblem = 1; - } - else - { - if (isproblem) - { - std::cout << "endvaltime changes, check run " << run << std::endl; - // return -1; - } - } - // std::cout << "starttime: " << rs1->getInt("startvaltime") << std::endl; - // std::cout << "endtime: " << rs1->getInt("endvaltime") << std::endl; - ionce++; - } - if (isproblem) - { - std::cout << "Adjusting run " << run << std::endl; - std::cout << "changing endvaltime from " << calibendval - << " to " << endticks << std::endl; - if (commit) - { - stmtupd->setInt(1, endticks); - stmtupd->setInt(2, startticks); - stmtupd->executeUpdate(); - } - } - if (!ionce) - { - std::cout << "Run " << run << " not found" << std::endl; - } - delete rs1; - } - delete rs; - delete con; - delete concalib; - return 0; -} - -int OnCalServer::SyncOncalTimeStampsToRunDB(const int commit) -{ - odbc::Connection *con = nullptr; - RunToTime *rt = RunToTime::instance(); - std::ostringstream cmd; - try - { - con = odbc::DriverManager::getConnection(database, "phnxrc", ""); - } - catch (odbc::SQLException &e) - { - std::cout << "Cannot connect to " << database.c_str() << std::endl; - std::cout << e.getMessage() << std::endl; - return -1; - } - odbc::Statement *stmt = nullptr; - try - { - stmt = con->createStatement(); - } - catch (odbc::SQLException &e) - { - std::cout << "Cannot create statement" << std::endl; - std::cout << e.getMessage() << std::endl; - return -1; - } - - odbc::PreparedStatement *stmtupd = nullptr; - try - { - cmd.str(""); - cmd << "UPDATE oncal_status set endvaltime = ? where runnumber = ?"; - stmtupd = con->prepareStatement(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << "Cannot create statement" << std::endl; - std::cout << e.getMessage() << std::endl; - return -1; - } - - cmd.str(""); - cmd << "select * from " - << successTable; //<< " where runnumber > 160000"; - odbc::ResultSet *rs = nullptr; - try - { - rs = stmt->executeQuery(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << "Message: " << e.getMessage() << std::endl; - return -1; - } - while (rs->next()) - { - int run = rs->getInt("runnumber"); - int startticks = rs->getLong("startvaltime"); - int endticks = rs->getLong("endvaltime"); - int rtstartticks = 0; - int rtendticks = 0; - PHTimeStamp *rtstart = rt->getBeginTime(run); - PHTimeStamp *rtend = rt->getEndTime(run); - if (rtstart) - { - rtstartticks = rtstart->getTics(); - delete rtstart; - } - if (rtend) - { - rtendticks = rtend->getTics(); - delete rtend; - } - if (rtstartticks != startticks) - { - std::cout << "Run " << run - << ": Start mismatch, oncal: " << startticks - << ", rt: " << rtstartticks << std::endl; - } - if (rtendticks != endticks) - { - // exclude starttime=endtime in runtotime (some crashed calibrations can do this) - // in this case the calibration adds 1 sec to starttime - if (rtstartticks != rtendticks) - { - std::cout << "Run " << run - << ": End mismatch, oncal: " << endticks - << ", rt: " << rtendticks << std::endl; - if (endticks > rtendticks) - { - std::cout << "BAD: endticks: " << endticks - << ", rtendticks: " << rtendticks - << std::endl; - return -1; - } - if (commit) - { - stmtupd->setLong(1, rtendticks); - stmtupd->setLong(2, run); - stmtupd->executeUpdate(); - } - } - else - { - if (startticks != endticks - 1) - { - std::cout << "Run " << run - << ": Start/End mismatch, Start: " << startticks - << ", End: " << endticks << std::endl; - endticks = startticks + 1; - if (commit) - { - stmtupd->setLong(1, endticks); - stmtupd->setLong(2, run); - stmtupd->executeUpdate(); - } - } - else - { - if (Verbosity() > 0) - { - std::cout << "run " << run << " was twiddled by OnCal" << std::endl; - } - } - } - } - // std::cout << "run: " << run - // << ", status: " << status - // << ", startticks: " << startticks - // << ", endticks: " << endticks << std::endl; - } - delete rs; - delete con; - return 0; -} - -int OnCalServer::CopyTables(const OnCal *calibrator, const int FromRun, const int ToRun, const int commit) -{ - int iret = calibrator->CopyTables(FromRun, ToRun, commit); - return iret; -} - -int OnCalServer::CreateCalibration(OnCal *calibrator, const int myrunnumber, const std::string &what, const int commit) -{ - int iret = -1; - runNum = myrunnumber; - SetBorTime(myrunnumber); - SetEorTime(myrunnumber); - if (!connectDB()) - { - std::cout << "could not connect to " << database << std::endl; - return -1; - } - add_calibrator_to_statustable(calibrator->Name()); - std::string table = "OnCal"; - table += calibrator->Name(); - check_create_subsystable(table); - odbc::Statement *stmt = DBconnection->createStatement(); - std::ostringstream cmd; - - cmd << "SELECT runnumber FROM " - << successTable << " where runnumber = " - << myrunnumber; - odbc::ResultSet *rs = nullptr; - try - { - rs = stmt->executeQuery(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << "Table " << successTable << " does not exist" << std::endl; - return -1; - } - if (!rs->next()) - { - insertRunNumInDB(successTable, myrunnumber); - } - delete rs; - cmd.str(""); - cmd << "SELECT runnumber FROM " - << successTable << " where runnumber = " - << myrunnumber << " and " - << calibrator->Name() << " <= 0"; - try - { - rs = stmt->executeQuery(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << PHWHERE << " Exception caught, Message: " - << e.getMessage() << std::endl; - return -1; - } - if (rs->next() || testmode) - { - std::string tablecomment = "Subsytem provided"; - iret = calibrator->CreateCalibration(runnumber, what, tablecomment, commit); - if (!iret) - { - std::cout << "Comment: " << tablecomment << std::endl; - std::cout << "updating oncal status tables for " << runnumber << std::endl; - if (commit) - { - CreateCalibrationUpdateStatus(calibrator, table, tablecomment, OnCalDBCodes::SUBSYSTEM); - } - } - else - { - std::cout << "Calibratior " << calibrator->Name() << " for run " << runnumber << " failed" << std::endl; - if (commit) - { - CreateCalibrationUpdateStatus(calibrator, table, tablecomment, OnCalDBCodes::FAILED); - } - } - } - else - { - std::cout << PHWHERE << " Run " << runnumber << " is already successfully calibrated for " - << calibrator->Name() << std::endl; - } - return iret; -} - -void OnCalServer::CreateCalibrationUpdateStatus(OnCal *calibrator, const std::string &table, const std::string &tablecomment, const int dbcode) -{ - updateDB(successTable, calibrator->Name(), dbcode); - insertRunNumInDB(table, RunNumber()); - updateDB(table, "comment", tablecomment, RunNumber(), true); - std::ostringstream stringarg; - stringarg.str(""); - stringarg << calibrator->CommitedToPdbCalOK(); - updateDB(table, "committed", stringarg.str(), RunNumber()); - stringarg.str(""); - stringarg << calibrator->VerificationOK(); - updateDB(table, "verified", stringarg.str(), RunNumber()); - odbc::Timestamp stp(time(nullptr)); - updateDB(table, "date", stp.toString(), RunNumber()); - time_t beginticks = beginTimeStamp.getTics(); - stringarg.str(""); - stringarg << beginticks; - updateDB(table, "startvaltime", stringarg.str(), RunNumber()); - stp.setTime(beginticks); - updateDB(table, "begintime", stp.toString(), RunNumber()); - time_t endticks = endTimeStamp.getTics(); - stringarg.str(""); - stringarg << endticks; - updateDB(table, "endvaltime", stringarg.str(), RunNumber()); - stp.setTime(endticks); - updateDB(table, "endtime", stp.toString(), RunNumber()); - updateDB(table, "cvstag", cvstag, RunNumber()); - std::vector flist = calibrator->GetLocalFileList(); - if (!flist.empty()) - { - std::string filelist; - for (const std::string &infile : flist) - { - filelist += infile; - filelist += " "; - } - filelist.pop_back(); // strip empty space at end from loop - std::cout << "FileList: " << filelist << std::endl; - updateDB(table, "files", filelist, RunNumber()); - } - return; -} - -int OnCalServer::ClosestGoodRun(OnCal *calibrator, const int irun, const int previous) -{ - RunToTime *rt = RunToTime::instance(); - PHTimeStamp *ts = rt->getBeginTime(irun); - if (!ts) - { - std::cout << PHWHERE << "Unknown Run " << irun << std::endl; - return -1; - } - int curstart = ts->getTics(); - delete ts; - ts = rt->getEndTime(irun); - int curend = curstart; - if (ts) - { - curend = ts->getTics(); - delete ts; - } - int closestrun = -1; - if (!connectDB()) - { - std::cout << "could not connect to " << database << std::endl; - return -1; - } - odbc::Statement *stmt = DBconnection->createStatement(); - std::ostringstream cmd; - - // look only for runs which were actually successfully calibrated (status = 1) - cmd << "SELECT runnumber,startvaltime,endvaltime FROM " - << successTable << " where runnumber < " - << irun << " and " - << calibrator->Name() << " = 1 order by runnumber desc limit 1"; - odbc::ResultSet *rs = nullptr; - try - { - rs = stmt->executeQuery(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << "Table " << successTable << " does not exist" << std::endl; - return -1; - } - int prevrun = -1; - unsigned int prevend = 0; - if (rs->next()) - { - prevrun = rs->getInt("runnumber"); - unsigned int prevstart = rs->getLong("startvaltime"); - prevend = rs->getLong("endvaltime"); - std::cout << "previous run: " << prevrun - << ", start: " << prevstart - << ", end: " << prevend - << std::endl; - } - else - { - if (Verbosity() > 0) - { - std::cout << PHWHERE << " No previous good run found for run " << irun << std::endl; - } - } - delete rs; - closestrun = prevrun; - if (previous == fetchrun::PREVIOUS) - { - if (Verbosity() > 0) - { - std::cout << "Closest previous run is " << closestrun << std::endl; - } - return closestrun; - } - cmd.str(""); - cmd << "SELECT runnumber,startvaltime,endvaltime FROM " - << successTable << " where runnumber > " - << irun << " and " - << calibrator->Name() << " = 1 order by runnumber asc limit 1"; - try - { - rs = stmt->executeQuery(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << "Table " << successTable << " does not exist" << std::endl; - return -1; - } - int nextrun = -1; - unsigned int nextstart = 0; - if (rs->next()) - { - nextrun = rs->getInt("runnumber"); - nextstart = rs->getLong("startvaltime"); - unsigned int nextend = rs->getLong("endvaltime"); - if (Verbosity() > 0) - { - std::cout << "next run: " << nextrun - << ", start: " << nextstart - << ", end: " << nextend - << std::endl; - } - } - else - { - if (Verbosity() > 0) - { - std::cout << PHWHERE << " No next good run found for run " << irun << std::endl; - } - } - delete rs; - int tdiffprev = curstart - prevend; - int tdiffnext; - if (nextstart > 0) - { - tdiffnext = nextstart - curend; - } - else - { - // just make it larger then previous run time diff - tdiffnext = tdiffprev + 1; - } - if (Verbosity() > 0) - { - std::cout << "diff prev: " << tdiffprev - << ", next: " << tdiffnext - << std::endl; - } - if (tdiffprev < tdiffnext) - { - closestrun = prevrun; - } - else - { - closestrun = nextrun; - } - if (Verbosity() > 0) - { - std::cout << "closest run: " << closestrun << std::endl; - } - return closestrun; -} - -int OnCalServer::OverwriteCalibration(OnCal *calibrator, const int runno, const int commit, const int FromRun) -{ - if (FromRun < 0) - { - return -1; - } - int iret = CopyTables(calibrator, FromRun, runno, commit); - return iret; -} - -int OnCalServer::FixMissingCalibration(OnCal *calibrator, const int runno, const int commit, const int fromrun) -{ - int iret = -1; - // find this run in oncal_status - if (!connectDB()) - { - std::cout << "could not connect to " << database << std::endl; - return -1; - } - runNum = runno; - odbc::Statement *stmt = DBconnection->createStatement(); - std::ostringstream cmd; - - cmd << "SELECT runnumber FROM " - << successTable << " where runnumber = " - << runno; - odbc::ResultSet *rs = nullptr; - try - { - rs = stmt->executeQuery(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << "Table " << successTable << " does not exist" << std::endl; - return -1; - } - if (!rs->next()) - { - insertRunNumInDB(successTable, runNum); - } - delete rs; - cmd.str(""); - cmd << "SELECT runnumber FROM " - << successTable << " where runnumber = " - << runno << " and " - << calibrator->Name() << " <= 0"; - try - { - rs = stmt->executeQuery(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << PHWHERE << " Exception caught, Message: " - << e.getMessage() << std::endl; - return -1; - } - if (rs->next()) - { - int FromRun; - if (fromrun > 0) - { - FromRun = fromrun; - } - else - { - FromRun = ClosestGoodRun(calibrator, runno); - if (FromRun < 0) - { - std::cout << "ClosestGoodRun returned bad runnumber: " << FromRun << std::endl; - return -1; - } - } - std::cout << "Going to copy calibration for run " << runno - << " from run " << FromRun << std::endl; - - iret = OverwriteCalibration(calibrator, runno, commit, FromRun); - if (!iret) - { - int newstatus = 0; - if (FromRun < runno) - { - newstatus = OnCalDBCodes::COPIEDPREVIOUS; - } - else - { - newstatus = OnCalDBCodes::COPIEDLATER; - } - std::string table = "OnCal"; - table += calibrator->Name(); - std::ostringstream comment; - comment << " CopiedRun(" << FromRun << ")"; - std::cout << "updating oncal status tables for " << runno << std::endl; - if (commit) - { - updateDB(successTable, calibrator->Name(), newstatus); - insertRunNumInDB(table, runNum); - updateDB(table, "comment", comment.str(), runNum, true); - updateDB(table, "committed", true); - } - } - } - else - { - std::cout << "Run " << runno - << " has a good calibrations, doing nothing" << std::endl; - } - delete rs; - return iret; -} - -int OnCalServer::SetBorTime(const int runno) -{ - // recoConsts *rc = recoConsts::instance(); - RunToTime *runTime = RunToTime::instance(); - - PHTimeStamp *BorTimeStp(runTime->getBeginTime(runno)); - if (!BorTimeStp) - { - std::cout << PHWHERE << "Cannot get begin time for run " << runno << std::endl; - std::cout << "Exiting" << std::endl; - exit(1); - } - BeginTimeStamp(*BorTimeStp); - - // enter begin run timestamp into rc flags - PHTimeStamp BeginRunTimeStamp(*BorTimeStp); - // rc->set_TimeStamp(BeginRunTimeStamp); - std::cout << "OnCalServer::SetBorTime from RunToTime was found for run : " << runno << " to "; - BeginRunTimeStamp.print(); - std::cout << std::endl; - - delete BorTimeStp; - return 0; -} - -int OnCalServer::SetEorTime(const int runno) -{ - // recoConsts *rc = recoConsts::instance(); - RunToTime *runTime = RunToTime::instance(); - - time_t eorticks = 0; - - time_t borticks = 0; //(rc->get_TimeStamp()).getTics(); - PHTimeStamp *EorTimeStp(runTime->getEndTime(runno)); - if (EorTimeStp) - { - eorticks = EorTimeStp->getTics(); - } - else - { - EorTimeStp = new PHTimeStamp(eorticks); - } - // if end of run timestamp missing or smaller-equal borstamp eor = bor+1 sec - if (eorticks <= borticks) - { - eorticks = borticks + 1; - EorTimeStp->setTics(eorticks); - } - EndTimeStamp(*EorTimeStp); - std::cout << "OnCalServer::SetEorTime: setting eor time to "; - EorTimeStp->print(); - std::cout << std::endl; - delete EorTimeStp; - return 0; -} - -int OnCalServer::GetRunTimeTicks(const int runno, time_t &borticks, time_t &eorticks) -{ - RunToTime *runTime = RunToTime::instance(); - PHTimeStamp *TimeStp(runTime->getBeginTime(runno)); - if (!TimeStp) - { - std::cout << PHWHERE << "Cannot get begin time for run " << runno << std::endl; - std::cout << "Exiting" << std::endl; - exit(1); - } - borticks = TimeStp->getTics(); - delete TimeStp; - TimeStp = runTime->getEndTime(runno); - if (TimeStp) - { - eorticks = TimeStp->getTics(); - delete TimeStp; - } - else - { - eorticks = 0; - } - // if end of run timestamp missing or smaller-equal borstamp eor = bor+1 sec - if (eorticks <= borticks) - { - eorticks = borticks + 1; - } - return 0; -} - -int OnCalServer::requiredCalibration(SubsysReco *reco, const std::string &calibratorname) -{ - std::map >::iterator iter; - if (check_calibrator_in_statustable(calibratorname)) - { - std::cout << PHWHERE << " the calibrator " << calibratorname << " is unknown to me" << std::endl; - return -1; - } - iter = requiredCalibrators.find(calibratorname); - if (iter != requiredCalibrators.end()) - { - iter->second.insert(reco); - } - else - { - std::set subsys; - subsys.insert(reco); - requiredCalibrators[calibratorname] = subsys; - } - return 0; -} - -int OnCalServer::FindClosestCalibratedRun(const int irun) -{ - RunToTime *rt = RunToTime::instance(); - PHTimeStamp *ts = rt->getBeginTime(irun); - if (!ts) - { - std::cout << PHWHERE << "Unknown Run " << irun << std::endl; - return -1; - } - if (requiredCalibrators.empty()) - { - std::cout << PHWHERE << "No required calibrations given" << std::endl; - return irun; - } - int curstart = ts->getTics(); - delete ts; - ts = rt->getEndTime(irun); - int curend = curstart; - if (ts) - { - curend = ts->getTics(); - delete ts; - } - int closestrun = -1; - if (!connectDB()) - { - std::cout << "could not connect to " << database << std::endl; - return -1; - } - odbc::Statement *stmt = DBconnection->createStatement(); - std::ostringstream cmd; - std::map >::const_iterator iter; - // look only for runs which were actually successfully calibrated (status = 1) - cmd << "SELECT runnumber,startvaltime,endvaltime FROM " - << successTable << " where runnumber <= " - << irun; - for (iter = requiredCalibrators.begin(); iter != requiredCalibrators.end(); ++iter) - { - cmd << " and " << iter->first << " > 0 "; - } - - cmd << " order by runnumber desc limit 1"; - odbc::ResultSet *rs = nullptr; - try - { - rs = stmt->executeQuery(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << "Table " << successTable << " does not exist" << std::endl; - return -1; - } - int prevrun = 0; - unsigned int prevend = 0; - if (rs->next()) - { - prevrun = rs->getInt("runnumber"); - unsigned int prevstart = rs->getLong("startvaltime"); - prevend = rs->getLong("endvaltime"); - if (prevrun != irun) - { - std::cout << "previous run: " << prevrun - << ", start: " << prevstart - << ", end: " << prevend - << std::endl; - } - } - else - { - std::cout << PHWHERE << " No previous good run found for run " << irun << std::endl; - } - delete rs; - // if the current run fullfills requirements return immediately - if (prevrun == irun) - { - std::cout << "closest run with required calibs is current run: " << irun << std::endl; - return irun; - } - cmd.str(""); - cmd << "SELECT runnumber,startvaltime,endvaltime FROM " - << successTable << " where runnumber > " - << irun; - for (iter = requiredCalibrators.begin(); iter != requiredCalibrators.end(); ++iter) - { - cmd << " and " << iter->first << " > 0 "; - } - - cmd << " order by runnumber asc limit 1"; - try - { - rs = stmt->executeQuery(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << "Table " << successTable << " does not exist" << std::endl; - return -1; - } - int nextrun = 0; - unsigned int nextstart = 0; - if (rs->next()) - { - nextrun = rs->getInt("runnumber"); - nextstart = rs->getLong("startvaltime"); - unsigned int nextend = rs->getLong("endvaltime"); - std::cout << "next run: " << nextrun - << ", start: " << nextstart - << ", end: " << nextend - << std::endl; - } - else - { - std::cout << PHWHERE << " No next good run found for run " << irun << std::endl; - } - delete rs; - int tdiffprev = curstart - prevend; - int tdiffnext; - if (nextstart > 0) - { - tdiffnext = nextstart - curend; - } - else - { - // just make it larger then previous run time diff - tdiffnext = tdiffprev + 1; - } - if (tdiffprev < tdiffnext) - { - closestrun = prevrun; - } - else - { - closestrun = nextrun; - } - std::cout << "closest run with required calibs: " << closestrun << std::endl; - return closestrun; -} - -int OnCalServer::FillRunListFromFileList() -{ - for (Fun4AllSyncManager *sync : SyncManagers) - { - for (Fun4AllInputManager *inmgr : sync->GetInputManagers()) - { - for (const std::string &infile : inmgr->GetFileList()) - { - std::pair runseg = Fun4AllUtils::GetRunSegment(infile); - runlist.insert(runseg.first); - } - } - } - return 0; -} - -int OnCalServer::AdjustRichTimeStampForMultipleRuns() -{ - int firstrun = *runlist.begin(); - int lastrun = *runlist.rbegin(); - time_t dummy; - time_t beginticks; - time_t endticks; - std::string table = "OnCalRichCal"; - check_create_subsystable(table); - GetRunTimeTicks(firstrun, beginticks, dummy); - GetRunTimeTicks(lastrun, dummy, endticks); - std::ostringstream stringarg; - stringarg << OnCalDBCodes::COVERED; - // std::set::const_iterator runiter; - /* - for (runiter = runlist.begin(); runiter != runlist.end(); runiter++) - { - updateDB(successTable, "RichCal", stringarg.str(), *runiter); - } - stringarg.str(""); - stringarg << OnCalDBCodes::SUCCESS; - - updateDB(successTable, "RichCal", stringarg.str(), firstrun); - */ - odbc::Timestamp stp; - stringarg.str(""); - stringarg << beginticks; - updateDB(table, "startvaltime", stringarg.str(), firstrun); - stp.setTime(beginticks); - updateDB(table, "begintime", stp.toString(), firstrun); - stringarg.str(""); - stringarg << endticks; - updateDB(table, "endvaltime", stringarg.str(), firstrun); - stp.setTime(endticks); - updateDB(table, "endtime", stp.toString(), firstrun); - /* - std::string tablename = "calibrichadc"; - odbc::Connection *con = 0; - std::ostringstream cmd; - try - { - con = odbc::DriverManager::getConnection("oncal", "phnxrc", ""); - } - catch (odbc::SQLException& e) - { - std::cout << "Cannot connect to " << database.c_str() << std::endl; - std::cout << e.getMessage() << std::endl; - return -1; - } - odbc::Statement *stmt = 0; - odbc::Statement *stmtup = 0; - try - { - stmt = con->createStatement(); - stmtup = con->createStatement(); - } - catch (odbc::SQLException& e) - { - std::cout << "Cannot create statement" << std::endl; - std::cout << e.getMessage() << std::endl; - return -1; - } - - odbc::ResultSet *rs1 = 0; - cmd.str(""); - cmd << "SELECT endvaltime from " << tablename - << " where bankid = 1 and startvaltime = " << beginticks; - std::cout << "sql cmd: " << cmd.str() << std::endl; - try - { - rs1 = stmt->executeQuery(cmd.str()); - } - catch (odbc::SQLException& e) - { - std::cout << "Cannot create statement" << std::endl; - std::cout << e.getMessage() << std::endl; - return -1; - } - if (rs1->next()) - { - std::cout << "Endcaltime: " << rs1->getInt("endvaltime") << std::endl; - std::cout << "future endvaltime: " << endticks << std::endl; - cmd.str(""); - cmd << "Update " << tablename - << " set endvaltime = " << endticks - << " where bankid = 1 and startvaltime = " - << beginticks; - stmtup->executeUpdate(cmd.str()); - - } - else - { - std::cout << "Could not find startvaltime " << beginticks - << "from run " << firstrun << std::endl; - } - - */ - - return 0; -} - -int OnCalServer::GetCalibStatus(const std::string &calibname, const int runno) -{ - int iret = -3; - if (!connectDB()) - { - std::cout << "could not connect to " << database << std::endl; - return -4; - } - odbc::Statement *stmt = DBconnection->createStatement(); - std::ostringstream cmd; - - // look only for runs which were actually successfully calibrated (status = 1) - cmd << "SELECT " << calibname << " FROM " - << successTable << " where runnumber = " - << runno; - std::cout << "exec " << cmd.str() << std::endl; - odbc::ResultSet *rs = nullptr; - try - { - rs = stmt->executeQuery(cmd.str()); - } - catch (odbc::SQLException &e) - { - std::cout << "Table " << successTable << " does not exist" << std::endl; - return -5; - } - if (rs->next()) - { - iret = rs->getInt(calibname); - } - else - { - std::cout << PHWHERE << " No calib status for " << calibname - << " for " << runno << std::endl; - } - delete rs; - return iret; -} - -void OnCalServer::TestMode(const int i) -{ - const char *logname = getenv("LOGNAME"); - if (logname) - { - if (strcmp(logname, "sphnxpro") == 0 || strcmp(logname, "anatrain") == 0) - { - std::cout << "phnxcal,anatrain account is not allowed to run in testmode" << std::endl; - } - else - { - testmode = i; - } - } - else - { - std::cout << "could not get account via env var LOGNAME, not setting testmode" << std::endl; - } - return; -} diff --git a/calibrations/framework/oncal/OnCalServer.h b/calibrations/framework/oncal/OnCalServer.h deleted file mode 100644 index 890901207c..0000000000 --- a/calibrations/framework/oncal/OnCalServer.h +++ /dev/null @@ -1,140 +0,0 @@ -#ifndef ONCAL_ONCALSERVER_H -#define ONCAL_ONCALSERVER_H - -#include -#include - -#include // for time_t -#include -#include -#include -#include - -class OnCal; -class SubsysReco; -class TH1; - -namespace fetchrun -{ - enum - { - CLOSEST, - PREVIOUS - }; -}; - -class OnCalServer : public Fun4AllServer -{ - public: - static OnCalServer *instance(); - ~OnCalServer() override; - using Fun4AllServer::registerHisto; - void registerHisto(TH1 *h1d, OnCal *Calibrator, const int replace = 0); - void unregisterHisto(const std::string &calibratorname); - void Print(const std::string &what = "ALL") const override; - - void dumpHistos(); - int process_event() override; - int BeginRun(const int runno) override; - int EndRun(const int /*runno*/) override { return 0; } // do not execute EndRun - int End() override; - - PHTimeStamp *GetEndValidityTS(); - - PHTimeStamp *GetBeginValidityTS(); - void printStamps(); - PHTimeStamp *GetLastGoodRunTS(OnCal *calibrator, const int irun); - - void recordDataBase(const bool bookkeep = false); - - // RunNumber() tells the server which run is being analyzed. - // and if recordDB is true, this will insert the run number in - // calprocess_stat table in calBookKeep database. - // All updates are made to the row in the database containing this runNum. - // Note that the run number is the primary key in the tables. - // If calBookKeep database is not to be updated, this function - // should not be called. - void RunNumber(const int runnum); - int RunNumber() const { return runNum; } - - void BeginTimeStamp(const PHTimeStamp &TimeStp); - void EndTimeStamp(const PHTimeStamp &TimeStp); - - int SyncCalibTimeStampsToOnCal(const OnCal *calibrator, const std::string &table, const int commit = 0); - int SyncCalibTimeStampsToOnCal(const OnCal *calibrator, const int commit = 0); - int SyncOncalTimeStampsToRunDB(const int commit = 0); - int ClosestGoodRun(OnCal *calibrator, const int irun, const int previous = fetchrun::CLOSEST); - static int CopyTables(const OnCal *calibrator, const int FromRun, const int ToRun, const int commit = 0); - static int OverwriteCalibration(OnCal *calibrator, const int runno, const int commit = 0, const int fromrun = -1); - int FixMissingCalibration(OnCal *calibrator, const int runno, const int commit = 0, const int fromrun = -1); - - int SetBorTime(const int runno); - int SetEorTime(const int runno); - int requiredCalibration(SubsysReco *reco, const std::string &calibratorname); - int FindClosestCalibratedRun(const int irun); - int FillRunListFromFileList(); - int AdjustRichTimeStampForMultipleRuns(); - int CreateCalibration(OnCal *calibrator, const int myrunnumber, const std::string &what, const int commit = 0); - int GetCalibStatus(const std::string &calibname, const int runno); - static int DisconnectDB(); - void TestMode(const int i = 1); - // need to be able to call this from the outside - bool updateDBRunRange(const std::string &table, const std::string &column, const int entry, const int firstrun, const int lastrun); - void EventCheckFrequency(const unsigned int i) { eventcheckfrequency = i; } - - protected: - //------------------------------------- - // following functions access DB using odbc++ library - // these are designed to insert status in calBookKeep (or success) database. - // setDB() sets the name of the database to connect to. e.g., calibration - // this database should exist in the odbc.ini file. - // void setDB(const char* DBname){database = DBname;} - bool connectDB(); - - // insertRunNumInDB enters the run number in the calBookKeep database. - // All other updates are made to rows in the database containing the runNum. - // This function should be called before any updates are made. - // Returns true on successful DB insert. - bool insertRunNumInDB(const std::string &DBtable, const int runno); - - bool findRunNumInDB(const std::string &DBtable, const int runno); - - // these functions update different columns in the success database tables. - // Ony the row with the run number set by setRunNum() is updated. - - bool updateDB(const std::string &table, const std::string &column, int entry); - bool updateDB(const std::string &table, const std::string &column, bool entry); - bool updateDB(const std::string &table, const std::string &column, const std::string &entry, - const int runno, const bool append = false); - int updateDB(const std::string &table, const std::string &column, const time_t ticks); - - int check_create_subsystable(const std::string &tablename); - int check_create_successtable(const std::string &tablename); - int add_calibrator_to_statustable(const std::string &calibratorname); - int check_calibrator_in_statustable(const std::string &calibratorname); - static int GetRunTimeTicks(const int runno, time_t &borticks, time_t &eorticks); - void CreateCalibrationUpdateStatus(OnCal *calibrator, const std::string &table, const std::string &tablecomment, const int dbcode); - OnCalServer(const std::string &name = "OnCalServer"); - PHTimeStamp beginTimeStamp; // begin run timestamp of run analysing - PHTimeStamp endTimeStamp; // end run timestamp of run analysing - int testmode{0}; - bool recordDB{false}; - TH1 *OnCalServerVars{nullptr}; - std::map Histo; - std::map > calibratorhistomap; - bool SetEndTimeStampByHand{false}; - bool SetBeginTimeStampByHand{false}; - - std::string successTable; - unsigned int runNum{0}; - unsigned int nEvents{0}; - unsigned int eventcheckfrequency{1000}; - std::string database{"calBookKeep"}; // this holds the name of the database - // should be set to calibrations for normal running - std::map > requiredCalibrators; - std::vector analysed_runs; - std::vector inputfilelist; - std::set runlist; -}; - -#endif /* __ONCALSERVER_H */ diff --git a/calibrations/framework/oncal/autogen.sh b/calibrations/framework/oncal/autogen.sh deleted file mode 100755 index dea267bbfd..0000000000 --- a/calibrations/framework/oncal/autogen.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -srcdir=`dirname $0` -test -z "$srcdir" && srcdir=. - -(cd $srcdir; aclocal -I ${OFFLINE_MAIN}/share;\ -libtoolize --force; automake -a --add-missing; autoconf) - -$srcdir/configure "$@" diff --git a/calibrations/framework/oncal/configure.ac b/calibrations/framework/oncal/configure.ac deleted file mode 100644 index e5467a38b0..0000000000 --- a/calibrations/framework/oncal/configure.ac +++ /dev/null @@ -1,16 +0,0 @@ -AC_INIT(oncal,[2.00]) -AC_CONFIG_SRCDIR([configure.ac]) - -AM_INIT_AUTOMAKE - -AC_PROG_CXX(CC g++) - -LT_INIT([disable-static]) - -dnl no point in suppressing warnings people should -dnl at least see them, so here we go for g++: -Wall -if test $ac_cv_prog_gxx = yes; then - CXXFLAGS="$CXXFLAGS -Wall -Wextra -Wshadow -Werror" -fi - -AC_OUTPUT(Makefile) From dfe01e0187ff9d1492c33ac0890b8e81b328ad7e Mon Sep 17 00:00:00 2001 From: bkimelman Date: Fri, 6 Feb 2026 10:44:52 -0500 Subject: [PATCH 184/393] Changes to fix issues identified by coderabbit and clang-tidy --- offline/packages/tpc/LaserClusterizer.cc | 39 +++++++++++-------- .../tpccalib/TpcCentralMembraneMatching.cc | 9 +++-- .../tpccalib/TpcCentralMembraneMatching.h | 7 ++++ .../packages/tpccalib/TpcLaminationFitting.cc | 12 +++--- .../packages/tpccalib/TpcLaminationFitting.h | 11 +++++- 5 files changed, 51 insertions(+), 27 deletions(-) diff --git a/offline/packages/tpc/LaserClusterizer.cc b/offline/packages/tpc/LaserClusterizer.cc index 8ffaa10433..a875747201 100644 --- a/offline/packages/tpc/LaserClusterizer.cc +++ b/offline/packages/tpc/LaserClusterizer.cc @@ -47,6 +47,7 @@ #include #include #include // for _Rb_tree_cons... +#include #include #include #include @@ -145,7 +146,7 @@ namespace return par[0] * g * cdf; } - void splitWeaklyConnectedRegion(const std::vector ®ion, std::vector> &outputRegions) + void splitWeaklyConnectedRegion(const std::vector ®ion, std::vector> &outputRegions, int aVerbosity) { int N = region.size(); std::vector> adj(N); @@ -153,7 +154,7 @@ namespace { for(int j=i+1; j() + neigh.get<0>() - region[j].first.get<0>()) < 0.01 && fabs(region[i].first.get<1>() + neigh.get<1>() - region[j].first.get<1>()) < 0.01 && @@ -167,9 +168,11 @@ namespace } } - std::cout << " constructed adjacency list, average degree = " << std::accumulate(adj.begin(), adj.end(), 0.0, [](double s, auto &v) { return s + v.size(); }) / N << ")" << std::endl; + if(aVerbosity > 3) std::cout << " constructed adjacency list, average degree = " << std::accumulate(adj.begin(), adj.end(), 0.0, [](double s, auto &v) { return s + v.size(); }) / N << ")" << std::endl; - std::vector disc(N, -1), low(N, -1), parent(N, -1); + std::vector disc(N, -1); + std::vector low(N, -1); + std::vector parent(N, -1); std::vector> bridges; int time=0; @@ -200,7 +203,7 @@ namespace if(disc[i] == -1) dfs(i); } - std::cout << " Found " << bridges.size() << " bridges in region of size " << N << std::endl; + if(aVerbosity > 2) std::cout << " Found " << bridges.size() << " bridges in region of size " << N << std::endl; std::vector> adj2 = adj; int removed = 0; @@ -211,11 +214,11 @@ namespace adj2[u].erase(std::remove(adj2[u].begin(), adj2[u].end(), v), adj2[u].end()); adj2[v].erase(std::remove(adj2[v].begin(), adj2[v].end(), u), adj2[v].end()); removed++; - std::cout << " removed weak bridge between nodes " << u << " (deg = " << adj[u].size() << ") and " << v << " (deg = " << adj[v].size() << ")" << std::endl; + if(aVerbosity > 3) std::cout << " removed weak bridge between nodes " << u << " (deg = " << adj[u].size() << ") and " << v << " (deg = " << adj[v].size() << ")" << std::endl; } } - std::cout << " Removed " << removed << " weak bridges, now finding connected components" << std::endl; + if(aVerbosity > 3) std::cout << " Removed " << removed << " weak bridges, now finding connected components" << std::endl; std::vector visited(N, false); for(int i=0; i 3) std::cout << " found subregion of size " << sub.size() << std::endl; } - std::cout << " finished splitting region into " << outputRegions.size() << " subregions" << std::endl; + if(aVerbosity > 2) std::cout << " finished splitting region into " << outputRegions.size() << " subregions" << std::endl; } - void findConnectedRegions3(std::vector &clusHits, std::pair &maxKey) + void findConnectedRegions3(std::vector &clusHits, std::pair &maxKey, int aVerbosity) { std::vector> regions; @@ -307,22 +310,22 @@ namespace regions.push_back(region); } - std::cout << "finished with normal region finding, now splitting weakly connected regions" << std::endl; + if(aVerbosity > 2) std::cout << "finished with normal region finding, now splitting weakly connected regions" << std::endl; std::vector> refinedRegions; int regionNum = 0; for(auto ®ion : regions) { std::vector> tmpRefinedRegions; - std::cout << "starting to split region " << regionNum << " with " << region.size() << " hits" << std::endl; + if(aVerbosity > 2) std::cout << "starting to split region " << regionNum << " with " << region.size() << " hits" << std::endl; regionNum++; - splitWeaklyConnectedRegion(region, tmpRefinedRegions); - std::cout << "finished splitting region into " << tmpRefinedRegions.size() << std::endl; + splitWeaklyConnectedRegion(region, tmpRefinedRegions, aVerbosity); + if(aVerbosity > 2) std::cout << "finished splitting region into " << tmpRefinedRegions.size() << std::endl; for(auto &subregion : tmpRefinedRegions) { refinedRegions.push_back(subregion); } - std::cout << "total refined regions so far: " << refinedRegions.size() << std::endl; + if(aVerbosity > 2) std::cout << "total refined regions so far: " << refinedRegions.size() << std::endl; } std::sort(refinedRegions.begin(), refinedRegions.end(), [&](const auto &a, const auto &b) @@ -353,6 +356,10 @@ namespace }); clusHits.clear(); + if(refinedRegions[0].size() == 0) + { + return; + } for(auto hit : refinedRegions[0]) { clusHits.push_back(hit); @@ -382,7 +389,7 @@ namespace void calc_cluster_parameter(std::vector &clusHits, thread_data &my_data, std::pair maxADCKey) { - findConnectedRegions3(clusHits, maxADCKey); + findConnectedRegions3(clusHits, maxADCKey, my_data.Verbosity); double rSum = 0.0; double phiSum = 0.0; diff --git a/offline/packages/tpccalib/TpcCentralMembraneMatching.cc b/offline/packages/tpccalib/TpcCentralMembraneMatching.cc index 2e85f78a0c..aae5dbc901 100644 --- a/offline/packages/tpccalib/TpcCentralMembraneMatching.cc +++ b/offline/packages/tpccalib/TpcCentralMembraneMatching.cc @@ -1093,7 +1093,7 @@ int TpcCentralMembraneMatching::InitRun(PHCompositeNode* topNode) // Get truth cluster positions //===================== - CDBTTree *cdbttree = new CDBTTree("/sphenix/u/bkimelman/CMStripePattern.root"); + CDBTTree *cdbttree = new CDBTTree(m_stripePatternFile); cdbttree->LoadCalibrations(); auto cdbMap = cdbttree->GetDoubleEntryMap(); for (const auto &[index, values] : cdbMap) @@ -2196,7 +2196,7 @@ int TpcCentralMembraneMatching::process_event(PHCompositeNode* topNode) dr = static_pos[reco_index].Perp() - m_truth_pos[i].Perp(); dphi = delta_phi(static_pos[reco_index].Phi() - m_truth_pos[i].Phi()); } - if(m_totalDistMode) + else if(m_totalDistMode) { clus_r = raw_pos[reco_index].Perp(); clus_phi = raw_pos[reco_index].Phi(); @@ -2540,7 +2540,8 @@ int TpcCentralMembraneMatching::End(PHCompositeNode* /*topNode*/) for (int s = 0; s < 2; s++) { int N = gr_dR[s]->GetN(); - std::vector dataX(N), dataY(N); + std::vector dataX(N); + std::vector dataY(N); double minR = 99.0; double maxR = 0.0; @@ -2555,7 +2556,7 @@ int TpcCentralMembraneMatching::End(PHCompositeNode* /*topNode*/) { gr_dR_toInterp[s]->RemovePoint(i); gr_dPhi_toInterp[s]->RemovePoint(i); - gr_points[s]->RemovePoint(i); + //gr_points[s]->RemovePoint(i); break; } } diff --git a/offline/packages/tpccalib/TpcCentralMembraneMatching.h b/offline/packages/tpccalib/TpcCentralMembraneMatching.h index 2c2bce46b8..ef5ba5e600 100644 --- a/offline/packages/tpccalib/TpcCentralMembraneMatching.h +++ b/offline/packages/tpccalib/TpcCentralMembraneMatching.h @@ -119,6 +119,11 @@ class TpcCentralMembraneMatching : public SubsysReco m_event_index = 100 * seq; } + void set_stripePatternFile(std::string stripePatternFile) + { + m_stripePatternFile = stripePatternFile; + } + // void set_laminationFile(const std::string& filename) //{ // m_lamfilename = filename; @@ -212,6 +217,8 @@ class TpcCentralMembraneMatching : public SubsysReco TTree *match_tree{nullptr}; TTree *event_tree{nullptr}; + std::string m_stripePatternFile = "/sphenix/u/bkimelman/CMStripePattern.root"; + bool m_useHeader{true}; bool m_averageMode{false}; bool m_totalDistMode{false}; diff --git a/offline/packages/tpccalib/TpcLaminationFitting.cc b/offline/packages/tpccalib/TpcLaminationFitting.cc index acf2604125..f6d09275a9 100644 --- a/offline/packages/tpccalib/TpcLaminationFitting.cc +++ b/offline/packages/tpccalib/TpcLaminationFitting.cc @@ -184,7 +184,7 @@ int TpcLaminationFitting::InitRun(PHCompositeNode *topNode) } } */ - CDBTTree *cdbttree = new CDBTTree("/sphenix/u/bkimelman/CMStripePattern.root"); + CDBTTree *cdbttree = new CDBTTree(m_stripePatternFile); cdbttree->LoadCalibrations(); auto cdbMap = cdbttree->GetDoubleEntryMap(); for (const auto &[index, values] : cdbMap) @@ -200,6 +200,11 @@ int TpcLaminationFitting::InitRun(PHCompositeNode *topNode) m_truthPhi[1].push_back(cdbttree->GetDoubleValue(index, "truthPhi")); } } + if(m_truthR[0].size() == 0 || m_truthPhi[0].size() == 0 || m_truthR[1].size() == 0 || m_truthPhi[1].size() == 0) + { + std::cerr << "stripe pattern file passed has no stripes on one side. Exiting" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } /* for(int i=0; i<32; i++) { @@ -836,7 +841,6 @@ int TpcLaminationFitting::doGlobalRMatching(int side) { double meanA = 0.0; double meanC = 0.0; - double meanOffset = 0.0; int nGoodFits = 0; for(int l = 0; l < 18; l++) { @@ -847,7 +851,6 @@ int TpcLaminationFitting::doGlobalRMatching(int side) meanA += m_fLamination[l][side]->GetParameter(0); meanB += m_fLamination[l][side]->GetParameter(1); meanC += m_fLamination[l][side]->GetParameter(2); - meanOffset += m_laminationOffset[l][side]; nGoodFits++; } if(nGoodFits == 0) @@ -858,7 +861,6 @@ int TpcLaminationFitting::doGlobalRMatching(int side) meanA /= nGoodFits; meanB /= nGoodFits; meanC /= nGoodFits; - meanOffset /= nGoodFits; //tmpLamFit->SetParameters(meanA, meanB, meanC, meanOffset); tmpLamFit->SetParameters(meanA, meanB, meanC, 0.0); } @@ -1188,7 +1190,7 @@ int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) phiDistortionLamination[s]->Write(); //scaleFactorMap[s]->Write(); m_hPetal[s]->Write(); - m_bestRMatch[s]->Write(); + if(m_bestRMatch[s]) m_bestRMatch[s]->Write(); m_parameterScan[s]->Write(); } m_laminationTree->Write(); diff --git a/offline/packages/tpccalib/TpcLaminationFitting.h b/offline/packages/tpccalib/TpcLaminationFitting.h index 44e8b56868..86c0448f00 100644 --- a/offline/packages/tpccalib/TpcLaminationFitting.h +++ b/offline/packages/tpccalib/TpcLaminationFitting.h @@ -43,6 +43,11 @@ class TpcLaminationFitting : public SubsysReco m_QAFileName = QAFileName; } + void set_stripePatternFile(std::string stripePatternFile) + { + m_stripePatternFile = stripePatternFile; + } + void set_ppMode(bool mode){ ppMode = mode; } void set_fieldOff(bool fieldOff){ m_fieldOff = fieldOff; } @@ -98,7 +103,7 @@ class TpcLaminationFitting : public SubsysReco TH2 *phiDistortionLamination[2]{nullptr}; - TH2 *scaleFactorMap[2]{nullptr}; + //TH2 *scaleFactorMap[2]{nullptr}; unsigned int m_nLayerCut{1}; @@ -115,7 +120,9 @@ class TpcLaminationFitting : public SubsysReco double m_ZDC_coincidence{0}; //std::map m_run_ZDC_map_pp; //std::map m_run_ZDC_map_auau; - + + std::string m_stripePatternFile = "/sphenix/u/bkimelman/CMStripePattern.root"; + bool m_fieldOff{false}; TTree *m_laminationTree{nullptr}; From 26c30d88a24d279c464587dfc5028fbbec6931b4 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Fri, 6 Feb 2026 10:55:45 -0500 Subject: [PATCH 185/393] remove dependency on liboncal --- calibrations/xingshift/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/calibrations/xingshift/Makefile.am b/calibrations/xingshift/Makefile.am index 81ea4dbca4..08c0220b6b 100644 --- a/calibrations/xingshift/Makefile.am +++ b/calibrations/xingshift/Makefile.am @@ -23,9 +23,9 @@ libXingShiftCal_la_SOURCES = \ libXingShiftCal_la_LIBADD = \ -lcdbobjects \ -lfun4all \ + -lfun4cal \ -lphool \ - -lSubsysReco \ - -loncal + -lSubsysReco BUILT_SOURCES = testexternals.cc From 29702424b82425068a93f50429329862be50cce2 Mon Sep 17 00:00:00 2001 From: bkimelman Date: Fri, 6 Feb 2026 11:59:08 -0500 Subject: [PATCH 186/393] More changes to appease clang-tidy and cppcheck in addition to some coderabbit suggestions --- offline/packages/tpc/LaserClusterizer.cc | 66 +++++++++++++++---- .../tpccalib/TpcCentralMembraneMatching.cc | 23 ++++--- .../tpccalib/TpcCentralMembraneMatching.h | 2 +- .../packages/tpccalib/TpcLaminationFitting.cc | 25 ++++--- .../packages/tpccalib/TpcLaminationFitting.h | 2 +- 5 files changed, 84 insertions(+), 34 deletions(-) diff --git a/offline/packages/tpc/LaserClusterizer.cc b/offline/packages/tpc/LaserClusterizer.cc index a875747201..177cd6fc5f 100644 --- a/offline/packages/tpc/LaserClusterizer.cc +++ b/offline/packages/tpc/LaserClusterizer.cc @@ -149,6 +149,7 @@ namespace void splitWeaklyConnectedRegion(const std::vector ®ion, std::vector> &outputRegions, int aVerbosity) { int N = region.size(); + /* std::vector> adj(N); for(int i=0; i, int> coordIndex; + for(int i=0; i(std::round(region[i].first.get<0>())); + int p = static_cast(std::round(region[i].first.get<1>())); + int t = static_cast(std::round(region[i].first.get<2>())); + coordIndex[{l,p,t}] = i; + } + std::vector> adj(N); + for(int i=0; i(std::round(region[i].first.get<0>())); + int p = static_cast(std::round(region[i].first.get<1>())); + int t = static_cast(std::round(region[i].first.get<2>())); + for(const auto &neigh : neighborOffsets) + { + int nl = l + static_cast(neigh.get<0>()); + int np = p + static_cast(neigh.get<1>()); + int nt = t + static_cast(neigh.get<2>()); + auto it = coordIndex.find[{nl,np,nt}]; + if(it != coordIndex.end()) + { + adj[i].push_back(it.second); + } + } + } - if(aVerbosity > 3) std::cout << " constructed adjacency list, average degree = " << std::accumulate(adj.begin(), adj.end(), 0.0, [](double s, auto &v) { return s + v.size(); }) / N << ")" << std::endl; + if(aVerbosity > 3) { std::cout << " constructed adjacency list, average degree = " << std::accumulate(adj.begin(), adj.end(), 0.0, [](double s, auto &v) { return s + v.size(); }) / N << ")" << std::endl; +} std::vector disc(N, -1); std::vector low(N, -1); @@ -200,10 +229,12 @@ namespace for(int i=0; i 2) std::cout << " Found " << bridges.size() << " bridges in region of size " << N << std::endl; + if(aVerbosity > 2) { std::cout << " Found " << bridges.size() << " bridges in region of size " << N << std::endl; +} std::vector> adj2 = adj; int removed = 0; @@ -214,16 +245,19 @@ namespace adj2[u].erase(std::remove(adj2[u].begin(), adj2[u].end(), v), adj2[u].end()); adj2[v].erase(std::remove(adj2[v].begin(), adj2[v].end(), u), adj2[v].end()); removed++; - if(aVerbosity > 3) std::cout << " removed weak bridge between nodes " << u << " (deg = " << adj[u].size() << ") and " << v << " (deg = " << adj[v].size() << ")" << std::endl; + if(aVerbosity > 3) { std::cout << " removed weak bridge between nodes " << u << " (deg = " << adj[u].size() << ") and " << v << " (deg = " << adj[v].size() << ")" << std::endl; +} } } - if(aVerbosity > 3) std::cout << " Removed " << removed << " weak bridges, now finding connected components" << std::endl; + if(aVerbosity > 3) { std::cout << " Removed " << removed << " weak bridges, now finding connected components" << std::endl; +} std::vector visited(N, false); for(int i=0; i sub; std::queue q; q.push(i); @@ -243,9 +277,11 @@ namespace } } outputRegions.push_back(sub); - if(aVerbosity > 3) std::cout << " found subregion of size " << sub.size() << std::endl; + if(aVerbosity > 3) { std::cout << " found subregion of size " << sub.size() << std::endl; +} } - if(aVerbosity > 2) std::cout << " finished splitting region into " << outputRegions.size() << " subregions" << std::endl; + if(aVerbosity > 2) { std::cout << " finished splitting region into " << outputRegions.size() << " subregions" << std::endl; +} } void findConnectedRegions3(std::vector &clusHits, std::pair &maxKey, int aVerbosity) @@ -310,22 +346,26 @@ namespace regions.push_back(region); } - if(aVerbosity > 2) std::cout << "finished with normal region finding, now splitting weakly connected regions" << std::endl; + if(aVerbosity > 2) { std::cout << "finished with normal region finding, now splitting weakly connected regions" << std::endl; +} std::vector> refinedRegions; int regionNum = 0; for(auto ®ion : regions) { std::vector> tmpRefinedRegions; - if(aVerbosity > 2) std::cout << "starting to split region " << regionNum << " with " << region.size() << " hits" << std::endl; + if(aVerbosity > 2) { std::cout << "starting to split region " << regionNum << " with " << region.size() << " hits" << std::endl; +} regionNum++; splitWeaklyConnectedRegion(region, tmpRefinedRegions, aVerbosity); - if(aVerbosity > 2) std::cout << "finished splitting region into " << tmpRefinedRegions.size() << std::endl; + if(aVerbosity > 2) { std::cout << "finished splitting region into " << tmpRefinedRegions.size() << std::endl; +} for(auto &subregion : tmpRefinedRegions) { refinedRegions.push_back(subregion); } - if(aVerbosity > 2) std::cout << "total refined regions so far: " << refinedRegions.size() << std::endl; + if(aVerbosity > 2) { std::cout << "total refined regions so far: " << refinedRegions.size() << std::endl; +} } std::sort(refinedRegions.begin(), refinedRegions.end(), [&](const auto &a, const auto &b) @@ -356,7 +396,7 @@ namespace }); clusHits.clear(); - if(refinedRegions[0].size() == 0) + if(refinedRegions.empty() || refinedRegions[0].empty()) { return; } diff --git a/offline/packages/tpccalib/TpcCentralMembraneMatching.cc b/offline/packages/tpccalib/TpcCentralMembraneMatching.cc index aae5dbc901..2cb4942994 100644 --- a/offline/packages/tpccalib/TpcCentralMembraneMatching.cc +++ b/offline/packages/tpccalib/TpcCentralMembraneMatching.cc @@ -2474,7 +2474,7 @@ int TpcCentralMembraneMatching::End(PHCompositeNode* /*topNode*/) bc = hPeaks->GetBinContent(i); if(bc > 10 && bc > pbc) { - if(peakBins.size() == 0 || i > peakBins[peakBins.size()-1] + 1) + if(peakBins.empty() || i > peakBins[peakBins.size()-1] + 1) { peakBins.push_back(i); } @@ -2508,9 +2508,10 @@ int TpcCentralMembraneMatching::End(PHCompositeNode* /*topNode*/) for(int i=0; i<(int)peakVals.size(); i++) { f1->SetParameters(hPeaks->GetBinContent(hPeaks->FindBin(peakVals[i])),peakVals[i],0.2); - if(i == 0) hPeaks->Fit(f1,"Q","",peakVals[i]-0.5,(peakVals[i]+peakVals[i+1])/2); - else if (i<(int)peakVals.size()-1) hPeaks->Fit(f1,"Q","",(peakVals[i-1]+peakVals[i])/2,(peakVals[i]+peakVals[i+1])/2); - else hPeaks->Fit(f1,"Q","",(peakVals[i-1]+peakVals[i])/2,peakVals[i]+1); + double lo = (i == 0) ? peakVals[i] - 0.5 : (peakVals[i-1] + peakVals[i])/2.0; + double hi = (i < (int)peakVals.size() - 1) ? (peakVals[i] + peakVals[i+1])/2.0 : peakVals[i] + 1.0; + hPeaks->Fit(f1,"Q","",lo,hi); + mu.push_back(f1->GetParameter(1)); sig.push_back(f1->GetParameter(2)); } @@ -2570,8 +2571,8 @@ int TpcCentralMembraneMatching::End(PHCompositeNode* /*topNode*/) dataX[k] = RVal*cos(gr_dR[s]->GetX()[k]); dataY[k] = RVal*sin(gr_dR[s]->GetX()[k]); - if(RVal < minR) minR = RVal; - if(RVal > maxR) maxR = RVal; + minR = std::min(RVal, minR); + maxR = std::max(RVal, maxR); } //bool firstGoodR = false; @@ -2581,7 +2582,8 @@ int TpcCentralMembraneMatching::End(PHCompositeNode* /*topNode*/) double Rlow = m_dcc_out_aggregated->m_hDRint[s]->GetYaxis()->GetBinLowEdge(j); double Rhigh = m_dcc_out_aggregated->m_hDRint[s]->GetYaxis()->GetBinLowEdge(j + 1); - if(Rhigh < minR || Rlow > maxR) continue; + if(Rhigh < minR || Rlow > maxR) { continue; +} /* if (!firstGoodR) @@ -2617,9 +2619,9 @@ int TpcCentralMembraneMatching::End(PHCompositeNode* /*topNode*/) bool skipPoint = false; if(m_skipOutliers) { - for(int l=0; l<(int)pointsToSkip[s].size(); l++) + for(int l : pointsToSkip[s]) { - if(k == pointsToSkip[s][l]) + if(k == l) { skipPoint = true; break; @@ -2636,7 +2638,8 @@ int TpcCentralMembraneMatching::End(PHCompositeNode* /*topNode*/) double dy = hY - dataY[k]; double distSq = (dx*dx) + (dy*dy); - if(distSq > 100.0) continue; + if(distSq > 100.0) { continue; +} if(distSq < 1e-9) { diff --git a/offline/packages/tpccalib/TpcCentralMembraneMatching.h b/offline/packages/tpccalib/TpcCentralMembraneMatching.h index ef5ba5e600..cdde093629 100644 --- a/offline/packages/tpccalib/TpcCentralMembraneMatching.h +++ b/offline/packages/tpccalib/TpcCentralMembraneMatching.h @@ -119,7 +119,7 @@ class TpcCentralMembraneMatching : public SubsysReco m_event_index = 100 * seq; } - void set_stripePatternFile(std::string stripePatternFile) + void set_stripePatternFile(const std::string &stripePatternFile) { m_stripePatternFile = stripePatternFile; } diff --git a/offline/packages/tpccalib/TpcLaminationFitting.cc b/offline/packages/tpccalib/TpcLaminationFitting.cc index f6d09275a9..2eaf6fcf4c 100644 --- a/offline/packages/tpccalib/TpcLaminationFitting.cc +++ b/offline/packages/tpccalib/TpcLaminationFitting.cc @@ -200,7 +200,7 @@ int TpcLaminationFitting::InitRun(PHCompositeNode *topNode) m_truthPhi[1].push_back(cdbttree->GetDoubleValue(index, "truthPhi")); } } - if(m_truthR[0].size() == 0 || m_truthPhi[0].size() == 0 || m_truthR[1].size() == 0 || m_truthPhi[1].size() == 0) + if(m_truthR[0].empty() || m_truthPhi[0].empty() || m_truthR[1].empty() || m_truthPhi[1].empty()) { std::cerr << "stripe pattern file passed has no stripes on one side. Exiting" << std::endl; return Fun4AllReturnCodes::ABORTRUN; @@ -695,8 +695,9 @@ int TpcLaminationFitting::fitLaminations() m_distanceToFit[l][s] = distToFunc / nBinsUsed; m_nBinsFit[l][s] = nBinsUsed; - if(c>0) m_fitRMSE[l][s] = sqrt(wc / c); - else m_fitRMSE[l][s] = -999; + if(c>0) { m_fitRMSE[l][s] = sqrt(wc / c); + } else { m_fitRMSE[l][s] = -999; +} if (nBinsUsed < 10 || distToFunc / nBinsUsed > 1.0 || nBinsUsed_R_lt_45 < 5) { m_laminationGoodFit[l][s] = false; @@ -903,7 +904,8 @@ int TpcLaminationFitting::doGlobalRMatching(int side) for(int j=-2; j<=2; j++) { int neighborBinR = binR + j; - if(neighborBinR < 1 || neighborBinR > m_hPetal[side]->GetNbinsY()) continue; + if(neighborBinR < 1 || neighborBinR > m_hPetal[side]->GetNbinsY()) { continue; +} for(int k=-5; k<=5; k++) { int neighborBinPhi = binPhi + k; @@ -919,7 +921,11 @@ int TpcLaminationFitting::doGlobalRMatching(int side) } } } - std::cout << "working on side " << side << " m step " << xbin-1 << " b step " << ybin-1 << " with m = " << m << " and b = " << b << " with sum = " << sum << std::endl; + + if(Verbosity() > 2) + { + std::cout << "working on side " << side << " m step " << xbin-1 << " b step " << ybin-1 << " with m = " << m << " and b = " << b << " with sum = " << sum << std::endl; + } m_parameterScan[side]->Fill(m, b, sum); @@ -947,13 +953,13 @@ int TpcLaminationFitting::doGlobalRMatching(int side) } std::vector bestDistortedR; - for(int i=0; i<(int)m_truthR[side].size(); i++) + for(double i : m_truthR[side]) { - double distortedR = (m_truthR[side][i] + best_b)/(1.0 - best_m); + double distortedR = (i + best_b)/(1.0 - best_m); bestDistortedR.push_back(distortedR); } - m_bestRMatch[side] = new TGraph(distortedPhi.size(), &distortedPhi[0], &bestDistortedR[0]); + m_bestRMatch[side] = new TGraph(distortedPhi.size(), distortedPhi.data(), bestDistortedR.data()); m_bestRMatch[side]->SetTitle((boost::format("Best R matching TPC %s, m = %.3f b = %.3f") %(side == 0 ? "South" : "North") %best_m %best_b).str().c_str()); m_bestRMatch[side]->SetName((boost::format("bestRMatch_side%d") %side).str().c_str()); m_bestRMatch[side]->SetMarkerStyle(25); @@ -1190,7 +1196,8 @@ int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) phiDistortionLamination[s]->Write(); //scaleFactorMap[s]->Write(); m_hPetal[s]->Write(); - if(m_bestRMatch[s]) m_bestRMatch[s]->Write(); + if(m_bestRMatch[s]) { m_bestRMatch[s]->Write(); +} m_parameterScan[s]->Write(); } m_laminationTree->Write(); diff --git a/offline/packages/tpccalib/TpcLaminationFitting.h b/offline/packages/tpccalib/TpcLaminationFitting.h index 86c0448f00..561a9ab199 100644 --- a/offline/packages/tpccalib/TpcLaminationFitting.h +++ b/offline/packages/tpccalib/TpcLaminationFitting.h @@ -43,7 +43,7 @@ class TpcLaminationFitting : public SubsysReco m_QAFileName = QAFileName; } - void set_stripePatternFile(std::string stripePatternFile) + void set_stripePatternFile(const std::string &stripePatternFile) { m_stripePatternFile = stripePatternFile; } From 54c8a9eda7c85ed830305b4448cb65efa73ff376 Mon Sep 17 00:00:00 2001 From: bkimelman Date: Fri, 6 Feb 2026 12:06:05 -0500 Subject: [PATCH 187/393] Fixed issue with brackets instead of parentheses --- offline/packages/tpc/LaserClusterizer.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/tpc/LaserClusterizer.cc b/offline/packages/tpc/LaserClusterizer.cc index 177cd6fc5f..3d9d1ca2e5 100644 --- a/offline/packages/tpc/LaserClusterizer.cc +++ b/offline/packages/tpc/LaserClusterizer.cc @@ -188,7 +188,7 @@ namespace int nl = l + static_cast(neigh.get<0>()); int np = p + static_cast(neigh.get<1>()); int nt = t + static_cast(neigh.get<2>()); - auto it = coordIndex.find[{nl,np,nt}]; + auto it = coordIndex.find({nl,np,nt}); if(it != coordIndex.end()) { adj[i].push_back(it.second); From 4dfbee8874259f8c65b43ada8fc5e678d96604a4 Mon Sep 17 00:00:00 2001 From: bkimelman Date: Fri, 6 Feb 2026 12:07:09 -0500 Subject: [PATCH 188/393] Fixed pointer issue --- offline/packages/tpc/LaserClusterizer.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/tpc/LaserClusterizer.cc b/offline/packages/tpc/LaserClusterizer.cc index 3d9d1ca2e5..cea92afe11 100644 --- a/offline/packages/tpc/LaserClusterizer.cc +++ b/offline/packages/tpc/LaserClusterizer.cc @@ -191,7 +191,7 @@ namespace auto it = coordIndex.find({nl,np,nt}); if(it != coordIndex.end()) { - adj[i].push_back(it.second); + adj[i].push_back(it->second); } } } From f310306304826443ee4e2d8217fbd4c1efcd70f1 Mon Sep 17 00:00:00 2001 From: Antonio Silva Date: Fri, 6 Feb 2026 12:22:44 -0500 Subject: [PATCH 189/393] Fix to the cluster key init --- offline/packages/trackbase_historic/SvtxTrackState_v3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/trackbase_historic/SvtxTrackState_v3.h b/offline/packages/trackbase_historic/SvtxTrackState_v3.h index 8f32d0e872..a29bd179ca 100644 --- a/offline/packages/trackbase_historic/SvtxTrackState_v3.h +++ b/offline/packages/trackbase_historic/SvtxTrackState_v3.h @@ -78,7 +78,7 @@ class SvtxTrackState_v3 : public SvtxTrackState float _pos[3]{}; float _mom[3]{}; float _covar[21]{}; // 6x6 triangular packed storage - TrkrDefs::cluskey _ckey{}; // clusterkey that is associated with this state + TrkrDefs::cluskey _ckey{std::numeric_limits::max()}; // clusterkey that is associated with this state std::string state_name; ClassDefOverride(SvtxTrackState_v3, 1) From 494b21b830d682437c6ccc3e7a1a878be097844c Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Fri, 6 Feb 2026 13:41:26 -0500 Subject: [PATCH 190/393] RunnumberRange - O+O - Update the first and last runnumbers for Run 3 O+O. --- offline/framework/phool/RunnumberRange.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/offline/framework/phool/RunnumberRange.h b/offline/framework/phool/RunnumberRange.h index 2c809f2fb9..0a447f259b 100644 --- a/offline/framework/phool/RunnumberRange.h +++ b/offline/framework/phool/RunnumberRange.h @@ -15,8 +15,8 @@ * @var RUN3AUAU_LAST Last Run 3 Au+Au (heavy-ion) physics run. * @var RUN3PP_FIRST First Run 3 proton-proton (beam) physics run. * @var RUN3PP_LAST Last Run 3 proton-proton physics run. - * @var RUN3OO_FIRST Temporary placeholder for the first Run 3 OO run (to be updated once OO starts). - * @var RUN3OO_LAST Temporary upper bound for Run 3 OO runs. + * @var RUN3OO_FIRST First Run 3 O+O physics run. + * @var RUN3OO_LAST Last Run 3 O+O physics run. */ namespace RunnumberRange { @@ -29,8 +29,8 @@ namespace RunnumberRange static const int RUN3AUAU_LAST = 78954; static const int RUN3PP_FIRST = 79146; // first beam data static const int RUN3PP_LAST = 81668; - static const int RUN3OO_FIRST = 82300; // TEMP (to be updated once OO starts) - static const int RUN3OO_LAST = 200000; + static const int RUN3OO_FIRST = 82374; + static const int RUN3OO_LAST = 82703; } #endif From 00ecb7f952ed535bec20cb1cdde6f8807bfd790d Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Fri, 6 Feb 2026 17:13:45 -0500 Subject: [PATCH 191/393] replace Form or boost::format with std::format --- .../packages/tpccalib/TpcLaminationFitting.cc | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/offline/packages/tpccalib/TpcLaminationFitting.cc b/offline/packages/tpccalib/TpcLaminationFitting.cc index 2eaf6fcf4c..cc811e8e90 100644 --- a/offline/packages/tpccalib/TpcLaminationFitting.cc +++ b/offline/packages/tpccalib/TpcLaminationFitting.cc @@ -1033,18 +1033,18 @@ int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) { lineIdeal = new TLine(30,m_laminationIdeal[l][s],80,m_laminationIdeal[l][s]); lineIdeal->SetLineColor(kBlue); - leg->AddEntry(lineIdeal,Form("#phi_{ideal}=%.6f",m_laminationIdeal[l][s]), "l"); + leg->AddEntry(lineIdeal,std::format("#phi_{{ideal}}={:.6f}",m_laminationIdeal[l][s]).c_str(), "l"); } else { lineIdeal = new TLine(30,m_laminationIdeal[l][s],80,m_laminationIdeal[l][s]); lineIdeal->SetLineColor(kBlue); - leg->AddEntry(lineIdeal,Form("#phi_{ideal}=%.6f",m_laminationIdeal[l][s]), "l"); + leg->AddEntry(lineIdeal,std::format("#phi_{{ideal}}={:.6f}",m_laminationIdeal[l][s]).c_str(), "l"); lineOffset = new TLine(30,m_laminationIdeal[l][s]+m_laminationOffset[l][s],80,m_laminationIdeal[l][s]+m_laminationOffset[l][s]); lineOffset->SetLineColor(kGreen+2); lineOffset->SetLineStyle(2); - leg->AddEntry(lineOffset,Form("#phi_{ideal}+#phi_{offset}=%.6f",m_laminationOffset[l][s]), "l"); + leg->AddEntry(lineOffset,std::format("#phi_{{ideal}}+#phi_{{offset}}={:.6f}",m_laminationOffset[l][s]).c_str(), "l"); lineOffset->Draw("same"); } lineIdeal->Draw("same"); @@ -1054,27 +1054,27 @@ int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) TPaveText *pars = new TPaveText(0.6, 0.55, 0.85, 0.85, "NDC"); - if(m_fieldOff) - { - pars->AddText("#phi = #phi_{ideal} + #phi_{offset}"); - pars->AddText((boost::format("#phi_{ideal}=%.3f#pm %.3f") %m_fLamination[l][s]->GetParameter(1) %m_fLamination[l][s]->GetParError(1)).str().c_str()); - pars->AddText((boost::format("#phi_{offset}=%.3f#pm %.3f") %m_fLamination[l][s]->GetParameter(0) %m_fLamination[l][s]->GetParError(0)).str().c_str()); - pars->AddText((boost::format("Distance to line=%.2f") %m_distanceToFit[l][s]).str().c_str()); - pars->AddText((boost::format("Number of Bins used=%d") %m_nBinsFit[l][s]).str().c_str()); - pars->AddText((boost::format("WRMSE=%.2f") %m_fitRMSE[l][s]).str().c_str()); - } + if(m_fieldOff) + { + pars->AddText("#phi = #phi_{ideal} + #phi_{offset}"); + pars->AddText(std::format("#phi_{{ideal}}={:.3f}#pm {:.3f}",m_fLamination[l][s]->GetParameter(1), m_fLamination[l][s]->GetParError(1)).c_str()); + pars->AddText(std::format("#phi_{{offset}}={:.3f}#pm {:.3f}", m_fLamination[l][s]->GetParameter(0), m_fLamination[l][s]->GetParError(0)).c_str()); + pars->AddText(std::format("Distance to line={:.2f}", m_distanceToFit[l][s]).c_str()); + pars->AddText(std::format("Number of Bins used={}", m_nBinsFit[l][s]).c_str()); + pars->AddText(std::format("WRMSE={:.2f}", m_fitRMSE[l][s]).c_str()); + } else { pars->AddText("#phi = #phi_{ideal} + A#times (1 - e^{-C#times (R - B)})"); - pars->AddText((boost::format("A=%.3f#pm %.3f") %m_fLamination[l][s]->GetParameter(0) %m_fLamination[l][s]->GetParError(0)).str().c_str()); - //pars->AddText((boost::format("#phi_{ideal}=%.3f#pm 0.000") %m_laminationIdeal[l][s]).str().c_str()); - pars->AddText((boost::format("#phi_{nominal}=%.3f#pm 0.000") %(m_laminationIdeal[l][s]+m_laminationOffset[l][s])).str().c_str()); - //pars->AddText((boost::format("#phi_{offset}=%.3f#pm 0.000") %m_laminationOffset[l][s]).str().c_str()); - pars->AddText((boost::format("B=%.3f#pm %.3f") %m_fLamination[l][s]->GetParameter(1) %m_fLamination[l][s]->GetParError(1)).str().c_str()); - pars->AddText((boost::format("C=%.3f#pm %.3f") %m_fLamination[l][s]->GetParameter(2) %m_fLamination[l][s]->GetParError(2)).str().c_str()); - pars->AddText((boost::format("Distance to line=%.2f") %m_distanceToFit[l][s]).str().c_str()); - pars->AddText((boost::format("Number of Bins used=%d") %m_nBinsFit[l][s]).str().c_str()); - pars->AddText((boost::format("WRMSE=%.2f") %m_fitRMSE[l][s]).str().c_str()); + pars->AddText(std::format("A={:.3f}#pm {:.3f}", m_fLamination[l][s]->GetParameter(0), m_fLamination[l][s]->GetParError(0)).c_str()); + //pars->AddText(std::format("#phi_{{ideal}}=%.3f#pm 0.000", m_laminationIdeal[l][s]).c_str()); + pars->AddText(std::format("#phi_{{nominal}}={:.3f}#pm 0.000", (m_laminationIdeal[l][s]+m_laminationOffset[l][s])).c_str()); + //pars->AddText(std::format("#phi_{{offset}}={:.3f}#pm 0.000", m_laminationOffset[l][s]).c_str()); + pars->AddText(std::format("B={:.3f}#pm {:.3f}", m_fLamination[l][s]->GetParameter(1), m_fLamination[l][s]->GetParError(1)).c_str()); + pars->AddText(std::format("C={:.3f}#pm {:.3f}", m_fLamination[l][s]->GetParameter(2), m_fLamination[l][s]->GetParError(2)).c_str()); + pars->AddText(std::format("Distance to line={:.2f}", m_distanceToFit[l][s]).c_str()); +pars->AddText(std::format("Number of Bins used={}", m_nBinsFit[l][s]).c_str()); +pars->AddText(std::format("WRMSE={:.2f}", m_fitRMSE[l][s]).c_str()); } pars->Draw("same"); c1->SaveAs(m_QAFileName.c_str()); @@ -1139,7 +1139,7 @@ int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) } */ //m_dcc_out->m_hDRint[s] = (TH2 *) simRDistortion[s]->Clone(); - //m_dcc_out->m_hDRint[s]->SetName((boost::format("hIntDistortionR%s") %(s == 0 ? "_negz" : "_posz")).str().c_str()); + //m_dcc_out->m_hDRint[s]->SetName(std::format("hIntDistortionR{}", (s == 0 ? "_negz" : "_posz")).c_str()); //m_dcc_out->m_hDRint[s]->Multiply(scaleFactorMap[s]); } From 21d54afaa9f82570a70e3502c954fb9d5f16f9de Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Sat, 7 Feb 2026 10:00:13 -0500 Subject: [PATCH 192/393] suppress clang-tidy warning in CaloWaveformFitting --- offline/packages/CaloReco/CaloWaveformFitting.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/offline/packages/CaloReco/CaloWaveformFitting.cc b/offline/packages/CaloReco/CaloWaveformFitting.cc index 3d2223abab..74aa269c17 100644 --- a/offline/packages/CaloReco/CaloWaveformFitting.cc +++ b/offline/packages/CaloReco/CaloWaveformFitting.cc @@ -659,8 +659,8 @@ double CaloWaveformFitting::SignalShape_PowerLawDoubleExp(double *x, double *par return pedestal + signal; } - -double CaloWaveformFitting::SignalShape_FermiExp(double *x, double *par) +// chp: needs to be verified, but I can vaguely recall that making the args const fails in root +double CaloWaveformFitting::SignalShape_FermiExp(double *x, double *par) //NOLINT(readability-non-const-parameter) { // par[0]: Amplitude // par[1]: Midpoint (t0) From 41a3e8f6899573060c035e678230631529719b27 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Sat, 7 Feb 2026 10:20:39 -0500 Subject: [PATCH 193/393] remove redundant comment --- offline/packages/CaloReco/CaloWaveformFitting.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/offline/packages/CaloReco/CaloWaveformFitting.cc b/offline/packages/CaloReco/CaloWaveformFitting.cc index 74aa269c17..ba59367542 100644 --- a/offline/packages/CaloReco/CaloWaveformFitting.cc +++ b/offline/packages/CaloReco/CaloWaveformFitting.cc @@ -839,7 +839,7 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con } } } - else if(m_funcfit_type == POWERLAWDOUBLEEXP) // POWERLAWDOUBLEEXP + else if(m_funcfit_type == POWERLAWDOUBLEEXP) { // Create fit function with 7 parameters TF1 f("f_doubleexp", SignalShape_PowerLawDoubleExp, 0, nsamples, 7); @@ -889,7 +889,7 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con } } } - else if(m_funcfit_type == FERMIEXP) // POWERLAWDOUBLEEXP + else if(m_funcfit_type == FERMIEXP) { TF1 f("f_fermiexp", SignalShape_FermiExp, 0, nsamples, 5); npar = 5; From 9a0ede1040dc08e650edd48e46e2e1c498b52601 Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Sat, 7 Feb 2026 18:43:41 -0500 Subject: [PATCH 194/393] sEPD_TreeGen: Cleanup and Refactor - Remove saving to regular TTrees, instead only save to DST - No need to save sepd channel phi as it can be reconstructed from the EpdGeom node that's saved to the DST by default - Remove usage of std::format - Remove usage of unique_ptr - Add Print Method for verbosity and debug - Ensure EventPlaneData has proper Reset Method to refresh buffer between events --- .../sepd_eventplanecalib/EventPlaneData.cc | 37 +++- .../sepd_eventplanecalib/EventPlaneData.h | 24 ++- .../sepd/sepd_eventplanecalib/QVecDefs.h | 2 +- .../sepd/sepd_eventplanecalib/sEPD_TreeGen.cc | 176 ++++++++++-------- .../sepd/sepd_eventplanecalib/sEPD_TreeGen.h | 44 +---- 5 files changed, 158 insertions(+), 125 deletions(-) diff --git a/calibrations/sepd/sepd_eventplanecalib/EventPlaneData.cc b/calibrations/sepd/sepd_eventplanecalib/EventPlaneData.cc index 67223236eb..6dedea4a15 100644 --- a/calibrations/sepd/sepd_eventplanecalib/EventPlaneData.cc +++ b/calibrations/sepd/sepd_eventplanecalib/EventPlaneData.cc @@ -3,7 +3,40 @@ EventPlaneData::EventPlaneData() { sepd_charge.fill(0); - sepd_phi.fill(0); } - +void EventPlaneData::Reset() +{ + event_id = 0; + event_zvertex = std::numeric_limits::quiet_NaN(); + event_centrality = std::numeric_limits::quiet_NaN(); + sepd_totalcharge = std::numeric_limits::quiet_NaN(); + sepd_charge.fill(0); +} + +void EventPlaneData::identify(std::ostream& os) const +{ + os << "--- EventPlaneData Identify ---" << std::endl; + os << "Event ID: " << event_id << std::endl; + os << "Z-Vertex: " << event_zvertex << std::endl; + os << "Centrality: " << event_centrality << std::endl; + os << "sEPD Total Charge: " << sepd_totalcharge << std::endl; + os << "-------------------------------" << std::endl; +} + +int EventPlaneData::isValid() const +{ + // An object is considered invalid if the Z-vertex is still NaN + // or if the event ID hasn't been set (remains 0). + if (std::isnan(event_zvertex)) + { + return 0; + } + + if (event_id == 0) + { + return 0; + } + + return 1; +} diff --git a/calibrations/sepd/sepd_eventplanecalib/EventPlaneData.h b/calibrations/sepd/sepd_eventplanecalib/EventPlaneData.h index b68fdfb5ff..255f488712 100644 --- a/calibrations/sepd/sepd_eventplanecalib/EventPlaneData.h +++ b/calibrations/sepd/sepd_eventplanecalib/EventPlaneData.h @@ -1,9 +1,12 @@ #ifndef SEPD_EVENTPLANECALIB_EVENTPLANEDATA_H #define SEPD_EVENTPLANECALIB_EVENTPLANEDATA_H +#include "QVecDefs.h" + #include #include +#include #include class EventPlaneData : public PHObject @@ -12,9 +15,12 @@ class EventPlaneData : public PHObject EventPlaneData(); ~EventPlaneData() override = default; - void Reset() override {*this = EventPlaneData();} // check if this works - // this should be in an sepd define (e.g. ../../../offline/packages/epd/EPDDefs.h) - static constexpr int SEPD_CHANNELS = 744; + EventPlaneData(const EventPlaneData&) = default; + EventPlaneData& operator=(const EventPlaneData&) = default; + EventPlaneData(EventPlaneData&&) = default; + EventPlaneData& operator=(EventPlaneData&&) = default; + + void Reset() override; void set_event_id(int id) {event_id = id;} int get_event_id() const {return event_id;} @@ -27,17 +33,19 @@ class EventPlaneData : public PHObject void set_sepd_charge(int channel, double chg) {sepd_charge[channel] = chg;} double get_sepd_charge(int channel) const {return sepd_charge[channel];} - void set_sepd_phi(int channel, double phi) {sepd_phi[channel] = phi;} - double get_sepd_phi(int channel) const {return sepd_phi[channel];} - + void set_event_centrality(double cent) { event_centrality = cent; } + double get_event_centrality() const { return event_centrality; } + + void identify(std::ostream& os = std::cout) const override; + int isValid() const override; + private: int event_id {0}; double event_zvertex {std::numeric_limits::quiet_NaN()}; double event_centrality{std::numeric_limits::quiet_NaN()}; double sepd_totalcharge{std::numeric_limits::quiet_NaN()}; - std::array sepd_charge {}; - std::array sepd_phi {}; + std::array sepd_charge {}; ClassDefOverride(EventPlaneData, 1); }; diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h b/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h index 0b42e1f105..3bc58344fe 100644 --- a/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h +++ b/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h @@ -10,7 +10,7 @@ namespace QVecShared { static constexpr size_t CENT_BINS = 8; static constexpr std::array HARMONICS = {2, 3, 4}; - static constexpr int sepd_channels = 744; + static constexpr int SEPD_CHANNELS = 744; enum class ChannelStatus : int { diff --git a/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc b/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc index 279577e295..3570fb6bc7 100644 --- a/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc +++ b/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc @@ -3,13 +3,12 @@ #include "EventPlaneData.h" // -- c++ -#include +#include #include // -- Calo #include #include -#include // -- Vtx #include @@ -44,13 +43,6 @@ sEPD_TreeGen::sEPD_TreeGen(const std::string &name) //____________________________________________________________________________.. int sEPD_TreeGen::Init(PHCompositeNode *topNode) { - // Early guard against filename collision - if (m_outfile_name == m_outtree_name) - { - std::cout << PHWHERE << " Error: Histogram filename and Tree filename are identical: " << m_outfile_name << ". This will cause data loss." << std::endl; - return Fun4AllReturnCodes::ABORTRUN; - } - Fun4AllServer *se = Fun4AllServer::instance(); se->Print("NODETREE"); @@ -62,34 +54,26 @@ int sEPD_TreeGen::Init(PHCompositeNode *topNode) double centrality_low{-0.5}; double centrality_high{79.5}; - hSEPD_Charge = std::make_unique("hSEPD_Charge", "|z| < 10 cm and MB; Channel; Avg Charge", QVecShared::sepd_channels, 0, QVecShared::sepd_channels); + hSEPD_Charge = new TProfile("hSEPD_Charge", "|z| < 10 cm and MB; Channel; Avg Charge", QVecShared::SEPD_CHANNELS, 0, QVecShared::SEPD_CHANNELS); hSEPD_Charge->Sumw2(); - h2SEPD_totalcharge_centrality = std::make_unique("h2SEPD_totalcharge_centrality", "|z| < 10 cm and MB; sEPD Total Charge; Centrality [%]", bins_sepd_totalcharge, sepd_totalcharge_low, sepd_totalcharge_high, bins_centrality, centrality_low, centrality_high); + h2SEPD_totalcharge_centrality = new TH2F("h2SEPD_totalcharge_centrality", + "|z| < 10 cm and MB; sEPD Total Charge; Centrality [%]", + bins_sepd_totalcharge, sepd_totalcharge_low, sepd_totalcharge_high, + bins_centrality, centrality_low, centrality_high); + + se->registerHisto(hSEPD_Charge); + se->registerHisto(h2SEPD_totalcharge_centrality); - m_output = std::make_unique(m_outtree_name.c_str(), "recreate"); + PHNodeIterator node_itr(topNode); + PHCompositeNode *dstNode = dynamic_cast(node_itr.findFirst("PHCompositeNode", "DST")); - if (!m_output || m_output->IsZombie()) + if (!dstNode) { - std::cout << PHWHERE << "Failed to open tree output file: " << m_outtree_name << std::endl; + std::cout << PHWHERE << "DST node missing, cannot attach EventPlaneData." << std::endl; return Fun4AllReturnCodes::ABORTRUN; } - m_output->cd(); - - // TTree - m_tree = std::make_unique("T", "T"); - m_tree->SetDirectory(m_output.get()); - m_tree->Branch("event_id", &m_data.event_id); - m_tree->Branch("event_zvertex", &m_data.event_zvertex); - m_tree->Branch("event_centrality", &m_data.event_centrality); - m_tree->Branch("sepd_totalcharge", &m_data.sepd_totalcharge); - m_tree->Branch("sepd_channel", &m_data.sepd_channel); - m_tree->Branch("sepd_charge", &m_data.sepd_charge); - m_tree->Branch("sepd_phi", &m_data.sepd_phi); - PHNodeIterator node_itr(topNode); - PHCompositeNode *dstNode = dynamic_cast(node_itr.findFirst("PHCompositeNode", "DST")); - EventPlaneData *evtdata = findNode::getClass(topNode, "EventPlaneData"); if (!evtdata) { @@ -112,12 +96,18 @@ int sEPD_TreeGen::process_event_check(PHCompositeNode *topNode) return Fun4AllReturnCodes::ABORTRUN; } - if (!vertexmap->empty()) + if (vertexmap->empty()) { - GlobalVertex *vtx = vertexmap->begin()->second; - m_data.event_zvertex = vtx->get_z(); + if (Verbosity() > 1) + { + std::cout << PHWHERE << "GlobalVertexMap Empty, Skipping Event: " << m_data.event_id << std::endl; + } + return Fun4AllReturnCodes::ABORTEVENT; } + GlobalVertex *vtx = vertexmap->begin()->second; + double zvtx = vtx->get_z(); + MinimumBiasInfo *m_mb_info = findNode::getClass(topNode, "MinimumBiasInfo"); if (!m_mb_info) { @@ -128,7 +118,7 @@ int sEPD_TreeGen::process_event_check(PHCompositeNode *topNode) // skip event if not minimum bias if (!m_mb_info->isAuAuMinimumBias()) { - if (Verbosity() > 2) + if (Verbosity() > 1) { std::cout << "Event: " << m_data.event_id << ", Not Min Bias, Skipping" << std::endl; } @@ -136,15 +126,17 @@ int sEPD_TreeGen::process_event_check(PHCompositeNode *topNode) } // skip event if zvtx is too large - if (std::abs(m_data.event_zvertex) >= m_cuts.m_zvtx_max) + if (std::abs(zvtx) >= m_cuts.m_zvtx_max) { - if (Verbosity() > 2) + if (Verbosity() > 1) { - std::cout << "Event: " << m_data.event_id << ", Z: " << m_data.event_zvertex << " cm, Skipping" << std::endl; + std::cout << "Event: " << m_data.event_id << ", Z: " << zvtx << " cm, Skipping" << std::endl; } return Fun4AllReturnCodes::ABORTEVENT; } + m_evtdata->set_event_zvertex(zvtx); + return Fun4AllReturnCodes::EVENT_OK; } @@ -158,18 +150,21 @@ int sEPD_TreeGen::process_centrality(PHCompositeNode *topNode) return Fun4AllReturnCodes::ABORTRUN; } - m_data.event_centrality = centInfo->get_centile(CentralityInfo::PROP::mbd_NS) * 100; + double cent = centInfo->get_centile(CentralityInfo::PROP::mbd_NS) * 100; // skip event if centrality is too peripheral - if (!std::isfinite(m_data.event_centrality) || m_data.event_centrality < 0 || m_data.event_centrality >= m_cuts.m_cent_max) + if (!std::isfinite(cent) || cent < 0 || cent >= m_cuts.m_cent_max) { - if(Verbosity() > 2) + if (Verbosity() > 1) { - std::cout << "Event: " << m_data.event_id << ", Centrality: " << m_data.event_centrality << ", Skipping" << std::endl; + std::cout << "Event: " << m_data.event_id << ", Centrality: " << cent << ", Skipping" << std::endl; } return Fun4AllReturnCodes::ABORTEVENT; } + m_evtdata->set_event_centrality(cent); + m_data.event_centrality = cent; + return Fun4AllReturnCodes::EVENT_OK; } @@ -193,26 +188,24 @@ int sEPD_TreeGen::process_sEPD(PHCompositeNode *topNode) // sepd unsigned int sepd_channels = towerinfosEPD->size(); - if(sepd_channels != QVecShared::sepd_channels) + if(sepd_channels != QVecShared::SEPD_CHANNELS) { - if (Verbosity() > 2) + if (Verbosity() > 1) { - std::cout << "Event: " << m_data.event_id << ", SEPD Channels = " << sepd_channels << " != " << QVecShared::sepd_channels << std::endl; + std::cout << "Event: " << m_data.event_id << ", SEPD Channels = " << sepd_channels << " != " << QVecShared::SEPD_CHANNELS << std::endl; } return Fun4AllReturnCodes::ABORTEVENT; } - m_data.sepd_totalcharge = 0; + double sepd_totalcharge = 0; for (unsigned int channel = 0; channel < sepd_channels; ++channel) { - unsigned int key = TowerInfoDefs::encode_epd(channel); - TowerInfo *tower = towerinfosEPD->get_tower_at_channel(channel); if (!tower) { - if (Verbosity() > 2) + if (Verbosity() > 1) { std::cout << PHWHERE << "Null SEPD tower at channel " << channel << std::endl; } @@ -221,7 +214,6 @@ int sEPD_TreeGen::process_sEPD(PHCompositeNode *topNode) double charge = tower->get_energy(); bool isZS = tower->get_isZS(); - double phi = epdgeom->get_phi(key); // exclude ZS // exclude Nmips @@ -230,20 +222,57 @@ int sEPD_TreeGen::process_sEPD(PHCompositeNode *topNode) continue; } - m_data.sepd_channel.push_back(channel); - m_data.sepd_charge.push_back(charge); - m_data.sepd_phi.push_back(phi); + m_evtdata->set_sepd_charge(channel, charge); - m_data.sepd_totalcharge += charge; + sepd_totalcharge += charge; hSEPD_Charge->Fill(channel, charge); } - h2SEPD_totalcharge_centrality->Fill(m_data.sepd_totalcharge, m_data.event_centrality); + m_evtdata->set_sepd_totalcharge(sepd_totalcharge); + h2SEPD_totalcharge_centrality->Fill(sepd_totalcharge, m_data.event_centrality); return Fun4AllReturnCodes::EVENT_OK; } +//____________________________________________________________________________.. +void sEPD_TreeGen::Print([[maybe_unused]] const std::string &what) const +{ + // Only execute if Verbosity is high enough + if (Verbosity() <= 2) return; + + std::cout << "\n============================================================" << std::endl; + std::cout << "sEPD_TreeGen::Print -> Event Data State" << std::endl; + + if (!m_evtdata) + { + std::cout << " [WARNING] m_evtdata is null." << std::endl; + return; + } + + // Verbosity > 2: Print basic scalars + std::cout << " Event ID: " << m_evtdata->get_event_id() << std::endl; + std::cout << " Z-Vertex: " << m_evtdata->get_event_zvertex() << " cm" << std::endl; + std::cout << " Centrality: " << m_evtdata->get_event_centrality() << " %" << std::endl; + std::cout << " sEPD Total Charge: " << m_evtdata->get_sepd_totalcharge() << std::endl; + + // Verbosity > 3: Print channel arrays + if (Verbosity() > 3) + { + std::cout << " Active Towers (Charge > 0):" << std::endl; + for (int i = 0; i < QVecShared::SEPD_CHANNELS; ++i) + { + double charge = m_evtdata->get_sepd_charge(i); + if (charge > 0) + { + std::cout << " Channel: " << std::setw(3) << i + << " | Charge: " << std::fixed << std::setprecision(4) << charge << std::endl; + } + } + } + std::cout << "============================================================\n" << std::endl; +} + //____________________________________________________________________________.. int sEPD_TreeGen::process_event(PHCompositeNode *topNode) { @@ -256,12 +285,21 @@ int sEPD_TreeGen::process_event(PHCompositeNode *topNode) m_data.event_id = eventInfo->get_EvtSequence(); - if (Verbosity() > 1 && m_event % PROGRESS_PRINT_INTERVAL == 0) + if (Verbosity() && m_event % PROGRESS_PRINT_INTERVAL == 0) { std::cout << "Progress: " << m_event << ", Global: " << m_data.event_id << std::endl; } ++m_event; + m_evtdata = findNode::getClass(topNode, "EventPlaneData"); + if (!m_evtdata) + { + std::cout << PHWHERE << "EventPlaneData Node missing." << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + m_evtdata->set_event_id(m_data.event_id); + int ret = process_event_check(topNode); if (ret) { @@ -279,9 +317,8 @@ int sEPD_TreeGen::process_event(PHCompositeNode *topNode) { return ret; } - - // Fill the TTree - m_tree->Fill(); + + Print(); return Fun4AllReturnCodes::EVENT_OK; } @@ -291,14 +328,13 @@ int sEPD_TreeGen::ResetEvent([[maybe_unused]] PHCompositeNode *topNode) { // Event m_data.event_id = -1; - m_data.event_zvertex = 9999; m_data.event_centrality = 9999; - // sEPD - m_data.sepd_totalcharge = 0; - m_data.sepd_channel.clear(); - m_data.sepd_charge.clear(); - m_data.sepd_phi.clear(); + // DST + if (m_evtdata) + { + m_evtdata->Reset(); + } return Fun4AllReturnCodes::EVENT_OK; } @@ -307,19 +343,5 @@ int sEPD_TreeGen::ResetEvent([[maybe_unused]] PHCompositeNode *topNode) int sEPD_TreeGen::End([[maybe_unused]] PHCompositeNode *topNode) { std::cout << "sEPD_TreeGen::End" << std::endl; - - TFile output(m_outfile_name.c_str(), "recreate"); - output.cd(); - - hSEPD_Charge->Write(); - h2SEPD_totalcharge_centrality->Write(); - - output.Close(); - - // TTree - m_output->cd(); - m_tree->Write(); - m_output->Close(); - return Fun4AllReturnCodes::EVENT_OK; } diff --git a/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.h b/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.h index 57436314fb..0c735cda36 100644 --- a/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.h +++ b/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.h @@ -5,19 +5,14 @@ #include // -- c++ -#include -#include -#include #include -#include // -- ROOT -#include #include #include -#include class PHCompositeNode; +class EventPlaneData; /** * @class sEPD_TreeGen @@ -67,22 +62,10 @@ class sEPD_TreeGen : public SubsysReco int End(PHCompositeNode *topNode) override; /** - * @brief Sets the filename for the QA histograms ROOT file. - * @param file Output path for histograms. + * @brief Prints the current state of the EventPlaneData object. + * @param what Optional string to specify what to print (default "ALL"). */ - void set_filename(const std::string &file) - { - m_outfile_name = file; - } - - /** - * @brief Sets the filename for the flat TTree ROOT file. - * @param file Output path for the TTree. - */ - void set_tree_filename(const std::string &file) - { - m_outtree_name = file; - } + void Print(const std::string &what = "ALL") const override; /** * @brief Sets the maximum allowed Z-vertex position for event selection. @@ -136,9 +119,6 @@ class sEPD_TreeGen : public SubsysReco int m_event{0}; - std::string m_outfile_name{"test.root"}; - std::string m_outtree_name{"tree.root"}; - static constexpr int PROGRESS_PRINT_INTERVAL = 20; // Cuts @@ -154,24 +134,14 @@ class sEPD_TreeGen : public SubsysReco struct EventData { int event_id{0}; - double event_zvertex{9999}; double event_centrality{9999}; - - double sepd_totalcharge{-9999}; - - std::vector sepd_channel; - std::vector sepd_charge; - std::vector sepd_phi; }; EventData m_data; + EventPlaneData* m_evtdata{nullptr}; - std::unique_ptr m_output; - std::unique_ptr m_tree; - - std::unique_ptr hSEPD_Charge; - std::unique_ptr h2SEPD_totalcharge_centrality; + TProfile *hSEPD_Charge{nullptr}; + TH2 *h2SEPD_totalcharge_centrality{nullptr}; }; - #endif // SEPD_TREEGEN_H From ddacfb7b8db24faa079fd7bd0f5051937a4588df Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Sun, 8 Feb 2026 17:53:31 -0500 Subject: [PATCH 195/393] QVecCalib - Refactor Executable to Fun4All - Transformed QVecCalib into a Fun4All module - Reads from slim DST instead of TTree - Merged Functionality of QVecCDB into QVecCalib - Remove QVecCDB and it's corresponding executable - Removed usage of unique_ptr - Using Fun4All server HistoManager to keep track of the histograms --- .../sepd/sepd_eventplanecalib/GenQVecCDB.cc | 54 - .../sepd/sepd_eventplanecalib/Makefile.am | 14 +- .../sepd/sepd_eventplanecalib/QVecCDB.cc | 214 --- .../sepd/sepd_eventplanecalib/QVecCDB.h | 139 -- .../sepd/sepd_eventplanecalib/QVecCalib.cc | 1423 +++++++++-------- .../sepd/sepd_eventplanecalib/QVecCalib.h | 516 +++--- .../sepd/sepd_eventplanecalib/QVecDefs.h | 17 +- .../sepd/sepd_eventplanecalib/sEPD_TreeGen.cc | 5 +- 8 files changed, 1061 insertions(+), 1321 deletions(-) delete mode 100644 calibrations/sepd/sepd_eventplanecalib/GenQVecCDB.cc delete mode 100644 calibrations/sepd/sepd_eventplanecalib/QVecCDB.cc delete mode 100644 calibrations/sepd/sepd_eventplanecalib/QVecCDB.h diff --git a/calibrations/sepd/sepd_eventplanecalib/GenQVecCDB.cc b/calibrations/sepd/sepd_eventplanecalib/GenQVecCDB.cc deleted file mode 100644 index 324f774950..0000000000 --- a/calibrations/sepd/sepd_eventplanecalib/GenQVecCDB.cc +++ /dev/null @@ -1,54 +0,0 @@ -#include "QVecCDB.h" - -#include -#include - -int main(int argc, const char* const argv[]) -{ - const std::vector args(argv, argv + argc); - - if (args.size() < 3 || args.size() > 5) - { - std::cout << "Usage: " << args[0] << " input_file runnumber [output_dir] [cdb_tag]" << std::endl; - return 1; - } - - const std::string &input_file = args[1]; - const std::string output_dir = (args.size() >= 4) ? args[3] : "."; - const std::string cdb_tag = (args.size() >= 5) ? args[4] : "new_newcdbtag_v008"; - - try - { - int runnumber = std::stoi(args[2]); - - std::cout << std::format("{:#<20}\n", ""); - std::cout << std::format("Analysis Params\n"); - std::cout << std::format("Input File: {}\n", input_file); - std::cout << std::format("Run: {}\n", runnumber); - std::cout << std::format("Output Dir: {}\n", output_dir); - std::cout << std::format("CDB Tag: {}\n", cdb_tag); - std::cout << std::format("{:#<20}\n", ""); - - QVecCDB analysis(input_file, runnumber, output_dir, cdb_tag); - analysis.run(); - } - catch (const std::invalid_argument& e) - { - std::cout << "Error: runnumber must be an integer: " << args[2] << std::endl; - return 1; - } - catch (const std::out_of_range& e) - { - std::cout << "Error: runnumber is out of range for an integer." << std::endl; - return 1; - } - catch (const std::exception& e) - { - std::cout << "An exception occurred: " << e.what() << std::endl; - return 1; - } - - std::cout << "======================================" << std::endl; - std::cout << "done" << std::endl; - return 0; -} diff --git a/calibrations/sepd/sepd_eventplanecalib/Makefile.am b/calibrations/sepd/sepd_eventplanecalib/Makefile.am index d09895d691..d17c56b4a0 100644 --- a/calibrations/sepd/sepd_eventplanecalib/Makefile.am +++ b/calibrations/sepd/sepd_eventplanecalib/Makefile.am @@ -1,9 +1,5 @@ AUTOMAKE_OPTIONS = foreign -bin_PROGRAMS = \ - GenQVecCalib \ - GenQVecCDB - AM_CPPFLAGS = \ -I$(includedir) \ -isystem$(OFFLINE_MAIN)/include \ @@ -18,7 +14,6 @@ AM_LDFLAGS = \ pkginclude_HEADERS = \ sEPD_TreeGen.h \ QVecCalib.h \ - QVecCDB.h \ QVecDefs.h lib_LTLIBRARIES = \ @@ -36,8 +31,7 @@ libsepd_eventplanecalib_la_SOURCES = \ $(ROOTDICTS) \ EventPlaneData.cc \ sEPD_TreeGen.cc \ - QVecCalib.cc \ - QVecCDB.cc + QVecCalib.cc libsepd_eventplanecalib_la_LIBADD = \ -lphool \ @@ -51,12 +45,6 @@ libsepd_eventplanecalib_la_LIBADD = \ -lcdbobjects \ -lepd_io -GenQVecCalib_SOURCES = GenQVecCalib.cc -GenQVecCalib_LDADD = libsepd_eventplanecalib.la - -GenQVecCDB_SOURCES = GenQVecCDB.cc -GenQVecCDB_LDADD = libsepd_eventplanecalib.la - # Rule for generating table CINT dictionaries. %_Dict.cc: %.h %LinkDef.h rootcint -f $@ @CINTDEFS@ $(DEFAULT_INCLUDES) $(AM_CPPFLAGS) $^ diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecCDB.cc b/calibrations/sepd/sepd_eventplanecalib/QVecCDB.cc deleted file mode 100644 index ef284faa9d..0000000000 --- a/calibrations/sepd/sepd_eventplanecalib/QVecCDB.cc +++ /dev/null @@ -1,214 +0,0 @@ -#include "QVecCDB.h" - -// ==================================================================== -// sPHENIX Includes -// ==================================================================== -#include -#include - -// ==================================================================== -// ROOT Includes -// ==================================================================== -#include - -// ==================================================================== -// Standard C++ Includes -// ==================================================================== -#include -#include -#include -#include -#include - -template -std::unique_ptr QVecCDB::load_and_clone(const std::string& name) { - auto* obj = dynamic_cast(m_tfile->Get(name.c_str())); - if (!obj) - { - throw std::runtime_error(std::format("Could not find histogram '{}' in file '{}'", name, m_tfile->GetName())); - } - return std::unique_ptr(static_cast(obj->Clone())); -} - -QVecShared::CorrectionMoments& QVecCDB::getData(size_t h_idx, size_t cent_bin, QVecShared::Subdetector sub) { - return m_correction_data[h_idx][cent_bin][static_cast(sub)]; -} - -void QVecCDB::load_data() -{ - m_tfile = std::unique_ptr(TFile::Open(m_input_file.c_str())); - - // Check if the file was opened successfully. - if (!m_tfile || m_tfile->IsZombie()) - { - throw std::runtime_error(std::format("Could not open file '{}'", m_input_file)); - } - - for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) - { - load_correction_data(h_idx); - } -} - -void QVecCDB::load_correction_data(size_t h_idx) -{ - int n = m_harmonics[h_idx]; - - // Load recentering terms (x, y) - auto pS_x = load_and_clone(QVecShared::get_hist_name("S", "x", n)); - auto pS_y = load_and_clone(QVecShared::get_hist_name("S", "y", n)); - auto pN_x = load_and_clone(QVecShared::get_hist_name("N", "x", n)); - auto pN_y = load_and_clone(QVecShared::get_hist_name("N", "y", n)); - - // Load flattening terms (xx, yy, xy) - auto pS_xx = load_and_clone(QVecShared::get_hist_name("S", "xx", n)); - auto pS_yy = load_and_clone(QVecShared::get_hist_name("S", "yy", n)); - auto pS_xy = load_and_clone(QVecShared::get_hist_name("S", "xy", n)); - auto pN_xx = load_and_clone(QVecShared::get_hist_name("N", "xx", n)); - auto pN_yy = load_and_clone(QVecShared::get_hist_name("N", "yy", n)); - auto pN_xy = load_and_clone(QVecShared::get_hist_name("N", "xy", n)); - - // Load NS flattening terms - auto pNS_xx = load_and_clone(QVecShared::get_hist_name("NS", "xx", n)); - auto pNS_yy = load_and_clone(QVecShared::get_hist_name("NS", "yy", n)); - auto pNS_xy = load_and_clone(QVecShared::get_hist_name("NS", "xy", n)); - - for (size_t cent_bin = 0; cent_bin < m_cent_bins; ++cent_bin) - { - int bin = static_cast(cent_bin) + 1; // ROOT bins start at 1 - - // South - auto& dataS = getData(h_idx, cent_bin, QVecShared::Subdetector::S); - dataS.avg_Q = {pS_x->GetBinContent(bin), pS_y->GetBinContent(bin)}; - dataS.avg_Q_xx = pS_xx->GetBinContent(bin); - dataS.avg_Q_yy = pS_yy->GetBinContent(bin); - dataS.avg_Q_xy = pS_xy->GetBinContent(bin); - - // North - auto& dataN = getData(h_idx, cent_bin, QVecShared::Subdetector::N); - dataN.avg_Q = {pN_x->GetBinContent(bin), pN_y->GetBinContent(bin)}; - dataN.avg_Q_xx = pN_xx->GetBinContent(bin); - dataN.avg_Q_yy = pN_yy->GetBinContent(bin); - dataN.avg_Q_xy = pN_xy->GetBinContent(bin); - - // North South - auto& dataNS = getData(h_idx, cent_bin, QVecShared::Subdetector::NS); - dataNS.avg_Q_xx = pNS_xx->GetBinContent(bin); - dataNS.avg_Q_yy = pNS_yy->GetBinContent(bin); - dataNS.avg_Q_xy = pNS_xy->GetBinContent(bin); - } -} - -void QVecCDB::write_cdb() -{ - std::string output_dir = std::format("{}/{}", m_output_dir, m_runnumber); - - std::error_code ec; - if (std::filesystem::create_directories(output_dir, ec)) - { - std::cout << std::format("Success: Directory {} created.\n", output_dir); - } - else if (ec) - { - throw std::runtime_error(std::format("Failed to create directory {}: {}", output_dir, ec.message())); - } - else - { - std::cout << std::format("Info: Directory {} already exists.\n", output_dir); - } - - write_cdb_EventPlane(output_dir); - write_cdb_BadTowers(output_dir); -} - -void QVecCDB::write_cdb_BadTowers(const std::string &output_dir) -{ - std::string payload = "SEPD_HotMap"; - std::string fieldname_status = "status"; - std::string fieldname_sigma = "SEPD_sigma"; - std::string output_file = std::format("{}/{}-{}-{}.root", output_dir, payload, m_cdb_tag, m_runnumber); - - std::unique_ptr cdbttree = std::make_unique(output_file); - - auto h_sEPD_Bad_Channels = load_and_clone("h_sEPD_Bad_Channels"); - - for (int channel = 0; channel < h_sEPD_Bad_Channels->GetNbinsX(); ++channel) - { - unsigned int key = TowerInfoDefs::encode_epd(channel); - int status = h_sEPD_Bad_Channels->GetBinContent(channel+1); - - float sigma = 0; - - // Hot - if (status == static_cast(QVecShared::ChannelStatus::Hot)) - { - sigma = SIGMA_HOT; - } - - // Cold - else if (status == static_cast(QVecShared::ChannelStatus::Cold)) - { - sigma = SIGMA_COLD; - } - - cdbttree->SetIntValue(key, fieldname_status, status); - cdbttree->SetFloatValue(key, fieldname_sigma, sigma); - } - - std::cout << std::format("Saving CDB: {} to {}\n", payload, output_file); - - cdbttree->Commit(); - cdbttree->WriteCDBTTree(); -} - -void QVecCDB::write_cdb_EventPlane(const std::string &output_dir) -{ - std::string payload = "SEPD_EventPlaneCalib"; - std::string output_file = std::format("{}/{}-{}-{}.root", output_dir, payload, m_cdb_tag, m_runnumber); - - std::unique_ptr cdbttree = std::make_unique(output_file); - - for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) - { - int n = m_harmonics[h_idx]; - - // Define lambdas to generate field names consistently - auto field = [&](const char* det, const char* var) { - return std::format("Q_{}_{}_{}_avg", det, var, n); - }; - - for (size_t cent_bin = 0; cent_bin < m_cent_bins; ++cent_bin) - { - int key = static_cast(cent_bin); - - // Access data references to clean up the calls - const auto& S = getData(h_idx, cent_bin, QVecShared::Subdetector::S); - const auto& N = getData(h_idx, cent_bin, QVecShared::Subdetector::N); - const auto& NS = getData(h_idx, cent_bin, QVecShared::Subdetector::NS); - - // South - cdbttree->SetDoubleValue(key, field("S", "x"), S.avg_Q.x); - cdbttree->SetDoubleValue(key, field("S", "y"), S.avg_Q.y); - cdbttree->SetDoubleValue(key, field("S", "xx"), S.avg_Q_xx); - cdbttree->SetDoubleValue(key, field("S", "yy"), S.avg_Q_yy); - cdbttree->SetDoubleValue(key, field("S", "xy"), S.avg_Q_xy); - - // North - cdbttree->SetDoubleValue(key, field("N", "x"), N.avg_Q.x); - cdbttree->SetDoubleValue(key, field("N", "y"), N.avg_Q.y); - cdbttree->SetDoubleValue(key, field("N", "xx"), N.avg_Q_xx); - cdbttree->SetDoubleValue(key, field("N", "yy"), N.avg_Q_yy); - cdbttree->SetDoubleValue(key, field("N", "xy"), N.avg_Q_xy); - - // North South - cdbttree->SetDoubleValue(key, field("NS", "xx"), NS.avg_Q_xx); - cdbttree->SetDoubleValue(key, field("NS", "yy"), NS.avg_Q_yy); - cdbttree->SetDoubleValue(key, field("NS", "xy"), NS.avg_Q_xy); - } - } - - std::cout << std::format("Saving CDB: {} to {}\n", payload, output_file); - - cdbttree->Commit(); - cdbttree->WriteCDBTTree(); -} diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecCDB.h b/calibrations/sepd/sepd_eventplanecalib/QVecCDB.h deleted file mode 100644 index 54b9b37901..0000000000 --- a/calibrations/sepd/sepd_eventplanecalib/QVecCDB.h +++ /dev/null @@ -1,139 +0,0 @@ -#ifndef QVECCDB_H -#define QVECCDB_H - -#include "QVecDefs.h" - -// ==================================================================== -// ROOT Includes -// ==================================================================== -#include - -// ==================================================================== -// Standard C++ Includes -// ==================================================================== -#include -#include - -/** - * @class QVecCDB - * @brief Generates sPHENIX Calibration Database (CDB) payloads for sEPD calibrations. - * - * QVecCDB is responsible for consolidating the correction parameters derived - * during the calibration stage into standardized database formats: - * * - **SEPD_EventPlaneCalib**: Encapsulates re-centering offsets (, ) and - * flattening moments (, , ) indexed by centrality bin. - * - **SEPD_HotMap**: Maps sEPD tower statuses (Dead, Hot, or Cold) to their - * respective channel IDs for use in reconstruction. - * * The class interfaces with the `CDBTTree` object to commit these payloads - * for a specific run number and database tag. - */ -class QVecCDB -{ - public: - // The constructor takes the configuration - QVecCDB(std::string input_file, int runnumber, std::string output_dir, std::string cdb_tag) - : m_input_file(std::move(input_file)) - , m_runnumber(runnumber) - , m_output_dir(std::move(output_dir)) - , m_cdb_tag(std::move(cdb_tag)) - { - } - - void run() - { - load_data(); - write_cdb(); - } - - private: - - static constexpr size_t m_cent_bins = QVecShared::CENT_BINS; - static constexpr auto m_harmonics = QVecShared::HARMONICS; - - static constexpr float SIGMA_HOT = 6.0F; - static constexpr float SIGMA_COLD = -6.0F; - - // Holds all correction data - // key: [Harmonic][Cent][Subdetector] - // Harmonics {2,3,4} -> 3 elements - // Subdetectors {S,N,NS} -> 3 elements - std::array, m_cent_bins>, m_harmonics.size()> m_correction_data; - - // --- Member Variables --- - std::string m_input_file; - int m_runnumber; - std::string m_output_dir; - std::string m_cdb_tag; - - std::unique_ptr m_tfile; - - // --- Private Helper Methods --- -/** - * @brief Safely retrieves a ROOT object from the internal TFile and returns a managed unique_ptr. - * * Utilizes the internal m_tfile member to locate the object. Performs a - * dynamic_cast for type safety and Clones the object for persistent use. - * * @tparam T The ROOT class type (e.g., TProfile, TH3). - * @param name The name of the object within the internal file. - * @return std::unique_ptr A managed pointer to the cloned object. - * @throws std::runtime_error If the object is not found or type mismatch occurs. - */ - template - std::unique_ptr load_and_clone(const std::string& name); - -/** - * @brief Provides safe access to the internal correction data storage. - * * This accessor handles the mapping between the physics-based Subdetector enum - * and the zero-based indexing of the underlying multi-dimensional array. - * * @param h_idx The index of the harmonic order in the m_harmonics array. - * @param cent_bin The index of the centrality bin. - * @param sub The subdetector arm (South or North) using the QVecShared enum. - * @return QVecShared::CorrectionMoments& A reference to the specific data entry. - */ - QVecShared::CorrectionMoments& getData(size_t h_idx, size_t cent_bin, QVecShared::Subdetector sub); - -/** - * @brief High-level orchestrator for loading calibration input from a ROOT file. - * * Opens the input file specified in the constructor and validates its integrity - * before iteratively calling load_correction_data() for every defined harmonic. - * * Throws a std::runtime_error if the file cannot be opened or is found to be - * a "zombie" file. - */ - void load_data(); - -/** - * @brief Loads 1st and 2nd order correction parameters from a calibration file. - * * Iterates through harmonics and centrality bins to populate the internal - * correction matrix using the centralized QVecShared naming scheme. - * * @param h_idx The index of the harmonic to load. - */ - void load_correction_data(size_t h_idx); - -/** - * @brief Top-level orchestrator for the CDB writing phase. - * - * This method manages the creation of the run-specific directory structure - * (e.g., [output_dir]/[runnumber]) within the base output path. Once the - * filesystem is prepared, it delegates the generation and commitment of - * specific calibration payloads to write_cdb_EventPlane() and - * write_cdb_BadTowers(). - */ - void write_cdb(); - -/** - * @brief Writes the Event Plane calibration constants to a CDB-formatted TTree. - * * Formats the re-centering and flattening moments into a CDBTTree payload - * indexed by centrality bin for sPHENIX database integration. - * * @param output_dir The filesystem directory where the .root payload will be saved. - */ - void write_cdb_EventPlane(const std::string &output_dir); - -/** - * @brief Writes the Hot/Cold tower status map to a CDB-formatted TTree. - * * Encodes sEPD channel indices into TowerInfo keys and maps status codes (1=Dead, - * 2=Hot, 3=Cold) to the final database payload. - * * @param output_dir The filesystem directory where the .root payload will be saved. - */ - void write_cdb_BadTowers(const std::string &output_dir); -}; - -#endif // QVECCDB_H diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc index b2a4a97e55..f14b0cc536 100644 --- a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc +++ b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc @@ -1,164 +1,154 @@ #include "QVecCalib.h" +#include "EventPlaneData.h" // ==================================================================== // sPHENIX Includes // ==================================================================== #include +// -- Fun4All +#include +#include + +// -- Nodes +#include +#include + +// -- sEPD +#include + +// -- Run +#include + +// -- CDBTTree +#include + // ==================================================================== // Standard C++ Includes // ==================================================================== -#include -#include -#include -#include +#include #include +#include -// ==================================================================== -// ROOT Includes -// ==================================================================== -#include +//____________________________________________________________________________.. +QVecCalib::QVecCalib(const std::string &name): + SubsysReco(name) +{ + std::cout << "QVecCalib::QVecCalib(const std::string &name) Calling ctor" << std::endl; +} -std::unique_ptr QVecCalib::setupTChain(const std::string& input_filepath, const std::string& tree_name_in_file) +//____________________________________________________________________________.. +int QVecCalib::Init([[maybe_unused]] PHCompositeNode *topNode) { - // 1. Pre-check: Does the file exist at all? (C++17 filesystem or traditional fstream) - if (!std::filesystem::exists(input_filepath)) - { - std::cout << "Error: Input file does not exist: " << input_filepath << std::endl; - return nullptr; // Return a null unique_ptr indicating failure - } + std::cout << "QVecCalib::Init(PHCompositeNode *topNode) Initializing" << std::endl; - // 2. Open the file to check for the TTree directly - // Use TFile::Open and unique_ptr for robust file handling (RAII) - std::unique_ptr file_checker(TFile::Open(input_filepath.c_str(), "READ")); + Fun4AllServer *se = Fun4AllServer::instance(); + se->Print("NODETREE"); - if (!file_checker || file_checker->IsZombie()) + int ret = process_QA_hist(); + if (ret) { - std::cout << "Error: Could not open file " << input_filepath << " to check for TTree." << std::endl; - return nullptr; + return ret; } - // Check if the TTree exists in the file - // Get() returns a TObject*, which can be cast to TTree*. - // If the object doesn't exist or isn't a TTree, Get() returns nullptr. - TTree* tree_obj = dynamic_cast(file_checker->Get(tree_name_in_file.c_str())); - if (!tree_obj) + init_hists(); + + if (m_pass == Pass::ApplyRecentering || m_pass == Pass::ApplyFlattening) { - std::cout << "Error: TTree '" << tree_name_in_file << "' not found in file " << input_filepath << std::endl; - return nullptr; - } - // File will be automatically closed by file_checker's unique_ptr destructor - - // 3. If everything checks out, create and configure the TChain - std::unique_ptr chain = std::make_unique(tree_name_in_file.c_str()); - if (!chain) - { // Check if make_unique failed (e.g. out of memory) - std::cout << "Error: Could not create TChain object." << std::endl; - return nullptr; + ret = load_correction_data(); + if (ret) + { + return ret; + } } - chain->Add(input_filepath.c_str()); + prepare_hists(); + + return Fun4AllReturnCodes::EVENT_OK; +} - // 4. Verify TChain's state (optional but good final check) - // GetEntries() will be -1 if no valid trees were added. - if (chain->GetEntries() == 0) +void QVecCalib::prepare_hists() +{ + if (m_pass == Pass::ComputeRecentering) { - std::cout << "Warning: TChain has 0 entries after adding file. This might indicate a problem." << std::endl; - // Depending on your logic, you might return nullptr here too. + prepare_average_hists(); } - else + else if (m_pass == Pass::ApplyRecentering) { - std::cout << "Successfully set up TChain for tree '" << tree_name_in_file - << "' from file '" << input_filepath << "'. Entries: " << chain->GetEntries() << std::endl; + prepare_recenter_hists(); } - - return chain; // Return the successfully created and configured TChain -} - -void QVecCalib::setup_chain() -{ - std::cout << "Processing... setup_chain" << std::endl; - - m_chain = setupTChain(m_input_file, "T"); - - if (m_chain == nullptr) + else if (m_pass == Pass::ApplyFlattening) { - throw std::runtime_error(std::format("Error in TChain Setup from file: {}", m_input_file)); + prepare_flattening_hists(); } - - // Setup branches - m_chain->SetBranchStatus("*", false); - m_chain->SetBranchStatus("event_id", true); - m_chain->SetBranchStatus("event_centrality", true); - m_chain->SetBranchStatus("sepd_totalcharge", true); - m_chain->SetBranchStatus("sepd_channel", true); - m_chain->SetBranchStatus("sepd_charge", true); - m_chain->SetBranchStatus("sepd_phi", true); - - m_chain->SetBranchAddress("event_id", &m_event_data.event_id); - m_chain->SetBranchAddress("event_centrality", &m_event_data.event_centrality); - m_chain->SetBranchAddress("sepd_totalcharge", &m_event_data.sepd_totalcharge); - m_chain->SetBranchAddress("sepd_channel", &m_event_data.sepd_channel); - m_chain->SetBranchAddress("sepd_charge", &m_event_data.sepd_charge); - m_chain->SetBranchAddress("sepd_phi", &m_event_data.sepd_phi); - - std::cout << "Finished... setup_chain" << std::endl; } -void QVecCalib::process_QA_hist() +int QVecCalib::process_QA_hist() { TH1::AddDirectory(kFALSE); - auto file = std::unique_ptr(TFile::Open(m_input_hist.c_str())); + auto* file = TFile::Open(m_input_hist.c_str()); // Check if the file was opened successfully. if (!file || file->IsZombie()) { - throw std::runtime_error(std::format("Could not open file '{}'", m_input_hist)); + std::cout << PHWHERE << "Error! Cannot not open file: " << m_input_hist << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + // Get sEPD Total Charge Bounds as function of centrality + int ret = process_sEPD_event_thresholds(file); + if (ret) + { + return ret; } // Get List of Bad Channels - process_bad_channels(file.get()); + ret = process_bad_channels(file); + if (ret) + { + return ret; + } - // Get sEPD Total Charge Bounds as function of centrality - process_sEPD_event_thresholds(file.get()); + // cleanup + file->Close(); + delete file; + + return Fun4AllReturnCodes::EVENT_OK; } -void QVecCalib::process_sEPD_event_thresholds(TFile* file) +int QVecCalib::process_sEPD_event_thresholds(TFile* file) { + Fun4AllServer *se = Fun4AllServer::instance(); + std::string sepd_totalcharge_centrality = "h2SEPD_totalcharge_centrality"; - auto* hist = file->Get(sepd_totalcharge_centrality.c_str()); + auto* hist = file->Get(sepd_totalcharge_centrality.c_str()); // Check if the hist is stored in the file if (hist == nullptr) { - throw std::runtime_error(std::format("Cannot find hist: {}", sepd_totalcharge_centrality)); - } - - auto* h2_check = dynamic_cast(hist); - if (!h2_check) - { - throw std::runtime_error(std::format("Histogram '{}' is not a TH2", sepd_totalcharge_centrality)); + std::cout << PHWHERE << "Error! Cannot find hist: " << sepd_totalcharge_centrality << std::endl; + return Fun4AllReturnCodes::ABORTRUN; } - m_hists2D["h2SEPD_Charge"] = std::unique_ptr(static_cast(h2_check->Clone("h2SEPD_Charge"))); - m_hists2D["h2SEPD_Chargev2"] = std::unique_ptr(static_cast(h2_check->Clone("h2SEPD_Chargev2"))); + h2SEPD_Charge = static_cast(hist->Clone("h2SEPD_Charge")); + h2SEPD_Chargev2 = static_cast(hist->Clone("h2SEPD_Chargev2")); - auto* h2SEPD_Charge = m_hists2D["h2SEPD_Charge"].get(); - auto* h2SEPD_Chargev2 = m_hists2D["h2SEPD_Chargev2"].get(); + se->registerHisto(h2SEPD_Charge); + se->registerHisto(h2SEPD_Chargev2); - std::unique_ptr h2SEPD_Charge_py(h2SEPD_Charge->ProfileY("h2SEPD_Charge_py", 1, -1, "s")); + auto* h2SEPD_Charge_py = h2SEPD_Charge->ProfileY("h2SEPD_Charge_py", 1, -1, "s"); int binsx = h2SEPD_Charge->GetNbinsX(); int binsy = h2SEPD_Charge->GetNbinsY(); double ymin = h2SEPD_Charge->GetYaxis()->GetXmin(); double ymax = h2SEPD_Charge->GetYaxis()->GetXmax(); - m_profiles["hSEPD_Charge_Min"] = std::make_unique("hSEPD_Charge_Min", "; Centrality [%]; sEPD Total Charge", binsy, ymin, ymax); - m_profiles["hSEPD_Charge_Max"] = std::make_unique("hSEPD_Charge_Max", "; Centrality [%]; sEPD Total Charge", binsy, ymin, ymax); + hSEPD_Charge_Min = new TProfile("hSEPD_Charge_Min", "; Centrality [%]; sEPD Total Charge", binsy, ymin, ymax); + hSEPD_Charge_Max = new TProfile("hSEPD_Charge_Max", "; Centrality [%]; sEPD Total Charge", binsy, ymin, ymax); - auto* hSEPD_Charge_Min = m_profiles["hSEPD_Charge_Min"].get(); - auto* hSEPD_Charge_Max = m_profiles["hSEPD_Charge_Max"].get(); + se->registerHisto(hSEPD_Charge_Min); + se->registerHisto(hSEPD_Charge_Max); for (int y = 1; y <= binsy; ++y) { @@ -182,70 +172,75 @@ void QVecCalib::process_sEPD_event_thresholds(TFile* file) double charge = h2SEPD_Charge->GetXaxis()->GetBinCenter(x); double zscore = (charge - mean) / sigma; - if (std::fabs(zscore) > m_sEPD_sigma_threshold) + if (std::abs(zscore) > m_sEPD_sigma_threshold) { h2SEPD_Chargev2->SetBinContent(x, y, 0); + h2SEPD_Chargev2->SetBinError(x, y, 0); } } } + + return Fun4AllReturnCodes::EVENT_OK; } -void QVecCalib::process_bad_channels(TFile* file) +int QVecCalib::process_bad_channels(TFile* file) { + Fun4AllServer *se = Fun4AllServer::instance(); + std::string sepd_charge_hist = "hSEPD_Charge"; - auto* hist = file->Get(sepd_charge_hist.c_str()); + auto* hSEPD_Charge = file->Get(sepd_charge_hist.c_str()); // Check if the hist is stored in the file - if (hist == nullptr) - { - throw std::runtime_error(std::format("Cannot find hist: {}", sepd_charge_hist)); - } - - auto* hSEPD_Charge = dynamic_cast(hist); - - if (!hSEPD_Charge) + if (hSEPD_Charge == nullptr) { - throw std::runtime_error(std::format("Histogram '{}' is not a TH1", sepd_charge_hist)); + std::cout << PHWHERE << "Error! Cannot find hist: " << sepd_charge_hist << ", in file: " << file->GetName() << std::endl; + return Fun4AllReturnCodes::ABORTRUN; } int rbins = 16; int bins_charge = 40; - m_hists2D["h2SEPD_South_Charge_rbin"] = std::make_unique("h2SEPD_South_Charge_rbin", - "sEPD South; r_{bin}; Avg Charge", - rbins, -0.5, rbins - 0.5, - bins_charge, 0, bins_charge); + h2SEPD_South_Charge_rbin = new TH2F("h2SEPD_South_Charge_rbin", + "sEPD South; r_{bin}; Avg Charge", + rbins, -0.5, rbins - 0.5, + bins_charge, 0, bins_charge); + + h2SEPD_North_Charge_rbin = new TH2F("h2SEPD_North_Charge_rbin", + "sEPD North; r_{bin}; Avg Charge", + rbins, -0.5, rbins - 0.5, + bins_charge, 0, bins_charge); - m_hists2D["h2SEPD_North_Charge_rbin"] = std::make_unique("h2SEPD_North_Charge_rbin", - "sEPD North; r_{bin}; Avg Charge", - rbins, -0.5, rbins - 0.5, - bins_charge, 0, bins_charge); + h2SEPD_South_Charge_rbinv2 = new TH2F("h2SEPD_South_Charge_rbinv2", + "sEPD South; r_{bin}; Avg Charge", + rbins, -0.5, rbins - 0.5, + bins_charge, 0, bins_charge); - m_hists2D["h2SEPD_South_Charge_rbinv2"] = std::make_unique("h2SEPD_South_Charge_rbinv2", - "sEPD South; r_{bin}; Avg Charge", - rbins, -0.5, rbins - 0.5, - bins_charge, 0, bins_charge); + h2SEPD_North_Charge_rbinv2 = new TH2F("h2SEPD_North_Charge_rbinv2", + "sEPD North; r_{bin}; Avg Charge", + rbins, -0.5, rbins - 0.5, + bins_charge, 0, bins_charge); - m_hists2D["h2SEPD_North_Charge_rbinv2"] = std::make_unique("h2SEPD_North_Charge_rbinv2", - "sEPD North; r_{bin}; Avg Charge", - rbins, -0.5, rbins - 0.5, - bins_charge, 0, bins_charge); + hSEPD_Bad_Channels = new TProfile("h_sEPD_Bad_Channels", "sEPD Bad Channels; Channel; Status", QVecShared::SEPD_CHANNELS, -0.5, QVecShared::SEPD_CHANNELS-0.5); - m_profiles["h_sEPD_Bad_Channels"] = std::make_unique("h_sEPD_Bad_Channels", "sEPD Bad Channels; Channel; Status", QVecShared::sepd_channels, -0.5, QVecShared::sepd_channels-0.5); + se->registerHisto(h2SEPD_South_Charge_rbin); + se->registerHisto(h2SEPD_North_Charge_rbin); + se->registerHisto(h2SEPD_South_Charge_rbinv2); + se->registerHisto(h2SEPD_North_Charge_rbinv2); + se->registerHisto(hSEPD_Bad_Channels); - auto* h2S = m_hists2D["h2SEPD_South_Charge_rbin"].get(); - auto* h2N = m_hists2D["h2SEPD_North_Charge_rbin"].get(); + auto* h2S = h2SEPD_South_Charge_rbin; + auto* h2N = h2SEPD_North_Charge_rbin; - auto* h2Sv2 = m_hists2D["h2SEPD_South_Charge_rbinv2"].get(); - auto* h2Nv2 = m_hists2D["h2SEPD_North_Charge_rbinv2"].get(); + auto* h2Sv2 = h2SEPD_South_Charge_rbinv2; + auto* h2Nv2 = h2SEPD_North_Charge_rbinv2; - auto* hBad = m_profiles["h_sEPD_Bad_Channels"].get(); + auto* hBad = hSEPD_Bad_Channels; - for (int channel = 0; channel < QVecShared::sepd_channels; ++channel) + for (int channel = 0; channel < QVecShared::SEPD_CHANNELS; ++channel) { - unsigned int key = TowerInfoDefs::encode_epd(static_cast(channel)); - int rbin = static_cast(TowerInfoDefs::get_epd_rbin(key)); + unsigned int key = TowerInfoDefs::encode_epd(channel); + int rbin = TowerInfoDefs::get_epd_rbin(key); unsigned int arm = TowerInfoDefs::get_epd_arm(key); double avg_charge = hSEPD_Charge->GetBinContent(channel + 1); @@ -255,21 +250,21 @@ void QVecCalib::process_bad_channels(TFile* file) h2->Fill(rbin, avg_charge); } - std::unique_ptr hSpx(h2S->ProfileX("hSpx", 2, -1, "s")); - std::unique_ptr hNpx(h2N->ProfileX("hNpx", 2, -1, "s")); + auto* hSpx = h2S->ProfileX("hSpx", 2, -1, "s"); + auto* hNpx = h2N->ProfileX("hNpx", 2, -1, "s"); int ctr_dead = 0; int ctr_hot = 0; int ctr_cold = 0; - for (int channel = 0; channel < QVecShared::sepd_channels; ++channel) + for (int channel = 0; channel < QVecShared::SEPD_CHANNELS; ++channel) { - unsigned int key = TowerInfoDefs::encode_epd(static_cast(channel)); - int rbin = static_cast(TowerInfoDefs::get_epd_rbin(key)); + unsigned int key = TowerInfoDefs::encode_epd(channel); + int rbin = TowerInfoDefs::get_epd_rbin(key); unsigned int arm = TowerInfoDefs::get_epd_arm(key); auto* h2 = (arm == 0) ? h2Sv2 : h2Nv2; - auto* hprof = (arm == 0) ? hSpx.get() : hNpx.get(); + auto* hprof = (arm == 0) ? hSpx : hNpx; double charge = hSEPD_Charge->GetBinContent(channel + 1); double mean_charge = hprof->GetBinContent(rbin + 1); @@ -281,7 +276,7 @@ void QVecCalib::process_bad_channels(TFile* file) zscore = (charge - mean_charge) / sigma; } - if (charge < m_sEPD_min_avg_charge_threshold || std::fabs(zscore) > m_sEPD_sigma_threshold) + if (charge < m_sEPD_min_avg_charge_threshold || std::abs(zscore) > m_sEPD_sigma_threshold) { m_bad_channels.insert(channel); @@ -311,7 +306,8 @@ void QVecCalib::process_bad_channels(TFile* file) } hBad->Fill(channel, status_fill); - std::cout << std::format("{:4} Channel: {:3d}, arm: {}, rbin: {:2d}, Mean: {:5.2f}, Charge: {:5.2f}, Z-Score: {:5.2f}\n", type, channel, arm, rbin, mean_charge, charge, zscore); + std::cout << std::format("{:4} Channel: {:3d}, arm: {}, rbin: {:2d}, Mean: {:5.2f}, Charge: {:5.2f}, Z-Score: {:5.2f}", + type, channel, arm, rbin, mean_charge, charge, zscore) << std::endl; } else { @@ -319,9 +315,10 @@ void QVecCalib::process_bad_channels(TFile* file) } } - std::cout << std::format("Total Bad Channels: {}, Dead: {}, Hot: {}, Cold: {}\n", m_bad_channels.size(), ctr_dead, ctr_hot, ctr_cold); + std::cout << std::format("Total Bad Channels: {}, Dead: {}, Hot: {}, Cold: {}", m_bad_channels.size(), ctr_dead, ctr_hot, ctr_cold) << std::endl; std::cout << "Finished processing Hot sEPD channels" << std::endl; + return Fun4AllReturnCodes::EVENT_OK; } void QVecCalib::init_hists() @@ -330,7 +327,10 @@ void QVecCalib::init_hists() double psi_low = -std::numbers::pi; double psi_high = std::numbers::pi; - m_hists1D["h_Cent"] = std::make_unique("h_Cent", "", m_cent_bins, m_cent_low, m_cent_high); + Fun4AllServer *se = Fun4AllServer::instance(); + + hCentrality = new TH1F("hCentrality", "|z| < 10 cm and MB; Centrality [%]; Events", m_cent_bins, m_cent_low, m_cent_high); + se->registerHisto(hCentrality); std::string pass_suffix; if (m_pass == Pass::ApplyRecentering) @@ -353,9 +353,9 @@ void QVecCalib::init_hists() std::string title_N = std::format("sEPD North #Psi (Order {0}); Centrality [%]; {0}#Psi^{{N}}_{{{0}}}", n); std::string title_NS = std::format("sEPD North South #Psi (Order {0}); Centrality [%]; {0}#Psi^{{NS}}_{{{0}}}", n); - m_hists2D[name_S] = std::make_unique(name_S.c_str(), title_S.c_str(), m_cent_bins, m_cent_low, m_cent_high, bins_psi, psi_low, psi_high); - m_hists2D[name_N] = std::make_unique(name_N.c_str(), title_N.c_str(), m_cent_bins, m_cent_low, m_cent_high, bins_psi, psi_low, psi_high); - m_hists2D[name_NS] = std::make_unique(name_NS.c_str(), title_NS.c_str(), m_cent_bins, m_cent_low, m_cent_high, bins_psi, psi_low, psi_high); + m_hists2D[name_S] = new TH2F(name_S.c_str(), title_S.c_str(), m_cent_bins, m_cent_low, m_cent_high, bins_psi, psi_low, psi_high); + m_hists2D[name_N] = new TH2F(name_N.c_str(), title_N.c_str(), m_cent_bins, m_cent_low, m_cent_high, bins_psi, psi_low, psi_high); + m_hists2D[name_NS] = new TH2F(name_NS.c_str(), title_NS.c_str(), m_cent_bins, m_cent_low, m_cent_high, bins_psi, psi_low, psi_high); // South, North for (auto det : m_subdetectors) @@ -378,7 +378,7 @@ void QVecCalib::init_hists() if (!q_avg_sq_cross_name.empty()) { - m_profiles[q_avg_sq_cross_name] = std::make_unique(q_avg_sq_cross_name.c_str(), q_avg_sq_cross_title.c_str(), + m_profiles[q_avg_sq_cross_name] = new TProfile(q_avg_sq_cross_name.c_str(), q_avg_sq_cross_title.c_str(), m_cent_bins, m_cent_low, m_cent_high); } @@ -390,7 +390,7 @@ void QVecCalib::init_hists() auto add_profile = [&](const std::string& prof_name, std::string_view label_suffix = "") { std::string title = std::format("sEPD {}; Centrality [%]; ", det_name, n, comp_str, label_suffix); - m_profiles[prof_name] = std::make_unique(prof_name.c_str(), title.c_str(), m_cent_bins, m_cent_low, m_cent_high); + m_profiles[prof_name] = new TProfile(prof_name.c_str(), title.c_str(), m_cent_bins, m_cent_low, m_cent_high); }; add_profile(name); @@ -430,7 +430,7 @@ void QVecCalib::init_hists() { std::string name = QVecShared::get_hist_name(det_str, comp, n); std::string title = std::format("sEPD NS; Centrality [%]; ", n, comp); - m_profiles[name] = std::make_unique(name.c_str(), title.c_str(), m_cent_bins, m_cent_low, m_cent_high); + m_profiles[name] = new TProfile(name.c_str(), title.c_str(), m_cent_bins, m_cent_low, m_cent_high); } // Initialize Validation Profiles (Flattened NS) @@ -440,11 +440,355 @@ void QVecCalib::init_hists() { std::string name = QVecShared::get_hist_name(det_str, comp, n, "_corr"); std::string title = std::format("sEPD NS Corrected; Centrality [%]; ", n, comp); - m_profiles[name] = std::make_unique(name.c_str(), title.c_str(), m_cent_bins, m_cent_low, m_cent_high); + m_profiles[name] = new TProfile(name.c_str(), title.c_str(), m_cent_bins, m_cent_low, m_cent_high); + } + } + } + } +} + +std::array, 2> QVecCalib::calculate_flattening_matrix(double xx, double yy, double xy, int n, int cent_bin, const std::string& det_label) +{ + double D_arg = (xx * yy) - (xy * xy); + if (D_arg < 1e-12) + { + std::cout << "Warning: Near-zero determinant in bin " << cent_bin << ". Skipping matrix calc." << std::endl; + return std::array, 2>{{{1, 0}, {0, 1}}}; // Return Identity + } + double D = std::sqrt(D_arg); + + double N_term = D * (xx + yy + (2 * D)); + if (N_term <= 0) + { + throw std::runtime_error(std::format( + "Invalid N-term ({}) for n={}, cent={}, det={}", N_term, n, cent_bin, det_label)); + } + double inv_sqrt_N = 1.0 / std::sqrt(N_term); + + std::array, 2> mat{}; + mat[0][0] = inv_sqrt_N * (yy + D); + mat[0][1] = -inv_sqrt_N * xy; + mat[1][0] = mat[0][1]; + mat[1][1] = inv_sqrt_N * (xx + D); + return mat; +} + +template +T* QVecCalib::load_and_clone(TFile* file, const std::string& name) { + auto* obj = file->Get(name.c_str()); + if (!obj) + { + throw std::runtime_error(std::format("Could not find histogram '{}' in file '{}'", name, file->GetName())); + } + return static_cast(obj->Clone()); +} + +int QVecCalib::load_correction_data() +{ + Fun4AllServer *se = Fun4AllServer::instance(); + auto* file = TFile::Open(m_input_Q_calib.c_str()); + + if (!file || file->IsZombie()) + { + std::cout << PHWHERE << "Error! Cannot open: " << m_input_Q_calib << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + using SD = QVecShared::Subdetector; + + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + int n = m_harmonics[h_idx]; + + // Helper to load and register histograms automatically + auto load_reg = [&](const std::string& det, const std::string& var, const std::string& suffix = "") + { + std::string name = QVecShared::get_hist_name(det, var, n, suffix); + m_profiles[name] = load_and_clone(file, name); + se->registerHisto(m_profiles[name]); + return name; + }; + + // Load standard Recentering averages for S and N + std::string s_names[2][2]; // [det][comp] + for (int d = 0; d < 2; ++d) + { + std::string det_str = (d == 0) ? "S" : "N"; + s_names[d][0] = load_reg(det_str, "x"); + s_names[d][1] = load_reg(det_str, "y"); + } + + // Load Flattening (2nd moment) data if needed + if (m_pass == Pass::ApplyFlattening) + { + for (const auto& det_str : {"S", "N", "NS"}) + { + for (const auto& var : {"xx", "yy", "xy"}) + { + load_reg(det_str, var); + } + } + } + + // Populate the CorrectionData matrix + for (size_t cent_bin = 0; cent_bin < m_cent_bins; ++cent_bin) + { + int bin = static_cast(cent_bin) + 1; + + // Populate Recentering (S, N) + for (int d = 0; d < 2; ++d) + { + m_correction_data[cent_bin][h_idx][d].avg_Q = {m_profiles[s_names[d][0]]->GetBinContent(bin), m_profiles[s_names[d][1]]->GetBinContent(bin)}; + } + + if (m_pass == Pass::ApplyFlattening) + { + // Populate Flattening for S, N, and NS + for (int d = 0; d < (int) SD::Count; ++d) + { + std::string det_str = (d == 0) ? "S" : (d == 1) ? "N" : "NS"; + double xx = m_profiles[QVecShared::get_hist_name(det_str, "xx", n)]->GetBinContent(bin); + double yy = m_profiles[QVecShared::get_hist_name(det_str, "yy", n)]->GetBinContent(bin); + double xy = m_profiles[QVecShared::get_hist_name(det_str, "xy", n)]->GetBinContent(bin); + + auto& data = m_correction_data[cent_bin][h_idx][d]; + data.X_matrix = calculate_flattening_matrix(xx, yy, xy, n, cent_bin, det_str); + data.avg_Q_xx = xx; + data.avg_Q_yy = yy; + data.avg_Q_xy = xy; } } } } + + file->Close(); + delete file; + return Fun4AllReturnCodes::EVENT_OK; +} + +void QVecCalib::prepare_average_hists() +{ + Fun4AllServer *se = Fun4AllServer::instance(); + + for (int n : m_harmonics) + { + std::string S_x_avg_name = QVecShared::get_hist_name("S", "x", n); + std::string S_y_avg_name = QVecShared::get_hist_name("S", "y", n); + std::string N_x_avg_name = QVecShared::get_hist_name("N", "x", n); + std::string N_y_avg_name = QVecShared::get_hist_name("N", "y", n); + + std::string psi_S_name = std::format("h2_sEPD_Psi_S_{}", n); + std::string psi_N_name = std::format("h2_sEPD_Psi_N_{}", n); + std::string psi_NS_name = std::format("h2_sEPD_Psi_NS_{}", n); + + AverageHists h; + + h.S_x_avg = m_profiles.at(S_x_avg_name); + h.S_y_avg = m_profiles.at(S_y_avg_name); + h.N_x_avg = m_profiles.at(N_x_avg_name); + h.N_y_avg = m_profiles.at(N_y_avg_name); + + h.Psi_S = m_hists2D.at(psi_S_name); + h.Psi_N = m_hists2D.at(psi_N_name); + h.Psi_NS = m_hists2D.at(psi_NS_name); + + se->registerHisto(h.S_x_avg); + se->registerHisto(h.S_y_avg); + se->registerHisto(h.N_x_avg); + se->registerHisto(h.N_y_avg); + + se->registerHisto(h.Psi_S); + se->registerHisto(h.Psi_N); + se->registerHisto(h.Psi_NS); + + m_average_hists.push_back(h); + } +} + +void QVecCalib::prepare_recenter_hists() +{ + Fun4AllServer *se = Fun4AllServer::instance(); + + for (int n : m_harmonics) + { + std::string S_x_corr_avg_name = QVecShared::get_hist_name("S", "x", n, "_corr"); + std::string S_y_corr_avg_name = QVecShared::get_hist_name("S", "y", n, "_corr"); + std::string N_x_corr_avg_name = QVecShared::get_hist_name("N", "x", n, "_corr"); + std::string N_y_corr_avg_name = QVecShared::get_hist_name("N", "y", n, "_corr"); + + std::string S_xx_avg_name = QVecShared::get_hist_name("S", "xx", n); + std::string S_yy_avg_name = QVecShared::get_hist_name("S", "yy", n); + std::string S_xy_avg_name = QVecShared::get_hist_name("S", "xy", n); + std::string N_xx_avg_name = QVecShared::get_hist_name("N", "xx", n); + std::string N_yy_avg_name = QVecShared::get_hist_name("N", "yy", n); + std::string N_xy_avg_name = QVecShared::get_hist_name("N", "xy", n); + + std::string NS_xx_avg_name = QVecShared::get_hist_name("NS", "xx", n); + std::string NS_yy_avg_name = QVecShared::get_hist_name("NS", "yy", n); + std::string NS_xy_avg_name = QVecShared::get_hist_name("NS", "xy", n); + + std::string psi_S_name = std::format("h2_sEPD_Psi_S_{}_corr", n); + std::string psi_N_name = std::format("h2_sEPD_Psi_N_{}_corr", n); + std::string psi_NS_name = std::format("h2_sEPD_Psi_NS_{}_corr", n); + + RecenterHists h; + + h.S_x_corr_avg = m_profiles.at(S_x_corr_avg_name); + h.S_y_corr_avg = m_profiles.at(S_y_corr_avg_name); + h.N_x_corr_avg = m_profiles.at(N_x_corr_avg_name); + h.N_y_corr_avg = m_profiles.at(N_y_corr_avg_name); + + h.S_xx_avg = m_profiles.at(S_xx_avg_name); + h.S_yy_avg = m_profiles.at(S_yy_avg_name); + h.S_xy_avg = m_profiles.at(S_xy_avg_name); + + h.N_xx_avg = m_profiles.at(N_xx_avg_name); + h.N_yy_avg = m_profiles.at(N_yy_avg_name); + h.N_xy_avg = m_profiles.at(N_xy_avg_name); + + h.NS_xx_avg = m_profiles.at(NS_xx_avg_name); + h.NS_yy_avg = m_profiles.at(NS_yy_avg_name); + h.NS_xy_avg = m_profiles.at(NS_xy_avg_name); + + h.Psi_S_corr = m_hists2D.at(psi_S_name); + h.Psi_N_corr = m_hists2D.at(psi_N_name); + h.Psi_NS_corr = m_hists2D.at(psi_NS_name); + + se->registerHisto(h.S_x_corr_avg); + se->registerHisto(h.S_y_corr_avg); + se->registerHisto(h.N_x_corr_avg); + se->registerHisto(h.N_y_corr_avg); + + se->registerHisto(h.S_xx_avg); + se->registerHisto(h.S_yy_avg); + se->registerHisto(h.S_xy_avg); + + se->registerHisto(h.N_xx_avg); + se->registerHisto(h.N_yy_avg); + se->registerHisto(h.N_xy_avg); + + se->registerHisto(h.NS_xx_avg); + se->registerHisto(h.NS_yy_avg); + se->registerHisto(h.NS_xy_avg); + + se->registerHisto(h.Psi_S_corr); + se->registerHisto(h.Psi_N_corr); + se->registerHisto(h.Psi_NS_corr); + + m_recenter_hists.push_back(h); + } +} + +void QVecCalib::prepare_flattening_hists() +{ + Fun4AllServer *se = Fun4AllServer::instance(); + + for (int n : m_harmonics) + { + std::string S_x_corr2_avg_name = QVecShared::get_hist_name("S", "x", n, "_corr2"); + std::string S_y_corr2_avg_name = QVecShared::get_hist_name("S", "y", n, "_corr2"); + std::string N_x_corr2_avg_name = QVecShared::get_hist_name("N", "x", n, "_corr2"); + std::string N_y_corr2_avg_name = QVecShared::get_hist_name("N", "y", n, "_corr2"); + + std::string S_xx_corr_avg_name = QVecShared::get_hist_name("S", "xx", n, "_corr"); + std::string S_yy_corr_avg_name = QVecShared::get_hist_name("S", "yy", n, "_corr"); + std::string S_xy_corr_avg_name = QVecShared::get_hist_name("S", "xy", n, "_corr"); + std::string N_xx_corr_avg_name = QVecShared::get_hist_name("N", "xx", n, "_corr"); + std::string N_yy_corr_avg_name = QVecShared::get_hist_name("N", "yy", n, "_corr"); + std::string N_xy_corr_avg_name = QVecShared::get_hist_name("N", "xy", n, "_corr"); + + std::string NS_xx_corr_avg_name = QVecShared::get_hist_name("NS", "xx", n, "_corr"); + std::string NS_yy_corr_avg_name = QVecShared::get_hist_name("NS", "yy", n, "_corr"); + std::string NS_xy_corr_avg_name = QVecShared::get_hist_name("NS", "xy", n, "_corr"); + + std::string psi_S_name = std::format("h2_sEPD_Psi_S_{}_corr2", n); + std::string psi_N_name = std::format("h2_sEPD_Psi_N_{}_corr2", n); + std::string psi_NS_name = std::format("h2_sEPD_Psi_NS_{}_corr2", n); + + FlatteningHists h; + + h.S_x_corr2_avg = m_profiles.at(S_x_corr2_avg_name); + h.S_y_corr2_avg = m_profiles.at(S_y_corr2_avg_name); + h.N_x_corr2_avg = m_profiles.at(N_x_corr2_avg_name); + h.N_y_corr2_avg = m_profiles.at(N_y_corr2_avg_name); + + h.S_xx_corr_avg = m_profiles.at(S_xx_corr_avg_name); + h.S_yy_corr_avg = m_profiles.at(S_yy_corr_avg_name); + h.S_xy_corr_avg = m_profiles.at(S_xy_corr_avg_name); + + h.N_xx_corr_avg = m_profiles.at(N_xx_corr_avg_name); + h.N_yy_corr_avg = m_profiles.at(N_yy_corr_avg_name); + h.N_xy_corr_avg = m_profiles.at(N_xy_corr_avg_name); + + h.NS_xx_corr_avg = m_profiles.at(NS_xx_corr_avg_name); + h.NS_yy_corr_avg = m_profiles.at(NS_yy_corr_avg_name); + h.NS_xy_corr_avg = m_profiles.at(NS_xy_corr_avg_name); + + h.Psi_S_corr2 = m_hists2D.at(psi_S_name); + h.Psi_N_corr2 = m_hists2D.at(psi_N_name); + h.Psi_NS_corr2 = m_hists2D.at(psi_NS_name); + + se->registerHisto(h.S_x_corr2_avg); + se->registerHisto(h.S_y_corr2_avg); + se->registerHisto(h.N_x_corr2_avg); + se->registerHisto(h.N_y_corr2_avg); + + se->registerHisto(h.S_xx_corr_avg); + se->registerHisto(h.S_yy_corr_avg); + se->registerHisto(h.S_xy_corr_avg); + + se->registerHisto(h.N_xx_corr_avg); + se->registerHisto(h.N_yy_corr_avg); + se->registerHisto(h.N_xy_corr_avg); + + se->registerHisto(h.NS_xx_corr_avg); + se->registerHisto(h.NS_yy_corr_avg); + se->registerHisto(h.NS_xy_corr_avg); + + se->registerHisto(h.Psi_S_corr2); + se->registerHisto(h.Psi_N_corr2); + se->registerHisto(h.Psi_NS_corr2); + + m_flattening_hists.push_back(h); + } +} + +int QVecCalib::InitRun(PHCompositeNode *topNode) +{ + RunHeader* run_header = findNode::getClass(topNode, "RunHeader"); + if (!run_header) + { + std::cout << PHWHERE << "RunHeader Node missing." << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + m_runnumber = run_header->get_RunNumber(); + + EpdGeom* epdgeom = findNode::getClass(topNode, "TOWERGEOM_EPD"); + if (!epdgeom) + { + std::cout << PHWHERE << "TOWERGEOM_EPD Node missing." << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + m_trig_cache.assign(m_harmonics.size(), std::vector>(QVecShared::SEPD_CHANNELS)); + + for (int channel = 0; channel < QVecShared::SEPD_CHANNELS; ++channel) + { + unsigned int key = TowerInfoDefs::encode_epd(channel); + double phi = epdgeom->get_phi(key); + + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + int n = m_harmonics[h_idx]; + m_trig_cache[h_idx][channel] = {std::cos(n * phi), std::sin(n * phi)}; + } + } + + std::cout << "QVecCalib::InitRun - Trigonometry cache initialized for " + << QVecShared::SEPD_CHANNELS << " channels." << std::endl; + + return Fun4AllReturnCodes::EVENT_OK; } void QVecCalib::process_averages(double cent, const QVecShared::QVec& q_S, const QVecShared::QVec& q_N, const AverageHists& h) @@ -465,12 +809,15 @@ void QVecCalib::process_averages(double cent, const QVecShared::QVec& q_S, const void QVecCalib::process_recentering(double cent, size_t h_idx, const QVecShared::QVec& q_S, const QVecShared::QVec& q_N, const RecenterHists& h) { - size_t cent_bin = static_cast(m_hists1D["h_Cent"]->FindBin(cent) - 1); + size_t cent_bin = static_cast(hCentrality->FindBin(cent) - 1); - double Q_S_x_avg = m_correction_data[cent_bin][h_idx][0].avg_Q.x; - double Q_S_y_avg = m_correction_data[cent_bin][h_idx][0].avg_Q.y; - double Q_N_x_avg = m_correction_data[cent_bin][h_idx][1].avg_Q.x; - double Q_N_y_avg = m_correction_data[cent_bin][h_idx][1].avg_Q.y; + const auto& S = m_correction_data[cent_bin][h_idx][(size_t) QVecShared::Subdetector::S]; + const auto& N = m_correction_data[cent_bin][h_idx][(size_t) QVecShared::Subdetector::N]; + + double Q_S_x_avg = S.avg_Q.x; + double Q_S_y_avg = S.avg_Q.y; + double Q_N_x_avg = N.avg_Q.x; + double Q_N_y_avg = N.avg_Q.y; QVecShared::QVec q_S_corr = {q_S.x - Q_S_x_avg, q_S.y - Q_S_y_avg}; QVecShared::QVec q_N_corr = {q_N.x - Q_N_x_avg, q_N.y - Q_N_y_avg}; @@ -506,12 +853,16 @@ void QVecCalib::process_recentering(double cent, size_t h_idx, const QVecShared: void QVecCalib::process_flattening(double cent, size_t h_idx, const QVecShared::QVec& q_S, const QVecShared::QVec& q_N, const FlatteningHists& h) { - size_t cent_bin = static_cast(m_hists1D["h_Cent"]->FindBin(cent) - 1); + size_t cent_bin = static_cast(hCentrality->FindBin(cent) - 1); + + const auto& S = m_correction_data[cent_bin][h_idx][(size_t) QVecShared::Subdetector::S]; + const auto& N = m_correction_data[cent_bin][h_idx][(size_t) QVecShared::Subdetector::N]; + const auto& NS = m_correction_data[cent_bin][h_idx][(size_t) QVecShared::Subdetector::NS]; - double Q_S_x_avg = m_correction_data[cent_bin][h_idx][0].avg_Q.x; - double Q_S_y_avg = m_correction_data[cent_bin][h_idx][0].avg_Q.y; - double Q_N_x_avg = m_correction_data[cent_bin][h_idx][1].avg_Q.x; - double Q_N_y_avg = m_correction_data[cent_bin][h_idx][1].avg_Q.y; + double Q_S_x_avg = S.avg_Q.x; + double Q_S_y_avg = S.avg_Q.y; + double Q_N_x_avg = N.avg_Q.x; + double Q_N_y_avg = N.avg_Q.y; QVecShared::QVec q_S_corr = {q_S.x - Q_S_x_avg, q_S.y - Q_S_y_avg}; QVecShared::QVec q_N_corr = {q_N.x - Q_N_x_avg, q_N.y - Q_N_y_avg}; @@ -519,9 +870,9 @@ void QVecCalib::process_flattening(double cent, size_t h_idx, const QVecShared:: // Construct Combined Recentered Vector QVecShared::QVec q_NS_corr = {q_S_corr.x + q_N_corr.x, q_S_corr.y + q_N_corr.y}; - const auto& X_S = m_correction_data[cent_bin][h_idx][0].X_matrix; - const auto& X_N = m_correction_data[cent_bin][h_idx][1].X_matrix; - const auto& X_NS = m_correction_data[cent_bin][h_idx][IDX_NS].X_matrix; + const auto& X_S = S.X_matrix; + const auto& X_N = N.X_matrix; + const auto& X_NS = NS.X_matrix; double Q_S_x_corr2 = X_S[0][0] * q_S_corr.x + X_S[0][1] * q_S_corr.y; double Q_S_y_corr2 = X_S[1][0] * q_S_corr.x + X_S[1][1] * q_S_corr.y; @@ -560,24 +911,174 @@ void QVecCalib::process_flattening(double cent, size_t h_idx, const QVecShared:: h.Psi_NS_corr2->Fill(cent, psi_NS); } -void QVecCalib::compute_averages(size_t cent_bin, int h_idx) +bool QVecCalib::process_sEPD() { - int n = m_harmonics[h_idx]; + double sepd_total_charge_south = 0; + double sepd_total_charge_north = 0; - std::string S_x_avg_name = QVecShared::get_hist_name("S", "x", n); - std::string S_y_avg_name = QVecShared::get_hist_name("S", "y", n); - std::string N_x_avg_name = QVecShared::get_hist_name("N", "x", n); - std::string N_y_avg_name = QVecShared::get_hist_name("N", "y", n); + // Loop over all sEPD Channels + for (int channel = 0; channel < QVecShared::SEPD_CHANNELS; ++channel) + { + double charge = m_evtdata->get_sepd_charge(channel); - int bin = static_cast(cent_bin + 1); + // Skip Bad Channels + if (m_bad_channels.contains(channel) || charge <= 0) + { + continue; + } + + unsigned int key = TowerInfoDefs::encode_epd(channel); + unsigned int arm = TowerInfoDefs::get_epd_arm(key); + + // arm = 0: South + // arm = 1: North + if (arm == 0) + { + sepd_total_charge_south += charge; + } + else + { + sepd_total_charge_north += charge; + } + + // Compute Raw Q vectors for each harmonic and respective arm + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + // Optimized lookup instead of std::cos/std::sin calls + const auto& [cached_cos, cached_sin] = m_trig_cache[h_idx][channel]; + + m_q_vectors[h_idx][arm].x += charge * cached_cos; + m_q_vectors[h_idx][arm].y += charge * cached_sin; + } + } + + // Skip Events with Zero sEPD Total Charge in either arm + if (sepd_total_charge_south == 0 || sepd_total_charge_north == 0) + { + return false; + } + + // Normalize the Q-vectors by total charge + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + for (auto det : m_subdetectors) + { + size_t det_idx = (det == QVecShared::Subdetector::S) ? 0 : 1; + double sepd_total_charge = (det_idx == 0) ? sepd_total_charge_south : sepd_total_charge_north; + m_q_vectors[h_idx][det_idx].x /= sepd_total_charge; + m_q_vectors[h_idx][det_idx].y /= sepd_total_charge; + } + } + + return true; +} + +bool QVecCalib::process_event_check() +{ + double cent = m_evtdata->get_event_centrality(); + int cent_bin = hSEPD_Charge_Min->FindBin(cent); + + double sepd_totalcharge = m_evtdata->get_sepd_totalcharge(); + + double sepd_totalcharge_min = hSEPD_Charge_Min->GetBinContent(cent_bin); + double sepd_totalcharge_max = hSEPD_Charge_Max->GetBinContent(cent_bin); + + return sepd_totalcharge > sepd_totalcharge_min && sepd_totalcharge < sepd_totalcharge_max; +} + +//____________________________________________________________________________.. +int QVecCalib::process_event([[maybe_unused]] PHCompositeNode *topNode) +{ + m_evtdata = findNode::getClass(topNode, "EventPlaneData"); + if (!m_evtdata) + { + std::cout << PHWHERE << "EventPlaneData Node missing." << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + int event_id = m_evtdata->get_event_id(); + + if (Verbosity() && m_event % PROGRESS_REPORT_INTERVAL == 0) + { + std::cout << "Progress: " << m_event << ", Global: " << event_id << std::endl; + } + ++m_event; + + double cent = m_evtdata->get_event_centrality(); + + bool isGood = process_event_check(); + + // Skip Events with non correlation between centrality and sEPD + if (!isGood) + { + ++m_event_counters.bad_centrality_sepd_correlation; + return Fun4AllReturnCodes::ABORTEVENT; + } + + isGood = process_sEPD(); + + // Skip Events with Zero sEPD Total Charge in either arm + if (!isGood) + { + ++m_event_counters.zero_sepd_total_charge; + return Fun4AllReturnCodes::ABORTEVENT; + } + + hCentrality->Fill(cent); + + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + const auto& q_S = m_q_vectors[h_idx][0]; // 0 for South + const auto& q_N = m_q_vectors[h_idx][1]; // 1 for North + + // --- First Pass: Derive 1st Order --- + if (m_pass == Pass::ComputeRecentering) + { + process_averages(cent, q_S, q_N, m_average_hists[h_idx]); + } + + // --- Second Pass: Apply 1st Order, Derive 2nd Order --- + else if (m_pass == Pass::ApplyRecentering) + { + process_recentering(cent, h_idx, q_S, q_N, m_recenter_hists[h_idx]); + } + + // --- Third Pass: Apply 2nd Order, Validate --- + else if (m_pass == Pass::ApplyFlattening) + { + process_flattening(cent, h_idx, q_S, q_N, m_flattening_hists[h_idx]); + } + } + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int QVecCalib::ResetEvent([[maybe_unused]] PHCompositeNode *topNode) +{ + m_q_vectors = {}; + + return Fun4AllReturnCodes::EVENT_OK; +} + +void QVecCalib::compute_averages(size_t cent_bin, int h_idx) +{ + int n = m_harmonics[h_idx]; + + std::string S_x_avg_name = QVecShared::get_hist_name("S", "x", n); + std::string S_y_avg_name = QVecShared::get_hist_name("S", "y", n); + std::string N_x_avg_name = QVecShared::get_hist_name("N", "x", n); + std::string N_y_avg_name = QVecShared::get_hist_name("N", "y", n); + + int bin = static_cast(cent_bin + 1); double Q_S_x_avg = m_profiles[S_x_avg_name]->GetBinContent(bin); double Q_S_y_avg = m_profiles[S_y_avg_name]->GetBinContent(bin); double Q_N_x_avg = m_profiles[N_x_avg_name]->GetBinContent(bin); double Q_N_y_avg = m_profiles[N_y_avg_name]->GetBinContent(bin); - m_correction_data[cent_bin][h_idx][0].avg_Q = {Q_S_x_avg, Q_S_y_avg}; - m_correction_data[cent_bin][h_idx][1].avg_Q = {Q_N_x_avg, Q_N_y_avg}; + m_correction_data[cent_bin][h_idx][(size_t)QVecShared::Subdetector::S].avg_Q = {Q_S_x_avg, Q_S_y_avg}; + m_correction_data[cent_bin][h_idx][(size_t)QVecShared::Subdetector::N].avg_Q = {Q_N_x_avg, Q_N_y_avg}; std::cout << std::format( "Centrality Bin: {}, " @@ -585,39 +1086,13 @@ void QVecCalib::compute_averages(size_t cent_bin, int h_idx) "Q_S_x_avg: {:13.10f}, " "Q_S_y_avg: {:13.10f}, " "Q_N_x_avg: {:13.10f}, " - "Q_N_y_avg: {:13.10f}\n", + "Q_N_y_avg: {:13.10f}", cent_bin, n, Q_S_x_avg, Q_S_y_avg, Q_N_x_avg, - Q_N_y_avg); -} - -std::array, 2> QVecCalib::calculate_flattening_matrix(double xx, double yy, double xy, int n, int cent_bin, const std::string& det_label) -{ - double D_arg = (xx * yy) - (xy * xy); - if (D_arg <= 0) - { - throw std::runtime_error(std::format( - "Invalid D-term ({}) for n={}, cent={}, det={}", D_arg, n, cent_bin, det_label)); - } - double D = std::sqrt(D_arg); - - double N_term = D * (xx + yy + (2 * D)); - if (N_term <= 0) - { - throw std::runtime_error(std::format( - "Invalid N-term ({}) for n={}, cent={}, det={}", N_term, n, cent_bin, det_label)); - } - double inv_sqrt_N = 1.0 / std::sqrt(N_term); - - std::array, 2> mat{}; - mat[0][0] = inv_sqrt_N * (yy + D); - mat[0][1] = -inv_sqrt_N * xy; - mat[1][0] = mat[0][1]; - mat[1][1] = inv_sqrt_N * (xx + D); - return mat; + Q_N_y_avg) << std::endl; } void QVecCalib::compute_recentering(size_t cent_bin, int h_idx) @@ -660,7 +1135,7 @@ void QVecCalib::compute_recentering(size_t cent_bin, int h_idx) double Q_NS_yy_avg = m_profiles[NS_yy_avg_name]->GetBinContent(bin); double Q_NS_xy_avg = m_profiles[NS_xy_avg_name]->GetBinContent(bin); - m_correction_data[cent_bin][h_idx][IDX_NS].X_matrix = calculate_flattening_matrix(Q_NS_xx_avg, Q_NS_yy_avg, Q_NS_xy_avg, n, cent_bin, "NS"); + m_correction_data[cent_bin][h_idx][(size_t)QVecShared::Subdetector::NS].X_matrix = calculate_flattening_matrix(Q_NS_xx_avg, Q_NS_yy_avg, Q_NS_xy_avg, n, cent_bin, "NS"); for (size_t det_idx = 0; det_idx < 2; ++det_idx) { @@ -685,7 +1160,7 @@ void QVecCalib::compute_recentering(size_t cent_bin, int h_idx) "Q_NS_xx_avg / Q_NS_yy_avg: {:13.10f}, " "Q_S_xy_avg: {:13.10f}, " "Q_N_xy_avg: {:13.10f}, " - "Q_NS_xy_avg: {:13.10f}\n", + "Q_NS_xy_avg: {:13.10f}", cent_bin, n, Q_S_x_corr_avg, @@ -697,7 +1172,7 @@ void QVecCalib::compute_recentering(size_t cent_bin, int h_idx) Q_NS_xx_avg / Q_NS_yy_avg, Q_S_xy_avg, Q_N_xy_avg, - Q_NS_xy_avg); + Q_NS_xy_avg) << std::endl; } void QVecCalib::print_flattening(size_t cent_bin, int n) const @@ -748,7 +1223,7 @@ void QVecCalib::print_flattening(size_t cent_bin, int n) const "Q_NS_xx_corr_avg / Q_NS_yy_corr_avg: {:13.10f}, " "Q_S_xy_corr_avg: {:13.10f}, " "Q_N_xy_corr_avg: {:13.10f}, " - "Q_NS_xy_corr_avg: {:13.10f}\n", + "Q_NS_xy_corr_avg: {:13.10f}", cent_bin, n, Q_S_x_corr2_avg, @@ -760,331 +1235,149 @@ void QVecCalib::print_flattening(size_t cent_bin, int n) const Q_NS_xx_corr_avg / Q_NS_yy_corr_avg, Q_S_xy_corr_avg, Q_N_xy_corr_avg, - Q_NS_xy_corr_avg); + Q_NS_xy_corr_avg) << std::endl; } -std::vector QVecCalib::prepare_average_hists() +void QVecCalib::write_cdb() { - std::vector hists_cache; - for (int n : m_harmonics) + std::error_code ec; + if (std::filesystem::create_directories(m_cdb_output_dir, ec)) { - - std::string S_x_avg_name = QVecShared::get_hist_name("S", "x", n); - std::string S_y_avg_name = QVecShared::get_hist_name("S", "y", n); - std::string N_x_avg_name = QVecShared::get_hist_name("N", "x", n); - std::string N_y_avg_name = QVecShared::get_hist_name("N", "y", n); - - std::string psi_S_name = std::format("h2_sEPD_Psi_S_{}", n); - std::string psi_N_name = std::format("h2_sEPD_Psi_N_{}", n); - std::string psi_NS_name = std::format("h2_sEPD_Psi_NS_{}", n); - - AverageHists h; - - h.S_x_avg = m_profiles.at(S_x_avg_name).get(); - h.S_y_avg = m_profiles.at(S_y_avg_name).get(); - h.N_x_avg = m_profiles.at(N_x_avg_name).get(); - h.N_y_avg = m_profiles.at(N_y_avg_name).get(); - - h.Psi_S = m_hists2D.at(psi_S_name).get(); - h.Psi_N = m_hists2D.at(psi_N_name).get(); - h.Psi_NS = m_hists2D.at(psi_NS_name).get(); - - hists_cache.push_back(h); + std::cout << "Success: Directory " << m_cdb_output_dir << " created" << std::endl; } - - return hists_cache; -} - -bool QVecCalib::process_sEPD() -{ - size_t nChannels = m_event_data.sepd_channel->size(); - - double sepd_total_charge_south = 0; - double sepd_total_charge_north = 0; - - // Loop over all sEPD Channels - for (size_t idx = 0; idx < nChannels; ++idx) - { - int channel = m_event_data.sepd_channel->at(idx); - double charge = m_event_data.sepd_charge->at(idx); - double phi = m_event_data.sepd_phi->at(idx); - - // Skip Bad Channels - if (m_bad_channels.contains(channel)) - { - continue; - } - - unsigned int key = TowerInfoDefs::encode_epd(static_cast(channel)); - unsigned int arm = TowerInfoDefs::get_epd_arm(key); - - // arm = 0: South - // arm = 1: North - double& sepd_total_charge = (arm == 0) ? sepd_total_charge_south : sepd_total_charge_north; - - // Compute total charge for the respective sEPD arm - sepd_total_charge += charge; - - // Compute Raw Q vectors for each harmonic and respective arm - for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) - { - int n = m_harmonics[h_idx]; - m_event_data.q_vectors[h_idx][arm].x += charge * std::cos(n * phi); - m_event_data.q_vectors[h_idx][arm].y += charge * std::sin(n * phi); - } - } - - // Skip Events with Zero sEPD Total Charge in either arm - if (sepd_total_charge_south == 0 || sepd_total_charge_north == 0) + else if (ec) { - return false; + throw std::runtime_error(std::format("Failed to create directory {}: {}", m_cdb_output_dir, ec.message())); } - - // Normalize the Q-vectors by total charge - for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + else { - for (auto det : m_subdetectors) - { - size_t det_idx = (det == QVecShared::Subdetector::S) ? 0 : 1; - double sepd_total_charge = (det_idx == 0) ? sepd_total_charge_south : sepd_total_charge_north; - m_event_data.q_vectors[h_idx][det_idx].x /= sepd_total_charge; - m_event_data.q_vectors[h_idx][det_idx].y /= sepd_total_charge; - } + std::cout << "Info: Directory " << m_cdb_output_dir << " already exists." << std::endl; } - return true; + write_cdb_BadTowers(); + write_cdb_EventPlane(); } -std::vector QVecCalib::prepare_recenter_hists() +void QVecCalib::write_cdb_BadTowers() { - std::vector hists_cache; - for (int n : m_harmonics) - { - std::string S_x_corr_avg_name = QVecShared::get_hist_name("S", "x", n, "_corr"); - std::string S_y_corr_avg_name = QVecShared::get_hist_name("S", "y", n, "_corr"); - std::string N_x_corr_avg_name = QVecShared::get_hist_name("N", "x", n, "_corr"); - std::string N_y_corr_avg_name = QVecShared::get_hist_name("N", "y", n, "_corr"); + std::cout << "Writing Bad Towers CDB" << std::endl; - std::string S_xx_avg_name = QVecShared::get_hist_name("S", "xx", n); - std::string S_yy_avg_name = QVecShared::get_hist_name("S", "yy", n); - std::string S_xy_avg_name = QVecShared::get_hist_name("S", "xy", n); - std::string N_xx_avg_name = QVecShared::get_hist_name("N", "xx", n); - std::string N_yy_avg_name = QVecShared::get_hist_name("N", "yy", n); - std::string N_xy_avg_name = QVecShared::get_hist_name("N", "xy", n); + std::string payload = "SEPD_HotMap"; + std::string fieldname_status = "status"; + std::string fieldname_sigma = "SEPD_sigma"; + std::string output_file = std::format("{}/{}-{}-{}.root", m_cdb_output_dir, payload, m_dst_tag, m_runnumber); - std::string NS_xx_avg_name = QVecShared::get_hist_name("NS", "xx", n); - std::string NS_yy_avg_name = QVecShared::get_hist_name("NS", "yy", n); - std::string NS_xy_avg_name = QVecShared::get_hist_name("NS", "xy", n); - - std::string psi_S_name = std::format("h2_sEPD_Psi_S_{}_corr", n); - std::string psi_N_name = std::format("h2_sEPD_Psi_N_{}_corr", n); - std::string psi_NS_name = std::format("h2_sEPD_Psi_NS_{}_corr", n); - - RecenterHists h; - - h.S_x_corr_avg = m_profiles.at(S_x_corr_avg_name).get(); - h.S_y_corr_avg = m_profiles.at(S_y_corr_avg_name).get(); - h.N_x_corr_avg = m_profiles.at(N_x_corr_avg_name).get(); - h.N_y_corr_avg = m_profiles.at(N_y_corr_avg_name).get(); - - h.S_xx_avg = m_profiles.at(S_xx_avg_name).get(); - h.S_yy_avg = m_profiles.at(S_yy_avg_name).get(); - h.S_xy_avg = m_profiles.at(S_xy_avg_name).get(); - h.N_xx_avg = m_profiles.at(N_xx_avg_name).get(); - h.N_yy_avg = m_profiles.at(N_yy_avg_name).get(); - h.N_xy_avg = m_profiles.at(N_xy_avg_name).get(); - - h.NS_xx_avg = m_profiles.at(NS_xx_avg_name).get(); - h.NS_yy_avg = m_profiles.at(NS_yy_avg_name).get(); - h.NS_xy_avg = m_profiles.at(NS_xy_avg_name).get(); - - h.Psi_S_corr = m_hists2D.at(psi_S_name).get(); - h.Psi_N_corr = m_hists2D.at(psi_N_name).get(); - h.Psi_NS_corr = m_hists2D.at(psi_NS_name).get(); + CDBTTree cdbttree(output_file); - hists_cache.push_back(h); - } - - return hists_cache; -} - -std::vector QVecCalib::prepare_flattening_hists() -{ - std::vector hists_cache; - for (int n : m_harmonics) + for (int channel = 0; channel < QVecShared::SEPD_CHANNELS; ++channel) { + unsigned int key = TowerInfoDefs::encode_epd(channel); + int status = hSEPD_Bad_Channels->GetBinContent(channel+1); - std::string S_x_corr2_avg_name = QVecShared::get_hist_name("S", "x", n, "_corr2"); - std::string S_y_corr2_avg_name = QVecShared::get_hist_name("S", "y", n, "_corr2"); - std::string N_x_corr2_avg_name = QVecShared::get_hist_name("N", "x", n, "_corr2"); - std::string N_y_corr2_avg_name = QVecShared::get_hist_name("N", "y", n, "_corr2"); + float sigma = 0; - std::string S_xx_corr_avg_name = QVecShared::get_hist_name("S", "xx", n, "_corr"); - std::string S_yy_corr_avg_name = QVecShared::get_hist_name("S", "yy", n, "_corr"); - std::string S_xy_corr_avg_name = QVecShared::get_hist_name("S", "xy", n, "_corr"); - std::string N_xx_corr_avg_name = QVecShared::get_hist_name("N", "xx", n, "_corr"); - std::string N_yy_corr_avg_name = QVecShared::get_hist_name("N", "yy", n, "_corr"); - std::string N_xy_corr_avg_name = QVecShared::get_hist_name("N", "xy", n, "_corr"); - - std::string NS_xx_corr_avg_name = QVecShared::get_hist_name("NS", "xx", n, "_corr"); - std::string NS_yy_corr_avg_name = QVecShared::get_hist_name("NS", "yy", n, "_corr"); - std::string NS_xy_corr_avg_name = QVecShared::get_hist_name("NS", "xy", n, "_corr"); - - std::string psi_S_name = std::format("h2_sEPD_Psi_S_{}_corr2", n); - std::string psi_N_name = std::format("h2_sEPD_Psi_N_{}_corr2", n); - std::string psi_NS_name = std::format("h2_sEPD_Psi_NS_{}_corr2", n); - - FlatteningHists h; - - h.S_x_corr2_avg = m_profiles.at(S_x_corr2_avg_name).get(); - h.S_y_corr2_avg = m_profiles.at(S_y_corr2_avg_name).get(); - h.N_x_corr2_avg = m_profiles.at(N_x_corr2_avg_name).get(); - h.N_y_corr2_avg = m_profiles.at(N_y_corr2_avg_name).get(); - - h.S_xx_corr_avg = m_profiles.at(S_xx_corr_avg_name).get(); - h.S_yy_corr_avg = m_profiles.at(S_yy_corr_avg_name).get(); - h.S_xy_corr_avg = m_profiles.at(S_xy_corr_avg_name).get(); - - h.N_xx_corr_avg = m_profiles.at(N_xx_corr_avg_name).get(); - h.N_yy_corr_avg = m_profiles.at(N_yy_corr_avg_name).get(); - h.N_xy_corr_avg = m_profiles.at(N_xy_corr_avg_name).get(); - - h.NS_xx_corr_avg = m_profiles.at(NS_xx_corr_avg_name).get(); - h.NS_yy_corr_avg = m_profiles.at(NS_yy_corr_avg_name).get(); - h.NS_xy_corr_avg = m_profiles.at(NS_xy_corr_avg_name).get(); + // Hot + if (status == static_cast(QVecShared::ChannelStatus::Hot)) + { + sigma = SIGMA_HOT; + } - h.Psi_S_corr2 = m_hists2D.at(psi_S_name).get(); - h.Psi_N_corr2 = m_hists2D.at(psi_N_name).get(); - h.Psi_NS_corr2 = m_hists2D.at(psi_NS_name).get(); + // Cold + else if (status == static_cast(QVecShared::ChannelStatus::Cold)) + { + sigma = SIGMA_COLD; + } - hists_cache.push_back(h); + cdbttree.SetIntValue(key, fieldname_status, status); + cdbttree.SetFloatValue(key, fieldname_sigma, sigma); } - return hists_cache; -} + std::cout << "Saving CDB: " << payload << " to " << output_file << std::endl; -bool QVecCalib::process_event_check() -{ - auto* hSEPD_Charge_Min = m_profiles["hSEPD_Charge_Min"].get(); - auto* hSEPD_Charge_Max = m_profiles["hSEPD_Charge_Max"].get(); - - double cent = m_event_data.event_centrality; - int cent_bin = hSEPD_Charge_Min->FindBin(cent); - - double sepd_totalcharge = m_event_data.sepd_totalcharge; - - double sepd_totalcharge_min = hSEPD_Charge_Min->GetBinContent(cent_bin); - double sepd_totalcharge_max = hSEPD_Charge_Max->GetBinContent(cent_bin); - - return sepd_totalcharge > sepd_totalcharge_min && sepd_totalcharge < sepd_totalcharge_max; + cdbttree.Commit(); + cdbttree.WriteCDBTTree(); } -void QVecCalib::run_event_loop() +void QVecCalib::write_cdb_EventPlane() { - std::cout << std::format("Pass: {}\n", static_cast(m_pass)); + std::cout << "Writing Event Plane CDB" << std::endl; - long long n_entries = m_chain->GetEntries(); - if (m_events_to_process > 0) - { - n_entries = std::min(m_events_to_process, n_entries); - } + std::string payload = "SEPD_EventPlaneCalib"; + std::string output_file = std::format("{}/{}-{}-{}.root", m_cdb_output_dir, payload, m_dst_tag, m_runnumber); - std::vector average_hists; - std::vector recenter_hists; - std::vector flattening_hists; + CDBTTree cdbttree(output_file); - if (m_pass == Pass::ComputeRecentering) - { - average_hists = prepare_average_hists(); - } - else if (m_pass == Pass::ApplyRecentering) - { - recenter_hists = prepare_recenter_hists(); - } - else if (m_pass == Pass::ApplyFlattening) - { - flattening_hists = prepare_flattening_hists(); - } + using SD = QVecShared::Subdetector; - std::map ctr; - // Event Loop - for (long long i = 0; i < n_entries; ++i) + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) { - // Load Event Data from TChain - m_chain->GetEntry(i); - m_event_data.reset(); - - if (i % PROGRESS_REPORT_INTERVAL == 0) - { - std::cout << std::format("Processing {}/{}: {:.2f} %", i, n_entries, static_cast(i) / n_entries * 100.) << std::endl; - } - - double cent = m_event_data.event_centrality; - - int cent_bin_int = m_hists1D["h_Cent"]->FindBin(cent) - 1; - - // ensure centrality is valid - if (cent_bin_int < 0 || static_cast(cent_bin_int) >= m_cent_bins) - { - std::cout << std::format("Weird Centrality: {}, Skipping Event: {}\n", cent, m_event_data.event_id); - ++ctr["invalid_cent_bin"]; - continue; - } - - bool isGood = process_event_check(); - - // Skip Events with non correlation between centrality and sEPD - if (!isGood) - { - ++ctr["bad_centrality_sepd_correlation"]; - continue; - } - - isGood = process_sEPD(); + int n = m_harmonics[h_idx]; - // Skip Events with Zero sEPD Total Charge in either arm - if (!isGood) + // Define lambdas to generate field names consistently + auto field = [&](const std::string& det, const std::string& var) { - ++ctr["zero_sepd_total_charge"]; - continue; - } + return std::format("Q_{}_{}_{}_avg", det, var, n); + }; - m_hists1D["h_Cent"]->Fill(cent); - - for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + for (size_t cent_bin = 0; cent_bin < m_cent_bins; ++cent_bin) { - const auto& q_S = m_event_data.q_vectors[h_idx][0]; // 0 for South - const auto& q_N = m_event_data.q_vectors[h_idx][1]; // 1 for North + int key = static_cast(cent_bin); - // --- First Pass: Derive 1st Order --- - if (m_pass == Pass::ComputeRecentering) + // Iterate through all subdetectors (S, N, NS) using the Enum Count + for (size_t d = 0; d < static_cast(SD::Count); ++d) { - process_averages(cent, q_S, q_N, average_hists[h_idx]); - } + auto det_enum = static_cast(d); - // --- Second Pass: Apply 1st Order, Derive 2nd Order --- - else if (m_pass == Pass::ApplyRecentering) - { - process_recentering(cent, h_idx, q_S, q_N, recenter_hists[h_idx]); - } + // Map enum to the string labels used in the CDB field names + std::string det_label; + switch (det_enum) + { + case SD::S: + det_label = "S"; + break; + case SD::N: + det_label = "N"; + break; + case SD::NS: + det_label = "NS"; + break; + default: + continue; + } - // --- Third Pass: Apply 2nd Order, Validate --- - else if (m_pass == Pass::ApplyFlattening) - { - process_flattening(cent, h_idx, q_S, q_N, flattening_hists[h_idx]); + const auto& data = m_correction_data[cent_bin][h_idx][d]; + // 1st Order Moments (Recentering) - Skip for NS as it is a combined vector + if (det_enum != SD::NS) + { + cdbttree.SetDoubleValue(key, field(det_label, "x"), data.avg_Q.x); + cdbttree.SetDoubleValue(key, field(det_label, "y"), data.avg_Q.y); + } + + // 2nd Order Moments (Flattening) - Applicable to S, N, and NS + cdbttree.SetDoubleValue(key, field(det_label, "xx"), data.avg_Q_xx); + cdbttree.SetDoubleValue(key, field(det_label, "yy"), data.avg_Q_yy); + cdbttree.SetDoubleValue(key, field(det_label, "xy"), data.avg_Q_xy); } } } - std::cout << "Skipped Event Types\n"; - for (const auto& [name, events] : ctr) - { - std::cout << std::format("{}: {}, {:.2f} %\n", name, events, static_cast(events) / n_entries * 100.); - } + std::cout << "Saving CDB: " << payload << " to " << output_file << std::endl; + + cdbttree.Commit(); + cdbttree.WriteCDBTTree(); +} + +//____________________________________________________________________________.. +int QVecCalib::End([[maybe_unused]] PHCompositeNode *topNode) +{ + std::cout << "QVecCalib::End(PHCompositeNode *topNode) This is the End..." << std::endl; - // --------------- + std::cout << "\n--- Event Counter Summary ---" << std::endl; + std::cout << "Bad Centrality/sEPD corr: " << m_event_counters.bad_centrality_sepd_correlation << std::endl; + std::cout << "Zero sEPD Charge: " << m_event_counters.zero_sepd_total_charge << std::endl; + std::cout << "Total Events Seen: " << m_event << std::endl; + std::cout << "-----------------------------\n" << std::endl; - std::cout << std::format("{:#<20}\n", ""); for (size_t cent_bin = 0; cent_bin < m_cent_bins; ++cent_bin) { for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) @@ -1108,160 +1401,10 @@ void QVecCalib::run_event_loop() } } - std::cout << "Event loop finished." << std::endl; -} - -template -std::unique_ptr QVecCalib::load_and_clone(TFile* file, const std::string& name) { - auto* obj = dynamic_cast(file->Get(name.c_str())); - if (!obj) - { - throw std::runtime_error(std::format("Could not find histogram '{}' in file '{}'", name, file->GetName())); - } - return std::unique_ptr(static_cast(obj->Clone())); -} - -void QVecCalib::load_correction_data() -{ - TH1::AddDirectory(kFALSE); - - auto file = std::unique_ptr(TFile::Open(m_input_Q_calib.c_str())); - - // Check if the file was opened successfully. - if (!file || file->IsZombie()) - { - throw std::runtime_error(std::format("Could not open file '{}'", m_input_Q_calib)); - } - - for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) - { - int n = m_harmonics[h_idx]; - - std::string S_x_avg_name = QVecShared::get_hist_name("S", "x", n); - std::string S_y_avg_name = QVecShared::get_hist_name("S", "y", n); - std::string N_x_avg_name = QVecShared::get_hist_name("N", "x", n); - std::string N_y_avg_name = QVecShared::get_hist_name("N", "y", n); - - m_profiles[S_x_avg_name] = load_and_clone(file.get(), S_x_avg_name); - m_profiles[S_y_avg_name] = load_and_clone(file.get(), S_y_avg_name); - m_profiles[N_x_avg_name] = load_and_clone(file.get(), N_x_avg_name); - m_profiles[N_y_avg_name] = load_and_clone(file.get(), N_y_avg_name); - - std::string S_xx_avg_name = QVecShared::get_hist_name("S", "xx", n); - std::string S_yy_avg_name = QVecShared::get_hist_name("S", "yy", n); - std::string S_xy_avg_name = QVecShared::get_hist_name("S", "xy", n); - std::string N_xx_avg_name = QVecShared::get_hist_name("N", "xx", n); - std::string N_yy_avg_name = QVecShared::get_hist_name("N", "yy", n); - std::string N_xy_avg_name = QVecShared::get_hist_name("N", "xy", n); - - std::string NS_xx_avg_name = QVecShared::get_hist_name("NS", "xx", n); - std::string NS_yy_avg_name = QVecShared::get_hist_name("NS", "yy", n); - std::string NS_xy_avg_name = QVecShared::get_hist_name("NS", "xy", n); - - if(m_pass == Pass::ApplyFlattening) - { - m_profiles[S_xx_avg_name] = load_and_clone(file.get(), S_xx_avg_name); - m_profiles[S_yy_avg_name] = load_and_clone(file.get(), S_yy_avg_name); - m_profiles[S_xy_avg_name] = load_and_clone(file.get(), S_xy_avg_name); - - m_profiles[N_xx_avg_name] = load_and_clone(file.get(), N_xx_avg_name); - m_profiles[N_yy_avg_name] = load_and_clone(file.get(), N_yy_avg_name); - m_profiles[N_xy_avg_name] = load_and_clone(file.get(), N_xy_avg_name); - - m_profiles[NS_xx_avg_name] = load_and_clone(file.get(), NS_xx_avg_name); - m_profiles[NS_yy_avg_name] = load_and_clone(file.get(), NS_yy_avg_name); - m_profiles[NS_xy_avg_name] = load_and_clone(file.get(), NS_xy_avg_name); - } - - size_t south_idx = static_cast(QVecShared::Subdetector::S); - size_t north_idx = static_cast(QVecShared::Subdetector::N); - - for (size_t cent_bin = 0; cent_bin < m_cent_bins; ++cent_bin) - { - int bin = static_cast(cent_bin) + 1; - - double Q_S_x_avg = m_profiles[S_x_avg_name]->GetBinContent(bin); - double Q_S_y_avg = m_profiles[S_y_avg_name]->GetBinContent(bin); - double Q_N_x_avg = m_profiles[N_x_avg_name]->GetBinContent(bin); - double Q_N_y_avg = m_profiles[N_y_avg_name]->GetBinContent(bin); - - // Recentering Params - m_correction_data[cent_bin][h_idx][south_idx].avg_Q = {Q_S_x_avg, Q_S_y_avg}; - m_correction_data[cent_bin][h_idx][north_idx].avg_Q = {Q_N_x_avg, Q_N_y_avg}; - - if (m_pass == Pass::ApplyFlattening) - { - double Q_S_xx_avg = m_profiles[S_xx_avg_name]->GetBinContent(bin); - double Q_S_yy_avg = m_profiles[S_yy_avg_name]->GetBinContent(bin); - double Q_S_xy_avg = m_profiles[S_xy_avg_name]->GetBinContent(bin); - - double Q_N_xx_avg = m_profiles[N_xx_avg_name]->GetBinContent(bin); - double Q_N_yy_avg = m_profiles[N_yy_avg_name]->GetBinContent(bin); - double Q_N_xy_avg = m_profiles[N_xy_avg_name]->GetBinContent(bin); - - double Q_NS_xx_avg = m_profiles[NS_xx_avg_name]->GetBinContent(bin); - double Q_NS_yy_avg = m_profiles[NS_yy_avg_name]->GetBinContent(bin); - double Q_NS_xy_avg = m_profiles[NS_xy_avg_name]->GetBinContent(bin); - - m_correction_data[cent_bin][h_idx][IDX_NS].X_matrix = calculate_flattening_matrix(Q_NS_xx_avg, Q_NS_yy_avg, Q_NS_xy_avg, n, cent_bin, "NS"); - - // Flattening Params - for (size_t det_idx = 0; det_idx < 2; ++det_idx) - { - double xx = (det_idx == 0) ? Q_S_xx_avg : Q_N_xx_avg; - double yy = (det_idx == 0) ? Q_S_yy_avg : Q_N_yy_avg; - double xy = (det_idx == 0) ? Q_S_xy_avg : Q_N_xy_avg; - - std::string label = (det_idx == 0) ? "S" : "N"; - - m_correction_data[cent_bin][h_idx][det_idx].X_matrix = calculate_flattening_matrix(xx, yy, xy, n, cent_bin, label); - } - } - } - } -} - -void QVecCalib::process_events() -{ - if (m_pass == Pass::ApplyRecentering || m_pass == Pass::ApplyFlattening) - { - load_correction_data(); - } - - run_event_loop(); -} - -void QVecCalib::save_results() const -{ - std::filesystem::create_directories(m_output_dir); - - std::filesystem::path input_path(m_input_file); - std::string output_stem = input_path.stem().string(); - std::string output_filename = std::format("{}/Q-vec-corr_Pass-{}_{}.root", m_output_dir, static_cast(m_pass), output_stem); - - auto output_file = std::make_unique(output_filename.c_str(), "RECREATE"); - - if (!output_file || output_file->IsZombie()) - { - throw std::runtime_error(std::format("Failed to create output file: {}", output_filename)); - } - - for (const auto& [name, hist] : m_hists1D) - { - std::cout << std::format("Saving 1D: {}\n", name); - hist->Write(); - } - for (const auto& [name, hist] : m_hists2D) - { - std::cout << std::format("Saving 2D: {}\n", name); - hist->Write(); - } - for (const auto& [name, hist] : m_profiles) + if (m_pass == Pass::ApplyFlattening) { - std::cout << std::format("Saving Profile: {}\n", name); - hist->Write(); + write_cdb(); } - output_file->Close(); - std::cout << std::format("Results saved to: {}", output_filename) << std::endl; + return Fun4AllReturnCodes::EVENT_OK; } diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.h b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.h index 7a70cfb03e..a0029949d8 100644 --- a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.h +++ b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.h @@ -3,23 +3,22 @@ #include "QVecDefs.h" -// ==================================================================== -// ROOT Includes -// ==================================================================== +#include + +#include +#include +#include +#include +#include -#include #include #include #include #include -// ==================================================================== -// Standard C++ Includes -// ==================================================================== -#include -#include -#include -#include +class PHCompositeNode; +class EventPlaneData; +class EpdGeom; /** * @class QVecCalib @@ -36,28 +35,34 @@ * * The class manages event-level selections based on charge-centrality correlations * and handles the exclusion of "bad" (hot/cold/dead) sEPD channels. */ -class QVecCalib +class QVecCalib : public SubsysReco { public: - // The constructor takes the configuration - QVecCalib(std::string input_file, std::string input_hist, std::string input_Q_calib, int pass, long long events, std::string output_dir) - : m_input_file(std::move(input_file)) - , m_input_hist(std::move(input_hist)) - , m_input_Q_calib(std::move(input_Q_calib)) - , m_pass(validate_pass(pass)) - , m_events_to_process(events) - , m_output_dir(std::move(output_dir)) - { - } + explicit QVecCalib(const std::string& name = "QVecCalib"); - void run() - { - setup_chain(); - process_QA_hist(); - init_hists(); - process_events(); - save_results(); - } + /** Called during initialization. + Typically this is where you can book histograms, and e.g. + register them to Fun4AllServer (so they can be output to file + using Fun4AllServer::dumpHistos() method). + */ + int Init(PHCompositeNode* topNode) override; + + /** Called for first event when run number is known. + Typically this is where you may want to fetch data from + database, because you know the run number. + */ + int InitRun(PHCompositeNode *topNode) override; + + /** Called for each event. + This is where you do the real work. + */ + int process_event(PHCompositeNode* topNode) override; + + /// Clean up internals after each event. + int ResetEvent(PHCompositeNode* topNode) override; + + /// Called at the end of all processing. + int End(PHCompositeNode* topNode) override; enum class Pass { @@ -66,6 +71,31 @@ class QVecCalib ApplyFlattening }; + void set_pass(int pass) + { + m_pass = validate_pass(pass); + } + + void set_input_hist(std::string_view file) + { + m_input_hist = file; + } + + void set_input_Q_calib(std::string_view file) + { + m_input_Q_calib = file; + } + + void set_dst_tag(std::string_view tag) + { + m_dst_tag = tag; + } + + void set_cdb_output_dir(std::string_view cdb_dir) + { + m_cdb_output_dir = cdb_dir; + } + private: static Pass validate_pass(int pass) { @@ -85,15 +115,45 @@ class QVecCalib struct CorrectionData { QVecShared::QVec avg_Q{}; + + double avg_Q_xx{0.0}; + double avg_Q_yy{0.0}; + double avg_Q_xy{0.0}; + std::array, 2> X_matrix{}; }; static constexpr size_t m_cent_bins = QVecShared::CENT_BINS; static constexpr auto m_harmonics = QVecShared::HARMONICS; - double m_cent_low = -0.5; - double m_cent_high = 79.5; - static constexpr int PROGRESS_REPORT_INTERVAL = 10000; + static constexpr float SIGMA_HOT = 6.0F; + static constexpr float SIGMA_COLD = -6.0F; + + double m_cent_low{-0.5}; + double m_cent_high{79.5}; + + std::string m_input_hist; + std::string m_input_Q_calib; + std::string m_dst_tag; + std::string m_cdb_output_dir{"."}; + Pass m_pass{Pass::ComputeRecentering}; + EventPlaneData* m_evtdata{nullptr}; + + int m_event{0}; + int m_runnumber{0}; + + struct EventCounters + { + int bad_centrality_sepd_correlation{0}; + int zero_sepd_total_charge{0}; + int total_processed{0}; + }; + + EventCounters m_event_counters; + + std::array, m_harmonics.size()> m_q_vectors{}; + + static constexpr int PROGRESS_REPORT_INTERVAL = 1000; // Holds all correction data // key: [Cent][Harmonic][Subdetector] @@ -101,37 +161,12 @@ class QVecCalib // Subdetectors {S,N,NS} -> 3 elements std::array, m_harmonics.size()>, m_cent_bins> m_correction_data; - static constexpr size_t IDX_NS = 2; - // Store harmonic orders and subdetectors for easy iteration static constexpr std::array m_subdetectors = {QVecShared::Subdetector::S, QVecShared::Subdetector::N}; static constexpr std::array m_components = {QVecShared::QComponent::X, QVecShared::QComponent::Y}; - struct EventData - { - int event_id{0}; // NOLINT(misc-non-private-member-variables-in-classes) - double event_zvertex{0.0}; // NOLINT(misc-non-private-member-variables-in-classes) - double event_centrality{0.0}; // NOLINT(misc-non-private-member-variables-in-classes) - double sepd_totalcharge{0.0}; // NOLINT(misc-non-private-member-variables-in-classes) - - std::array, m_harmonics.size()> q_vectors; // NOLINT(misc-non-private-member-variables-in-classes) - - void reset() - { - for (auto& q_vec_harmonic : q_vectors) - { - for (auto& q_vec : q_vec_harmonic) - { - q_vec.x = 0.0; - q_vec.y = 0.0; - } - } - } - - std::vector* sepd_channel{nullptr}; // NOLINT(misc-non-private-member-variables-in-classes) - std::vector* sepd_charge{nullptr}; // NOLINT(misc-non-private-member-variables-in-classes) - std::vector* sepd_phi{nullptr}; // NOLINT(misc-non-private-member-variables-in-classes) - }; + // [Harmonic Index][Channel Index] -> {cos, sin} + std::vector>> m_trig_cache; struct AverageHists { @@ -192,224 +227,209 @@ class QVecCalib TH2* Psi_NS_corr2{nullptr}; }; - // --- Member Variables --- - EventData m_event_data; - std::unique_ptr m_chain; - - // Configuration stored as members - std::string m_input_file; - std::string m_input_hist; - std::string m_input_Q_calib; - Pass m_pass{Pass::ComputeRecentering}; - long long m_events_to_process; - std::string m_output_dir; - - // Hists - std::map> m_hists1D; - std::map> m_hists2D; - std::map> m_profiles; - // sEPD Bad Channels std::unordered_set m_bad_channels; double m_sEPD_min_avg_charge_threshold{1}; double m_sEPD_sigma_threshold{3}; - // --- Private Helper Methods --- + // Hists + TH1* hCentrality{nullptr}; + + TH2* h2SEPD_Charge{nullptr}; + TH2* h2SEPD_Chargev2{nullptr}; -/** - * @brief Sets up a TChain and performs structural validation of the input ROOT file. - * * Verifies file existence, ensures the requested TTree exists, and checks for - * non-zero entries before returning a configured chain. - * * @param input_filepath Path to the input .root file. - * @param tree_name_in_file Name of the TTree inside the file. - * @return std::unique_ptr A configured TChain, or nullptr if validation fails. - */ - std::unique_ptr setupTChain(const std::string& input_filepath, const std::string& tree_name_in_file); + TH2* h2SEPD_South_Charge_rbin{nullptr}; + TH2* h2SEPD_North_Charge_rbin{nullptr}; -/** - * @brief Orchestrates the TChain initialization and branch configuration. - * * Sets the branch statuses and addresses for event-level data (ID, centrality, charge) - * and sEPD tower-level data (channel, charge, phi) needed for the calibration. - */ - void setup_chain(); + TH2* h2SEPD_South_Charge_rbinv2{nullptr}; + TH2* h2SEPD_North_Charge_rbinv2{nullptr}; -/** - * @brief Initializes all output histograms and profiles. - * * Dynamically generates histogram names using the shared naming helper based on - * the current calibration pass (e.g., adding "_corr" or "_corr2" suffixes). - */ - void init_hists(); + TProfile* hSEPD_Charge_Min{nullptr}; + TProfile* hSEPD_Charge_Max{nullptr}; -/** - * @brief Safely retrieves a ROOT object from a file and returns a managed unique_ptr. - * * Performs a dynamic_cast to verify the requested type T and Clones the object - * to ensure it remains valid after the source file is closed. - * * @tparam T The ROOT class type (e.g., TProfile). - * @param file Pointer to the source TFile. - * @param name The name of the object within the file. - * @return std::unique_ptr A managed pointer to the cloned object. - * @throws std::runtime_error If the object is not found or type mismatch occurs. - */ - template - std::unique_ptr load_and_clone(TFile* file, const std::string& name); + TProfile* hSEPD_Bad_Channels{nullptr}; -/** - * @brief Loads the results of previous passes from a calibration file. - * * Populates the internal correction data structure with averages and/or - * matrices required for the current processing pass. - */ - void load_correction_data(); + std::map m_hists2D; + std::map m_profiles; -/** - * @brief High-level orchestrator for the event processing phase. - * * If the current pass requires existing calibration data (Recentering or Flattening), - * it triggers the data loading sequence before starting the main event loop. - */ - void process_events(); + std::vector m_average_hists; + std::vector m_recenter_hists; + std::vector m_flattening_hists; -/** - * @brief Validates events based on sEPD total charge vs. centrality correlation. - * * Compares the current event's total charge against the 3-sigma bounds derived - * from the QA histograms to reject pile-up or background-dominated events. - * @return True if the event falls within the acceptable charge window. - */ + /** + * @brief Initializes all output histograms and profiles. + * * Dynamically generates histogram names using the shared naming helper based on + * the current calibration pass (e.g., adding "_corr" or "_corr2" suffixes). + */ + void init_hists(); + + /** + * @brief Safely retrieves a ROOT object from a file and returns a managed pointer. + * * Performs a dynamic_cast to verify the requested type T and Clones the object + * to ensure it remains valid after the source file is closed. + * * @tparam T The ROOT class type (e.g., TProfile). + * @param file Pointer to the source TFile. + * @param name The name of the object within the file. + * @return T* A managed pointer to the cloned object. + * @throws std::runtime_error If the object is not found or type mismatch occurs. + */ + template + T* load_and_clone(TFile* file, const std::string& name); + + /** + * @brief Loads the results of previous passes from a calibration file. + * * Populates the internal correction data structure with averages and/or + * matrices required for the current processing pass. + */ + int load_correction_data(); + + /** + * @brief Validates events based on sEPD total charge vs. centrality correlation. + * * Compares the current event's total charge against the 3-sigma bounds derived + * from the QA histograms to reject pile-up or background-dominated events. + * @return True if the event falls within the acceptable charge window. + */ bool process_event_check(); -/** - * @brief Performs the primary tower-by-tower Q-vector calculation and normalization. - * * Loops through sEPD channels, excludes bad channels, calculates the raw Q-vector - * for all harmonics, and normalizes the results by the total arm charge. - * @return True if both South and North arms have non-zero total charge. - */ + /** + * @brief Performs the primary tower-by-tower Q-vector calculation and normalization. + * * Loops through sEPD channels, excludes bad channels, calculates the raw Q-vector + * for all harmonics, and normalizes the results by the total arm charge. + * @return True if both South and North arms have non-zero total charge. + */ bool process_sEPD(); -/** - * @brief Primary event loop orchestrator. - * * Iterates through the TChain entries, performs event selection, executes - * normalization/re-centering/flattening logic based on the current pass, - * and fills the output histograms. - */ - void run_event_loop(); - -/** - * @brief Finalizes the analysis by writing all histograms to the output ROOT file. - * * Creates the output directory if it does not exist and ensures all 1D, 2D - * and TProfiles are safely persisted to disk. - */ - void save_results() const; - -/** - * @brief Calculates and fills profiles for the initial Q-vector averages. - * @param cent The event centrality. - * @param q_S The South arm normalized Q-vector. - * @param q_N The North arm normalized Q-vector. - * @param h Reference to the cache of profiles for the first pass. - */ + /** + * @brief Calculates and fills profiles for the initial Q-vector averages. + * @param cent The event centrality. + * @param q_S The South arm normalized Q-vector. + * @param q_N The North arm normalized Q-vector. + * @param h Reference to the cache of profiles for the first pass. + */ static void process_averages(double cent, const QVecShared::QVec& q_S, const QVecShared::QVec& q_N, const AverageHists& h); -/** - * @brief Applies re-centering offsets and fills profiles for second-moment calculation. - * @param cent The event centrality. - * @param h_idx Harmonic index. - * @param q_S The South arm normalized Q-vector. - * @param q_N The North arm normalized Q-vector. - * @param h Reference to the cache of profiles for the second pass. - */ + /** + * @brief Applies re-centering offsets and fills profiles for second-moment calculation. + * @param cent The event centrality. + * @param h_idx Harmonic index. + * @param q_S The South arm normalized Q-vector. + * @param q_N The North arm normalized Q-vector. + * @param h Reference to the cache of profiles for the second pass. + */ void process_recentering(double cent, size_t h_idx, const QVecShared::QVec& q_S, const QVecShared::QVec& q_N, const RecenterHists& h); -/** - * @brief Applies the full correction (re-centering + flattening) for validation. - * @param cent The event centrality. - * @param h_idx Harmonic index. - * @param q_S The South arm normalized Q-vector. - * @param q_N The North arm normalized Q-vector. - * @param h Reference to the cache of profiles for the third pass. - */ + /** + * @brief Applies the full correction (re-centering + flattening) for validation. + * @param cent The event centrality. + * @param h_idx Harmonic index. + * @param q_S The South arm normalized Q-vector. + * @param q_N The North arm normalized Q-vector. + * @param h Reference to the cache of profiles for the third pass. + */ void process_flattening(double cent, size_t h_idx, const QVecShared::QVec& q_S, const QVecShared::QVec& q_N, const FlatteningHists& h); -/** - * @brief Calculates the 2x2 anisotropy correction (whitening) matrix. - * * This matrix transforms the elliptical Q-vector distribution into a circularly - * symmetric (isotropic) distribution. It effectively corrects for detector - * acceptance effects and gain non-uniformities by normalizing the second-order - * moments of the Q-vector. - * * @param xx The second moment. - * @param yy The second moment. - * @param xy The cross-moment. - * @param n Harmonic order (used for error logging context). - * @param cent_bin Centrality bin (used for error logging context). - * @param det_label Detector label ("S" or "N"). - * @return std::array, 2> The 2x2 correction matrix. - */ + /** + * @brief Calculates the 2x2 anisotropy correction (whitening) matrix. + * * This matrix transforms the elliptical Q-vector distribution into a circularly + * symmetric (isotropic) distribution. It effectively corrects for detector + * acceptance effects and gain non-uniformities by normalizing the second-order + * moments of the Q-vector. + * * @param xx The second moment. + * @param yy The second moment. + * @param xy The cross-moment. + * @param n Harmonic order (used for error logging context). + * @param cent_bin Centrality bin (used for error logging context). + * @param det_label Detector label ("S" or "N"). + * @return std::array, 2> The 2x2 correction matrix. + */ std::array, 2> calculate_flattening_matrix(double xx, double yy, double xy, int n, int cent_bin, const std::string& det_label); - -/** - * @brief Computes 1st-order re-centering offsets for a specific centrality bin. - * * Extracts average Q-vector components from histograms and stores them in the - * correction data matrix for use in subsequent processing passes. - * * @param cent_bin The index of the centrality bin. - * @param h_idx The index of the harmonic order in the harmonics array. - */ + /** + * @brief Computes 1st-order re-centering offsets for a specific centrality bin. + * * Extracts average Q-vector components from histograms and stores them in the + * correction data matrix for use in subsequent processing passes. + * * @param cent_bin The index of the centrality bin. + * @param h_idx The index of the harmonic order in the harmonics array. + */ void compute_averages(size_t cent_bin, int h_idx); -/** - * @brief Computes re-centering parameters and solves the flattening matrices. - * * Extracts the re-centered second moments from the profiles and populates the - * internal CorrectionData matrix with calculated flattening coefficients. - * @param cent_bin The centrality bin index. - * @param h_idx The harmonic index. - */ + /** + * @brief Computes re-centering parameters and solves the flattening matrices. + * * Extracts the re-centered second moments from the profiles and populates the + * internal CorrectionData matrix with calculated flattening coefficients. + * @param cent_bin The centrality bin index. + * @param h_idx The harmonic index. + */ void compute_recentering(size_t cent_bin, int h_idx); -/** - * @brief Logs the final corrected moments to verify successful flattening. - * @param cent_bin The centrality bin index. - * @param n The harmonic order. - */ + /** + * @brief Logs the final corrected moments to verify successful flattening. + * @param cent_bin The centrality bin index. + * @param n The harmonic order. + */ void print_flattening(size_t cent_bin, int n) const; -/** - * @brief Prepares a vector of pointers to histograms used in the first pass. - * @return A vector of AverageHists structs, indexed by harmonic. - */ - std::vector prepare_average_hists(); - -/** - * @brief Prepares a vector of pointers to histograms used in the second pass. - * @return A vector of RecenterHists structs, indexed by harmonic. - */ - std::vector prepare_recenter_hists(); - -/** - * @brief Prepares a vector of pointers to histograms used in the third pass. - * @return A vector of FlatteningHists structs, indexed by harmonic. - */ - std::vector prepare_flattening_hists(); - -/** - * @brief Top-level driver for processing Quality Assurance histograms. - * * Loads the reference histogram file to identify bad channels and establish - * event-level charge thresholds as a function of centrality. - */ - void process_QA_hist(); - -/** - * @brief Identifies and catalogs "Bad" (Hot, Cold, or Dead) sEPD channels. - * * Uses a reference charge histogram to compute Z-scores based on mean charge - * per radial bin. Channels exceeding the sigma threshold are added to the internal exclusion set. - * * @param file Pointer to the open TFile containing QA histograms. - */ - void process_bad_channels(TFile* file); - -/** - * @brief Establishes sEPD charge-cut thresholds for event selection. - * * Uses the 2D total charge vs. centrality distribution to derive mean and - * sigma values, generating a 1D profile of the selection window. - * @param file Pointer to the open QA histogram file. - */ - void process_sEPD_event_thresholds(TFile* file); + void prepare_hists(); + + /** + * @brief Prepares a vector of pointers to histograms used in the first pass. + * @return A vector of AverageHists structs, indexed by harmonic. + */ + void prepare_average_hists(); + + /** + * @brief Prepares a vector of pointers to histograms used in the second pass. + * @return A vector of RecenterHists structs, indexed by harmonic. + */ + void prepare_recenter_hists(); + + /** + * @brief Prepares a vector of pointers to histograms used in the third pass. + * @return A vector of FlatteningHists structs, indexed by harmonic. + */ + void prepare_flattening_hists(); + + /** + * @brief Top-level driver for processing Quality Assurance histograms. + * * Loads the reference histogram file to identify bad channels and establish + * event-level charge thresholds as a function of centrality. + */ + int process_QA_hist(); + + /** + * @brief Identifies and catalogs "Bad" (Hot, Cold, or Dead) sEPD channels. + * * Uses a reference charge histogram to compute Z-scores based on mean charge + * per radial bin. Channels exceeding the sigma threshold are added to the internal exclusion set. + * * @param file Pointer to the open TFile containing QA histograms. + */ + int process_bad_channels(TFile* file); + + /** + * @brief Establishes sEPD charge-cut thresholds for event selection. + * * Uses the 2D total charge vs. centrality distribution to derive mean and + * sigma values, generating a 1D profile of the selection window. + * @param file Pointer to the open QA histogram file. + */ + int process_sEPD_event_thresholds(TFile* file); + + void write_cdb(); + + /** + * @brief Writes the Event Plane calibration constants to a CDB-formatted TTree. + * * Formats the re-centering and flattening moments into a CDBTTree payload + * indexed by centrality bin for sPHENIX database integration. + * * @param output_dir The filesystem directory where the .root payload will be saved. + */ + void write_cdb_EventPlane(); + + /** + * @brief Writes the Hot/Cold tower status map to a CDB-formatted TTree. + * * Encodes sEPD channel indices into TowerInfo keys and maps status codes (1=Dead, + * 2=Hot, 3=Cold) to the final database payload. + * * @param output_dir The filesystem directory where the .root payload will be saved. + */ + void write_cdb_BadTowers(); }; -#endif // QVECCALIB_H +#endif // QVECCALIB_H diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h b/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h index 3bc58344fe..ebbeec8743 100644 --- a/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h +++ b/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h @@ -20,11 +20,12 @@ namespace QVecShared Cold = 3 }; - enum class Subdetector + enum class Subdetector : size_t { - S, // South - N, // North - NS // North South + S = 0, + N = 1, + NS = 2, + Count = 3 }; enum class QComponent @@ -39,14 +40,6 @@ namespace QVecShared double y{0.0}; }; - struct CorrectionMoments - { - QVec avg_Q{}; // Mean Q vector - double avg_Q_xx{0.0}; - double avg_Q_yy{0.0}; - double avg_Q_xy{0.0}; - }; - /** * @brief Centralized helper to generate standard histogram names for the sEPD calibration. * * Standardizes the naming convention: h_sEPD_Q_{det}_{var}_{n}{suffix}_avg diff --git a/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc b/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc index 3570fb6bc7..5ce0e97a58 100644 --- a/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc +++ b/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc @@ -239,7 +239,10 @@ int sEPD_TreeGen::process_sEPD(PHCompositeNode *topNode) void sEPD_TreeGen::Print([[maybe_unused]] const std::string &what) const { // Only execute if Verbosity is high enough - if (Verbosity() <= 2) return; + if (Verbosity() <= 2) + { + return; + } std::cout << "\n============================================================" << std::endl; std::cout << "sEPD_TreeGen::Print -> Event Data State" << std::endl; From 6e237318746a2dbfa20c83483c1184feaf705886 Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Sun, 8 Feb 2026 18:02:10 -0500 Subject: [PATCH 196/393] Debug Counter Increase - Prevent lots of output by increasing the progress report counter --- calibrations/sepd/sepd_eventplanecalib/QVecCalib.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.h b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.h index a0029949d8..5fceb0f47e 100644 --- a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.h +++ b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.h @@ -153,7 +153,7 @@ class QVecCalib : public SubsysReco std::array, m_harmonics.size()> m_q_vectors{}; - static constexpr int PROGRESS_REPORT_INTERVAL = 1000; + static constexpr int PROGRESS_REPORT_INTERVAL = 10000; // Holds all correction data // key: [Cent][Harmonic][Subdetector] From 4aacac3f41e2980b17ff0b1385d8113d0beaed86 Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Mon, 9 Feb 2026 00:47:35 -0500 Subject: [PATCH 197/393] clang-tidy fix - removed GenQVecCalib.cc - Address readability-avoid-nested-conditional-operator --- .../sepd/sepd_eventplanecalib/GenQVecCalib.cc | 59 ------------------- .../sepd/sepd_eventplanecalib/QVecCalib.cc | 15 ++++- 2 files changed, 14 insertions(+), 60 deletions(-) delete mode 100644 calibrations/sepd/sepd_eventplanecalib/GenQVecCalib.cc diff --git a/calibrations/sepd/sepd_eventplanecalib/GenQVecCalib.cc b/calibrations/sepd/sepd_eventplanecalib/GenQVecCalib.cc deleted file mode 100644 index 0dd1fa1fbe..0000000000 --- a/calibrations/sepd/sepd_eventplanecalib/GenQVecCalib.cc +++ /dev/null @@ -1,59 +0,0 @@ -#include "QVecCalib.h" - -#include - -int main(int argc, const char* const argv[]) -{ - const std::vector args(argv, argv + argc); - - if (args.size() < 4 || args.size() > 7) - { - std::cout << "Usage: " << args[0] << " [pass] [events] [output_directory]" << std::endl; - return 1; // Indicate error - } - - const std::string &input_file = args[1]; - const std::string &input_hist = args[2]; - const std::string &input_Q_calib = args[3]; - const std::string &pass_str = (args.size() >= 5) ? args[4] : "ComputeRecentering"; // Default to the first pass - std::string output_dir = (args.size() >= 7) ? args[6] : "."; - - const std::map pass_map = { - {"ComputeRecentering", QVecCalib::Pass::ComputeRecentering}, - {"ApplyRecentering", QVecCalib::Pass::ApplyRecentering}, - {"ApplyFlattening", QVecCalib::Pass::ApplyFlattening} - }; - - QVecCalib::Pass pass = QVecCalib::Pass::ComputeRecentering; - if (pass_map.contains(pass_str)) - { - pass = pass_map.at(pass_str); - } - else - { - std::cout << "Error: Invalid pass specified: " << pass_str << std::endl; - std::cout << "Available passes are: ComputeRecentering, ApplyRecentering, ApplyFlattening" << std::endl; - return 1; - } - - try - { - long long events = (args.size() >= 6) ? std::stoll(args[5]) : 0; - QVecCalib analysis(input_file, input_hist, input_Q_calib, static_cast(pass), events, output_dir); - analysis.run(); - } - catch (const std::invalid_argument& e) - { - std::cout << "Error: events must be an integer" << std::endl; - return 1; - } - catch (const std::exception& e) - { - std::cout << "An exception occurred: " << e.what() << std::endl; - return 1; - } - - std::cout << "======================================" << std::endl; - std::cout << "done" << std::endl; - return 0; -} diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc index f14b0cc536..4a1c9d7e51 100644 --- a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc +++ b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc @@ -546,7 +546,20 @@ int QVecCalib::load_correction_data() // Populate Flattening for S, N, and NS for (int d = 0; d < (int) SD::Count; ++d) { - std::string det_str = (d == 0) ? "S" : (d == 1) ? "N" : "NS"; + std::string det_str; + switch (d) + { + case 0: + det_str = "S"; + break; + case 1: + det_str = "N"; + break; + default: + det_str = "NS"; + break; + } + double xx = m_profiles[QVecShared::get_hist_name(det_str, "xx", n)]->GetBinContent(bin); double yy = m_profiles[QVecShared::get_hist_name(det_str, "yy", n)]->GetBinContent(bin); double xy = m_profiles[QVecShared::get_hist_name(det_str, "xy", n)]->GetBinContent(bin); From 8ddb0ce8dffd87c672ea20ec970dcdc920939fea Mon Sep 17 00:00:00 2001 From: bkimelman Date: Mon, 9 Feb 2026 10:17:45 -0500 Subject: [PATCH 198/393] Fixed indentation issue that clang-tidy complained about --- .../packages/tpccalib/TpcLaminationFitting.cc | 176 +++++++++--------- 1 file changed, 92 insertions(+), 84 deletions(-) diff --git a/offline/packages/tpccalib/TpcLaminationFitting.cc b/offline/packages/tpccalib/TpcLaminationFitting.cc index 2eaf6fcf4c..f2dcb09ed9 100644 --- a/offline/packages/tpccalib/TpcLaminationFitting.cc +++ b/offline/packages/tpccalib/TpcLaminationFitting.cc @@ -80,18 +80,20 @@ int TpcLaminationFitting::InitRun(PHCompositeNode *topNode) //m_laminationOffset[l][s] = -0.00296837 + 0.0014604 * cos(shift - 1.2246); if(s == 0) { - m_laminationOffset[l][s] = -0.00236289 + 0.00143918 * cos(shift - 1.31782); + //m_laminationOffset[l][s] = -0.00236289 + 0.00143918 * cos(shift - 1.31782); + m_laminationOffset[l][s] = -0.00148465 + 0.00219335 * cos(shift - 1.24219); } else { - m_laminationOffset[l][s] = -0.00323259 + 0.00138333 * cos(shift - 1.25373); + //m_laminationOffset[l][s] = -0.00323259 + 0.00138333 * cos(shift - 1.25373); + m_laminationOffset[l][s] = -0.00303345 + 0.0010828 * cos(shift - 1.03718); } if(m_fieldOff) { m_hLamination[l][s] = new TH2D((boost::format("hLamination%d_%s") %l %(s == 1 ? "North" : "South")).str().c_str(), (boost::format("Lamination %d %s, #phi_{ideal}=%.2f;R [cm];#phi") %l %(s == 1 ? "North" : "South") %m_laminationIdeal[l][s]).str().c_str(), 200, 30, 80, 200, m_laminationIdeal[l][s] - 0.2, m_laminationIdeal[l][s] + 0.2); m_fLamination[l][s] = new TF1((boost::format("fLamination%d_%s") %l %(s == 1 ? "North" : "South")).str().c_str(), "[0]+[1]", 30, 80); - m_fLamination[l][s]->SetParameters(-0.003, m_laminationIdeal[l][s]); + m_fLamination[l][s]->SetParameters(m_laminationOffset[l][s], m_laminationIdeal[l][s]); m_fLamination[l][s]->SetParLimits(0, -0.05, 0.05); m_fLamination[l][s]->FixParameter(1, m_laminationIdeal[l][s]); } @@ -559,7 +561,7 @@ int TpcLaminationFitting::fitLaminations() if(m_fieldOff) { - m_fLamination[l][s]->SetParameters(0.003, m_laminationIdeal[l][s]); + m_fLamination[l][s]->SetParameters(m_laminationOffset[l][s], m_laminationIdeal[l][s]); m_fLamination[l][s]->FixParameter(1, m_laminationIdeal[l][s]); } else @@ -743,6 +745,7 @@ int TpcLaminationFitting::InterpolatePhiDistortions() int phiBin = phiDistortionLamination[s]->GetXaxis()->FindBin(phi); if(m_fieldOff) { + m_laminationOffset[l][s] = m_fLamination[l][s]->GetParameter(0); m_fLamination[l][s]->SetParameter(1, 0.0); } else @@ -971,7 +974,7 @@ int TpcLaminationFitting::doGlobalRMatching(int side) int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) { - + std::string sql = "SELECT * FROM gl1_scalers WHERE runnumber = " + std::to_string(m_runnumber) + ";"; odbc::Statement *stmt = DBInterface::instance()->getStatement("daq"); odbc::ResultSet *resultSet = stmt->executeQuery(sql); @@ -982,7 +985,7 @@ int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) delete resultSet; return Fun4AllReturnCodes::ABORTRUN; } - + while (resultSet->next()) { int index = resultSet->getInt("index"); @@ -991,20 +994,20 @@ int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) scalers[index][1] = resultSet->getLong("live"); scalers[index][2] = resultSet->getLong("raw"); } - + delete resultSet; - + m_ZDC_coincidence = (1.0*scalers[3][2]/scalers[0][2])/(106e-9); - + std::cout << "Runnumber: " << m_runnumber << " ppMode: " << ppMode << " ZDC coindicence rate: " << m_ZDC_coincidence << std::endl; - + int fitSuccess = fitLaminations(); if (fitSuccess != Fun4AllReturnCodes::EVENT_OK) { std::cout << PHWHERE << " Return code for lamination fitting was " << fitSuccess << " and not successful" << std::endl; return Fun4AllReturnCodes::ABORTRUN; } - + if(!m_QAFileName.empty()) { TCanvas *c1 = new TCanvas(); @@ -1025,46 +1028,49 @@ int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) } m_fLamination[l][s]->Draw("same"); - TLegend *leg = new TLegend(0.15,0.15,0.45,0.4); - + TLegend *leg = new TLegend(0.15,0.15,0.45,0.4); + TLine *lineIdeal; - TLine *lineOffset; - if(m_fieldOff) - { - lineIdeal = new TLine(30,m_laminationIdeal[l][s],80,m_laminationIdeal[l][s]); - lineIdeal->SetLineColor(kBlue); - leg->AddEntry(lineIdeal,Form("#phi_{ideal}=%.6f",m_laminationIdeal[l][s]), "l"); - } - else - { - lineIdeal = new TLine(30,m_laminationIdeal[l][s],80,m_laminationIdeal[l][s]); - lineIdeal->SetLineColor(kBlue); - leg->AddEntry(lineIdeal,Form("#phi_{ideal}=%.6f",m_laminationIdeal[l][s]), "l"); - - lineOffset = new TLine(30,m_laminationIdeal[l][s]+m_laminationOffset[l][s],80,m_laminationIdeal[l][s]+m_laminationOffset[l][s]); - lineOffset->SetLineColor(kGreen+2); - lineOffset->SetLineStyle(2); - leg->AddEntry(lineOffset,Form("#phi_{ideal}+#phi_{offset}=%.6f",m_laminationOffset[l][s]), "l"); - lineOffset->Draw("same"); - } + TLine *lineOffset; + if(m_fieldOff) + { + lineIdeal = new TLine(30,m_laminationIdeal[l][s],80,m_laminationIdeal[l][s]); + lineIdeal->SetLineColor(kBlue); + leg->AddEntry(lineIdeal,(boost::format("#phi_{ideal}=%.6f") %m_laminationIdeal[l][s]).str().c_str(), "l"); + //leg->AddEntry(lineIdeal,Form("#phi_{ideal}=%.6f",m_laminationIdeal[l][s]), "l"); + } + else + { + lineIdeal = new TLine(30,m_laminationIdeal[l][s],80,m_laminationIdeal[l][s]); + lineIdeal->SetLineColor(kBlue); + leg->AddEntry(lineIdeal,(boost::format("#phi_{ideal}=%.6f") %m_laminationIdeal[l][s]).str().c_str(), "l"); + //leg->AddEntry(lineIdeal,Form("#phi_{ideal}=%.6f",m_laminationIdeal[l][s]), "l"); + + lineOffset = new TLine(30,m_laminationIdeal[l][s]+m_laminationOffset[l][s],80,m_laminationIdeal[l][s]+m_laminationOffset[l][s]); + lineOffset->SetLineColor(kGreen+2); + lineOffset->SetLineStyle(2); + leg->AddEntry(lineOffset,(boost::format("#phi_{ideal}+#phi_{offset}=%.6f") %m_laminationOffset[l][s]).str().c_str(), "l"); + //leg->AddEntry(lineOffset,Form("#phi_{ideal}+#phi_{offset}=%.6f",m_laminationOffset[l][s]), "l"); + lineOffset->Draw("same"); + } lineIdeal->Draw("same"); - - leg->Draw("same"); - - + + leg->Draw("same"); + + TPaveText *pars = new TPaveText(0.6, 0.55, 0.85, 0.85, "NDC"); - if(m_fieldOff) - { - pars->AddText("#phi = #phi_{ideal} + #phi_{offset}"); - pars->AddText((boost::format("#phi_{ideal}=%.3f#pm %.3f") %m_fLamination[l][s]->GetParameter(1) %m_fLamination[l][s]->GetParError(1)).str().c_str()); - pars->AddText((boost::format("#phi_{offset}=%.3f#pm %.3f") %m_fLamination[l][s]->GetParameter(0) %m_fLamination[l][s]->GetParError(0)).str().c_str()); - pars->AddText((boost::format("Distance to line=%.2f") %m_distanceToFit[l][s]).str().c_str()); - pars->AddText((boost::format("Number of Bins used=%d") %m_nBinsFit[l][s]).str().c_str()); - pars->AddText((boost::format("WRMSE=%.2f") %m_fitRMSE[l][s]).str().c_str()); - } - else - { + if(m_fieldOff) + { + pars->AddText("#phi = #phi_{ideal} + #phi_{offset}"); + pars->AddText((boost::format("#phi_{ideal}=%.3f#pm %.3f") %m_fLamination[l][s]->GetParameter(1) %m_fLamination[l][s]->GetParError(1)).str().c_str()); + pars->AddText((boost::format("#phi_{offset}=%.3f#pm %.3f") %m_fLamination[l][s]->GetParameter(0) %m_fLamination[l][s]->GetParError(0)).str().c_str()); + pars->AddText((boost::format("Distance to line=%.2f") %m_distanceToFit[l][s]).str().c_str()); + pars->AddText((boost::format("Number of Bins used=%d") %m_nBinsFit[l][s]).str().c_str()); + pars->AddText((boost::format("WRMSE=%.2f") %m_fitRMSE[l][s]).str().c_str()); + } + else + { pars->AddText("#phi = #phi_{ideal} + A#times (1 - e^{-C#times (R - B)})"); pars->AddText((boost::format("A=%.3f#pm %.3f") %m_fLamination[l][s]->GetParameter(0) %m_fLamination[l][s]->GetParError(0)).str().c_str()); //pars->AddText((boost::format("#phi_{ideal}=%.3f#pm 0.000") %m_laminationIdeal[l][s]).str().c_str()); @@ -1074,8 +1080,8 @@ int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) pars->AddText((boost::format("C=%.3f#pm %.3f") %m_fLamination[l][s]->GetParameter(2) %m_fLamination[l][s]->GetParError(2)).str().c_str()); pars->AddText((boost::format("Distance to line=%.2f") %m_distanceToFit[l][s]).str().c_str()); pars->AddText((boost::format("Number of Bins used=%d") %m_nBinsFit[l][s]).str().c_str()); - pars->AddText((boost::format("WRMSE=%.2f") %m_fitRMSE[l][s]).str().c_str()); - } + pars->AddText((boost::format("WRMSE=%.2f") %m_fitRMSE[l][s]).str().c_str()); + } pars->Draw("same"); c1->SaveAs(m_QAFileName.c_str()); } @@ -1091,32 +1097,32 @@ int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) //TH3 *hIntDistortionP_negz = (TH3 *) simDistortion->Get("hIntDistortionP_negz"); //hIntDistortionP_negz->GetZaxis()->SetRange(hIntDistortionP_negz->GetNbinsZ() - 1, hIntDistortionP_negz->GetNbinsZ() - 1); //simPhiDistortion[0] = (TH2 *) hIntDistortionP_negz->Project3D("yx"); - + int interpolateSuccess = InterpolatePhiDistortions(); if (interpolateSuccess != Fun4AllReturnCodes::EVENT_OK) { std::cout << PHWHERE << " Return code for lamination interpolation was " << interpolateSuccess << " and not successful" << std::endl; return Fun4AllReturnCodes::ABORTRUN; } - + /* - for (int s = 0; s < 2; s++) - { + for (int s = 0; s < 2; s++) + { scaleFactorMap[s] = (TH2 *) m_dcc_out->m_hDPint[s]->Clone(); scaleFactorMap[s]->SetName(std::format("scaleFactorMap{}", s).c_str()); scaleFactorMap[s]->Divide(simPhiDistortion[s]); - } - - TH3 *hIntDistortionR_posz = (TH3 *) simDistortion->Get("hIntDistortionR_posz"); - hIntDistortionR_posz->GetZaxis()->SetRange(2, 2); - TH2 *simRDistortion[2]; - simRDistortion[1] = (TH2 *) hIntDistortionR_posz->Project3D("yx"); - TH3 *hIntDistortionR_negz = (TH3 *) simDistortion->Get("hIntDistortionR_negz"); - hIntDistortionR_negz->GetZaxis()->SetRange(hIntDistortionR_negz->GetNbinsZ() - 1, hIntDistortionR_negz->GetNbinsZ() - 1); - simRDistortion[0] = (TH2 *) hIntDistortionR_negz->Project3D("yx"); + } + + TH3 *hIntDistortionR_posz = (TH3 *) simDistortion->Get("hIntDistortionR_posz"); + hIntDistortionR_posz->GetZaxis()->SetRange(2, 2); + TH2 *simRDistortion[2]; + simRDistortion[1] = (TH2 *) hIntDistortionR_posz->Project3D("yx"); + TH3 *hIntDistortionR_negz = (TH3 *) simDistortion->Get("hIntDistortionR_negz"); + hIntDistortionR_negz->GetZaxis()->SetRange(hIntDistortionR_negz->GetNbinsZ() - 1, hIntDistortionR_negz->GetNbinsZ() - 1); + simRDistortion[0] = (TH2 *) hIntDistortionR_negz->Project3D("yx"); */ - - + + for (int s = 0; s < 2; s++) { @@ -1127,27 +1133,27 @@ int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) return Fun4AllReturnCodes::ABORTRUN; } /* - for(int i=1; i<=m_dcc_out->m_hDRint[s]->GetNbinsX(); i++) - { - for(int j=1; j<=m_dcc_out->m_hDRint[s]->GetNbinsY(); j++) - { - if(simRDistortion[s]->GetBinContent(i,j) != 0.0) - { - m_dcc_out->m_hDRint[s]->SetBinContent(i,j, simRDistortion[s]->GetBinContent(i,j)); - } - } - } + for(int i=1; i<=m_dcc_out->m_hDRint[s]->GetNbinsX(); i++) + { + for(int j=1; j<=m_dcc_out->m_hDRint[s]->GetNbinsY(); j++) + { + if(simRDistortion[s]->GetBinContent(i,j) != 0.0) + { + m_dcc_out->m_hDRint[s]->SetBinContent(i,j, simRDistortion[s]->GetBinContent(i,j)); + } + } + } */ //m_dcc_out->m_hDRint[s] = (TH2 *) simRDistortion[s]->Clone(); //m_dcc_out->m_hDRint[s]->SetName((boost::format("hIntDistortionR%s") %(s == 0 ? "_negz" : "_posz")).str().c_str()); //m_dcc_out->m_hDRint[s]->Multiply(scaleFactorMap[s]); } - - + + fill_guarding_bins(m_dcc_out); - - + + for(int s=0; s<2; s++) { for(int l=0; l<18; l++) @@ -1181,7 +1187,7 @@ int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) m_laminationTree->Fill(); } } - + TFile *outputfile = new TFile(m_outputfile.c_str(), "RECREATE"); outputfile->cd(); for (int s = 0; s < 2; s++) @@ -1196,19 +1202,21 @@ int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) phiDistortionLamination[s]->Write(); //scaleFactorMap[s]->Write(); m_hPetal[s]->Write(); - if(m_bestRMatch[s]) { m_bestRMatch[s]->Write(); -} + if(m_bestRMatch[s]) + { + m_bestRMatch[s]->Write(); + } m_parameterScan[s]->Write(); } m_laminationTree->Write(); - + m_hLamination[13][0]->Write(); m_hLamination[13][1]->Write(); m_hLamination[14][1]->Write(); - + outputfile->Close(); - + return Fun4AllReturnCodes::EVENT_OK; } From 6ce3aea5ce9fd373a4d45f2c18192a3dacfac9b2 Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Mon, 19 Jan 2026 21:26:29 -0500 Subject: [PATCH 199/393] sEPD Event Plane Calibration - Application Introduces a new sEPD event plane reconstruction module (v2) and an expanded info container (v2) to support a full calibration chain including recentering and flattening. Eventplaneinfov2: - Inherits from Eventplaneinfo. - Adds dedicated storage for raw, recentered, and final (flattened) Q-vectors. - Provides getters/setters for extended Q-vector stages to allow for systematic studies of calibration effects. EventPlaneRecov2: - New SubsysReco module specifically for sEPD Q-vector calibration. - Implements a multi-step calibration workflow: 1. Raw Q-vector calculation from sEPD channel charges and geometry. 2. Recentering: Subtracts offsets per centrality bin. 3. Flattening: Applies a 2x2 correction matrix calculated from Q-vector variances (Qxx, Qyy, Qxy). - Features integration with CDBTTree to load calibration parameters dynamically via the Calibration Database. - Processes harmonics n=2,3, and 4 for South, North, and Combined (NS) subdetectors. - Automatically handles centrality-based binning (8 bins) for calibrations. - Populates EventplaneinfoMap with Eventplaneinfov2 objects for downstream analysis. - Includes diagnostic verbosity levels for inspecting calibration matrices and per-event vector transformations. --- .../eventplaneinfo/EventPlaneRecov2.cc | 625 ++++++++++++++++++ .../eventplaneinfo/EventPlaneRecov2.h | 136 ++++ .../packages/eventplaneinfo/Eventplaneinfo.h | 4 + .../eventplaneinfo/Eventplaneinfov2.cc | 23 + .../eventplaneinfo/Eventplaneinfov2.h | 55 ++ .../eventplaneinfo/Eventplaneinfov2LinkDef.h | 5 + offline/packages/eventplaneinfo/Makefile.am | 9 +- 7 files changed, 855 insertions(+), 2 deletions(-) create mode 100644 offline/packages/eventplaneinfo/EventPlaneRecov2.cc create mode 100644 offline/packages/eventplaneinfo/EventPlaneRecov2.h create mode 100644 offline/packages/eventplaneinfo/Eventplaneinfov2.cc create mode 100644 offline/packages/eventplaneinfo/Eventplaneinfov2.h create mode 100644 offline/packages/eventplaneinfo/Eventplaneinfov2LinkDef.h diff --git a/offline/packages/eventplaneinfo/EventPlaneRecov2.cc b/offline/packages/eventplaneinfo/EventPlaneRecov2.cc new file mode 100644 index 0000000000..8a468a1acb --- /dev/null +++ b/offline/packages/eventplaneinfo/EventPlaneRecov2.cc @@ -0,0 +1,625 @@ +#include "EventPlaneRecov2.h" + +#include "EventplaneinfoMapv1.h" +#include "Eventplaneinfov2.h" + +#include +#include + +#include +#include +#include + +#include +#include +#include + +// -- event +#include + +// -- Centrality +#include + +// -- sEPD +#include + +// -- root includes -- +#include +#include + +// c++ includes -- +#include +#include +#include +#include +#include +#include + +//____________________________________________________________________________.. +EventPlaneRecov2::EventPlaneRecov2(const std::string &name): + SubsysReco(name) +{ +} + +//____________________________________________________________________________.. +EventPlaneRecov2::~EventPlaneRecov2() +{ + std::cout << "EventPlaneRecov2::~EventPlaneRecov2() Calling dtor" << std::endl; +} + +bool EventPlaneRecov2::hasValidTree(const std::string &filePath) +{ + // 1. Attempt to open the file + // "READ" is the default, but being explicit is good practice + std::unique_ptr file(TFile::Open(filePath.c_str(), "READ")); + + // 2. Validate the file pointer and check if the file is "Zombie" (corrupt/unreadable) + if (!file || file->IsZombie()) + { + std::cout << "Error: Could not open file: " << filePath << std::endl; + return false; + } + + // 3. Attempt to get the object by name + TObject *obj = file->Get("Multiple"); + + // 4. Validate existence and check if it actually inherits from TTree + if (obj && obj->InheritsFrom(TTree::Class())) + { + return true; + } + + std::cout << "Error: Object 'Multiple' not found or is not a TTree." << std::endl; + return false; +} + +//____________________________________________________________________________.. +int EventPlaneRecov2::Init([[maybe_unused]] PHCompositeNode *topNode) +{ + std::string calibdir = CDBInterface::instance()->getUrl(m_calibName); + + if (hasValidTree(m_directURL_EventPlaneCalib)) + { + m_cdbttree = std::make_unique(m_directURL_EventPlaneCalib); + std::cout << PHWHERE << " Custom Event Plane Calib Found: " << m_directURL_EventPlaneCalib << std::endl; + } + else if (!calibdir.empty()) + { + m_cdbttree = std::make_unique(calibdir); + std::cout << PHWHERE << " Event Plane Calib Found: " << calibdir << std::endl; + } + else if (m_doAbortNoEventPlaneCalib) + { + std::cout << PHWHERE << " Error: No Event Plane Calib Found and m_doAbortNoEventPlaneCalib is true. Aborting." << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + else + { + std::cout << PHWHERE << " Error: No Event Plane Calib Found. Skipping Event Plane Calibrations." << std::endl; + m_doNotCalib = true; + } + + if (!m_doNotCalib) + { + LoadCalib(); + } + + if (Verbosity() > 0) + { + print_correction_data(); + } + + CreateNodes(topNode); + + return Fun4AllReturnCodes::EVENT_OK; +} + +std::array, 2> EventPlaneRecov2::calculate_flattening_matrix(double xx, double yy, double xy, int n, int cent_bin, const std::string& det_label) +{ + std::array, 2> mat{}; + + double D_arg = (xx * yy) - (xy * xy); + if (D_arg <= 0) + { + std::cout << PHWHERE << "Invalid D-term " << D_arg << " for n=" << n << ", cent bin=" << cent_bin << ", det=" << det_label << std::endl; + // Return Identity Matrix to preserve Recentered vector + mat[0][0] = 1.0; + mat[1][1] = 1.0; + return mat; + } + double D = std::sqrt(D_arg); + + double N_term = D * (xx + yy + (2 * D)); + if (N_term <= 0) + { + std::cout << PHWHERE << "Invalid N-term " << N_term << " for n=" << n << ", cent bin=" << cent_bin << ", det=" << det_label << std::endl; + // Return Identity Matrix to preserve Recentered vector + mat[0][0] = 1.0; + mat[1][1] = 1.0; + return mat; + } + double inv_sqrt_N = 1.0 / std::sqrt(N_term); + + mat[0][0] = inv_sqrt_N * (yy + D); + mat[0][1] = -inv_sqrt_N * xy; + mat[1][0] = mat[0][1]; + mat[1][1] = inv_sqrt_N * (xx + D); + return mat; +} + +//____________________________________________________________________________.. +void EventPlaneRecov2::LoadCalib() +{ + size_t south_idx = static_cast(Subdetector::S); + size_t north_idx = static_cast(Subdetector::N); + + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + int n = m_harmonics[h_idx]; + + std::string S_x_avg_name = std::format("Q_S_x_{}_avg", n); + std::string S_y_avg_name = std::format("Q_S_y_{}_avg", n); + std::string N_x_avg_name = std::format("Q_N_x_{}_avg", n); + std::string N_y_avg_name = std::format("Q_N_y_{}_avg", n); + + std::string S_xx_avg_name = std::format("Q_S_xx_{}_avg", n); + std::string S_yy_avg_name = std::format("Q_S_yy_{}_avg", n); + std::string S_xy_avg_name = std::format("Q_S_xy_{}_avg", n); + std::string N_xx_avg_name = std::format("Q_N_xx_{}_avg", n); + std::string N_yy_avg_name = std::format("Q_N_yy_{}_avg", n); + std::string N_xy_avg_name = std::format("Q_N_xy_{}_avg", n); + + for (size_t cent_bin = 0; cent_bin < m_bins_cent; ++cent_bin) + { + int key = static_cast(cent_bin); + + // South + auto& dataS = m_correction_data[h_idx][cent_bin][south_idx]; + dataS.avg_Q.x = m_cdbttree->GetDoubleValue(key, S_x_avg_name); + dataS.avg_Q.y = m_cdbttree->GetDoubleValue(key, S_y_avg_name); + + dataS.avg_Q_xx = m_cdbttree->GetDoubleValue(key, S_xx_avg_name); + dataS.avg_Q_yy = m_cdbttree->GetDoubleValue(key, S_yy_avg_name); + dataS.avg_Q_xy = m_cdbttree->GetDoubleValue(key, S_xy_avg_name); + + dataS.X_matrix = calculate_flattening_matrix(dataS.avg_Q_xx, dataS.avg_Q_yy, dataS.avg_Q_xy, n, cent_bin, "South"); + + // North + auto& dataN = m_correction_data[h_idx][cent_bin][north_idx]; + dataN.avg_Q.x = m_cdbttree->GetDoubleValue(key, N_x_avg_name); + dataN.avg_Q.y = m_cdbttree->GetDoubleValue(key, N_y_avg_name); + + dataN.avg_Q_xx = m_cdbttree->GetDoubleValue(key, N_xx_avg_name); + dataN.avg_Q_yy = m_cdbttree->GetDoubleValue(key, N_yy_avg_name); + dataN.avg_Q_xy = m_cdbttree->GetDoubleValue(key, N_xy_avg_name); + + dataN.X_matrix = calculate_flattening_matrix(dataN.avg_Q_xx, dataN.avg_Q_yy, dataN.avg_Q_xy, n, cent_bin, "North"); + } + } +} + +//____________________________________________________________________________.. +void EventPlaneRecov2::print_correction_data() +{ + std::cout << std::format("\n{:=>60}\n", ""); + std::cout << std::format("{:^60}\n", "EVENT PLANE CORRECTION DATA SUMMARY"); + std::cout << std::format("{:=>60}\n", ""); + + // Iterate through harmonics {2, 3, 4} + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + int n = m_harmonics[h_idx]; + std::cout << std::format("\n>>> HARMONIC n = {} <<<\n", n); + + // Iterate through Centrality Bins (0-7) + for (size_t cent = 0; cent < m_bins_cent; ++cent) + { + std::cout << std::format("\n Centrality Bin: {}\n", cent); + std::cout << std::format(" {:->30}\n", ""); + + // Header with fixed column widths + std::cout << std::format(" {:<12} {:>10} {:>10} {:>10} {:>10} {:>10}\n", + "Detector", "Avg Qx", "Avg Qy", "Avg Qxx", "Avg Qyy", "Avg Qxy"); + + // Iterate through Subdetectors {S, N} + for (size_t det_idx = 0; det_idx < 2; ++det_idx) + { + std::string det_name = (det_idx == static_cast(Subdetector::S)) ? "South" : "North"; + const auto& data = m_correction_data[h_idx][cent][det_idx]; // + + std::cout << std::format(" {:<12} {:>10.6f} {:>10.6f} {:>10.6f} {:>10.6f} {:>10.6f}\n", + det_name, + data.avg_Q.x, data.avg_Q.y, + data.avg_Q_xx, data.avg_Q_yy, data.avg_Q_xy); + + // Print X-Matrix in a bracketed layout + std::cout << std::format(" X-Matrix: [ {:>8.6f}, {:>8.6f} ]\n", + data.X_matrix[0][0], data.X_matrix[0][1]); + std::cout << std::format(" [ {:>8.6f}, {:>8.6f} ]\n", + data.X_matrix[1][0], data.X_matrix[1][1]); + } + } + } + std::cout << std::format("\n{:=>60}\n", ""); +} + +int EventPlaneRecov2::CreateNodes(PHCompositeNode *topNode) { + PHNodeIterator iter(topNode); + + PHCompositeNode *dstNode = dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); + if (!dstNode) + { + std::cout << PHWHERE << "DST Node missing, doing nothing." << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + PHCompositeNode *globalNode = dynamic_cast(iter.findFirst("PHCompositeNode", "GLOBAL")); + if (!globalNode) + { + auto global_ptr = std::make_unique("GLOBAL"); + globalNode = global_ptr.get(); + dstNode->addNode(global_ptr.release()); + } + + EventplaneinfoMap *eps = findNode::getClass(topNode, "EventplaneinfoMap"); + if (!eps) + { + auto eps_ptr = std::make_unique(); + auto epMapNode_ptr = std::make_unique>(eps_ptr.release(), "EventplaneinfoMap", "PHObject"); + globalNode->addNode(epMapNode_ptr.release()); + } + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int EventPlaneRecov2::process_centrality(PHCompositeNode *topNode) +{ + CentralityInfo* centInfo = findNode::getClass(topNode, "CentralityInfo"); + if (!centInfo) + { + std::cout << PHWHERE << " CentralityInfo is missing doing nothing" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + m_cent = centInfo->get_centile(CentralityInfo::PROP::mbd_NS) * 100; + + if (!std::isfinite(m_cent) || m_cent < 0) + { + if (Verbosity() > 1) + { + std::cout << PHWHERE << " Warning Centrality is out of range. Cent: " << m_cent << ". Cannot calibrate Q vector for this event." << std::endl; + } + m_doNotCalibEvent = true; + } + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int EventPlaneRecov2::process_sEPD(PHCompositeNode* topNode) +{ + TowerInfoContainer* towerinfosEPD = findNode::getClass(topNode, m_inputNode); + if (!towerinfosEPD) + { + std::cout << PHWHERE << " TOWERINFO_CALIB_SEPD is missing doing nothing" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + EpdGeom* epdgeom = findNode::getClass(topNode, "TOWERGEOM_EPD"); + if (!epdgeom) + { + std::cout << PHWHERE << " TOWERGEOM_EPD is missing doing nothing" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + // sepd + unsigned int nchannels_epd = towerinfosEPD->size(); + + double sepd_total_charge_south = 0; + double sepd_total_charge_north = 0; + + for (unsigned int channel = 0; channel < nchannels_epd; ++channel) + { + TowerInfo* tower = towerinfosEPD->get_tower_at_channel(channel); + + unsigned int key = TowerInfoDefs::encode_epd(channel); + double charge = tower->get_energy(); + double phi = epdgeom->get_phi(key); + + // skip bad channels + // skip channels with very low charge + if (!tower->get_isGood() || charge < m_sepd_min_channel_charge) + { + continue; + } + + // arm = 0: South + // arm = 1: North + unsigned int arm = TowerInfoDefs::get_epd_arm(key); + + // sepd charge sums + double& sepd_total_charge = (arm == 0) ? sepd_total_charge_south : sepd_total_charge_north; + + // Compute total charge for the respective sEPD arm + sepd_total_charge += charge; + + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + int n = m_harmonics[h_idx]; + QVec q_n = {charge * std::cos(n * phi), charge * std::sin(n * phi)}; + m_Q_raw[h_idx][arm].x += q_n.x; + m_Q_raw[h_idx][arm].y += q_n.y; + } + } + + // ensure both total charges are nonzero + if (sepd_total_charge_south == 0 || sepd_total_charge_north == 0) + { + if (Verbosity() > 1) + { + std::cout << PHWHERE << " Error: Total sEPD Charge is Zero: " + << "South = " << sepd_total_charge_south + << ", North = " << sepd_total_charge_north << std::endl; + } + + // ensure raw Q vec is reset + m_Q_raw = {}; + m_doNotCalibEvent = true; + return Fun4AllReturnCodes::EVENT_OK; + } + + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + m_Q_raw[h_idx][0].x /= sepd_total_charge_south; + m_Q_raw[h_idx][0].y /= sepd_total_charge_south; + + m_Q_raw[h_idx][1].x /= sepd_total_charge_north; + m_Q_raw[h_idx][1].y /= sepd_total_charge_north; + } + + return Fun4AllReturnCodes::EVENT_OK; +} + +void EventPlaneRecov2::correct_QVecs() +{ + size_t cent_bin = static_cast(m_cent / 10.0); + if (cent_bin >= m_bins_cent) + { + cent_bin = m_bins_cent - 1; // Clamp max + } + + size_t south_idx = static_cast(Subdetector::S); + size_t north_idx = static_cast(Subdetector::N); + + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + auto& dataS = m_correction_data[h_idx][cent_bin][south_idx]; + auto& dataN = m_correction_data[h_idx][cent_bin][north_idx]; + + double Q_S_x_avg = dataS.avg_Q.x; + double Q_S_y_avg = dataS.avg_Q.y; + double Q_N_x_avg = dataN.avg_Q.x; + double Q_N_y_avg = dataN.avg_Q.y; + + QVec q_S = m_Q_raw[h_idx][south_idx]; + QVec q_N = m_Q_raw[h_idx][north_idx]; + + // Apply Recentering + QVec q_S_recenter = {q_S.x - Q_S_x_avg, q_S.y - Q_S_y_avg}; + QVec q_N_recenter = {q_N.x - Q_N_x_avg, q_N.y - Q_N_y_avg}; + + m_Q_recentered[h_idx][0] = q_S_recenter; + m_Q_recentered[h_idx][1] = q_N_recenter; + + const auto &X_S = dataS.X_matrix; + const auto &X_N = dataN.X_matrix; + + // Apply Flattening + double Q_S_x_flat = X_S[0][0] * q_S_recenter.x + X_S[0][1] * q_S_recenter.y; + double Q_S_y_flat = X_S[1][0] * q_S_recenter.x + X_S[1][1] * q_S_recenter.y; + double Q_N_x_flat = X_N[0][0] * q_N_recenter.x + X_N[0][1] * q_N_recenter.y; + double Q_N_y_flat = X_N[1][0] * q_N_recenter.x + X_N[1][1] * q_N_recenter.y; + + QVec q_S_flat = {Q_S_x_flat, Q_S_y_flat}; + QVec q_N_flat = {Q_N_x_flat, Q_N_y_flat}; + + m_Q_flat[h_idx][south_idx] = q_S_flat; + m_Q_flat[h_idx][north_idx] = q_N_flat; + } +} + +void EventPlaneRecov2::print_QVectors() +{ + std::string header_text = std::format("EVENT Q-VECTOR SUMMARY (Event: {}, CENTRALITY: {:.0f}%)", m_globalEvent, m_cent); + + std::cout << std::format("\n{:*>100}\n", ""); + std::cout << std::format("{:^100}\n", header_text); + std::cout << std::format("{:*>100}\n", ""); + + // Table Header + std::cout << std::format(" {:<10} {:<10} | {:>21} | {:>21} | {:>21}\n", + "Harmonic", "Detector", "Raw (x, y)", "Recentered (x, y)", "Flattened (x, y)"); + std::cout << std::format(" {:-<100}\n", ""); + + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + int n = m_harmonics[h_idx]; + + for (size_t det_idx = 0; det_idx < 2; ++det_idx) + { + std::string det_name = (det_idx == static_cast(Subdetector::S)) ? "South" : "North"; + + const auto& raw = m_Q_raw[h_idx][det_idx]; + const auto& rec = m_Q_recentered[h_idx][det_idx]; + const auto& flat = m_Q_flat[h_idx][det_idx]; + + std::string h_label = (det_idx == 0) ? std::format("n={}", n) : ""; + + // Groups x and y into (val, val) pairs for better scannability + std::string raw_str = std::format("({:>8.5f}, {:>8.5f})", raw.x, raw.y); + std::string rec_str = std::format("({:>8.5f}, {:>8.5f})", rec.x, rec.y); + std::string flat_str = std::format("({:>8.5f}, {:>8.5f})", flat.x, flat.y); + + std::cout << std::format(" {:<10} {:<10} | {:<21} | {:<21} | {:10}\n", + h_label, det_name, raw_str, rec_str, flat_str); + } + if (h_idx < m_harmonics.size() - 1) + { + std::cout << std::format(" {:.>100}\n", ""); + } + } + std::cout << std::format("{:*>100}\n\n", ""); +} + +int EventPlaneRecov2::FillNode([[maybe_unused]] PHCompositeNode *topNode) +{ + EventplaneinfoMap *epmap = findNode::getClass(topNode, "EventplaneinfoMap"); + if (!epmap) + { + std::cout << PHWHERE << " EventplaneinfoMap is missing doing nothing" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + size_t vec_size = static_cast(*std::ranges::max_element(m_harmonics)); + + std::vector> south_Qvec_raw(vec_size, {NAN, NAN}); + std::vector> south_Qvec_recentered(vec_size, {NAN, NAN}); + std::vector> south_Qvec(vec_size, {NAN, NAN}); + + std::vector> north_Qvec_raw(vec_size, {NAN, NAN}); + std::vector> north_Qvec_recentered(vec_size, {NAN, NAN}); + std::vector> north_Qvec(vec_size, {NAN, NAN}); + + std::vector> northsouth_Qvec_raw(vec_size, {NAN, NAN}); + std::vector> northsouth_Qvec_recentered(vec_size, {NAN, NAN}); + std::vector> northsouth_Qvec(vec_size, {NAN, NAN}); + + std::vector south_psi(vec_size, NAN); + std::vector north_psi(vec_size, NAN); + std::vector northsouth_psi(vec_size, NAN); + + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + int n = m_harmonics[h_idx]; + int idx = n - 1; + + // Fallback logic: Use raw if calibration failed or centrality is out of range + const auto& Q_S = (m_doNotCalib || m_doNotCalibEvent) ? m_Q_raw[h_idx][0] : m_Q_flat[h_idx][0]; + const auto& Q_N = (m_doNotCalib || m_doNotCalibEvent) ? m_Q_raw[h_idx][1] : m_Q_flat[h_idx][1]; + + const auto& Q_S_raw = m_Q_raw[h_idx][0]; + const auto& Q_S_recentered = m_Q_recentered[h_idx][0]; + + const auto& Q_N_raw = m_Q_raw[h_idx][1]; + const auto& Q_N_recentered = m_Q_recentered[h_idx][1]; + + // South + south_Qvec_raw[idx] = {Q_S_raw.x, Q_S_raw.y}; + south_Qvec_recentered[idx] = {Q_S_recentered.x, Q_S_recentered.y}; + south_Qvec[idx] = {Q_S.x, Q_S.y}; + + // North + north_Qvec_raw[idx] = {Q_N_raw.x, Q_N_raw.y}; + north_Qvec_recentered[idx] = {Q_N_recentered.x, Q_N_recentered.y}; + north_Qvec[idx] = {Q_N.x, Q_N.y}; + + // Combined (North + South) + double Qx_NS_raw = Q_S_raw.x + Q_N_raw.x; + double Qy_NS_raw = Q_S_raw.y + Q_N_raw.y; + + double Qx_NS_recentered = Q_S_recentered.x + Q_N_recentered.x; + double Qy_NS_recentered = Q_S_recentered.y + Q_N_recentered.y; + + double Qx_NS = Q_S.x + Q_N.x; + double Qy_NS = Q_S.y + Q_N.y; + + northsouth_Qvec_raw[idx] = {Qx_NS_raw, Qy_NS_raw}; + northsouth_Qvec_recentered[idx] = {Qx_NS_recentered, Qy_NS_recentered}; + northsouth_Qvec[idx] = {Qx_NS, Qy_NS}; + } + + // Helper lambda to fill nodes using the class's GetPsi method + auto create_and_fill = [&](const std::vector>& qvecs_raw, const std::vector>& qvecs_recentered, const std::vector>& qvecs) { + auto node = std::make_unique(); + node->set_qvector_raw(qvecs_raw); + node->set_qvector_recentered(qvecs_recentered); + node->set_qvector(qvecs); + + std::vector psi_vec(vec_size, NAN); + for (int n : m_harmonics) { + psi_vec[n-1] = node->GetPsi(qvecs[n-1].first, qvecs[n-1].second, n); + } + node->set_shifted_psi(psi_vec); + return node; + }; + + epmap->insert(create_and_fill(south_Qvec_raw, south_Qvec_recentered, south_Qvec).release(), EventplaneinfoMap::sEPDS); + epmap->insert(create_and_fill(north_Qvec_raw, north_Qvec_recentered, north_Qvec).release(), EventplaneinfoMap::sEPDN); + epmap->insert(create_and_fill(northsouth_Qvec_raw, northsouth_Qvec_recentered, northsouth_Qvec).release(), EventplaneinfoMap::sEPDNS); + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int EventPlaneRecov2::process_event([[maybe_unused]] PHCompositeNode *topNode) +{ + + EventHeader *eventInfo = findNode::getClass(topNode, "EventHeader"); + if (!eventInfo) + { + return Fun4AllReturnCodes::ABORTRUN; + } + + m_globalEvent = eventInfo->get_EvtSequence(); + + int ret = process_centrality(topNode); + if (ret) + { + return ret; + } + + ret = process_sEPD(topNode); + if (ret) + { + return ret; + } + + // Calibrate Q Vectors + if (!m_doNotCalib && !m_doNotCalibEvent) + { + correct_QVecs(); + } + + ret = FillNode(topNode); + if (ret) + { + return ret; + } + + if (Verbosity() > 1) + { + print_QVectors(); + } + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int EventPlaneRecov2::ResetEvent([[maybe_unused]] PHCompositeNode *topNode) +{ + m_doNotCalibEvent = false; + + m_Q_raw = {}; + m_Q_recentered = {}; + m_Q_flat = {}; + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int EventPlaneRecov2::End([[maybe_unused]] PHCompositeNode *topNode) +{ + std::cout << "EventPlaneRecov2::End(PHCompositeNode *topNode) This is the End..." << std::endl; + return Fun4AllReturnCodes::EVENT_OK; +} diff --git a/offline/packages/eventplaneinfo/EventPlaneRecov2.h b/offline/packages/eventplaneinfo/EventPlaneRecov2.h new file mode 100644 index 0000000000..a1d5017ca3 --- /dev/null +++ b/offline/packages/eventplaneinfo/EventPlaneRecov2.h @@ -0,0 +1,136 @@ +#ifndef EVENTPLANEINFO_EVENTPLANERECOV2_H +#define EVENTPLANEINFO_EVENTPLANERECOV2_H + +#include +#include // for CDBTTree + +#include +#include +#include + +class PHCompositeNode; + +class EventPlaneRecov2 : public SubsysReco +{ + public: + + explicit EventPlaneRecov2(const std::string &name = "EventPlaneRecov2"); + ~EventPlaneRecov2() override; + + // Explicitly disable copying and moving + EventPlaneRecov2(const EventPlaneRecov2&) = delete; + EventPlaneRecov2& operator=(const EventPlaneRecov2&) = delete; + EventPlaneRecov2(EventPlaneRecov2&&) = delete; + EventPlaneRecov2& operator=(EventPlaneRecov2&&) = delete; + + /** Called during initialization. + Typically this is where you can book histograms, and e.g. + register them to Fun4AllServer (so they can be output to file + using Fun4AllServer::dumpHistos() method). + */ + int Init(PHCompositeNode *topNode) override; + + /** Called for each event. + This is where you do the real work. + */ + int process_event(PHCompositeNode *topNode) override; + + /// Clean up internals after each event. + int ResetEvent(PHCompositeNode *topNode) override; + + /// Called at the end of all processing. + int End(PHCompositeNode *topNode) override; + + + void set_inputNode(const std::string &inputNode) + { + m_inputNode = inputNode; + } + + void set_directURL_EventPlaneCalib(const std::string &directURL_EventPlaneCalib) + { + m_directURL_EventPlaneCalib = directURL_EventPlaneCalib; + } + + void set_doAbortNoEventPlaneCalib(bool status = true) + { + m_doAbortNoEventPlaneCalib = status; + } + + void set_sepd_min_channel_charge(double sepd_min_channel_charge) + { + m_sepd_min_channel_charge = sepd_min_channel_charge; + } + + private: + + static bool hasValidTree(const std::string &filePath); + static int CreateNodes(PHCompositeNode *topNode); + + std::array, 2> calculate_flattening_matrix(double xx, double yy, double xy, int n, int cent_bin, const std::string& det_label); + void LoadCalib(); + + void print_correction_data(); + void print_QVectors(); + + int process_centrality(PHCompositeNode *topNode); + int process_sEPD(PHCompositeNode *topNode); + void correct_QVecs(); + + int FillNode(PHCompositeNode *topNode); + + std::string m_directURL_EventPlaneCalib; + bool m_doAbortNoEventPlaneCalib{false}; + bool m_doNotCalib{false}; + bool m_doNotCalibEvent{false}; + + double m_cent{0.0}; + double m_globalEvent{0}; + double m_sepd_min_channel_charge{0.2}; + + std::string m_calibName{"SEPD_EventPlaneCalib"}; + std::string m_inputNode{"TOWERINFO_CALIB_SEPD"}; + + std::unique_ptr m_cdbttree; + + enum class Subdetector + { + S, + N + }; + + struct QVec + { + double x{0.0}; + double y{0.0}; + }; + + struct CorrectionData + { + // Averages of Qx, Qy, Qx^2, Qy^2, Qxy + QVec avg_Q{}; + double avg_Q_xx{0.0}; + double avg_Q_yy{0.0}; + double avg_Q_xy{0.0}; + + // Correction matrix + std::array, 2> X_matrix{}; + }; + + static constexpr size_t m_bins_cent = 8; + static constexpr std::array m_harmonics = {2, 3, 4}; + + // Holds all correction data + // key: [Harmonic][Cent][Subdetector] + // Harmonics {2,3,4} -> 3 elements + // Subdetectors {S,N} -> 2 elements + std::array, m_bins_cent>, m_harmonics.size()> m_correction_data; + + // sEPD Q Vectors + // key: [Harmonic][Subdetector] + // Subdetectors {S,N} -> 2 elements + std::array, m_harmonics.size()> m_Q_raw{}; + std::array, m_harmonics.size()> m_Q_recentered{}; + std::array, m_harmonics.size()> m_Q_flat{}; +}; +#endif diff --git a/offline/packages/eventplaneinfo/Eventplaneinfo.h b/offline/packages/eventplaneinfo/Eventplaneinfo.h index 1ad2665881..32dbb4ca54 100644 --- a/offline/packages/eventplaneinfo/Eventplaneinfo.h +++ b/offline/packages/eventplaneinfo/Eventplaneinfo.h @@ -23,8 +23,12 @@ class Eventplaneinfo : public PHObject PHObject* CloneMe() const override { return nullptr; } virtual void set_qvector(std::vector> /*Qvec*/) { return; } + virtual void set_qvector_raw(const std::vector>& /*Qvec*/) { return; } + virtual void set_qvector_recentered(const std::vector>& /*Qvec*/) { return; } virtual void set_shifted_psi(std::vector /*Psi_Shifted*/) { return; } virtual std::pair get_qvector(int /*order*/) const { return std::make_pair(NAN, NAN); } + virtual std::pair get_qvector_raw(int /*order*/) const { return std::make_pair(NAN, NAN); } + virtual std::pair get_qvector_recentered(int /*order*/) const { return std::make_pair(NAN, NAN); } virtual double get_psi(int /*order*/) const { return NAN; } virtual double get_shifted_psi(int /*order*/) const { return NAN; } virtual double GetPsi(const double /*Qx*/, const double /*Qy*/, const unsigned int /*order*/) const { return NAN; } diff --git a/offline/packages/eventplaneinfo/Eventplaneinfov2.cc b/offline/packages/eventplaneinfo/Eventplaneinfov2.cc new file mode 100644 index 0000000000..7f35820034 --- /dev/null +++ b/offline/packages/eventplaneinfo/Eventplaneinfov2.cc @@ -0,0 +1,23 @@ +#include "Eventplaneinfov2.h" + +#include + +void Eventplaneinfov2::identify(std::ostream& os) const +{ + os << "---------Eventplaneinfov2------------------" << std::endl; + return; +} + +double Eventplaneinfov2::GetPsi(const double Qx, const double Qy, const unsigned int order) const +{ + double temp; + if ((Qx == 0.0) && (Qy == 0.0)) + { + temp = NAN; + } + else + { + temp = atan2(Qy, Qx) / ((double) order); + } + return temp; +} diff --git a/offline/packages/eventplaneinfo/Eventplaneinfov2.h b/offline/packages/eventplaneinfo/Eventplaneinfov2.h new file mode 100644 index 0000000000..c447316590 --- /dev/null +++ b/offline/packages/eventplaneinfo/Eventplaneinfov2.h @@ -0,0 +1,55 @@ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef EVENTPLANEINFOV2_H +#define EVENTPLANEINFOV2_H + +#include "Eventplaneinfo.h" + +#include // for size_t +#include +#include +#include // for pair, make_pair +#include + +class PHObject; + +class Eventplaneinfov2 : public Eventplaneinfo +{ + public: + Eventplaneinfov2() = default; + ~Eventplaneinfov2() override = default; + + Eventplaneinfov2(const Eventplaneinfov2&) = default; + Eventplaneinfov2& operator=(const Eventplaneinfov2&) = default; + Eventplaneinfov2(Eventplaneinfov2&&) = default; + Eventplaneinfov2& operator=(Eventplaneinfov2&&) = default; + + void identify(std::ostream& os = std::cout) const override; + void Reset() override { *this = Eventplaneinfov2(); } + PHObject* CloneMe() const override { return new Eventplaneinfov2(*this); } + + void set_qvector(std::vector> Qvec) override { mQvec = Qvec; } + void set_qvector_raw(const std::vector>& Qvec) override { mQvec_raw = Qvec; } + void set_qvector_recentered(const std::vector>& Qvec) override { mQvec_recentered = Qvec; } + void set_shifted_psi(std::vector Psi_Shifted) override { mPsi_Shifted = Psi_Shifted; } + std::pair get_qvector(int order) const override { return std::make_pair(mQvec[order - 1].first, mQvec[order - 1].second); } + std::pair get_qvector_raw(int order) const override { return std::make_pair(mQvec_raw[order - 1].first, mQvec_raw[order - 1].second); } + std::pair get_qvector_recentered(int order) const override { return std::make_pair(mQvec_recentered[order - 1].first, mQvec_recentered[order - 1].second); } + void set_ring_qvector(std::vector>> Qvec) override { ring_Qvec = Qvec; } + std::pair get_ring_qvector(int ring_index, int order) const override { return ring_Qvec[ring_index][order - 1]; } + double get_ring_psi(int ring_index, int order) const override {return GetPsi(ring_Qvec[ring_index][order - 1].first,ring_Qvec[ring_index][order - 1].second,order);} + double GetPsi(double Qx, double Qy, unsigned int order) const override; + double get_psi(int order) const override { return GetPsi(mQvec[order - 1].first, mQvec[order - 1].second, order);} + double get_shifted_psi(int order) const override { return mPsi_Shifted[order - 1]; } + + private: + std::vector> mQvec; + std::vector> mQvec_raw; + std::vector> mQvec_recentered; + std::vector mPsi_Shifted; + std::vector>> ring_Qvec; + ClassDefOverride(Eventplaneinfov2, 1); +}; + +#endif + diff --git a/offline/packages/eventplaneinfo/Eventplaneinfov2LinkDef.h b/offline/packages/eventplaneinfo/Eventplaneinfov2LinkDef.h new file mode 100644 index 0000000000..961c0446cf --- /dev/null +++ b/offline/packages/eventplaneinfo/Eventplaneinfov2LinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class Eventplaneinfov2 + ; + +#endif /* __CINT__ */ diff --git a/offline/packages/eventplaneinfo/Makefile.am b/offline/packages/eventplaneinfo/Makefile.am index 3a1192095d..293e3675d6 100644 --- a/offline/packages/eventplaneinfo/Makefile.am +++ b/offline/packages/eventplaneinfo/Makefile.am @@ -32,13 +32,16 @@ pkginclude_HEADERS = \ EventPlaneCalibration.h \ Eventplaneinfo.h \ Eventplaneinfov1.h \ + Eventplaneinfov2.h \ EventplaneinfoMap.h \ EventplaneinfoMapv1.h \ - EventPlaneReco.h + EventPlaneReco.h \ + EventPlaneRecov2.h ROOTDICTS = \ Eventplaneinfo_Dict.cc \ Eventplaneinfov1_Dict.cc \ + Eventplaneinfov2_Dict.cc \ EventplaneinfoMap_Dict.cc \ EventplaneinfoMapv1_Dict.cc @@ -50,12 +53,14 @@ libeventplaneinfo_io_la_SOURCES = \ $(ROOTDICTS) \ Eventplaneinfo.cc \ Eventplaneinfov1.cc \ + Eventplaneinfov2.cc \ EventplaneinfoMap.cc \ EventplaneinfoMapv1.cc libeventplaneinfo_la_SOURCES = \ EventPlaneCalibration.cc \ - EventPlaneReco.cc + EventPlaneReco.cc \ + EventPlaneRecov2.cc # Rule for generating table CINT dictionaries. %_Dict.cc: %.h %LinkDef.h From aedac34906cd32551f024a3d44b37d9491b8478e Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Fri, 23 Jan 2026 14:01:49 -0500 Subject: [PATCH 200/393] CaloTowerStatus - sEPD Bad Tower Maps - Allow the sEPD bad tower maps to be processed via the CaloTowerStatus module. --- offline/packages/CaloReco/CaloTowerStatus.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/CaloReco/CaloTowerStatus.cc b/offline/packages/CaloReco/CaloTowerStatus.cc index c5401edb33..954c0a2b3b 100644 --- a/offline/packages/CaloReco/CaloTowerStatus.cc +++ b/offline/packages/CaloReco/CaloTowerStatus.cc @@ -144,7 +144,7 @@ int CaloTowerStatus::InitRun(PHCompositeNode *topNode) } m_calibName_hotMap = m_detector + "nome"; - if (m_dettype == CaloTowerDefs::CEMC) + if (m_dettype == CaloTowerDefs::CEMC || m_dettype == CaloTowerDefs::SEPD) { m_calibName_hotMap = m_detector + "_BadTowerMap"; } From 6fb59afba8cf615bebe50a1805850a00a328a0f8 Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Thu, 29 Jan 2026 22:37:40 -0500 Subject: [PATCH 201/393] Combined North-South Q-vector Calibration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Integrate the "Combined NS" calibration strategy into the reconstruction pipeline to improve event plane resolution and flatness. This update treats the combined North-South detector as a distinct third entity for flattening, while preserving multiplicity-based resolution weighting through individual sub-detector recentering. Core Logic Updates: - Calibration Loading: Updated LoadCalib to retrieve North-South specific second moments (⟨Qx2​⟩, ⟨Qy2​⟩, ⟨Qx​Qy​⟩) from the Calibration Database (CDB). - Matrix Computation: Implemented unique flattening matrix calculation for the NS detector slot (Index 2) during initialization. 1) "Best of Both Worlds" Correction: Refactored correct_QVecs to implement the optimized combination logic: 2) Recenters South and North vectors individually. 3) Sums the recentered components to form the combined recentered vector: Q_NS,rec​ = Q_S,rec ​+ Q_N,rec​. - Applies the dedicated NS flattening matrix to the resulting sum to ensure a circular (flat) distribution. - Raw Vector Summation: Updated process_sEPD to populate the raw NS vector by summing normalized sub-detector components, facilitating direct QA comparisons. Infrastructure & Efficiency: - Array Expansion: Increased internal storage arrays for m_correction_data, m_Q_raw, m_Q_recentered, and m_Q_flat from size 2 to size 3 to accommodate the NS detector index. Diagnostics & Quality Assurance: - Print Methods: Expanded print_correction_data and print_QVectors to display diagnostic information for all three detector slots (South, North, and NorthSouth). - Fallback Safety: Maintained fallback logic that utilizes raw Q-vectors in the event of missing calibration data or invalid event centrality, preventing empty output nodes. --- .../eventplaneinfo/EventPlaneRecov2.cc | 99 ++++++++++++++----- .../eventplaneinfo/EventPlaneRecov2.h | 15 +-- 2 files changed, 83 insertions(+), 31 deletions(-) diff --git a/offline/packages/eventplaneinfo/EventPlaneRecov2.cc b/offline/packages/eventplaneinfo/EventPlaneRecov2.cc index 8a468a1acb..f475f0ef57 100644 --- a/offline/packages/eventplaneinfo/EventPlaneRecov2.cc +++ b/offline/packages/eventplaneinfo/EventPlaneRecov2.cc @@ -74,7 +74,7 @@ bool EventPlaneRecov2::hasValidTree(const std::string &filePath) } //____________________________________________________________________________.. -int EventPlaneRecov2::Init([[maybe_unused]] PHCompositeNode *topNode) +int EventPlaneRecov2::Init(PHCompositeNode *topNode) { std::string calibdir = CDBInterface::instance()->getUrl(m_calibName); @@ -152,6 +152,7 @@ void EventPlaneRecov2::LoadCalib() { size_t south_idx = static_cast(Subdetector::S); size_t north_idx = static_cast(Subdetector::N); + size_t ns_idx = static_cast(Subdetector::NS); for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) { @@ -169,6 +170,10 @@ void EventPlaneRecov2::LoadCalib() std::string N_yy_avg_name = std::format("Q_N_yy_{}_avg", n); std::string N_xy_avg_name = std::format("Q_N_xy_{}_avg", n); + std::string NS_xx_avg_name = std::format("Q_NS_xx_{}_avg", n); + std::string NS_yy_avg_name = std::format("Q_NS_yy_{}_avg", n); + std::string NS_xy_avg_name = std::format("Q_NS_xy_{}_avg", n); + for (size_t cent_bin = 0; cent_bin < m_bins_cent; ++cent_bin) { int key = static_cast(cent_bin); @@ -194,6 +199,16 @@ void EventPlaneRecov2::LoadCalib() dataN.avg_Q_xy = m_cdbttree->GetDoubleValue(key, N_xy_avg_name); dataN.X_matrix = calculate_flattening_matrix(dataN.avg_Q_xx, dataN.avg_Q_yy, dataN.avg_Q_xy, n, cent_bin, "North"); + + // North South + // Note: We do NOT load avg_Q (x,y) for NS because NS is recentered by summing the recentered S and N vectors. + auto& dataNS = m_correction_data[h_idx][cent_bin][ns_idx]; + + dataNS.avg_Q_xx = m_cdbttree->GetDoubleValue(key, NS_xx_avg_name); + dataNS.avg_Q_yy = m_cdbttree->GetDoubleValue(key, NS_yy_avg_name); + dataNS.avg_Q_xy = m_cdbttree->GetDoubleValue(key, NS_xy_avg_name); + + dataNS.X_matrix = calculate_flattening_matrix(dataNS.avg_Q_xx, dataNS.avg_Q_yy, dataNS.avg_Q_xy, n, cent_bin, "NorthSouth"); } } } @@ -222,11 +237,26 @@ void EventPlaneRecov2::print_correction_data() "Detector", "Avg Qx", "Avg Qy", "Avg Qxx", "Avg Qyy", "Avg Qxy"); // Iterate through Subdetectors {S, N} - for (size_t det_idx = 0; det_idx < 2; ++det_idx) + for (size_t det_idx = 0; det_idx < 3; ++det_idx) { - std::string det_name = (det_idx == static_cast(Subdetector::S)) ? "South" : "North"; - const auto& data = m_correction_data[h_idx][cent][det_idx]; // - + std::string det_name; + if (det_idx == 0) + { + det_name = "South"; + } + else if (det_idx == 1) + { + det_name = "North"; + } + else + { + det_name = "NorthSouth"; + } + + const auto& data = m_correction_data[h_idx][cent][det_idx]; + + // For NS, Avg Qx/Qy will be 0.0 because they are not loaded from CDB. + // This is expected behavior. std::cout << std::format(" {:<12} {:>10.6f} {:>10.6f} {:>10.6f} {:>10.6f} {:>10.6f}\n", det_name, data.avg_Q.x, data.avg_Q.y, @@ -376,6 +406,10 @@ int EventPlaneRecov2::process_sEPD(PHCompositeNode* topNode) m_Q_raw[h_idx][1].x /= sepd_total_charge_north; m_Q_raw[h_idx][1].y /= sepd_total_charge_north; + + // NEW: Calculate Raw NS (Sum of Raw S + Raw N) + m_Q_raw[h_idx][2].x = m_Q_raw[h_idx][0].x + m_Q_raw[h_idx][1].x; + m_Q_raw[h_idx][2].y = m_Q_raw[h_idx][0].y + m_Q_raw[h_idx][1].y; } return Fun4AllReturnCodes::EVENT_OK; @@ -391,11 +425,13 @@ void EventPlaneRecov2::correct_QVecs() size_t south_idx = static_cast(Subdetector::S); size_t north_idx = static_cast(Subdetector::N); + size_t ns_idx = static_cast(Subdetector::NS); for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) { auto& dataS = m_correction_data[h_idx][cent_bin][south_idx]; auto& dataN = m_correction_data[h_idx][cent_bin][north_idx]; + auto& dataNS = m_correction_data[h_idx][cent_bin][ns_idx]; double Q_S_x_avg = dataS.avg_Q.x; double Q_S_y_avg = dataS.avg_Q.y; @@ -408,12 +444,16 @@ void EventPlaneRecov2::correct_QVecs() // Apply Recentering QVec q_S_recenter = {q_S.x - Q_S_x_avg, q_S.y - Q_S_y_avg}; QVec q_N_recenter = {q_N.x - Q_N_x_avg, q_N.y - Q_N_y_avg}; + QVec q_NS_recenter = {q_S_recenter.x + q_N_recenter.x, q_S_recenter.y + q_N_recenter.y}; - m_Q_recentered[h_idx][0] = q_S_recenter; - m_Q_recentered[h_idx][1] = q_N_recenter; + m_Q_recentered[h_idx][south_idx] = q_S_recenter; + m_Q_recentered[h_idx][north_idx] = q_N_recenter; + m_Q_recentered[h_idx][ns_idx] = q_NS_recenter; + // Flattening Matrix const auto &X_S = dataS.X_matrix; const auto &X_N = dataN.X_matrix; + const auto &X_NS = dataNS.X_matrix; // Apply Flattening double Q_S_x_flat = X_S[0][0] * q_S_recenter.x + X_S[0][1] * q_S_recenter.y; @@ -421,11 +461,16 @@ void EventPlaneRecov2::correct_QVecs() double Q_N_x_flat = X_N[0][0] * q_N_recenter.x + X_N[0][1] * q_N_recenter.y; double Q_N_y_flat = X_N[1][0] * q_N_recenter.x + X_N[1][1] * q_N_recenter.y; + double Q_NS_x_flat = X_NS[0][0] * q_NS_recenter.x + X_NS[0][1] * q_NS_recenter.y; + double Q_NS_y_flat = X_NS[1][0] * q_NS_recenter.x + X_NS[1][1] * q_NS_recenter.y; + QVec q_S_flat = {Q_S_x_flat, Q_S_y_flat}; QVec q_N_flat = {Q_N_x_flat, Q_N_y_flat}; + QVec q_NS_flat = {Q_NS_x_flat, Q_NS_y_flat}; m_Q_flat[h_idx][south_idx] = q_S_flat; m_Q_flat[h_idx][north_idx] = q_N_flat; + m_Q_flat[h_idx][ns_idx] = q_NS_flat; } } @@ -446,9 +491,21 @@ void EventPlaneRecov2::print_QVectors() { int n = m_harmonics[h_idx]; - for (size_t det_idx = 0; det_idx < 2; ++det_idx) + for (size_t det_idx = 0; det_idx < 3; ++det_idx) { - std::string det_name = (det_idx == static_cast(Subdetector::S)) ? "South" : "North"; + std::string det_name; + if (det_idx == 0) + { + det_name = "South"; + } + else if (det_idx == 1) + { + det_name = "North"; + } + else + { + det_name = "NorthSouth"; + } const auto& raw = m_Q_raw[h_idx][det_idx]; const auto& rec = m_Q_recentered[h_idx][det_idx]; @@ -472,7 +529,7 @@ void EventPlaneRecov2::print_QVectors() std::cout << std::format("{:*>100}\n\n", ""); } -int EventPlaneRecov2::FillNode([[maybe_unused]] PHCompositeNode *topNode) +int EventPlaneRecov2::FillNode(PHCompositeNode *topNode) { EventplaneinfoMap *epmap = findNode::getClass(topNode, "EventplaneinfoMap"); if (!epmap) @@ -507,6 +564,7 @@ int EventPlaneRecov2::FillNode([[maybe_unused]] PHCompositeNode *topNode) // Fallback logic: Use raw if calibration failed or centrality is out of range const auto& Q_S = (m_doNotCalib || m_doNotCalibEvent) ? m_Q_raw[h_idx][0] : m_Q_flat[h_idx][0]; const auto& Q_N = (m_doNotCalib || m_doNotCalibEvent) ? m_Q_raw[h_idx][1] : m_Q_flat[h_idx][1]; + const auto& Q_NS = (m_doNotCalib || m_doNotCalibEvent) ? m_Q_raw[h_idx][2] : m_Q_flat[h_idx][2]; const auto& Q_S_raw = m_Q_raw[h_idx][0]; const auto& Q_S_recentered = m_Q_recentered[h_idx][0]; @@ -514,6 +572,9 @@ int EventPlaneRecov2::FillNode([[maybe_unused]] PHCompositeNode *topNode) const auto& Q_N_raw = m_Q_raw[h_idx][1]; const auto& Q_N_recentered = m_Q_recentered[h_idx][1]; + const auto& Q_NS_raw = m_Q_raw[h_idx][2]; + const auto& Q_NS_recentered = m_Q_recentered[h_idx][2]; + // South south_Qvec_raw[idx] = {Q_S_raw.x, Q_S_raw.y}; south_Qvec_recentered[idx] = {Q_S_recentered.x, Q_S_recentered.y}; @@ -525,18 +586,9 @@ int EventPlaneRecov2::FillNode([[maybe_unused]] PHCompositeNode *topNode) north_Qvec[idx] = {Q_N.x, Q_N.y}; // Combined (North + South) - double Qx_NS_raw = Q_S_raw.x + Q_N_raw.x; - double Qy_NS_raw = Q_S_raw.y + Q_N_raw.y; - - double Qx_NS_recentered = Q_S_recentered.x + Q_N_recentered.x; - double Qy_NS_recentered = Q_S_recentered.y + Q_N_recentered.y; - - double Qx_NS = Q_S.x + Q_N.x; - double Qy_NS = Q_S.y + Q_N.y; - - northsouth_Qvec_raw[idx] = {Qx_NS_raw, Qy_NS_raw}; - northsouth_Qvec_recentered[idx] = {Qx_NS_recentered, Qy_NS_recentered}; - northsouth_Qvec[idx] = {Qx_NS, Qy_NS}; + northsouth_Qvec_raw[idx] = {Q_NS_raw.x, Q_NS_raw.y}; + northsouth_Qvec_recentered[idx] = {Q_NS_recentered.x, Q_NS_recentered.y}; + northsouth_Qvec[idx] = {Q_NS.x, Q_NS.y}; } // Helper lambda to fill nodes using the class's GetPsi method @@ -562,9 +614,8 @@ int EventPlaneRecov2::FillNode([[maybe_unused]] PHCompositeNode *topNode) } //____________________________________________________________________________.. -int EventPlaneRecov2::process_event([[maybe_unused]] PHCompositeNode *topNode) +int EventPlaneRecov2::process_event(PHCompositeNode *topNode) { - EventHeader *eventInfo = findNode::getClass(topNode, "EventHeader"); if (!eventInfo) { diff --git a/offline/packages/eventplaneinfo/EventPlaneRecov2.h b/offline/packages/eventplaneinfo/EventPlaneRecov2.h index a1d5017ca3..4d12aca1bd 100644 --- a/offline/packages/eventplaneinfo/EventPlaneRecov2.h +++ b/offline/packages/eventplaneinfo/EventPlaneRecov2.h @@ -96,7 +96,8 @@ class EventPlaneRecov2 : public SubsysReco enum class Subdetector { S, - N + N, + NS }; struct QVec @@ -123,14 +124,14 @@ class EventPlaneRecov2 : public SubsysReco // Holds all correction data // key: [Harmonic][Cent][Subdetector] // Harmonics {2,3,4} -> 3 elements - // Subdetectors {S,N} -> 2 elements - std::array, m_bins_cent>, m_harmonics.size()> m_correction_data; + // Subdetectors {S,N,NS} -> 3 elements + std::array, m_bins_cent>, m_harmonics.size()> m_correction_data; // sEPD Q Vectors // key: [Harmonic][Subdetector] - // Subdetectors {S,N} -> 2 elements - std::array, m_harmonics.size()> m_Q_raw{}; - std::array, m_harmonics.size()> m_Q_recentered{}; - std::array, m_harmonics.size()> m_Q_flat{}; + // Subdetectors {S,N,NS} -> 3 elements + std::array, m_harmonics.size()> m_Q_raw{}; + std::array, m_harmonics.size()> m_Q_recentered{}; + std::array, m_harmonics.size()> m_Q_flat{}; }; #endif From 8b5c354c39a7ed64cae634b3bc9139e6a699c85d Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Sat, 31 Jan 2026 22:41:34 -0500 Subject: [PATCH 202/393] Code Review Address Major Issues: - Ensure m_directURL_EventPlaneCalib is not empty before passing it to hasValidTree - Removed unused vectors in EventPlaneRecov2 (south_psi, north_psi, northsouth_psi) - Guard against order == 0 to avoid divide-by-zero. - Add bounds checks before indexing Q-vector storage. --- .../eventplaneinfo/EventPlaneRecov2.cc | 6 +-- .../eventplaneinfo/Eventplaneinfov2.cc | 11 ++--- .../eventplaneinfo/Eventplaneinfov2.h | 48 +++++++++++++++---- 3 files changed, 46 insertions(+), 19 deletions(-) diff --git a/offline/packages/eventplaneinfo/EventPlaneRecov2.cc b/offline/packages/eventplaneinfo/EventPlaneRecov2.cc index f475f0ef57..c2cd8e3360 100644 --- a/offline/packages/eventplaneinfo/EventPlaneRecov2.cc +++ b/offline/packages/eventplaneinfo/EventPlaneRecov2.cc @@ -78,7 +78,7 @@ int EventPlaneRecov2::Init(PHCompositeNode *topNode) { std::string calibdir = CDBInterface::instance()->getUrl(m_calibName); - if (hasValidTree(m_directURL_EventPlaneCalib)) + if (!m_directURL_EventPlaneCalib.empty() && hasValidTree(m_directURL_EventPlaneCalib)) { m_cdbttree = std::make_unique(m_directURL_EventPlaneCalib); std::cout << PHWHERE << " Custom Event Plane Calib Found: " << m_directURL_EventPlaneCalib << std::endl; @@ -552,10 +552,6 @@ int EventPlaneRecov2::FillNode(PHCompositeNode *topNode) std::vector> northsouth_Qvec_recentered(vec_size, {NAN, NAN}); std::vector> northsouth_Qvec(vec_size, {NAN, NAN}); - std::vector south_psi(vec_size, NAN); - std::vector north_psi(vec_size, NAN); - std::vector northsouth_psi(vec_size, NAN); - for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) { int n = m_harmonics[h_idx]; diff --git a/offline/packages/eventplaneinfo/Eventplaneinfov2.cc b/offline/packages/eventplaneinfo/Eventplaneinfov2.cc index 7f35820034..e8ff5385b8 100644 --- a/offline/packages/eventplaneinfo/Eventplaneinfov2.cc +++ b/offline/packages/eventplaneinfo/Eventplaneinfov2.cc @@ -10,14 +10,13 @@ void Eventplaneinfov2::identify(std::ostream& os) const double Eventplaneinfov2::GetPsi(const double Qx, const double Qy, const unsigned int order) const { - double temp; - if ((Qx == 0.0) && (Qy == 0.0)) + if (order == 0) { - temp = NAN; + return NAN; } - else + if ((Qx == 0.0) && (Qy == 0.0)) { - temp = atan2(Qy, Qx) / ((double) order); + return NAN; } - return temp; + return atan2(Qy, Qx) / static_cast(order); } diff --git a/offline/packages/eventplaneinfo/Eventplaneinfov2.h b/offline/packages/eventplaneinfo/Eventplaneinfov2.h index c447316590..d69bc9a5ae 100644 --- a/offline/packages/eventplaneinfo/Eventplaneinfov2.h +++ b/offline/packages/eventplaneinfo/Eventplaneinfov2.h @@ -32,17 +32,49 @@ class Eventplaneinfov2 : public Eventplaneinfo void set_qvector_raw(const std::vector>& Qvec) override { mQvec_raw = Qvec; } void set_qvector_recentered(const std::vector>& Qvec) override { mQvec_recentered = Qvec; } void set_shifted_psi(std::vector Psi_Shifted) override { mPsi_Shifted = Psi_Shifted; } - std::pair get_qvector(int order) const override { return std::make_pair(mQvec[order - 1].first, mQvec[order - 1].second); } - std::pair get_qvector_raw(int order) const override { return std::make_pair(mQvec_raw[order - 1].first, mQvec_raw[order - 1].second); } - std::pair get_qvector_recentered(int order) const override { return std::make_pair(mQvec_recentered[order - 1].first, mQvec_recentered[order - 1].second); } + std::pair get_qvector(int order) const override { return safe_qvec(mQvec, order); } + std::pair get_qvector_raw(int order) const override { return safe_qvec(mQvec_raw, order); } + std::pair get_qvector_recentered(int order) const override { return safe_qvec(mQvec_recentered, order); } void set_ring_qvector(std::vector>> Qvec) override { ring_Qvec = Qvec; } - std::pair get_ring_qvector(int ring_index, int order) const override { return ring_Qvec[ring_index][order - 1]; } - double get_ring_psi(int ring_index, int order) const override {return GetPsi(ring_Qvec[ring_index][order - 1].first,ring_Qvec[ring_index][order - 1].second,order);} + std::pair get_ring_qvector(int ring_index, int order) const override + { + if (ring_index < 0 || static_cast(ring_index) >= ring_Qvec.size()) + { + return {NAN, NAN}; + } + return safe_qvec(ring_Qvec[ring_index], order); + } + double get_ring_psi(int ring_index, int order) const override + { + auto q = get_ring_qvector(ring_index, order); + return GetPsi(q.first, q.second, static_cast(order)); + } + double GetPsi(double Qx, double Qy, unsigned int order) const override; - double get_psi(int order) const override { return GetPsi(mQvec[order - 1].first, mQvec[order - 1].second, order);} - double get_shifted_psi(int order) const override { return mPsi_Shifted[order - 1]; } - + double get_psi(int order) const override + { + auto q = get_qvector(order); + return GetPsi(q.first, q.second, static_cast(order)); + } + double get_shifted_psi(int order) const override + { + if (order <= 0 || static_cast(order) > mPsi_Shifted.size()) + { + return NAN; + } + return mPsi_Shifted[order - 1]; + } + private: + static std::pair safe_qvec(const std::vector>& v, int order) + { + if (order <= 0 || static_cast(order) > v.size()) + { + return {NAN, NAN}; + } + return v[order - 1]; + } + std::vector> mQvec; std::vector> mQvec_raw; std::vector> mQvec_recentered; From db925a71d75d22494ba41cd548e03fed517940e1 Mon Sep 17 00:00:00 2001 From: Joseph Clement Date: Mon, 9 Feb 2026 16:46:18 -0500 Subject: [PATCH 203/393] fix typo --- offline/packages/jetbackground/TimingCut.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/jetbackground/TimingCut.h b/offline/packages/jetbackground/TimingCut.h index ad212d1146..a12c432c31 100644 --- a/offline/packages/jetbackground/TimingCut.h +++ b/offline/packages/jetbackground/TimingCut.h @@ -24,7 +24,7 @@ class TimingCut : public SubsysReco float Correct_Time_Ohfrac(float t, float ohfrac) { - float corrt = t + _fitFunc->Eval(ohfrac); + float corrt = t - _fitFunc->Eval(ohfrac); return corrt; } From 0e80888920b77df04b0f548bb9bdb7bbbba9c00a Mon Sep 17 00:00:00 2001 From: Joseph Clement Date: Mon, 9 Feb 2026 17:12:04 -0500 Subject: [PATCH 204/393] add includes and cdb stuff --- offline/packages/jetbackground/TimingCut.cc | 11 ++++++++++- offline/packages/jetbackground/TimingCut.h | 5 +++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/offline/packages/jetbackground/TimingCut.cc b/offline/packages/jetbackground/TimingCut.cc index 81053863f6..7d63e5c432 100644 --- a/offline/packages/jetbackground/TimingCut.cc +++ b/offline/packages/jetbackground/TimingCut.cc @@ -12,6 +12,11 @@ #include #include +#include // for CDBTF1 + +#include +#include +#include #include #include // for basic_ostream, operator<< #include // for _Rb_tree_iterator, opera... @@ -36,6 +41,10 @@ int TimingCut::Init(PHCompositeNode *topNode) return Fun4AllReturnCodes::ABORTRUN; } + _fitFile = new CDBTF(CDBInterface::instance()->getUrl("t_ohfrac_calib_Default")); + _fitFile->LoadCalibrations(); + _fitFunc = _fitFile->getTF("t_ohcal_calib_function_Default"); + return Fun4AllReturnCodes::EVENT_OK; } @@ -58,7 +67,7 @@ int TimingCut::CreateNodeTree(PHCompositeNode *topNode) int TimingCut::process_event(PHCompositeNode *topNode) { JetContainer *jets = findNode::getClass(topNode, _jetNodeName); - TowerInfoContainer* towersOH = findNode::getClas(topNode, _ohTowerName); + TowerInfoContainer* towersOH = findNode::getClass(topNode, _ohTowerName); if (!jets || !towersOH) { if (Verbosity() > 0 && !_missingInfoWarningPrinted) diff --git a/offline/packages/jetbackground/TimingCut.h b/offline/packages/jetbackground/TimingCut.h index a12c432c31..d932c4cac5 100644 --- a/offline/packages/jetbackground/TimingCut.h +++ b/offline/packages/jetbackground/TimingCut.h @@ -13,6 +13,7 @@ #include #include +class CDBTF; class PHCompositeNode; class TimingCut : public SubsysReco @@ -108,8 +109,8 @@ class TimingCut : public SubsysReco float _t_shift{0.0}; float _mbd_dt_width{3.0}; float _min_dphi{3*M_PI/4}; - TFile* _fitFile = nullptr; - TF1* _fitFunc = nullptr; + CDBTF* _fitFile{nullptr}; + TF1* _fitFunc{nullptr}; }; #endif From 7722e11146d6c4bf231bf71331eb0c5b4d816464 Mon Sep 17 00:00:00 2001 From: Anthony Denis Frawley Date: Mon, 9 Feb 2026 21:34:37 -0500 Subject: [PATCH 205/393] Mods to allow different decay masses for the two decay particles --- .../KshortReconstruction.cc | 237 +++++++++++++++--- .../KshortReconstruction.h | 17 +- 2 files changed, 220 insertions(+), 34 deletions(-) diff --git a/offline/packages/TrackingDiagnostics/KshortReconstruction.cc b/offline/packages/TrackingDiagnostics/KshortReconstruction.cc index f92bfc9581..a7a240ffcf 100644 --- a/offline/packages/TrackingDiagnostics/KshortReconstruction.cc +++ b/offline/packages/TrackingDiagnostics/KshortReconstruction.cc @@ -260,36 +260,63 @@ int KshortReconstruction::process_event(PHCompositeNode* topNode) // if(pair_dca_proj > pair_dca_cut) continue; - // invariant mass is calculated in this method - fillHistogram(projected_mom1, projected_mom2, recomass, invariantMass, invariantPt, invariantPhi, rapidity, pseudorapidity); - fillNtp(tr1, tr2, dcaVals1, dcaVals2, pca_rel1, pca_rel2, pair_dca, invariantMass, invariantPt, invariantPhi, rapidity, pseudorapidity, projected_pos1, projected_pos2, projected_mom1, projected_mom2, pca_rel1_proj, pca_rel2_proj, pair_dca_proj, track1_silicon_cluster_size, track2_silicon_cluster_size, track1_mvtx_cluster_size, track1_mvtx_state_size, track1_intt_cluster_size, track1_intt_state_size, track2_mvtx_cluster_size, track2_mvtx_state_size, track2_intt_cluster_size, track2_intt_state_size, m_runNumber, m_evtNumber); - - if (Verbosity() > 1) - { - std::cout << " Accepted Track Pair" << std::endl; - std::cout << " id1 " << id1 << " id2 " << id2 << std::endl; - std::cout << " crossing1 " << crossing1 << " crossing2 " << crossing2 << std::endl; - std::cout << " invariant mass: " << invariantMass << std::endl; - std::cout << " track1 dca_cut: " << this_dca_cut << " track2 dca_cut: " << this_dca_cut2 << std::endl; - std::cout << " dca3dxy1,dca3dz1,phi1: " << dcaVals1 << std::endl; - std::cout << " dca3dxy2,dca3dz2,phi2: " << dcaVals2 << std::endl; - std::cout << "Initial: pca_rel1: " << pca_rel1 << " pca_rel2: " << pca_rel2 << std::endl; - std::cout << " Initial: mom1: " << mom1 << " mom2: " << mom2 << std::endl; - std::cout << "Proj_pca_rel: proj_pos1: " << projected_pos1 << " proj_pos2: " << projected_pos2 << " proj_mom1: " << projected_mom1 << " proj_mom2: " << projected_mom2 << std::endl; - std::cout << " Relative PCA = " << abs(pair_dca) << " pca_cut = " << pair_dca_cut << std::endl; - std::cout << " charge 1: " << tr1->get_charge() << " charge2: " << tr2->get_charge() << std::endl; - std::cout << "found viable projection" << std::endl; - std::cout << "Final: pca_rel1_proj: " << pca_rel1_proj << " pca_rel2_proj: " << pca_rel2_proj << " mom1: " << projected_mom1 << " mom2: " << projected_mom2 << std::endl - << std::endl; - } - + // calculate both ways if decaymass1 and decaymass2 are different + int ncombinations = 1; + if(decaymass1 != decaymass2) + { + ncombinations = 2; + } + for(int icomb=0;icomb < ncombinations; ++icomb) + { + float decaymassa = decaymass1; + float decaymassb = decaymass2; + if(icomb == 1) + { + decaymassa = decaymass2; + decaymassb = decaymass1; + } + + // invariant mass is calculated in this method + fillHistogram(projected_mom1, projected_mom2, recomass, invariantMass, invariantPt, invariantPhi, rapidity, pseudorapidity,decaymassa, decaymassb); + fillNtp(tr1, tr2, decaymassa, decaymassb, dcaVals1, dcaVals2, pca_rel1, pca_rel2, pair_dca, invariantMass, invariantPt, invariantPhi, rapidity, pseudorapidity, projected_pos1, projected_pos2, projected_mom1, projected_mom2, pca_rel1_proj, pca_rel2_proj, pair_dca_proj, track1_silicon_cluster_size, track2_silicon_cluster_size, track1_mvtx_cluster_size, track1_mvtx_state_size, track1_intt_cluster_size, track1_intt_state_size, track2_mvtx_cluster_size, track2_mvtx_state_size, track2_intt_cluster_size, track2_intt_state_size, m_runNumber, m_evtNumber); + + + + + + + /* + // invariant mass is calculated in this method + fillHistogram(projected_mom1, projected_mom2, recomass, invariantMass, invariantPt, invariantPhi, rapidity, pseudorapidity); + fillNtp(tr1, tr2, dcaVals1, dcaVals2, pca_rel1, pca_rel2, pair_dca, invariantMass, invariantPt, invariantPhi, rapidity, pseudorapidity, projected_pos1, projected_pos2, projected_mom1, projected_mom2, pca_rel1_proj, pca_rel2_proj, pair_dca_proj, track1_silicon_cluster_size, track2_silicon_cluster_size, track1_mvtx_cluster_size, track1_mvtx_state_size, track1_intt_cluster_size, track1_intt_state_size, track2_mvtx_cluster_size, track2_mvtx_state_size, track2_intt_cluster_size, track2_intt_state_size, m_runNumber, m_evtNumber); + */ + + if (Verbosity() > 1) + { + std::cout << " Accepted Track Pair" << std::endl; + std::cout << " id1 " << id1 << " id2 " << id2 << std::endl; + std::cout << " crossing1 " << crossing1 << " crossing2 " << crossing2 << std::endl; + std::cout << " invariant mass: " << invariantMass << std::endl; + std::cout << " track1 dca_cut: " << this_dca_cut << " track2 dca_cut: " << this_dca_cut2 << std::endl; + std::cout << " dca3dxy1,dca3dz1,phi1: " << dcaVals1 << std::endl; + std::cout << " dca3dxy2,dca3dz2,phi2: " << dcaVals2 << std::endl; + std::cout << "Initial: pca_rel1: " << pca_rel1 << " pca_rel2: " << pca_rel2 << std::endl; + std::cout << " Initial: mom1: " << mom1 << " mom2: " << mom2 << std::endl; + std::cout << "Proj_pca_rel: proj_pos1: " << projected_pos1 << " proj_pos2: " << projected_pos2 << " proj_mom1: " << projected_mom1 << " proj_mom2: " << projected_mom2 << std::endl; + std::cout << " Relative PCA = " << abs(pair_dca) << " pca_cut = " << pair_dca_cut << std::endl; + std::cout << " charge 1: " << tr1->get_charge() << " charge2: " << tr2->get_charge() << std::endl; + std::cout << "found viable projection" << std::endl; + std::cout << "Final: pca_rel1_proj: " << pca_rel1_proj << " pca_rel2_proj: " << pca_rel2_proj << " mom1: " << projected_mom1 << " mom2: " << projected_mom2 << std::endl + << std::endl; + } + } if (m_save_tracks) - { - m_output_trackMap = findNode::getClass(topNode, m_output_trackMap_node_name); - m_output_trackMap->insertWithKey(tr1, tr1->get_id()); - m_output_trackMap->insertWithKey(tr2, tr2->get_id()); - } - + { + m_output_trackMap = findNode::getClass(topNode, m_output_trackMap_node_name); + m_output_trackMap->insertWithKey(tr1, tr1->get_id()); + m_output_trackMap->insertWithKey(tr2, tr2->get_id()); + } + } } } @@ -340,6 +367,53 @@ std::vector KshortReconstruction::getTrackStates(SvtxTrack *track) return nstates; } +void KshortReconstruction::fillNtp(SvtxTrack* track1, SvtxTrack* track2, float mass1, float mass2, Acts::Vector3 dcavals1, Acts::Vector3 dcavals2, Acts::Vector3 pca_rel1, Acts::Vector3 pca_rel2, double pair_dca, double invariantMass, double invariantPt, float invariantPhi, float rapidity, float pseudorapidity, Eigen::Vector3d projected_pos1, Eigen::Vector3d projected_pos2, Eigen::Vector3d projected_mom1, Eigen::Vector3d projected_mom2, Acts::Vector3 pca_rel1_proj, Acts::Vector3 pca_rel2_proj, double pair_dca_proj, unsigned int track1_silicon_cluster_size, unsigned int track2_silicon_cluster_size, unsigned int track1_mvtx_cluster_size, unsigned int track1_mvtx_state_size, unsigned int track1_intt_cluster_size, unsigned int track1_intt_state_size, unsigned int track2_mvtx_cluster_size, unsigned int track2_mvtx_state_size, unsigned int track2_intt_cluster_size, unsigned int track2_intt_state_size, int runNumber, int eventNumber) +{ + double px1 = track1->get_px(); + double py1 = track1->get_py(); + double pz1 = track1->get_pz(); + auto *tpcSeed1 = track1->get_tpc_seed(); + size_t tpcClusters1 = tpcSeed1->size_cluster_keys(); + double eta1 = asinh(pz1 / sqrt(pow(px1, 2) + pow(py1, 2))); + + double px2 = track2->get_px(); + double py2 = track2->get_py(); + double pz2 = track2->get_pz(); + auto *tpcSeed2 = track2->get_tpc_seed(); + size_t tpcClusters2 = tpcSeed2->size_cluster_keys(); + double eta2 = asinh(pz2 / sqrt(pow(px2, 2) + pow(py2, 2))); + + auto vtxid = track1->get_vertex_id(); + + int ntracks_vertex = 0; + Acts::Vector3 vertex(0, 0, track1->get_z()); // fake primary vertex + auto *svtxVertex = m_vertexMap->get(vtxid); + if (svtxVertex) + { + vertex(0) = svtxVertex->get_x(); + vertex(1) = svtxVertex->get_y(); + vertex(2) = svtxVertex->get_z(); + ntracks_vertex = svtxVertex->size_tracks(); + } + + Acts::Vector3 pathLength = (pca_rel1 + pca_rel2) * 0.5 - vertex; + Acts::Vector3 pathLength_proj = (pca_rel1_proj + pca_rel2_proj) * 0.5 - vertex; + + float mag_pathLength = sqrt(pow(pathLength(0), 2) + pow(pathLength(1), 2) + pow(pathLength(2), 2)); + float mag_pathLength_proj = sqrt(pow(pathLength_proj(0), 2) + pow(pathLength_proj(1), 2) + pow(pathLength_proj(2), 2)); + + Acts::Vector3 projected_momentum = projected_mom1 + projected_mom2; + float cos_theta_reco = pathLength_proj.dot(projected_momentum) / (projected_momentum.norm() * pathLength_proj.norm()); + + + float reco_info[] = {(float) track1->get_id(), (float) mass1, (float) track1->get_crossing(), track1->get_x(), track1->get_y(), track1->get_z(), track1->get_px(), track1->get_py(), track1->get_pz(), (float) dcavals1(0), (float) dcavals1(1), (float) dcavals1(2), (float) pca_rel1(0), (float) pca_rel1(1), (float) pca_rel1(2), (float) eta1, (float) track1->get_charge(), (float) tpcClusters1, (float) track2->get_id(), (float) mass2, (float) track2->get_crossing(), track2->get_x(), track2->get_y(), track2->get_z(), track2->get_px(), track2->get_py(), track2->get_pz(), (float) dcavals2(0), (float) dcavals2(1), (float) dcavals2(2), (float) pca_rel2(0), (float) pca_rel2(1), (float) pca_rel2(2), (float) eta2, (float) track2->get_charge(), (float) tpcClusters2, (float) ntracks_vertex, (float) vertex(0), (float) vertex(1), (float) vertex(2), (float) pair_dca, (float) invariantMass, (float) invariantPt, invariantPhi, (float) pathLength(0), (float) pathLength(1), (float) pathLength(2), mag_pathLength, rapidity, pseudorapidity, (float) projected_pos1(0), (float) projected_pos1(1), (float) projected_pos1(2), (float) projected_pos2(0), (float) projected_pos2(1), (float) projected_pos2(2), (float) projected_mom1(0), (float) projected_mom1(1), (float) projected_mom1(2), (float) projected_mom2(0), (float) projected_mom2(1), (float) projected_mom2(2), (float) pca_rel1_proj(0), (float) pca_rel1_proj(1), (float) pca_rel1_proj(2), (float) pca_rel2_proj(0), (float) pca_rel2_proj(1), (float) pca_rel2_proj(2), (float) pair_dca_proj, (float) pathLength_proj(0), (float) pathLength_proj(1), (float) pathLength_proj(2), mag_pathLength_proj, track1->get_quality(), track2->get_quality(), cos_theta_reco, (float) track1_silicon_cluster_size, (float) track2_silicon_cluster_size, (float) track1_mvtx_cluster_size, (float) track1_mvtx_state_size, (float) track1_intt_cluster_size, (float) track1_intt_state_size, (float) track2_mvtx_cluster_size, (float) track2_mvtx_state_size, (float) track2_intt_cluster_size, (float) track2_intt_state_size, (float) runNumber, (float) eventNumber}; + + ntp_reco_info->Fill(reco_info); +} + + + +/* void KshortReconstruction::fillNtp(SvtxTrack* track1, SvtxTrack* track2, Acts::Vector3 dcavals1, Acts::Vector3 dcavals2, Acts::Vector3 pca_rel1, Acts::Vector3 pca_rel2, double pair_dca, double invariantMass, double invariantPt, float invariantPhi, float rapidity, float pseudorapidity, Eigen::Vector3d projected_pos1, Eigen::Vector3d projected_pos2, Eigen::Vector3d projected_mom1, Eigen::Vector3d projected_mom2, Acts::Vector3 pca_rel1_proj, Acts::Vector3 pca_rel2_proj, double pair_dca_proj, unsigned int track1_silicon_cluster_size, unsigned int track2_silicon_cluster_size, unsigned int track1_mvtx_cluster_size, unsigned int track1_mvtx_state_size, unsigned int track1_intt_cluster_size, unsigned int track1_intt_state_size, unsigned int track2_mvtx_cluster_size, unsigned int track2_mvtx_state_size, unsigned int track2_intt_cluster_size, unsigned int track2_intt_state_size, int runNumber, int eventNumber) { double px1 = track1->get_px(); @@ -381,6 +455,40 @@ void KshortReconstruction::fillNtp(SvtxTrack* track1, SvtxTrack* track2, Acts::V ntp_reco_info->Fill(reco_info); } +*/ + +void KshortReconstruction::fillHistogram(Eigen::Vector3d mom1, Eigen::Vector3d mom2, TH1* massreco, double& invariantMass, double& invariantPt, float& invariantPhi, float& rapidity, float& pseudorapidity, float &decaymassa, float &decaymassb) +{ + double E1 = sqrt(pow(mom1(0), 2) + pow(mom1(1), 2) + pow(mom1(2), 2) + pow(decaymassa, 2)); + double E2 = sqrt(pow(mom2(0), 2) + pow(mom2(1), 2) + pow(mom2(2), 2) + pow(decaymassb, 2)); + + TLorentzVector v1(mom1(0), mom1(1), mom1(2), E1); + TLorentzVector v2(mom2(0), mom2(1), mom2(2), E2); + + TLorentzVector tsum; + tsum = v1 + v2; + + rapidity = tsum.Rapidity(); + pseudorapidity = tsum.Eta(); + invariantMass = tsum.M(); + invariantPt = tsum.Pt(); + invariantPhi = tsum.Phi(); + + if (Verbosity() > 1) + { + std::cout << "px1: " << mom1(0) << " py1: " << mom1(1) << " pz1: " << mom1(2) << " mass " << decaymassa << " E1: " << E1 << std::endl; + std::cout << "px2: " << mom2(0) << " py2: " << mom2(1) << " pz2: " << mom2(2) << " mass2 " << decaymassb << " E2: " << E2 << std::endl; + std::cout << "tsum: " << tsum(0) << " " << tsum(1) << " " << tsum(2) << " " << tsum(3) << std::endl; + std::cout << "invariant mass: " << invariantMass << " invariant Pt: " << invariantPt << " invariantPhi: " << invariantPhi << std::endl; + } + + if (invariantPt > invariant_pt_cut) + { + massreco->Fill(invariantMass); + } +} + +/* void KshortReconstruction::fillHistogram(Eigen::Vector3d mom1, Eigen::Vector3d mom2, TH1* massreco, double& invariantMass, double& invariantPt, float& invariantPhi, float& rapidity, float& pseudorapidity) { @@ -412,6 +520,7 @@ void KshortReconstruction::fillHistogram(Eigen::Vector3d mom1, Eigen::Vector3d m massreco->Fill(invariantMass); } } +*/ bool KshortReconstruction::projectTrackToPoint(SvtxTrack* track, Eigen::Vector3d PCA, Eigen::Vector3d& pos, Eigen::Vector3d& mom) { @@ -529,6 +638,66 @@ Acts::Vector3 KshortReconstruction::getVertex(SvtxTrack* track) return vertex; } +void KshortReconstruction::findPcaTwoTracks(const Acts::Vector3& pos1, const Acts::Vector3& pos2, Acts::Vector3 mom1, Acts::Vector3 mom2, Acts::Vector3& pca1, Acts::Vector3& pca2, double& dca) const +{ + TLorentzVector v1; + TLorentzVector v2; + + double px1 = mom1(0); + double py1 = mom1(1); + double pz1 = mom1(2); + double px2 = mom2(0); + double py2 = mom2(1); + double pz2 = mom2(2); + + // calculate lorentz vector + const Eigen::Vector3d& a1 = pos1; + const Eigen::Vector3d& a2 = pos2; + + Eigen::Vector3d b1(px1, py1, pz1); + Eigen::Vector3d b2(px2, py2, pz2); + + // The shortest distance between two skew lines described by + // a1 + c * b1 + // a2 + d * b2 + // where a1, a2, are vectors representing points on the lines, b1, b2 are direction vectors, and c and d are scalars + // dca = (b1 x b2) .(a2-a1) / |b1 x b2| + + // bcrossb/mag_bcrossb is a unit vector perpendicular to both direction vectors b1 and b2 + auto bcrossb = b1.cross(b2); + auto mag_bcrossb = bcrossb.norm(); + // a2-a1 is the vector joining any arbitrary points on the two lines + auto aminusa = a2 - a1; + + // The DCA of these two lines is the projection of a2-a1 along the direction of the perpendicular to both + // remember that a2-a1 is longer than (or equal to) the dca by definition + dca = 999; + if (mag_bcrossb != 0) + { + dca = bcrossb.dot(aminusa) / mag_bcrossb; + } + else + { + return; // same track, skip combination + } + + // get the points at which the normal to the lines intersect the lines, where the lines are perpendicular + double X = b1.dot(b2) - (b1.dot(b1) * b2.dot(b2) / b2.dot(b1)); + double Y = (a2.dot(b2) - a1.dot(b2)) - ((a2.dot(b1) - a1.dot(b1)) * b2.dot(b2) / b2.dot(b1)); + double c = Y / X; + + double F = b1.dot(b1) / b2.dot(b1); + double G = -(a2.dot(b1) - a1.dot(b1)) / b2.dot(b1); + double d = (c * F) + G; + + // then the points of closest approach are: + pca1 = a1 + c * b1; + pca2 = a2 + d * b2; + + return; +} + +/* void KshortReconstruction::findPcaTwoTracks(const Acts::Vector3& pos1, const Acts::Vector3& pos2, Acts::Vector3 mom1, Acts::Vector3 mom2, Acts::Vector3& pca1, Acts::Vector3& pca2, double& dca) const { TLorentzVector v1; @@ -593,6 +762,7 @@ void KshortReconstruction::findPcaTwoTracks(const Acts::Vector3& pos1, const Act return; } +*/ KshortReconstruction::KshortReconstruction(const std::string& name) : SubsysReco(name) @@ -653,8 +823,15 @@ int KshortReconstruction::InitRun(PHCompositeNode* topNode) { const char* cfilepath = filepath.c_str(); fout = new TFile(cfilepath, "recreate"); - ntp_reco_info = new TNtuple("ntp_reco_info", "decay_pairs", "id1:crossing1:x1:y1:z1:px1:py1:pz1:dca3dxy1:dca3dz1:phi1:pca_rel1_x:pca_rel1_y:pca_rel1_z:eta1:charge1:tpcClusters_1:id2:crossing2:x2:y2:z2:px2:py2:pz2:dca3dxy2:dca3dz2:phi2:pca_rel2_x:pca_rel2_y:pca_rel2_z:eta2:charge2:tpcClusters_2:vertex_x:vertex_y:vertex_z:pair_dca:invariant_mass:invariant_pt:invariantPhi:pathlength_x:pathlength_y:pathlength_z:pathlength:rapidity:pseudorapidity:projected_pos1_x:projected_pos1_y:projected_pos1_z:projected_pos2_x:projected_pos2_y:projected_pos2_z:projected_mom1_x:projected_mom1_y:projected_mom1_z:projected_mom2_x:projected_mom2_y:projected_mom2_z:projected_pca_rel1_x:projected_pca_rel1_y:projected_pca_rel1_z:projected_pca_rel2_x:projected_pca_rel2_y:projected_pca_rel2_z:projected_pair_dca:projected_pathlength_x:projected_pathlength_y:projected_pathlength_z:projected_pathlength:quality1:quality2:cosThetaReco:track1_silicon_clusters:track2_silicon_clusters:track1_mvtx_clusters:track1_mvtx_states:track1_intt_clusters:track1_intt_states:track2_mvtx_clusters:track2_mvtx_states:track2_intt_clusters:track2_intt_states:runNumber:eventNumber"); +ntp_reco_info = new TNtuple("ntp_reco_info", "decay_pairs", "id1:mass1:crossing1:x1:y1:z1:px1:py1:pz1:dca3dxy1:dca3dz1:phi1:pca_rel1_x:pca_rel1_y:pca_rel1_z:eta1:charge1:tpcClusters_1:id2:mass2:crossing2:x2:y2:z2:px2:py2:pz2:dca3dxy2:dca3dz2:phi2:pca_rel2_x:pca_rel2_y:pca_rel2_z:eta2:charge2:tpcClusters_2:ntracks_vertex:vertex_x:vertex_y:vertex_z:pair_dca:invariant_mass:invariant_pt:invariantPhi:pathlength_x:pathlength_y:pathlength_z:pathlength:rapidity:pseudorapidity:projected_pos1_x:projected_pos1_y:projected_pos1_z:projected_pos2_x:projected_pos2_y:projected_pos2_z:projected_mom1_x:projected_mom1_y:projected_mom1_z:projected_mom2_x:projected_mom2_y:projected_mom2_z:projected_pca_rel1_x:projected_pca_rel1_y:projected_pca_rel1_z:projected_pca_rel2_x:projected_pca_rel2_y:projected_pca_rel2_z:projected_pair_dca:projected_pathlength_x:projected_pathlength_y:projected_pathlength_z:projected_pathlength:quality1:quality2:cosThetaReco:track1_silicon_clusters:track2_silicon_clusters:track1_mvtx_clusters:track1_mvtx_states:track1_intt_clusters:track1_intt_states:track2_mvtx_clusters:track2_mvtx_states:track2_intt_clusters:track2_intt_states:runNumber:eventNumber"); + + + +/* + ntp_reco_info = new TNtuple("ntp_reco_info", "decay_pairs", "id1:crossing1:x1:y1:z1:px1:py1:pz1:dca3dxy1:dca3dz1:phi1:pca_rel1_x:pca_rel1_y:pca_rel1_z:eta1:charge1:tpcClusters_1:id2:crossing2:x2:y2:z2:px2:py2:pz2:dca3dxy2:dca3dz2:phi2:pca_rel2_x:pca_rel2_y:pca_rel2_z:eta2:charge2:tpcClusters_2:vertex_x:vertex_y:vertex_z:pair_dca:invariant_mass:invariant_pt:invariantPhi:pathlength_x:pathlength_y:pathlength_z:pathlength:rapidity:pseudorapidity:projected_pos1_x:projected_pos1_y:projected_pos1_z:projected_pos2_x:projected_pos2_y:projected_pos2_z:projected_mom1_x:projected_mom1_y:projected_mom1_z:projected_mom2_x:projected_mom2_y:projected_mom2_z:projected_pca_rel1_x:projected_pca_rel1_y:projected_pca_rel1_z:projected_pca_rel2_x:projected_pca_rel2_y:projected_pca_rel2_z:projected_pair_dca:projected_pathlength_x:projected_pathlength_y:projected_pathlength_z:projected_pathlength:quality1:quality2:cosThetaReco:track1_silicon_clusters:track2_silicon_clusters:track1_mvtx_clusters:track1_mvtx_states:track1_intt_clusters:track1_intt_states:track2_mvtx_clusters:track2_mvtx_states:track2_intt_clusters:track2_intt_states:runNumber:eventNumber"); +*/ + getNodes(topNode); recomass = new TH1D("recomass", "recomass", 1000, 0.0, 1); // root histogram arguments: name,title,bins,minvalx,maxvalx diff --git a/offline/packages/TrackingDiagnostics/KshortReconstruction.h b/offline/packages/TrackingDiagnostics/KshortReconstruction.h index 3ff1ae3501..2057ed18e2 100644 --- a/offline/packages/TrackingDiagnostics/KshortReconstruction.h +++ b/offline/packages/TrackingDiagnostics/KshortReconstruction.h @@ -33,14 +33,20 @@ class KshortReconstruction : public SubsysReco void setPairDCACut(double cut) { pair_dca_cut = cut; } void setTrackDCACut(double cut) { track_dca_cut = cut; } void setRequireMVTX(bool set) { _require_mvtx = set; } - void setDecayMass(float decayMassSet) { decaymass = decayMassSet; } //(muons decaymass = 0.1057) (pions = 0.13957) (electron = 0.000511) + void setDecayMass1(float decayMassSet) { decaymass1 = decayMassSet; } //(muons decaymass = 0.1057) (pions = 0.13957) (electron = 0.000511) + void setDecayMass2(float decayMassSet) { decaymass2 = decayMassSet; } //(muons decaymass = 0.1057) (pions = 0.13957) (electron = 0.000511) + // void setDecayMass(float decayMassSet) { decaymass = decayMassSet; } //(muons decaymass = 0.1057) (pions = 0.13957) (electron = 0.000511) void set_output_file(const std::string& outputfile) { filepath = outputfile; } void save_tracks(bool save = true) { m_save_tracks = save; } private: - void fillNtp(SvtxTrack* track1, SvtxTrack* track2, Acts::Vector3 dcavals1, Acts::Vector3 dcavals2, Acts::Vector3 pca_rel1, Acts::Vector3 pca_rel2, double pair_dca, double invariantMass, double invariantPt, float invariantPhi, float rapidity, float pseudorapidity, Eigen::Vector3d projected_pos1, Eigen::Vector3d projected_pos2, Eigen::Vector3d projected_mom1, Eigen::Vector3d projected_mom2, Acts::Vector3 pca_rel1_proj, Acts::Vector3 pca_rel2_proj, double pair_dca_proj,unsigned int track1_silicon_cluster_size, unsigned int track2_silicon_cluster_size, unsigned int track1_mvtx_cluster_size, unsigned int track1_mvtx_state_size, unsigned int track1_intt_cluster_size, unsigned int track1_intt_state_size, unsigned int track2_mvtx_cluster_size, unsigned int track2_mvtx_state_size, unsigned int track2_intt_cluster_size, unsigned int track2_intt_state_size, int runNumber, int eventNumber); + void fillNtp(SvtxTrack* track1, SvtxTrack* track2, float mass1, float mass2, Acts::Vector3 dcavals1, Acts::Vector3 dcavals2, Acts::Vector3 pca_rel1, Acts::Vector3 pca_rel2, double pair_dca, double invariantMass, double invariantPt, float invariantPhi, float rapidity, float pseudorapidity, Eigen::Vector3d projected_pos1, Eigen::Vector3d projected_pos2, Eigen::Vector3d projected_mom1, Eigen::Vector3d projected_mom2, Acts::Vector3 pca_rel1_proj, Acts::Vector3 pca_rel2_proj, double pair_dca_proj,unsigned int track1_silicon_cluster_size, unsigned int track2_silicon_cluster_size, unsigned int track1_mvtx_cluster_size, unsigned int track1_mvtx_state_size, unsigned int track1_intt_cluster_size, unsigned int track1_intt_state_size, unsigned int track2_mvtx_cluster_size, unsigned int track2_mvtx_state_size, unsigned int track2_intt_cluster_size, unsigned int track2_intt_state_size, int runNumber, int eventNumber); - void fillHistogram(Eigen::Vector3d mom1, Eigen::Vector3d mom2, TH1* massreco, double& invariantMass, double& invariantPt, float& invariantPhi, float& rapidity, float& pseudorapidity); + // void fillNtp(SvtxTrack* track1, SvtxTrack* track2, Acts::Vector3 dcavals1, Acts::Vector3 dcavals2, Acts::Vector3 pca_rel1, Acts::Vector3 pca_rel2, double pair_dca, double invariantMass, double invariantPt, float invariantPhi, float rapidity, float pseudorapidity, Eigen::Vector3d projected_pos1, Eigen::Vector3d projected_pos2, Eigen::Vector3d projected_mom1, Eigen::Vector3d projected_mom2, Acts::Vector3 pca_rel1_proj, Acts::Vector3 pca_rel2_proj, double pair_dca_proj,unsigned int track1_silicon_cluster_size, unsigned int track2_silicon_cluster_size, unsigned int track1_mvtx_cluster_size, unsigned int track1_mvtx_state_size, unsigned int track1_intt_cluster_size, unsigned int track1_intt_state_size, unsigned int track2_mvtx_cluster_size, unsigned int track2_mvtx_state_size, unsigned int track2_intt_cluster_size, unsigned int track2_intt_state_size, int runNumber, int eventNumber); + + void fillHistogram(Eigen::Vector3d mom1, Eigen::Vector3d mom2, TH1* massreco, double& invariantMass, double& invariantPt, float& invariantPhi, float& rapidity, float& pseudorapidity, float& decaymass1, float& decaymass2); + + // void fillHistogram(Eigen::Vector3d mom1, Eigen::Vector3d mom2, TH1* massreco, double& invariantMass, double& invariantPt, float& invariantPhi, float& rapidity, float& pseudorapidity); // void findPcaTwoTracks(SvtxTrack *track1, SvtxTrack *track2, Acts::Vector3& pca1, Acts::Vector3& pca2, double& dca); void findPcaTwoTracks(const Acts::Vector3& pos1, const Acts::Vector3& pos2, Acts::Vector3 mom1, Acts::Vector3 mom2, Acts::Vector3& pca1, Acts::Vector3& pca2, double& dca) const; @@ -61,7 +67,10 @@ class KshortReconstruction : public SubsysReco SvtxVertexMap* m_vertexMap {nullptr}; std::string filepath {""}; - float decaymass {0.13957}; // pion decay mass + float decaymass1 = 0.13957; // pion decay mass + float decaymass2 = 0.13957; // pion decay mass + + //float decaymass {0.13957}; // pion decay mass bool _require_mvtx {true}; double _qual_cut {1000.0}; double pair_dca_cut {0.05}; // kshort relative cut 500 microns From 0b274287ca69bcb31f580b11166f95237ce2aaa0 Mon Sep 17 00:00:00 2001 From: Hugo Pereira Da Costa Date: Tue, 10 Feb 2026 12:54:13 -0500 Subject: [PATCH 206/393] streamlined disabling distortion corrections in the TpcGlobalPosition wrapper using local variables to store the information is unnecessary. --- offline/packages/tpccalib/PHTpcResiduals.cc | 16 ------------ offline/packages/tpccalib/PHTpcResiduals.h | 29 ++++++++++++++------- 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/offline/packages/tpccalib/PHTpcResiduals.cc b/offline/packages/tpccalib/PHTpcResiduals.cc index 54bcb5b42e..4360bc7d1b 100644 --- a/offline/packages/tpccalib/PHTpcResiduals.cc +++ b/offline/packages/tpccalib/PHTpcResiduals.cc @@ -769,22 +769,6 @@ int PHTpcResiduals::getNodes(PHCompositeNode* topNode) // tpc global position wrapper m_globalPositionWrapper.loadNodes(topNode); - if (m_disable_module_edge_corr) - { - m_globalPositionWrapper.set_enable_module_edge_corr(false); - } - if (m_disable_static_corr) - { - m_globalPositionWrapper.set_enable_static_corr(false); - } - if (m_disable_average_corr) - { - m_globalPositionWrapper.set_enable_average_corr(false); - } - if (m_disable_fluctuation_corr) - { - m_globalPositionWrapper.set_enable_fluctuation_corr(false); - } return Fun4AllReturnCodes::EVENT_OK; } diff --git a/offline/packages/tpccalib/PHTpcResiduals.h b/offline/packages/tpccalib/PHTpcResiduals.h index 66da67239d..62609e9400 100644 --- a/offline/packages/tpccalib/PHTpcResiduals.h +++ b/offline/packages/tpccalib/PHTpcResiduals.h @@ -106,10 +106,25 @@ class PHTpcResiduals : public SubsysReco m_useMicromegas = value; } - void disableModuleEdgeCorr() { m_disable_module_edge_corr = true; } - void disableStaticCorr() { m_disable_static_corr = true; } - void disableAverageCorr() { m_disable_average_corr = true; } - void disableFluctuationCorr() { m_disable_fluctuation_corr = true; } + void disableModuleEdgeCorr() + { + m_globalPositionWrapper.set_enable_module_edge_corr(false); + } + + void disableStaticCorr() + { + m_globalPositionWrapper.set_enable_static_corr(false); + } + + void disableAverageCorr() + { + m_globalPositionWrapper.set_enable_average_corr(false); + } + + void disableFluctuationCorr() + { + m_globalPositionWrapper.set_enable_fluctuation_corr(false); + } /// modify track map name void setTrackMapName( const std::string& value ) @@ -178,12 +193,6 @@ class PHTpcResiduals : public SubsysReco /// require track crossing zero bool m_requireCrossing = false; - /// disable distortion correction - bool m_disable_module_edge_corr = false; - bool m_disable_static_corr = false; - bool m_disable_average_corr = false; - bool m_disable_fluctuation_corr = false; - /// output file std::string m_outputfile = "TpcSpaceChargeMatrices.root"; From 4020ff11ae31044510947679a59996418887be33 Mon Sep 17 00:00:00 2001 From: Luke Legnosky Date: Tue, 10 Feb 2026 16:17:50 -0500 Subject: [PATCH 207/393] Updating TPC modules to replace floats with doubles. --- offline/packages/tpc/LaserClusterizer.cc | 32 ++++----- offline/packages/tpc/LaserClusterizer.h | 6 +- offline/packages/tpc/LaserEventIdentifier.cc | 2 +- offline/packages/tpc/LaserEventIdentifier.h | 4 +- offline/packages/tpc/LaserEventInfo.h | 4 +- offline/packages/tpc/LaserEventInfov1.cc | 2 +- offline/packages/tpc/LaserEventInfov1.h | 6 +- offline/packages/tpc/LaserEventInfov2.cc | 2 +- offline/packages/tpc/Tpc3DClusterizer.cc | 26 ++++---- offline/packages/tpc/Tpc3DClusterizer.h | 14 ++-- .../tpc/TpcClusterZCrossingCorrection.cc | 16 ++--- .../tpc/TpcClusterZCrossingCorrection.h | 14 ++-- offline/packages/tpc/TpcClusterizer.cc | 48 +++++++------- offline/packages/tpc/TpcClusterizer.h | 12 ++-- .../tpc/TpcCombinedRawDataUnpacker.cc | 56 ++++++++-------- .../packages/tpc/TpcCombinedRawDataUnpacker.h | 8 +-- .../tpc/TpcCombinedRawDataUnpackerDebug.cc | 66 +++++++++---------- .../tpc/TpcCombinedRawDataUnpackerDebug.h | 10 +-- .../tpc/TpcDistortionCorrectionContainer.h | 2 +- .../tpc/TpcLoadDistortionCorrection.h | 4 +- offline/packages/tpc/TpcRawWriter.cc | 4 +- offline/packages/tpc/TpcSimpleClusterizer.cc | 4 +- 22 files changed, 171 insertions(+), 171 deletions(-) diff --git a/offline/packages/tpc/LaserClusterizer.cc b/offline/packages/tpc/LaserClusterizer.cc index 754ee8d248..535e744ef1 100644 --- a/offline/packages/tpc/LaserClusterizer.cc +++ b/offline/packages/tpc/LaserClusterizer.cc @@ -59,7 +59,7 @@ namespace bg = boost::geometry; namespace bgi = boost::geometry::index; -using point = bg::model::point; +using point = bg::model::point; using box = bg::model::box; using specHitKey = std::pair; using adcKey = std::pair; @@ -180,16 +180,16 @@ namespace while (!q.empty()) { - float ix = q.front().first.get<0>(); - float iy = q.front().first.get<1>(); - float iz = q.front().first.get<2>(); + double ix = q.front().first.get<0>(); + double iy = q.front().first.get<1>(); + double iz = q.front().first.get<2>(); q.pop(); for (auto neigh : neighborOffsets) { - float nx = ix + neigh.get<0>(); - float ny = iy + neigh.get<1>(); - float nz = iz + neigh.get<2>(); + double nx = ix + neigh.get<0>(); + double ny = iy + neigh.get<1>(); + double nz = iz + neigh.get<2>(); for (unsigned int v = 0; v < unvisited.size(); v++) { @@ -258,9 +258,9 @@ namespace int meanSide = 0; - std::vector usedLayer; - std::vector usedIPhi; - std::vector usedIT; + std::vector usedLayer; + std::vector usedIPhi; + std::vector usedIT; double meanLayer = 0.0; double meanIPhi = 0.0; @@ -268,7 +268,7 @@ namespace for (auto &clusHit : clusHits) { - float coords[3] = {clusHit.first.get<0>(), clusHit.first.get<1>(), clusHit.first.get<2>()}; + double coords[3] = {clusHit.first.get<0>(), clusHit.first.get<1>(), clusHit.first.get<2>()}; std::pair spechitkey = clusHit.second.second; unsigned int adc = clusHit.second.first; @@ -293,7 +293,7 @@ namespace double hitZ = my_data.tdriftmax * my_data.tGeometry->get_drift_velocity() - hitzdriftlength; bool foundLayer = false; - for (float i : usedLayer) + for (double i : usedLayer) { if (coords[0] == i) { @@ -308,7 +308,7 @@ namespace } bool foundIPhi = false; - for (float i : usedIPhi) + for (double i : usedIPhi) { if (coords[1] == i) { @@ -323,7 +323,7 @@ namespace } bool foundIT = false; - for (float i : usedIT) + for (double i : usedIT) { if (coords[2] == i) { @@ -344,7 +344,7 @@ namespace clus->setHitX(clus->getNhits() - 1, r * cos(phi)); clus->setHitY(clus->getNhits() - 1, r * sin(phi)); clus->setHitZ(clus->getNhits() - 1, hitZ); - clus->setHitAdc(clus->getNhits() - 1, (float) adc); + clus->setHitAdc(clus->getNhits() - 1, (double) adc); rSum += r * adc; phiSum += phi * adc; @@ -669,7 +669,7 @@ namespace for (TrkrHitSet::ConstIterator hitr = hitrangei.first; hitr != hitrangei.second; ++hitr) { - float_t fadc = hitr->second->getAdc(); + double_t fadc = hitr->second->getAdc(); unsigned short adc = 0; if (fadc > my_data->adc_threshold) { diff --git a/offline/packages/tpc/LaserClusterizer.h b/offline/packages/tpc/LaserClusterizer.h index 8dc501a64f..28e4aaac73 100644 --- a/offline/packages/tpc/LaserClusterizer.h +++ b/offline/packages/tpc/LaserClusterizer.h @@ -40,9 +40,9 @@ class LaserClusterizer : public SubsysReco //void calc_cluster_parameter(std::vector &clusHits, std::multimap, std::array>> &adcMap, bool isLamination); //void remove_hits(std::vector &clusHits, boost::geometry::index::rtree> &rtree, std::multimap, std::array>> &adcMap); - void set_adc_threshold(float val) { m_adc_threshold = val; } - void set_min_clus_size(float val) { min_clus_size = val; } - void set_min_adc_sum(float val) { min_adc_sum = val; } + void set_adc_threshold(double val) { m_adc_threshold = val; } + void set_min_clus_size(double val) { min_clus_size = val; } + void set_min_adc_sum(double val) { min_adc_sum = val; } void set_max_time_samples(int val) { m_time_samples_max = val; } void set_lamination(bool val) { m_lamination = val; } void set_do_sequential(bool val) { m_do_sequential = val; } diff --git a/offline/packages/tpc/LaserEventIdentifier.cc b/offline/packages/tpc/LaserEventIdentifier.cc index 5968d2f09f..3c214161ae 100644 --- a/offline/packages/tpc/LaserEventIdentifier.cc +++ b/offline/packages/tpc/LaserEventIdentifier.cc @@ -89,7 +89,7 @@ int LaserEventIdentifier::InitRun(PHCompositeNode *topNode) { m_debugFile = new TFile(m_debugFileName.c_str(), "RECREATE"); } - float timeHistMax = m_time_samples_max; + double timeHistMax = m_time_samples_max; timeHistMax -= 0.5; m_itHist_0 = new TH1I("m_itHist_0", "side 0;it", m_time_samples_max, -0.5, timeHistMax); m_itHist_1 = new TH1I("m_itHist_1", "side 1;it", m_time_samples_max, -0.5, timeHistMax); diff --git a/offline/packages/tpc/LaserEventIdentifier.h b/offline/packages/tpc/LaserEventIdentifier.h index 5c0c5faf54..fa4f43733f 100644 --- a/offline/packages/tpc/LaserEventIdentifier.h +++ b/offline/packages/tpc/LaserEventIdentifier.h @@ -53,8 +53,8 @@ class LaserEventIdentifier : public SubsysReco bool isGl1LaserPileupEvent = false; int peakSample0 = -999; int peakSample1 = -999; - float peakWidth0 = -999; - float peakWidth1 = -999; + double peakWidth0 = -999; + double peakWidth1 = -999; int m_runnumber = 0; uint64_t prev_BCO = 0; diff --git a/offline/packages/tpc/LaserEventInfo.h b/offline/packages/tpc/LaserEventInfo.h index 48e5379b70..5379862549 100644 --- a/offline/packages/tpc/LaserEventInfo.h +++ b/offline/packages/tpc/LaserEventInfo.h @@ -32,8 +32,8 @@ class LaserEventInfo : public PHObject virtual int getPeakSample(const bool /*side*/) const { return std::numeric_limits::max(); } virtual void setPeakSample(const bool /*side*/, const int /*sample*/) {} - virtual float getPeakWidth(const bool /*side*/) const { return std::numeric_limits::quiet_NaN(); } - virtual void setPeakWidth(const bool /*side*/, const float /*width*/) {} + virtual double getPeakWidth(const bool /*side*/) const { return std::numeric_limits::quiet_NaN(); } + virtual void setPeakWidth(const bool /*side*/, const double /*width*/) {} protected: LaserEventInfo() = default; diff --git a/offline/packages/tpc/LaserEventInfov1.cc b/offline/packages/tpc/LaserEventInfov1.cc index 448cbb7e2b..9e68e0baba 100644 --- a/offline/packages/tpc/LaserEventInfov1.cc +++ b/offline/packages/tpc/LaserEventInfov1.cc @@ -20,7 +20,7 @@ void LaserEventInfov1::Reset() for (int i = 0; i < 2; i++) { m_peakSample[i] = std::numeric_limits::max(); - m_peakWidth[i] = std::numeric_limits::quiet_NaN(); + m_peakWidth[i] = std::numeric_limits::quiet_NaN(); } return; diff --git a/offline/packages/tpc/LaserEventInfov1.h b/offline/packages/tpc/LaserEventInfov1.h index 7497fdd780..e032736b01 100644 --- a/offline/packages/tpc/LaserEventInfov1.h +++ b/offline/packages/tpc/LaserEventInfov1.h @@ -23,14 +23,14 @@ class LaserEventInfov1 : public LaserEventInfo int getPeakSample(const bool side) const override { return m_peakSample[side]; } void setPeakSample(const bool side, const int sample) override { m_peakSample[side] = sample; } - float getPeakWidth(const bool side) const override { return m_peakWidth[side]; } - void setPeakWidth(const bool side, const float width) override { m_peakWidth[side] = width; } + double getPeakWidth(const bool side) const override { return m_peakWidth[side]; } + void setPeakWidth(const bool side, const double width) override { m_peakWidth[side] = width; } protected: bool m_isLaserEvent{false}; int m_peakSample[2] = {std::numeric_limits::max(), std::numeric_limits::max()}; - float m_peakWidth[2] = {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}; + double m_peakWidth[2] = {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}; ClassDefOverride(LaserEventInfov1, 1); }; diff --git a/offline/packages/tpc/LaserEventInfov2.cc b/offline/packages/tpc/LaserEventInfov2.cc index c5f2ab60f4..ae40a14c62 100644 --- a/offline/packages/tpc/LaserEventInfov2.cc +++ b/offline/packages/tpc/LaserEventInfov2.cc @@ -24,7 +24,7 @@ void LaserEventInfov2::Reset() for (int i = 0; i < 2; i++) { m_peakSample[i] = std::numeric_limits::max(); - m_peakWidth[i] = std::numeric_limits::quiet_NaN(); + m_peakWidth[i] = std::numeric_limits::quiet_NaN(); } return; diff --git a/offline/packages/tpc/Tpc3DClusterizer.cc b/offline/packages/tpc/Tpc3DClusterizer.cc index 562231b71b..bdbfbb99e4 100644 --- a/offline/packages/tpc/Tpc3DClusterizer.cc +++ b/offline/packages/tpc/Tpc3DClusterizer.cc @@ -50,7 +50,7 @@ namespace bg = boost::geometry; namespace bgi = boost::geometry::index; -using point = bg::model::point; +using point = bg::model::point; using box = bg::model::box; using specHitKey = std::pair; using pointKeyLaser = std::pair; @@ -215,7 +215,7 @@ int Tpc3DClusterizer::process_event(PHCompositeNode *topNode) int iphi = TpcDefs::getPad(hitr->first); int it = TpcDefs::getTBin(hitr->first); // std::cout << " iphi: " << iphi << " it: " << it << std::endl; - float_t fadc = (hitr->second->getAdc()); // - m_pedestal; // proper int rounding +0.5 + double_t fadc = (hitr->second->getAdc()); // - m_pedestal; // proper int rounding +0.5 unsigned short adc = 0; if (fadc > 0) { @@ -270,7 +270,7 @@ int Tpc3DClusterizer::process_event(PHCompositeNode *topNode) int iphi = TpcDefs::getPad(hitr->first); int it = TpcDefs::getTBin(hitr->first); // std::cout << " iphi: " << iphi << " it: " << it << std::endl; - float_t fadc = (hitr->second->getAdc()); // - m_pedestal; // proper int rounding +0.5 + double_t fadc = (hitr->second->getAdc()); // - m_pedestal; // proper int rounding +0.5 unsigned short adc = 0; // std::cout << " nhit: " << nhits++ << "adc: " << fadc << " phi: " << iphi << " it: " << it << std::endl; if (fadc > 0) @@ -347,9 +347,9 @@ int Tpc3DClusterizer::process_event(PHCompositeNode *topNode) double m_sampa_tbias = 39.6; double zdriftlength = (layergeom->get_zcenter(it)+ m_sampa_tbias) * m_tGeometry->get_drift_velocity(); - float x = r * cos(phi); - float y = r * sin(phi); - float z = m_tdriftmax * m_tGeometry->get_drift_velocity() - zdriftlength; + double x = r * cos(phi); + double y = r * sin(phi); + double z = m_tdriftmax * m_tGeometry->get_drift_velocity() - zdriftlength; if (side == 0){ z = -z; it = -it; @@ -524,13 +524,13 @@ void Tpc3DClusterizer::calc_cluster_parameter(std::vector &clusHi int iphimax = -1; int ilaymin = 6666; int ilaymax = -1; - float itmin = 66666666.6; - float itmax = -6666666666.6; + double itmin = 66666666.6; + double itmax = -6666666666.6; auto *clus = new LaserClusterv1; for (auto &clusHit : clusHits) { - float coords[3] = {clusHit.first.get<0>(), clusHit.first.get<1>(), clusHit.first.get<2>()}; + double coords[3] = {clusHit.first.get<0>(), clusHit.first.get<1>(), clusHit.first.get<2>()}; std::pair spechitkey = clusHit.second; int side = TpcDefs::getSide(spechitkey.second); @@ -555,8 +555,8 @@ void Tpc3DClusterizer::calc_cluster_parameter(std::vector &clusHi iphimax = std::max(phi, iphimax); ilaymin = std::min(lay, ilaymin); ilaymax = std::max(lay, ilaymax); - itmin = std::min(tbin, itmin); - itmax = std::max(tbin, itmax); + itmin = std::min(tbin, itmin); + itmax = std::max(tbin, itmax); for (auto &iterKey : adcMap) { @@ -571,7 +571,7 @@ void Tpc3DClusterizer::calc_cluster_parameter(std::vector &clusHi clus->setHitX(clus->getNhits() - 1, r * cos(phi)); clus->setHitY(clus->getNhits() - 1, r * sin(phi)); clus->setHitZ(clus->getNhits() - 1, hitZ); - clus->setHitAdc(clus->getNhits() - 1, (float) adc); + clus->setHitAdc(clus->getNhits() - 1, (double) adc); rSum += r * adc; phiSum += phi * adc; @@ -657,7 +657,7 @@ void Tpc3DClusterizer::calc_cluster_parameter(std::vector &clusHi << std::endl; */ // if (m_output){ - float fX[20] = {0}; + double fX[20] = {0}; int n = 0; fX[n++] = m_event; fX[n++] = m_seed; diff --git a/offline/packages/tpc/Tpc3DClusterizer.h b/offline/packages/tpc/Tpc3DClusterizer.h index 54175a3c9a..3e6ad621a9 100644 --- a/offline/packages/tpc/Tpc3DClusterizer.h +++ b/offline/packages/tpc/Tpc3DClusterizer.h @@ -34,7 +34,7 @@ class PHG4TpcGeomContainer; class Tpc3DClusterizer : public SubsysReco { public: -typedef boost::geometry::model::point point; +typedef boost::geometry::model::point point; typedef boost::geometry::model::box box; typedef std::pair specHitKey; typedef std::pair pointKeyLaser; @@ -49,7 +49,7 @@ typedef std::pair pointKeyLaser; // void calc_cluster_parameter(std::vector &clusHits, std::multimap> &adcMap); void calc_cluster_parameter(std::vector &clusHits, std::multimap, std::array>> &adcMap); - // void remove_hits(std::vector &clusHits, boost::geometry::index::rtree > &rtree, std::multimap > &adcMap, std::multimap &adcCoords); + // void remove_hits(std::vector &clusHits, boost::geometry::index::rtree > &rtree, std::multimap > &adcMap, std::multimap &adcCoords); void remove_hits(std::vector &clusHits, boost::geometry::index::rtree> &rtree, std::multimap, std::array>> &adcMap); void set_debug(bool debug) { m_debug = debug; } @@ -57,9 +57,9 @@ typedef std::pair pointKeyLaser; void set_output(bool output) { m_output = output; } void set_output_name(const std::string &name) { m_outputFileName = name; } - void set_pedestal(float val) { pedestal = val; } - void set_min_clus_size(float val) { min_clus_size = val; } - void set_min_adc_sum(float val) { min_adc_sum = val; } + void set_pedestal(double val) { pedestal = val; } + void set_min_clus_size(double val) { min_clus_size = val; } + void set_min_adc_sum(double val) { min_adc_sum = val; } private: int m_event {-1}; @@ -106,8 +106,8 @@ typedef std::pair pointKeyLaser; LaserCluster *m_currentCluster {nullptr}; std::vector m_eventClusters; - std::vector m_currentHit; - std::vector m_currentHit_hardware; + std::vector m_currentHit; + std::vector m_currentHit_hardware; std::unique_ptr t_all; std::unique_ptr t_search; diff --git a/offline/packages/tpc/TpcClusterZCrossingCorrection.cc b/offline/packages/tpc/TpcClusterZCrossingCorrection.cc index 24c2552f55..dc4f8589fc 100644 --- a/offline/packages/tpc/TpcClusterZCrossingCorrection.cc +++ b/offline/packages/tpc/TpcClusterZCrossingCorrection.cc @@ -13,32 +13,32 @@ #include // default value, override from macro (cm/ns) -float TpcClusterZCrossingCorrection::_vdrift = 8.0e-03; +double TpcClusterZCrossingCorrection::_vdrift = 8.0e-03; // ns, same value as in pileup generator -float TpcClusterZCrossingCorrection::_time_between_crossings = sphenix_constants::time_between_crossings; +double TpcClusterZCrossingCorrection::_time_between_crossings = sphenix_constants::time_between_crossings; //______________________________________________________________________________________________ -float TpcClusterZCrossingCorrection::correctZ(float zinit, unsigned int side, short int crossing) +double TpcClusterZCrossingCorrection::correctZ(double zinit, unsigned int side, short int crossing) { if (crossing == std::numeric_limits::max()) { - return std::numeric_limits::quiet_NaN(); + return std::numeric_limits::quiet_NaN(); } - float z_bunch_separation = _time_between_crossings * _vdrift; + double z_bunch_separation = _time_between_crossings * _vdrift; // +ve crossing occurs in the future relative to time zero // -ve z side (south, side 0), cluster arrives late, so z seems more positive // +ve z side (north, side 1), cluster arrives late, so z seems more negative - float corrected_z; + double corrected_z; if (side == 0) { - corrected_z = zinit - (float) crossing * z_bunch_separation; + corrected_z = zinit - (double) crossing * z_bunch_separation; } else { - corrected_z = zinit + (float) crossing * z_bunch_separation; + corrected_z = zinit + (double) crossing * z_bunch_separation; } // std::cout << " TpcClusterZCrossingCorrection: crossing " << crossing << " _vdrift " << _vdrift << " zinit " << zinit << " side " << side << " z_bunch_separation " << z_bunch_separation << " corrected_z " << corrected_z << std::endl; diff --git a/offline/packages/tpc/TpcClusterZCrossingCorrection.h b/offline/packages/tpc/TpcClusterZCrossingCorrection.h index 5a95ca7f86..8321d31f7d 100644 --- a/offline/packages/tpc/TpcClusterZCrossingCorrection.h +++ b/offline/packages/tpc/TpcClusterZCrossingCorrection.h @@ -15,34 +15,34 @@ class TpcClusterZCrossingCorrection //@{ //! drift velocity (cm/ns) - static float get_vdrift() { return _vdrift; } + static double get_vdrift() { return _vdrift; } //! time between crossing (ns) - static float get_time_between_crossings() { return _time_between_crossings; } + static double get_time_between_crossings() { return _time_between_crossings; } //! apply correction on a given z - static float correctZ(float zinit, unsigned int side, short int crossing); + static double correctZ(double zinit, unsigned int side, short int crossing); //@} //!@name modifiers //@{ //! drift velocity (cm/ns) - static void set_vdrift( float value ) { _vdrift = value; } + static void set_vdrift( double value ) { _vdrift = value; } //! time between crossing (ns) - static void set_time_between_crossings( float value ) { _time_between_crossings = value; } + static void set_time_between_crossings( double value ) { _time_between_crossings = value; } //@} // TODO: move to private //!@name parameters //@{ //! drift velocity (cm/ns) - static float _vdrift; + static double _vdrift; private: //! time between crossing (ns) - static float _time_between_crossings; + static double _time_between_crossings; //@} diff --git a/offline/packages/tpc/TpcClusterizer.cc b/offline/packages/tpc/TpcClusterizer.cc index 24405c8df4..f402f3e60f 100644 --- a/offline/packages/tpc/TpcClusterizer.cc +++ b/offline/packages/tpc/TpcClusterizer.cc @@ -101,16 +101,16 @@ namespace unsigned int layer = 0; int side = 0; unsigned int sector = 0; - float radius = 0; - float drift_velocity = 0; + double radius = 0; + double drift_velocity = 0; unsigned short pads_per_sector = 0; - float phistep = 0; - float pedestal = 0; - float seed_threshold = 0; - float edge_threshold = 0; - float min_err_squared = 0; - float min_clus_size = 0; - float min_adc_sum = 0; + double phistep = 0; + double pedestal = 0; + double seed_threshold = 0; + double edge_threshold = 0; + double min_err_squared = 0; + double min_clus_size = 0; + double min_adc_sum = 0; bool do_assoc = true; bool do_wedge_emulation = true; bool do_singles = true; @@ -661,8 +661,8 @@ namespace double clusiphi = iphi_sum / adc_sum; double clusphi = my_data.layergeom->get_phi(clusiphi, my_data.side); - float clusx = radius * cos(clusphi); - float clusy = radius * sin(clusphi); + double clusx = radius * cos(clusphi); + double clusy = radius * sin(clusphi); double clust = t_sum / adc_sum; // needed for surface identification double zdriftlength = clust * my_data.tGeometry->get_drift_velocity(); @@ -750,22 +750,22 @@ namespace { // Create a vector of inputs std::vector inputs; - inputs.emplace_back(torch::stack({torch::from_blob(std::vector(training_hits->v_adc.begin(), training_hits->v_adc.end()).data(), {1, 2 * nd + 1, 2 * nd + 1}, torch::kFloat32), + inputs.emplace_back(torch::stack({torch::from_blob(std::vector(training_hits->v_adc.begin(), training_hits->v_adc.end()).data(), {1, 2 * nd + 1, 2 * nd + 1}, torch::kFloat32), torch::full({1, 2 * nd + 1, 2 * nd + 1}, std::clamp((training_hits->layer - 7) / 16, 0, 2), torch::kFloat32), torch::full({1, 2 * nd + 1, 2 * nd + 1}, training_hits->z / radius, torch::kFloat32)}, 1)); // Execute the model and turn its output into a tensor at::Tensor ten_pos = module_pos.forward(inputs).toTensor(); - float nn_phi = training_hits->phi + std::clamp(ten_pos[0][0][0].item(), -(float) nd, (float) nd) * training_hits->phistep; - float nn_z = training_hits->z + std::clamp(ten_pos[0][1][0].item(), -(float) nd, (float) nd) * training_hits->zstep; - float nn_x = radius * std::cos(nn_phi); - float nn_y = radius * std::sin(nn_phi); + double nn_phi = training_hits->phi + std::clamp(ten_pos[0][0][0].item(), -(double) nd, (double) nd) * training_hits->phistep; + double nn_z = training_hits->z + std::clamp(ten_pos[0][1][0].item(), -(double) nd, (double) nd) * training_hits->zstep; + double nn_x = radius * std::cos(nn_phi); + double nn_y = radius * std::sin(nn_phi); Acts::Vector3 nn_global(nn_x, nn_y, nn_z); nn_global *= Acts::UnitConstants::cm; Acts::Vector3 nn_local = surface->transform(my_data.tGeometry->geometry().geoContext).inverse() * nn_global; nn_local /= Acts::UnitConstants::cm; - float nn_t = my_data.m_tdriftmax - std::fabs(nn_z) / my_data.tGeometry->get_drift_velocity(); + double nn_t = my_data.m_tdriftmax - std::fabs(nn_z) / my_data.tGeometry->get_drift_velocity(); clus_base->setLocalX(nn_local(0)); clus_base->setLocalY(nn_t); } @@ -921,7 +921,7 @@ namespace { continue; } - float_t fadc = (hitr->second->getAdc()) - pedestal; // proper int rounding +0.5 + double_t fadc = (hitr->second->getAdc()) - pedestal; // proper int rounding +0.5 unsigned short adc = 0; if (fadc > 0) { @@ -1657,13 +1657,13 @@ int TpcClusterizer::process_event(PHCompositeNode *topNode) /* PHG4TpcGeom *testlayergeom = geom_container->GetLayerCellGeom(32); - for( float iphi = 1408; iphi < 1408+ 128;iphi+=0.1){ + for( double iphi = 1408; iphi < 1408+ 128;iphi+=0.1){ double clusiphi = iphi; double clusphi = testlayergeom->get_phi(clusiphi); double radius = layergeom->get_radius(); - float clusx = radius * cos(clusphi); - float clusy = radius * sin(clusphi); - float clusz = -37.524; + double clusx = radius * cos(clusphi); + double clusy = radius * sin(clusphi); + double clusz = -37.524; TrkrDefs::hitsetkey tpcHitSetKey = TpcDefs::genHitSetKey( 32,11, 0 ); Acts::Vector3 global(clusx, clusy, clusz); @@ -1762,11 +1762,11 @@ int TpcClusterizer::process_event(PHCompositeNode *topNode) { for (const auto &hit : data.phivec_ClusHitsVerbose[index]) { - mClusHitsVerbose->addPhiHit(hit.first, (float) hit.second); + mClusHitsVerbose->addPhiHit(hit.first, (double) hit.second); } for (const auto &hit : data.zvec_ClusHitsVerbose[index]) { - mClusHitsVerbose->addZHit(hit.first, (float) hit.second); + mClusHitsVerbose->addZHit(hit.first, (double) hit.second); } mClusHitsVerbose->push_hits(ckey); } diff --git a/offline/packages/tpc/TpcClusterizer.h b/offline/packages/tpc/TpcClusterizer.h index 84a58ceca6..801207654e 100644 --- a/offline/packages/tpc/TpcClusterizer.h +++ b/offline/packages/tpc/TpcClusterizer.h @@ -44,12 +44,12 @@ class TpcClusterizer : public SubsysReco void set_do_sequential(bool do_seq) { do_sequential = do_seq; } void set_do_split(bool split) { do_split = split; } void set_fixed_window(int fixed) { do_fixed_window = fixed; } - void set_pedestal(float val) { pedestal = val; } - void set_seed_threshold(float val) { seed_threshold = val; } - void set_edge_threshold(float val) { edge_threshold = val; } - void set_min_err_squared(float val) { min_err_squared = val; } - void set_min_clus_size(float val) { min_clus_size = val; } - void set_min_adc_sum(float val) { min_adc_sum = val; } + void set_pedestal(double val) { pedestal = val; } + void set_seed_threshold(double val) { seed_threshold = val; } + void set_edge_threshold(double val) { edge_threshold = val; } + void set_min_err_squared(double val) { min_err_squared = val; } + void set_min_clus_size(double val) { min_clus_size = val; } + void set_min_adc_sum(double val) { min_adc_sum = val; } void set_remove_singles(bool do_sing) { do_singles = do_sing; } void set_read_raw(bool read_raw) { do_read_raw = read_raw; } void set_max_cluster_half_size_phi(unsigned short size) { MaxClusterHalfSizePhi = size; } diff --git a/offline/packages/tpc/TpcCombinedRawDataUnpacker.cc b/offline/packages/tpc/TpcCombinedRawDataUnpacker.cc index 5f276c3c3a..5abec18a2c 100644 --- a/offline/packages/tpc/TpcCombinedRawDataUnpacker.cc +++ b/offline/packages/tpc/TpcCombinedRawDataUnpacker.cc @@ -324,8 +324,8 @@ int TpcCombinedRawDataUnpacker::process_event(PHCompositeNode* topNode) hit_set_key = TpcDefs::genHitSetKey(layer, (mc_sectors[sector % 12]), side); hit_set_container_itr = trkr_hit_set_container->findOrAddHitSet(hit_set_key); - float hpedestal = 0; - float hpedwidth = 0; + double hpedestal = 0; + double hpedwidth = 0; if (Verbosity() > 2) { @@ -372,7 +372,7 @@ int TpcCombinedRawDataUnpacker::process_event(PHCompositeNode* topNode) auto fee_entries_it = feeentries_map.find(fee_key); std::vector& fee_entries_vec = (*fee_entries_it).second; - float threshold_cut = m_zs_threshold[region]; + double threshold_cut = m_zs_threshold[region]; int nhitschan = 0; @@ -391,7 +391,7 @@ int TpcCombinedRawDataUnpacker::process_event(PHCompositeNode* topNode) { if (adc > 0) { - if ((float(adc) - hpedestal) > threshold_cut) + if ((double(adc) - hpedestal) > threshold_cut) { nhitschan++; } @@ -424,7 +424,7 @@ int TpcCombinedRawDataUnpacker::process_event(PHCompositeNode* topNode) { if (adc > 0) { - if ((float(adc) - hpedestal) > threshold_cut) + if ((double(adc) - hpedestal) > threshold_cut) { feehist->Fill(t, adc - hpedestal); if (t < (int) fee_entries_vec.size()) @@ -435,7 +435,7 @@ int TpcCombinedRawDataUnpacker::process_event(PHCompositeNode* topNode) } } - if ((float(adc) - hpedestal) > threshold_cut) + if ((double(adc) - hpedestal) > threshold_cut) { hit_key = TpcDefs::genHitKey(phibin, (unsigned int) t); // find existing hit, or create new one @@ -443,13 +443,13 @@ int TpcCombinedRawDataUnpacker::process_event(PHCompositeNode* topNode) if (!hit) { hit = new TrkrHitv2(); - hit->setAdc(float(adc) - hpedestal); + hit->setAdc(double(adc) - hpedestal); hit_set_container_itr->second->addHitSpecificKey(hit_key, hit); } if (m_writeTree) { - float fXh[18]; + double fXh[18]; int nh = 0; fXh[nh++] = _ievent - 1; @@ -462,10 +462,10 @@ int TpcCombinedRawDataUnpacker::process_event(PHCompositeNode* topNode) fXh[nh++] = channel; // channel; fXh[nh++] = sampadd; // sampadd; fXh[nh++] = sampch; // sampch; - fXh[nh++] = (float) phibin; - fXh[nh++] = (float) t; + fXh[nh++] = (double) phibin; + fXh[nh++] = (double) t; fXh[nh++] = layer; - fXh[nh++] = (float(adc) - hpedestal); + fXh[nh++] = (double(adc) - hpedestal); fXh[nh++] = hpedestal; fXh[nh++] = hpedwidth; m_ntup_hits->Fill(fXh); @@ -499,18 +499,18 @@ int TpcCombinedRawDataUnpacker::process_event(PHCompositeNode* topNode) } std::vector::iterator fee_entries_vec_it = (*fee_entries_it).second.begin(); - std::vector pedvec(hist2d->GetNbinsX(), 0); + std::vector pedvec(hist2d->GetNbinsX(), 0); feebaseline_map.insert(std::make_pair(hiter.first, pedvec)); - std::map>::iterator fee_blm_it = feebaseline_map.find(hiter.first); + std::map>::iterator fee_blm_it = feebaseline_map.find(hiter.first); (*fee_blm_it).second.resize(hist2d->GetNbinsX(), 0); for (int binx = 1; binx < hist2d->GetNbinsX(); binx++) { double timebin = (hist2d->GetXaxis())->GetBinCenter(binx); std::string histname1d = "h" + std::to_string(hiter.first) + "_" + std::to_string((int) timebin); nhisttotal++; - float local_ped = 0; - float local_width = 0; - float entries = fee_entries_vec_it[timebin]; + double local_ped = 0; + double local_width = 0; + double entries = fee_entries_vec_it[timebin]; if (fee_entries_vec_it[timebin] > 100) { nhistfilled++; @@ -532,8 +532,8 @@ int TpcCombinedRawDataUnpacker::process_event(PHCompositeNode* topNode) for (int isum = -3; isum <= 3; isum++) { - float val = hist1d->GetBinContent(maxbin + isum); - float center = hist1d->GetBinCenter(maxbin + isum); + double val = hist1d->GetBinContent(maxbin + isum); + double center = hist1d->GetBinCenter(maxbin + isum); hibin_sum += center * val; hibin2_sum += center * center * val; hadc_sum += val; @@ -547,7 +547,7 @@ int TpcCombinedRawDataUnpacker::process_event(PHCompositeNode* topNode) if (m_writeTree) { - float fXh[11]; + double fXh[11]; int nh = 0; fXh[nh++] = _ievent - 1; @@ -601,7 +601,7 @@ int TpcCombinedRawDataUnpacker::process_event(PHCompositeNode* topNode) unsigned int pad_key = create_pad_key(side, layer, phibin); - float fee = 0; + double fee = 0; std::map::iterator chan_it = chan_map.find(pad_key); if (chan_it != chan_map.end()) { @@ -612,10 +612,10 @@ int TpcCombinedRawDataUnpacker::process_event(PHCompositeNode* topNode) } int rx = get_rx(layer); - float corr = 0; + double corr = 0; unsigned int fee_key = create_fee_key(side, sector, rx, fee); - std::map>::iterator fee_blm_it = feebaseline_map.find(fee_key); + std::map>::iterator fee_blm_it = feebaseline_map.find(fee_key); if (fee_blm_it != feebaseline_map.end()) { if (tbin < (int) (*fee_blm_it).second.size()) @@ -623,13 +623,13 @@ int TpcCombinedRawDataUnpacker::process_event(PHCompositeNode* topNode) corr = (*fee_blm_it).second[tbin]; } hitr->second->setAdc(0); - float nuadc = (float(adc) - corr); - nuadc = std::max(nuadc, 0); + double nuadc = (double(adc) - corr); + nuadc = std::max(nuadc, 0); hitr->second->setAdc(nuadc); if (m_writeTree) { - float fXh[18]; + double fXh[18]; int nh = 0; fXh[nh++] = _ievent - 1; @@ -642,10 +642,10 @@ int TpcCombinedRawDataUnpacker::process_event(PHCompositeNode* topNode) fXh[nh++] = 0; // channel; fXh[nh++] = 0; // sampadd; fXh[nh++] = 0; // sampch; - fXh[nh++] = (float) phibin; - fXh[nh++] = (float) tbin; + fXh[nh++] = (double) phibin; + fXh[nh++] = (double) tbin; fXh[nh++] = layer; - fXh[nh++] = float(adc); + fXh[nh++] = double(adc); fXh[nh++] = 0; // hpedestal2; fXh[nh++] = 0; // hpedwidth2; fXh[nh++] = corr; diff --git a/offline/packages/tpc/TpcCombinedRawDataUnpacker.h b/offline/packages/tpc/TpcCombinedRawDataUnpacker.h index 8c8bfd353b..0dcb0e555e 100644 --- a/offline/packages/tpc/TpcCombinedRawDataUnpacker.h +++ b/offline/packages/tpc/TpcCombinedRawDataUnpacker.h @@ -88,8 +88,8 @@ class TpcCombinedRawDataUnpacker : public SubsysReco struct chan_info { unsigned int fee = std::numeric_limits::max(); - float ped = -1; - float width = -1; + double ped = -1; + double width = -1; int entries = 0; }; TNtuple *m_ntup{nullptr}; @@ -113,7 +113,7 @@ class TpcCombinedRawDataUnpacker : public SubsysReco bool m_doChanHitsCut{false}; int m_ChanHitsCut{9999}; - float m_ped_sig_cut{4.0}; + double m_ped_sig_cut{4.0}; bool m_writeTree{false}; bool m_do_baseline_corr{false}; @@ -125,7 +125,7 @@ class TpcCombinedRawDataUnpacker : public SubsysReco std::map chan_map; // stays in place std::map feeadc_map; // histos reset after each event std::map> feeentries_map; // cleared after each event - std::map> feebaseline_map; // cleared after each event + std::map> feebaseline_map; // cleared after each event }; #endif // TPC_COMBINEDRAWDATAUNPACKER_H diff --git a/offline/packages/tpc/TpcCombinedRawDataUnpackerDebug.cc b/offline/packages/tpc/TpcCombinedRawDataUnpackerDebug.cc index 803a822aa9..c7dfe58261 100644 --- a/offline/packages/tpc/TpcCombinedRawDataUnpackerDebug.cc +++ b/offline/packages/tpc/TpcCombinedRawDataUnpackerDebug.cc @@ -278,7 +278,7 @@ int TpcCombinedRawDataUnpackerDebug::process_event(PHCompositeNode* topNode) unsigned int phibin = layergeom->get_phibin(phi, side); if (m_writeTree) { - float fX[12]; + double fX[12]; int n = 0; fX[n++] = _ievent - 1; @@ -298,8 +298,8 @@ int TpcCombinedRawDataUnpackerDebug::process_event(PHCompositeNode* topNode) hit_set_key = TpcDefs::genHitSetKey(layer, (mc_sectors[sector % 12]), side); hit_set_container_itr = trkr_hit_set_container->findOrAddHitSet(hit_set_key); - float hpedestal = 0; - float hpedwidth = 0; + double hpedestal = 0; + double hpedwidth = 0; pedhist.Reset(); if (!m_do_zerosup) @@ -323,7 +323,7 @@ int TpcCombinedRawDataUnpackerDebug::process_event(PHCompositeNode* topNode) if (!hit) { hit = new TrkrHitv2(); - hit->setAdc(float(adc)); + hit->setAdc(double(adc)); hit_set_container_itr->second->addHitSpecificKey(hit_key, hit); } @@ -357,7 +357,7 @@ int TpcCombinedRawDataUnpackerDebug::process_event(PHCompositeNode* topNode) int hmaxbin = 0; for (int nbin = 1; nbin <= pedhist.GetNbinsX(); nbin++) { - float val = pedhist.GetBinContent(nbin); + double val = pedhist.GetBinContent(nbin); if (val > hmax) { hmaxbin = nbin; @@ -381,8 +381,8 @@ int TpcCombinedRawDataUnpackerDebug::process_event(PHCompositeNode* topNode) for (int isum = -3; isum <= 3; isum++) { - float val = pedhist.GetBinContent(hmaxbin + isum); - float center = pedhist.GetBinCenter(hmaxbin + isum); + double val = pedhist.GetBinContent(hmaxbin + isum); + double center = pedhist.GetBinCenter(hmaxbin + isum); ibin_sum += center * val; ibin2_sum += center * center * val; adc_sum += val; @@ -462,12 +462,12 @@ int TpcCombinedRawDataUnpackerDebug::process_event(PHCompositeNode* topNode) feehist->Fill(t, adc - hpedestal + pedestal_offset); } } - float threshold_cut = (hpedwidth * m_ped_sig_cut); + double threshold_cut = (hpedwidth * m_ped_sig_cut); if (m_do_zs_emulation) { threshold_cut = m_zs_threshold; } - if ((float(adc) - hpedestal) > threshold_cut) + if ((double(adc) - hpedestal) > threshold_cut) { hit_key = TpcDefs::genHitKey(phibin, (unsigned int) t); // find existing hit, or create new one @@ -477,17 +477,17 @@ int TpcCombinedRawDataUnpackerDebug::process_event(PHCompositeNode* topNode) hit = new TrkrHitv2(); if (m_do_baseline_corr) { - hit->setAdc(float(adc) - hpedestal + pedestal_offset); + hit->setAdc(double(adc) - hpedestal + pedestal_offset); } else { - hit->setAdc(float(adc) - hpedestal); + hit->setAdc(double(adc) - hpedestal); } hit_set_container_itr->second->addHitSpecificKey(hit_key, hit); } if (m_writeTree) { - float fXh[18]; + double fXh[18]; int nh = 0; fXh[nh++] = _ievent - 1; @@ -500,10 +500,10 @@ int TpcCombinedRawDataUnpackerDebug::process_event(PHCompositeNode* topNode) fXh[nh++] = 0; // channel; fXh[nh++] = 0; // sampadd; fXh[nh++] = 0; // sampch; - fXh[nh++] = (float) phibin; - fXh[nh++] = (float) t; + fXh[nh++] = (double) phibin; + fXh[nh++] = (double) t; fXh[nh++] = layer; - fXh[nh++] = (float(adc) - hpedestal + pedestal_offset); + fXh[nh++] = (double(adc) - hpedestal + pedestal_offset); fXh[nh++] = hpedestal; fXh[nh++] = hpedwidth; @@ -527,9 +527,9 @@ int TpcCombinedRawDataUnpackerDebug::process_event(PHCompositeNode* topNode) if (hiter.second != nullptr) { TH2I* hist2d = hiter.second; - std::vector pedvec(hist2d->GetNbinsX(), 0); + std::vector pedvec(hist2d->GetNbinsX(), 0); feebaseline_map.insert(std::make_pair(hiter.first, pedvec)); - std::map>::iterator fee_blm_it = feebaseline_map.find(hiter.first); + std::map>::iterator fee_blm_it = feebaseline_map.find(hiter.first); (*fee_blm_it).second.resize(hist2d->GetNbinsX(), 0); for (int binx = 1; binx < hist2d->GetNbinsX(); binx++) @@ -537,7 +537,7 @@ int TpcCombinedRawDataUnpackerDebug::process_event(PHCompositeNode* topNode) double timebin = ( hist2d->GetXaxis())->GetBinCenter(binx); std::string histname1d = "h" + std::to_string(hiter.first) + "_" + std::to_string((int) timebin); TH1D* hist1d = hist2d->ProjectionY(histname1d.c_str(), binx, binx); - float local_ped = 0; + double local_ped = 0; #ifdef DEBUG // if((*hiter).first == 210802&&timebin==383){ @@ -557,8 +557,8 @@ int TpcCombinedRawDataUnpackerDebug::process_event(PHCompositeNode* topNode) for (int isum = -3; isum <= 3; isum++) { - float val = hist1d->GetBinContent(maxbin + isum); - float center = hist1d->GetBinCenter(maxbin + isum); + double val = hist1d->GetBinContent(maxbin + isum); + double center = hist1d->GetBinCenter(maxbin + isum); hibin_sum += center * val; // hibin2_sum += center * center * val; hadc_sum += val; @@ -624,9 +624,9 @@ int TpcCombinedRawDataUnpackerDebug::process_event(PHCompositeNode* topNode) unsigned int pad_key = create_pad_key(side, layer, phibin); - float fee = 0; - float hpedestal2 = 0; - float hpedwidth2 = 0; + double fee = 0; + double hpedestal2 = 0; + double hpedwidth2 = 0; std::map::iterator chan_it = chan_map.find(pad_key); if (chan_it != chan_map.end()) { @@ -637,10 +637,10 @@ int TpcCombinedRawDataUnpackerDebug::process_event(PHCompositeNode* topNode) } int rx = get_rx(layer); - float corr = 0; + double corr = 0; unsigned int fee_key = create_fee_key(side, sector, rx, fee); - std::map>::iterator fee_blm_it = feebaseline_map.find(fee_key); + std::map>::iterator fee_blm_it = feebaseline_map.find(fee_key); if (fee_blm_it != feebaseline_map.end()) { corr = (*fee_blm_it).second[tbin] - pedestal_offset; @@ -689,10 +689,10 @@ int TpcCombinedRawDataUnpackerDebug::process_event(PHCompositeNode* topNode) } if (hpedwidth2 > -100 && hpedestal2 > -100) { - if ((float(adc) - pedestal_offset - corr) > (hpedwidth2 * m_ped_sig_cut)) + if ((double(adc) - pedestal_offset - corr) > (hpedwidth2 * m_ped_sig_cut)) { - float nuadc = (float(adc) - corr - pedestal_offset); - nuadc = std::max(nuadc, 0); + double nuadc = (double(adc) - corr - pedestal_offset); + nuadc = std::max(nuadc, 0); hitr->second->setAdc(nuadc); #ifdef DEBUG // hitr->second->setAdc(10); @@ -709,14 +709,14 @@ int TpcCombinedRawDataUnpackerDebug::process_event(PHCompositeNode* topNode) << " phibin " << phibin << " adc " << adc << " corr: " << corr - << " adcnu " << (float(adc) - corr - pedestal_offset) + << " adcnu " << (double(adc) - corr - pedestal_offset) << " adc in " << hitr->second->getAdc() << std::endl; } #endif if (m_writeTree) { - float fXh[18]; + double fXh[18]; int nh = 0; fXh[nh++] = _ievent - 1; @@ -729,10 +729,10 @@ int TpcCombinedRawDataUnpackerDebug::process_event(PHCompositeNode* topNode) fXh[nh++] = 0; // channel; fXh[nh++] = 0; // sampadd; fXh[nh++] = 0; // sampch; - fXh[nh++] = (float) phibin; - fXh[nh++] = (float) tbin; + fXh[nh++] = (double) phibin; + fXh[nh++] = (double) tbin; fXh[nh++] = layer; - fXh[nh++] = float(adc); + fXh[nh++] = double(adc); fXh[nh++] = hpedestal2; fXh[nh++] = hpedwidth2; fXh[nh++] = corr; diff --git a/offline/packages/tpc/TpcCombinedRawDataUnpackerDebug.h b/offline/packages/tpc/TpcCombinedRawDataUnpackerDebug.h index baca369042..dd68e55863 100644 --- a/offline/packages/tpc/TpcCombinedRawDataUnpackerDebug.h +++ b/offline/packages/tpc/TpcCombinedRawDataUnpackerDebug.h @@ -28,7 +28,7 @@ class TpcCombinedRawDataUnpackerDebug : public SubsysReco int End(PHCompositeNode *topNode) override; void writeTree() { m_writeTree = true; } void do_zero_suppression(bool b) { m_do_zerosup = b; } - void set_pedestalSigmaCut(float b) { m_ped_sig_cut = b; } + void set_pedestalSigmaCut(double b) { m_ped_sig_cut = b; } void do_noise_rejection(bool b) { m_do_noise_rejection = b; } void doBaselineCorr(bool val) { m_do_baseline_corr = val; } void doZSEmulation(bool val) { m_do_zs_emulation = val; } @@ -49,8 +49,8 @@ class TpcCombinedRawDataUnpackerDebug : public SubsysReco struct chan_info { unsigned int fee = std::numeric_limits::max(); - float ped = -1; - float width = -1; + double ped = -1; + double width = -1; }; unsigned int get_rx(unsigned int layer) { @@ -104,7 +104,7 @@ class TpcCombinedRawDataUnpackerDebug : public SubsysReco int FEE_map[26]{4, 5, 0, 2, 1, 11, 9, 10, 8, 7, 6, 0, 1, 3, 7, 6, 5, 4, 3, 2, 0, 2, 1, 3, 5, 4}; int FEE_R[26]{2, 2, 1, 1, 1, 3, 3, 3, 3, 3, 3, 2, 2, 1, 2, 2, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3}; - float m_ped_sig_cut{4.0}; + double m_ped_sig_cut{4.0}; bool m_writeTree{false}; bool m_do_zerosup{true}; @@ -117,7 +117,7 @@ class TpcCombinedRawDataUnpackerDebug : public SubsysReco std::string outfile_name; std::map chan_map; // stays in place std::map feeadc_map; // histos reset after each event - std::map> feebaseline_map; // cleared after each event + std::map> feebaseline_map; // cleared after each event }; #endif // TPC_COMBINEDRAWDATAUNPACKER_H diff --git a/offline/packages/tpc/TpcDistortionCorrectionContainer.h b/offline/packages/tpc/TpcDistortionCorrectionContainer.h index c7ba14937b..2d65ca79dd 100644 --- a/offline/packages/tpc/TpcDistortionCorrectionContainer.h +++ b/offline/packages/tpc/TpcDistortionCorrectionContainer.h @@ -21,7 +21,7 @@ class TpcDistortionCorrectionContainer int m_dimensions = 3; bool m_use_scalefactor = false; - float m_scalefactor = 1.0; + double m_scalefactor = 1.0; //! set the phi histogram to be interpreted as radians rather than mm bool m_phi_hist_in_radians = true; diff --git a/offline/packages/tpc/TpcLoadDistortionCorrection.h b/offline/packages/tpc/TpcLoadDistortionCorrection.h index 6727957487..276d18fec4 100644 --- a/offline/packages/tpc/TpcLoadDistortionCorrection.h +++ b/offline/packages/tpc/TpcLoadDistortionCorrection.h @@ -48,7 +48,7 @@ class TpcLoadDistortionCorrection : public SubsysReco } //! set the scale factor to be applied to the correction - void set_scale_factor(DistortionType i, float value) + void set_scale_factor(DistortionType i, double value) { m_use_scalefactor[i] = true; m_scalefactor[i] = value; @@ -97,7 +97,7 @@ class TpcLoadDistortionCorrection : public SubsysReco std::array m_use_scalefactor = {}; //! scale factors - std::array m_scalefactor = {1.0,1.0,1.0,1.0}; + std::array m_scalefactor = {1.0,1.0,1.0,1.0}; //! set the phi histogram to be interpreted as radians rather than mm std::array m_phi_hist_in_radians = {true,true,true,true}; diff --git a/offline/packages/tpc/TpcRawWriter.cc b/offline/packages/tpc/TpcRawWriter.cc index 41c5f26df3..bc217516d7 100644 --- a/offline/packages/tpc/TpcRawWriter.cc +++ b/offline/packages/tpc/TpcRawWriter.cc @@ -311,7 +311,7 @@ int TpcRawWriter::process_event(PHCompositeNode *topNode) // count++; } std::cout << "processing tpc" << std::endl; - float tpc_zmax = m_tGeometry->get_max_driftlength() + m_tGeometry->get_CM_halfwidth(); + double tpc_zmax = m_tGeometry->get_max_driftlength() + m_tGeometry->get_CM_halfwidth(); // loop over the TPC HitSet objects TrkrHitSetContainer::ConstRange tpc_hitsetrange = m_hits->getHitSets(TrkrDefs::TrkrId::tpcId); @@ -405,7 +405,7 @@ int TpcRawWriter::process_event(PHCompositeNode *topNode) { continue; } - float_t fadc = (hitr->second->getAdc()) - pedestal; // proper int rounding +0.5 + double_t fadc = (hitr->second->getAdc()) - pedestal; // proper int rounding +0.5 unsigned short adc = 0; if (fadc > 0) { diff --git a/offline/packages/tpc/TpcSimpleClusterizer.cc b/offline/packages/tpc/TpcSimpleClusterizer.cc index f1fb0d5b76..ec49c51aec 100644 --- a/offline/packages/tpc/TpcSimpleClusterizer.cc +++ b/offline/packages/tpc/TpcSimpleClusterizer.cc @@ -64,7 +64,7 @@ namespace unsigned int layer = 0; int side = 0; unsigned int sector = 0; - float pedestal = 0; + double pedestal = 0; bool do_assoc = true; unsigned short phibins = 0; unsigned short phioffset = 0; @@ -292,7 +292,7 @@ namespace unsigned short phibin = TpcDefs::getPad(hitr->first) - phioffset; unsigned short zbin = TpcDefs::getTBin(hitr->first) - zoffset; - float_t fadc = (hitr->second->getAdc()) - pedestal; // proper int rounding +0.5 + double_t fadc = (hitr->second->getAdc()) - pedestal; // proper int rounding +0.5 // std::cout << " layer: " << my_data->layer << " phibin " << phibin << " zbin " << zbin << " fadc " << hitr->second->getAdc() << " pedestal " << pedestal << " fadc " << std::endl unsigned short adc = 0; From 24b32d04cb306e399d3db156e5ed1b8aa32ba79a Mon Sep 17 00:00:00 2001 From: Joseph Clement Date: Wed, 11 Feb 2026 18:25:24 -0500 Subject: [PATCH 208/393] add protection against missing calib file or function --- offline/packages/jetbackground/TimingCut.cc | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/offline/packages/jetbackground/TimingCut.cc b/offline/packages/jetbackground/TimingCut.cc index 7d63e5c432..719fc8181c 100644 --- a/offline/packages/jetbackground/TimingCut.cc +++ b/offline/packages/jetbackground/TimingCut.cc @@ -42,8 +42,21 @@ int TimingCut::Init(PHCompositeNode *topNode) } _fitFile = new CDBTF(CDBInterface::instance()->getUrl("t_ohfrac_calib_Default")); - _fitFile->LoadCalibrations(); - _fitFunc = _fitFile->getTF("t_ohcal_calib_function_Default"); + if(_fitFile) + { + _fitFile->LoadCalibrations(); + _fitFunc = _fitFile->getTF("t_ohcal_calib_function_Default"); + if(!_fitFunc) + { + std::cout << "ERROR: NO CALIBRATION TF1 FOUND FOR TIMING CUT OHCAL FRACTION CORRECTION! This should never happen. ABORT RUN!" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + } + else + { + std::cout << "ERROR: NO CALIBRATION FILE FOUND FOR TIMING CUT OHCAL FRACTION CORRECTION! ABORT RUN!" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } return Fun4AllReturnCodes::EVENT_OK; } From 3fd2a487f9877573ef098986a781258ab695ae7b Mon Sep 17 00:00:00 2001 From: Ishan Goel Date: Wed, 11 Feb 2026 21:40:21 -0500 Subject: [PATCH 209/393] Fixes for maps --- offline/packages/tpc/TpcClusterizer.cc | 30 ++++++++++++++++++++++---- offline/packages/tpc/TpcClusterizer.h | 3 +++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/offline/packages/tpc/TpcClusterizer.cc b/offline/packages/tpc/TpcClusterizer.cc index 24405c8df4..17d7a0b4d1 100644 --- a/offline/packages/tpc/TpcClusterizer.cc +++ b/offline/packages/tpc/TpcClusterizer.cc @@ -29,6 +29,8 @@ #include #include // for SubsysReco +#include + #include #include @@ -1308,6 +1310,19 @@ int TpcClusterizer::InitRun(PHCompositeNode *topNode) auto *g3 = static_cast (geom->GetLayerCellGeom(40)); // cast because << not in the base class std::cout << *g3 << std::endl; + auto evtHeader = findNode::getClass(topNode, "EVENTHEADER"); + if (evtHeader) + { + m_runNumber = evtHeader->get_RunNumber(); + m_isSimulation = (m_runNumber < 1000); // Threshold: < 1000 is simulation + std::cout << PHWHERE << "Run number = " << m_runNumber << ", isSimulation = " << m_isSimulation << std::endl; + } + else + { + std::cout << PHWHERE << "WARNING: EventHeader node not found; defaulting to simulation." << std::endl; + m_isSimulation = true; + } + if (m_maskDeadChannels) { m_deadChannelMap.clear(); @@ -1859,10 +1874,17 @@ void TpcClusterizer::makeChannelMask(hitMaskTpcSet &aMask, const std::string &db for (int i = 0; i < NChan; i++) { - int Layer = cdbttree->GetIntValue(i, "layer"); - int Sector = cdbttree->GetIntValue(i, "sector"); - int Side = cdbttree->GetIntValue(i, "side"); - int Pad = cdbttree->GetIntValue(i, "pad"); + int Layer0 = cdbttree->GetIntValue(i, "layer0"); // Simulation layer + int Layer1 = cdbttree->GetIntValue(i, "layer1"); // Data layer + int Sec = cdbttree->GetIntValue(i, "sector"); // Stored sector + int Side = cdbttree->GetIntValue(i, "side"); // 0 or 1 + int Pad0 = cdbttree->GetIntValue(i, "pad0"); // Simulation pad + int Pad1 = cdbttree->GetIntValue(i, "pad1"); // Data pad + + int Layer = (m_isSimulation) ? Layer0 : Layer1; + int Pad = (m_isSimulation) ? Pad0 : Pad1; + int Sector = (m_isSimulation) ? mc_sectors[Sec] : Sec; + if (Verbosity() > VERBOSITY_A_LOT) { std::cout << dbName << ": Will mask layer: " << Layer << ", sector: " << Sector << ", side: " << Side << ", Pad: " << Pad << std::endl; diff --git a/offline/packages/tpc/TpcClusterizer.h b/offline/packages/tpc/TpcClusterizer.h index 84a58ceca6..e8ceb04983 100644 --- a/offline/packages/tpc/TpcClusterizer.h +++ b/offline/packages/tpc/TpcClusterizer.h @@ -95,6 +95,9 @@ class TpcClusterizer : public SubsysReco bool is_in_sector_boundary(int phibin, int sector, PHG4TpcGeom *layergeom) const; bool record_ClusHitsVerbose{false}; + int m_runNumber = -1; // Store run number from Event Header + bool m_isSimulation = true; // Default true; Updated based on run number + int mc_sectors[12]{5, 4, 3, 2, 1, 0, 11, 10, 9, 8, 7, 6}; void makeChannelMask(hitMaskTpcSet& aMask, const std::string& dbName, const std::string& totalChannelsToMask); TrkrHitSetContainer *m_hits = nullptr; From edb448dc40e7f45f05790f4baddd6c2c779a39be Mon Sep 17 00:00:00 2001 From: Ishan Goel Date: Wed, 11 Feb 2026 22:10:51 -0500 Subject: [PATCH 210/393] Fix --- offline/packages/tpc/TpcClusterizer.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/offline/packages/tpc/TpcClusterizer.cc b/offline/packages/tpc/TpcClusterizer.cc index 17d7a0b4d1..cd27eeb8f0 100644 --- a/offline/packages/tpc/TpcClusterizer.cc +++ b/offline/packages/tpc/TpcClusterizer.cc @@ -1881,6 +1881,14 @@ void TpcClusterizer::makeChannelMask(hitMaskTpcSet &aMask, const std::string &db int Pad0 = cdbttree->GetIntValue(i, "pad0"); // Simulation pad int Pad1 = cdbttree->GetIntValue(i, "pad1"); // Data pad + if (Sec < 0 || Sec >= 12) + { + std::cout << PHWHERE << "WARNING: sector index " << Sec + << " out of range [0,11] in " << dbName + << ", skipping channel " << i << std::endl; + continue; + } + int Layer = (m_isSimulation) ? Layer0 : Layer1; int Pad = (m_isSimulation) ? Pad0 : Pad1; int Sector = (m_isSimulation) ? mc_sectors[Sec] : Sec; From 2305b2220986f5576c5fcd7782d2e79a0c7bd1b7 Mon Sep 17 00:00:00 2001 From: Ishan Goel Date: Wed, 11 Feb 2026 22:25:46 -0500 Subject: [PATCH 211/393] Fix2 --- offline/packages/tpc/TpcClusterizer.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/offline/packages/tpc/TpcClusterizer.cc b/offline/packages/tpc/TpcClusterizer.cc index cd27eeb8f0..dba038abe6 100644 --- a/offline/packages/tpc/TpcClusterizer.cc +++ b/offline/packages/tpc/TpcClusterizer.cc @@ -1893,6 +1893,22 @@ void TpcClusterizer::makeChannelMask(hitMaskTpcSet &aMask, const std::string &db int Pad = (m_isSimulation) ? Pad0 : Pad1; int Sector = (m_isSimulation) ? mc_sectors[Sec] : Sec; + if (Layer < 7 || Layer > 48) + { + std::cout << PHWHERE << "WARNING: layer " << Layer + << " out of TPC range [7,48] in " << dbName + << ", skipping channel " << i << std::endl; + continue; + } + + if (Side < 0 || Side > 1) + { + std::cout << PHWHERE << "WARNING: side " << Side + << " out of range [0,1] in " << dbName + << ", skipping channel " << i << std::endl; + continue; + } + if (Verbosity() > VERBOSITY_A_LOT) { std::cout << dbName << ": Will mask layer: " << Layer << ", sector: " << Sector << ", side: " << Side << ", Pad: " << Pad << std::endl; From 0bc9fe491953708645e1909132a86570ebad9d9d Mon Sep 17 00:00:00 2001 From: Ishan Goel Date: Wed, 11 Feb 2026 22:41:21 -0500 Subject: [PATCH 212/393] Some --- offline/packages/tpc/TpcClusterizer.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/tpc/TpcClusterizer.cc b/offline/packages/tpc/TpcClusterizer.cc index dba038abe6..9217ebc40a 100644 --- a/offline/packages/tpc/TpcClusterizer.cc +++ b/offline/packages/tpc/TpcClusterizer.cc @@ -1310,7 +1310,7 @@ int TpcClusterizer::InitRun(PHCompositeNode *topNode) auto *g3 = static_cast (geom->GetLayerCellGeom(40)); // cast because << not in the base class std::cout << *g3 << std::endl; - auto evtHeader = findNode::getClass(topNode, "EVENTHEADER"); + auto *evtHeader = findNode::getClass(topNode, "EVENTHEADER"); if (evtHeader) { m_runNumber = evtHeader->get_RunNumber(); From f34b4423c5e8e2d12394c46a3f52fd9ac84f397c Mon Sep 17 00:00:00 2001 From: bogui56 Date: Thu, 12 Feb 2026 07:22:24 -0500 Subject: [PATCH 213/393] reco error update --- .../packages/trackbase/ClusterErrorPara.cc | 235 ++++++++++++++++-- offline/packages/trackbase/ClusterErrorPara.h | 1 + 2 files changed, 209 insertions(+), 27 deletions(-) diff --git a/offline/packages/trackbase/ClusterErrorPara.cc b/offline/packages/trackbase/ClusterErrorPara.cc index cb62ed10f5..18e6a999b1 100644 --- a/offline/packages/trackbase/ClusterErrorPara.cc +++ b/offline/packages/trackbase/ClusterErrorPara.cc @@ -1,7 +1,8 @@ #include "ClusterErrorPara.h" #include "TrkrCluster.h" - +//#include +#include #include #include @@ -18,10 +19,18 @@ namespace { return x * x; } + } // namespace ClusterErrorPara::ClusterErrorPara() { + /* + ftpcR1 = new TF1("ftpcR1", "pol2", 0, 10); + ftpcR1->SetParameter(0, 3.206); + ftpcR1->SetParameter(1, -0.252); + ftpcR1->SetParameter(2, 0.007); + */ + f0 = new TF1("f0", "pol1", 0, 10); f0->SetParameter(0, 0.0163943); f0->SetParameter(1, 0.0192931); @@ -476,40 +485,212 @@ ClusterErrorPara::ClusterErrorPara() //_________________________________________________________________________________ ClusterErrorPara::error_t ClusterErrorPara::get_clusterv5_modified_error(TrkrCluster* cluster, double /*unused*/, TrkrDefs::cluskey key) { + bool is_data_reco; + recoConsts* rc = recoConsts::instance(); + if(rc->get_StringFlag("CDB_GLOBALTAG").find("MDC") != std::string::npos){ + is_data_reco = false; + } + else{ + // std::cout << "CHECK Setting reconstruction for data with CDB tag " << rc->get_StringFlag("CDB_GLOBALTAG") << std::endl; + is_data_reco = true; + } + int layer = TrkrDefs::getLayer(key); double phierror = cluster->getRPhiError(); double zerror = cluster->getZError(); - if (TrkrDefs::getTrkrId(key) == TrkrDefs::tpcId) - { - if (layer == 7 || layer == 22 || layer == 23 || layer == 38 || layer == 39) - { - phierror *= 4; - zerror *= 4; - } - if (cluster->getEdge() >= 3) - { - phierror *= 4; - } - if (cluster->getOverlap() >= 2) - { - phierror *= 2; - } - if (cluster->getPhiSize() == 1) - { - phierror *= 10; + if(is_data_reco==false){ + if (TrkrDefs::getTrkrId(key) == TrkrDefs::tpcId) + { + if (layer == 7 || layer == 22 || layer == 23 || layer == 38 || layer == 39) + { + phierror *= 4; + zerror *= 4; + } + if (cluster->getEdge() >= 3) + { + phierror *= 4; + } + if (cluster->getOverlap() >= 2) + { + phierror *= 2; + } + if (cluster->getPhiSize() == 1) + { + phierror *= 10; + } + if (cluster->getPhiSize() >= 5) + { + phierror *= 10; + } + + phierror = std::min(phierror, 0.1); + if (phierror < 0.0005) + { + phierror = 0.1; + } + } + }else{ + + if (TrkrDefs::getTrkrId(key) == TrkrDefs::tpcId) + { + if (layer == 7 || layer == 22 || layer == 23 || layer == 38 || layer == 39 || layer == 54) + { + phierror *= 4; + zerror *= 4; + } + if (cluster->getEdge() >= 3) + { + phierror *= 4; + } + if (cluster->getOverlap() >= 2) + { + phierror *= 2; + } + if(layer>=7&&layer<(7+48)){ + //Set phi error + if (cluster->getPhiSize() == 1) + { + phierror *= 1.0; + } + if (cluster->getPhiSize() == 2) + { + phierror*=3.15; + } + if (cluster->getPhiSize() == 3) + { + phierror *=3.5; + } + if (cluster->getPhiSize() >3) + { + phierror *= 4; + } + //Set Z Error + if (cluster->getZSize() == 1){ + zerror*=1.0; + } + if (cluster->getZSize() == 2){ + if(layer>=7&&layer<(7+16)){ + zerror*=7; + } + if(layer>=(7+16)&&layer<(7+32)){ + zerror*=4.5; + } + if(layer>=(7+32)&&layer<(7+48)){ + zerror*=4.5; + } + + } + if ((cluster->getZSize() == 3) || (cluster->getZSize() == 4)){ + if(layer>=7&&layer<(7+16)){ + zerror*=7; + } + if(layer>=(7+16)&&layer<(7+32)){ + zerror*=5; + } + if(layer>=(7+32)&&layer<(7+48)){ + zerror*=5; + } + // zerror*=6; + } + if (cluster->getZSize() >5){ + if(layer>=7&&layer<(7+16)){ + zerror*=20; + } + if(layer>=(7+16)&&layer<(7+32)){ + zerror*=6; + } + if(layer>=(7+32)&&layer<(7+48)){ + zerror*=7; + } + } + TF1 ftpcR1("ftpcR1", "pol2", 0, 60); + ftpcR1.SetParameter(0, 3.206); + ftpcR1.SetParameter(1, -0.252); + ftpcR1.SetParameter(2, 0.007); + + TF1 ftpcR2("ftpcR2", "pol2", 0, 60); + ftpcR2.SetParameter(0, 4.48); + ftpcR2.SetParameter(1, -0.226); + ftpcR2.SetParameter(2, 0.00362); + + TF1 ftpcR3("ftpcR3", "pol2", 0, 60); + ftpcR3.SetParameter(0, 14.8112); + ftpcR3.SetParameter(1, -0.577); + ftpcR3.SetParameter(2, 0.00605); + + if(layer>=7&&layer<(7+16)){ + phierror*= ftpcR1.Eval(layer); + } + if(layer>=(7+16)&&layer<(7+32)){ + phierror*= ftpcR2.Eval(layer); + } + if(layer>=(7+32)&&layer<(7+48)){ + phierror*= ftpcR3.Eval(layer); + } + ftpcR2.SetParameter(0, 5.593); + ftpcR2.SetParameter(1, -0.2458); + ftpcR2.SetParameter(2, 0.00333455); + + ftpcR3.SetParameter(0, 5.6964); + ftpcR3.SetParameter(1, -0.21338); + ftpcR3.SetParameter(2, 0.002502); + + if(layer>=(7+16)&&layer<(7+32)){ + zerror*= ftpcR2.Eval(layer); + } + if(layer>=(7+32)&&layer<(7+48)){ + zerror*= ftpcR3.Eval(layer); + } + } + if (cluster->getPhiSize() >= 5) + { + phierror *= 10; + } + } + + if (TrkrDefs::getTrkrId(key) == TrkrDefs::mvtxId){ + phierror*=2; + zerror*=2; } - if (cluster->getPhiSize() >= 5) - { - phierror *= 10; + + if (TrkrDefs::getTrkrId(key) == TrkrDefs::inttId){ + phierror*=9; + if (cluster->getPhiSize() == 1){ + phierror *= 1.25; + } + if (cluster->getPhiSize() == 2){ + phierror *= 2.25; + } + if(layer==3||layer==4) + phierror*=0.8; + if(layer==5||layer==6) + phierror*=1.2; } - - phierror = std::min(phierror, 0.1); - if (phierror < 0.0005) - { - phierror = 0.1; + + if (TrkrDefs::getTrkrId(key) == TrkrDefs::micromegasId){ + if(layer==55){ + /* + phierror*=5.4; + phierror*=4.6; + phierror*=3.0; + zerror*=0.82; + */ + phierror = 0.0289; + } + + if(layer==56){ + /* + phierror*=0.9; + phierror*=0.95; + zerror*=4.5; + zerror*=3.4; + */ + zerror = 0.577; + } } } + return std::make_pair(square(phierror), square(zerror)); } diff --git a/offline/packages/trackbase/ClusterErrorPara.h b/offline/packages/trackbase/ClusterErrorPara.h index b125858217..ad12c1b522 100644 --- a/offline/packages/trackbase/ClusterErrorPara.h +++ b/offline/packages/trackbase/ClusterErrorPara.h @@ -128,6 +128,7 @@ class ClusterErrorPara double scale_mm_1 {1.5}; double pull_fine_phi[60]{}; double pull_fine_z[60]{}; + }; #endif From e13fbb091d87c78fdadf87e397640bad2df84d07 Mon Sep 17 00:00:00 2001 From: bogui56 Date: Thu, 12 Feb 2026 07:52:14 -0500 Subject: [PATCH 214/393] jenkins 1 --- offline/packages/trackbase/ClusterErrorPara.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/trackbase/ClusterErrorPara.cc b/offline/packages/trackbase/ClusterErrorPara.cc index 18e6a999b1..965f1db09a 100644 --- a/offline/packages/trackbase/ClusterErrorPara.cc +++ b/offline/packages/trackbase/ClusterErrorPara.cc @@ -22,7 +22,7 @@ namespace } // namespace -ClusterErrorPara::ClusterErrorPara() +ClusterErrorPara::ClusterErrorPara(): f0{new TF1("f0", "pol1", 0, 10)} { /* ftpcR1 = new TF1("ftpcR1", "pol2", 0, 10); From 89772f9056642c741f192da7953b23a5002c3df1 Mon Sep 17 00:00:00 2001 From: Ishan Goel Date: Thu, 12 Feb 2026 12:48:03 -0500 Subject: [PATCH 215/393] Requested fixes. --- offline/packages/tpc/TpcClusterizer.cc | 61 ++++++++++++++------------ offline/packages/tpc/TpcClusterizer.h | 8 +++- 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/offline/packages/tpc/TpcClusterizer.cc b/offline/packages/tpc/TpcClusterizer.cc index 9217ebc40a..0de48f2cdd 100644 --- a/offline/packages/tpc/TpcClusterizer.cc +++ b/offline/packages/tpc/TpcClusterizer.cc @@ -29,8 +29,6 @@ #include #include // for SubsysReco -#include - #include #include @@ -1310,19 +1308,6 @@ int TpcClusterizer::InitRun(PHCompositeNode *topNode) auto *g3 = static_cast (geom->GetLayerCellGeom(40)); // cast because << not in the base class std::cout << *g3 << std::endl; - auto *evtHeader = findNode::getClass(topNode, "EVENTHEADER"); - if (evtHeader) - { - m_runNumber = evtHeader->get_RunNumber(); - m_isSimulation = (m_runNumber < 1000); // Threshold: < 1000 is simulation - std::cout << PHWHERE << "Run number = " << m_runNumber << ", isSimulation = " << m_isSimulation << std::endl; - } - else - { - std::cout << PHWHERE << "WARNING: EventHeader node not found; defaulting to simulation." << std::endl; - m_isSimulation = true; - } - if (m_maskDeadChannels) { m_deadChannelMap.clear(); @@ -1883,29 +1868,51 @@ void TpcClusterizer::makeChannelMask(hitMaskTpcSet &aMask, const std::string &db if (Sec < 0 || Sec >= 12) { - std::cout << PHWHERE << "WARNING: sector index " << Sec - << " out of range [0,11] in " << dbName - << ", skipping channel " << i << std::endl; + if (Verbosity() > VERBOSITY_A_LOT) + { + std::cout << PHWHERE << "WARNING: sector index " << Sec + << " out of range [0,11] in " << dbName + << ", skipping channel " << i << std::endl; + } continue; } - int Layer = (m_isSimulation) ? Layer0 : Layer1; - int Pad = (m_isSimulation) ? Pad0 : Pad1; - int Sector = (m_isSimulation) ? mc_sectors[Sec] : Sec; + int Layer; + int Pad; + int Sector; + + if (!m_is_data) + { + Layer = Layer0; + Pad = Pad0; + Sector = mc_sectors[Sec]; + } + else + { + Layer = Layer1; + Pad = Pad1; + Sector = Sec; + } if (Layer < 7 || Layer > 48) { - std::cout << PHWHERE << "WARNING: layer " << Layer - << " out of TPC range [7,48] in " << dbName - << ", skipping channel " << i << std::endl; + if (Verbosity() > VERBOSITY_A_LOT) + { + std::cout << PHWHERE << "WARNING: layer " << Layer + << " out of TPC range [7,48] in " << dbName + << ", skipping channel " << i << std::endl; + } continue; } if (Side < 0 || Side > 1) { - std::cout << PHWHERE << "WARNING: side " << Side - << " out of range [0,1] in " << dbName - << ", skipping channel " << i << std::endl; + if (Verbosity() > VERBOSITY_A_LOT) + { + std::cout << PHWHERE << "WARNING: side " << Side + << " out of range [0,1] in " << dbName + << ", skipping channel " << i << std::endl; + } continue; } diff --git a/offline/packages/tpc/TpcClusterizer.h b/offline/packages/tpc/TpcClusterizer.h index e8ceb04983..8eaf47e02d 100644 --- a/offline/packages/tpc/TpcClusterizer.h +++ b/offline/packages/tpc/TpcClusterizer.h @@ -75,6 +75,11 @@ class TpcClusterizer : public SubsysReco ClusHitsVerbosev1 *mClusHitsVerbose{nullptr}; + void SetSimDataFlag(bool flag) + { + m_is_data = flag; + } + void SetMaskChannelsFromFile() { m_maskFromFile = true; @@ -95,8 +100,6 @@ class TpcClusterizer : public SubsysReco bool is_in_sector_boundary(int phibin, int sector, PHG4TpcGeom *layergeom) const; bool record_ClusHitsVerbose{false}; - int m_runNumber = -1; // Store run number from Event Header - bool m_isSimulation = true; // Default true; Updated based on run number int mc_sectors[12]{5, 4, 3, 2, 1, 0, 11, 10, 9, 8, 7, 6}; void makeChannelMask(hitMaskTpcSet& aMask, const std::string& dbName, const std::string& totalChannelsToMask); @@ -137,6 +140,7 @@ class TpcClusterizer : public SubsysReco bool m_maskDeadChannels {false}; bool m_maskHotChannels {false}; + bool m_is_data {false}; bool m_maskFromFile {false}; std::string m_deadChannelMapName; std::string m_hotChannelMapName; From b42fdf57f3efbd78048290d274d421ac2e8478ca Mon Sep 17 00:00:00 2001 From: Ishan Goel Date: Thu, 12 Feb 2026 12:54:17 -0500 Subject: [PATCH 216/393] More --- offline/packages/tpc/TpcClusterizer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/tpc/TpcClusterizer.h b/offline/packages/tpc/TpcClusterizer.h index 8eaf47e02d..550301f813 100644 --- a/offline/packages/tpc/TpcClusterizer.h +++ b/offline/packages/tpc/TpcClusterizer.h @@ -75,7 +75,7 @@ class TpcClusterizer : public SubsysReco ClusHitsVerbosev1 *mClusHitsVerbose{nullptr}; - void SetSimDataFlag(bool flag) + void SetIsData(bool flag) { m_is_data = flag; } From 4a18fc36a8b4747579510b222890db26799e2a96 Mon Sep 17 00:00:00 2001 From: Ishan Goel Date: Thu, 12 Feb 2026 23:55:14 -0500 Subject: [PATCH 217/393] Another fix. --- offline/packages/tpc/TpcClusterizer.cc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/offline/packages/tpc/TpcClusterizer.cc b/offline/packages/tpc/TpcClusterizer.cc index 0de48f2cdd..e7fa17fa9e 100644 --- a/offline/packages/tpc/TpcClusterizer.cc +++ b/offline/packages/tpc/TpcClusterizer.cc @@ -1859,8 +1859,7 @@ void TpcClusterizer::makeChannelMask(hitMaskTpcSet &aMask, const std::string &db for (int i = 0; i < NChan; i++) { - int Layer0 = cdbttree->GetIntValue(i, "layer0"); // Simulation layer - int Layer1 = cdbttree->GetIntValue(i, "layer1"); // Data layer + int Layer = cdbttree->GetIntValue(i, "layer"); // Stored layer int Sec = cdbttree->GetIntValue(i, "sector"); // Stored sector int Side = cdbttree->GetIntValue(i, "side"); // 0 or 1 int Pad0 = cdbttree->GetIntValue(i, "pad0"); // Simulation pad @@ -1877,19 +1876,16 @@ void TpcClusterizer::makeChannelMask(hitMaskTpcSet &aMask, const std::string &db continue; } - int Layer; int Pad; int Sector; if (!m_is_data) { - Layer = Layer0; Pad = Pad0; Sector = mc_sectors[Sec]; } else { - Layer = Layer1; Pad = Pad1; Sector = Sec; } From 3d74e878218b940240de2922392be3fd02545830 Mon Sep 17 00:00:00 2001 From: bogui56 Date: Fri, 13 Feb 2026 05:16:36 -0500 Subject: [PATCH 218/393] thanks for coderabbits help --- .../packages/trackbase/ClusterErrorPara.cc | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/offline/packages/trackbase/ClusterErrorPara.cc b/offline/packages/trackbase/ClusterErrorPara.cc index 965f1db09a..7e7ec8fca5 100644 --- a/offline/packages/trackbase/ClusterErrorPara.cc +++ b/offline/packages/trackbase/ClusterErrorPara.cc @@ -485,14 +485,15 @@ ClusterErrorPara::ClusterErrorPara(): f0{new TF1("f0", "pol1", 0, 10)} //_________________________________________________________________________________ ClusterErrorPara::error_t ClusterErrorPara::get_clusterv5_modified_error(TrkrCluster* cluster, double /*unused*/, TrkrDefs::cluskey key) { - bool is_data_reco; + recoConsts* rc = recoConsts::instance(); - if(rc->get_StringFlag("CDB_GLOBALTAG").find("MDC") != std::string::npos){ - is_data_reco = false; - } - else{ - // std::cout << "CHECK Setting reconstruction for data with CDB tag " << rc->get_StringFlag("CDB_GLOBALTAG") << std::endl; - is_data_reco = true; + bool is_data_reco = true; // default to data + if(rc->FlagExist("CDB_GLOBALTAG")) + { + if(rc->get_StringFlag("CDB_GLOBALTAG").find("MDC") != std::string::npos) + { + is_data_reco = false; + } } int layer = TrkrDefs::getLayer(key); @@ -593,7 +594,7 @@ ClusterErrorPara::error_t ClusterErrorPara::get_clusterv5_modified_error(TrkrClu } // zerror*=6; } - if (cluster->getZSize() >5){ + if (cluster->getZSize() >=5){ if(layer>=7&&layer<(7+16)){ zerror*=20; } @@ -604,17 +605,17 @@ ClusterErrorPara::error_t ClusterErrorPara::get_clusterv5_modified_error(TrkrClu zerror*=7; } } - TF1 ftpcR1("ftpcR1", "pol2", 0, 60); + static TF1 ftpcR1("ftpcR1", "pol2", 0, 60); ftpcR1.SetParameter(0, 3.206); ftpcR1.SetParameter(1, -0.252); ftpcR1.SetParameter(2, 0.007); - TF1 ftpcR2("ftpcR2", "pol2", 0, 60); + static TF1 ftpcR2("ftpcR2", "pol2", 0, 60); ftpcR2.SetParameter(0, 4.48); ftpcR2.SetParameter(1, -0.226); ftpcR2.SetParameter(2, 0.00362); - TF1 ftpcR3("ftpcR3", "pol2", 0, 60); + static TF1 ftpcR3("ftpcR3", "pol2", 0, 60); ftpcR3.SetParameter(0, 14.8112); ftpcR3.SetParameter(1, -0.577); ftpcR3.SetParameter(2, 0.00605); From 0ae0e709d54e7f8ae674289c036dff0f79a4778a Mon Sep 17 00:00:00 2001 From: bogui56 Date: Fri, 13 Feb 2026 06:37:34 -0500 Subject: [PATCH 219/393] more rabbits --- .../packages/trackbase/ClusterErrorPara.cc | 44 +++++++++++++++---- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/offline/packages/trackbase/ClusterErrorPara.cc b/offline/packages/trackbase/ClusterErrorPara.cc index 7e7ec8fca5..6baf4bc291 100644 --- a/offline/packages/trackbase/ClusterErrorPara.cc +++ b/offline/packages/trackbase/ClusterErrorPara.cc @@ -486,14 +486,18 @@ ClusterErrorPara::ClusterErrorPara(): f0{new TF1("f0", "pol1", 0, 10)} ClusterErrorPara::error_t ClusterErrorPara::get_clusterv5_modified_error(TrkrCluster* cluster, double /*unused*/, TrkrDefs::cluskey key) { - recoConsts* rc = recoConsts::instance(); - bool is_data_reco = true; // default to data - if(rc->FlagExist("CDB_GLOBALTAG")) - { - if(rc->get_StringFlag("CDB_GLOBALTAG").find("MDC") != std::string::npos) - { - is_data_reco = false; - } + static bool is_data_reco{true}; // default to data + static bool is_data_reco_set{false}; // default to data + if(!is_data_reco_set){ + recoConsts* rc = recoConsts::instance(); + if(rc->FlagExist("CDB_GLOBALTAG")) + { + if(rc->get_StringFlag("CDB_GLOBALTAG").find("MDC") != std::string::npos) + { + is_data_reco = false; + } + } + is_data_reco_set = true; } int layer = TrkrDefs::getLayer(key); @@ -605,6 +609,7 @@ ClusterErrorPara::error_t ClusterErrorPara::get_clusterv5_modified_error(TrkrClu zerror*=7; } } + /* static TF1 ftpcR1("ftpcR1", "pol2", 0, 60); ftpcR1.SetParameter(0, 3.206); ftpcR1.SetParameter(1, -0.252); @@ -642,6 +647,29 @@ ClusterErrorPara::error_t ClusterErrorPara::get_clusterv5_modified_error(TrkrClu } if(layer>=(7+32)&&layer<(7+48)){ zerror*= ftpcR3.Eval(layer); + } + */ + + // Inline pol2 evaluation: p0 + p1*x + p2*x^2 + auto pol2 = [](double x, double p0, double p1, double p2) { + return p0 + p1 * x + p2 * x * x; + }; + + if(layer>=7&&layer<(7+16)){ + phierror *= pol2(layer, 3.206, -0.252, 0.007); + } + if(layer>=(7+16)&&layer<(7+32)){ + phierror *= pol2(layer, 4.48, -0.226, 0.00362); + } + if(layer>=(7+32)&&layer<(7+48)){ + phierror *= pol2(layer, 14.8112, -0.577, 0.00605); + } + + if(layer>=(7+16)&&layer<(7+32)){ + zerror *= pol2(layer, 5.593, -0.2458, 0.00333455); + } + if(layer>=(7+32)&&layer<(7+48)){ + zerror *= pol2(layer, 5.6964, -0.21338, 0.002502); } } if (cluster->getPhiSize() >= 5) From ee1177c011476e8f7a8d535dd08ea25b3a5d04af Mon Sep 17 00:00:00 2001 From: bogui56 Date: Fri, 13 Feb 2026 06:53:17 -0500 Subject: [PATCH 220/393] and another rabbit --- offline/packages/trackbase/ClusterErrorPara.cc | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/offline/packages/trackbase/ClusterErrorPara.cc b/offline/packages/trackbase/ClusterErrorPara.cc index 6baf4bc291..f2df20c0f9 100644 --- a/offline/packages/trackbase/ClusterErrorPara.cc +++ b/offline/packages/trackbase/ClusterErrorPara.cc @@ -486,6 +486,18 @@ ClusterErrorPara::ClusterErrorPara(): f0{new TF1("f0", "pol1", 0, 10)} ClusterErrorPara::error_t ClusterErrorPara::get_clusterv5_modified_error(TrkrCluster* cluster, double /*unused*/, TrkrDefs::cluskey key) { + static const bool is_data_reco = []() { + recoConsts* rc = recoConsts::instance(); + if (rc->FlagExist("CDB_GLOBALTAG")) + { + if (rc->get_StringFlag("CDB_GLOBALTAG").find("MDC") != std::string::npos) + { + return false; + } + } + return true; // default to data + }(); + /* static bool is_data_reco{true}; // default to data static bool is_data_reco_set{false}; // default to data if(!is_data_reco_set){ @@ -499,7 +511,7 @@ ClusterErrorPara::error_t ClusterErrorPara::get_clusterv5_modified_error(TrkrClu } is_data_reco_set = true; } - + */ int layer = TrkrDefs::getLayer(key); double phierror = cluster->getRPhiError(); From e18101b7274693507df186e239b1d9751a6ea263 Mon Sep 17 00:00:00 2001 From: bogui56 Date: Fri, 13 Feb 2026 08:23:31 -0500 Subject: [PATCH 221/393] now to jenkins --- .../packages/trackbase/ClusterErrorPara.cc | 88 +++++++++++++------ 1 file changed, 59 insertions(+), 29 deletions(-) diff --git a/offline/packages/trackbase/ClusterErrorPara.cc b/offline/packages/trackbase/ClusterErrorPara.cc index f2df20c0f9..16fe2066b4 100644 --- a/offline/packages/trackbase/ClusterErrorPara.cc +++ b/offline/packages/trackbase/ClusterErrorPara.cc @@ -22,7 +22,37 @@ namespace } // namespace -ClusterErrorPara::ClusterErrorPara(): f0{new TF1("f0", "pol1", 0, 10)} +ClusterErrorPara::ClusterErrorPara(): + f0{new TF1("f0", "pol1", 0, 10)}, + f1{new TF1("f1", "pol2", 0, 10)}, + f2{new TF1("f2", "pol2", 0, 10)}, + f0fine{new TF1("f0fine", "pol2", 0, 20000)}, + f1fine{new TF1("f1fine", "pol3", 0, 20000)}, + f2fine{new TF1("f2fine", "pol5", 0, 20000)}, + f2fine2{new TF1("f2fine", "pol5", 0, 20000)}, + fz0{new TF1("fz0", "pol2", -2, 2)}, + fz1{new TF1("fz1", "pol4", -2, 2)}, + fz2{new TF1("fz2", "pol2", -2, 2)}, + fz0fine{new TF1("fz0fine", "pol2", 0, 20000)}, + fz1fine{new TF1("fz1fine", "pol3", 0, 20000)}, + fz2fine{new TF1("fz2fine", "pol5", 0, 20000)}, + fmm_55_2{new TF1("fmm_55_2", "pol2", -2, 2)}, + fmm_56_2{new TF1("fmm_56_2", "pol2", -2, 2)}, + fmm_3{new TF1("fmm_3", "pol2", -2, 2)}, + fadcz0{new TF1("fadcz0", "pol5", 0, 20000)}, + fadcz1{new TF1("fadcz1", "pol5", 0, 20000)}, + fadcz2{new TF1("fadcz2", "pol5", 0, 20000)}, + fadcz0fine{new TF1("fadcz0fine", "[0]+([1]/pow(x-[2],2))", 0, 20000)}, + fadcz1fine{new TF1("fadcz1fine", "[0]+([1]/pow(x-[2],2))", 0, 20000)}, + fadcz2fine{new TF1("fadcz2fine", "[0]+([1]/pow(x-[2],2))", 0, 20000)}, + fadcphi0{new TF1("fadcphi0", "pol4", 0, 20000)}, + fadcphi0fine{new TF1("fadcphi0fine", "pol2", 0, 20000)}, + fadcphi1{new TF1("fadcphi1", "pol4", 0, 20000)}, + fadcphi1fine{new TF1("fadcphi1fine", "pol4", 0, 20000)}, + fadcphi2{new TF1("fadcphi2", "pol5", 0, 20000)}, + fadcphi2fine1{new TF1("fadcphi2fine1", "pol4", 0, 20000)}, + fadcphi2fine2{new TF1("fadcphi2fine2", "pol1", 0, 20000)} + { /* ftpcR1 = new TF1("ftpcR1", "pol2", 0, 10); @@ -31,54 +61,54 @@ ClusterErrorPara::ClusterErrorPara(): f0{new TF1("f0", "pol1", 0, 10)} ftpcR1->SetParameter(2, 0.007); */ - f0 = new TF1("f0", "pol1", 0, 10); + // f0 = new TF1("f0", "pol1", 0, 10); f0->SetParameter(0, 0.0163943); f0->SetParameter(1, 0.0192931); - f1 = new TF1("f1", "pol2", 0, 10); + // f1 = new TF1("f1", "pol2", 0, 10); f1->SetParameter(0, 0.0119384); f1->SetParameter(1, 0.0253197); f1->SetParameter(2, 0.0404213); - f2 = new TF1("f2", "pol2", 0, 10); + // f2 = new TF1("f2", "pol2", 0, 10); f2->SetParameter(0, 0.0107316); f2->SetParameter(1, 0.0294968); f2->SetParameter(2, 0.0414098); // f2->SetParameter(3,9.75877); - fz0 = new TF1("fz0", "pol2", -2, 2); + // fz0 = new TF1("fz0", "pol2", -2, 2); fz0->SetParameter(0, 0.0520278); fz0->SetParameter(1, -0.00578699); fz0->SetParameter(2, 0.0156972); - fz1 = new TF1("fz1", "pol4", -2, 2); + // fz1 = new TF1("fz1", "pol4", -2, 2); fz1->SetParameter(0, 0.0383233); fz1->SetParameter(1, -0.00577128); fz1->SetParameter(2, 0.0770914); fz1->SetParameter(3, -0.0818139); fz1->SetParameter(4, 0.050305); - fz2 = new TF1("fz2", "pol2", -2, 2); + // fz2 = new TF1("fz2", "pol2", -2, 2); fz2->SetParameter(0, 0.0371611); fz2->SetParameter(1, -0.000694558); fz2->SetParameter(2, 0.0437917); - fmm_55_2 = new TF1("fmm_55_2", "pol2", -2, 2); + // fmm_55_2 = new TF1("fmm_55_2", "pol2", -2, 2); fmm_55_2->SetParameter(0, 0.0430592); fmm_55_2->SetParameter(1, -0.000177174); fmm_55_2->SetParameter(2, 0.0914288); - fmm_56_2 = new TF1("fmm_56_2", "pol2", -2, 2); + // fmm_56_2 = new TF1("fmm_56_2", "pol2", -2, 2); fmm_56_2->SetParameter(0, 0.00363897); fmm_56_2->SetParameter(1, 0.0109713); fmm_56_2->SetParameter(2, 0.032354); - fmm_3 = new TF1("fmm_3", "pol2", -2, 2); + // fmm_3 = new TF1("fmm_3", "pol2", -2, 2); fmm_3->SetParameter(0, 0.00305396); fmm_3->SetParameter(1, 0.00505814); fmm_3->SetParameter(2, 0.0395137); - fadcz0 = new TF1("fadcz0", "pol5", 0, 20000); + // fadcz0 = new TF1("fadcz0", "pol5", 0, 20000); fadcz0->SetParameter(0, 2.08854); fadcz0->SetParameter(1, -0.0536847); fadcz0->SetParameter(2, 0.000989393); @@ -86,7 +116,7 @@ ClusterErrorPara::ClusterErrorPara(): f0{new TF1("f0", "pol1", 0, 10)} fadcz0->SetParameter(4, 4.42178e-08); fadcz0->SetParameter(5, -7.79669e-11); - fadcz1 = new TF1("fadcz1", "pol5", 0, 20000); + // fadcz1 = new TF1("fadcz1", "pol5", 0, 20000); fadcz1->SetParameter(0, 2.35278); fadcz1->SetParameter(1, -0.0535903); fadcz1->SetParameter(2, 0.00088052); @@ -94,7 +124,7 @@ ClusterErrorPara::ClusterErrorPara(): f0{new TF1("f0", "pol1", 0, 10)} fadcz1->SetParameter(4, 3.35361e-08); fadcz1->SetParameter(5, -5.61371e-11); - fadcz2 = new TF1("fadcz2", "pol5", 0, 20000); + // fadcz2 = new TF1("fadcz2", "pol5", 0, 20000); fadcz2->SetParameter(0, 2.53191); fadcz2->SetParameter(1, -0.062285); fadcz2->SetParameter(2, 0.00103893); @@ -102,22 +132,22 @@ ClusterErrorPara::ClusterErrorPara(): f0{new TF1("f0", "pol1", 0, 10)} fadcz2->SetParameter(4, 3.9802e-08); fadcz2->SetParameter(5, -6.67137e-11); - fadcz0fine = new TF1("fadcz0fine", "[0]+([1]/pow(x-[2],2))", 0, 20000); + // fadcz0fine = new TF1("fadcz0fine", "[0]+([1]/pow(x-[2],2))", 0, 20000); fadcz0fine->SetParameter(0, 9.63983e-01); fadcz0fine->SetParameter(1, 2.68585e+01); fadcz0fine->SetParameter(2, -4.78664e+00); - fadcz1fine = new TF1("fadcz1fine", "[0]+([1]/pow(x-[2],2))", 0, 20000); + // fadcz1fine = new TF1("fadcz1fine", "[0]+([1]/pow(x-[2],2))", 0, 20000); fadcz1fine->SetParameter(0, 9.85546e-01); fadcz1fine->SetParameter(1, 1.12622e+02); fadcz1fine->SetParameter(2, -1.26552e+01); - fadcz2fine = new TF1("fadcz2fine", "[0]+([1]/pow(x-[2],2))", 0, 20000); + // fadcz2fine = new TF1("fadcz2fine", "[0]+([1]/pow(x-[2],2))", 0, 20000); fadcz2fine->SetParameter(0, 9.71125e-01); fadcz2fine->SetParameter(1, 6.67244e+01); fadcz2fine->SetParameter(2, -3.55034e+00); - fadcphi0 = new TF1("fadcphi0", "pol4", 0, 20000); + // fadcphi0 = new TF1("fadcphi0", "pol4", 0, 20000); fadcphi0->SetParameter(0, 1.79273); fadcphi0->SetParameter(1, -0.0306044); fadcphi0->SetParameter(2, 0.000355984); @@ -125,26 +155,26 @@ ClusterErrorPara::ClusterErrorPara(): f0{new TF1("f0", "pol1", 0, 10)} fadcphi0->SetParameter(4, 4.26161e-09); // fadcphi0->SetParameter(5,-4.22758e-11); - fadcphi0fine = new TF1("fadcphi0fine", "pol2", 0, 20000); + // fadcphi0fine = new TF1("fadcphi0fine", "pol2", 0, 20000); fadcphi0fine->SetParameter(0, 1.02625); fadcphi0fine->SetParameter(1, -0.00167294); fadcphi0fine->SetParameter(2, 2.2912e-5); - fadcphi1 = new TF1("fadcphi1", "pol4", 0, 20000); + // fadcphi1 = new TF1("fadcphi1", "pol4", 0, 20000); fadcphi1->SetParameter(0, 2.12873); fadcphi1->SetParameter(1, -0.0369604); fadcphi1->SetParameter(2, 0.00042828); fadcphi1->SetParameter(3, -2.3665e-06); fadcphi1->SetParameter(4, 4.87683e-09); - fadcphi1fine = new TF1("fadcphi1fine", "pol4", 0, 20000); + // fadcphi1fine = new TF1("fadcphi1fine", "pol4", 0, 20000); fadcphi1fine->SetParameter(0, 1.11749); fadcphi1fine->SetParameter(1, -0.00354277); fadcphi1fine->SetParameter(2, 5.60236e-05); fadcphi1fine->SetParameter(3, -4.46412e-07); fadcphi1fine->SetParameter(4, 1.22689e-09); - fadcphi2 = new TF1("fadcphi2", "pol5", 0, 20000); + // fadcphi2 = new TF1("fadcphi2", "pol5", 0, 20000); fadcphi2->SetParameter(0, 2.29); fadcphi2->SetParameter(1, -0.0474362); fadcphi2->SetParameter(2, 0.000717789); @@ -152,23 +182,23 @@ ClusterErrorPara::ClusterErrorPara(): f0{new TF1("f0", "pol1", 0, 10)} fadcphi2->SetParameter(4, 2.52007e-08); fadcphi2->SetParameter(5, -4.14747e-11); - fadcphi2fine1 = new TF1("fadcphi2fine1", "pol4", 0, 20000); + // fadcphi2fine1 = new TF1("fadcphi2fine1", "pol4", 0, 20000); fadcphi2fine1->SetParameter(0, 1.39404); fadcphi2fine1->SetParameter(1, -0.0202245); fadcphi2fine1->SetParameter(2, 0.000394666); fadcphi2fine1->SetParameter(3, -3.37831e-06); fadcphi2fine1->SetParameter(4, 1.05017e-08); - fadcphi2fine2 = new TF1("fadcphi2fine2", "pol1", 0, 20000); + // fadcphi2fine2 = new TF1("fadcphi2fine2", "pol1", 0, 20000); fadcphi2fine2->SetParameter(0, 0.997); fadcphi2fine2->SetParameter(1, 0.00047); - f0fine = new TF1("f0fine", "pol2", 0, 20000); + // f0fine = new TF1("f0fine", "pol2", 0, 20000); f0fine->SetParameter(0, 0.98611); f0fine->SetParameter(1, -0.169505); f0fine->SetParameter(2, 1.12907); - f1fine = new TF1("f1fine", "pol3", 0, 20000); + // f1fine = new TF1("f1fine", "pol3", 0, 20000); f1fine->SetParameter(0, 0.968625); f1fine->SetParameter(1, -0.38894); f1fine->SetParameter(2, 3.36493); @@ -181,7 +211,7 @@ ClusterErrorPara::ClusterErrorPara(): f0{new TF1("f0", "pol1", 0, 10)} f2fine->SetParameter(3,-42.4668); f2fine->SetParameter(4,43.6083); */ - f2fine = new TF1("f2fine", "pol5", 0, 20000); + // f2fine = new TF1("f2fine", "pol5", 0, 20000); f2fine->SetLineColor(kBlue); f2fine->SetParameter(0, 1.14119); f2fine->SetParameter(1, -2.81483); @@ -190,18 +220,18 @@ ClusterErrorPara::ClusterErrorPara(): f0{new TF1("f0", "pol1", 0, 10)} f2fine->SetParameter(4, 72.2359); f2fine->SetParameter(5, -20.3802); - fz0fine = new TF1("fz0fine", "pol2", 0, 20000); + // fz0fine = new TF1("fz0fine", "pol2", 0, 20000); fz0fine->SetParameter(0, 0.96933); fz0fine->SetParameter(1, -0.0458534); fz0fine->SetParameter(2, 0.231419); - fz1fine = new TF1("fz1fine", "pol3", 0, 20000); + // fz1fine = new TF1("fz1fine", "pol3", 0, 20000); fz1fine->SetParameter(0, 0.886262); fz1fine->SetParameter(1, -0.0818167); fz1fine->SetParameter(2, 0.805824); fz1fine->SetParameter(3, -0.425423); - fz2fine = new TF1("fz2fine", "pol5", 0, 20000); + // fz2fine = new TF1("fz2fine", "pol5", 0, 20000); fz2fine->SetLineColor(kBlue); fz2fine->SetParameter(0, 0.880153); fz2fine->SetParameter(1, 0.552461); From e11adf0566fe8cfa6db382c1499077fabf2d29cd Mon Sep 17 00:00:00 2001 From: bogui56 Date: Fri, 13 Feb 2026 10:02:26 -0500 Subject: [PATCH 222/393] jenkins 2 --- offline/packages/trackbase/ClusterErrorPara.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/offline/packages/trackbase/ClusterErrorPara.cc b/offline/packages/trackbase/ClusterErrorPara.cc index 16fe2066b4..5795f24347 100644 --- a/offline/packages/trackbase/ClusterErrorPara.cc +++ b/offline/packages/trackbase/ClusterErrorPara.cc @@ -733,9 +733,9 @@ ClusterErrorPara::error_t ClusterErrorPara::get_clusterv5_modified_error(TrkrClu if (cluster->getPhiSize() == 2){ phierror *= 2.25; } - if(layer==3||layer==4) + if((layer==3)||(layer==4)) phierror*=0.8; - if(layer==5||layer==6) + if((layer==5)||(layer==6)) phierror*=1.2; } From 4c4088d2cf901636843a4fdfb79731a895e818f4 Mon Sep 17 00:00:00 2001 From: bogui56 Date: Fri, 13 Feb 2026 10:56:30 -0500 Subject: [PATCH 223/393] clang 1 --- offline/packages/trackbase/ClusterErrorPara.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/offline/packages/trackbase/ClusterErrorPara.cc b/offline/packages/trackbase/ClusterErrorPara.cc index 5795f24347..1d6bf4b924 100644 --- a/offline/packages/trackbase/ClusterErrorPara.cc +++ b/offline/packages/trackbase/ClusterErrorPara.cc @@ -733,10 +733,12 @@ ClusterErrorPara::error_t ClusterErrorPara::get_clusterv5_modified_error(TrkrClu if (cluster->getPhiSize() == 2){ phierror *= 2.25; } - if((layer==3)||(layer==4)) + if((layer==3)||(layer==4)){ phierror*=0.8; - if((layer==5)||(layer==6)) + } + if((layer==5)||(layer==6)){ phierror*=1.2; + } } if (TrkrDefs::getTrkrId(key) == TrkrDefs::micromegasId){ From 0a41d07cf2e4fcfaa240632a2a7b4be646bbcfdc Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Fri, 13 Feb 2026 15:25:30 -0500 Subject: [PATCH 224/393] do not reference data for qa filling --- offline/framework/fun4allraw/TpcTimeFrameBuilder.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/framework/fun4allraw/TpcTimeFrameBuilder.cc b/offline/framework/fun4allraw/TpcTimeFrameBuilder.cc index 8eeca60c88..309e7bf391 100644 --- a/offline/framework/fun4allraw/TpcTimeFrameBuilder.cc +++ b/offline/framework/fun4allraw/TpcTimeFrameBuilder.cc @@ -713,7 +713,7 @@ int TpcTimeFrameBuilder::process_fee_data(unsigned int fee) } // valid packet - const uint16_t& pkt_length = data_buffer[0]; // this is indeed the number of 10-bit words + 5 in this packet + const uint16_t pkt_length = data_buffer[0]; // this is indeed the number of 10-bit words + 5 in this packet if (pkt_length > MAX_PACKET_LENGTH) { if (m_verbosity > 1) From f03fde5c4c04238a0c4d157abe7ec30dfc10a669 Mon Sep 17 00:00:00 2001 From: Ishan Goel Date: Sat, 14 Feb 2026 20:54:06 -0500 Subject: [PATCH 225/393] Finally fixed the bugs. --- offline/packages/tpc/TpcClusterizer.cc | 31 +++++++------------------- offline/packages/tpc/TpcClusterizer.h | 6 ----- 2 files changed, 8 insertions(+), 29 deletions(-) diff --git a/offline/packages/tpc/TpcClusterizer.cc b/offline/packages/tpc/TpcClusterizer.cc index e7fa17fa9e..85fdd151fc 100644 --- a/offline/packages/tpc/TpcClusterizer.cc +++ b/offline/packages/tpc/TpcClusterizer.cc @@ -1859,43 +1859,28 @@ void TpcClusterizer::makeChannelMask(hitMaskTpcSet &aMask, const std::string &db for (int i = 0; i < NChan; i++) { - int Layer = cdbttree->GetIntValue(i, "layer"); // Stored layer - int Sec = cdbttree->GetIntValue(i, "sector"); // Stored sector - int Side = cdbttree->GetIntValue(i, "side"); // 0 or 1 - int Pad0 = cdbttree->GetIntValue(i, "pad0"); // Simulation pad - int Pad1 = cdbttree->GetIntValue(i, "pad1"); // Data pad + int Layer = cdbttree->GetIntValue(i, "layer"); + int Sector = cdbttree->GetIntValue(i, "sector"); + int Side = cdbttree->GetIntValue(i, "side"); + int Pad = cdbttree->GetIntValue(i, "pad"); - if (Sec < 0 || Sec >= 12) + if (Sector < 0 || Sector >= 12) { if (Verbosity() > VERBOSITY_A_LOT) { - std::cout << PHWHERE << "WARNING: sector index " << Sec + std::cout << PHWHERE << "WARNING: sector index " << Sector << " out of range [0,11] in " << dbName << ", skipping channel " << i << std::endl; } continue; } - int Pad; - int Sector; - - if (!m_is_data) - { - Pad = Pad0; - Sector = mc_sectors[Sec]; - } - else - { - Pad = Pad1; - Sector = Sec; - } - - if (Layer < 7 || Layer > 48) + if (Layer < 7 || Layer > 54) { if (Verbosity() > VERBOSITY_A_LOT) { std::cout << PHWHERE << "WARNING: layer " << Layer - << " out of TPC range [7,48] in " << dbName + << " out of TPC range [7,54] in " << dbName << ", skipping channel " << i << std::endl; } continue; diff --git a/offline/packages/tpc/TpcClusterizer.h b/offline/packages/tpc/TpcClusterizer.h index 550301f813..dc325a05ca 100644 --- a/offline/packages/tpc/TpcClusterizer.h +++ b/offline/packages/tpc/TpcClusterizer.h @@ -75,11 +75,6 @@ class TpcClusterizer : public SubsysReco ClusHitsVerbosev1 *mClusHitsVerbose{nullptr}; - void SetIsData(bool flag) - { - m_is_data = flag; - } - void SetMaskChannelsFromFile() { m_maskFromFile = true; @@ -140,7 +135,6 @@ class TpcClusterizer : public SubsysReco bool m_maskDeadChannels {false}; bool m_maskHotChannels {false}; - bool m_is_data {false}; bool m_maskFromFile {false}; std::string m_deadChannelMapName; std::string m_hotChannelMapName; From 70b8bd9b95015b806190b0e29dd06b7e90da6d60 Mon Sep 17 00:00:00 2001 From: mchiu-bnl Date: Sat, 14 Feb 2026 21:05:25 -0500 Subject: [PATCH 226/393] changed running ped to 8 samples, added ped study, handle contamination to waveform due to events from prior crossings better --- offline/packages/mbd/MbdCalib.cc | 30 +++- offline/packages/mbd/MbdCalib.h | 49 +++--- offline/packages/mbd/MbdEvent.cc | 10 +- offline/packages/mbd/MbdSig.cc | 259 ++++++++++++++++++++----------- offline/packages/mbd/MbdSig.h | 24 +-- 5 files changed, 243 insertions(+), 129 deletions(-) diff --git a/offline/packages/mbd/MbdCalib.cc b/offline/packages/mbd/MbdCalib.cc index 3ebe139ffb..e8d10ba00a 100644 --- a/offline/packages/mbd/MbdCalib.cc +++ b/offline/packages/mbd/MbdCalib.cc @@ -2497,7 +2497,7 @@ void MbdCalib::Reset_Pileup() _pileup_p0err.fill(std::numeric_limits::quiet_NaN()); _pileup_p1err.fill(std::numeric_limits::quiet_NaN()); _pileup_p2err.fill(std::numeric_limits::quiet_NaN()); - _qfit_chi2ndf.fill(std::numeric_limits::quiet_NaN()); + _pileup_chi2ndf.fill(std::numeric_limits::quiet_NaN()); } void MbdCalib::Reset_Thresholds() @@ -2590,3 +2590,31 @@ TGraph *MbdCalib::get_lut_graph(const int pmtch, std::string_view type) return g; } + +void MbdCalib::set_pileup(const int ifeech, const int ipar, const float pval) +{ + int chtype = (ifeech / 8) % 2; // 0=T-ch, 1=Q-ch + + if (ipar==0) + { + _pileup_p0[ifeech] = pval; + } + else if (ipar==1) + { + _pileup_p1[ifeech] = pval; + } + else if (ipar==2) + { + _pileup_p2[ifeech] = pval; + } + else if (ipar==3 && chtype==0) + { + _pileup_p1err[ifeech] = pval; + } + else if (ipar==4 && chtype==0) + { + _pileup_p2err[ifeech] = pval; + } +} + + diff --git a/offline/packages/mbd/MbdCalib.h b/offline/packages/mbd/MbdCalib.h index 49129ac749..6f0a6e579a 100644 --- a/offline/packages/mbd/MbdCalib.h +++ b/offline/packages/mbd/MbdCalib.h @@ -38,6 +38,36 @@ class MbdCalib float get_pedrms(const int ifeech) const { return _pedsigma[ifeech]; } int get_sampmax(const int ifeech) const { return _sampmax[ifeech]; } int get_status(const int ifeech) const { return _mbdstatus[ifeech]; } + + float get_pileup(const int ifeech, const int ipar) const + { + int chtype = (ifeech / 8) % 2; // 0=T-ch, 1=Q-ch + + if (ipar==0) + { + return _pileup_p0[ifeech]; + } + else if (ipar==1) + { + return _pileup_p1[ifeech]; + } + else if (ipar==2) + { + return _pileup_p2[ifeech]; + } + else if (ipar==3 && chtype==0) + { + return _pileup_p1err[ifeech]; + } + else if (ipar==4 && chtype==0) + { + return _pileup_p2err[ifeech]; + } + + return std::numeric_limits::quiet_NaN(); + } + + float get_tcorr(const int ifeech, const int tdc) const { if (tdc<0) { @@ -86,24 +116,6 @@ class MbdCalib std::vector get_shape(const int ifeech) const { return _shape_y[ifeech]; } std::vector get_sherr(const int ifeech) const { return _sherr_yerr[ifeech]; } - float get_pileup(const int ifeech, const int ipar) const { - - if (ipar==0) - { - return _pileup_p0[ifeech]; - } - else if (ipar==1) - { - return _pileup_p1[ifeech]; - } - else if (ipar==2) - { - return _pileup_p2[ifeech]; - } - - return std::numeric_limits::quiet_NaN(); - } - float get_threshold(const int pmtch, const int rel_or_abs = 0); TGraph *get_lut_graph(const int pmtch, std::string_view type); @@ -111,6 +123,7 @@ class MbdCalib void set_sampmax(const int ifeech, const int val) { _sampmax[ifeech] = val; } void set_status(const int ifeech, const int val) { _mbdstatus[ifeech] = val; } void set_ped(const int ifeech, const float m, const float merr, const float s, const float serr); + void set_pileup(const int ifeech, const int ipar, const float val); void set_tt0(const int ipmt, const float t0) { _ttfit_t0mean[ipmt] = t0; } void set_tq0(const int ipmt, const float t0) { _tqfit_t0mean[ipmt] = t0; } diff --git a/offline/packages/mbd/MbdEvent.cc b/offline/packages/mbd/MbdEvent.cc index 72cecb212d..62a6c96fe7 100644 --- a/offline/packages/mbd/MbdEvent.cc +++ b/offline/packages/mbd/MbdEvent.cc @@ -380,6 +380,7 @@ int MbdEvent::End() for (auto & sig : _mbdsig) { + sig.WritePedvsEvent(); sig.WriteChi2Hist(); } @@ -1127,11 +1128,6 @@ int MbdEvent::Calculate(MbdPmtContainer *bbcpmts, MbdOut *bbcout, PHCompositeNod gausfit[iarm]->SetRange(hevt_bbct[iarm]->GetMean() - 5, hevt_bbct[iarm]->GetMean() + 5); */ - if ( hevt_bbct[iarm]->GetEntries()==0 )//chiu - { - std::cout << PHWHERE << " hevt_bbct EMPTY" << std::endl; - } - hevt_bbct[iarm]->Fit(gausfit[iarm], "BNQLR"); // m_bbct[iarm] = m_bbct[iarm] / m_bbcn[iarm]; @@ -1462,10 +1458,6 @@ int MbdEvent::CalcPedCalib() pedgaus->SetParameters(ampl,mean,sigma); pedgaus->SetRange(mean-(4*sigma), mean+(4*sigma)); - if ( hped0->GetEntries()==0 ) //chiu - { - std::cout << "HPED0 EMPTY" << std::endl; - } hped0->Fit(pedgaus,"RNQ"); mean = pedgaus->GetParameter(1); diff --git a/offline/packages/mbd/MbdSig.cc b/offline/packages/mbd/MbdSig.cc index 1118ba2e60..57a9615f13 100644 --- a/offline/packages/mbd/MbdSig.cc +++ b/offline/packages/mbd/MbdSig.cc @@ -49,12 +49,13 @@ void MbdSig::Init() gSubPulse->SetName(name); gSubPulse->GetHistogram()->SetXTitle("sample"); gSubPulse->GetHistogram()->SetYTitle("ADC"); + gSubPulse->GetHistogram()->SetTitle(name); hpulse = hRawPulse; // hpulse,gpulse point to raw by default gpulse = gRawPulse; // we switch to sub for default if ped is applied - //ped0stats = std::make_unique(100); // use the last 100 events for running pedestal - ped0stats = new MbdRunningStats(100); // use the last 100 events for running pedestal + ped0stats = new MbdRunningStats(8); // use the last 8 samples for running pedestal + name = "hPed0_"; name += _ch; hPed0 = new TH1F(name, name, 3000, -0.5, 2999.5); @@ -62,6 +63,15 @@ void MbdSig::Init() name = "hPedEvt_"; name += _ch; hPedEvt = new TH1F(name, name, 3000, -0.5, 2999.5); + if ( _pedstudyflag ) + { + gPedvsEvent = new TGraphErrors(); + name = "gpedvsevent"; + name += _ch; + gPedvsEvent->SetName(name); + gPedvsEvent->GetHistogram()->SetXTitle("evtnum"); + gPedvsEvent->GetHistogram()->SetYTitle("ped"); + } SetTemplateSize(900, 1000, -10., 20.); // SetTemplateSize(300,300,0.,15.); @@ -137,9 +147,9 @@ MbdSig::~MbdSig() delete hSubPulse; delete gRawPulse; delete gSubPulse; - delete hPed0; delete ped0stats; - // h2Template->Write(); + delete hPed0; + delete hPedEvt; delete h2Template; delete h2Residuals; delete hAmpl; @@ -149,6 +159,10 @@ MbdSig::~MbdSig() delete ped_fcn; delete ped_tail; delete h_chi2ndf; + if ( _pedstudyflag ) + { + delete gPedvsEvent; + } } void MbdSig::SetEventPed0PreSamp(const Int_t presample, const Int_t nsamps, const int max_samp) @@ -327,54 +341,123 @@ void MbdSig::Remove_Pileup() if ( (_ch/8)%2 == 0 ) // time ch { - float offset = _pileup_p0*gSubPulse->GetPointY(0); + double x_at_max = TMath::LocMax( 5, gSubPulse->GetY() ); - for (int isamp = 0; isamp < _nsamples; isamp++) + if ( x_at_max != 0 ) { - double x = gSubPulse->GetPointX(isamp); - double y = gSubPulse->GetPointY(isamp); + // time hit in prev crossing + if ( fit_pileup == nullptr ) + { + TString name = "fit_pileup"; name += _ch; + fit_pileup = new TF1(name,"pol3",0,16000); + for (int ipar=0; ipar<4; ipar++) + { + fit_pileup->SetParameter( ipar, _mbdcal->get_pileup(_ch,ipar+1) ); + } + } + + int sampmax = _mbdcal->get_sampmax(_ch); + double x_sampmax = gSubPulse->GetPointX(sampmax); + double y_sampmax = gSubPulse->GetPointY(sampmax); + double y_min6 = gSubPulse->GetPointY(sampmax-6); + + double offset = y_min6*fit_pileup->Eval(y_min6); + + hSubPulse->SetBinContent( sampmax + 1, y_sampmax - offset ); + gSubPulse->SetPoint( sampmax, x_sampmax, y_sampmax - offset ); - hSubPulse->SetBinContent( isamp + 1, y - offset ); - gSubPulse->SetPoint( isamp, x, y - offset ); } - } - else - { - if ( fit_pileup == nullptr ) + else { - TString name = "fit_pileup"; name += _ch; - fit_pileup = new TF1(name,"gaus",-0.1,4.1); - fit_pileup->SetLineColor(2); - } + // time hit in 2 crossings before + float offset = _pileup_p0*gSubPulse->GetPointY(0); - fit_pileup->SetRange(-0.1,4.1); - fit_pileup->SetParameters( _pileup_p0*gSubPulse->GetPointY(0), _pileup_p1, _pileup_p2 ); - - // fix par limits - double plow{0.}; - double phigh{0.}; - fit_pileup->GetParLimits(2,plow,phigh); - if ( phigh < _pileup_p2 ) - { - phigh = 2*_pileup_p2; - fit_pileup->SetParLimits(2,plow,phigh); + for (int isamp = 0; isamp < _nsamples; isamp++) + { + double x = gSubPulse->GetPointX(isamp); + double y = gSubPulse->GetPointY(isamp); + + hSubPulse->SetBinContent( isamp + 1, y - offset ); + gSubPulse->SetPoint( isamp, x, y - offset ); + } } + } + else // charge ch + { + double ymax = TMath::MaxElement( 5, gSubPulse->GetY() ); + double x_at_max = TMath::LocMax( 5, gSubPulse->GetY() ); - if ( _verbose ) + if ( x_at_max != 0 ) { - gSubPulse->Fit( fit_pileup, "R" ); - gSubPulse->Draw("ap"); - PadUpdate(); + // Fit a pulse in prev crossing + template_fcn->SetParameters(ymax, x_at_max); + template_fcn->SetRange(0, x_at_max+2.1); + + if (_verbose == 0) + { + //std::cout << PHWHERE << std::endl; + gSubPulse->Fit(template_fcn, "RNQ"); + } + else + { + std::cout << "pre-pileup " << _ch << "\t" << x_at_max << "\t" << ymax << std::endl; + gSubPulse->Fit(template_fcn, "R"); + gSubPulse->Draw("ap"); + gSubPulse->GetHistogram()->SetTitle(gSubPulse->GetName()); + gPad->SetGridy(1); + PadUpdate(); + //gSubPulse->Print("ALL"); + } + } else { - gSubPulse->Fit( fit_pileup, "RNQ" ); + // Fit the tail + if ( fit_pileup == nullptr ) + { + TString name = "fit_pileup"; name += _ch; + fit_pileup = new TF1(name,"gaus",-0.1,4.1); + fit_pileup->SetLineColor(2); + } + + fit_pileup->SetRange(-0.1,4.1); + fit_pileup->SetParameters( _pileup_p0*gSubPulse->GetPointY(0), _pileup_p1, _pileup_p2 ); + + // fix par limits + double plow{0.}; + double phigh{0.}; + fit_pileup->GetParLimits(2,plow,phigh); + if ( phigh < _pileup_p2 ) + { + phigh = 2*_pileup_p2; + fit_pileup->SetParLimits(2,plow,phigh); + } + + if ( _verbose ) + { + gSubPulse->Fit( fit_pileup, "R" ); + gSubPulse->Draw("ap"); + PadUpdate(); + } + else + { + gSubPulse->Fit( fit_pileup, "RNQ" ); + } } + // subtract pre-pulse for (int isamp = 0; isamp < _nsamples; isamp++) { - double bkg = fit_pileup->Eval(isamp); + double bkg = 0.; + if ( x_at_max != 0 ) + { + bkg = template_fcn->Eval(isamp); + } + else + { + bkg = fit_pileup->Eval(isamp); + } double x = gSubPulse->GetPointX(isamp); double y = gSubPulse->GetPointY(isamp); @@ -388,6 +471,7 @@ void MbdSig::Remove_Pileup() if ( _verbose ) { + std::cout << "pileup sub " << _ch << std::endl; gSubPulse->Draw("ap"); PadUpdate(); } @@ -428,6 +512,14 @@ void MbdSig::WritePedHist() hPed0->Write(); } +void MbdSig::WritePedvsEvent() +{ + if ( _pedstudyflag ) + { + gPedvsEvent->Write(); + } +} + void MbdSig::FillPed0(const Int_t sampmin, const Int_t sampmax) { Double_t x; @@ -438,13 +530,6 @@ void MbdSig::FillPed0(const Int_t sampmin, const Int_t sampmax) // gRawPulse->Print("all"); hPed0->Fill(y); - /* - // chiu taken out - ped0stats->Push( y ); - ped0 = ped0stats->Mean(); - ped0rms = ped0stats->RMS(); - */ - // std::cout << "ped0 " << _ch << " " << n << "\t" << ped0 << std::endl; // std::cout << "ped0 " << _ch << "\t" << ped0 << std::endl; } @@ -463,10 +548,10 @@ void MbdSig::FillPed0(const Double_t begin, const Double_t end) hPed0->Fill(y); /* - ped0stats->Push( y ); - ped0 = ped0stats->Mean(); - ped0rms = ped0stats->RMS(); - */ + ped0stats->Push( y ); + ped0 = ped0stats->Mean(); + ped0rms = ped0stats->RMS(); + */ // std::cout << "ped0 " << _ch << " " << n << "\t" << x << "\t" << y << std::endl; } @@ -548,9 +633,7 @@ void MbdSig::CalcEventPed0(const Double_t minpedx, const Double_t maxpedx) // If a prev event pileup is detected, return 1, otherwise, return 0 int MbdSig::CalcEventPed0_PreSamp(const int presample, const int nsamps) { - //std::cout << PHWHERE << std::endl; //chiu //_verbose = 100; - //ped0stats->Clear(); int status = 0; // assume no pileup @@ -608,11 +691,6 @@ int MbdSig::CalcEventPed0_PreSamp(const int presample, const int nsamps) ped_fcn->SetRange(minsamp-0.1,maxsamp+0.1); ped_fcn->SetParameter(0,1500.); - if ( gRawPulse->GetN()==0 )//chiu - { - std::cout << PHWHERE << " gRawPulse 0" << std::endl; - } - if ( _verbose ) { gRawPulse->Fit( ped_fcn, "RQ" ); @@ -630,18 +708,6 @@ int MbdSig::CalcEventPed0_PreSamp(const int presample, const int nsamps) //std::cout << PHWHERE << std::endl; gRawPulse->Fit( ped_fcn, "RNQ" ); - /* - double chi2ndf = ped_fcn->GetChisquare()/ped_fcn->GetNDF(); - if ( _pileupfile != nullptr && chi2ndf > 4.0 ) - { - *_pileupfile << "ped " << _ch << " mean " << mean << "\t"; - for ( int i=0; iGetN(); i++) - { - *_pileupfile << std::setw(6) << gRawPulse->GetPointY(i); - } - *_pileupfile << std::endl; - } - */ } double chi2 = ped_fcn->GetChisquare(); @@ -670,6 +736,28 @@ int MbdSig::CalcEventPed0_PreSamp(const int presample, const int nsamps) << "isamp " << isamp << "\t" << x << "\t" << y << std::endl; } } + + // study pedestal vs event + if ( _pedstudyflag ) + { + // running pedestal (replace with mean and meanerr for evt-by-evt) + double ped_evtnum = _evt_counter; + double ped_mean = ped0stats->Mean(); + double ped_meanerr = rms; + if ( ped0stats->Size()>1 ) + { + ped_meanerr = ped0stats->RMS()/std::sqrt(ped0stats->Size()); + } + else + { + ped_meanerr = _mbdcal->get_pedrms(_ch); + } + + int n = gPedvsEvent->GetN(); + gPedvsEvent->SetPoint(n,ped_evtnum,ped_mean); + gPedvsEvent->SetPointError(n,0,ped_meanerr); + } + } else { @@ -700,11 +788,18 @@ int MbdSig::CalcEventPed0_PreSamp(const int presample, const int nsamps) } } - // use straight mean for pedestal - // Could consider using fit to hPed0 to remove outliers - //rms = ped0stats->RMS(); - //Double_t mean = hPed0->GetMean(); - //Double_t rms = hPed0->GetRMS(); + // uncomment this to write out file with pileup waveforms + /* + if ( _pileupfile != nullptr ) + { + *_pileupfile << "ped " << _ch << " mean " << mean << "\t"; + for ( int i=0; iGetN(); i++) + { + *_pileupfile << std::setw(6) << gRawPulse->GetPointY(i); + } + *_pileupfile << std::endl; + } + */ } SetPed0(mean, rms); @@ -982,9 +1077,10 @@ void MbdSig::PadUpdate() const std::cout << PHWHERE << " PadUpdate\t_verbose = " << _verbose << std::endl; if ( _verbose>5 ) { + gPad->SetGridy(1); gPad->Modified(); gPad->Update(); - std::cout << _ch << " ? "; + std::cout << _evt_counter << ": " << _ch << " ? "; if ( _verbose>10 ) { std::string junk; @@ -1124,7 +1220,7 @@ Double_t MbdSig::TemplateFcn(const Double_t* x, const Double_t* par) // sampmax>0 means fit to the peak near sampmax int MbdSig::FitTemplate( const Int_t sampmax ) { - //std::cout << PHWHERE << std::endl; //chiu + //std::cout << PHWHERE << std::endl; /* if ( _evt_counter==2142 && _ch==92 ) { @@ -1265,7 +1361,7 @@ int MbdSig::FitTemplate( const Int_t sampmax ) // fit was out of time, likely from pileup, try two waveforms if ( (f_time<(sampmax-2.5) || f_time>sampmax) && (nsaturated<=3) ) { - //_verbose = 100; //chiu + //_verbose = 100; if ( _verbose ) { @@ -1310,15 +1406,6 @@ int MbdSig::FitTemplate( const Int_t sampmax ) } } - - /* chiu - if ( f_time<0. || f_time>9 ) - { - _verbose = 100; - f_time = _nsamples*0.5; // bad fit last time - } - */ - // refit with new range to exclude after-pulses template_fcn->SetParameters(ymax, x_at_max); //template_fcn->SetParameters( f_ampl, f_time ); @@ -1369,14 +1456,6 @@ int MbdSig::FitTemplate( const Int_t sampmax ) h_chi2ndf->Fill( f_chi2/f_ndf ); - /* - if ( (f_chi2/f_ndf) > 100. ) //chiu - { - std::cout << "very bad chi2ndf after refit " << f_ampl << "\t" << f_time << "\t" << f_chi2/f_ndf << std::endl; - //_verbose = 100; - } - */ - //if ( f_time<0 || f_time>30 ) //if ( (_ch==185||_ch==155||_ch==249) && (fabs(f_ampl) > 44000.) ) //double chi2 = template_fcn->GetChisquare(); diff --git a/offline/packages/mbd/MbdSig.h b/offline/packages/mbd/MbdSig.h index a3ee986c33..bafdd9339c 100644 --- a/offline/packages/mbd/MbdSig.h +++ b/offline/packages/mbd/MbdSig.h @@ -116,6 +116,7 @@ class MbdSig void SetMinMaxFitTime(const Double_t mintime, const Double_t maxtime); void WritePedHist(); + void WritePedvsEvent(); void WriteChi2Hist(); void DrawWaveform(); /// Draw Subtracted Waveform @@ -157,22 +158,22 @@ class MbdSig TGraphErrors *gpulse{nullptr}; //! /** for CalcPed0 */ - //std::unique_ptr ped0stats{nullptr}; //! - MbdRunningStats *ped0stats{nullptr}; //! - TH1 *hPed0{nullptr}; //! all events - TH1 *hPedEvt{nullptr}; //! evt-by-event pedestal + MbdRunningStats *ped0stats{nullptr}; //! running pedestal + TH1 *hPed0{nullptr}; //! all events + TH1 *hPedEvt{nullptr}; //! evt-by-event pedestal + TGraphErrors *gPedvsEvent{nullptr}; //! Keep track of pedestal vs evtnum TF1 *ped_fcn{nullptr}; - TF1 *ped_tail{nullptr}; //! tail of prev signal + TF1 *ped_tail{nullptr}; //! tail of prev signal Double_t ped0{0.}; //! Double_t ped0rms{0.}; //! - int use_ped0{0}; //! whether to apply ped0 - Int_t minped0samp{-9999}; //! min sample for event-by-event ped, inclusive - Int_t maxped0samp{-9999}; //! max sample for event-by-event ped, inclusive + int use_ped0{0}; //! whether to apply ped0 + Int_t minped0samp{-9999}; //! min sample for event-by-event ped, inclusive + Int_t maxped0samp{-9999}; //! max sample for event-by-event ped, inclusive Double_t minped0x{0.}; //! min x for event-by-event ped, inclusive Double_t maxped0x{0.}; //! max x for event-by-event ped, inclusive - Double_t ped_presamp{}; //! presamples for ped calculation - Double_t ped_presamp_nsamps{}; //! num of presamples for ped calculation - Double_t ped_presamp_maxsamp{-1}; //! a peak sample for ped calc (-1 = use max) + Double_t ped_presamp{}; //! presamples for ped calculation + Double_t ped_presamp_nsamps{}; //! num of presamples for ped calculation + Double_t ped_presamp_maxsamp{-1}; //! a peak sample for ped calc (-1 = use max) /** for time calibration */ // Double_t time_calib; @@ -200,6 +201,7 @@ class MbdSig TH1 *h_chi2ndf{nullptr}; //! for eval int _verbose{0}; + bool _pedstudyflag{false}; }; #endif // __MBDSIG_H__ From a07fca0c6093a63463753a2ebf05e00f9f4cc6de Mon Sep 17 00:00:00 2001 From: mchiu-bnl Date: Sat, 14 Feb 2026 22:03:39 -0500 Subject: [PATCH 227/393] check we don't underflow the sample number --- offline/packages/mbd/MbdSig.cc | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/offline/packages/mbd/MbdSig.cc b/offline/packages/mbd/MbdSig.cc index 57a9615f13..9b270e8ee8 100644 --- a/offline/packages/mbd/MbdSig.cc +++ b/offline/packages/mbd/MbdSig.cc @@ -357,15 +357,26 @@ void MbdSig::Remove_Pileup() } int sampmax = _mbdcal->get_sampmax(_ch); - double x_sampmax = gSubPulse->GetPointX(sampmax); - double y_sampmax = gSubPulse->GetPointY(sampmax); - double y_min6 = gSubPulse->GetPointY(sampmax-6); - - double offset = y_min6*fit_pileup->Eval(y_min6); + if ( (sampmax-6) > 0 ) + { + double x_sampmax = gSubPulse->GetPointX(sampmax); + double y_sampmax = gSubPulse->GetPointY(sampmax); + double y_min6 = gSubPulse->GetPointY(sampmax-6); - hSubPulse->SetBinContent( sampmax + 1, y_sampmax - offset ); - gSubPulse->SetPoint( sampmax, x_sampmax, y_sampmax - offset ); + double offset = y_min6*fit_pileup->Eval(y_min6); + hSubPulse->SetBinContent( sampmax + 1, y_sampmax - offset ); + gSubPulse->SetPoint( sampmax, x_sampmax, y_sampmax - offset ); + } + else + { + static int ctr = 0; + if ( ctr<10 ) + { + std::cout << PHWHERE << " WARNING, sampmax too early for time pileup corr" << std::endl; + ctr++; + } + } } else { From 4c4fdf492349cc2d3b8fd16219d98ffde2260131 Mon Sep 17 00:00:00 2001 From: Ishan Goel Date: Sun, 15 Feb 2026 09:16:56 -0500 Subject: [PATCH 228/393] Minor fix. --- offline/packages/tpc/TpcClusterizer.h | 1 - 1 file changed, 1 deletion(-) diff --git a/offline/packages/tpc/TpcClusterizer.h b/offline/packages/tpc/TpcClusterizer.h index dc325a05ca..84a58ceca6 100644 --- a/offline/packages/tpc/TpcClusterizer.h +++ b/offline/packages/tpc/TpcClusterizer.h @@ -95,7 +95,6 @@ class TpcClusterizer : public SubsysReco bool is_in_sector_boundary(int phibin, int sector, PHG4TpcGeom *layergeom) const; bool record_ClusHitsVerbose{false}; - int mc_sectors[12]{5, 4, 3, 2, 1, 0, 11, 10, 9, 8, 7, 6}; void makeChannelMask(hitMaskTpcSet& aMask, const std::string& dbName, const std::string& totalChannelsToMask); TrkrHitSetContainer *m_hits = nullptr; From 28b0d9537d0d92e071ac7dd56e17956977db4dad Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Mon, 16 Feb 2026 10:40:10 -0500 Subject: [PATCH 229/393] add 12 GeV jets to CreateFileList.pl --- offline/framework/frog/CreateFileList.pl | 30 ++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/offline/framework/frog/CreateFileList.pl b/offline/framework/frog/CreateFileList.pl index 1f71d9897f..bc8135ec6d 100755 --- a/offline/framework/frog/CreateFileList.pl +++ b/offline/framework/frog/CreateFileList.pl @@ -77,6 +77,7 @@ "36" => "JS pythia8 Jet ptmin = 5GeV", "37" => "hijing O+O (0-15fm)", "38" => "JS pythia8 Jet ptmin = 60GeV", + "39" => "JS pythia8 Jet ptmin = 12GeV" ); my %pileupdesc = ( @@ -975,6 +976,35 @@ $pileupstring = $pp_pileupstring; &commonfiletypes(); } + elsif ($prodtype == 39) + { + $embedok = 1; + $filenamestring = "pythia8_Jet12"; + if (! defined $nopileup) + { + if (defined $embed) + { + if ($embed eq "pau") + { + $filenamestring = sprintf("%s_sHijing_pAu_0_10fm%s",$filenamestring, $pAu_pileupstring); + } + elsif ($embed eq "central") + { + $filenamestring = sprintf("%s_sHijing_0_488fm%s",$filenamestring, $AuAu_pileupstring); + } + else + { + $filenamestring = sprintf("%s_sHijing_0_20fm%s",$filenamestring, $AuAu_pileupstring); + } + } + else + { + $filenamestring = sprintf("%s%s",$filenamestring,$pp_pileupstring); + } + } + $pileupstring = $pp_pileupstring; + &commonfiletypes(); + } else { From c700d69e3c66f9874bccded3051adbeb6ef1e162 Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Tue, 17 Feb 2026 11:29:36 -0500 Subject: [PATCH 230/393] QVecDefs - Update Centrality Binning - Use 1% centrality bins instead of 10% - Allows to capture the finer variations of calibraitons that change on the order of 1% centrality --- calibrations/sepd/sepd_eventplanecalib/QVecDefs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h b/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h index ebbeec8743..8b9e4ebcd7 100644 --- a/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h +++ b/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h @@ -8,7 +8,7 @@ namespace QVecShared { - static constexpr size_t CENT_BINS = 8; + static constexpr size_t CENT_BINS = 80; static constexpr std::array HARMONICS = {2, 3, 4}; static constexpr int SEPD_CHANNELS = 744; From 388a36bd33b650b008df3a3f56c70d3ec345bb9c Mon Sep 17 00:00:00 2001 From: mchiu-bnl Date: Tue, 17 Feb 2026 13:00:51 -0500 Subject: [PATCH 231/393] add method to get MbdEvent, bypass calibration existence check during calibration runs --- offline/packages/mbd/MbdEvent.cc | 2 +- offline/packages/mbd/MbdReco.h | 2 ++ offline/packages/mbd/MbdSig.cc | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/offline/packages/mbd/MbdEvent.cc b/offline/packages/mbd/MbdEvent.cc index 62a6c96fe7..e5ae966587 100644 --- a/offline/packages/mbd/MbdEvent.cc +++ b/offline/packages/mbd/MbdEvent.cc @@ -156,7 +156,7 @@ int MbdEvent::InitRun() { // Download calibrations int status = _mbdcal->Download_All(); - if ( status == -1 ) + if ( status < 0 && _calpass==0 ) // only abort for normal processing { return Fun4AllReturnCodes::ABORTRUN; } diff --git a/offline/packages/mbd/MbdReco.h b/offline/packages/mbd/MbdReco.h index eced3b89e9..13a635d602 100644 --- a/offline/packages/mbd/MbdReco.h +++ b/offline/packages/mbd/MbdReco.h @@ -40,6 +40,8 @@ class MbdReco : public SubsysReco void SetProcChargeCh(const bool s) { _always_process_charge = s; } void SetMbdTrigOnly(const int m) { _mbdonly = m; } + MbdEvent* GetMbdEvent() { return m_mbdevent.get(); } + private: int createNodes(PHCompositeNode *topNode); int getNodes(PHCompositeNode *topNode); diff --git a/offline/packages/mbd/MbdSig.cc b/offline/packages/mbd/MbdSig.cc index 9b270e8ee8..155d731719 100644 --- a/offline/packages/mbd/MbdSig.cc +++ b/offline/packages/mbd/MbdSig.cc @@ -311,11 +311,13 @@ void MbdSig::SetXY(const Float_t* x, const Float_t* y, const int invert) Remove_Pileup(); } + /* if ( _verbose && _ch==9 ) { std::cout << "SetXY: ch " << _ch << std::endl; gSubPulse->Print("ALL"); } + */ } _evt_counter++; From 09e88174e67d2280cc6f3c24d625cf746782791c Mon Sep 17 00:00:00 2001 From: "Blair D. Seidlitz" Date: Tue, 17 Feb 2026 18:26:09 -0500 Subject: [PATCH 232/393] Adding exit for missing calibrations --- offline/packages/CaloReco/CaloTowerCalib.cc | 16 +++++++++++ offline/packages/CaloReco/CaloTowerCalib.h | 30 ++++++++++++++++++++ offline/packages/CaloReco/CaloTowerStatus.cc | 12 +++++++- offline/packages/CaloReco/CaloTowerStatus.h | 19 +++++++++++++ 4 files changed, 76 insertions(+), 1 deletion(-) diff --git a/offline/packages/CaloReco/CaloTowerCalib.cc b/offline/packages/CaloReco/CaloTowerCalib.cc index cbd13ce4ed..ecc7da5157 100644 --- a/offline/packages/CaloReco/CaloTowerCalib.cc +++ b/offline/packages/CaloReco/CaloTowerCalib.cc @@ -114,6 +114,12 @@ int CaloTowerCalib::InitRun(PHCompositeNode *topNode) } else { + if (m_doAbortNoEnergyCalib) + { + std::cout << "CaloTowerCalib::InitRun: No energy calibration found for " << m_calibName << " and abort mode is set. Exiting." << std::endl; + gSystem->Exit(1); + } + calibdir = CDBInterface::instance()->getUrl(default_time_independent_calib); if (calibdir.empty()) @@ -151,6 +157,11 @@ int CaloTowerCalib::InitRun(PHCompositeNode *topNode) } else { + if (m_doAbortNoTimeCalib) + { + std::cout << "CaloTowerCalib::InitRun: No time calibration found for " << m_calibName_time << " and abort mode is set. Exiting." << std::endl; + gSystem->Exit(1); + } m_dotimecalib = false; if (Verbosity() > 0) { @@ -185,6 +196,11 @@ int CaloTowerCalib::InitRun(PHCompositeNode *topNode) } else { + if (m_doAbortNoZSCalib) + { + std::cout << "CaloTowerCalib::InitRun: No ZS cross calibration found for " << m_calibName_ZScrosscalib << " and abort mode is set. Exiting." << std::endl; + gSystem->Exit(1); + } m_doZScrosscalib = false; if (Verbosity() > 0) { diff --git a/offline/packages/CaloReco/CaloTowerCalib.h b/offline/packages/CaloReco/CaloTowerCalib.h index 06ae6148a1..10a3f2771f 100644 --- a/offline/packages/CaloReco/CaloTowerCalib.h +++ b/offline/packages/CaloReco/CaloTowerCalib.h @@ -92,6 +92,32 @@ class CaloTowerCalib : public SubsysReco } } + void set_doAbortNoEnergyCalib(bool doAbort = true) + { + m_doAbortNoEnergyCalib = doAbort; + return; + } + + void set_doAbortNoTimeCalib(bool doAbort = true) + { + m_doAbortNoTimeCalib = doAbort; + return; + } + + void set_doAbortNoZSCalib(bool doAbort = true) + { + m_doAbortNoZSCalib = doAbort; + return; + } + + void set_doAbortMissingCalib(bool doAbort = true) + { + m_doAbortNoEnergyCalib = doAbort; + m_doAbortNoTimeCalib = doAbort; + m_doAbortNoZSCalib = doAbort; + return; + } + void set_use_TowerInfov2(bool use) { m_use_TowerInfov2 = use; } private: @@ -125,6 +151,10 @@ class CaloTowerCalib : public SubsysReco std::string m_directURL_ZScrosscalib = ""; bool m_doZScrosscalib = true; + bool m_doAbortNoEnergyCalib{false}; + bool m_doAbortNoTimeCalib{false}; + bool m_doAbortNoZSCalib{false}; + CDBTTree *cdbttree = nullptr; CDBTTree *cdbttree_time = nullptr; CDBTTree *cdbttree_ZScrosscalib = nullptr; diff --git a/offline/packages/CaloReco/CaloTowerStatus.cc b/offline/packages/CaloReco/CaloTowerStatus.cc index c5401edb33..0445dc9374 100644 --- a/offline/packages/CaloReco/CaloTowerStatus.cc +++ b/offline/packages/CaloReco/CaloTowerStatus.cc @@ -105,6 +105,11 @@ int CaloTowerStatus::InitRun(PHCompositeNode *topNode) } else { + if (m_doAbortNoChi2) + { + std::cout << "CaloTowerStatus::InitRun: No chi2 calibration found for " << m_calibName_chi2 << " and abort mode is set. Exiting." << std::endl; + gSystem->Exit(1); + } m_doHotChi2 = false; if (Verbosity() > 0) { @@ -135,6 +140,11 @@ int CaloTowerStatus::InitRun(PHCompositeNode *topNode) } else { + if (m_doAbortNoTime) + { + std::cout << "CaloTowerStatus::InitRun: No time calibration found for " << m_calibName_time << " and abort mode is set. Exiting." << std::endl; + gSystem->Exit(1); + } m_doTime = false; if (Verbosity() > 1) { @@ -164,7 +174,7 @@ int CaloTowerStatus::InitRun(PHCompositeNode *topNode) { if (m_doAbortNoHotMap) { - std::cout << "CaloTowerStatus::InitRun: No hot map.. exiting" << std::endl; + std::cout << "CaloTowerStatus::InitRun: No hot map found for " << m_calibName_hotMap << " and abort mode is set. Exiting." << std::endl; gSystem->Exit(1); } if (use_directURL_hotMap) diff --git a/offline/packages/CaloReco/CaloTowerStatus.h b/offline/packages/CaloReco/CaloTowerStatus.h index 8c6f20ecf6..1c961c9f0e 100644 --- a/offline/packages/CaloReco/CaloTowerStatus.h +++ b/offline/packages/CaloReco/CaloTowerStatus.h @@ -91,6 +91,23 @@ class CaloTowerStatus : public SubsysReco m_doAbortNoHotMap = status; return; } + void set_doAbortNoTime(bool status = true) + { + m_doAbortNoTime = status; + return; + } + void set_doAbortNoChi2(bool status = true) + { + m_doAbortNoChi2 = status; + return; + } + void set_doAbortMissingCalib(bool status = true) + { + m_doAbortNoHotMap = status; + m_doAbortNoTime = status; + m_doAbortNoChi2 = status; + return; + } private: TowerInfoContainer *m_raw_towers{nullptr}; @@ -103,6 +120,8 @@ class CaloTowerStatus : public SubsysReco bool m_doTime{true}; bool m_doHotMap{true}; bool m_doAbortNoHotMap{false}; + bool m_doAbortNoTime{false}; + bool m_doAbortNoChi2{false}; CaloTowerDefs::DetectorSystem m_dettype{CaloTowerDefs::DETECTOR_INVALID}; From ccc849875701d1dbb6a9869763296a5a3babdfcc Mon Sep 17 00:00:00 2001 From: Nikhil Kumar Date: Wed, 18 Feb 2026 10:49:41 -0500 Subject: [PATCH 233/393] inital commit of calostatusskimmer This module will be used to skim on the status of packets. Specifically we are re-using the not instrumented status bit to flag empty and missing packets. The number of these status bits are counted, and if they pass a certain number of towers, the event will be aborted. --- .../CaloStatusSkimmer/CaloStatusSkimmer.cc | 190 ++++++++++++++++++ .../CaloStatusSkimmer/CaloStatusSkimmer.h | 80 ++++++++ .../Skimmers/CaloStatusSkimmer/Makefile.am | 43 ++++ .../Skimmers/CaloStatusSkimmer/autogen.sh | 8 + .../Skimmers/CaloStatusSkimmer/configure.ac | 16 ++ 5 files changed, 337 insertions(+) create mode 100644 offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc create mode 100644 offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h create mode 100644 offline/packages/Skimmers/CaloStatusSkimmer/Makefile.am create mode 100644 offline/packages/Skimmers/CaloStatusSkimmer/autogen.sh create mode 100644 offline/packages/Skimmers/CaloStatusSkimmer/configure.ac diff --git a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc new file mode 100644 index 0000000000..726afac8e1 --- /dev/null +++ b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc @@ -0,0 +1,190 @@ +#include "CaloStatusSkimmer.h" + +#include +#include + +#include +#include +#include + +// Tower stuff +#include +#include +// #include +#include +#include + +// ROOT stuff +#include +#include +#include +#include +#include + +// for cluster vertex correction +#include +#include +#include +#include +#include +#include +#include + + +//____________________________________________________________________________.. +CaloStatusSkimmer::CaloStatusSkimmer(const std::string &name) : SubsysReco(name) +{ + n_eventcounter = 0; + n_skimcounter = 0; + n_notowernodecounter = 0; + std::cout << "CaloStatusSkimmer::CaloStatusSkimmer(const std::string &name) Calling ctor" << std::endl; +} + +//____________________________________________________________________________.. +CaloStatusSkimmer::~CaloStatusSkimmer() +{ + //std::cout << "CaloStatusSkimmer::~CaloStatusSkimmer() Calling dtor" << std::endl; +} + +//____________________________________________________________________________.. +int CaloStatusSkimmer::Init(PHCompositeNode *topNode) +{ + std::cout << "CaloStatusSkimmer::Init(PHCompositeNode *topNode) Initializing" << std::endl; + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) +{ + n_eventcounter++; + if (b_do_skim_EMCal) + { + TowerInfoContainer *towers = findNode::getClass(topNode, "TOWERS_CEMC"); + if (!towers) + { + n_notowernodecounter++; + std::cout << PHWHERE << "calostatuscheck::process_event: missing TOWERS_CEMC\n"; + return Fun4AllReturnCodes::ABORTEVENT; + } + const UInt_t ntowers = towers->size(); + uint16_t notinstr_count = 0; + for (UInt_t ch = 0; ch < ntowers; ++ch) + { + TowerInfo *tower = towers->get_tower_at_channel(ch); + if (tower->get_isNotInstr()) + { + ++notinstr_count; + } + } + if (notinstr_count >= m_EMC_skim_threshold) + { + n_skimcounter++; + return Fun4AllReturnCodes::ABORTEVENT; + } + } + + if (b_do_skim_HCal) + { + TowerInfoContainer *hcalin_towers = findNode::getClass(topNode, "TOWERS_HCALIN"); + TowerInfoContainer *hcalout_towers = findNode::getClass(topNode, "TOWERS_HCALOUT"); + if (!hcalin_towers || !hcalout_towers) + { + n_notowernodecounter++; + std::cout << PHWHERE << "calostatuscheck::process_event: missing TOWERS_HCALIN or TOWERS_HCALOUT\n"; + return Fun4AllReturnCodes::ABORTEVENT;// do I want ABORTPROCESSING or just ABORTEVENT here? ABORTPROCESSING will stop the entire job, while ABORTEVENT will just skip this event and continue with the next one. + } + + const UInt_t ntowers_hcalin = hcalin_towers->size(); + uint16_t notinstr_count_hcalin = 0; + for (UInt_t ch = 0; ch < ntowers_hcalin; ++ch) + { + TowerInfo *tower_in = hcalin_towers->get_tower_at_channel(ch); + if (tower_in->get_isNotInstr()) + { + ++notinstr_count_hcalin; + } + } + + const UInt_t ntowers_hcalout = hcalout_towers->size(); + uint16_t notinstr_count_hcalout = 0; + for (UInt_t ch = 0; ch < ntowers_hcalout; ++ch) + { + TowerInfo *tower_out = hcalout_towers->get_tower_at_channel(ch); + if (tower_out->get_isNotInstr()) + { + ++notinstr_count_hcalout; + } + } + + if (notinstr_count_hcalin >= m_HCal_skim_threshold || notinstr_count_hcalout >= m_HCal_skim_threshold) + { + n_skimcounter++; + return Fun4AllReturnCodes::ABORTEVENT; + } + } + + if (b_do_skim_sEPD) + { + TowerInfoContainer *sepd_towers = findNode::getClass(topNode, "TOWERS_SEPD"); + if (!sepd_towers) + { + n_notowernodecounter++; + std::cout << PHWHERE << "calostatuscheck::process_event: missing TOWERS_SEPD\n"; + return Fun4AllReturnCodes::ABORTEVENT; + } + const UInt_t ntowers = sepd_towers->size(); + uint16_t notinstr_count = 0; + for (UInt_t ch = 0; ch < ntowers; ++ch) + { + TowerInfo *tower = sepd_towers->get_tower_at_channel(ch); + if (tower->get_isNotInstr()) + { + ++notinstr_count; + } + } + if (notinstr_count >= m_sEPD_skim_threshold) + { + n_skimcounter++; + return Fun4AllReturnCodes::ABORTEVENT; + } + } + + if (b_do_skim_ZDC) + { + TowerInfoContainer *zdc_towers = findNode::getClass(topNode, "TOWERS_ZDC"); + if (!zdc_towers) + { + n_notowernodecounter++; + std::cout << PHWHERE << "calostatuscheck::process_event: missing TOWERS_ZDC\n"; + return Fun4AllReturnCodes::ABORTEVENT; + } + const UInt_t ntowers = zdc_towers->size(); + uint16_t notinstr_count = 0; + for (UInt_t ch = 0; ch < ntowers; ++ch) + { + TowerInfo *tower = zdc_towers->get_tower_at_channel(ch); + if (tower->get_isNotInstr()) + { + ++notinstr_count; + } + } + if (notinstr_count >= m_ZDC_skim_threshold) + { + n_skimcounter++; + return Fun4AllReturnCodes::ABORTEVENT; + } + } + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int CaloStatusSkimmer::End(PHCompositeNode *topNode) +{ + std::cout << "CaloStatusSkimmer::End(PHCompositeNode *topNode) This is the End..." << std::endl; + std::cout << "Total events processed: " << n_eventcounter << std::endl; + std::cout << "Total events skimmed: " << n_skimcounter << std::endl; + std::cout << "Total events with missing tower nodes: " << n_notowernodecounter << std::endl; + + return Fun4AllReturnCodes::EVENT_OK; +} diff --git a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h new file mode 100644 index 0000000000..965a42abe2 --- /dev/null +++ b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h @@ -0,0 +1,80 @@ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef CALOSTATUSSKIMMER_H +#define CALOSTATUSSKIMMER_H + +#include + +#include +#include +#include +#include + +class PHCompositeNode; + +class CaloStatusSkimmer : public SubsysReco +{ +public: + CaloStatusSkimmer(const std::string &name = "CaloStatusSkimmer"); + + ~CaloStatusSkimmer() override; + + /** Called during initialization. + Typically this is where you can book histograms, and e.g. + register them to Fun4AllServer (so they can be output to file + using Fun4AllServer::dumpHistos() method). + */ + int Init(PHCompositeNode *topNode) override; + + /** Called for each event. + This is where you do the real work. + */ + int process_event(PHCompositeNode *topNode) override; + + /// Called at the end of all processing. + int End(PHCompositeNode *topNode) override; + + void do_skim_EMCal(bool do_skim, uint16_t threshold) + { + b_do_skim_EMCal = do_skim; + m_EMC_skim_threshold = threshold; + } + + void do_skim_HCal(bool do_skim, uint16_t threshold) + { + b_do_skim_HCal = do_skim; + m_HCal_skim_threshold = threshold; + } + + void do_skim_sEPD(bool do_skim, uint16_t threshold) + { + b_do_skim_sEPD = do_skim; + m_sEPD_skim_threshold = threshold; + } + + void do_skim_ZDC(bool do_skim, uint16_t threshold) + { + b_do_skim_ZDC = do_skim; + m_ZDC_skim_threshold = threshold; + } + +private: + + uint32_t n_eventcounter{0}; + uint32_t n_skimcounter{0}; + uint32_t n_notowernodecounter{0}; + + bool b_do_skim_EMCal{false}; + uint16_t m_EMC_skim_threshold{192}; // skim if nchannels >= this many not-instrumented(empty/missing pckt) channels in EMCal + + bool b_do_skim_HCal{false}; + uint16_t m_HCal_skim_threshold{192}; // skim if nchannels >= this many not-instrumented(empty/missing pckt) channels in HCal + + bool b_do_skim_sEPD{false}; + uint16_t m_sEPD_skim_threshold{192}; // skim if nchannels >= this many not-instrumented(empty/missing pckt) channels in sEPD + + bool b_do_skim_ZDC{false}; + uint16_t m_ZDC_skim_threshold{192}; // skim if nchannels >= this many not-instrumented(empty/missing pckt) channels in ZDC +}; + +#endif // CALOSTATUSSKIMMER_H diff --git a/offline/packages/Skimmers/CaloStatusSkimmer/Makefile.am b/offline/packages/Skimmers/CaloStatusSkimmer/Makefile.am new file mode 100644 index 0000000000..9f496c8587 --- /dev/null +++ b/offline/packages/Skimmers/CaloStatusSkimmer/Makefile.am @@ -0,0 +1,43 @@ +AUTOMAKE_OPTIONS = foreign + +AM_CPPFLAGS = \ + -I$(includedir) \ + -I$(OFFLINE_MAIN)/include \ + -isystem$(ROOTSYS)/include + +AM_LDFLAGS = \ + -L$(libdir) \ + -L$(OFFLINE_MAIN)/lib \ + -L$(OFFLINE_MAIN)/lib64 + +pkginclude_HEADERS = \ + CaloStatusSkimmer.h + +lib_LTLIBRARIES = \ + libCaloStatusSkimmer.la + +libCaloStatusSkimmer_la_SOURCES = \ + CaloStatusSkimmer.cc + +libCaloStatusSkimmer_la_LIBADD = \ + -lphool \ + -lSubsysReco \ + -lcalo_io + +BUILT_SOURCES = testexternals.cc + +noinst_PROGRAMS = \ + testexternals + +testexternals_SOURCES = testexternals.cc +testexternals_LDADD = libCaloStatusSkimmer.la + +testexternals.cc: + echo "//*** this is a generated file. Do not commit, do not edit" > $@ + echo "int main()" >> $@ + echo "{" >> $@ + echo " return 0;" >> $@ + echo "}" >> $@ + +clean-local: + rm -f $(BUILT_SOURCES) diff --git a/offline/packages/Skimmers/CaloStatusSkimmer/autogen.sh b/offline/packages/Skimmers/CaloStatusSkimmer/autogen.sh new file mode 100644 index 0000000000..dea267bbfd --- /dev/null +++ b/offline/packages/Skimmers/CaloStatusSkimmer/autogen.sh @@ -0,0 +1,8 @@ +#!/bin/sh +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +(cd $srcdir; aclocal -I ${OFFLINE_MAIN}/share;\ +libtoolize --force; automake -a --add-missing; autoconf) + +$srcdir/configure "$@" diff --git a/offline/packages/Skimmers/CaloStatusSkimmer/configure.ac b/offline/packages/Skimmers/CaloStatusSkimmer/configure.ac new file mode 100644 index 0000000000..3934c375e4 --- /dev/null +++ b/offline/packages/Skimmers/CaloStatusSkimmer/configure.ac @@ -0,0 +1,16 @@ +AC_INIT(calostatusskimmer,[1.00]) +AC_CONFIG_SRCDIR([configure.ac]) + +AM_INIT_AUTOMAKE +AC_PROG_CXX(CC g++) + +LT_INIT([disable-static]) + +dnl no point in suppressing warnings people should +dnl at least see them, so here we go for g++: -Wall +if test $ac_cv_prog_gxx = yes; then + CXXFLAGS="$CXXFLAGS -Wall -Werror" +fi + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT From 0a29355aa458408d1454b959fdebe49a319810fd Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Wed, 18 Feb 2026 12:06:51 -0500 Subject: [PATCH 234/393] CaloTowerStatus - Add inputNode Option - Allow for providing a generic input node name that does not strictly adhere to the suffix from `m_detector`. - By default this is empty and does not override existing functionality unless explicity set via the `set_inputNode` method. --- offline/packages/CaloReco/CaloTowerStatus.cc | 4 ++++ offline/packages/CaloReco/CaloTowerStatus.h | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/offline/packages/CaloReco/CaloTowerStatus.cc b/offline/packages/CaloReco/CaloTowerStatus.cc index 0445dc9374..a98a64a27b 100644 --- a/offline/packages/CaloReco/CaloTowerStatus.cc +++ b/offline/packages/CaloReco/CaloTowerStatus.cc @@ -309,6 +309,10 @@ int CaloTowerStatus::process_event(PHCompositeNode * /*topNode*/) void CaloTowerStatus::CreateNodeTree(PHCompositeNode *topNode) { std::string RawTowerNodeName = m_inputNodePrefix + m_detector; + if (!m_inputNode.empty()) + { + RawTowerNodeName = m_inputNode; + } m_raw_towers = findNode::getClass(topNode, RawTowerNodeName); if (!m_raw_towers) { diff --git a/offline/packages/CaloReco/CaloTowerStatus.h b/offline/packages/CaloReco/CaloTowerStatus.h index 1c961c9f0e..646116368d 100644 --- a/offline/packages/CaloReco/CaloTowerStatus.h +++ b/offline/packages/CaloReco/CaloTowerStatus.h @@ -38,6 +38,11 @@ class CaloTowerStatus : public SubsysReco m_inputNodePrefix = name; return; } + void set_inputNode(const std::string &name) + { + m_inputNode = name; + return; + } void set_badChi2_const_threshold(float threshold) { badChi2_treshold_const = threshold; @@ -134,6 +139,7 @@ class CaloTowerStatus : public SubsysReco std::string m_fieldname_z_score; std::string m_calibName_hotMap; std::string m_inputNodePrefix{"TOWERS_"}; + std::string m_inputNode; std::string m_directURL_time; std::string m_directURL_hotMap; From 95d02470facc7e52b179c09194fbb2da01a3ea7f Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Wed, 18 Feb 2026 13:04:57 -0500 Subject: [PATCH 235/393] residual calculator compiles --- .../trackbase_historic/TrackAnalysisUtils.cc | 126 +++++++++++++++--- .../trackbase_historic/TrackAnalysisUtils.h | 8 ++ 2 files changed, 116 insertions(+), 18 deletions(-) diff --git a/offline/packages/trackbase_historic/TrackAnalysisUtils.cc b/offline/packages/trackbase_historic/TrackAnalysisUtils.cc index 744949c8fe..6dd4085a9b 100644 --- a/offline/packages/trackbase_historic/TrackAnalysisUtils.cc +++ b/offline/packages/trackbase_historic/TrackAnalysisUtils.cc @@ -1,12 +1,11 @@ #include "TrackAnalysisUtils.h" +#include #include #include #include #include -#include -#include #include "SvtxTrack.h" #include "TrackSeed.h" @@ -98,7 +97,7 @@ namespace TrackAnalysisUtils float thickness_per_region[4]) { auto clusterKeys = get_cluster_keys(track->get_tpc_seed()); - + std::vector dedxlist; for (unsigned long cluster_key : clusterKeys) { @@ -150,14 +149,14 @@ namespace TrackAnalysisUtils { betacorr = 4; } - if(track->get_crossing() < SHRT_MAX) + if (track->get_crossing() < SHRT_MAX) { - double z_crossing_corrected = - TpcClusterZCrossingCorrection::correctZ(cglob.z(), - TpcDefs::getSide(cluster_key), track->get_crossing()); + double z_crossing_corrected = + TpcClusterZCrossingCorrection::correctZ(cglob.z(), + TpcDefs::getSide(cluster_key), track->get_crossing()); - double maxz = tgeometry->get_max_driftlength() + tgeometry->get_CM_halfwidth(); - adc /= (1 - ((maxz - abs(z_crossing_corrected)) * 0.50 / maxz)); + double maxz = tgeometry->get_max_driftlength() + tgeometry->get_CM_halfwidth(); + adc /= (1 - ((maxz - abs(z_crossing_corrected)) * 0.50 / maxz)); } adc /= thickness; adc *= alphacorr; @@ -178,7 +177,7 @@ namespace TrackAnalysisUtils return sumdedx; } - TrackAnalysisUtils::DCAPair get_dca(SvtxTrack *track, + TrackAnalysisUtils::DCAPair get_dca(SvtxTrack* track, GlobalVertex* vertex) { Acts::Vector3 vpos(vertex->get_x(), @@ -201,9 +200,8 @@ namespace TrackAnalysisUtils vertexCov(i, j) = vertex->get_error(i, j); } } - - Acts::ActsSquareMatrix<3> rotCov = rot * (posCov+vertexCov) * rot_T; + Acts::ActsSquareMatrix<3> rotCov = rot * (posCov + vertexCov) * rot_T; dca.first.second = sqrt(rotCov(0, 0)); dca.second.second = sqrt(rotCov(2, 2)); @@ -274,12 +272,12 @@ namespace TrackAnalysisUtils std::vector get_cluster_keys(TrackSeed* seed) { std::vector out; - - if (seed) - { - std::copy(seed->begin_cluster_keys(), seed->end_cluster_keys(), std::back_inserter(out)); - } - + + if (seed) + { + std::copy(seed->begin_cluster_keys(), seed->end_cluster_keys(), std::back_inserter(out)); + } + return out; } @@ -296,4 +294,96 @@ namespace TrackAnalysisUtils return out; } + std::pair + get_residual(TrkrDefs::cluskey& ckey, SvtxTrack* track, + TpcGlobalPositionWrapper& globalWrapper, TrkrClusterContainer* clustermap, + ActsGeometry* geometry, TpcClusterMover& mover) + { + auto* cluster = clustermap->findCluster(ckey); + std::vector> global_raw; + for (const auto& key : get_cluster_keys(track)) + { + auto* clus = clustermap->findCluster(ckey); + + // Fully correct the cluster positions for the crossing and all distortions + Acts::Vector3 global = globalWrapper.getGlobalPositionDistortionCorrected(key, clus, track->get_crossing()); + + // add the global positions to a vector to give to the cluster mover + global_raw.emplace_back(key, global); + } + + auto global_moved = mover.processTrack(global_raw); + // loop over global vectors and get this cluster + Acts::Vector3 clusglob(0, 0, 0); + for (const auto& pair : global_raw) + { + auto thiskey = pair.first; + clusglob = pair.second; + if (thiskey == ckey) + { + break; + } + } + + Acts::Vector3 clusglob_moved(0, 0, 0); + for (const auto& pair : global_moved) + { + auto thiskey = pair.first; + clusglob_moved = pair.second; + if (thiskey == ckey) + { + break; + } + } + SvtxTrackState* state = nullptr; + for (auto state_iter = track->begin_states(); + state_iter != track->end_states(); + ++state_iter) + { + SvtxTrackState* tstate = state_iter->second; + auto stateckey = tstate->get_cluskey(); + if (stateckey == ckey) + { + state = tstate; + break; + } + } + Surface surf = geometry->maps().getSurface(ckey, cluster); + Surface surf_ideal = geometry->maps().getSurface(ckey, cluster); // Unchanged by distortion corrections + // if this is a TPC cluster, the crossing correction may have moved it across the central membrane, check the surface + auto trkrid = TrkrDefs::getTrkrId(ckey); + if (trkrid == TrkrDefs::tpcId) + { + TrkrDefs::hitsetkey hitsetkey = TrkrDefs::getHitSetKeyFromClusKey(ckey); + TrkrDefs::subsurfkey new_subsurfkey = 0; + surf = geometry->get_tpc_surface_from_coords(hitsetkey, clusglob_moved, new_subsurfkey); + } + + auto loc = geometry->getLocalCoords(ckey, cluster, track->get_crossing()); + // in this case we get local coords from transform of corrected global coords + clusglob_moved *= Acts::UnitConstants::cm; // we want mm for transformations + Acts::Vector3 normal = surf->normal(geometry->geometry().getGeoContext(), + Acts::Vector3(1, 1, 1), Acts::Vector3(1, 1, 1)); + auto local = surf->globalToLocal(geometry->geometry().getGeoContext(), + clusglob_moved, normal); + if (local.ok()) + { + loc = local.value() / Acts::UnitConstants::cm; + } + else + { + // otherwise take the manual calculation for the TPC + // doing it this way just avoids the bounds check that occurs in the surface class method + Acts::Vector3 loct = surf->transform(geometry->geometry().getGeoContext()).inverse() * clusglob_moved; // global is in mm + loct /= Acts::UnitConstants::cm; + + loc(0) = loct(0); + loc(1) = loct(1); + } + clusglob_moved /= Acts::UnitConstants::cm; // we want cm for the tree + Acts::Vector2 stateloc(state->get_localX(), state->get_localY()); + Acts::Vector3 stateglob(state->get_x(), state->get_y(), state->get_z()); + return std::make_pair(stateloc - loc, stateglob - clusglob_moved); + } + } // namespace TrackAnalysisUtils diff --git a/offline/packages/trackbase_historic/TrackAnalysisUtils.h b/offline/packages/trackbase_historic/TrackAnalysisUtils.h index 168ff7495f..a7d9fbd1ed 100644 --- a/offline/packages/trackbase_historic/TrackAnalysisUtils.h +++ b/offline/packages/trackbase_historic/TrackAnalysisUtils.h @@ -4,6 +4,9 @@ #include #include +#include +#include +#include #include class SvtxTrack; @@ -32,6 +35,11 @@ namespace TrackAnalysisUtils float calc_dedx(TrackSeed* tpcseed, TrkrClusterContainer* clustermap, ActsGeometry* tgeometry, float thickness_per_region[4]); + std::pair + get_residual(TrkrDefs::cluskey& ckey, SvtxTrack* track, + TpcGlobalPositionWrapper& globalWrapper, TrkrClusterContainer* clustermap, + ActsGeometry* geometry, TpcClusterMover& mover); + }; // namespace TrackAnalysisUtils #endif From e13a266985d582cff23dfca2d8525a99a25833d2 Mon Sep 17 00:00:00 2001 From: bkimelman Date: Wed, 18 Feb 2026 13:34:35 -0500 Subject: [PATCH 236/393] Added toggles for storting CM phi distortions as r*dPhi vs dPhi (default is now in dPhi) --- .../packages/tpccalib/TpcCentralMembraneMatching.cc | 13 ++++++++----- .../packages/tpccalib/TpcCentralMembraneMatching.h | 5 +++++ offline/packages/tpccalib/TpcLaminationFitting.h | 4 ++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/offline/packages/tpccalib/TpcCentralMembraneMatching.cc b/offline/packages/tpccalib/TpcCentralMembraneMatching.cc index 2cb4942994..ec488c9d68 100644 --- a/offline/packages/tpccalib/TpcCentralMembraneMatching.cc +++ b/offline/packages/tpccalib/TpcCentralMembraneMatching.cc @@ -2351,7 +2351,8 @@ int TpcCentralMembraneMatching::process_event(PHCompositeNode* topNode) } */ m_dcc_out->m_hDRint[s]->SetBinContent(i, j, gr_dR[s]->Interpolate(phiVal,RVal)); - m_dcc_out->m_hDPint[s]->SetBinContent(i, j, RVal*gr_dPhi[s]->Interpolate(phiVal,RVal)); + if(!m_phiHist_in_rad) m_dcc_out->m_hDPint[s]->SetBinContent(i, j, RVal*gr_dPhi[s]->Interpolate(phiVal,RVal)); + else m_dcc_out->m_hDPint[s]->SetBinContent(i, j, gr_dPhi[s]->Interpolate(phiVal,RVal)); } } } @@ -2660,13 +2661,15 @@ int TpcCentralMembraneMatching::End(PHCompositeNode* /*topNode*/) if(den > 0.0) { m_dcc_out_aggregated->m_hDRint[s]->SetBinContent(i, j, num_dR / den); - m_dcc_out_aggregated->m_hDPint[s]->SetBinContent(i, j, RVal*(num_dPhi / den)); + if(!m_phiHist_in_rad) m_dcc_out_aggregated->m_hDPint[s]->SetBinContent(i, j, RVal*(num_dPhi / den)); + else m_dcc_out_aggregated->m_hDPint[s]->SetBinContent(i, j, num_dPhi / den); } } else { m_dcc_out_aggregated->m_hDRint[s]->SetBinContent(i, j, gr_dR_toInterp[s]->Interpolate(phiVal,RVal)); - m_dcc_out_aggregated->m_hDPint[s]->SetBinContent(i, j, RVal*gr_dPhi_toInterp[s]->Interpolate(phiVal,RVal)); + if(!m_phiHist_in_rad) m_dcc_out_aggregated->m_hDPint[s]->SetBinContent(i, j, RVal*gr_dPhi_toInterp[s]->Interpolate(phiVal,RVal)); + else m_dcc_out_aggregated->m_hDPint[s]->SetBinContent(i, j, gr_dPhi_toInterp[s]->Interpolate(phiVal,RVal)); } } } @@ -2873,8 +2876,8 @@ int TpcCentralMembraneMatching::GetNodes(PHCompositeNode* topNode) std::cout << "TpcCentralMembraneMatching::GetNodes - creating TpcDistortionCorrectionContainer in node " << dcc_out_node_name << std::endl; m_dcc_out = new TpcDistortionCorrectionContainer; m_dcc_out->m_dimensions = 2; - m_dcc_out->m_phi_hist_in_radians = false; - m_dcc_out->m_interpolate_z = true; + m_dcc_out->m_phi_hist_in_radians = m_phiHist_in_rad; + m_dcc_out->m_interpolate_z = false; auto* node = new PHDataNode(m_dcc_out, dcc_out_node_name); runNode->addNode(node); } diff --git a/offline/packages/tpccalib/TpcCentralMembraneMatching.h b/offline/packages/tpccalib/TpcCentralMembraneMatching.h index cdde093629..2bc44e5ede 100644 --- a/offline/packages/tpccalib/TpcCentralMembraneMatching.h +++ b/offline/packages/tpccalib/TpcCentralMembraneMatching.h @@ -124,6 +124,9 @@ class TpcCentralMembraneMatching : public SubsysReco m_stripePatternFile = stripePatternFile; } + void set_phiHistInRad(bool rad){ m_phiHist_in_rad = rad; } + + // void set_laminationFile(const std::string& filename) //{ // m_lamfilename = filename; @@ -156,6 +159,8 @@ class TpcCentralMembraneMatching : public SubsysReco //! tpc distortion correction utility class TpcDistortionCorrection m_distortionCorrection; + bool m_phiHist_in_rad{true}; + //! CMFlashClusterContainer *m_corrected_CMcluster_map{nullptr}; LaserClusterContainer *m_corrected_CMcluster_map{nullptr}; CMFlashDifferenceContainer *m_cm_flash_diffs{nullptr}; diff --git a/offline/packages/tpccalib/TpcLaminationFitting.h b/offline/packages/tpccalib/TpcLaminationFitting.h index 561a9ab199..d9aeddf75e 100644 --- a/offline/packages/tpccalib/TpcLaminationFitting.h +++ b/offline/packages/tpccalib/TpcLaminationFitting.h @@ -50,6 +50,8 @@ class TpcLaminationFitting : public SubsysReco void set_ppMode(bool mode){ ppMode = mode; } + void set_phiHistInRad(bool rad){ m_phiHist_in_rad = rad; } + void set_fieldOff(bool fieldOff){ m_fieldOff = fieldOff; } void set_grid_dimensions(int phibins, int rbins); @@ -121,6 +123,8 @@ class TpcLaminationFitting : public SubsysReco //std::map m_run_ZDC_map_pp; //std::map m_run_ZDC_map_auau; + bool m_phiHist_in_rad{true}; + std::string m_stripePatternFile = "/sphenix/u/bkimelman/CMStripePattern.root"; bool m_fieldOff{false}; From 5951a0eb5ca60474018159618df5b8ec84041721 Mon Sep 17 00:00:00 2001 From: bkimelman Date: Wed, 18 Feb 2026 13:54:02 -0500 Subject: [PATCH 237/393] Added lamination fitting cc that was missed in previous commit --- offline/packages/tpccalib/TpcLaminationFitting.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/offline/packages/tpccalib/TpcLaminationFitting.cc b/offline/packages/tpccalib/TpcLaminationFitting.cc index 1b3062dd7d..617e9a9387 100644 --- a/offline/packages/tpccalib/TpcLaminationFitting.cc +++ b/offline/packages/tpccalib/TpcLaminationFitting.cc @@ -745,7 +745,7 @@ int TpcLaminationFitting::InterpolatePhiDistortions() int phiBin = phiDistortionLamination[s]->GetXaxis()->FindBin(phi); if(m_fieldOff) { - m_laminationOffset[l][s] = m_fLamination[l][s]->GetParameter(0); + m_laminationOffset[l][s] = m_fLamination[l][s]->GetParameter(0); m_fLamination[l][s]->SetParameter(1, 0.0); } else @@ -753,7 +753,8 @@ int TpcLaminationFitting::InterpolatePhiDistortions() //m_fLamination[l][s]->SetParameter(3, -1.0*m_laminationOffset[l][s]); m_fLamination[l][s]->SetParameter(3, 0.0); } - double phiDistortion = R * m_fLamination[l][s]->Integral(phiDistortionLamination[s]->GetYaxis()->GetBinLowEdge(i), phiDistortionLamination[s]->GetYaxis()->GetBinLowEdge(i + 1)) / (phiDistortionLamination[s]->GetYaxis()->GetBinLowEdge(i + 1) - phiDistortionLamination[s]->GetYaxis()->GetBinLowEdge(i)); + double phiDistortion = m_fLamination[l][s]->Integral(phiDistortionLamination[s]->GetYaxis()->GetBinLowEdge(i), phiDistortionLamination[s]->GetYaxis()->GetBinLowEdge(i + 1)) / (phiDistortionLamination[s]->GetYaxis()->GetBinLowEdge(i + 1) - phiDistortionLamination[s]->GetYaxis()->GetBinLowEdge(i)); + if(!m_phiHist_in_rad) phiDistortion *= R; if(m_fieldOff) { m_fLamination[l][s]->SetParameter(1, m_laminationIdeal[l][s]); From 347fb4fe1cbaf2a47da87ae2bb97faf31d8ec315 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Wed, 18 Feb 2026 14:38:41 -0500 Subject: [PATCH 238/393] fix stupid bug --- offline/packages/trackbase_historic/TrackAnalysisUtils.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/offline/packages/trackbase_historic/TrackAnalysisUtils.cc b/offline/packages/trackbase_historic/TrackAnalysisUtils.cc index 6dd4085a9b..42450833d2 100644 --- a/offline/packages/trackbase_historic/TrackAnalysisUtils.cc +++ b/offline/packages/trackbase_historic/TrackAnalysisUtils.cc @@ -303,16 +303,16 @@ namespace TrackAnalysisUtils std::vector> global_raw; for (const auto& key : get_cluster_keys(track)) { - auto* clus = clustermap->findCluster(ckey); + auto* clus = clustermap->findCluster(key); // Fully correct the cluster positions for the crossing and all distortions Acts::Vector3 global = globalWrapper.getGlobalPositionDistortionCorrected(key, clus, track->get_crossing()); - // add the global positions to a vector to give to the cluster mover global_raw.emplace_back(key, global); } auto global_moved = mover.processTrack(global_raw); + // loop over global vectors and get this cluster Acts::Vector3 clusglob(0, 0, 0); for (const auto& pair : global_raw) @@ -380,9 +380,10 @@ namespace TrackAnalysisUtils loc(0) = loct(0); loc(1) = loct(1); } - clusglob_moved /= Acts::UnitConstants::cm; // we want cm for the tree + clusglob_moved /= Acts::UnitConstants::cm; // we want cm for the tree Acts::Vector2 stateloc(state->get_localX(), state->get_localY()); Acts::Vector3 stateglob(state->get_x(), state->get_y(), state->get_z()); + return std::make_pair(stateloc - loc, stateglob - clusglob_moved); } From d98db224ce7c2c63e127168be998e1dbfd110ab2 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Wed, 18 Feb 2026 15:22:38 -0500 Subject: [PATCH 239/393] consolidate --- .../trackbase_historic/TrackAnalysisUtils.cc | 18 +++++++++++++++--- .../trackbase_historic/TrackAnalysisUtils.h | 5 ++--- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/offline/packages/trackbase_historic/TrackAnalysisUtils.cc b/offline/packages/trackbase_historic/TrackAnalysisUtils.cc index 42450833d2..c4c80fb77e 100644 --- a/offline/packages/trackbase_historic/TrackAnalysisUtils.cc +++ b/offline/packages/trackbase_historic/TrackAnalysisUtils.cc @@ -1,11 +1,16 @@ #include "TrackAnalysisUtils.h" #include + +#include +#include + #include #include #include #include +#include #include "SvtxTrack.h" #include "TrackSeed.h" @@ -295,10 +300,17 @@ namespace TrackAnalysisUtils } std::pair - get_residual(TrkrDefs::cluskey& ckey, SvtxTrack* track, - TpcGlobalPositionWrapper& globalWrapper, TrkrClusterContainer* clustermap, - ActsGeometry* geometry, TpcClusterMover& mover) + get_residual(TrkrDefs::cluskey& ckey, SvtxTrack* track, TrkrClusterContainer* clustermap, + PHCompositeNode* topNode) { + TpcGlobalPositionWrapper globalWrapper; + globalWrapper.loadNodes(topNode); + globalWrapper.set_suppressCrossing(true); + TpcClusterMover mover; + auto* tpccellgeo = findNode::getClass(topNode, "TPCGEOMCONTAINER"); + mover.initialize_geometry(tpccellgeo); + mover.set_verbosity(0); + auto* geometry = findNode::getClass(topNode, "ActsGeometry"); auto* cluster = clustermap->findCluster(ckey); std::vector> global_raw; for (const auto& key : get_cluster_keys(track)) diff --git a/offline/packages/trackbase_historic/TrackAnalysisUtils.h b/offline/packages/trackbase_historic/TrackAnalysisUtils.h index a7d9fbd1ed..1756a8c751 100644 --- a/offline/packages/trackbase_historic/TrackAnalysisUtils.h +++ b/offline/packages/trackbase_historic/TrackAnalysisUtils.h @@ -36,9 +36,8 @@ namespace TrackAnalysisUtils float thickness_per_region[4]); std::pair - get_residual(TrkrDefs::cluskey& ckey, SvtxTrack* track, - TpcGlobalPositionWrapper& globalWrapper, TrkrClusterContainer* clustermap, - ActsGeometry* geometry, TpcClusterMover& mover); + get_residual(TrkrDefs::cluskey& ckey, SvtxTrack* track, TrkrClusterContainer* clustermap, + PHCompositeNode *topNode); }; // namespace TrackAnalysisUtils From 5e828de02b47122896da7daf8de64278598e5d52 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Wed, 18 Feb 2026 15:22:54 -0500 Subject: [PATCH 240/393] clang-format --- offline/packages/trackbase_historic/TrackAnalysisUtils.cc | 4 ++-- offline/packages/trackbase_historic/TrackAnalysisUtils.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/offline/packages/trackbase_historic/TrackAnalysisUtils.cc b/offline/packages/trackbase_historic/TrackAnalysisUtils.cc index c4c80fb77e..cacbab9aec 100644 --- a/offline/packages/trackbase_historic/TrackAnalysisUtils.cc +++ b/offline/packages/trackbase_historic/TrackAnalysisUtils.cc @@ -301,7 +301,7 @@ namespace TrackAnalysisUtils std::pair get_residual(TrkrDefs::cluskey& ckey, SvtxTrack* track, TrkrClusterContainer* clustermap, - PHCompositeNode* topNode) + PHCompositeNode* topNode) { TpcGlobalPositionWrapper globalWrapper; globalWrapper.loadNodes(topNode); @@ -392,7 +392,7 @@ namespace TrackAnalysisUtils loc(0) = loct(0); loc(1) = loct(1); } - clusglob_moved /= Acts::UnitConstants::cm; // we want cm for the tree + clusglob_moved /= Acts::UnitConstants::cm; // we want cm for the tree Acts::Vector2 stateloc(state->get_localX(), state->get_localY()); Acts::Vector3 stateglob(state->get_x(), state->get_y(), state->get_z()); diff --git a/offline/packages/trackbase_historic/TrackAnalysisUtils.h b/offline/packages/trackbase_historic/TrackAnalysisUtils.h index 1756a8c751..00cca752f7 100644 --- a/offline/packages/trackbase_historic/TrackAnalysisUtils.h +++ b/offline/packages/trackbase_historic/TrackAnalysisUtils.h @@ -37,7 +37,7 @@ namespace TrackAnalysisUtils std::pair get_residual(TrkrDefs::cluskey& ckey, SvtxTrack* track, TrkrClusterContainer* clustermap, - PHCompositeNode *topNode); + PHCompositeNode* topNode); }; // namespace TrackAnalysisUtils From 806959a9a6598ac5abf9146373659c4e72bbe2b6 Mon Sep 17 00:00:00 2001 From: Hugo Pereira Da Costa Date: Wed, 18 Feb 2026 15:01:55 -0500 Subject: [PATCH 241/393] Moved filtering sourcelinks to a separate methods, so that one can remove measurements whether or not we run the direct navigations. GetSurfaceVect, as used for the direct navigation, does not apply any filtering. --- offline/packages/trackreco/PHActsTrkFitter.cc | 72 ++++++++----------- offline/packages/trackreco/PHActsTrkFitter.h | 26 +++---- 2 files changed, 45 insertions(+), 53 deletions(-) diff --git a/offline/packages/trackreco/PHActsTrkFitter.cc b/offline/packages/trackreco/PHActsTrkFitter.cc index 5a92307b81..d361af240a 100644 --- a/offline/packages/trackreco/PHActsTrkFitter.cc +++ b/offline/packages/trackreco/PHActsTrkFitter.cc @@ -543,17 +543,21 @@ void PHActsTrkFitter::loopTracks(Acts::Logging::Level logLevel) continue; } + // filter sourcelinks to remove detectors that we don't want to include in the fit + sourceLinks = filterSourceLinks( sourceLinks ); + if (sourceLinks.empty()) { continue; } /// If using directed navigation, collect surface list to navigate - SurfacePtrVec surfaces_tmp; SurfacePtrVec surfaces; if (m_fitSiliconMMs || m_directNavigation) { - sourceLinks = getSurfaceVector(sourceLinks, surfaces_tmp); + + // get surfaces matching source links + const auto surfaces_tmp = getSurfaceVector(sourceLinks); // skip if there is no surfaces if (surfaces_tmp.empty()) @@ -960,59 +964,45 @@ ActsTrackFittingAlgorithm::TrackFitterResult PHActsTrkFitter::fitTrack( } //__________________________________________________________________________________ -SourceLinkVec PHActsTrkFitter::getSurfaceVector(const SourceLinkVec& sourceLinks, SurfacePtrVec& surfaces) const +SourceLinkVec PHActsTrkFitter::filterSourceLinks(const SourceLinkVec& sourceLinks ) const { - SourceLinkVec siliconMMSls; - - // if(Verbosity() > 1) - // std::cout << "Sorting " << sourceLinks.size() << " SLs" << std::endl; - + SourceLinkVec filtered; for (const auto& sl : sourceLinks) { const ActsSourceLink asl = sl.get(); - if (Verbosity() > 1) - { - std::cout << "SL available on : " << asl.geometryId() << std::endl; - } - const auto* const surf = m_tGeometry->geometry().tGeometry->findSurface(asl.geometryId()); - if (m_fitSiliconMMs) - { - // skip TPC surfaces - if (m_tGeometry->maps().isTpcSurface(surf)) - { - continue; - } - // also skip micromegas surfaces if not used - if (m_tGeometry->maps().isMicromegasSurface(surf) && !m_useMicromegas) - { - continue; - } - } + // skip TPC surfaces for fitSilicon MMs + if (m_tGeometry->maps().isTpcSurface(surf) && m_fitSiliconMMs) + { continue; } - if (m_forceSiOnlyFit) - { - if (m_tGeometry->maps().isMicromegasSurface(surf) || m_tGeometry->maps().isTpcSurface(surf)) - { - continue; - } - } + // skip micromegas surfaces if not used + if (m_tGeometry->maps().isMicromegasSurface(surf) && !m_useMicromegas) + { continue; } + + // skip everything but silicons if only silicon fit is required + if (m_forceSiOnlyFit && (m_tGeometry->maps().isMicromegasSurface(surf) || m_tGeometry->maps().isTpcSurface(surf)) ) + { continue; } // update vectors - siliconMMSls.push_back(sl); - surfaces.push_back(surf); + filtered.push_back(sl); } - if (Verbosity() > 10) + return filtered; +} + +//__________________________________________________________________________________ +SurfacePtrVec PHActsTrkFitter::getSurfaceVector(const SourceLinkVec& sourceLinks) const +{ + SurfacePtrVec surfaces; + for (const auto& sl : sourceLinks) { - for (const auto& surf : surfaces) - { - std::cout << "Surface vector : " << surf->geometryId() << std::endl; - } + const ActsSourceLink asl = sl.get(); + const auto* const surf = m_tGeometry->geometry().tGeometry->findSurface(asl.geometryId()); + surfaces.push_back(surf); } - return siliconMMSls; + return surfaces; } void PHActsTrkFitter::checkSurfaceVec(SurfacePtrVec& surfaces) const diff --git a/offline/packages/trackreco/PHActsTrkFitter.h b/offline/packages/trackreco/PHActsTrkFitter.h index 09a8ab9d1d..056c3e88b3 100644 --- a/offline/packages/trackreco/PHActsTrkFitter.h +++ b/offline/packages/trackreco/PHActsTrkFitter.h @@ -164,18 +164,20 @@ class PHActsTrkFitter : public SubsysReco /// Helper function to call either the regular navigation or direct /// navigation, depending on m_fitSiliconMMs ActsTrackFittingAlgorithm::TrackFitterResult fitTrack( - const std::vector& sourceLinks, - const ActsTrackFittingAlgorithm::TrackParameters& seed, - const ActsTrackFittingAlgorithm::GeneralFitterOptions& - kfOptions, - const SurfacePtrVec& surfSequence, - const CalibratorAdapter& calibrator, - ActsTrackFittingAlgorithm::TrackContainer& tracks); - - /// Functions to get list of sorted surfaces for direct navigation, if - /// applicable - SourceLinkVec getSurfaceVector(const SourceLinkVec& sourceLinks, - SurfacePtrVec& surfaces) const; + const std::vector& sourceLinks, + const ActsTrackFittingAlgorithm::TrackParameters& seed, + const ActsTrackFittingAlgorithm::GeneralFitterOptions& kfOptions, + const SurfacePtrVec& surfSequence, + const CalibratorAdapter& calibrator, + ActsTrackFittingAlgorithm::TrackContainer& tracks); + + // remove all source links for detectors that we don't want to include in the fit + SourceLinkVec filterSourceLinks(const SourceLinkVec& sourceLinks ) const; + + /// get list of sorted surfaces for direct navigation, if applicable + SurfacePtrVec getSurfaceVector(const SourceLinkVec& sourceLinks) const; + + /// check ordering of the surfaces void checkSurfaceVec(SurfacePtrVec& surfaces) const; bool getTrackFitResult(const FitResult& fitOutput, TrackSeed* seed, From 42a15a95d59ece20f48cbfb224b359fda7d28285 Mon Sep 17 00:00:00 2001 From: Nikhil Kumar Date: Wed, 18 Feb 2026 15:43:17 -0500 Subject: [PATCH 242/393] Update CaloTowerBuilder.cc --- offline/packages/CaloReco/CaloTowerBuilder.cc | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/offline/packages/CaloReco/CaloTowerBuilder.cc b/offline/packages/CaloReco/CaloTowerBuilder.cc index a84706599d..736479fba0 100644 --- a/offline/packages/CaloReco/CaloTowerBuilder.cc +++ b/offline/packages/CaloReco/CaloTowerBuilder.cc @@ -307,6 +307,25 @@ int CaloTowerBuilder::process_data(PHCompositeNode *topNode, std::vectoriValue(0, "CHANNELS"); unsigned int adc_skip_mask = 0; + if (nchannels == 0)// push back -1 and return for empty packets + { + for (int channel = 0; channel < m_nchannels; channel++) + { + if (skipChannel(channel, pid)) + { + continue; + } + std::vector waveform; + waveform.reserve(m_nzerosuppsamples); + for (int samp = 0; samp < m_nzerosuppsamples; samp++) + { + waveform.push_back(-1); + } + waveforms.push_back(waveform); + } + return Fun4AllReturnCodes::EVENT_OK; + } + if (m_dettype == CaloTowerDefs::CEMC) { adc_skip_mask = cdbttree->GetIntValue(pid, m_fieldname); @@ -406,7 +425,7 @@ int CaloTowerBuilder::process_data(PHCompositeNode *topNode, std::vectorset_isNotInstr(true); } From 9d02849111da5374214e5d150025c8aceb06cd49 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Wed, 18 Feb 2026 17:14:52 -0500 Subject: [PATCH 243/393] Add additional compiler warnings for g++ need to update the perl script to update the compiler flags --- offline/packages/Skimmers/CaloStatusSkimmer/configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/Skimmers/CaloStatusSkimmer/configure.ac b/offline/packages/Skimmers/CaloStatusSkimmer/configure.ac index 3934c375e4..d31173586b 100644 --- a/offline/packages/Skimmers/CaloStatusSkimmer/configure.ac +++ b/offline/packages/Skimmers/CaloStatusSkimmer/configure.ac @@ -9,7 +9,7 @@ LT_INIT([disable-static]) dnl no point in suppressing warnings people should dnl at least see them, so here we go for g++: -Wall if test $ac_cv_prog_gxx = yes; then - CXXFLAGS="$CXXFLAGS -Wall -Werror" + CXXFLAGS="$CXXFLAGS -Wall -Wextra -Wshadow -Werror" fi AC_CONFIG_FILES([Makefile]) From c0b2905148d13e0e26c15597d6afb6844405251d Mon Sep 17 00:00:00 2001 From: Nikhil Kumar Date: Wed, 18 Feb 2026 19:37:57 -0500 Subject: [PATCH 244/393] remove skip channels in empty packet loop, and clang-format --- offline/packages/CaloReco/CaloTowerBuilder.cc | 463 +++++++----------- 1 file changed, 176 insertions(+), 287 deletions(-) diff --git a/offline/packages/CaloReco/CaloTowerBuilder.cc b/offline/packages/CaloReco/CaloTowerBuilder.cc index 736479fba0..2584302138 100644 --- a/offline/packages/CaloReco/CaloTowerBuilder.cc +++ b/offline/packages/CaloReco/CaloTowerBuilder.cc @@ -14,17 +14,17 @@ #include #include -#include // for SubsysReco +#include // for SubsysReco #include #include -#include // for PHIODataNode -#include // for PHNode -#include // for PHNodeIterator -#include // for PHObject +#include // for PHIODataNode +#include // for PHNode +#include // for PHNodeIterator +#include // for PHObject #include -#include // for CDBTTree +#include // for CDBTTree #include @@ -35,10 +35,10 @@ #include #include -#include // for operator<<, endl, basic... -#include // for allocator_traits<>::val... +#include // for operator<<, endl, basic... +#include // for allocator_traits<>::val... #include -#include // for vector +#include // for vector static const std::map nodemap{ {CaloTowerDefs::CEMC, "CEMCPackets"}, @@ -48,50 +48,43 @@ static const std::map nodemap{ {CaloTowerDefs::SEPD, "SEPDPackets"}}; //____________________________________________________________________________.. CaloTowerBuilder::CaloTowerBuilder(const std::string &name) - : SubsysReco(name) - , WaveformProcessing(new CaloWaveformProcessing()) -{ -} + : SubsysReco(name), WaveformProcessing(new CaloWaveformProcessing()) {} //____________________________________________________________________________.. -CaloTowerBuilder::~CaloTowerBuilder() -{ +CaloTowerBuilder::~CaloTowerBuilder() { delete cdbttree; delete cdbttree_tbt_zs; delete WaveformProcessing; } //____________________________________________________________________________.. -int CaloTowerBuilder::InitRun(PHCompositeNode *topNode) -{ +int CaloTowerBuilder::InitRun(PHCompositeNode *topNode) { WaveformProcessing->set_processing_type(_processingtype); - WaveformProcessing->set_softwarezerosuppression(m_bdosoftwarezerosuppression, m_nsoftwarezerosuppression); - if (m_setTimeLim) - { + WaveformProcessing->set_softwarezerosuppression(m_bdosoftwarezerosuppression, + m_nsoftwarezerosuppression); + if (m_setTimeLim) { WaveformProcessing->set_timeFitLim(m_timeLim_low, m_timeLim_high); } - if (m_dobitfliprecovery) - { + if (m_dobitfliprecovery) { WaveformProcessing->set_bitFlipRecovery(m_dobitfliprecovery); } // Set functional fit parameters - if (_processingtype == CaloWaveformProcessing::FUNCFIT) - { + if (_processingtype == CaloWaveformProcessing::FUNCFIT) { WaveformProcessing->set_funcfit_type(m_funcfit_type); WaveformProcessing->set_powerlaw_params(m_powerlaw_power, m_powerlaw_decay); - WaveformProcessing->set_doubleexp_params(m_doubleexp_power, m_doubleexp_peaktime1, m_doubleexp_peaktime2, m_doubleexp_ratio); + WaveformProcessing->set_doubleexp_params( + m_doubleexp_power, m_doubleexp_peaktime1, m_doubleexp_peaktime2, + m_doubleexp_ratio); } - if (m_dettype == CaloTowerDefs::CEMC) - { + if (m_dettype == CaloTowerDefs::CEMC) { m_detector = "CEMC"; m_packet_low = 6001; m_packet_high = 6128; m_nchannels = 192; WaveformProcessing->set_template_name("CEMC_TEMPLATE"); - if (_processingtype == CaloWaveformProcessing::NONE) - { + if (_processingtype == CaloWaveformProcessing::NONE) { WaveformProcessing->set_processing_type(CaloWaveformProcessing::TEMPLATE); } @@ -104,47 +97,41 @@ int CaloTowerBuilder::InitRun(PHCompositeNode *topNode) m_fieldname = "adcskipmask"; calibdir = CDBInterface::instance()->getUrl(m_calibName); - if (calibdir.empty()) - { - std::cout << PHWHERE << "ADC Skip mask not found in CDB, not even in the default... " << std::endl; + if (calibdir.empty()) { + std::cout << PHWHERE + << "ADC Skip mask not found in CDB, not even in the default... " + << std::endl; exit(1); } cdbttree = new CDBTTree(calibdir); - } - else if (m_dettype == CaloTowerDefs::HCALIN) - { + } else if (m_dettype == CaloTowerDefs::HCALIN) { m_packet_low = 7001; m_packet_high = 7008; m_detector = "HCALIN"; m_nchannels = 192; WaveformProcessing->set_template_name("IHCAL_TEMPLATE"); - if (_processingtype == CaloWaveformProcessing::NONE) - { + if (_processingtype == CaloWaveformProcessing::NONE) { WaveformProcessing->set_processing_type(CaloWaveformProcessing::TEMPLATE); } - } - else if (m_dettype == CaloTowerDefs::HCALOUT) - { + } else if (m_dettype == CaloTowerDefs::HCALOUT) { m_detector = "HCALOUT"; m_packet_low = 8001; m_packet_high = 8008; m_nchannels = 192; WaveformProcessing->set_template_name("OHCAL_TEMPLATE"); - if (_processingtype == CaloWaveformProcessing::NONE) - { + if (_processingtype == CaloWaveformProcessing::NONE) { WaveformProcessing->set_processing_type(CaloWaveformProcessing::TEMPLATE); } - } - else if (m_dettype == CaloTowerDefs::SEPD) - { + } else if (m_dettype == CaloTowerDefs::SEPD) { m_detector = "SEPD"; m_packet_low = 9001; m_packet_high = 9006; m_nchannels = 128; WaveformProcessing->set_template_name("SEPD_TEMPLATE"); - if (_processingtype == CaloWaveformProcessing::NONE) - { - WaveformProcessing->set_processing_type(CaloWaveformProcessing::TEMPLATE); // default the EPD to fast processing + if (_processingtype == CaloWaveformProcessing::NONE) { + WaveformProcessing->set_processing_type( + CaloWaveformProcessing::TEMPLATE); // default the EPD to fast + // processing } m_calibName = "SEPD_CHANNELMAP2"; @@ -152,28 +139,25 @@ int CaloTowerBuilder::InitRun(PHCompositeNode *topNode) calibdir = CDBInterface::instance()->getUrl(m_calibName); - if (calibdir.empty()) - { - std::cout << PHWHERE << "No sEPD mapping file for domain " << m_calibName << " found" << std::endl; + if (calibdir.empty()) { + std::cout << PHWHERE << "No sEPD mapping file for domain " << m_calibName + << " found" << std::endl; exit(1); } cdbttree_sepd_map = new CDBTTree(calibdir); - } - else if (m_dettype == CaloTowerDefs::ZDC) - { + } else if (m_dettype == CaloTowerDefs::ZDC) { m_detector = "ZDC"; m_packet_low = 12001; m_packet_high = 12001; m_nchannels = 128; - if (_processingtype == CaloWaveformProcessing::NONE) - { - WaveformProcessing->set_processing_type(CaloWaveformProcessing::FAST); // default the ZDC to fast processing + if (_processingtype == CaloWaveformProcessing::NONE) { + WaveformProcessing->set_processing_type( + CaloWaveformProcessing::FAST); // default the ZDC to fast processing } } WaveformProcessing->initialize_processing(); - if (m_dotbtszs) - { + if (m_dotbtszs) { cdbttree_tbt_zs = new CDBTTree(m_zsURL); } @@ -181,36 +165,30 @@ int CaloTowerBuilder::InitRun(PHCompositeNode *topNode) return Fun4AllReturnCodes::EVENT_OK; } -int CaloTowerBuilder::process_sim() -{ +int CaloTowerBuilder::process_sim() { std::vector> waveforms; - for (int ich = 0; ich < (int) m_CalowaveformContainer->size(); ich++) - { + for (int ich = 0; ich < (int)m_CalowaveformContainer->size(); ich++) { TowerInfo *towerinfo = m_CalowaveformContainer->get_tower_at_channel(ich); std::vector waveform; waveform.reserve(m_nsamples); bool fillwaveform = true; // get key - if (m_dotbtszs) - { + if (m_dotbtszs) { unsigned int key = m_CalowaveformContainer->encode_key(ich); int zs_threshold = cdbttree_tbt_zs->GetIntValue(key, m_zs_fieldname); int pre = towerinfo->get_waveform_value(0); // this is always safe since towerinfo v3 has 31 samples int post = towerinfo->get_waveform_value(6); - if ((post - pre) <= zs_threshold) - { + if ((post - pre) <= zs_threshold) { // zero suppressed fillwaveform = false; waveform.push_back(pre); waveform.push_back(post); } } - if (fillwaveform) - { - for (int samp = 0; samp < m_nsamples; samp++) - { + if (fillwaveform) { + for (int samp = 0; samp < m_nsamples; samp++) { waveform.push_back(towerinfo->get_waveform_value(samp)); } } @@ -218,10 +196,10 @@ int CaloTowerBuilder::process_sim() waveform.clear(); } - std::vector> processed_waveforms = WaveformProcessing->process_waveform(waveforms); + std::vector> processed_waveforms = + WaveformProcessing->process_waveform(waveforms); int n_channels = processed_waveforms.size(); - for (int i = 0; i < n_channels; i++) - { + for (int i = 0; i < n_channels; i++) { // this is for copying the truth info to the downstream object TowerInfo *towerwaveform = m_CalowaveformContainer->get_tower_at_channel(i); TowerInfo *towerinfo = m_CaloInfoContainer->get_tower_at_channel(i); @@ -231,25 +209,20 @@ int CaloTowerBuilder::process_sim() towerinfo->set_time(processed_waveforms.at(i).at(1)); towerinfo->set_pedestal(processed_waveforms.at(i).at(2)); towerinfo->set_chi2(processed_waveforms.at(i).at(3)); - bool SZS = isSZS(processed_waveforms.at(i).at(1), processed_waveforms.at(i).at(3)); - if (processed_waveforms.at(i).at(4) == 0) - { + bool SZS = + isSZS(processed_waveforms.at(i).at(1), processed_waveforms.at(i).at(3)); + if (processed_waveforms.at(i).at(4) == 0) { towerinfo->set_isRecovered(false); - } - else - { + } else { towerinfo->set_isRecovered(true); } int n_samples = waveforms.at(i).size(); - if (n_samples == m_nzerosuppsamples || SZS) - { + if (n_samples == m_nzerosuppsamples || SZS) { towerinfo->set_isZS(true); } - for (int j = 0; j < n_samples; j++) - { + for (int j = 0; j < n_samples; j++) { towerinfo->set_waveform_value(j, waveforms.at(i).at(j)); - if (std::round(waveforms.at(i).at(j)) >= m_saturation) - { + if (std::round(waveforms.at(i).at(j)) >= m_saturation) { towerinfo->set_isSaturated(true); } } @@ -259,66 +232,50 @@ int CaloTowerBuilder::process_sim() return Fun4AllReturnCodes::EVENT_OK; } -int CaloTowerBuilder::process_data(PHCompositeNode *topNode, std::vector> &waveforms) -{ +int CaloTowerBuilder::process_data(PHCompositeNode *topNode, + std::vector> &waveforms) { std::variant event; - if (m_UseOfflinePacketFlag) - { - CaloPacketContainer *calopacketcontainer = findNode::getClass(topNode, nodemap.find(m_dettype)->second); - if (!calopacketcontainer) - { - for (int pid = m_packet_low; pid <= m_packet_high; pid++) - { - if (findNode::getClass(topNode, pid)) - { + if (m_UseOfflinePacketFlag) { + CaloPacketContainer *calopacketcontainer = + findNode::getClass( + topNode, nodemap.find(m_dettype)->second); + if (!calopacketcontainer) { + for (int pid = m_packet_low; pid <= m_packet_high; pid++) { + if (findNode::getClass(topNode, pid)) { m_PacketNodesFlag = true; break; } } - if (!m_PacketNodesFlag) - { + if (!m_PacketNodesFlag) { return Fun4AllReturnCodes::EVENT_OK; } - } - else - { + } else { event = calopacketcontainer; } - } - else - { + } else { Event *_event = findNode::getClass(topNode, "PRDF"); - if (_event == nullptr) - { + if (_event == nullptr) { std::cout << PHWHERE << " Event not found" << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } - if (_event->getEvtType() != DATAEVENT) - { + if (_event->getEvtType() != DATAEVENT) { return Fun4AllReturnCodes::ABORTEVENT; } event = _event; } - // since the function call on Packet and CaloPacket is the same, maybe we can use lambda? - auto process_packet = [&](auto *packet, int pid) - { - if (packet) - { + // since the function call on Packet and CaloPacket is the same, maybe we can + // use lambda? + auto process_packet = [&](auto *packet, int pid) { + if (packet) { int nchannels = packet->iValue(0, "CHANNELS"); unsigned int adc_skip_mask = 0; - if (nchannels == 0)// push back -1 and return for empty packets + if (nchannels == 0) // push back -1 and return for empty packets { - for (int channel = 0; channel < m_nchannels; channel++) - { - if (skipChannel(channel, pid)) - { - continue; - } + for (int channel = 0; channel < m_nchannels; channel++) { std::vector waveform; waveform.reserve(m_nzerosuppsamples); - for (int samp = 0; samp < m_nzerosuppsamples; samp++) - { + for (int samp = 0; samp < m_nzerosuppsamples; samp++) { waveform.push_back(-1); } waveforms.push_back(waveform); @@ -326,41 +283,33 @@ int CaloTowerBuilder::process_data(PHCompositeNode *topNode, std::vectorGetIntValue(pid, m_fieldname); } - if (m_dettype == CaloTowerDefs::ZDC) - { + if (m_dettype == CaloTowerDefs::ZDC) { nchannels = m_nchannels; } - if (nchannels > m_nchannels) // packet is corrupted and reports too many channels + if (nchannels > + m_nchannels) // packet is corrupted and reports too many channels { return Fun4AllReturnCodes::ABORTEVENT; } int n_pad_skip_mask = 0; - for (int channel = 0; channel < nchannels; channel++) - { - if (skipChannel(channel, pid)) - { + for (int channel = 0; channel < nchannels; channel++) { + if (skipChannel(channel, pid)) { continue; } - if (m_dettype == CaloTowerDefs::CEMC) - { - if (channel % 64 == 0) - { - unsigned int adcboard = (unsigned int) channel / 64; - if ((adc_skip_mask >> adcboard) & 0x1U) - { - for (int iskip = 0; iskip < 64; iskip++) - { + if (m_dettype == CaloTowerDefs::CEMC) { + if (channel % 64 == 0) { + unsigned int adcboard = (unsigned int)channel / 64; + if ((adc_skip_mask >> adcboard) & 0x1U) { + for (int iskip = 0; iskip < 64; iskip++) { n_pad_skip_mask++; std::vector waveform; waveform.reserve(m_nsamples); - for (int samp = 0; samp < m_nzerosuppsamples; samp++) - { + for (int samp = 0; samp < m_nzerosuppsamples; samp++) { waveform.push_back(0); } waveforms.push_back(waveform); @@ -372,15 +321,11 @@ int CaloTowerBuilder::process_data(PHCompositeNode *topNode, std::vector waveform; waveform.reserve(m_nsamples); - if (packet->iValue(channel, "SUPPRESSED")) - { + if (packet->iValue(channel, "SUPPRESSED")) { waveform.push_back(packet->iValue(channel, "PRE")); waveform.push_back(packet->iValue(channel, "POST")); - } - else - { - for (int samp = 0; samp < m_nsamples; samp++) - { + } else { + for (int samp = 0; samp < m_nsamples; samp++) { waveform.push_back(packet->iValue(samp, channel)); } } @@ -389,43 +334,35 @@ int CaloTowerBuilder::process_data(PHCompositeNode *topNode, std::vector waveform; waveform.reserve(m_nsamples); - for (int samp = 0; samp < m_nzerosuppsamples; samp++) - { + for (int samp = 0; samp < m_nzerosuppsamples; samp++) { waveform.push_back(0); } waveforms.push_back(waveform); waveform.clear(); } } - } - else // if the packet is missing treat constitutent channels as zero suppressed + } else // if the packet is missing treat constitutent channels as zero + // suppressed { - for (int channel = 0; channel < m_nchannels; channel++) - { - if (skipChannel(channel, pid)) - { + for (int channel = 0; channel < m_nchannels; channel++) { + if (skipChannel(channel, pid)) { continue; } std::vector waveform; waveform.reserve(2); - for (int samp = 0; samp < m_nzerosuppsamples; samp++) - { - waveform.push_back(-1); // push back -1 for missing packets + for (int samp = 0; samp < m_nzerosuppsamples; samp++) { + waveform.push_back(-1); // push back -1 for missing packets } waveforms.push_back(waveform); waveform.clear(); @@ -434,32 +371,23 @@ int CaloTowerBuilder::process_data(PHCompositeNode *topNode, std::vector(&event)) - { + for (int pid = m_packet_low; pid <= m_packet_high; pid++) { + if (!m_PacketNodesFlag) { + if (auto *hcalcont = std::get_if(&event)) { CaloPacket *packet = (*hcalcont)->getPacketbyId(pid); - if (process_packet(packet, pid) == Fun4AllReturnCodes::ABORTEVENT) - { + if (process_packet(packet, pid) == Fun4AllReturnCodes::ABORTEVENT) { return Fun4AllReturnCodes::ABORTEVENT; } - } - else if (auto *_event = std::get_if(&event)) - { + } else if (auto *_event = std::get_if(&event)) { Packet *packet = (*_event)->getPacket(pid); - if (process_packet(packet, pid) == Fun4AllReturnCodes::ABORTEVENT) - { + if (process_packet(packet, pid) == Fun4AllReturnCodes::ABORTEVENT) { // I think it is safe to delete a nullptr... delete packet; return Fun4AllReturnCodes::ABORTEVENT; } delete packet; } - } - else - { + } else { CaloPacket *calopacket = findNode::getClass(topNode, pid); process_packet(calopacket, pid); } @@ -468,32 +396,27 @@ int CaloTowerBuilder::process_data(PHCompositeNode *topNode, std::vector> waveforms; - if (process_data(topNode, waveforms) == Fun4AllReturnCodes::ABORTEVENT) - { + if (process_data(topNode, waveforms) == Fun4AllReturnCodes::ABORTEVENT) { return Fun4AllReturnCodes::ABORTEVENT; } - if (waveforms.empty()) - { + if (waveforms.empty()) { return Fun4AllReturnCodes::EVENT_OK; } - // waveform vector is filled here, now fill our output. methods from the base class make sure - // we only fill what the chosen container version supports - std::vector> processed_waveforms = WaveformProcessing->process_waveform(waveforms); + // waveform vector is filled here, now fill our output. methods from the base + // class make sure we only fill what the chosen container version supports + std::vector> processed_waveforms = + WaveformProcessing->process_waveform(waveforms); int n_channels = processed_waveforms.size(); - for (int i = 0; i < n_channels; i++) - { + for (int i = 0; i < n_channels; i++) { int idx = i; // Align sEPD ADC channels to TowerInfoContainer - if (m_dettype == CaloTowerDefs::SEPD) - { + if (m_dettype == CaloTowerDefs::SEPD) { idx = cdbttree_sepd_map->GetIntValue(i, m_fieldname); } TowerInfo *towerinfo = m_CaloInfoContainer->get_tower_at_channel(i); @@ -502,33 +425,27 @@ int CaloTowerBuilder::process_event(PHCompositeNode *topNode) towerinfo->set_time(processed_waveforms.at(idx).at(1)); towerinfo->set_pedestal(processed_waveforms.at(idx).at(2)); towerinfo->set_chi2(processed_waveforms.at(idx).at(3)); - bool SZS = isSZS(processed_waveforms.at(idx).at(1), processed_waveforms.at(idx).at(3)); + bool SZS = isSZS(processed_waveforms.at(idx).at(1), + processed_waveforms.at(idx).at(3)); - if (processed_waveforms.at(idx).at(4) == 0) - { + if (processed_waveforms.at(idx).at(4) == 0) { towerinfo->set_isRecovered(false); - } - else - { + } else { towerinfo->set_isRecovered(true); } int n_samples = waveforms.at(idx).size(); - if (n_samples == m_nzerosuppsamples || SZS) - { - if (waveforms.at(idx).at(0) == -1) // set bit for missing and empty packets. + if (n_samples == m_nzerosuppsamples || SZS) { + if (waveforms.at(idx).at(0) == + -1) // set bit for missing and empty packets. { towerinfo->set_isNotInstr(true); - } - else - { + } else { towerinfo->set_isZS(true); } } - for (int j = 0; j < n_samples; j++) - { - if (std::round(waveforms.at(idx).at(j)) >= m_saturation) - { + for (int j = 0; j < n_samples; j++) { + if (std::round(waveforms.at(idx).at(j)) >= m_saturation) { towerinfo->set_isSaturated(true); } towerinfo->set_waveform_value(j, waveforms.at(idx).at(j)); @@ -539,30 +456,23 @@ int CaloTowerBuilder::process_event(PHCompositeNode *topNode) return Fun4AllReturnCodes::EVENT_OK; } -bool CaloTowerBuilder::skipChannel(int ich, int pid) -{ - if (m_dettype == CaloTowerDefs::SEPD) - { +bool CaloTowerBuilder::skipChannel(int ich, int pid) { + if (m_dettype == CaloTowerDefs::SEPD) { int sector = ((ich + 1) / 32); int emptych = -999; - if ((sector == 0) && (pid == 9001)) - { + if ((sector == 0) && (pid == 9001)) { emptych = 1; - } - else - { + } else { emptych = 14 + 32 * sector; } - if (ich == emptych) - { + if (ich == emptych) { return true; } } - if (m_dettype == CaloTowerDefs::ZDC) - { - if (((ich > 17) && (ich < 48)) || ((ich > 63) && (ich < 80)) || ((ich > 81) && (ich < 112))) - { + if (m_dettype == CaloTowerDefs::ZDC) { + if (((ich > 17) && (ich < 48)) || ((ich > 63) && (ich < 80)) || + ((ich > 81) && (ich < 112))) { return true; } } @@ -570,34 +480,31 @@ bool CaloTowerBuilder::skipChannel(int ich, int pid) return false; } -bool CaloTowerBuilder::isSZS(float time, float chi2) -{ +bool CaloTowerBuilder::isSZS(float time, float chi2) { // isfinite - if (!std::isfinite(time) && !std::isfinite(chi2)) - { + if (!std::isfinite(time) && !std::isfinite(chi2)) { return true; } return false; } -void CaloTowerBuilder::CreateNodeTree(PHCompositeNode *topNode) -{ +void CaloTowerBuilder::CreateNodeTree(PHCompositeNode *topNode) { PHNodeIterator topNodeItr(topNode); // DST node - PHCompositeNode *dstNode = dynamic_cast(topNodeItr.findFirst("PHCompositeNode", "DST")); - if (!dstNode) - { + PHCompositeNode *dstNode = dynamic_cast( + topNodeItr.findFirst("PHCompositeNode", "DST")); + if (!dstNode) { std::cout << "PHComposite node created: DST" << std::endl; dstNode = new PHCompositeNode("DST"); topNode->addNode(dstNode); } - if (!m_isdata) - { + if (!m_isdata) { std::string waveformNodeName = m_inputNodePrefix + m_detector; - m_CalowaveformContainer = findNode::getClass(topNode, waveformNodeName); - if (!m_CalowaveformContainer) - { - std::cout << PHWHERE << "simulation waveform container " << waveformNodeName << " not found" << std::endl; + m_CalowaveformContainer = + findNode::getClass(topNode, waveformNodeName); + if (!m_CalowaveformContainer) { + std::cout << PHWHERE << "simulation waveform container " + << waveformNodeName << " not found" << std::endl; gSystem->Exit(1); exit(1); } @@ -606,73 +513,55 @@ void CaloTowerBuilder::CreateNodeTree(PHCompositeNode *topNode) // towers PHNodeIterator nodeItr(dstNode); PHCompositeNode *DetNode; - // enum CaloTowerDefs::DetectorSystem and TowerInfoContainer::DETECTOR are different!!!! - TowerInfoContainer::DETECTOR DetectorEnum = TowerInfoContainer::DETECTOR::DETECTOR_INVALID; + // enum CaloTowerDefs::DetectorSystem and TowerInfoContainer::DETECTOR are + // different!!!! + TowerInfoContainer::DETECTOR DetectorEnum = + TowerInfoContainer::DETECTOR::DETECTOR_INVALID; std::string DetectorNodeName; - if (m_dettype == CaloTowerDefs::CEMC) - { + if (m_dettype == CaloTowerDefs::CEMC) { DetectorEnum = TowerInfoContainer::DETECTOR::EMCAL; DetectorNodeName = "CEMC"; - } - else if (m_dettype == CaloTowerDefs::SEPD) - { + } else if (m_dettype == CaloTowerDefs::SEPD) { DetectorEnum = TowerInfoContainer::DETECTOR::SEPD; DetectorNodeName = "SEPD"; - } - else if (m_dettype == CaloTowerDefs::ZDC) - { + } else if (m_dettype == CaloTowerDefs::ZDC) { DetectorEnum = TowerInfoContainer::DETECTOR::ZDC; DetectorNodeName = "ZDC"; - } - else if (m_dettype == CaloTowerDefs::HCALIN) - { + } else if (m_dettype == CaloTowerDefs::HCALIN) { DetectorEnum = TowerInfoContainer::DETECTOR::HCAL; DetectorNodeName = "HCALIN"; - } - else if (m_dettype == CaloTowerDefs::HCALOUT) - { + } else if (m_dettype == CaloTowerDefs::HCALOUT) { DetectorEnum = TowerInfoContainer::DETECTOR::HCAL; DetectorNodeName = "HCALOUT"; - } - else - { + } else { std::cout << PHWHERE << " Invalid detector type " << m_dettype << std::endl; gSystem->Exit(1); exit(1); } - DetNode = dynamic_cast(nodeItr.findFirst("PHCompositeNode", DetectorNodeName)); - if (!DetNode) - { + DetNode = dynamic_cast( + nodeItr.findFirst("PHCompositeNode", DetectorNodeName)); + if (!DetNode) { DetNode = new PHCompositeNode(DetectorNodeName); dstNode->addNode(DetNode); } - if (m_buildertype == CaloTowerDefs::kPRDFTowerv1) - { + if (m_buildertype == CaloTowerDefs::kPRDFTowerv1) { m_CaloInfoContainer = new TowerInfoContainerv1(DetectorEnum); - } - else if (m_buildertype == CaloTowerDefs::kPRDFWaveform) - { + } else if (m_buildertype == CaloTowerDefs::kPRDFWaveform) { m_CaloInfoContainer = new TowerInfoContainerv3(DetectorEnum); - } - else if (m_buildertype == CaloTowerDefs::kWaveformTowerv2) - { + } else if (m_buildertype == CaloTowerDefs::kWaveformTowerv2) { m_CaloInfoContainer = new TowerInfoContainerv2(DetectorEnum); - } - else if (m_buildertype == CaloTowerDefs::kPRDFTowerv4) - { + } else if (m_buildertype == CaloTowerDefs::kPRDFTowerv4) { m_CaloInfoContainer = new TowerInfoContainerv4(DetectorEnum); - } - else if (m_buildertype == CaloTowerDefs::kWaveformTowerSimv1) - { + } else if (m_buildertype == CaloTowerDefs::kWaveformTowerSimv1) { m_CaloInfoContainer = new TowerInfoContainerSimv1(DetectorEnum); - } - else - { - std::cout << PHWHERE << "invalid builder type " << m_buildertype << std::endl; + } else { + std::cout << PHWHERE << "invalid builder type " << m_buildertype + << std::endl; gSystem->Exit(1); exit(1); } TowerNodeName = m_outputNodePrefix + m_detector; - PHIODataNode *newTowerNode = new PHIODataNode(m_CaloInfoContainer, TowerNodeName, "PHObject"); + PHIODataNode *newTowerNode = new PHIODataNode( + m_CaloInfoContainer, TowerNodeName, "PHObject"); DetNode->addNode(newTowerNode); } From 8a18f615325156044d66275cc3d47aa45b594d23 Mon Sep 17 00:00:00 2001 From: Nikhil Kumar Date: Wed, 18 Feb 2026 19:41:26 -0500 Subject: [PATCH 245/393] clang-format for the skimmer module --- .../CaloStatusSkimmer/CaloStatusSkimmer.cc | 141 +++++++++--------- .../CaloStatusSkimmer/CaloStatusSkimmer.h | 118 ++++++++------- 2 files changed, 128 insertions(+), 131 deletions(-) diff --git a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc index 726afac8e1..5011e2ff44 100644 --- a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc +++ b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc @@ -24,152 +24,145 @@ // for cluster vertex correction #include #include +#include #include #include -#include -#include #include - +#include //____________________________________________________________________________.. -CaloStatusSkimmer::CaloStatusSkimmer(const std::string &name) : SubsysReco(name) -{ +CaloStatusSkimmer::CaloStatusSkimmer(const std::string &name) + : SubsysReco(name) { n_eventcounter = 0; n_skimcounter = 0; n_notowernodecounter = 0; - std::cout << "CaloStatusSkimmer::CaloStatusSkimmer(const std::string &name) Calling ctor" << std::endl; + std::cout << "CaloStatusSkimmer::CaloStatusSkimmer(const std::string &name) " + "Calling ctor" + << std::endl; } //____________________________________________________________________________.. -CaloStatusSkimmer::~CaloStatusSkimmer() -{ - //std::cout << "CaloStatusSkimmer::~CaloStatusSkimmer() Calling dtor" << std::endl; +CaloStatusSkimmer::~CaloStatusSkimmer() { + // std::cout << "CaloStatusSkimmer::~CaloStatusSkimmer() Calling dtor" << + // std::endl; } //____________________________________________________________________________.. -int CaloStatusSkimmer::Init(PHCompositeNode *topNode) -{ - std::cout << "CaloStatusSkimmer::Init(PHCompositeNode *topNode) Initializing" << std::endl; +int CaloStatusSkimmer::Init(PHCompositeNode *topNode) { + std::cout << "CaloStatusSkimmer::Init(PHCompositeNode *topNode) Initializing" + << std::endl; return Fun4AllReturnCodes::EVENT_OK; } //____________________________________________________________________________.. -int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) -{ +int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) { n_eventcounter++; - if (b_do_skim_EMCal) - { - TowerInfoContainer *towers = findNode::getClass(topNode, "TOWERS_CEMC"); - if (!towers) - { + if (b_do_skim_EMCal) { + TowerInfoContainer *towers = + findNode::getClass(topNode, "TOWERS_CEMC"); + if (!towers) { n_notowernodecounter++; - std::cout << PHWHERE << "calostatuscheck::process_event: missing TOWERS_CEMC\n"; + std::cout << PHWHERE + << "calostatuscheck::process_event: missing TOWERS_CEMC\n"; return Fun4AllReturnCodes::ABORTEVENT; } const UInt_t ntowers = towers->size(); uint16_t notinstr_count = 0; - for (UInt_t ch = 0; ch < ntowers; ++ch) - { + for (UInt_t ch = 0; ch < ntowers; ++ch) { TowerInfo *tower = towers->get_tower_at_channel(ch); - if (tower->get_isNotInstr()) - { + if (tower->get_isNotInstr()) { ++notinstr_count; } } - if (notinstr_count >= m_EMC_skim_threshold) - { + if (notinstr_count >= m_EMC_skim_threshold) { n_skimcounter++; return Fun4AllReturnCodes::ABORTEVENT; } } - if (b_do_skim_HCal) - { - TowerInfoContainer *hcalin_towers = findNode::getClass(topNode, "TOWERS_HCALIN"); - TowerInfoContainer *hcalout_towers = findNode::getClass(topNode, "TOWERS_HCALOUT"); - if (!hcalin_towers || !hcalout_towers) - { + if (b_do_skim_HCal) { + TowerInfoContainer *hcalin_towers = + findNode::getClass(topNode, "TOWERS_HCALIN"); + TowerInfoContainer *hcalout_towers = + findNode::getClass(topNode, "TOWERS_HCALOUT"); + if (!hcalin_towers || !hcalout_towers) { n_notowernodecounter++; - std::cout << PHWHERE << "calostatuscheck::process_event: missing TOWERS_HCALIN or TOWERS_HCALOUT\n"; - return Fun4AllReturnCodes::ABORTEVENT;// do I want ABORTPROCESSING or just ABORTEVENT here? ABORTPROCESSING will stop the entire job, while ABORTEVENT will just skip this event and continue with the next one. + std::cout << PHWHERE + << "calostatuscheck::process_event: missing TOWERS_HCALIN or " + "TOWERS_HCALOUT\n"; + return Fun4AllReturnCodes:: + ABORTEVENT; // do I want ABORTPROCESSING or just ABORTEVENT here? + // ABORTPROCESSING will stop the entire job, while + // ABORTEVENT will just skip this event and continue with + // the next one. } const UInt_t ntowers_hcalin = hcalin_towers->size(); uint16_t notinstr_count_hcalin = 0; - for (UInt_t ch = 0; ch < ntowers_hcalin; ++ch) - { + for (UInt_t ch = 0; ch < ntowers_hcalin; ++ch) { TowerInfo *tower_in = hcalin_towers->get_tower_at_channel(ch); - if (tower_in->get_isNotInstr()) - { + if (tower_in->get_isNotInstr()) { ++notinstr_count_hcalin; } } - + const UInt_t ntowers_hcalout = hcalout_towers->size(); uint16_t notinstr_count_hcalout = 0; - for (UInt_t ch = 0; ch < ntowers_hcalout; ++ch) - { + for (UInt_t ch = 0; ch < ntowers_hcalout; ++ch) { TowerInfo *tower_out = hcalout_towers->get_tower_at_channel(ch); - if (tower_out->get_isNotInstr()) - { + if (tower_out->get_isNotInstr()) { ++notinstr_count_hcalout; } } - if (notinstr_count_hcalin >= m_HCal_skim_threshold || notinstr_count_hcalout >= m_HCal_skim_threshold) - { + if (notinstr_count_hcalin >= m_HCal_skim_threshold || + notinstr_count_hcalout >= m_HCal_skim_threshold) { n_skimcounter++; return Fun4AllReturnCodes::ABORTEVENT; } } - if (b_do_skim_sEPD) - { - TowerInfoContainer *sepd_towers = findNode::getClass(topNode, "TOWERS_SEPD"); - if (!sepd_towers) - { + if (b_do_skim_sEPD) { + TowerInfoContainer *sepd_towers = + findNode::getClass(topNode, "TOWERS_SEPD"); + if (!sepd_towers) { n_notowernodecounter++; - std::cout << PHWHERE << "calostatuscheck::process_event: missing TOWERS_SEPD\n"; + std::cout << PHWHERE + << "calostatuscheck::process_event: missing TOWERS_SEPD\n"; return Fun4AllReturnCodes::ABORTEVENT; } const UInt_t ntowers = sepd_towers->size(); uint16_t notinstr_count = 0; - for (UInt_t ch = 0; ch < ntowers; ++ch) - { + for (UInt_t ch = 0; ch < ntowers; ++ch) { TowerInfo *tower = sepd_towers->get_tower_at_channel(ch); - if (tower->get_isNotInstr()) - { + if (tower->get_isNotInstr()) { ++notinstr_count; } } - if (notinstr_count >= m_sEPD_skim_threshold) - { + if (notinstr_count >= m_sEPD_skim_threshold) { n_skimcounter++; return Fun4AllReturnCodes::ABORTEVENT; } } - if (b_do_skim_ZDC) - { - TowerInfoContainer *zdc_towers = findNode::getClass(topNode, "TOWERS_ZDC"); - if (!zdc_towers) - { + if (b_do_skim_ZDC) { + TowerInfoContainer *zdc_towers = + findNode::getClass(topNode, "TOWERS_ZDC"); + if (!zdc_towers) { n_notowernodecounter++; - std::cout << PHWHERE << "calostatuscheck::process_event: missing TOWERS_ZDC\n"; + std::cout << PHWHERE + << "calostatuscheck::process_event: missing TOWERS_ZDC\n"; return Fun4AllReturnCodes::ABORTEVENT; } const UInt_t ntowers = zdc_towers->size(); uint16_t notinstr_count = 0; - for (UInt_t ch = 0; ch < ntowers; ++ch) - { + for (UInt_t ch = 0; ch < ntowers; ++ch) { TowerInfo *tower = zdc_towers->get_tower_at_channel(ch); - if (tower->get_isNotInstr()) - { + if (tower->get_isNotInstr()) { ++notinstr_count; } } - if (notinstr_count >= m_ZDC_skim_threshold) - { + if (notinstr_count >= m_ZDC_skim_threshold) { n_skimcounter++; return Fun4AllReturnCodes::ABORTEVENT; } @@ -179,12 +172,14 @@ int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) } //____________________________________________________________________________.. -int CaloStatusSkimmer::End(PHCompositeNode *topNode) -{ - std::cout << "CaloStatusSkimmer::End(PHCompositeNode *topNode) This is the End..." << std::endl; +int CaloStatusSkimmer::End(PHCompositeNode *topNode) { + std::cout + << "CaloStatusSkimmer::End(PHCompositeNode *topNode) This is the End..." + << std::endl; std::cout << "Total events processed: " << n_eventcounter << std::endl; std::cout << "Total events skimmed: " << n_skimcounter << std::endl; - std::cout << "Total events with missing tower nodes: " << n_notowernodecounter << std::endl; + std::cout << "Total events with missing tower nodes: " << n_notowernodecounter + << std::endl; return Fun4AllReturnCodes::EVENT_OK; } diff --git a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h index 965a42abe2..5126fefa05 100644 --- a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h +++ b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h @@ -5,76 +5,78 @@ #include -#include #include -#include #include +#include +#include class PHCompositeNode; -class CaloStatusSkimmer : public SubsysReco -{ +class CaloStatusSkimmer : public SubsysReco { public: - CaloStatusSkimmer(const std::string &name = "CaloStatusSkimmer"); - - ~CaloStatusSkimmer() override; - - /** Called during initialization. - Typically this is where you can book histograms, and e.g. - register them to Fun4AllServer (so they can be output to file - using Fun4AllServer::dumpHistos() method). - */ - int Init(PHCompositeNode *topNode) override; - - /** Called for each event. - This is where you do the real work. - */ - int process_event(PHCompositeNode *topNode) override; - - /// Called at the end of all processing. - int End(PHCompositeNode *topNode) override; - - void do_skim_EMCal(bool do_skim, uint16_t threshold) - { - b_do_skim_EMCal = do_skim; - m_EMC_skim_threshold = threshold; - } - - void do_skim_HCal(bool do_skim, uint16_t threshold) - { - b_do_skim_HCal = do_skim; - m_HCal_skim_threshold = threshold; - } - - void do_skim_sEPD(bool do_skim, uint16_t threshold) - { - b_do_skim_sEPD = do_skim; - m_sEPD_skim_threshold = threshold; - } - - void do_skim_ZDC(bool do_skim, uint16_t threshold) - { - b_do_skim_ZDC = do_skim; - m_ZDC_skim_threshold = threshold; - } + CaloStatusSkimmer(const std::string &name = "CaloStatusSkimmer"); -private: + ~CaloStatusSkimmer() override; - uint32_t n_eventcounter{0}; - uint32_t n_skimcounter{0}; - uint32_t n_notowernodecounter{0}; + /** Called during initialization. + Typically this is where you can book histograms, and e.g. + register them to Fun4AllServer (so they can be output to file + using Fun4AllServer::dumpHistos() method). + */ + int Init(PHCompositeNode *topNode) override; - bool b_do_skim_EMCal{false}; - uint16_t m_EMC_skim_threshold{192}; // skim if nchannels >= this many not-instrumented(empty/missing pckt) channels in EMCal + /** Called for each event. + This is where you do the real work. + */ + int process_event(PHCompositeNode *topNode) override; - bool b_do_skim_HCal{false}; - uint16_t m_HCal_skim_threshold{192}; // skim if nchannels >= this many not-instrumented(empty/missing pckt) channels in HCal + /// Called at the end of all processing. + int End(PHCompositeNode *topNode) override; - bool b_do_skim_sEPD{false}; - uint16_t m_sEPD_skim_threshold{192}; // skim if nchannels >= this many not-instrumented(empty/missing pckt) channels in sEPD + void do_skim_EMCal(bool do_skim, uint16_t threshold) { + b_do_skim_EMCal = do_skim; + m_EMC_skim_threshold = threshold; + } - bool b_do_skim_ZDC{false}; - uint16_t m_ZDC_skim_threshold{192}; // skim if nchannels >= this many not-instrumented(empty/missing pckt) channels in ZDC + void do_skim_HCal(bool do_skim, uint16_t threshold) { + b_do_skim_HCal = do_skim; + m_HCal_skim_threshold = threshold; + } + + void do_skim_sEPD(bool do_skim, uint16_t threshold) { + b_do_skim_sEPD = do_skim; + m_sEPD_skim_threshold = threshold; + } + + void do_skim_ZDC(bool do_skim, uint16_t threshold) { + b_do_skim_ZDC = do_skim; + m_ZDC_skim_threshold = threshold; + } + +private: + uint32_t n_eventcounter{0}; + uint32_t n_skimcounter{0}; + uint32_t n_notowernodecounter{0}; + + bool b_do_skim_EMCal{false}; + uint16_t m_EMC_skim_threshold{ + 192}; // skim if nchannels >= this many not-instrumented(empty/missing + // pckt) channels in EMCal + + bool b_do_skim_HCal{false}; + uint16_t m_HCal_skim_threshold{ + 192}; // skim if nchannels >= this many not-instrumented(empty/missing + // pckt) channels in HCal + + bool b_do_skim_sEPD{false}; + uint16_t m_sEPD_skim_threshold{ + 192}; // skim if nchannels >= this many not-instrumented(empty/missing + // pckt) channels in sEPD + + bool b_do_skim_ZDC{false}; + uint16_t m_ZDC_skim_threshold{ + 192}; // skim if nchannels >= this many not-instrumented(empty/missing + // pckt) channels in ZDC }; #endif // CALOSTATUSSKIMMER_H From 008a0128e539b7b359faee88b9910ccc12d875c0 Mon Sep 17 00:00:00 2001 From: bkimelman Date: Thu, 19 Feb 2026 08:16:57 -0500 Subject: [PATCH 246/393] clag-tidy fixes --- .../tpccalib/TpcCentralMembraneMatching.cc | 30 +++++++++++++++---- .../packages/tpccalib/TpcLaminationFitting.cc | 5 +++- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/offline/packages/tpccalib/TpcCentralMembraneMatching.cc b/offline/packages/tpccalib/TpcCentralMembraneMatching.cc index ec488c9d68..e790bb2b1d 100644 --- a/offline/packages/tpccalib/TpcCentralMembraneMatching.cc +++ b/offline/packages/tpccalib/TpcCentralMembraneMatching.cc @@ -2351,8 +2351,14 @@ int TpcCentralMembraneMatching::process_event(PHCompositeNode* topNode) } */ m_dcc_out->m_hDRint[s]->SetBinContent(i, j, gr_dR[s]->Interpolate(phiVal,RVal)); - if(!m_phiHist_in_rad) m_dcc_out->m_hDPint[s]->SetBinContent(i, j, RVal*gr_dPhi[s]->Interpolate(phiVal,RVal)); - else m_dcc_out->m_hDPint[s]->SetBinContent(i, j, gr_dPhi[s]->Interpolate(phiVal,RVal)); + if(!m_phiHist_in_rad) + { + m_dcc_out->m_hDPint[s]->SetBinContent(i, j, RVal*gr_dPhi[s]->Interpolate(phiVal,RVal)); + } + else + { + m_dcc_out->m_hDPint[s]->SetBinContent(i, j, gr_dPhi[s]->Interpolate(phiVal,RVal)); + } } } } @@ -2661,15 +2667,27 @@ int TpcCentralMembraneMatching::End(PHCompositeNode* /*topNode*/) if(den > 0.0) { m_dcc_out_aggregated->m_hDRint[s]->SetBinContent(i, j, num_dR / den); - if(!m_phiHist_in_rad) m_dcc_out_aggregated->m_hDPint[s]->SetBinContent(i, j, RVal*(num_dPhi / den)); - else m_dcc_out_aggregated->m_hDPint[s]->SetBinContent(i, j, num_dPhi / den); + if(!m_phiHist_in_rad) + { + m_dcc_out_aggregated->m_hDPint[s]->SetBinContent(i, j, RVal*(num_dPhi / den)); + } + else + { + m_dcc_out_aggregated->m_hDPint[s]->SetBinContent(i, j, num_dPhi / den); + } } } else { m_dcc_out_aggregated->m_hDRint[s]->SetBinContent(i, j, gr_dR_toInterp[s]->Interpolate(phiVal,RVal)); - if(!m_phiHist_in_rad) m_dcc_out_aggregated->m_hDPint[s]->SetBinContent(i, j, RVal*gr_dPhi_toInterp[s]->Interpolate(phiVal,RVal)); - else m_dcc_out_aggregated->m_hDPint[s]->SetBinContent(i, j, gr_dPhi_toInterp[s]->Interpolate(phiVal,RVal)); + if(!m_phiHist_in_rad) + { + m_dcc_out_aggregated->m_hDPint[s]->SetBinContent(i, j, RVal*gr_dPhi_toInterp[s]->Interpolate(phiVal,RVal)); + } + else + { + m_dcc_out_aggregated->m_hDPint[s]->SetBinContent(i, j, gr_dPhi_toInterp[s]->Interpolate(phiVal,RVal)); + } } } } diff --git a/offline/packages/tpccalib/TpcLaminationFitting.cc b/offline/packages/tpccalib/TpcLaminationFitting.cc index 617e9a9387..290a1ab052 100644 --- a/offline/packages/tpccalib/TpcLaminationFitting.cc +++ b/offline/packages/tpccalib/TpcLaminationFitting.cc @@ -754,7 +754,10 @@ int TpcLaminationFitting::InterpolatePhiDistortions() m_fLamination[l][s]->SetParameter(3, 0.0); } double phiDistortion = m_fLamination[l][s]->Integral(phiDistortionLamination[s]->GetYaxis()->GetBinLowEdge(i), phiDistortionLamination[s]->GetYaxis()->GetBinLowEdge(i + 1)) / (phiDistortionLamination[s]->GetYaxis()->GetBinLowEdge(i + 1) - phiDistortionLamination[s]->GetYaxis()->GetBinLowEdge(i)); - if(!m_phiHist_in_rad) phiDistortion *= R; + if(!m_phiHist_in_rad) + { + phiDistortion *= R; + } if(m_fieldOff) { m_fLamination[l][s]->SetParameter(1, m_laminationIdeal[l][s]); From 3ec981b446c4f4fa72961f82f2344102f4802caa Mon Sep 17 00:00:00 2001 From: bkimelman Date: Thu, 19 Feb 2026 10:37:48 -0500 Subject: [PATCH 247/393] Added toggle to save all lamination fitting histograms to file if desired. Will be off by default, but allows for more in-depth QA --- .../packages/tpccalib/TpcLaminationFitting.cc | 47 ++++++++++++------- .../packages/tpccalib/TpcLaminationFitting.h | 3 ++ 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/offline/packages/tpccalib/TpcLaminationFitting.cc b/offline/packages/tpccalib/TpcLaminationFitting.cc index 290a1ab052..68cea6f83d 100644 --- a/offline/packages/tpccalib/TpcLaminationFitting.cc +++ b/offline/packages/tpccalib/TpcLaminationFitting.cc @@ -412,22 +412,22 @@ int TpcLaminationFitting::process_event(PHCompositeNode *topNode) { for (int l = 0; l < 18; l++) { - double shift = m_laminationIdeal[l][side]; + double shift = m_laminationIdeal[l][side]; - double phi2pi = tmp_pos.Phi(); - if (side && phi2pi < -0.2) - { - phi2pi += 2 * M_PI; - } - if (!side && phi2pi < M_PI / 18 - 0.2) - { - phi2pi += 2 * M_PI; - } + double phi2pi = tmp_pos.Phi(); + if (side && phi2pi < -0.2) + { + phi2pi += 2 * M_PI; + } + if (!side && phi2pi < M_PI / 18 - 0.2) + { + phi2pi += 2 * M_PI; + } - if (phi2pi > shift - 0.2 && phi2pi < shift + 0.2) - { - m_hLamination[l][side]->Fill(tmp_pos.Perp(), phi2pi); - } + if (phi2pi > shift - 0.2 && phi2pi < shift + 0.2) + { + m_hLamination[l][side]->Fill(tmp_pos.Perp(), phi2pi); + } } } @@ -1211,9 +1211,22 @@ int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) } m_laminationTree->Write(); - m_hLamination[13][0]->Write(); - m_hLamination[13][1]->Write(); - m_hLamination[14][1]->Write(); + if(m_saveAllLaminationHistograms) + { + for(int s=0; s<2; s++) + { + for(int l=0; l<18; l++) + { + m_hLamination[l][s]->Write(); + } + } + } + else + { + m_hLamination[13][0]->Write(); + m_hLamination[13][1]->Write(); + m_hLamination[14][1]->Write(); + } outputfile->Close(); diff --git a/offline/packages/tpccalib/TpcLaminationFitting.h b/offline/packages/tpccalib/TpcLaminationFitting.h index d9aeddf75e..5285dff0d2 100644 --- a/offline/packages/tpccalib/TpcLaminationFitting.h +++ b/offline/packages/tpccalib/TpcLaminationFitting.h @@ -52,6 +52,8 @@ class TpcLaminationFitting : public SubsysReco void set_phiHistInRad(bool rad){ m_phiHist_in_rad = rad; } + void set_saveAllLaminationHistograms(bool save){ m_saveAllLaminationHistograms = save; } + void set_fieldOff(bool fieldOff){ m_fieldOff = fieldOff; } void set_grid_dimensions(int phibins, int rbins); @@ -124,6 +126,7 @@ class TpcLaminationFitting : public SubsysReco //std::map m_run_ZDC_map_auau; bool m_phiHist_in_rad{true}; + bool m_saveAllLaminationHistograms{false}; std::string m_stripePatternFile = "/sphenix/u/bkimelman/CMStripePattern.root"; From 0eafbd462cbe1aed06c1c6619a51fd2aaae12b8f Mon Sep 17 00:00:00 2001 From: bkimelman Date: Thu, 19 Feb 2026 10:59:49 -0500 Subject: [PATCH 248/393] Changed to range-based loop --- offline/packages/tpccalib/TpcLaminationFitting.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/offline/packages/tpccalib/TpcLaminationFitting.cc b/offline/packages/tpccalib/TpcLaminationFitting.cc index 68cea6f83d..9e1eda849d 100644 --- a/offline/packages/tpccalib/TpcLaminationFitting.cc +++ b/offline/packages/tpccalib/TpcLaminationFitting.cc @@ -1213,11 +1213,11 @@ int TpcLaminationFitting::End(PHCompositeNode * /*topNode*/) if(m_saveAllLaminationHistograms) { - for(int s=0; s<2; s++) + for(auto &i : m_hLamination) { - for(int l=0; l<18; l++) + for(auto &j : i) { - m_hLamination[l][s]->Write(); + j->Write(); } } } From fedd13a53561f7ba72f33c291020892b9f8c5721 Mon Sep 17 00:00:00 2001 From: Nikhil Kumar Date: Thu, 19 Feb 2026 18:51:08 -0500 Subject: [PATCH 249/393] add back the channel skip This was causing an out of bounds error --- offline/packages/CaloReco/CaloTowerBuilder.cc | 7 ++++--- offline/packages/CaloReco/CaloTowerBuilder.h | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/offline/packages/CaloReco/CaloTowerBuilder.cc b/offline/packages/CaloReco/CaloTowerBuilder.cc index 2584302138..6fb4fe9e40 100644 --- a/offline/packages/CaloReco/CaloTowerBuilder.cc +++ b/offline/packages/CaloReco/CaloTowerBuilder.cc @@ -273,6 +273,9 @@ int CaloTowerBuilder::process_data(PHCompositeNode *topNode, if (nchannels == 0) // push back -1 and return for empty packets { for (int channel = 0; channel < m_nchannels; channel++) { + if (skipChannel(channel, pid)) { + continue; + } std::vector waveform; waveform.reserve(m_nzerosuppsamples); for (int samp = 0; samp < m_nzerosuppsamples; samp++) { @@ -435,9 +438,7 @@ int CaloTowerBuilder::process_event(PHCompositeNode *topNode) { } int n_samples = waveforms.at(idx).size(); if (n_samples == m_nzerosuppsamples || SZS) { - if (waveforms.at(idx).at(0) == - -1) // set bit for missing and empty packets. - { + if (waveforms.at(idx).at(0) == -1) { towerinfo->set_isNotInstr(true); } else { towerinfo->set_isZS(true); diff --git a/offline/packages/CaloReco/CaloTowerBuilder.h b/offline/packages/CaloReco/CaloTowerBuilder.h index 0fc5694638..c3b0bd2e8c 100644 --- a/offline/packages/CaloReco/CaloTowerBuilder.h +++ b/offline/packages/CaloReco/CaloTowerBuilder.h @@ -20,7 +20,7 @@ class TowerInfoContainerv3; class CaloTowerBuilder : public SubsysReco { - public: +public: explicit CaloTowerBuilder(const std::string &name = "CaloTowerBuilder"); ~CaloTowerBuilder() override; @@ -129,7 +129,7 @@ class CaloTowerBuilder : public SubsysReco CaloWaveformProcessing *get_WaveformProcessing() { return WaveformProcessing; } - private: +private: int process_sim(); bool skipChannel(int ich, int pid); static bool isSZS(float time, float chi2); From 459341aa68a6b19ed17cd3b65ff393e0a8c5a2b3 Mon Sep 17 00:00:00 2001 From: Nikhil Kumar Date: Thu, 19 Feb 2026 20:41:52 -0500 Subject: [PATCH 250/393] one more attempt at fixing formatting.... --- offline/packages/CaloReco/CaloTowerBuilder.cc | 462 +++++++++++------- 1 file changed, 286 insertions(+), 176 deletions(-) diff --git a/offline/packages/CaloReco/CaloTowerBuilder.cc b/offline/packages/CaloReco/CaloTowerBuilder.cc index 6fb4fe9e40..53f44d9cb8 100644 --- a/offline/packages/CaloReco/CaloTowerBuilder.cc +++ b/offline/packages/CaloReco/CaloTowerBuilder.cc @@ -14,17 +14,17 @@ #include #include -#include // for SubsysReco +#include // for SubsysReco #include #include -#include // for PHIODataNode -#include // for PHNode -#include // for PHNodeIterator -#include // for PHObject +#include // for PHIODataNode +#include // for PHNode +#include // for PHNodeIterator +#include // for PHObject #include -#include // for CDBTTree +#include // for CDBTTree #include @@ -35,10 +35,10 @@ #include #include -#include // for operator<<, endl, basic... -#include // for allocator_traits<>::val... +#include // for operator<<, endl, basic... +#include // for allocator_traits<>::val... #include -#include // for vector +#include // for vector static const std::map nodemap{ {CaloTowerDefs::CEMC, "CEMCPackets"}, @@ -48,43 +48,50 @@ static const std::map nodemap{ {CaloTowerDefs::SEPD, "SEPDPackets"}}; //____________________________________________________________________________.. CaloTowerBuilder::CaloTowerBuilder(const std::string &name) - : SubsysReco(name), WaveformProcessing(new CaloWaveformProcessing()) {} + : SubsysReco(name) + , WaveformProcessing(new CaloWaveformProcessing()) +{ +} //____________________________________________________________________________.. -CaloTowerBuilder::~CaloTowerBuilder() { +CaloTowerBuilder::~CaloTowerBuilder() +{ delete cdbttree; delete cdbttree_tbt_zs; delete WaveformProcessing; } //____________________________________________________________________________.. -int CaloTowerBuilder::InitRun(PHCompositeNode *topNode) { +int CaloTowerBuilder::InitRun(PHCompositeNode *topNode) +{ WaveformProcessing->set_processing_type(_processingtype); - WaveformProcessing->set_softwarezerosuppression(m_bdosoftwarezerosuppression, - m_nsoftwarezerosuppression); - if (m_setTimeLim) { + WaveformProcessing->set_softwarezerosuppression(m_bdosoftwarezerosuppression, m_nsoftwarezerosuppression); + if (m_setTimeLim) + { WaveformProcessing->set_timeFitLim(m_timeLim_low, m_timeLim_high); } - if (m_dobitfliprecovery) { + if (m_dobitfliprecovery) + { WaveformProcessing->set_bitFlipRecovery(m_dobitfliprecovery); } // Set functional fit parameters - if (_processingtype == CaloWaveformProcessing::FUNCFIT) { + if (_processingtype == CaloWaveformProcessing::FUNCFIT) + { WaveformProcessing->set_funcfit_type(m_funcfit_type); WaveformProcessing->set_powerlaw_params(m_powerlaw_power, m_powerlaw_decay); - WaveformProcessing->set_doubleexp_params( - m_doubleexp_power, m_doubleexp_peaktime1, m_doubleexp_peaktime2, - m_doubleexp_ratio); + WaveformProcessing->set_doubleexp_params(m_doubleexp_power, m_doubleexp_peaktime1, m_doubleexp_peaktime2, m_doubleexp_ratio); } - if (m_dettype == CaloTowerDefs::CEMC) { + if (m_dettype == CaloTowerDefs::CEMC) + { m_detector = "CEMC"; m_packet_low = 6001; m_packet_high = 6128; m_nchannels = 192; WaveformProcessing->set_template_name("CEMC_TEMPLATE"); - if (_processingtype == CaloWaveformProcessing::NONE) { + if (_processingtype == CaloWaveformProcessing::NONE) + { WaveformProcessing->set_processing_type(CaloWaveformProcessing::TEMPLATE); } @@ -97,41 +104,47 @@ int CaloTowerBuilder::InitRun(PHCompositeNode *topNode) { m_fieldname = "adcskipmask"; calibdir = CDBInterface::instance()->getUrl(m_calibName); - if (calibdir.empty()) { - std::cout << PHWHERE - << "ADC Skip mask not found in CDB, not even in the default... " - << std::endl; + if (calibdir.empty()) + { + std::cout << PHWHERE << "ADC Skip mask not found in CDB, not even in the default... " << std::endl; exit(1); } cdbttree = new CDBTTree(calibdir); - } else if (m_dettype == CaloTowerDefs::HCALIN) { + } + else if (m_dettype == CaloTowerDefs::HCALIN) + { m_packet_low = 7001; m_packet_high = 7008; m_detector = "HCALIN"; m_nchannels = 192; WaveformProcessing->set_template_name("IHCAL_TEMPLATE"); - if (_processingtype == CaloWaveformProcessing::NONE) { + if (_processingtype == CaloWaveformProcessing::NONE) + { WaveformProcessing->set_processing_type(CaloWaveformProcessing::TEMPLATE); } - } else if (m_dettype == CaloTowerDefs::HCALOUT) { + } + else if (m_dettype == CaloTowerDefs::HCALOUT) + { m_detector = "HCALOUT"; m_packet_low = 8001; m_packet_high = 8008; m_nchannels = 192; WaveformProcessing->set_template_name("OHCAL_TEMPLATE"); - if (_processingtype == CaloWaveformProcessing::NONE) { + if (_processingtype == CaloWaveformProcessing::NONE) + { WaveformProcessing->set_processing_type(CaloWaveformProcessing::TEMPLATE); } - } else if (m_dettype == CaloTowerDefs::SEPD) { + } + else if (m_dettype == CaloTowerDefs::SEPD) + { m_detector = "SEPD"; m_packet_low = 9001; m_packet_high = 9006; m_nchannels = 128; WaveformProcessing->set_template_name("SEPD_TEMPLATE"); - if (_processingtype == CaloWaveformProcessing::NONE) { - WaveformProcessing->set_processing_type( - CaloWaveformProcessing::TEMPLATE); // default the EPD to fast - // processing + if (_processingtype == CaloWaveformProcessing::NONE) + { + WaveformProcessing->set_processing_type(CaloWaveformProcessing::TEMPLATE); // default the EPD to fast processing } m_calibName = "SEPD_CHANNELMAP2"; @@ -139,25 +152,28 @@ int CaloTowerBuilder::InitRun(PHCompositeNode *topNode) { calibdir = CDBInterface::instance()->getUrl(m_calibName); - if (calibdir.empty()) { - std::cout << PHWHERE << "No sEPD mapping file for domain " << m_calibName - << " found" << std::endl; + if (calibdir.empty()) + { + std::cout << PHWHERE << "No sEPD mapping file for domain " << m_calibName << " found" << std::endl; exit(1); } cdbttree_sepd_map = new CDBTTree(calibdir); - } else if (m_dettype == CaloTowerDefs::ZDC) { + } + else if (m_dettype == CaloTowerDefs::ZDC) + { m_detector = "ZDC"; m_packet_low = 12001; m_packet_high = 12001; m_nchannels = 128; - if (_processingtype == CaloWaveformProcessing::NONE) { - WaveformProcessing->set_processing_type( - CaloWaveformProcessing::FAST); // default the ZDC to fast processing + if (_processingtype == CaloWaveformProcessing::NONE) + { + WaveformProcessing->set_processing_type(CaloWaveformProcessing::FAST); // default the ZDC to fast processing } } WaveformProcessing->initialize_processing(); - if (m_dotbtszs) { + if (m_dotbtszs) + { cdbttree_tbt_zs = new CDBTTree(m_zsURL); } @@ -165,30 +181,36 @@ int CaloTowerBuilder::InitRun(PHCompositeNode *topNode) { return Fun4AllReturnCodes::EVENT_OK; } -int CaloTowerBuilder::process_sim() { +int CaloTowerBuilder::process_sim() +{ std::vector> waveforms; - for (int ich = 0; ich < (int)m_CalowaveformContainer->size(); ich++) { + for (int ich = 0; ich < (int) m_CalowaveformContainer->size(); ich++) + { TowerInfo *towerinfo = m_CalowaveformContainer->get_tower_at_channel(ich); std::vector waveform; waveform.reserve(m_nsamples); bool fillwaveform = true; // get key - if (m_dotbtszs) { + if (m_dotbtszs) + { unsigned int key = m_CalowaveformContainer->encode_key(ich); int zs_threshold = cdbttree_tbt_zs->GetIntValue(key, m_zs_fieldname); int pre = towerinfo->get_waveform_value(0); // this is always safe since towerinfo v3 has 31 samples int post = towerinfo->get_waveform_value(6); - if ((post - pre) <= zs_threshold) { + if ((post - pre) <= zs_threshold) + { // zero suppressed fillwaveform = false; waveform.push_back(pre); waveform.push_back(post); } } - if (fillwaveform) { - for (int samp = 0; samp < m_nsamples; samp++) { + if (fillwaveform) + { + for (int samp = 0; samp < m_nsamples; samp++) + { waveform.push_back(towerinfo->get_waveform_value(samp)); } } @@ -196,10 +218,10 @@ int CaloTowerBuilder::process_sim() { waveform.clear(); } - std::vector> processed_waveforms = - WaveformProcessing->process_waveform(waveforms); + std::vector> processed_waveforms = WaveformProcessing->process_waveform(waveforms); int n_channels = processed_waveforms.size(); - for (int i = 0; i < n_channels; i++) { + for (int i = 0; i < n_channels; i++) + { // this is for copying the truth info to the downstream object TowerInfo *towerwaveform = m_CalowaveformContainer->get_tower_at_channel(i); TowerInfo *towerinfo = m_CaloInfoContainer->get_tower_at_channel(i); @@ -209,20 +231,25 @@ int CaloTowerBuilder::process_sim() { towerinfo->set_time(processed_waveforms.at(i).at(1)); towerinfo->set_pedestal(processed_waveforms.at(i).at(2)); towerinfo->set_chi2(processed_waveforms.at(i).at(3)); - bool SZS = - isSZS(processed_waveforms.at(i).at(1), processed_waveforms.at(i).at(3)); - if (processed_waveforms.at(i).at(4) == 0) { + bool SZS = isSZS(processed_waveforms.at(i).at(1), processed_waveforms.at(i).at(3)); + if (processed_waveforms.at(i).at(4) == 0) + { towerinfo->set_isRecovered(false); - } else { + } + else + { towerinfo->set_isRecovered(true); } int n_samples = waveforms.at(i).size(); - if (n_samples == m_nzerosuppsamples || SZS) { + if (n_samples == m_nzerosuppsamples || SZS) + { towerinfo->set_isZS(true); } - for (int j = 0; j < n_samples; j++) { + for (int j = 0; j < n_samples; j++) + { towerinfo->set_waveform_value(j, waveforms.at(i).at(j)); - if (std::round(waveforms.at(i).at(j)) >= m_saturation) { + if (std::round(waveforms.at(i).at(j)) >= m_saturation) + { towerinfo->set_isSaturated(true); } } @@ -232,53 +259,66 @@ int CaloTowerBuilder::process_sim() { return Fun4AllReturnCodes::EVENT_OK; } -int CaloTowerBuilder::process_data(PHCompositeNode *topNode, - std::vector> &waveforms) { +int CaloTowerBuilder::process_data(PHCompositeNode *topNode, std::vector> &waveforms) +{ std::variant event; - if (m_UseOfflinePacketFlag) { - CaloPacketContainer *calopacketcontainer = - findNode::getClass( - topNode, nodemap.find(m_dettype)->second); - if (!calopacketcontainer) { - for (int pid = m_packet_low; pid <= m_packet_high; pid++) { - if (findNode::getClass(topNode, pid)) { + if (m_UseOfflinePacketFlag) + { + CaloPacketContainer *calopacketcontainer = findNode::getClass(topNode, nodemap.find(m_dettype)->second); + if (!calopacketcontainer) + { + for (int pid = m_packet_low; pid <= m_packet_high; pid++) + { + if (findNode::getClass(topNode, pid)) + { m_PacketNodesFlag = true; break; } } - if (!m_PacketNodesFlag) { + if (!m_PacketNodesFlag) + { return Fun4AllReturnCodes::EVENT_OK; } - } else { + } + else + { event = calopacketcontainer; } - } else { + } + else + { Event *_event = findNode::getClass(topNode, "PRDF"); - if (_event == nullptr) { + if (_event == nullptr) + { std::cout << PHWHERE << " Event not found" << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } - if (_event->getEvtType() != DATAEVENT) { + if (_event->getEvtType() != DATAEVENT) + { return Fun4AllReturnCodes::ABORTEVENT; } event = _event; } - // since the function call on Packet and CaloPacket is the same, maybe we can - // use lambda? - auto process_packet = [&](auto *packet, int pid) { - if (packet) { + // since the function call on Packet and CaloPacket is the same, maybe we can use lambda? + auto process_packet = [&](auto *packet, int pid) + { + if (packet) + { int nchannels = packet->iValue(0, "CHANNELS"); unsigned int adc_skip_mask = 0; - if (nchannels == 0) // push back -1 and return for empty packets + if (nchannels == 0) // push back -1 and return for empty packets { - for (int channel = 0; channel < m_nchannels; channel++) { - if (skipChannel(channel, pid)) { + for (int channel = 0; channel < m_nchannels; channel++) + { + if (skipChannel(channel, pid)) + { continue; } std::vector waveform; waveform.reserve(m_nzerosuppsamples); - for (int samp = 0; samp < m_nzerosuppsamples; samp++) { + for (int samp = 0; samp < m_nzerosuppsamples; samp++) + { waveform.push_back(-1); } waveforms.push_back(waveform); @@ -286,33 +326,41 @@ int CaloTowerBuilder::process_data(PHCompositeNode *topNode, return Fun4AllReturnCodes::EVENT_OK; } - if (m_dettype == CaloTowerDefs::CEMC) { + if (m_dettype == CaloTowerDefs::CEMC) + { adc_skip_mask = cdbttree->GetIntValue(pid, m_fieldname); } - if (m_dettype == CaloTowerDefs::ZDC) { + if (m_dettype == CaloTowerDefs::ZDC) + { nchannels = m_nchannels; } - if (nchannels > - m_nchannels) // packet is corrupted and reports too many channels + if (nchannels > m_nchannels) // packet is corrupted and reports too many channels { return Fun4AllReturnCodes::ABORTEVENT; } int n_pad_skip_mask = 0; - for (int channel = 0; channel < nchannels; channel++) { - if (skipChannel(channel, pid)) { + for (int channel = 0; channel < nchannels; channel++) + { + if (skipChannel(channel, pid)) + { continue; } - if (m_dettype == CaloTowerDefs::CEMC) { - if (channel % 64 == 0) { - unsigned int adcboard = (unsigned int)channel / 64; - if ((adc_skip_mask >> adcboard) & 0x1U) { - for (int iskip = 0; iskip < 64; iskip++) { + if (m_dettype == CaloTowerDefs::CEMC) + { + if (channel % 64 == 0) + { + unsigned int adcboard = (unsigned int) channel / 64; + if ((adc_skip_mask >> adcboard) & 0x1U) + { + for (int iskip = 0; iskip < 64; iskip++) + { n_pad_skip_mask++; std::vector waveform; waveform.reserve(m_nsamples); - for (int samp = 0; samp < m_nzerosuppsamples; samp++) { + for (int samp = 0; samp < m_nzerosuppsamples; samp++) + { waveform.push_back(0); } waveforms.push_back(waveform); @@ -324,11 +372,15 @@ int CaloTowerBuilder::process_data(PHCompositeNode *topNode, std::vector waveform; waveform.reserve(m_nsamples); - if (packet->iValue(channel, "SUPPRESSED")) { + if (packet->iValue(channel, "SUPPRESSED")) + { waveform.push_back(packet->iValue(channel, "PRE")); waveform.push_back(packet->iValue(channel, "POST")); - } else { - for (int samp = 0; samp < m_nsamples; samp++) { + } + else + { + for (int samp = 0; samp < m_nsamples; samp++) + { waveform.push_back(packet->iValue(samp, channel)); } } @@ -337,35 +389,43 @@ int CaloTowerBuilder::process_data(PHCompositeNode *topNode, } int nch_padded = nchannels; - if (m_dettype == CaloTowerDefs::CEMC) { + if (m_dettype == CaloTowerDefs::CEMC) + { nch_padded += n_pad_skip_mask; } - if (nch_padded < m_nchannels) { - for (int channel = 0; channel < m_nchannels - nch_padded; channel++) { - if (skipChannel(channel, pid)) { + if (nch_padded < m_nchannels) + { + for (int channel = 0; channel < m_nchannels - nch_padded; channel++) + { + if (skipChannel(channel, pid)) + { continue; } std::vector waveform; waveform.reserve(m_nsamples); - for (int samp = 0; samp < m_nzerosuppsamples; samp++) { + for (int samp = 0; samp < m_nzerosuppsamples; samp++) + { waveform.push_back(0); } waveforms.push_back(waveform); waveform.clear(); } } - } else // if the packet is missing treat constitutent channels as zero - // suppressed + } + else // if the packet is missing treat constitutent channels as zero suppressed { - for (int channel = 0; channel < m_nchannels; channel++) { - if (skipChannel(channel, pid)) { + for (int channel = 0; channel < m_nchannels; channel++) + { + if (skipChannel(channel, pid)) + { continue; } std::vector waveform; waveform.reserve(2); - for (int samp = 0; samp < m_nzerosuppsamples; samp++) { - waveform.push_back(-1); // push back -1 for missing packets + for (int samp = 0; samp < m_nzerosuppsamples; samp++) + { + waveform.push_back(-1); // push back -1 for missing packets } waveforms.push_back(waveform); waveform.clear(); @@ -374,23 +434,32 @@ int CaloTowerBuilder::process_data(PHCompositeNode *topNode, return Fun4AllReturnCodes::EVENT_OK; }; - for (int pid = m_packet_low; pid <= m_packet_high; pid++) { - if (!m_PacketNodesFlag) { - if (auto *hcalcont = std::get_if(&event)) { + for (int pid = m_packet_low; pid <= m_packet_high; pid++) + { + if (!m_PacketNodesFlag) + { + if (auto *hcalcont = std::get_if(&event)) + { CaloPacket *packet = (*hcalcont)->getPacketbyId(pid); - if (process_packet(packet, pid) == Fun4AllReturnCodes::ABORTEVENT) { + if (process_packet(packet, pid) == Fun4AllReturnCodes::ABORTEVENT) + { return Fun4AllReturnCodes::ABORTEVENT; } - } else if (auto *_event = std::get_if(&event)) { + } + else if (auto *_event = std::get_if(&event)) + { Packet *packet = (*_event)->getPacket(pid); - if (process_packet(packet, pid) == Fun4AllReturnCodes::ABORTEVENT) { + if (process_packet(packet, pid) == Fun4AllReturnCodes::ABORTEVENT) + { // I think it is safe to delete a nullptr... delete packet; return Fun4AllReturnCodes::ABORTEVENT; } delete packet; } - } else { + } + else + { CaloPacket *calopacket = findNode::getClass(topNode, pid); process_packet(calopacket, pid); } @@ -399,27 +468,32 @@ int CaloTowerBuilder::process_data(PHCompositeNode *topNode, return Fun4AllReturnCodes::EVENT_OK; } //____________________________________________________________________________.. -int CaloTowerBuilder::process_event(PHCompositeNode *topNode) { - if (!m_isdata) { +int CaloTowerBuilder::process_event(PHCompositeNode *topNode) +{ + if (!m_isdata) + { return process_sim(); } std::vector> waveforms; - if (process_data(topNode, waveforms) == Fun4AllReturnCodes::ABORTEVENT) { + if (process_data(topNode, waveforms) == Fun4AllReturnCodes::ABORTEVENT) + { return Fun4AllReturnCodes::ABORTEVENT; } - if (waveforms.empty()) { + if (waveforms.empty()) + { return Fun4AllReturnCodes::EVENT_OK; } - // waveform vector is filled here, now fill our output. methods from the base - // class make sure we only fill what the chosen container version supports - std::vector> processed_waveforms = - WaveformProcessing->process_waveform(waveforms); + // waveform vector is filled here, now fill our output. methods from the base class make sure + // we only fill what the chosen container version supports + std::vector> processed_waveforms = WaveformProcessing->process_waveform(waveforms); int n_channels = processed_waveforms.size(); - for (int i = 0; i < n_channels; i++) { + for (int i = 0; i < n_channels; i++) + { int idx = i; // Align sEPD ADC channels to TowerInfoContainer - if (m_dettype == CaloTowerDefs::SEPD) { + if (m_dettype == CaloTowerDefs::SEPD) + { idx = cdbttree_sepd_map->GetIntValue(i, m_fieldname); } TowerInfo *towerinfo = m_CaloInfoContainer->get_tower_at_channel(i); @@ -428,25 +502,33 @@ int CaloTowerBuilder::process_event(PHCompositeNode *topNode) { towerinfo->set_time(processed_waveforms.at(idx).at(1)); towerinfo->set_pedestal(processed_waveforms.at(idx).at(2)); towerinfo->set_chi2(processed_waveforms.at(idx).at(3)); - bool SZS = isSZS(processed_waveforms.at(idx).at(1), - processed_waveforms.at(idx).at(3)); + bool SZS = isSZS(processed_waveforms.at(idx).at(1), processed_waveforms.at(idx).at(3)); - if (processed_waveforms.at(idx).at(4) == 0) { + if (processed_waveforms.at(idx).at(4) == 0) + { towerinfo->set_isRecovered(false); - } else { + } + else + { towerinfo->set_isRecovered(true); } int n_samples = waveforms.at(idx).size(); - if (n_samples == m_nzerosuppsamples || SZS) { - if (waveforms.at(idx).at(0) == -1) { + if (n_samples == m_nzerosuppsamples || SZS) + { + if (waveforms.at(idx).at(0) == 0) + { towerinfo->set_isNotInstr(true); - } else { + } + else + { towerinfo->set_isZS(true); } } - for (int j = 0; j < n_samples; j++) { - if (std::round(waveforms.at(idx).at(j)) >= m_saturation) { + for (int j = 0; j < n_samples; j++) + { + if (std::round(waveforms.at(idx).at(j)) >= m_saturation) + { towerinfo->set_isSaturated(true); } towerinfo->set_waveform_value(j, waveforms.at(idx).at(j)); @@ -457,23 +539,30 @@ int CaloTowerBuilder::process_event(PHCompositeNode *topNode) { return Fun4AllReturnCodes::EVENT_OK; } -bool CaloTowerBuilder::skipChannel(int ich, int pid) { - if (m_dettype == CaloTowerDefs::SEPD) { +bool CaloTowerBuilder::skipChannel(int ich, int pid) +{ + if (m_dettype == CaloTowerDefs::SEPD) + { int sector = ((ich + 1) / 32); int emptych = -999; - if ((sector == 0) && (pid == 9001)) { + if ((sector == 0) && (pid == 9001)) + { emptych = 1; - } else { + } + else + { emptych = 14 + 32 * sector; } - if (ich == emptych) { + if (ich == emptych) + { return true; } } - if (m_dettype == CaloTowerDefs::ZDC) { - if (((ich > 17) && (ich < 48)) || ((ich > 63) && (ich < 80)) || - ((ich > 81) && (ich < 112))) { + if (m_dettype == CaloTowerDefs::ZDC) + { + if (((ich > 17) && (ich < 48)) || ((ich > 63) && (ich < 80)) || ((ich > 81) && (ich < 112))) + { return true; } } @@ -481,31 +570,34 @@ bool CaloTowerBuilder::skipChannel(int ich, int pid) { return false; } -bool CaloTowerBuilder::isSZS(float time, float chi2) { +bool CaloTowerBuilder::isSZS(float time, float chi2) +{ // isfinite - if (!std::isfinite(time) && !std::isfinite(chi2)) { + if (!std::isfinite(time) && !std::isfinite(chi2)) + { return true; } return false; } -void CaloTowerBuilder::CreateNodeTree(PHCompositeNode *topNode) { +void CaloTowerBuilder::CreateNodeTree(PHCompositeNode *topNode) +{ PHNodeIterator topNodeItr(topNode); // DST node - PHCompositeNode *dstNode = dynamic_cast( - topNodeItr.findFirst("PHCompositeNode", "DST")); - if (!dstNode) { + PHCompositeNode *dstNode = dynamic_cast(topNodeItr.findFirst("PHCompositeNode", "DST")); + if (!dstNode) + { std::cout << "PHComposite node created: DST" << std::endl; dstNode = new PHCompositeNode("DST"); topNode->addNode(dstNode); } - if (!m_isdata) { + if (!m_isdata) + { std::string waveformNodeName = m_inputNodePrefix + m_detector; - m_CalowaveformContainer = - findNode::getClass(topNode, waveformNodeName); - if (!m_CalowaveformContainer) { - std::cout << PHWHERE << "simulation waveform container " - << waveformNodeName << " not found" << std::endl; + m_CalowaveformContainer = findNode::getClass(topNode, waveformNodeName); + if (!m_CalowaveformContainer) + { + std::cout << PHWHERE << "simulation waveform container " << waveformNodeName << " not found" << std::endl; gSystem->Exit(1); exit(1); } @@ -514,55 +606,73 @@ void CaloTowerBuilder::CreateNodeTree(PHCompositeNode *topNode) { // towers PHNodeIterator nodeItr(dstNode); PHCompositeNode *DetNode; - // enum CaloTowerDefs::DetectorSystem and TowerInfoContainer::DETECTOR are - // different!!!! - TowerInfoContainer::DETECTOR DetectorEnum = - TowerInfoContainer::DETECTOR::DETECTOR_INVALID; + // enum CaloTowerDefs::DetectorSystem and TowerInfoContainer::DETECTOR are different!!!! + TowerInfoContainer::DETECTOR DetectorEnum = TowerInfoContainer::DETECTOR::DETECTOR_INVALID; std::string DetectorNodeName; - if (m_dettype == CaloTowerDefs::CEMC) { + if (m_dettype == CaloTowerDefs::CEMC) + { DetectorEnum = TowerInfoContainer::DETECTOR::EMCAL; DetectorNodeName = "CEMC"; - } else if (m_dettype == CaloTowerDefs::SEPD) { + } + else if (m_dettype == CaloTowerDefs::SEPD) + { DetectorEnum = TowerInfoContainer::DETECTOR::SEPD; DetectorNodeName = "SEPD"; - } else if (m_dettype == CaloTowerDefs::ZDC) { + } + else if (m_dettype == CaloTowerDefs::ZDC) + { DetectorEnum = TowerInfoContainer::DETECTOR::ZDC; DetectorNodeName = "ZDC"; - } else if (m_dettype == CaloTowerDefs::HCALIN) { + } + else if (m_dettype == CaloTowerDefs::HCALIN) + { DetectorEnum = TowerInfoContainer::DETECTOR::HCAL; DetectorNodeName = "HCALIN"; - } else if (m_dettype == CaloTowerDefs::HCALOUT) { + } + else if (m_dettype == CaloTowerDefs::HCALOUT) + { DetectorEnum = TowerInfoContainer::DETECTOR::HCAL; DetectorNodeName = "HCALOUT"; - } else { + } + else + { std::cout << PHWHERE << " Invalid detector type " << m_dettype << std::endl; gSystem->Exit(1); exit(1); } - DetNode = dynamic_cast( - nodeItr.findFirst("PHCompositeNode", DetectorNodeName)); - if (!DetNode) { + DetNode = dynamic_cast(nodeItr.findFirst("PHCompositeNode", DetectorNodeName)); + if (!DetNode) + { DetNode = new PHCompositeNode(DetectorNodeName); dstNode->addNode(DetNode); } - if (m_buildertype == CaloTowerDefs::kPRDFTowerv1) { + if (m_buildertype == CaloTowerDefs::kPRDFTowerv1) + { m_CaloInfoContainer = new TowerInfoContainerv1(DetectorEnum); - } else if (m_buildertype == CaloTowerDefs::kPRDFWaveform) { + } + else if (m_buildertype == CaloTowerDefs::kPRDFWaveform) + { m_CaloInfoContainer = new TowerInfoContainerv3(DetectorEnum); - } else if (m_buildertype == CaloTowerDefs::kWaveformTowerv2) { + } + else if (m_buildertype == CaloTowerDefs::kWaveformTowerv2) + { m_CaloInfoContainer = new TowerInfoContainerv2(DetectorEnum); - } else if (m_buildertype == CaloTowerDefs::kPRDFTowerv4) { + } + else if (m_buildertype == CaloTowerDefs::kPRDFTowerv4) + { m_CaloInfoContainer = new TowerInfoContainerv4(DetectorEnum); - } else if (m_buildertype == CaloTowerDefs::kWaveformTowerSimv1) { + } + else if (m_buildertype == CaloTowerDefs::kWaveformTowerSimv1) + { m_CaloInfoContainer = new TowerInfoContainerSimv1(DetectorEnum); - } else { - std::cout << PHWHERE << "invalid builder type " << m_buildertype - << std::endl; + } + else + { + std::cout << PHWHERE << "invalid builder type " << m_buildertype << std::endl; gSystem->Exit(1); exit(1); } TowerNodeName = m_outputNodePrefix + m_detector; - PHIODataNode *newTowerNode = new PHIODataNode( - m_CaloInfoContainer, TowerNodeName, "PHObject"); + PHIODataNode *newTowerNode = new PHIODataNode(m_CaloInfoContainer, TowerNodeName, "PHObject"); DetNode->addNode(newTowerNode); } From 376ab122970fc626cc30942a2346c2113e665e67 Mon Sep 17 00:00:00 2001 From: Nikhil Kumar Date: Thu, 19 Feb 2026 20:51:55 -0500 Subject: [PATCH 251/393] add verbosity to skimmer, and fix comments/formatting --- .../CaloStatusSkimmer/CaloStatusSkimmer.cc | 146 +++++++++++------- .../CaloStatusSkimmer/CaloStatusSkimmer.h | 3 + 2 files changed, 94 insertions(+), 55 deletions(-) diff --git a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc index 5011e2ff44..f2771a64fe 100644 --- a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc +++ b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc @@ -32,137 +32,175 @@ //____________________________________________________________________________.. CaloStatusSkimmer::CaloStatusSkimmer(const std::string &name) - : SubsysReco(name) { + : SubsysReco(name) +{ n_eventcounter = 0; n_skimcounter = 0; n_notowernodecounter = 0; - std::cout << "CaloStatusSkimmer::CaloStatusSkimmer(const std::string &name) " - "Calling ctor" - << std::endl; + std::cout << "CaloStatusSkimmer::CaloStatusSkimmer(const std::string &name) ""Calling ctor" << std::endl; } //____________________________________________________________________________.. -CaloStatusSkimmer::~CaloStatusSkimmer() { +CaloStatusSkimmer::~CaloStatusSkimmer() +{ // std::cout << "CaloStatusSkimmer::~CaloStatusSkimmer() Calling dtor" << // std::endl; } //____________________________________________________________________________.. -int CaloStatusSkimmer::Init(PHCompositeNode *topNode) { - std::cout << "CaloStatusSkimmer::Init(PHCompositeNode *topNode) Initializing" - << std::endl; +int CaloStatusSkimmer::Init(PHCompositeNode *topNode) +{ + std::cout << "CaloStatusSkimmer::Init(PHCompositeNode *topNode) Initializing" << std::endl; return Fun4AllReturnCodes::EVENT_OK; } //____________________________________________________________________________.. -int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) { +int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) +{ n_eventcounter++; - if (b_do_skim_EMCal) { + if (b_do_skim_EMCal) + { TowerInfoContainer *towers = findNode::getClass(topNode, "TOWERS_CEMC"); - if (!towers) { + if (!towers) + { n_notowernodecounter++; - std::cout << PHWHERE - << "calostatuscheck::process_event: missing TOWERS_CEMC\n"; + if (Verbosity > 0) + std::cout << PHWHERE << "calostatuscheck::process_event: missing TOWERS_CEMC" << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } const UInt_t ntowers = towers->size(); uint16_t notinstr_count = 0; - for (UInt_t ch = 0; ch < ntowers; ++ch) { + for (UInt_t ch = 0; ch < ntowers; ++ch) + { TowerInfo *tower = towers->get_tower_at_channel(ch); - if (tower->get_isNotInstr()) { + if (tower->get_isNotInstr()) + { ++notinstr_count; } } - if (notinstr_count >= m_EMC_skim_threshold) { + if (Verbosity > 9) + { + std::cout << "CaloStatusSkimmer::process_event: event " << n_eventcounter << ", ntowers in EMCal = " << ntowers << ", not-instrumented(empty/missing pckt) towers in EMCal = " << notinstr_count << std::endl; + } + + if (notinstr_count >= m_EMC_skim_threshold) + { n_skimcounter++; return Fun4AllReturnCodes::ABORTEVENT; } } - if (b_do_skim_HCal) { - TowerInfoContainer *hcalin_towers = - findNode::getClass(topNode, "TOWERS_HCALIN"); - TowerInfoContainer *hcalout_towers = - findNode::getClass(topNode, "TOWERS_HCALOUT"); - if (!hcalin_towers || !hcalout_towers) { + if (b_do_skim_HCal) + { + TowerInfoContainer *hcalin_towers = findNode::getClass(topNode, "TOWERS_HCALIN"); + TowerInfoContainer *hcalout_towers = findNode::getClass(topNode, "TOWERS_HCALOUT"); + if (!hcalin_towers || !hcalout_towers) + { n_notowernodecounter++; - std::cout << PHWHERE - << "calostatuscheck::process_event: missing TOWERS_HCALIN or " - "TOWERS_HCALOUT\n"; - return Fun4AllReturnCodes:: - ABORTEVENT; // do I want ABORTPROCESSING or just ABORTEVENT here? - // ABORTPROCESSING will stop the entire job, while - // ABORTEVENT will just skip this event and continue with - // the next one. + if (Verbosity > 0) + std::cout << PHWHERE << "calostatuscheck::process_event: missing TOWERS_HCALIN or TOWERS_HCALOUT" << std::endl; + return Fun4AllReturnCodes::ABORTEVENT; } const UInt_t ntowers_hcalin = hcalin_towers->size(); uint16_t notinstr_count_hcalin = 0; - for (UInt_t ch = 0; ch < ntowers_hcalin; ++ch) { + for (UInt_t ch = 0; ch < ntowers_hcalin; ++ch) + { TowerInfo *tower_in = hcalin_towers->get_tower_at_channel(ch); - if (tower_in->get_isNotInstr()) { + if (tower_in->get_isNotInstr()) + { ++notinstr_count_hcalin; } } const UInt_t ntowers_hcalout = hcalout_towers->size(); uint16_t notinstr_count_hcalout = 0; - for (UInt_t ch = 0; ch < ntowers_hcalout; ++ch) { + for (UInt_t ch = 0; ch < ntowers_hcalout; ++ch) + { TowerInfo *tower_out = hcalout_towers->get_tower_at_channel(ch); - if (tower_out->get_isNotInstr()) { + if (tower_out->get_isNotInstr()) + { ++notinstr_count_hcalout; } } + if (Verbosity > 9) + { + std::cout << "CaloStatusSkimmer::process_event: event " << n_eventcounter << ", ntowers in HCalIn = " << ntowers_hcalin << ", not-instrumented(empty/missing pckt) towers in HCalIn = " << notinstr_count_hcalin << ", ntowers in HCalOut = " << ntowers_hcalout << ", not-instrumented(empty/missing pckt) towers in HCalOut = " << notinstr_count_hcalout << std::endl; + } + if (notinstr_count_hcalin >= m_HCal_skim_threshold || - notinstr_count_hcalout >= m_HCal_skim_threshold) { + notinstr_count_hcalout >= m_HCal_skim_threshold) + { n_skimcounter++; return Fun4AllReturnCodes::ABORTEVENT; } } - if (b_do_skim_sEPD) { + if (b_do_skim_sEPD) + { TowerInfoContainer *sepd_towers = findNode::getClass(topNode, "TOWERS_SEPD"); - if (!sepd_towers) { + if (!sepd_towers) + { n_notowernodecounter++; - std::cout << PHWHERE - << "calostatuscheck::process_event: missing TOWERS_SEPD\n"; + if (Verbosity > 0) + std::cout << PHWHERE << "calostatuscheck::process_event: missing TOWERS_SEPD" << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } const UInt_t ntowers = sepd_towers->size(); uint16_t notinstr_count = 0; - for (UInt_t ch = 0; ch < ntowers; ++ch) { + for (UInt_t ch = 0; ch < ntowers; ++ch) + { TowerInfo *tower = sepd_towers->get_tower_at_channel(ch); - if (tower->get_isNotInstr()) { + if (tower->get_isNotInstr()) + { ++notinstr_count; } } - if (notinstr_count >= m_sEPD_skim_threshold) { + + if (Verbosity > 9) + { + std::cout << "CaloStatusSkimmer::process_event: event " << n_eventcounter << ", ntowers in sEPD = " << ntowers << ", not-instrumented(empty/missing pckt) towers in sEPD = " << notinstr_count << std::endl; + } + + if (notinstr_count >= m_sEPD_skim_threshold) + { n_skimcounter++; return Fun4AllReturnCodes::ABORTEVENT; } } - if (b_do_skim_ZDC) { + if (b_do_skim_ZDC) + { TowerInfoContainer *zdc_towers = findNode::getClass(topNode, "TOWERS_ZDC"); - if (!zdc_towers) { + if (!zdc_towers) + { n_notowernodecounter++; - std::cout << PHWHERE - << "calostatuscheck::process_event: missing TOWERS_ZDC\n"; + if (Verbosity > 0) + std::cout << PHWHERE << "calostatuscheck::process_event: missing TOWERS_ZDC" << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } const UInt_t ntowers = zdc_towers->size(); uint16_t notinstr_count = 0; - for (UInt_t ch = 0; ch < ntowers; ++ch) { + for (UInt_t ch = 0; ch < ntowers; ++ch) + { TowerInfo *tower = zdc_towers->get_tower_at_channel(ch); - if (tower->get_isNotInstr()) { + if (tower->get_isNotInstr()) + { ++notinstr_count; } } - if (notinstr_count >= m_ZDC_skim_threshold) { + + if (Verbosity > 9) + { + std::cout << "CaloStatusSkimmer::process_event: event " << n_eventcounter << ", ntowers in ZDC = " << ntowers << ", not-instrumented(empty/missing pckt) towers in ZDC = " << notinstr_count << std::endl; + } + + if (notinstr_count >= m_ZDC_skim_threshold) + { n_skimcounter++; return Fun4AllReturnCodes::ABORTEVENT; } @@ -172,14 +210,12 @@ int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) { } //____________________________________________________________________________.. -int CaloStatusSkimmer::End(PHCompositeNode *topNode) { - std::cout - << "CaloStatusSkimmer::End(PHCompositeNode *topNode) This is the End..." - << std::endl; +int CaloStatusSkimmer::End(PHCompositeNode *topNode) +{ + std::cout << "CaloStatusSkimmer::End(PHCompositeNode *topNode) This is the End..." << std::endl; std::cout << "Total events processed: " << n_eventcounter << std::endl; std::cout << "Total events skimmed: " << n_skimcounter << std::endl; - std::cout << "Total events with missing tower nodes: " << n_notowernodecounter - << std::endl; + std::cout << "Total events with missing tower nodes: " << n_notowernodecounter << std::endl; return Fun4AllReturnCodes::EVENT_OK; } diff --git a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h index 5126fefa05..cb1adc6d78 100644 --- a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h +++ b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h @@ -53,10 +53,13 @@ class CaloStatusSkimmer : public SubsysReco { m_ZDC_skim_threshold = threshold; } + void SetVerbosity(uint8_t v) { Verbosity = v; } + private: uint32_t n_eventcounter{0}; uint32_t n_skimcounter{0}; uint32_t n_notowernodecounter{0}; + uint8_t Verbosity{0}; bool b_do_skim_EMCal{false}; uint16_t m_EMC_skim_threshold{ From 24b72924c10831b2af6e2bf915628c8b5fa94100 Mon Sep 17 00:00:00 2001 From: Nikhil Kumar Date: Thu, 19 Feb 2026 21:11:47 -0500 Subject: [PATCH 252/393] code rabbit fixes remove includes fix revert of not instrument flag -should be if == -1, or <0, but I changed it back to ==0 when fixing the formatting. Use official verbosity method. --- offline/packages/CaloReco/CaloTowerBuilder.cc | 2 +- .../CaloStatusSkimmer/CaloStatusSkimmer.cc | 36 +++++-------------- .../CaloStatusSkimmer/CaloStatusSkimmer.h | 3 -- 3 files changed, 10 insertions(+), 31 deletions(-) diff --git a/offline/packages/CaloReco/CaloTowerBuilder.cc b/offline/packages/CaloReco/CaloTowerBuilder.cc index 53f44d9cb8..5082b9e9c3 100644 --- a/offline/packages/CaloReco/CaloTowerBuilder.cc +++ b/offline/packages/CaloReco/CaloTowerBuilder.cc @@ -515,7 +515,7 @@ int CaloTowerBuilder::process_event(PHCompositeNode *topNode) int n_samples = waveforms.at(idx).size(); if (n_samples == m_nzerosuppsamples || SZS) { - if (waveforms.at(idx).at(0) == 0) + if (waveforms.at(idx).at(0) == -1) { towerinfo->set_isNotInstr(true); } diff --git a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc index f2771a64fe..2b44734247 100644 --- a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc +++ b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc @@ -1,34 +1,16 @@ #include "CaloStatusSkimmer.h" #include -#include #include #include #include -// Tower stuff -#include #include -// #include #include -#include - -// ROOT stuff -#include -#include -#include -#include -#include - -// for cluster vertex correction -#include -#include -#include + #include #include -#include -#include //____________________________________________________________________________.. CaloStatusSkimmer::CaloStatusSkimmer(const std::string &name) @@ -65,7 +47,7 @@ int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) if (!towers) { n_notowernodecounter++; - if (Verbosity > 0) + if (Verbosity() > 0) std::cout << PHWHERE << "calostatuscheck::process_event: missing TOWERS_CEMC" << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } @@ -79,7 +61,7 @@ int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) ++notinstr_count; } } - if (Verbosity > 9) + if (Verbosity() > 9) { std::cout << "CaloStatusSkimmer::process_event: event " << n_eventcounter << ", ntowers in EMCal = " << ntowers << ", not-instrumented(empty/missing pckt) towers in EMCal = " << notinstr_count << std::endl; } @@ -98,7 +80,7 @@ int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) if (!hcalin_towers || !hcalout_towers) { n_notowernodecounter++; - if (Verbosity > 0) + if (Verbosity() > 0) std::cout << PHWHERE << "calostatuscheck::process_event: missing TOWERS_HCALIN or TOWERS_HCALOUT" << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } @@ -125,7 +107,7 @@ int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) } } - if (Verbosity > 9) + if (Verbosity() > 9) { std::cout << "CaloStatusSkimmer::process_event: event " << n_eventcounter << ", ntowers in HCalIn = " << ntowers_hcalin << ", not-instrumented(empty/missing pckt) towers in HCalIn = " << notinstr_count_hcalin << ", ntowers in HCalOut = " << ntowers_hcalout << ", not-instrumented(empty/missing pckt) towers in HCalOut = " << notinstr_count_hcalout << std::endl; } @@ -145,7 +127,7 @@ int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) if (!sepd_towers) { n_notowernodecounter++; - if (Verbosity > 0) + if (Verbosity() > 0) std::cout << PHWHERE << "calostatuscheck::process_event: missing TOWERS_SEPD" << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } @@ -160,7 +142,7 @@ int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) } } - if (Verbosity > 9) + if (Verbosity() > 9) { std::cout << "CaloStatusSkimmer::process_event: event " << n_eventcounter << ", ntowers in sEPD = " << ntowers << ", not-instrumented(empty/missing pckt) towers in sEPD = " << notinstr_count << std::endl; } @@ -179,7 +161,7 @@ int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) if (!zdc_towers) { n_notowernodecounter++; - if (Verbosity > 0) + if (Verbosity() > 0) std::cout << PHWHERE << "calostatuscheck::process_event: missing TOWERS_ZDC" << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } @@ -194,7 +176,7 @@ int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) } } - if (Verbosity > 9) + if (Verbosity() > 9) { std::cout << "CaloStatusSkimmer::process_event: event " << n_eventcounter << ", ntowers in ZDC = " << ntowers << ", not-instrumented(empty/missing pckt) towers in ZDC = " << notinstr_count << std::endl; } diff --git a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h index cb1adc6d78..5126fefa05 100644 --- a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h +++ b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h @@ -53,13 +53,10 @@ class CaloStatusSkimmer : public SubsysReco { m_ZDC_skim_threshold = threshold; } - void SetVerbosity(uint8_t v) { Verbosity = v; } - private: uint32_t n_eventcounter{0}; uint32_t n_skimcounter{0}; uint32_t n_notowernodecounter{0}; - uint8_t Verbosity{0}; bool b_do_skim_EMCal{false}; uint16_t m_EMC_skim_threshold{ From ce1451066fc308f9d8872a78e4ebdebf89c46578 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Fri, 20 Feb 2026 06:29:25 -0500 Subject: [PATCH 253/393] clang-tidy --- offline/packages/trackbase_historic/TrackAnalysisUtils.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/offline/packages/trackbase_historic/TrackAnalysisUtils.cc b/offline/packages/trackbase_historic/TrackAnalysisUtils.cc index cacbab9aec..d9331a0cd6 100644 --- a/offline/packages/trackbase_historic/TrackAnalysisUtils.cc +++ b/offline/packages/trackbase_historic/TrackAnalysisUtils.cc @@ -22,7 +22,7 @@ namespace TrackAnalysisUtils float calc_dedx(TrackSeed* tpcseed, TrkrClusterContainer* clustermap, ActsGeometry* tgeometry, - float thickness_per_region[4]) + const float thickness_per_region[4]) { std::vector clusterKeys; clusterKeys.insert(clusterKeys.end(), tpcseed->begin_cluster_keys(), @@ -99,7 +99,7 @@ namespace TrackAnalysisUtils float calc_dedx_calib(SvtxTrack* track, TrkrClusterContainer* cluster_map, ActsGeometry* tgeometry, - float thickness_per_region[4]) + const float thickness_per_region[4]) { auto clusterKeys = get_cluster_keys(track->get_tpc_seed()); @@ -141,7 +141,7 @@ namespace TrackAnalysisUtils float adc = cluster->getAdc(); float r = std::sqrt(cglob(0) * cglob(0) + cglob(1) * cglob(1)); - auto tpcseed = track->get_tpc_seed(); + auto *tpcseed = track->get_tpc_seed(); float alpha = (r * r) / (2 * r * std::abs(1.0 / tpcseed->get_qOverR())); float beta = std::atan(tpcseed->get_slope()); float alphacorr = std::cos(alpha); From 3a04b62b11a9a8f9d5f5bbac7461fd062c950861 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Fri, 20 Feb 2026 06:29:49 -0500 Subject: [PATCH 254/393] clang-format --- offline/packages/trackbase_historic/TrackAnalysisUtils.cc | 2 +- offline/packages/trackbase_historic/TrackAnalysisUtils.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/offline/packages/trackbase_historic/TrackAnalysisUtils.cc b/offline/packages/trackbase_historic/TrackAnalysisUtils.cc index d9331a0cd6..a31a3b8efb 100644 --- a/offline/packages/trackbase_historic/TrackAnalysisUtils.cc +++ b/offline/packages/trackbase_historic/TrackAnalysisUtils.cc @@ -141,7 +141,7 @@ namespace TrackAnalysisUtils float adc = cluster->getAdc(); float r = std::sqrt(cglob(0) * cglob(0) + cglob(1) * cglob(1)); - auto *tpcseed = track->get_tpc_seed(); + auto* tpcseed = track->get_tpc_seed(); float alpha = (r * r) / (2 * r * std::abs(1.0 / tpcseed->get_qOverR())); float beta = std::atan(tpcseed->get_slope()); float alphacorr = std::cos(alpha); diff --git a/offline/packages/trackbase_historic/TrackAnalysisUtils.h b/offline/packages/trackbase_historic/TrackAnalysisUtils.h index 00cca752f7..a0cc429f07 100644 --- a/offline/packages/trackbase_historic/TrackAnalysisUtils.h +++ b/offline/packages/trackbase_historic/TrackAnalysisUtils.h @@ -31,9 +31,9 @@ namespace TrackAnalysisUtils // to pass these from the geometry object, which keeps the dependencies // of this helper class minimal. This will also help us catch any changes // when/if the tpc geometry changes in the future. This is to get us going - float thickness_per_region[4]); + const float thickness_per_region[4]); float calc_dedx(TrackSeed* tpcseed, TrkrClusterContainer* clustermap, ActsGeometry* tgeometry, - float thickness_per_region[4]); + const float thickness_per_region[4]); std::pair get_residual(TrkrDefs::cluskey& ckey, SvtxTrack* track, TrkrClusterContainer* clustermap, From ecddd62c08e23cb45a76caf175a5a72ffdeb7a84 Mon Sep 17 00:00:00 2001 From: Hugo Pereira Da Costa Date: Fri, 20 Feb 2026 14:05:30 -0500 Subject: [PATCH 255/393] When disabling Micromegas clusters from fit, use acts to propagate the track parameters to any TPOT surface for which a cluster was found at the seeding stage. This is similar to the extrapolation performed to TPC layers in distortion-targeted Silicon-MM fit. This will allow to obtain unbiased residuals in the Micromegas. --- offline/packages/trackreco/PHActsTrkFitter.cc | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/offline/packages/trackreco/PHActsTrkFitter.cc b/offline/packages/trackreco/PHActsTrkFitter.cc index d361af240a..69e6f2dea5 100644 --- a/offline/packages/trackreco/PHActsTrkFitter.cc +++ b/offline/packages/trackreco/PHActsTrkFitter.cc @@ -1169,6 +1169,40 @@ void PHActsTrkFitter::updateSvtxTrack( } } + // also propagate to Micromegas if not used for the fit + /* this is be used to get unbiased residuals in TPOT */ + if ((!m_useMicromegas) && seed) + { + // acts propagator + ActsPropagator propagator(m_tGeometry); + + // loop over cluster keys associated to TPC seed + for (auto key_iter = seed->begin_cluster_keys(); key_iter != seed->end_cluster_keys(); ++key_iter) + { + const auto& cluskey = *key_iter; + + // make sure cluster is from Micromegas (TPOT) + const auto detId = TrkrDefs::getTrkrId(cluskey); + if (detId != TrkrDefs::micromegasId) + { continue; } + + // get corresponding surface + const auto hitsetkey = TrkrDefs::getHitSetKeyFromClusKey(cluskey); + const auto surface = m_tGeometry->maps().getMMSurface(hitsetkey); + + // get layer, propagate + auto result = propagator.propagateTrack(params, surface); + if (!result.ok()) { continue; } + + // get path length and extrapolated parameters + auto& [pathLength, trackStateParams] = result.value(); + pathLength /= Acts::UnitConstants::cm; + + // create track state and add to track + transformer.addTrackState(track, cluskey, pathLength, trackStateParams, m_transient_geocontext); + } + } + trackStateTimer.stop(); auto stateTime = trackStateTimer.get_accumulated_time(); From 46fc8ad4f56d70641dc0808c60346c53cee8cea3 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Fri, 20 Feb 2026 15:13:25 -0500 Subject: [PATCH 256/393] use our standard compiler flags --- .../framework/fun4all/CreateSubsysRecoModule.pl | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/offline/framework/fun4all/CreateSubsysRecoModule.pl b/offline/framework/fun4all/CreateSubsysRecoModule.pl index 51f64ea25c..7cd7095893 100755 --- a/offline/framework/fun4all/CreateSubsysRecoModule.pl +++ b/offline/framework/fun4all/CreateSubsysRecoModule.pl @@ -138,6 +138,8 @@ () print F "// void $classname\:\:Print(const std::string &what) const\n"; print F "// Called from the command line - useful to print information when you need it\n"; print F "//\n"; + print F "// [[maybe_unused]] suppresses compiler warnings if topNode is not used in this method\n"; + print F "//\n"; print F "//____________________________________________________________________________..\n"; print F "\n"; @@ -166,7 +168,7 @@ () print F "\n"; print F "//____________________________________________________________________________..\n"; - print F "int $classname\:\:Init(PHCompositeNode *topNode)\n"; + print F "int $classname\:\:Init([[maybe_unused]] PHCompositeNode *topNode)\n"; print F "{\n"; print F " std::cout << \"$classname\:\:Init(PHCompositeNode *topNode) Initializing\" << std::endl;\n"; print F " return Fun4AllReturnCodes::EVENT_OK;\n"; @@ -174,7 +176,7 @@ () print F "\n"; print F "//____________________________________________________________________________..\n"; - print F "int $classname\:\:InitRun(PHCompositeNode *topNode)\n"; + print F "int $classname\:\:InitRun([[maybe_unused]] PHCompositeNode *topNode)\n"; print F "{\n"; print F " std::cout << \"$classname\:\:InitRun(PHCompositeNode *topNode) Initializing for Run XXX\" << std::endl;\n"; print F " return Fun4AllReturnCodes::EVENT_OK;\n"; @@ -182,7 +184,7 @@ () print F "\n"; print F "//____________________________________________________________________________..\n"; - print F "int $classname\:\:process_event(PHCompositeNode *topNode)\n"; + print F "int $classname\:\:process_event([[maybe_unused]] PHCompositeNode *topNode)\n"; print F "{\n"; print F " std::cout << \"$classname\:\:process_event(PHCompositeNode *topNode) Processing Event\" << std::endl;\n"; print F " return Fun4AllReturnCodes::EVENT_OK;\n"; @@ -190,7 +192,7 @@ () print F "\n"; print F "//____________________________________________________________________________..\n"; - print F "int $classname\:\:ResetEvent(PHCompositeNode *topNode)\n"; + print F "int $classname\:\:ResetEvent([[maybe_unused]] PHCompositeNode *topNode)\n"; print F "{\n"; print F " std::cout << \"$classname\:\:ResetEvent(PHCompositeNode *topNode) Resetting internal structures, prepare for next event\" << std::endl;\n"; print F " return Fun4AllReturnCodes::EVENT_OK;\n"; @@ -206,7 +208,7 @@ () print F "\n"; print F "//____________________________________________________________________________..\n"; - print F "int $classname\:\:End(PHCompositeNode *topNode)\n"; + print F "int $classname\:\:End([[maybe_unused]] PHCompositeNode *topNode)\n"; print F "{\n"; print F " std::cout << \"$classname\:\:End(PHCompositeNode *topNode) This is the End...\" << std::endl;\n"; print F " return Fun4AllReturnCodes::EVENT_OK;\n"; @@ -214,7 +216,7 @@ () print F "\n"; print F "//____________________________________________________________________________..\n"; - print F "int $classname\:\:Reset(PHCompositeNode *topNode)\n"; + print F "int $classname\:\:Reset([[maybe_unused]] PHCompositeNode *topNode)\n"; print F "{\n"; print F " std::cout << \"$classname\:\:Reset(PHCompositeNode *topNode) being Reset\" << std::endl;\n"; print F " return Fun4AllReturnCodes::EVENT_OK;\n"; @@ -331,7 +333,7 @@ () print F "dnl no point in suppressing warnings people should \n"; print F "dnl at least see them, so here we go for g++: -Wall\n"; print F "if test \$ac_cv_prog_gxx = yes; then\n"; - print F " CXXFLAGS=\"\$CXXFLAGS -Wall -Werror\"\n"; + print F " CXXFLAGS=\"\$CXXFLAGS -Wall -Wextra -Wshadow -Werror\"\n"; print F "fi\n"; print F "\n"; From bd14497a9ad33636f81acb75b764b03f57672df8 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Fri, 20 Feb 2026 15:18:53 -0500 Subject: [PATCH 257/393] use our standard compiler flags --- simulation/g4simulation/g4detectors/CreateG4Subsystem.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simulation/g4simulation/g4detectors/CreateG4Subsystem.pl b/simulation/g4simulation/g4detectors/CreateG4Subsystem.pl index f74af6957d..ccb34eca34 100755 --- a/simulation/g4simulation/g4detectors/CreateG4Subsystem.pl +++ b/simulation/g4simulation/g4detectors/CreateG4Subsystem.pl @@ -1007,7 +1007,7 @@ () print F "dnl no point in suppressing warnings people should \n"; print F "dnl at least see them, so here we go for g++: -Wall\n"; print F "if test \$ac_cv_prog_gxx = yes; then\n"; - print F " CXXFLAGS=\"\$CXXFLAGS -Wall -Werror\"\n"; + print F " CXXFLAGS=\"\$CXXFLAGS -Wall -Wextra -Wshadow -Werror\"\n"; print F "fi\n"; print F "\n"; From 739117ba21196b50eaeeb76da00655fe311646be Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Fri, 20 Feb 2026 15:20:32 -0500 Subject: [PATCH 258/393] use -isystem instead of -I for include paths --- simulation/g4simulation/g4detectors/CreateG4Subsystem.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/simulation/g4simulation/g4detectors/CreateG4Subsystem.pl b/simulation/g4simulation/g4detectors/CreateG4Subsystem.pl index ccb34eca34..a1dbd352c3 100755 --- a/simulation/g4simulation/g4detectors/CreateG4Subsystem.pl +++ b/simulation/g4simulation/g4detectors/CreateG4Subsystem.pl @@ -1027,8 +1027,8 @@ () print F "AM_CPPFLAGS = \\\n"; print F " -I\$(includedir) \\\n"; - print F " -I\$(OFFLINE_MAIN)/include \\\n"; - print F " -I\$(ROOTSYS)/include \n"; + print F " -isystem\$(OFFLINE_MAIN)/include \\\n"; + print F " -isystem\$(ROOTSYS)/include \n"; print F "\n"; print F "AM_LDFLAGS = \\\n"; From bf4806d4c90c1ee9fbcd873c047d9fc4a65a3466 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Fri, 20 Feb 2026 15:22:23 -0500 Subject: [PATCH 259/393] use -isystem instead of -I for include paths --- offline/framework/fun4all/CreateSubsysRecoModule.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/framework/fun4all/CreateSubsysRecoModule.pl b/offline/framework/fun4all/CreateSubsysRecoModule.pl index 7cd7095893..f46c37053d 100755 --- a/offline/framework/fun4all/CreateSubsysRecoModule.pl +++ b/offline/framework/fun4all/CreateSubsysRecoModule.pl @@ -350,7 +350,7 @@ () print F "AM_CPPFLAGS = \\\n"; print F " -I\$(includedir) \\\n"; - print F " -I\$(OFFLINE_MAIN)/include \\\n"; + print F " -isystem\$(OFFLINE_MAIN)/include \\\n"; print F " -isystem\$(ROOTSYS)/include\n"; print F "\n"; From a139a428cc24a66a70ec0cd6af78ed4adebc6c04 Mon Sep 17 00:00:00 2001 From: Hugo Pereira Da Costa Date: Fri, 20 Feb 2026 14:12:34 -0700 Subject: [PATCH 260/393] Update offline/packages/trackreco/PHActsTrkFitter.cc Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- offline/packages/trackreco/PHActsTrkFitter.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/offline/packages/trackreco/PHActsTrkFitter.cc b/offline/packages/trackreco/PHActsTrkFitter.cc index 69e6f2dea5..fc09c56067 100644 --- a/offline/packages/trackreco/PHActsTrkFitter.cc +++ b/offline/packages/trackreco/PHActsTrkFitter.cc @@ -1189,6 +1189,7 @@ void PHActsTrkFitter::updateSvtxTrack( // get corresponding surface const auto hitsetkey = TrkrDefs::getHitSetKeyFromClusKey(cluskey); const auto surface = m_tGeometry->maps().getMMSurface(hitsetkey); + if (!surface) { continue; } // get layer, propagate auto result = propagator.propagateTrack(params, surface); From 2a43e6fc6d96893849cf96ab73756649282bb705 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Fri, 20 Feb 2026 16:22:56 -0500 Subject: [PATCH 261/393] make it compile --- .../CaloStatusSkimmer/CaloStatusSkimmer.cc | 36 ++++++------------- .../CaloStatusSkimmer/CaloStatusSkimmer.h | 9 +---- .../Skimmers/CaloStatusSkimmer/autogen.sh | 0 3 files changed, 12 insertions(+), 33 deletions(-) mode change 100644 => 100755 offline/packages/Skimmers/CaloStatusSkimmer/autogen.sh diff --git a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc index 2b44734247..08b3ae34a6 100644 --- a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc +++ b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc @@ -22,20 +22,6 @@ CaloStatusSkimmer::CaloStatusSkimmer(const std::string &name) std::cout << "CaloStatusSkimmer::CaloStatusSkimmer(const std::string &name) ""Calling ctor" << std::endl; } -//____________________________________________________________________________.. -CaloStatusSkimmer::~CaloStatusSkimmer() -{ - // std::cout << "CaloStatusSkimmer::~CaloStatusSkimmer() Calling dtor" << - // std::endl; -} - -//____________________________________________________________________________.. -int CaloStatusSkimmer::Init(PHCompositeNode *topNode) -{ - std::cout << "CaloStatusSkimmer::Init(PHCompositeNode *topNode) Initializing" << std::endl; - return Fun4AllReturnCodes::EVENT_OK; -} - //____________________________________________________________________________.. int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) { @@ -51,9 +37,9 @@ int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) std::cout << PHWHERE << "calostatuscheck::process_event: missing TOWERS_CEMC" << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } - const UInt_t ntowers = towers->size(); + const uint32_t ntowers = towers->size(); uint16_t notinstr_count = 0; - for (UInt_t ch = 0; ch < ntowers; ++ch) + for (uint32_t ch = 0; ch < ntowers; ++ch) { TowerInfo *tower = towers->get_tower_at_channel(ch); if (tower->get_isNotInstr()) @@ -85,9 +71,9 @@ int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) return Fun4AllReturnCodes::ABORTEVENT; } - const UInt_t ntowers_hcalin = hcalin_towers->size(); + const uint32_t ntowers_hcalin = hcalin_towers->size(); uint16_t notinstr_count_hcalin = 0; - for (UInt_t ch = 0; ch < ntowers_hcalin; ++ch) + for (uint32_t ch = 0; ch < ntowers_hcalin; ++ch) { TowerInfo *tower_in = hcalin_towers->get_tower_at_channel(ch); if (tower_in->get_isNotInstr()) @@ -96,9 +82,9 @@ int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) } } - const UInt_t ntowers_hcalout = hcalout_towers->size(); + const uint32_t ntowers_hcalout = hcalout_towers->size(); uint16_t notinstr_count_hcalout = 0; - for (UInt_t ch = 0; ch < ntowers_hcalout; ++ch) + for (uint32_t ch = 0; ch < ntowers_hcalout; ++ch) { TowerInfo *tower_out = hcalout_towers->get_tower_at_channel(ch); if (tower_out->get_isNotInstr()) @@ -131,9 +117,9 @@ int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) std::cout << PHWHERE << "calostatuscheck::process_event: missing TOWERS_SEPD" << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } - const UInt_t ntowers = sepd_towers->size(); + const uint32_t ntowers = sepd_towers->size(); uint16_t notinstr_count = 0; - for (UInt_t ch = 0; ch < ntowers; ++ch) + for (uint32_t ch = 0; ch < ntowers; ++ch) { TowerInfo *tower = sepd_towers->get_tower_at_channel(ch); if (tower->get_isNotInstr()) @@ -165,9 +151,9 @@ int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) std::cout << PHWHERE << "calostatuscheck::process_event: missing TOWERS_ZDC" << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } - const UInt_t ntowers = zdc_towers->size(); + const uint32_t ntowers = zdc_towers->size(); uint16_t notinstr_count = 0; - for (UInt_t ch = 0; ch < ntowers; ++ch) + for (uint32_t ch = 0; ch < ntowers; ++ch) { TowerInfo *tower = zdc_towers->get_tower_at_channel(ch); if (tower->get_isNotInstr()) @@ -192,7 +178,7 @@ int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) } //____________________________________________________________________________.. -int CaloStatusSkimmer::End(PHCompositeNode *topNode) +int CaloStatusSkimmer::End([[maybe_unused]] PHCompositeNode *topNode) { std::cout << "CaloStatusSkimmer::End(PHCompositeNode *topNode) This is the End..." << std::endl; std::cout << "Total events processed: " << n_eventcounter << std::endl; diff --git a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h index 5126fefa05..628a582917 100644 --- a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h +++ b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h @@ -16,14 +16,7 @@ class CaloStatusSkimmer : public SubsysReco { public: CaloStatusSkimmer(const std::string &name = "CaloStatusSkimmer"); - ~CaloStatusSkimmer() override; - - /** Called during initialization. - Typically this is where you can book histograms, and e.g. - register them to Fun4AllServer (so they can be output to file - using Fun4AllServer::dumpHistos() method). - */ - int Init(PHCompositeNode *topNode) override; + ~CaloStatusSkimmer() override = default; /** Called for each event. This is where you do the real work. diff --git a/offline/packages/Skimmers/CaloStatusSkimmer/autogen.sh b/offline/packages/Skimmers/CaloStatusSkimmer/autogen.sh old mode 100644 new mode 100755 From ecb09d33dabd8940bd92bb8fb8aca6a5787e4fbc Mon Sep 17 00:00:00 2001 From: Hugo Pereira Da Costa Date: Fri, 20 Feb 2026 17:55:29 -0500 Subject: [PATCH 262/393] fixed comments --- offline/packages/trackreco/PHActsTrkFitter.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/trackreco/PHActsTrkFitter.cc b/offline/packages/trackreco/PHActsTrkFitter.cc index fc09c56067..d0006ac25c 100644 --- a/offline/packages/trackreco/PHActsTrkFitter.cc +++ b/offline/packages/trackreco/PHActsTrkFitter.cc @@ -1191,7 +1191,7 @@ void PHActsTrkFitter::updateSvtxTrack( const auto surface = m_tGeometry->maps().getMMSurface(hitsetkey); if (!surface) { continue; } - // get layer, propagate + // propagate auto result = propagator.propagateTrack(params, surface); if (!result.ok()) { continue; } From 3e526f3ee6612c5d75b72a0c1ffff6f1b92f36c0 Mon Sep 17 00:00:00 2001 From: Hugo Pereira Da Costa Date: Fri, 20 Feb 2026 17:55:32 -0500 Subject: [PATCH 263/393] clang-tidy --- .../trackbase_historic/TrackAnalysisUtils.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/offline/packages/trackbase_historic/TrackAnalysisUtils.cc b/offline/packages/trackbase_historic/TrackAnalysisUtils.cc index 744949c8fe..eee8283b61 100644 --- a/offline/packages/trackbase_historic/TrackAnalysisUtils.cc +++ b/offline/packages/trackbase_historic/TrackAnalysisUtils.cc @@ -18,7 +18,7 @@ namespace TrackAnalysisUtils float calc_dedx(TrackSeed* tpcseed, TrkrClusterContainer* clustermap, ActsGeometry* tgeometry, - float thickness_per_region[4]) + float const thickness_per_region[4]) { std::vector clusterKeys; clusterKeys.insert(clusterKeys.end(), tpcseed->begin_cluster_keys(), @@ -95,10 +95,10 @@ namespace TrackAnalysisUtils float calc_dedx_calib(SvtxTrack* track, TrkrClusterContainer* cluster_map, ActsGeometry* tgeometry, - float thickness_per_region[4]) + float const thickness_per_region[4]) { auto clusterKeys = get_cluster_keys(track->get_tpc_seed()); - + std::vector dedxlist; for (unsigned long cluster_key : clusterKeys) { @@ -137,7 +137,7 @@ namespace TrackAnalysisUtils float adc = cluster->getAdc(); float r = std::sqrt(cglob(0) * cglob(0) + cglob(1) * cglob(1)); - auto tpcseed = track->get_tpc_seed(); + auto* tpcseed = track->get_tpc_seed(); float alpha = (r * r) / (2 * r * std::abs(1.0 / tpcseed->get_qOverR())); float beta = std::atan(tpcseed->get_slope()); float alphacorr = std::cos(alpha); @@ -152,8 +152,8 @@ namespace TrackAnalysisUtils } if(track->get_crossing() < SHRT_MAX) { - double z_crossing_corrected = - TpcClusterZCrossingCorrection::correctZ(cglob.z(), + double z_crossing_corrected = + TpcClusterZCrossingCorrection::correctZ(cglob.z(), TpcDefs::getSide(cluster_key), track->get_crossing()); double maxz = tgeometry->get_max_driftlength() + tgeometry->get_CM_halfwidth(); @@ -201,7 +201,7 @@ namespace TrackAnalysisUtils vertexCov(i, j) = vertex->get_error(i, j); } } - + Acts::ActsSquareMatrix<3> rotCov = rot * (posCov+vertexCov) * rot_T; dca.first.second = sqrt(rotCov(0, 0)); @@ -274,12 +274,12 @@ namespace TrackAnalysisUtils std::vector get_cluster_keys(TrackSeed* seed) { std::vector out; - + if (seed) { std::copy(seed->begin_cluster_keys(), seed->end_cluster_keys(), std::back_inserter(out)); } - + return out; } From 7dcddfcdc133399bbaf7f8a0ca7b849a8cf7b488 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Sat, 21 Feb 2026 14:08:31 -0500 Subject: [PATCH 264/393] small cosmetic changes --- .../sepd_eventplanecalib/EventPlaneData.cc | 2 + .../sepd_eventplanecalib/EventPlaneData.h | 1 - .../sepd/sepd_eventplanecalib/QVecCalib.cc | 108 +++++++++--------- .../sepd/sepd_eventplanecalib/QVecCalib.h | 22 ++-- .../sepd/sepd_eventplanecalib/QVecDefs.h | 6 +- .../sepd/sepd_eventplanecalib/sEPD_TreeGen.cc | 35 +++--- .../sepd/sepd_eventplanecalib/sEPD_TreeGen.h | 21 +--- 7 files changed, 92 insertions(+), 103 deletions(-) diff --git a/calibrations/sepd/sepd_eventplanecalib/EventPlaneData.cc b/calibrations/sepd/sepd_eventplanecalib/EventPlaneData.cc index 6dedea4a15..57c3fcfc58 100644 --- a/calibrations/sepd/sepd_eventplanecalib/EventPlaneData.cc +++ b/calibrations/sepd/sepd_eventplanecalib/EventPlaneData.cc @@ -1,5 +1,7 @@ #include "EventPlaneData.h" +#include + EventPlaneData::EventPlaneData() { sepd_charge.fill(0); diff --git a/calibrations/sepd/sepd_eventplanecalib/EventPlaneData.h b/calibrations/sepd/sepd_eventplanecalib/EventPlaneData.h index 255f488712..d9ffea19c9 100644 --- a/calibrations/sepd/sepd_eventplanecalib/EventPlaneData.h +++ b/calibrations/sepd/sepd_eventplanecalib/EventPlaneData.h @@ -6,7 +6,6 @@ #include #include -#include #include class EventPlaneData : public PHObject diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc index 4a1c9d7e51..83e0b80489 100644 --- a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc +++ b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc @@ -23,6 +23,12 @@ // -- CDBTTree #include +#include +#include +#include +#include + + // ==================================================================== // Standard C++ Includes // ==================================================================== @@ -34,16 +40,19 @@ QVecCalib::QVecCalib(const std::string &name): SubsysReco(name) { - std::cout << "QVecCalib::QVecCalib(const std::string &name) Calling ctor" << std::endl; + // std::cout << "QVecCalib::QVecCalib(const std::string &name) Calling ctor" << std::endl; } //____________________________________________________________________________.. int QVecCalib::Init([[maybe_unused]] PHCompositeNode *topNode) { - std::cout << "QVecCalib::Init(PHCompositeNode *topNode) Initializing" << std::endl; + if (Verbosity() > 1) + { + std::cout << "QVecCalib::Init(PHCompositeNode *topNode) Initializing" << std::endl; - Fun4AllServer *se = Fun4AllServer::instance(); - se->Print("NODETREE"); + Fun4AllServer *se = Fun4AllServer::instance(); + se->Print("NODETREE"); + } int ret = process_QA_hist(); if (ret) @@ -122,7 +131,8 @@ int QVecCalib::process_sEPD_event_thresholds(TFile* file) std::string sepd_totalcharge_centrality = "h2SEPD_totalcharge_centrality"; - auto* hist = file->Get(sepd_totalcharge_centrality.c_str()); + TH2 *hist {nullptr}; + file->GetObject(sepd_totalcharge_centrality.c_str(),hist); // Check if the hist is stored in the file if (hist == nullptr) @@ -189,7 +199,8 @@ int QVecCalib::process_bad_channels(TFile* file) std::string sepd_charge_hist = "hSEPD_Charge"; - auto* hSEPD_Charge = file->Get(sepd_charge_hist.c_str()); + TProfile *hSEPD_Charge{nullptr}; + file->GetObject(sepd_charge_hist.c_str(), hSEPD_Charge); // Check if the hist is stored in the file if (hSEPD_Charge == nullptr) @@ -229,14 +240,6 @@ int QVecCalib::process_bad_channels(TFile* file) se->registerHisto(h2SEPD_North_Charge_rbinv2); se->registerHisto(hSEPD_Bad_Channels); - auto* h2S = h2SEPD_South_Charge_rbin; - auto* h2N = h2SEPD_North_Charge_rbin; - - auto* h2Sv2 = h2SEPD_South_Charge_rbinv2; - auto* h2Nv2 = h2SEPD_North_Charge_rbinv2; - - auto* hBad = hSEPD_Bad_Channels; - for (int channel = 0; channel < QVecShared::SEPD_CHANNELS; ++channel) { unsigned int key = TowerInfoDefs::encode_epd(channel); @@ -245,13 +248,13 @@ int QVecCalib::process_bad_channels(TFile* file) double avg_charge = hSEPD_Charge->GetBinContent(channel + 1); - auto* h2 = (arm == 0) ? h2S : h2N; + auto* h2 = (arm == 0) ? h2SEPD_South_Charge_rbin : h2SEPD_North_Charge_rbin; h2->Fill(rbin, avg_charge); } - auto* hSpx = h2S->ProfileX("hSpx", 2, -1, "s"); - auto* hNpx = h2N->ProfileX("hNpx", 2, -1, "s"); + auto* hSpx = h2SEPD_South_Charge_rbin->ProfileX("hSpx", 2, -1, "s"); + auto* hNpx = h2SEPD_North_Charge_rbin->ProfileX("hNpx", 2, -1, "s"); int ctr_dead = 0; int ctr_hot = 0; @@ -263,7 +266,7 @@ int QVecCalib::process_bad_channels(TFile* file) int rbin = TowerInfoDefs::get_epd_rbin(key); unsigned int arm = TowerInfoDefs::get_epd_arm(key); - auto* h2 = (arm == 0) ? h2Sv2 : h2Nv2; + auto* h2 = (arm == 0) ? h2SEPD_South_Charge_rbinv2 : h2SEPD_North_Charge_rbinv2; auto* hprof = (arm == 0) ? hSpx : hNpx; double charge = hSEPD_Charge->GetBinContent(channel + 1); @@ -281,31 +284,31 @@ int QVecCalib::process_bad_channels(TFile* file) m_bad_channels.insert(channel); std::string type; - int status_fill; + QVecShared::ChannelStatus status_fill; // dead channel if (charge == 0) { type = "Dead"; - status_fill = static_cast(QVecShared::ChannelStatus::Dead); + status_fill = QVecShared::ChannelStatus::Dead; ++ctr_dead; } // hot channel else if (zscore > m_sEPD_sigma_threshold) { type = "Hot"; - status_fill = static_cast(QVecShared::ChannelStatus::Hot); + status_fill = QVecShared::ChannelStatus::Hot; ++ctr_hot; } // cold channel else { type = "Cold"; - status_fill = static_cast(QVecShared::ChannelStatus::Cold); + status_fill = QVecShared::ChannelStatus::Cold; ++ctr_cold; } - hBad->Fill(channel, status_fill); + hSEPD_Bad_Channels->Fill(channel, static_cast(status_fill)); std::cout << std::format("{:4} Channel: {:3d}, arm: {}, rbin: {:2d}, Mean: {:5.2f}, Charge: {:5.2f}, Z-Score: {:5.2f}", type, channel, arm, rbin, mean_charge, charge, zscore) << std::endl; } @@ -315,7 +318,8 @@ int QVecCalib::process_bad_channels(TFile* file) } } - std::cout << std::format("Total Bad Channels: {}, Dead: {}, Hot: {}, Cold: {}", m_bad_channels.size(), ctr_dead, ctr_hot, ctr_cold) << std::endl; + std::cout << "Total Bad Channels: " << m_bad_channels.size() << ", Dead: " + << ctr_dead << ", Hot: " << ctr_hot << ", Cold: " << ctr_cold << std::endl; std::cout << "Finished processing Hot sEPD channels" << std::endl; return Fun4AllReturnCodes::EVENT_OK; @@ -460,8 +464,9 @@ std::array, 2> QVecCalib::calculate_flattening_matrix(doub double N_term = D * (xx + yy + (2 * D)); if (N_term <= 0) { - throw std::runtime_error(std::format( - "Invalid N-term ({}) for n={}, cent={}, det={}", N_term, n, cent_bin, det_label)); + std::cout << "Invalid N-term (" << N_term << ") for n=" << n << ", cent=" << cent_bin + << ", det=" << det_label << std::endl; + exit(1); } double inv_sqrt_N = 1.0 / std::sqrt(N_term); @@ -475,10 +480,12 @@ std::array, 2> QVecCalib::calculate_flattening_matrix(doub template T* QVecCalib::load_and_clone(TFile* file, const std::string& name) { - auto* obj = file->Get(name.c_str()); + T *obj {nullptr}; + file->GetObject(name.c_str(),obj); if (!obj) { - throw std::runtime_error(std::format("Could not find histogram '{}' in file '{}'", name, file->GetName())); + std::cout << "Could not find histogram " << name << " in file " << file->GetName() << std::endl; + exit(1); } return static_cast(obj->Clone()); } @@ -494,8 +501,6 @@ int QVecCalib::load_correction_data() return Fun4AllReturnCodes::ABORTRUN; } - using SD = QVecShared::Subdetector; - for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) { int n = m_harmonics[h_idx]; @@ -544,7 +549,7 @@ int QVecCalib::load_correction_data() if (m_pass == Pass::ApplyFlattening) { // Populate Flattening for S, N, and NS - for (int d = 0; d < (int) SD::Count; ++d) + for (int d = 0; d < (int) QVecShared::Subdetector::Count; ++d) { std::string det_str; switch (d) @@ -822,7 +827,7 @@ void QVecCalib::process_averages(double cent, const QVecShared::QVec& q_S, const void QVecCalib::process_recentering(double cent, size_t h_idx, const QVecShared::QVec& q_S, const QVecShared::QVec& q_N, const RecenterHists& h) { - size_t cent_bin = static_cast(hCentrality->FindBin(cent) - 1); + int cent_bin = hCentrality->FindBin(cent) - 1; const auto& S = m_correction_data[cent_bin][h_idx][(size_t) QVecShared::Subdetector::S]; const auto& N = m_correction_data[cent_bin][h_idx][(size_t) QVecShared::Subdetector::N]; @@ -866,7 +871,7 @@ void QVecCalib::process_recentering(double cent, size_t h_idx, const QVecShared: void QVecCalib::process_flattening(double cent, size_t h_idx, const QVecShared::QVec& q_S, const QVecShared::QVec& q_N, const FlatteningHists& h) { - size_t cent_bin = static_cast(hCentrality->FindBin(cent) - 1); + int cent_bin = hCentrality->FindBin(cent) - 1; const auto& S = m_correction_data[cent_bin][h_idx][(size_t) QVecShared::Subdetector::S]; const auto& N = m_correction_data[cent_bin][h_idx][(size_t) QVecShared::Subdetector::N]; @@ -1000,7 +1005,7 @@ bool QVecCalib::process_event_check() } //____________________________________________________________________________.. -int QVecCalib::process_event([[maybe_unused]] PHCompositeNode *topNode) +int QVecCalib::process_event(PHCompositeNode *topNode) { m_evtdata = findNode::getClass(topNode, "EventPlaneData"); if (!m_evtdata) @@ -1067,7 +1072,7 @@ int QVecCalib::process_event([[maybe_unused]] PHCompositeNode *topNode) } //____________________________________________________________________________.. -int QVecCalib::ResetEvent([[maybe_unused]] PHCompositeNode *topNode) +int QVecCalib::ResetEvent(PHCompositeNode *) { m_q_vectors = {}; @@ -1083,15 +1088,15 @@ void QVecCalib::compute_averages(size_t cent_bin, int h_idx) std::string N_x_avg_name = QVecShared::get_hist_name("N", "x", n); std::string N_y_avg_name = QVecShared::get_hist_name("N", "y", n); - int bin = static_cast(cent_bin + 1); + int bin = cent_bin + 1; double Q_S_x_avg = m_profiles[S_x_avg_name]->GetBinContent(bin); double Q_S_y_avg = m_profiles[S_y_avg_name]->GetBinContent(bin); double Q_N_x_avg = m_profiles[N_x_avg_name]->GetBinContent(bin); double Q_N_y_avg = m_profiles[N_y_avg_name]->GetBinContent(bin); - m_correction_data[cent_bin][h_idx][(size_t)QVecShared::Subdetector::S].avg_Q = {Q_S_x_avg, Q_S_y_avg}; - m_correction_data[cent_bin][h_idx][(size_t)QVecShared::Subdetector::N].avg_Q = {Q_N_x_avg, Q_N_y_avg}; + m_correction_data[cent_bin][h_idx][static_cast(QVecShared::Subdetector::S)].avg_Q = {Q_S_x_avg, Q_S_y_avg}; + m_correction_data[cent_bin][h_idx][static_cast(QVecShared::Subdetector::N)].avg_Q = {Q_N_x_avg, Q_N_y_avg}; std::cout << std::format( "Centrality Bin: {}, " @@ -1117,7 +1122,7 @@ void QVecCalib::compute_recentering(size_t cent_bin, int h_idx) std::string N_x_corr_avg_name = QVecShared::get_hist_name("N", "x", n, "_corr"); std::string N_y_corr_avg_name = QVecShared::get_hist_name("N", "y", n, "_corr"); - int bin = static_cast(cent_bin + 1); + int bin = cent_bin + 1; double Q_S_x_corr_avg = m_profiles[S_x_corr_avg_name]->GetBinContent(bin); double Q_S_y_corr_avg = m_profiles[S_y_corr_avg_name]->GetBinContent(bin); @@ -1148,7 +1153,7 @@ void QVecCalib::compute_recentering(size_t cent_bin, int h_idx) double Q_NS_yy_avg = m_profiles[NS_yy_avg_name]->GetBinContent(bin); double Q_NS_xy_avg = m_profiles[NS_xy_avg_name]->GetBinContent(bin); - m_correction_data[cent_bin][h_idx][(size_t)QVecShared::Subdetector::NS].X_matrix = calculate_flattening_matrix(Q_NS_xx_avg, Q_NS_yy_avg, Q_NS_xy_avg, n, cent_bin, "NS"); + m_correction_data[cent_bin][h_idx][static_cast(QVecShared::Subdetector::NS)].X_matrix = calculate_flattening_matrix(Q_NS_xx_avg, Q_NS_yy_avg, Q_NS_xy_avg, n, cent_bin, "NS"); for (size_t det_idx = 0; det_idx < 2; ++det_idx) { @@ -1206,7 +1211,7 @@ void QVecCalib::print_flattening(size_t cent_bin, int n) const std::string NS_yy_corr_avg_name = QVecShared::get_hist_name("NS", "yy", n, "_corr"); std::string NS_xy_corr_avg_name = QVecShared::get_hist_name("NS", "xy", n, "_corr"); - int bin = static_cast(cent_bin + 1); + int bin = cent_bin + 1; double Q_S_x_corr2_avg = m_profiles.at(S_x_corr2_avg_name)->GetBinContent(bin); double Q_S_y_corr2_avg = m_profiles.at(S_y_corr2_avg_name)->GetBinContent(bin); @@ -1260,7 +1265,8 @@ void QVecCalib::write_cdb() } else if (ec) { - throw std::runtime_error(std::format("Failed to create directory {}: {}", m_cdb_output_dir, ec.message())); + std::cout << "Failed to create directory " << m_cdb_output_dir << ": " << ec.message() << std::endl; + exit(1); } else { @@ -1320,8 +1326,6 @@ void QVecCalib::write_cdb_EventPlane() CDBTTree cdbttree(output_file); - using SD = QVecShared::Subdetector; - for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) { int n = m_harmonics[h_idx]; @@ -1334,24 +1338,24 @@ void QVecCalib::write_cdb_EventPlane() for (size_t cent_bin = 0; cent_bin < m_cent_bins; ++cent_bin) { - int key = static_cast(cent_bin); + int key = cent_bin; // Iterate through all subdetectors (S, N, NS) using the Enum Count - for (size_t d = 0; d < static_cast(SD::Count); ++d) + for (size_t d = 0; d < static_cast(QVecShared::Subdetector::Count); ++d) { - auto det_enum = static_cast(d); + auto det_enum = static_cast(d); // Map enum to the string labels used in the CDB field names std::string det_label; switch (det_enum) { - case SD::S: + case QVecShared::Subdetector::S: det_label = "S"; break; - case SD::N: + case QVecShared::Subdetector::N: det_label = "N"; break; - case SD::NS: + case QVecShared::Subdetector::NS: det_label = "NS"; break; default: @@ -1360,7 +1364,7 @@ void QVecCalib::write_cdb_EventPlane() const auto& data = m_correction_data[cent_bin][h_idx][d]; // 1st Order Moments (Recentering) - Skip for NS as it is a combined vector - if (det_enum != SD::NS) + if (det_enum != QVecShared::Subdetector::NS) { cdbttree.SetDoubleValue(key, field(det_label, "x"), data.avg_Q.x); cdbttree.SetDoubleValue(key, field(det_label, "y"), data.avg_Q.y); @@ -1381,7 +1385,7 @@ void QVecCalib::write_cdb_EventPlane() } //____________________________________________________________________________.. -int QVecCalib::End([[maybe_unused]] PHCompositeNode *topNode) +int QVecCalib::End(PHCompositeNode *) { std::cout << "QVecCalib::End(PHCompositeNode *topNode) This is the End..." << std::endl; diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.h b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.h index 5fceb0f47e..7f834273b2 100644 --- a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.h +++ b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.h @@ -1,24 +1,24 @@ -#ifndef QVECCALIB_H -#define QVECCALIB_H +#ifndef SEPDEVENTPLANECALIB_QVECCALIB_H +#define SEPDEVENTPLANECALIB_QVECCALIB_H #include "QVecDefs.h" #include +#include #include #include #include #include #include - -#include -#include -#include -#include +#include class PHCompositeNode; class EventPlaneData; -class EpdGeom; +class TFile; +class TH1; +class TH2; +class TProfile; /** * @class QVecCalib @@ -126,8 +126,8 @@ class QVecCalib : public SubsysReco static constexpr size_t m_cent_bins = QVecShared::CENT_BINS; static constexpr auto m_harmonics = QVecShared::HARMONICS; - static constexpr float SIGMA_HOT = 6.0F; - static constexpr float SIGMA_COLD = -6.0F; + static constexpr float SIGMA_HOT {6.0}; + static constexpr float SIGMA_COLD {-6.0}; double m_cent_low{-0.5}; double m_cent_high{79.5}; @@ -432,4 +432,4 @@ class QVecCalib : public SubsysReco void write_cdb_BadTowers(); }; -#endif // QVECCALIB_H +#endif // SEPDEVENTPLANECALIB_QVECCALIB_H diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h b/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h index 8b9e4ebcd7..656ec1dc8f 100644 --- a/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h +++ b/calibrations/sepd/sepd_eventplanecalib/QVecDefs.h @@ -1,5 +1,5 @@ -#ifndef QVECDEFS_H -#define QVECDEFS_H +#ifndef SEPDEVENTPLANECALIB_QVECDEFS_H +#define SEPDEVENTPLANECALIB_QVECDEFS_H #include #include @@ -55,4 +55,4 @@ namespace QVecShared } } // namespace QVecShared -#endif // QVECDEFS_H +#endif // SEPDEVENTPLANECALIB_QVECDEFS_H diff --git a/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc b/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc index 5ce0e97a58..7f11a07255 100644 --- a/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc +++ b/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.cc @@ -2,10 +2,6 @@ #include "QVecDefs.h" #include "EventPlaneData.h" -// -- c++ -#include -#include - // -- Calo #include #include @@ -15,8 +11,8 @@ #include // -- MB -#include #include + #include // -- sEPD @@ -34,6 +30,14 @@ #include #include +// -- ROOT +#include +#include + +// -- c++ +#include +#include + //____________________________________________________________________________.. sEPD_TreeGen::sEPD_TreeGen(const std::string &name) : SubsysReco(name) @@ -44,8 +48,10 @@ sEPD_TreeGen::sEPD_TreeGen(const std::string &name) int sEPD_TreeGen::Init(PHCompositeNode *topNode) { Fun4AllServer *se = Fun4AllServer::instance(); - se->Print("NODETREE"); - + if (Verbosity() > 0) + { + se->Print("NODETREE"); + } unsigned int bins_sepd_totalcharge{100}; double sepd_totalcharge_low{0}; double sepd_totalcharge_high{2e4}; @@ -152,7 +158,7 @@ int sEPD_TreeGen::process_centrality(PHCompositeNode *topNode) double cent = centInfo->get_centile(CentralityInfo::PROP::mbd_NS) * 100; - // skip event if centrality is too peripheral + // skip event if centrality is bad or too peripheral if (!std::isfinite(cent) || cent < 0 || cent >= m_cuts.m_cent_max) { if (Verbosity() > 1) @@ -333,18 +339,5 @@ int sEPD_TreeGen::ResetEvent([[maybe_unused]] PHCompositeNode *topNode) m_data.event_id = -1; m_data.event_centrality = 9999; - // DST - if (m_evtdata) - { - m_evtdata->Reset(); - } - - return Fun4AllReturnCodes::EVENT_OK; -} - -//____________________________________________________________________________.. -int sEPD_TreeGen::End([[maybe_unused]] PHCompositeNode *topNode) -{ - std::cout << "sEPD_TreeGen::End" << std::endl; return Fun4AllReturnCodes::EVENT_OK; } diff --git a/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.h b/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.h index 0c735cda36..2d777f4011 100644 --- a/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.h +++ b/calibrations/sepd/sepd_eventplanecalib/sEPD_TreeGen.h @@ -1,5 +1,5 @@ -#ifndef SEPD_TREEGEN_H -#define SEPD_TREEGEN_H +#ifndef SEPDEVENTPLANECALIB_SEPDTREEGEN_H +#define SEPDEVENTPLANECALIB_SEPDTREEGEN_H // -- sPHENIX #include @@ -7,12 +7,10 @@ // -- c++ #include -// -- ROOT -#include -#include - -class PHCompositeNode; class EventPlaneData; +class PHCompositeNode; +class TH2; +class TProfile; /** * @class sEPD_TreeGen @@ -54,13 +52,6 @@ class sEPD_TreeGen : public SubsysReco */ int ResetEvent(PHCompositeNode *topNode) override; - /** - * @brief Finalizes the module, writing all histograms and the TTree to disk. - * @param topNode Pointer to the node tree. - * @return Fun4All return code. - */ - int End(PHCompositeNode *topNode) override; - /** * @brief Prints the current state of the EventPlaneData object. * @param what Optional string to specify what to print (default "ALL"). @@ -144,4 +135,4 @@ class sEPD_TreeGen : public SubsysReco TH2 *h2SEPD_totalcharge_centrality{nullptr}; }; -#endif // SEPD_TREEGEN_H +#endif // SEPDEVENTPLANECALIB_SEPDTREEGEN_H From 7d79c3af890e7d39e914b0dc79af8c81fc163450 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Sat, 21 Feb 2026 15:07:30 -0500 Subject: [PATCH 265/393] fix clang-tidy --- calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc index 83e0b80489..46c99354e1 100644 --- a/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc +++ b/calibrations/sepd/sepd_eventplanecalib/QVecCalib.cc @@ -1072,7 +1072,7 @@ int QVecCalib::process_event(PHCompositeNode *topNode) } //____________________________________________________________________________.. -int QVecCalib::ResetEvent(PHCompositeNode *) +int QVecCalib::ResetEvent(PHCompositeNode * /*topNode*/) { m_q_vectors = {}; @@ -1385,7 +1385,7 @@ void QVecCalib::write_cdb_EventPlane() } //____________________________________________________________________________.. -int QVecCalib::End(PHCompositeNode *) +int QVecCalib::End(PHCompositeNode * /*topNode*/) { std::cout << "QVecCalib::End(PHCompositeNode *topNode) This is the End..." << std::endl; From c93920c2356b49a5af3edc5479fb14d096b02ac6 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Sat, 21 Feb 2026 15:59:40 -0500 Subject: [PATCH 266/393] remove unused version includes --- offline/packages/CaloReco/CaloTowerStatus.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/offline/packages/CaloReco/CaloTowerStatus.cc b/offline/packages/CaloReco/CaloTowerStatus.cc index 954c0a2b3b..446a943531 100644 --- a/offline/packages/CaloReco/CaloTowerStatus.cc +++ b/offline/packages/CaloReco/CaloTowerStatus.cc @@ -3,10 +3,6 @@ #include // for TowerInfo #include -#include -#include -#include -#include #include // for CDBTTree From 9b361cd0bb73281192cfe75d9c6f2680005f7cb4 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Mon, 23 Feb 2026 09:02:27 -0500 Subject: [PATCH 267/393] return all residuals and let user look up from a struct --- .../trackbase_historic/TrackAnalysisUtils.cc | 20 +++++++++++++------ .../trackbase_historic/TrackAnalysisUtils.h | 10 ++++++++-- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/offline/packages/trackbase_historic/TrackAnalysisUtils.cc b/offline/packages/trackbase_historic/TrackAnalysisUtils.cc index a31a3b8efb..e13601d462 100644 --- a/offline/packages/trackbase_historic/TrackAnalysisUtils.cc +++ b/offline/packages/trackbase_historic/TrackAnalysisUtils.cc @@ -299,10 +299,11 @@ namespace TrackAnalysisUtils return out; } - std::pair - get_residual(TrkrDefs::cluskey& ckey, SvtxTrack* track, TrkrClusterContainer* clustermap, - PHCompositeNode* topNode) + TrackAnalysisUtils::TrackFitResiduals + get_residuals(SvtxTrack* track, TrkrClusterContainer* clustermap, + PHCompositeNode* topNode) { + TrackAnalysisUtils::TrackFitResiduals residuals; TpcGlobalPositionWrapper globalWrapper; globalWrapper.loadNodes(topNode); globalWrapper.set_suppressCrossing(true); @@ -310,9 +311,11 @@ namespace TrackAnalysisUtils auto* tpccellgeo = findNode::getClass(topNode, "TPCGEOMCONTAINER"); mover.initialize_geometry(tpccellgeo); mover.set_verbosity(0); + auto* geometry = findNode::getClass(topNode, "ActsGeometry"); - auto* cluster = clustermap->findCluster(ckey); + std::vector> global_raw; + for (const auto& key : get_cluster_keys(track)) { auto* clus = clustermap->findCluster(key); @@ -325,6 +328,9 @@ namespace TrackAnalysisUtils auto global_moved = mover.processTrack(global_raw); + for(const auto& ckey : get_cluster_keys(track)) + { + auto *cluster = clustermap->findCluster(ckey); // loop over global vectors and get this cluster Acts::Vector3 clusglob(0, 0, 0); for (const auto& pair : global_raw) @@ -395,8 +401,10 @@ namespace TrackAnalysisUtils clusglob_moved /= Acts::UnitConstants::cm; // we want cm for the tree Acts::Vector2 stateloc(state->get_localX(), state->get_localY()); Acts::Vector3 stateglob(state->get_x(), state->get_y(), state->get_z()); - - return std::make_pair(stateloc - loc, stateglob - clusglob_moved); + residuals.local_residuals[ckey] = stateloc - loc; + residuals.global_residuals[ckey] = stateglob - clusglob_moved; + } + return residuals; } } // namespace TrackAnalysisUtils diff --git a/offline/packages/trackbase_historic/TrackAnalysisUtils.h b/offline/packages/trackbase_historic/TrackAnalysisUtils.h index a0cc429f07..ef3acfcb0e 100644 --- a/offline/packages/trackbase_historic/TrackAnalysisUtils.h +++ b/offline/packages/trackbase_historic/TrackAnalysisUtils.h @@ -16,6 +16,12 @@ class TrkrClusterContainer; class GlobalVertex; namespace TrackAnalysisUtils { + +struct TrackFitResiduals { + std::map local_residuals; + std::map global_residuals; +}; + /// Returns DCA as .first and uncertainty on DCA as .second using DCA = std::pair; using DCAPair = std::pair; @@ -35,8 +41,8 @@ namespace TrackAnalysisUtils float calc_dedx(TrackSeed* tpcseed, TrkrClusterContainer* clustermap, ActsGeometry* tgeometry, const float thickness_per_region[4]); - std::pair - get_residual(TrkrDefs::cluskey& ckey, SvtxTrack* track, TrkrClusterContainer* clustermap, + TrackFitResiduals + get_residuals(SvtxTrack* track, TrkrClusterContainer* clustermap, PHCompositeNode* topNode); }; // namespace TrackAnalysisUtils From 0d62d2549025b833c6198a1da5b7a240e5c036a0 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Mon, 23 Feb 2026 09:09:46 -0500 Subject: [PATCH 268/393] clang-format --- .../trackbase_historic/TrackAnalysisUtils.cc | 136 +++++++++--------- .../trackbase_historic/TrackAnalysisUtils.h | 11 +- 2 files changed, 74 insertions(+), 73 deletions(-) diff --git a/offline/packages/trackbase_historic/TrackAnalysisUtils.cc b/offline/packages/trackbase_historic/TrackAnalysisUtils.cc index e13601d462..4e80918fb6 100644 --- a/offline/packages/trackbase_historic/TrackAnalysisUtils.cc +++ b/offline/packages/trackbase_historic/TrackAnalysisUtils.cc @@ -301,7 +301,7 @@ namespace TrackAnalysisUtils TrackAnalysisUtils::TrackFitResiduals get_residuals(SvtxTrack* track, TrkrClusterContainer* clustermap, - PHCompositeNode* topNode) + PHCompositeNode* topNode) { TrackAnalysisUtils::TrackFitResiduals residuals; TpcGlobalPositionWrapper globalWrapper; @@ -313,9 +313,9 @@ namespace TrackAnalysisUtils mover.set_verbosity(0); auto* geometry = findNode::getClass(topNode, "ActsGeometry"); - + std::vector> global_raw; - + for (const auto& key : get_cluster_keys(track)) { auto* clus = clustermap->findCluster(key); @@ -328,81 +328,81 @@ namespace TrackAnalysisUtils auto global_moved = mover.processTrack(global_raw); - for(const auto& ckey : get_cluster_keys(track)) + for (const auto& ckey : get_cluster_keys(track)) { - auto *cluster = clustermap->findCluster(ckey); - // loop over global vectors and get this cluster - Acts::Vector3 clusglob(0, 0, 0); - for (const auto& pair : global_raw) - { - auto thiskey = pair.first; - clusglob = pair.second; - if (thiskey == ckey) + auto* cluster = clustermap->findCluster(ckey); + // loop over global vectors and get this cluster + Acts::Vector3 clusglob(0, 0, 0); + for (const auto& pair : global_raw) { - break; + auto thiskey = pair.first; + clusglob = pair.second; + if (thiskey == ckey) + { + break; + } } - } - Acts::Vector3 clusglob_moved(0, 0, 0); - for (const auto& pair : global_moved) - { - auto thiskey = pair.first; - clusglob_moved = pair.second; - if (thiskey == ckey) + Acts::Vector3 clusglob_moved(0, 0, 0); + for (const auto& pair : global_moved) { - break; + auto thiskey = pair.first; + clusglob_moved = pair.second; + if (thiskey == ckey) + { + break; + } } - } - SvtxTrackState* state = nullptr; - for (auto state_iter = track->begin_states(); - state_iter != track->end_states(); - ++state_iter) - { - SvtxTrackState* tstate = state_iter->second; - auto stateckey = tstate->get_cluskey(); - if (stateckey == ckey) + SvtxTrackState* state = nullptr; + for (auto state_iter = track->begin_states(); + state_iter != track->end_states(); + ++state_iter) { - state = tstate; - break; + SvtxTrackState* tstate = state_iter->second; + auto stateckey = tstate->get_cluskey(); + if (stateckey == ckey) + { + state = tstate; + break; + } + } + Surface surf = geometry->maps().getSurface(ckey, cluster); + Surface surf_ideal = geometry->maps().getSurface(ckey, cluster); // Unchanged by distortion corrections + // if this is a TPC cluster, the crossing correction may have moved it across the central membrane, check the surface + auto trkrid = TrkrDefs::getTrkrId(ckey); + if (trkrid == TrkrDefs::tpcId) + { + TrkrDefs::hitsetkey hitsetkey = TrkrDefs::getHitSetKeyFromClusKey(ckey); + TrkrDefs::subsurfkey new_subsurfkey = 0; + surf = geometry->get_tpc_surface_from_coords(hitsetkey, clusglob_moved, new_subsurfkey); } - } - Surface surf = geometry->maps().getSurface(ckey, cluster); - Surface surf_ideal = geometry->maps().getSurface(ckey, cluster); // Unchanged by distortion corrections - // if this is a TPC cluster, the crossing correction may have moved it across the central membrane, check the surface - auto trkrid = TrkrDefs::getTrkrId(ckey); - if (trkrid == TrkrDefs::tpcId) - { - TrkrDefs::hitsetkey hitsetkey = TrkrDefs::getHitSetKeyFromClusKey(ckey); - TrkrDefs::subsurfkey new_subsurfkey = 0; - surf = geometry->get_tpc_surface_from_coords(hitsetkey, clusglob_moved, new_subsurfkey); - } - auto loc = geometry->getLocalCoords(ckey, cluster, track->get_crossing()); - // in this case we get local coords from transform of corrected global coords - clusglob_moved *= Acts::UnitConstants::cm; // we want mm for transformations - Acts::Vector3 normal = surf->normal(geometry->geometry().getGeoContext(), - Acts::Vector3(1, 1, 1), Acts::Vector3(1, 1, 1)); - auto local = surf->globalToLocal(geometry->geometry().getGeoContext(), - clusglob_moved, normal); - if (local.ok()) - { - loc = local.value() / Acts::UnitConstants::cm; - } - else - { - // otherwise take the manual calculation for the TPC - // doing it this way just avoids the bounds check that occurs in the surface class method - Acts::Vector3 loct = surf->transform(geometry->geometry().getGeoContext()).inverse() * clusglob_moved; // global is in mm - loct /= Acts::UnitConstants::cm; + auto loc = geometry->getLocalCoords(ckey, cluster, track->get_crossing()); + // in this case we get local coords from transform of corrected global coords + clusglob_moved *= Acts::UnitConstants::cm; // we want mm for transformations + Acts::Vector3 normal = surf->normal(geometry->geometry().getGeoContext(), + Acts::Vector3(1, 1, 1), Acts::Vector3(1, 1, 1)); + auto local = surf->globalToLocal(geometry->geometry().getGeoContext(), + clusglob_moved, normal); + if (local.ok()) + { + loc = local.value() / Acts::UnitConstants::cm; + } + else + { + // otherwise take the manual calculation for the TPC + // doing it this way just avoids the bounds check that occurs in the surface class method + Acts::Vector3 loct = surf->transform(geometry->geometry().getGeoContext()).inverse() * clusglob_moved; // global is in mm + loct /= Acts::UnitConstants::cm; - loc(0) = loct(0); - loc(1) = loct(1); - } - clusglob_moved /= Acts::UnitConstants::cm; // we want cm for the tree - Acts::Vector2 stateloc(state->get_localX(), state->get_localY()); - Acts::Vector3 stateglob(state->get_x(), state->get_y(), state->get_z()); - residuals.local_residuals[ckey] = stateloc - loc; - residuals.global_residuals[ckey] = stateglob - clusglob_moved; + loc(0) = loct(0); + loc(1) = loct(1); + } + clusglob_moved /= Acts::UnitConstants::cm; // we want cm for the tree + Acts::Vector2 stateloc(state->get_localX(), state->get_localY()); + Acts::Vector3 stateglob(state->get_x(), state->get_y(), state->get_z()); + residuals.local_residuals[ckey] = stateloc - loc; + residuals.global_residuals[ckey] = stateglob - clusglob_moved; } return residuals; } diff --git a/offline/packages/trackbase_historic/TrackAnalysisUtils.h b/offline/packages/trackbase_historic/TrackAnalysisUtils.h index ef3acfcb0e..09106c81e0 100644 --- a/offline/packages/trackbase_historic/TrackAnalysisUtils.h +++ b/offline/packages/trackbase_historic/TrackAnalysisUtils.h @@ -17,10 +17,11 @@ class GlobalVertex; namespace TrackAnalysisUtils { -struct TrackFitResiduals { - std::map local_residuals; - std::map global_residuals; -}; + struct TrackFitResiduals + { + std::map local_residuals; + std::map global_residuals; + }; /// Returns DCA as .first and uncertainty on DCA as .second using DCA = std::pair; @@ -43,7 +44,7 @@ struct TrackFitResiduals { TrackFitResiduals get_residuals(SvtxTrack* track, TrkrClusterContainer* clustermap, - PHCompositeNode* topNode); + PHCompositeNode* topNode); }; // namespace TrackAnalysisUtils From cf5bfc471944cbfbf8c1978886b0e0c1227f9c2f Mon Sep 17 00:00:00 2001 From: Virginia Bailey Date: Mon, 23 Feb 2026 12:16:45 -0500 Subject: [PATCH 269/393] switching to use isGood tower flag --- .../jetbackground/DetermineTowerBackground.cc | 12 ++++++------ offline/packages/jetbackground/RetowerCEMC.cc | 2 +- offline/packages/jetbase/TowerJetInput.cc | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/offline/packages/jetbackground/DetermineTowerBackground.cc b/offline/packages/jetbackground/DetermineTowerBackground.cc index 78a930a8a0..c3a47a6b9b 100644 --- a/offline/packages/jetbackground/DetermineTowerBackground.cc +++ b/offline/packages/jetbackground/DetermineTowerBackground.cc @@ -278,7 +278,7 @@ int DetermineTowerBackground::process_event(PHCompositeNode *topNode) const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(RawTowerDefs::CalorimeterId::HCALIN, comp_ieta, comp_iphi); tower_geom = geomIH->get_tower_geometry(key); comp_ET = towerinfo->get_energy() / cosh(tower_geom->get_eta()); - comp_isBad = towerinfo->get_isHot() || towerinfo->get_isNoCalib() || towerinfo->get_isNotInstr() || towerinfo->get_isBadChi2(); + comp_isBad = !tower->get_isGood(); } else if (comp.first == 7 || comp.first == 27) { @@ -289,7 +289,7 @@ int DetermineTowerBackground::process_event(PHCompositeNode *topNode) const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(RawTowerDefs::CalorimeterId::HCALOUT, comp_ieta, comp_iphi); tower_geom = geomOH->get_tower_geometry(key); comp_ET = towerinfo->get_energy() / cosh(tower_geom->get_eta()); - comp_isBad = towerinfo->get_isHot() || towerinfo->get_isNoCalib() || towerinfo->get_isNotInstr() || towerinfo->get_isBadChi2(); + comp_isBad = !tower->get_isGood(); } else if (comp.first == 13 || comp.first == 28) { @@ -300,7 +300,7 @@ int DetermineTowerBackground::process_event(PHCompositeNode *topNode) const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(RawTowerDefs::CalorimeterId::HCALIN, comp_ieta, comp_iphi); tower_geom = geomIH->get_tower_geometry(key); comp_ET = towerinfo->get_energy() / cosh(tower_geom->get_eta()); - comp_isBad = towerinfo->get_isHot() || towerinfo->get_isNoCalib() || towerinfo->get_isNotInstr() || towerinfo->get_isBadChi2(); + comp_isBad = !tower->get_isGood(); } @@ -467,7 +467,7 @@ int DetermineTowerBackground::process_event(PHCompositeNode *topNode) int this_phibin = towerinfosEM3->getTowerPhiBin(key); TowerInfo *tower = towerinfosEM3->get_tower_at_channel(channel); float this_E = tower->get_energy(); - int this_isBad = tower->get_isHot() || tower->get_isNoCalib() || tower->get_isNotInstr() || tower->get_isBadChi2(); + int this_isBad = !tower->get_isGood(); _EMCAL_ISBAD[this_etabin][this_phibin] = this_isBad; if (!this_isBad) { // just in case since all energy is summed @@ -485,7 +485,7 @@ int DetermineTowerBackground::process_event(PHCompositeNode *topNode) int this_phibin = towerinfosIH3->getTowerPhiBin(key); TowerInfo *tower = towerinfosIH3->get_tower_at_channel(channel); float this_E = tower->get_energy(); - int this_isBad = tower->get_isHot() || tower->get_isNoCalib() || tower->get_isNotInstr() || tower->get_isBadChi2(); + int this_isBad = !tower->get_isGood(); _IHCAL_ISBAD[this_etabin][this_phibin] = this_isBad; if (!this_isBad) { // just in case since all energy is summed @@ -503,7 +503,7 @@ int DetermineTowerBackground::process_event(PHCompositeNode *topNode) int this_phibin = towerinfosOH3->getTowerPhiBin(key); TowerInfo *tower = towerinfosOH3->get_tower_at_channel(channel); float this_E = tower->get_energy(); - int this_isBad = tower->get_isHot() || tower->get_isNoCalib() || tower->get_isNotInstr() || tower->get_isBadChi2(); + int this_isBad = !tower->get_isGood(); _OHCAL_ISBAD[this_etabin][this_phibin] = this_isBad; if (!this_isBad) { // just in case since all energy is summed diff --git a/offline/packages/jetbackground/RetowerCEMC.cc b/offline/packages/jetbackground/RetowerCEMC.cc index 6125052a23..f9afbad6dd 100644 --- a/offline/packages/jetbackground/RetowerCEMC.cc +++ b/offline/packages/jetbackground/RetowerCEMC.cc @@ -86,7 +86,7 @@ int RetowerCEMC::process_event(PHCompositeNode *topNode) int iphi = towerinfosEM3->getTowerPhiBin(channelkey); rawtower_e[ieta][iphi] = tower->get_energy(); rawtower_time[ieta][iphi] = tower->get_time(); - rawtower_status[ieta][iphi] = tower->get_isHot() || tower->get_isNoCalib() || tower->get_isNotInstr() || tower->get_isBadChi2(); + rawtower_status[ieta][iphi] = !tower->get_isGood(); } EMRetowerName = m_towerNodePrefix + "_CEMC_RETOWER"; TowerInfoContainer *emcal_retower = findNode::getClass(topNode, EMRetowerName); diff --git a/offline/packages/jetbase/TowerJetInput.cc b/offline/packages/jetbase/TowerJetInput.cc index 052a6c1828..ca2af6ba3d 100644 --- a/offline/packages/jetbase/TowerJetInput.cc +++ b/offline/packages/jetbase/TowerJetInput.cc @@ -471,7 +471,7 @@ std::vector TowerJetInput::get_input(PHCompositeNode *topNode) int iphi = towerinfos->getTowerPhiBin(calokey); const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(geocaloid, ieta, iphi); // skip masked towers - if (tower->get_isHot() || tower->get_isNoCalib() || tower->get_isNotInstr() || tower->get_isBadChi2()) + if (!tower->get_isGood()) { continue; } From a8aa64754e306364326af2db5b65ae30cc80c0a9 Mon Sep 17 00:00:00 2001 From: Virginia Bailey Date: Mon, 23 Feb 2026 12:21:58 -0500 Subject: [PATCH 270/393] fix typo --- offline/packages/jetbackground/DetermineTowerBackground.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/offline/packages/jetbackground/DetermineTowerBackground.cc b/offline/packages/jetbackground/DetermineTowerBackground.cc index c3a47a6b9b..64ffd50835 100644 --- a/offline/packages/jetbackground/DetermineTowerBackground.cc +++ b/offline/packages/jetbackground/DetermineTowerBackground.cc @@ -278,7 +278,7 @@ int DetermineTowerBackground::process_event(PHCompositeNode *topNode) const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(RawTowerDefs::CalorimeterId::HCALIN, comp_ieta, comp_iphi); tower_geom = geomIH->get_tower_geometry(key); comp_ET = towerinfo->get_energy() / cosh(tower_geom->get_eta()); - comp_isBad = !tower->get_isGood(); + comp_isBad = !towerinfo->get_isGood(); } else if (comp.first == 7 || comp.first == 27) { @@ -289,7 +289,7 @@ int DetermineTowerBackground::process_event(PHCompositeNode *topNode) const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(RawTowerDefs::CalorimeterId::HCALOUT, comp_ieta, comp_iphi); tower_geom = geomOH->get_tower_geometry(key); comp_ET = towerinfo->get_energy() / cosh(tower_geom->get_eta()); - comp_isBad = !tower->get_isGood(); + comp_isBad = !towerinfo->get_isGood(); } else if (comp.first == 13 || comp.first == 28) { @@ -300,7 +300,7 @@ int DetermineTowerBackground::process_event(PHCompositeNode *topNode) const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(RawTowerDefs::CalorimeterId::HCALIN, comp_ieta, comp_iphi); tower_geom = geomIH->get_tower_geometry(key); comp_ET = towerinfo->get_energy() / cosh(tower_geom->get_eta()); - comp_isBad = !tower->get_isGood(); + comp_isBad = !towerinfo->get_isGood(); } From 1b27a2718beb4741d8fc67b803c9972ced63169a Mon Sep 17 00:00:00 2001 From: Nikhil Kumar Date: Mon, 23 Feb 2026 14:17:59 -0500 Subject: [PATCH 271/393] Fix clang-tidy issues, set threshold for ZDC and sEPD CaloStatusSkimmer changes: -fix two classes of clag-tidy warnings. First is braces for all conditional statements. 4 instances were simply indented. The second is setting member variables in the constructor. I already defined defaults in the class definition, so it was not needed anyway. - set very low defaults for ZDC and sEPD skimming. Avoids the issue of skipped channels in the sEPD. A single packet loss is huge for them anyway. --- .../CaloStatusSkimmer/CaloStatusSkimmer.cc | 11 +++++++--- .../CaloStatusSkimmer/CaloStatusSkimmer.h | 20 ++++++++----------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc index 08b3ae34a6..0447bf5ba6 100644 --- a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc +++ b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc @@ -16,9 +16,6 @@ CaloStatusSkimmer::CaloStatusSkimmer(const std::string &name) : SubsysReco(name) { - n_eventcounter = 0; - n_skimcounter = 0; - n_notowernodecounter = 0; std::cout << "CaloStatusSkimmer::CaloStatusSkimmer(const std::string &name) ""Calling ctor" << std::endl; } @@ -34,7 +31,9 @@ int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) { n_notowernodecounter++; if (Verbosity() > 0) + { std::cout << PHWHERE << "calostatuscheck::process_event: missing TOWERS_CEMC" << std::endl; + } return Fun4AllReturnCodes::ABORTEVENT; } const uint32_t ntowers = towers->size(); @@ -67,7 +66,9 @@ int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) { n_notowernodecounter++; if (Verbosity() > 0) + { std::cout << PHWHERE << "calostatuscheck::process_event: missing TOWERS_HCALIN or TOWERS_HCALOUT" << std::endl; + } return Fun4AllReturnCodes::ABORTEVENT; } @@ -114,7 +115,9 @@ int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) { n_notowernodecounter++; if (Verbosity() > 0) + { std::cout << PHWHERE << "calostatuscheck::process_event: missing TOWERS_SEPD" << std::endl; + } return Fun4AllReturnCodes::ABORTEVENT; } const uint32_t ntowers = sepd_towers->size(); @@ -148,7 +151,9 @@ int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) { n_notowernodecounter++; if (Verbosity() > 0) + { std::cout << PHWHERE << "calostatuscheck::process_event: missing TOWERS_ZDC" << std::endl; + } return Fun4AllReturnCodes::ABORTEVENT; } const uint32_t ntowers = zdc_towers->size(); diff --git a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h index 628a582917..ec03c20839 100644 --- a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h +++ b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h @@ -52,24 +52,20 @@ class CaloStatusSkimmer : public SubsysReco { uint32_t n_notowernodecounter{0}; bool b_do_skim_EMCal{false}; - uint16_t m_EMC_skim_threshold{ - 192}; // skim if nchannels >= this many not-instrumented(empty/missing - // pckt) channels in EMCal + uint16_t m_EMC_skim_threshold{192}; + // skim if nchannels >= this many not-instrumented (empty/missing packet) channels in EMCal bool b_do_skim_HCal{false}; - uint16_t m_HCal_skim_threshold{ - 192}; // skim if nchannels >= this many not-instrumented(empty/missing - // pckt) channels in HCal + uint16_t m_HCal_skim_threshold{192}; + // skim if nchannels >= this many not-instrumented (empty/missing packet) channels in HCal bool b_do_skim_sEPD{false}; - uint16_t m_sEPD_skim_threshold{ - 192}; // skim if nchannels >= this many not-instrumented(empty/missing - // pckt) channels in sEPD + uint16_t m_sEPD_skim_threshold{1}; + // skim if nchannels >= this many not-instrumented (empty/missing packet) channels in sEPD bool b_do_skim_ZDC{false}; - uint16_t m_ZDC_skim_threshold{ - 192}; // skim if nchannels >= this many not-instrumented(empty/missing - // pckt) channels in ZDC + uint16_t m_ZDC_skim_threshold{1}; + // skim if nchannels >= this many not-instrumented (empty/missing packet) channels in ZDC }; #endif // CALOSTATUSSKIMMER_H From edbc188c3aaa9019144bb04f1131f87b8f52925f Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Mon, 23 Feb 2026 16:01:18 -0500 Subject: [PATCH 272/393] no need for checking cdbttree file, uniq ptr with root object can cause problems and is counter productive here, remove not needed static casts --- .../eventplaneinfo/EventPlaneRecov2.cc | 65 ++++++------------- .../eventplaneinfo/EventPlaneRecov2.h | 8 +-- .../packages/eventplaneinfo/Eventplaneinfo.h | 24 +++---- .../eventplaneinfo/Eventplaneinfov2.cc | 7 +- .../eventplaneinfo/Eventplaneinfov2.h | 11 ++-- 5 files changed, 44 insertions(+), 71 deletions(-) diff --git a/offline/packages/eventplaneinfo/EventPlaneRecov2.cc b/offline/packages/eventplaneinfo/EventPlaneRecov2.cc index c2cd8e3360..0d1e9b673e 100644 --- a/offline/packages/eventplaneinfo/EventPlaneRecov2.cc +++ b/offline/packages/eventplaneinfo/EventPlaneRecov2.cc @@ -3,26 +3,29 @@ #include "EventplaneinfoMapv1.h" #include "Eventplaneinfov2.h" -#include -#include - -#include -#include -#include - #include #include #include -// -- event -#include - // -- Centrality #include // -- sEPD #include +#include // for CDBTTree + +// -- event +#include + +#include + +#include + +#include +#include +#include + // -- root includes -- #include #include @@ -41,51 +44,19 @@ EventPlaneRecov2::EventPlaneRecov2(const std::string &name): { } -//____________________________________________________________________________.. -EventPlaneRecov2::~EventPlaneRecov2() -{ - std::cout << "EventPlaneRecov2::~EventPlaneRecov2() Calling dtor" << std::endl; -} - -bool EventPlaneRecov2::hasValidTree(const std::string &filePath) -{ - // 1. Attempt to open the file - // "READ" is the default, but being explicit is good practice - std::unique_ptr file(TFile::Open(filePath.c_str(), "READ")); - - // 2. Validate the file pointer and check if the file is "Zombie" (corrupt/unreadable) - if (!file || file->IsZombie()) - { - std::cout << "Error: Could not open file: " << filePath << std::endl; - return false; - } - - // 3. Attempt to get the object by name - TObject *obj = file->Get("Multiple"); - - // 4. Validate existence and check if it actually inherits from TTree - if (obj && obj->InheritsFrom(TTree::Class())) - { - return true; - } - - std::cout << "Error: Object 'Multiple' not found or is not a TTree." << std::endl; - return false; -} - //____________________________________________________________________________.. int EventPlaneRecov2::Init(PHCompositeNode *topNode) { std::string calibdir = CDBInterface::instance()->getUrl(m_calibName); - if (!m_directURL_EventPlaneCalib.empty() && hasValidTree(m_directURL_EventPlaneCalib)) + if (!m_directURL_EventPlaneCalib.empty()) { - m_cdbttree = std::make_unique(m_directURL_EventPlaneCalib); + m_cdbttree = new CDBTTree(m_directURL_EventPlaneCalib); std::cout << PHWHERE << " Custom Event Plane Calib Found: " << m_directURL_EventPlaneCalib << std::endl; } else if (!calibdir.empty()) { - m_cdbttree = std::make_unique(calibdir); + m_cdbttree = new CDBTTree(calibdir); std::cout << PHWHERE << " Event Plane Calib Found: " << calibdir << std::endl; } else if (m_doAbortNoEventPlaneCalib) @@ -176,7 +147,7 @@ void EventPlaneRecov2::LoadCalib() for (size_t cent_bin = 0; cent_bin < m_bins_cent; ++cent_bin) { - int key = static_cast(cent_bin); + int key = cent_bin; // South auto& dataS = m_correction_data[h_idx][cent_bin][south_idx]; @@ -211,6 +182,8 @@ void EventPlaneRecov2::LoadCalib() dataNS.X_matrix = calculate_flattening_matrix(dataNS.avg_Q_xx, dataNS.avg_Q_yy, dataNS.avg_Q_xy, n, cent_bin, "NorthSouth"); } } + delete m_cdbttree; + m_cdbttree = nullptr; } //____________________________________________________________________________.. diff --git a/offline/packages/eventplaneinfo/EventPlaneRecov2.h b/offline/packages/eventplaneinfo/EventPlaneRecov2.h index 4d12aca1bd..fa4d315cac 100644 --- a/offline/packages/eventplaneinfo/EventPlaneRecov2.h +++ b/offline/packages/eventplaneinfo/EventPlaneRecov2.h @@ -2,12 +2,13 @@ #define EVENTPLANEINFO_EVENTPLANERECOV2_H #include -#include // for CDBTTree + #include #include #include +class CDBTTree; class PHCompositeNode; class EventPlaneRecov2 : public SubsysReco @@ -15,7 +16,7 @@ class EventPlaneRecov2 : public SubsysReco public: explicit EventPlaneRecov2(const std::string &name = "EventPlaneRecov2"); - ~EventPlaneRecov2() override; + ~EventPlaneRecov2() override = default; // Explicitly disable copying and moving EventPlaneRecov2(const EventPlaneRecov2&) = delete; @@ -64,7 +65,6 @@ class EventPlaneRecov2 : public SubsysReco private: - static bool hasValidTree(const std::string &filePath); static int CreateNodes(PHCompositeNode *topNode); std::array, 2> calculate_flattening_matrix(double xx, double yy, double xy, int n, int cent_bin, const std::string& det_label); @@ -91,7 +91,7 @@ class EventPlaneRecov2 : public SubsysReco std::string m_calibName{"SEPD_EventPlaneCalib"}; std::string m_inputNode{"TOWERINFO_CALIB_SEPD"}; - std::unique_ptr m_cdbttree; + CDBTTree *m_cdbttree; enum class Subdetector { diff --git a/offline/packages/eventplaneinfo/Eventplaneinfo.h b/offline/packages/eventplaneinfo/Eventplaneinfo.h index 32dbb4ca54..af903b6d06 100644 --- a/offline/packages/eventplaneinfo/Eventplaneinfo.h +++ b/offline/packages/eventplaneinfo/Eventplaneinfo.h @@ -1,12 +1,12 @@ // Tell emacs that this is a C++ source // -*- C++ -*-. -#ifndef EVENTPLANEINFO_H -#define EVENTPLANEINFO_H +#ifndef EVENTPLANEINFO_EVENTPLANEINFO_H +#define EVENTPLANEINFO_EVENTPLANEINFO_H #include -#include #include +#include #include #include @@ -26,18 +26,18 @@ class Eventplaneinfo : public PHObject virtual void set_qvector_raw(const std::vector>& /*Qvec*/) { return; } virtual void set_qvector_recentered(const std::vector>& /*Qvec*/) { return; } virtual void set_shifted_psi(std::vector /*Psi_Shifted*/) { return; } - virtual std::pair get_qvector(int /*order*/) const { return std::make_pair(NAN, NAN); } - virtual std::pair get_qvector_raw(int /*order*/) const { return std::make_pair(NAN, NAN); } - virtual std::pair get_qvector_recentered(int /*order*/) const { return std::make_pair(NAN, NAN); } - virtual double get_psi(int /*order*/) const { return NAN; } - virtual double get_shifted_psi(int /*order*/) const { return NAN; } - virtual double GetPsi(const double /*Qx*/, const double /*Qy*/, const unsigned int /*order*/) const { return NAN; } + virtual std::pair get_qvector(int /*order*/) const { return std::make_pair(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); } + virtual std::pair get_qvector_raw(int /*order*/) const { return std::make_pair(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); } + virtual std::pair get_qvector_recentered(int /*order*/) const { return std::make_pair(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); } + virtual double get_psi(int /*order*/) const { return std::numeric_limits::quiet_NaN(); } + virtual double get_shifted_psi(int /*order*/) const { return std::numeric_limits::quiet_NaN(); } + virtual double GetPsi(const double /*Qx*/, const double /*Qy*/, const unsigned int /*order*/) const { return std::numeric_limits::quiet_NaN(); } virtual void set_ring_qvector(std::vector>> /*RingQvecs*/) { return; } - virtual std::pair get_ring_qvector(int /*rbin*/, int /*order*/) const { return std::make_pair(NAN, NAN); } - virtual double get_ring_psi(int /*rbin*/, int /*order*/) const { return NAN; } + virtual std::pair get_ring_qvector(int /*rbin*/, int /*order*/) const { return std::make_pair(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); } + virtual double get_ring_psi(int /*rbin*/, int /*order*/) const { return std::numeric_limits::quiet_NaN(); } protected: - Eventplaneinfo() {} + Eventplaneinfo() = default; private: ClassDefOverride(Eventplaneinfo, 1); diff --git a/offline/packages/eventplaneinfo/Eventplaneinfov2.cc b/offline/packages/eventplaneinfo/Eventplaneinfov2.cc index e8ff5385b8..08bd60c9ba 100644 --- a/offline/packages/eventplaneinfo/Eventplaneinfov2.cc +++ b/offline/packages/eventplaneinfo/Eventplaneinfov2.cc @@ -1,6 +1,7 @@ #include "Eventplaneinfov2.h" #include +#include void Eventplaneinfov2::identify(std::ostream& os) const { @@ -12,11 +13,11 @@ double Eventplaneinfov2::GetPsi(const double Qx, const double Qy, const unsigned { if (order == 0) { - return NAN; + return std::numeric_limits::quiet_NaN(); } if ((Qx == 0.0) && (Qy == 0.0)) { - return NAN; + return std::numeric_limits::quiet_NaN(); } - return atan2(Qy, Qx) / static_cast(order); + return atan2(Qy, Qx) / order; } diff --git a/offline/packages/eventplaneinfo/Eventplaneinfov2.h b/offline/packages/eventplaneinfo/Eventplaneinfov2.h index d69bc9a5ae..bd6cb553c8 100644 --- a/offline/packages/eventplaneinfo/Eventplaneinfov2.h +++ b/offline/packages/eventplaneinfo/Eventplaneinfov2.h @@ -1,7 +1,7 @@ // Tell emacs that this is a C++ source // -*- C++ -*-. -#ifndef EVENTPLANEINFOV2_H -#define EVENTPLANEINFOV2_H +#ifndef EVENTPLANEINFO_EVENTPLANEINFOV2_H +#define EVENTPLANEINFO_EVENTPLANEINFOV2_H #include "Eventplaneinfo.h" @@ -40,7 +40,7 @@ class Eventplaneinfov2 : public Eventplaneinfo { if (ring_index < 0 || static_cast(ring_index) >= ring_Qvec.size()) { - return {NAN, NAN}; + return {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}; } return safe_qvec(ring_Qvec[ring_index], order); } @@ -60,7 +60,7 @@ class Eventplaneinfov2 : public Eventplaneinfo { if (order <= 0 || static_cast(order) > mPsi_Shifted.size()) { - return NAN; + return std::numeric_limits::quiet_NaN(); } return mPsi_Shifted[order - 1]; } @@ -70,7 +70,7 @@ class Eventplaneinfov2 : public Eventplaneinfo { if (order <= 0 || static_cast(order) > v.size()) { - return {NAN, NAN}; + return {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}; } return v[order - 1]; } @@ -84,4 +84,3 @@ class Eventplaneinfov2 : public Eventplaneinfo }; #endif - From 934e70d8ca4094fc6591ef2d6757e30a121bd7fe Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Mon, 23 Feb 2026 16:11:36 -0500 Subject: [PATCH 273/393] use consistent initialization --- offline/packages/eventplaneinfo/EventPlaneRecov2.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/offline/packages/eventplaneinfo/EventPlaneRecov2.h b/offline/packages/eventplaneinfo/EventPlaneRecov2.h index fa4d315cac..3810935f04 100644 --- a/offline/packages/eventplaneinfo/EventPlaneRecov2.h +++ b/offline/packages/eventplaneinfo/EventPlaneRecov2.h @@ -91,7 +91,7 @@ class EventPlaneRecov2 : public SubsysReco std::string m_calibName{"SEPD_EventPlaneCalib"}; std::string m_inputNode{"TOWERINFO_CALIB_SEPD"}; - CDBTTree *m_cdbttree; + CDBTTree *m_cdbttree {nullptr}; enum class Subdetector { @@ -118,7 +118,7 @@ class EventPlaneRecov2 : public SubsysReco std::array, 2> X_matrix{}; }; - static constexpr size_t m_bins_cent = 8; + static constexpr size_t m_bins_cent {8}; static constexpr std::array m_harmonics = {2, 3, 4}; // Holds all correction data From 714018bb29cdc3c395661734eb17a1c1b3ceb056 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Mon, 23 Feb 2026 16:12:40 -0500 Subject: [PATCH 274/393] remove redundant use of uniq_ptrs --- offline/packages/eventplaneinfo/EventPlaneRecov2.cc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/offline/packages/eventplaneinfo/EventPlaneRecov2.cc b/offline/packages/eventplaneinfo/EventPlaneRecov2.cc index 0d1e9b673e..34c28c837f 100644 --- a/offline/packages/eventplaneinfo/EventPlaneRecov2.cc +++ b/offline/packages/eventplaneinfo/EventPlaneRecov2.cc @@ -259,17 +259,16 @@ int EventPlaneRecov2::CreateNodes(PHCompositeNode *topNode) { PHCompositeNode *globalNode = dynamic_cast(iter.findFirst("PHCompositeNode", "GLOBAL")); if (!globalNode) { - auto global_ptr = std::make_unique("GLOBAL"); - globalNode = global_ptr.get(); - dstNode->addNode(global_ptr.release()); + globalNode = new PHCompositeNode("GLOBAL"); + dstNode->addNode(globalNode); } EventplaneinfoMap *eps = findNode::getClass(topNode, "EventplaneinfoMap"); if (!eps) { - auto eps_ptr = std::make_unique(); - auto epMapNode_ptr = std::make_unique>(eps_ptr.release(), "EventplaneinfoMap", "PHObject"); - globalNode->addNode(epMapNode_ptr.release()); + eps = new EventplaneinfoMapv1(); + PHIODataNode *newNode = new PHIODataNode(eps , "EventplaneinfoMap", "PHObject"); + globalNode->addNode(newNode); } return Fun4AllReturnCodes::EVENT_OK; From 66b8be60aa3eebc4f47cc7115ffbfb14856515b4 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Mon, 23 Feb 2026 16:33:34 -0500 Subject: [PATCH 275/393] minor cosmetics --- .../eventplaneinfo/EventPlaneRecov2.cc | 29 +++++++------------ .../eventplaneinfo/EventPlaneRecov2.h | 3 -- .../eventplaneinfo/Eventplaneinfov2.cc | 2 +- 3 files changed, 12 insertions(+), 22 deletions(-) diff --git a/offline/packages/eventplaneinfo/EventPlaneRecov2.cc b/offline/packages/eventplaneinfo/EventPlaneRecov2.cc index 34c28c837f..9635e0f3d6 100644 --- a/offline/packages/eventplaneinfo/EventPlaneRecov2.cc +++ b/offline/packages/eventplaneinfo/EventPlaneRecov2.cc @@ -512,17 +512,17 @@ int EventPlaneRecov2::FillNode(PHCompositeNode *topNode) size_t vec_size = static_cast(*std::ranges::max_element(m_harmonics)); - std::vector> south_Qvec_raw(vec_size, {NAN, NAN}); - std::vector> south_Qvec_recentered(vec_size, {NAN, NAN}); - std::vector> south_Qvec(vec_size, {NAN, NAN}); + std::vector> south_Qvec_raw(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); + std::vector> south_Qvec_recentered(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); + std::vector> south_Qvec(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); - std::vector> north_Qvec_raw(vec_size, {NAN, NAN}); - std::vector> north_Qvec_recentered(vec_size, {NAN, NAN}); - std::vector> north_Qvec(vec_size, {NAN, NAN}); + std::vector> north_Qvec_raw(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); + std::vector> north_Qvec_recentered(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); + std::vector> north_Qvec(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); - std::vector> northsouth_Qvec_raw(vec_size, {NAN, NAN}); - std::vector> northsouth_Qvec_recentered(vec_size, {NAN, NAN}); - std::vector> northsouth_Qvec(vec_size, {NAN, NAN}); + std::vector> northsouth_Qvec_raw(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); + std::vector> northsouth_Qvec_recentered(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); + std::vector> northsouth_Qvec(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) { @@ -566,7 +566,7 @@ int EventPlaneRecov2::FillNode(PHCompositeNode *topNode) node->set_qvector_recentered(qvecs_recentered); node->set_qvector(qvecs); - std::vector psi_vec(vec_size, NAN); + std::vector psi_vec(vec_size, std::numeric_limits::quiet_NaN()); for (int n : m_harmonics) { psi_vec[n-1] = node->GetPsi(qvecs[n-1].first, qvecs[n-1].second, n); } @@ -625,7 +625,7 @@ int EventPlaneRecov2::process_event(PHCompositeNode *topNode) } //____________________________________________________________________________.. -int EventPlaneRecov2::ResetEvent([[maybe_unused]] PHCompositeNode *topNode) +int EventPlaneRecov2::ResetEvent(PHCompositeNode */*topNode*/) { m_doNotCalibEvent = false; @@ -635,10 +635,3 @@ int EventPlaneRecov2::ResetEvent([[maybe_unused]] PHCompositeNode *topNode) return Fun4AllReturnCodes::EVENT_OK; } - -//____________________________________________________________________________.. -int EventPlaneRecov2::End([[maybe_unused]] PHCompositeNode *topNode) -{ - std::cout << "EventPlaneRecov2::End(PHCompositeNode *topNode) This is the End..." << std::endl; - return Fun4AllReturnCodes::EVENT_OK; -} diff --git a/offline/packages/eventplaneinfo/EventPlaneRecov2.h b/offline/packages/eventplaneinfo/EventPlaneRecov2.h index 3810935f04..217faddf88 100644 --- a/offline/packages/eventplaneinfo/EventPlaneRecov2.h +++ b/offline/packages/eventplaneinfo/EventPlaneRecov2.h @@ -39,9 +39,6 @@ class EventPlaneRecov2 : public SubsysReco /// Clean up internals after each event. int ResetEvent(PHCompositeNode *topNode) override; - /// Called at the end of all processing. - int End(PHCompositeNode *topNode) override; - void set_inputNode(const std::string &inputNode) { diff --git a/offline/packages/eventplaneinfo/Eventplaneinfov2.cc b/offline/packages/eventplaneinfo/Eventplaneinfov2.cc index 08bd60c9ba..7331117a17 100644 --- a/offline/packages/eventplaneinfo/Eventplaneinfov2.cc +++ b/offline/packages/eventplaneinfo/Eventplaneinfov2.cc @@ -19,5 +19,5 @@ double Eventplaneinfov2::GetPsi(const double Qx, const double Qy, const unsigned { return std::numeric_limits::quiet_NaN(); } - return atan2(Qy, Qx) / order; + return std::atan2(Qy, Qx) / order; } From 876b96f25a59f3d5b93353a417aade587468e160 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Mon, 23 Feb 2026 16:38:55 -0500 Subject: [PATCH 276/393] fix lib dependencies --- offline/packages/eventplaneinfo/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/offline/packages/eventplaneinfo/Makefile.am b/offline/packages/eventplaneinfo/Makefile.am index 293e3675d6..786a285bee 100644 --- a/offline/packages/eventplaneinfo/Makefile.am +++ b/offline/packages/eventplaneinfo/Makefile.am @@ -14,8 +14,7 @@ AM_LDFLAGS = \ -L$(OFFLINE_MAIN)/lib libeventplaneinfo_io_la_LIBADD = \ - -lphool \ - -lcentrality_io + -lphool libeventplaneinfo_la_LIBADD = \ libeventplaneinfo_io.la \ @@ -24,6 +23,7 @@ libeventplaneinfo_la_LIBADD = \ -lfun4all \ -lffamodules \ -lcalotrigger_io \ + -lcentrality_io \ -lffarawobjects \ -lcdbobjects \ -lglobalvertex_io From 28b6193b459ea77c8ac0dcc2e660be833c8c0d06 Mon Sep 17 00:00:00 2001 From: Hugo Pereira Da Costa Date: Mon, 23 Feb 2026 18:18:19 -0500 Subject: [PATCH 277/393] added missing const from header declaration. This should fix compiling TrackingDiagnostics. --- offline/packages/trackbase_historic/TrackAnalysisUtils.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/offline/packages/trackbase_historic/TrackAnalysisUtils.h b/offline/packages/trackbase_historic/TrackAnalysisUtils.h index 168ff7495f..0f87c2a7be 100644 --- a/offline/packages/trackbase_historic/TrackAnalysisUtils.h +++ b/offline/packages/trackbase_historic/TrackAnalysisUtils.h @@ -28,9 +28,9 @@ namespace TrackAnalysisUtils // to pass these from the geometry object, which keeps the dependencies // of this helper class minimal. This will also help us catch any changes // when/if the tpc geometry changes in the future. This is to get us going - float thickness_per_region[4]); + float const thickness_per_region[4]); float calc_dedx(TrackSeed* tpcseed, TrkrClusterContainer* clustermap, ActsGeometry* tgeometry, - float thickness_per_region[4]); + float const thickness_per_region[4]); }; // namespace TrackAnalysisUtils From becbe38c45d00bee4c2a546558542115b886fa53 Mon Sep 17 00:00:00 2001 From: Anthony Denis Frawley Date: Tue, 24 Feb 2026 14:16:35 -0500 Subject: [PATCH 278/393] Diagnostics added. --- .../KshortReconstruction.cc | 141 +++++++++++------- 1 file changed, 85 insertions(+), 56 deletions(-) diff --git a/offline/packages/TrackingDiagnostics/KshortReconstruction.cc b/offline/packages/TrackingDiagnostics/KshortReconstruction.cc index a7a240ffcf..68ae2dae25 100644 --- a/offline/packages/TrackingDiagnostics/KshortReconstruction.cc +++ b/offline/packages/TrackingDiagnostics/KshortReconstruction.cc @@ -92,8 +92,6 @@ int KshortReconstruction::process_event(PHCompositeNode* topNode) std::vector nstates1 = getTrackStates(tr1); unsigned int track1_mvtx_state_size = nstates1[0]; unsigned int track1_intt_state_size = nstates1[1]; - // unsigned int track1_tpc_state_size = nstates1[2]; - // unsigned int track1_mms_state_size = nstates1[3]; unsigned int track1_silicon_cluster_size = std::numeric_limits::quiet_NaN(); if (siliconseed) @@ -125,23 +123,46 @@ int KshortReconstruction::process_event(PHCompositeNode* topNode) Acts::Vector3 pos1(tr1->get_x(), tr1->get_y(), tr1->get_z()); Acts::Vector3 mom1(tr1->get_px(), tr1->get_py(), tr1->get_pz()); Acts::Vector3 dcaVals1 = calculateDca(tr1, mom1, pos1); - // first dca cuts if (fabs(dcaVals1(0)) < this_dca_cut || fabs(dcaVals1(1)) < this_dca_cut) - { - continue; - } - + { + std::cout << " tr1 failed dca cuts " << std::endl; + continue; + } // look for close DCA matches with all other such tracks for (auto tr2_it = std::next(tr1_it); tr2_it != m_svtxTrackMap->end(); ++tr2_it) { auto id2 = tr2_it->first; auto *tr2 = tr2_it->second; + + bool diag = false; + + // dca xy and dca z cut here compare to track dca cut + Acts::Vector3 pos2(tr2->get_x(), tr2->get_y(), tr2->get_z()); + Acts::Vector3 mom2(tr2->get_px(), tr2->get_py(), tr2->get_pz()); + Acts::Vector3 dcaVals2 = calculateDca(tr2, mom2, pos2); + + if( fabs(1.0 - std::tan(dcaVals1(2))) < 0.1 && abs(dcaVals2(2)-dcaVals1(2)) < 0.1 ) + { + diag = true; + std::cout << "*** Found phi values of interest " << std::endl; + } + if(diag) { std::cout << " tr1: id, dca3dxy1,dca3dz1,phi1: " << tr1->get_id() << " " << dcaVals1(0) << " " << dcaVals1(1) << " " << dcaVals1(2) << std::endl; } + if(diag) { std::cout << " tr2: id,dca3dxy2,dca3dz2,phi2: " << tr2->get_id() << " " << dcaVals2(0) << " " << dcaVals2(1) << " " << dcaVals2(2) << std::endl; } + if (tr2->get_quality() > _qual_cut) { - continue; + if(diag) + { + std::cout << " tr2 failed quality cut " << tr2->get_quality() << std::endl; + } + continue; } if (tr2->get_pt() < track_pt_cut) { + if(diag) + { + std::cout << " tr2 failed pT cut " << tr2->get_pt() << std::endl; + } continue; } @@ -161,15 +182,17 @@ int KshortReconstruction::process_event(PHCompositeNode* topNode) } if (_require_mvtx) { - continue; - } + if(diag) + { + std::cout << " tr2 failed mvtx cut " << std::endl; + } + continue; + } } std::vector nstates2 = getTrackStates(tr2); unsigned int track2_mvtx_state_size = nstates2[0]; unsigned int track2_intt_state_size = nstates2[1]; - // unsigned int track2_tpc_state_size = nstates2[2]; - // unsigned int track2_mms_state_size = nstates2[3]; unsigned int track2_silicon_cluster_size = std::numeric_limits::quiet_NaN(); if (siliconseed2) @@ -198,20 +221,20 @@ int KshortReconstruction::process_event(PHCompositeNode* topNode) } } - // dca xy and dca z cut here compare to track dca cut - Acts::Vector3 pos2(tr2->get_x(), tr2->get_y(), tr2->get_z()); - Acts::Vector3 mom2(tr2->get_px(), tr2->get_py(), tr2->get_pz()); - Acts::Vector3 dcaVals2 = calculateDca(tr2, mom2, pos2); - + if (fabs(dcaVals2(0)) < this_dca_cut2 || fabs(dcaVals2(1)) < this_dca_cut2) { + if(diag) + { + std::cout << " tr2 failed dca cut " << std::endl; + } continue; } - // find DCA of these two tracks + // find pair DCA of these two tracks if (Verbosity() > 3) { - std::cout << "Check DCA for tracks " << id1 << " and " << id2 << std::endl; + std::cout << "Check pair DCA for tracks " << id1 << " and " << id2 << std::endl; } if (tr1->get_charge() == tr2->get_charge()) @@ -233,7 +256,7 @@ int KshortReconstruction::process_event(PHCompositeNode* topNode) // This presently assumes straight line tracks to get a rough answer // Should update to use circles instead? findPcaTwoTracks(pos1, pos2, mom1, mom2, pca_rel1, pca_rel2, pair_dca); - + if(diag) { std::cout << " pair dca " << pair_dca << " pca_rel1 " << pca_rel1(0) << " " << pca_rel1(1) << " " << pca_rel1(2) << std::endl; } // tracks with small relative pca are k short candidates if (abs(pair_dca) < pair_dca_cut) { @@ -279,35 +302,35 @@ int KshortReconstruction::process_event(PHCompositeNode* topNode) // invariant mass is calculated in this method fillHistogram(projected_mom1, projected_mom2, recomass, invariantMass, invariantPt, invariantPhi, rapidity, pseudorapidity,decaymassa, decaymassb); fillNtp(tr1, tr2, decaymassa, decaymassb, dcaVals1, dcaVals2, pca_rel1, pca_rel2, pair_dca, invariantMass, invariantPt, invariantPhi, rapidity, pseudorapidity, projected_pos1, projected_pos2, projected_mom1, projected_mom2, pca_rel1_proj, pca_rel2_proj, pair_dca_proj, track1_silicon_cluster_size, track2_silicon_cluster_size, track1_mvtx_cluster_size, track1_mvtx_state_size, track1_intt_cluster_size, track1_intt_state_size, track2_mvtx_cluster_size, track2_mvtx_state_size, track2_intt_cluster_size, track2_intt_state_size, m_runNumber, m_evtNumber); - - - - - - /* - // invariant mass is calculated in this method - fillHistogram(projected_mom1, projected_mom2, recomass, invariantMass, invariantPt, invariantPhi, rapidity, pseudorapidity); - fillNtp(tr1, tr2, dcaVals1, dcaVals2, pca_rel1, pca_rel2, pair_dca, invariantMass, invariantPt, invariantPhi, rapidity, pseudorapidity, projected_pos1, projected_pos2, projected_mom1, projected_mom2, pca_rel1_proj, pca_rel2_proj, pair_dca_proj, track1_silicon_cluster_size, track2_silicon_cluster_size, track1_mvtx_cluster_size, track1_mvtx_state_size, track1_intt_cluster_size, track1_intt_state_size, track2_mvtx_cluster_size, track2_mvtx_state_size, track2_intt_cluster_size, track2_intt_state_size, m_runNumber, m_evtNumber); - */ + if(diag) + { + std::cout << "Accepted Track Pair" << " id1 " << id1 << " id2 " << id2 << " crossing1 " << crossing1 << " crossing2 " << crossing2 << std::endl; + std::cout << " invariant mass: " << invariantMass << " decaymassa " << decaymassa << " decaymassb " << decaymassb << std::endl; + } if (Verbosity() > 1) { - std::cout << " Accepted Track Pair" << std::endl; - std::cout << " id1 " << id1 << " id2 " << id2 << std::endl; - std::cout << " crossing1 " << crossing1 << " crossing2 " << crossing2 << std::endl; - std::cout << " invariant mass: " << invariantMass << std::endl; - std::cout << " track1 dca_cut: " << this_dca_cut << " track2 dca_cut: " << this_dca_cut2 << std::endl; - std::cout << " dca3dxy1,dca3dz1,phi1: " << dcaVals1 << std::endl; - std::cout << " dca3dxy2,dca3dz2,phi2: " << dcaVals2 << std::endl; - std::cout << "Initial: pca_rel1: " << pca_rel1 << " pca_rel2: " << pca_rel2 << std::endl; - std::cout << " Initial: mom1: " << mom1 << " mom2: " << mom2 << std::endl; - std::cout << "Proj_pca_rel: proj_pos1: " << projected_pos1 << " proj_pos2: " << projected_pos2 << " proj_mom1: " << projected_mom1 << " proj_mom2: " << projected_mom2 << std::endl; - std::cout << " Relative PCA = " << abs(pair_dca) << " pca_cut = " << pair_dca_cut << std::endl; - std::cout << " charge 1: " << tr1->get_charge() << " charge2: " << tr2->get_charge() << std::endl; - std::cout << "found viable projection" << std::endl; - std::cout << "Final: pca_rel1_proj: " << pca_rel1_proj << " pca_rel2_proj: " << pca_rel2_proj << " mom1: " << projected_mom1 << " mom2: " << projected_mom2 << std::endl - << std::endl; + std::cout << "Accepted Track Pair" << " id1 " << id1 << " id2 " << id2 << " crossing1 " << crossing1 << " crossing2 " << crossing2 << std::endl; + std::cout << " invariant mass: " << invariantMass << " decaymassa " << decaymassa << " decaymassb " << decaymassb << std::endl; + std::cout << " track1 dca_cut: " << this_dca_cut << " track2 dca_cut: " << this_dca_cut2 << std::endl; + std::cout << " dca3dxy1,dca3dz1,phi1: " << dcaVals1(0) << " " << dcaVals1(1) << " " << dcaVals1(2) << std::endl; + std::cout << " dca3dxy2,dca3dz2,phi2: " << dcaVals2(0) << " " << dcaVals2(1) << " " << dcaVals2(2) << std::endl; + std::cout << " Initial: pca_rel1: " << pca_rel1(0) << " " << pca_rel1(1) << " " << pca_rel1(2) << std::endl; + std::cout << " Initial: pca_rel2: " << pca_rel2(0) << " " << pca_rel2(1) << " " << pca_rel2(2) << std::endl; + std::cout << " Initial: mom1: " << mom1(0) << " " << mom1(1) << " " << mom1(2) << std::endl; + std::cout << " Initial: mom2: " << mom2(0) << " " << mom2(1) << " " << mom2(2) << std::endl; + std::cout << " Proj_pca_rel: proj_pos1: " << projected_pos1(0) << " " << projected_pos1(1) << " " << projected_pos1(2) << std::endl; + std::cout << " Proj_pca_rel: proj_pos2: " << projected_pos2(0) << " " << projected_pos2(1) << " " << projected_pos2(2) << std::endl; + std::cout << " proj_mom1: " << projected_mom1(0) << " " << projected_mom1(1) << " " << projected_mom1(2) << std::endl; + std::cout << " proj_mom2: " << projected_mom2(0) << " " << projected_mom2(1) << " " << projected_mom2(2) << std::endl; + std::cout << " Relative PCA = " << abs(pair_dca) << " pca_cut = " << pair_dca_cut << std::endl; + std::cout << " charge 1: " << tr1->get_charge() << " charge2: " << tr2->get_charge() << std::endl; + std::cout << " found viable projection" << std::endl; + std::cout << " Final: pca_rel1_proj: " << pca_rel1_proj(0) << " " << pca_rel1_proj(1) << " " << pca_rel1_proj(2) << std::endl; + std::cout << " Final: pca_rel2_proj: " << pca_rel2_proj(0) << " " << pca_rel2_proj(1) << " " << pca_rel2_proj(2) << std::endl; + std::cout << " Final: mom1: " << projected_mom1(0) << " " << projected_mom1(1) << " " << projected_mom1(2) << std::endl; + std::cout << " Final: mom2: " << projected_mom2(0) << " " << projected_mom2(1) << " " << projected_mom2(2) << std::endl; } } if (m_save_tracks) @@ -354,9 +377,7 @@ std::vector KshortReconstruction::getTrackStates(SvtxTrack *track) nmmsstate++; break; default: - std::cout << PHWHERE << " unknown key " << stateckey << std::endl; - gSystem->Exit(1); - exit(1); + break; } } nstates.push_back(nmapsstate); @@ -771,9 +792,16 @@ KshortReconstruction::KshortReconstruction(const std::string& name) Acts::Vector3 KshortReconstruction::calculateDca(SvtxTrack* track, const Acts::Vector3& momentum, Acts::Vector3 position) { + + /* + std::cout << " Input: pos(0) " << position(0) << " pos(1) " << position(1) << " pos(2) " << position(2) + << " mom(0) " << momentum(0) << " mom(1) " << momentum(1) << " mom(2) " << momentum(2) + << std::endl; + */ + // For the purposes of this module, we set default values to prevent this track from being rejected if the dca calc fails Acts::Vector3 r = momentum.cross(Acts::Vector3(0., 0., 1.)); - float phi = atan2(r(1), r(0)); + float phi = std::atan2(r(1), r(0)); Acts::Vector3 outVals(track_dca_cut*1.1, track_dca_cut*1.1, phi); auto vtxid = track->get_vertex_id(); if (!m_vertexMap) @@ -808,7 +836,14 @@ Acts::Vector3 KshortReconstruction::calculateDca(SvtxTrack* track, const Acts::V outVals(0) = abs(dca3dxy); outVals(1) = abs(dca3dz); outVals(2) = phi; - + /* + std::cout << " calculateDca: dca3dxy " << outVals(0) << " dca3dz " << outVals(1) << " phi " << outVals(2) << std::endl + << " vertex(0) " << vertex(0) << " vertex(1) " << vertex(1) << " vertex(2) " << vertex(2) << std::endl + << " position(0) " << position(0) << " position(1) " << position(1) << " position(2) " << position(2) << std::endl + << " momentum(0) " << momentum(0) << " momentum(1) " << momentum(1) << " momentum(2) " << momentum(2) + << std::endl; + */ + if (Verbosity() > 4) { std::cout << " pre-position: " << position << std::endl; @@ -826,12 +861,6 @@ int KshortReconstruction::InitRun(PHCompositeNode* topNode) ntp_reco_info = new TNtuple("ntp_reco_info", "decay_pairs", "id1:mass1:crossing1:x1:y1:z1:px1:py1:pz1:dca3dxy1:dca3dz1:phi1:pca_rel1_x:pca_rel1_y:pca_rel1_z:eta1:charge1:tpcClusters_1:id2:mass2:crossing2:x2:y2:z2:px2:py2:pz2:dca3dxy2:dca3dz2:phi2:pca_rel2_x:pca_rel2_y:pca_rel2_z:eta2:charge2:tpcClusters_2:ntracks_vertex:vertex_x:vertex_y:vertex_z:pair_dca:invariant_mass:invariant_pt:invariantPhi:pathlength_x:pathlength_y:pathlength_z:pathlength:rapidity:pseudorapidity:projected_pos1_x:projected_pos1_y:projected_pos1_z:projected_pos2_x:projected_pos2_y:projected_pos2_z:projected_mom1_x:projected_mom1_y:projected_mom1_z:projected_mom2_x:projected_mom2_y:projected_mom2_z:projected_pca_rel1_x:projected_pca_rel1_y:projected_pca_rel1_z:projected_pca_rel2_x:projected_pca_rel2_y:projected_pca_rel2_z:projected_pair_dca:projected_pathlength_x:projected_pathlength_y:projected_pathlength_z:projected_pathlength:quality1:quality2:cosThetaReco:track1_silicon_clusters:track2_silicon_clusters:track1_mvtx_clusters:track1_mvtx_states:track1_intt_clusters:track1_intt_states:track2_mvtx_clusters:track2_mvtx_states:track2_intt_clusters:track2_intt_states:runNumber:eventNumber"); - - -/* - ntp_reco_info = new TNtuple("ntp_reco_info", "decay_pairs", "id1:crossing1:x1:y1:z1:px1:py1:pz1:dca3dxy1:dca3dz1:phi1:pca_rel1_x:pca_rel1_y:pca_rel1_z:eta1:charge1:tpcClusters_1:id2:crossing2:x2:y2:z2:px2:py2:pz2:dca3dxy2:dca3dz2:phi2:pca_rel2_x:pca_rel2_y:pca_rel2_z:eta2:charge2:tpcClusters_2:vertex_x:vertex_y:vertex_z:pair_dca:invariant_mass:invariant_pt:invariantPhi:pathlength_x:pathlength_y:pathlength_z:pathlength:rapidity:pseudorapidity:projected_pos1_x:projected_pos1_y:projected_pos1_z:projected_pos2_x:projected_pos2_y:projected_pos2_z:projected_mom1_x:projected_mom1_y:projected_mom1_z:projected_mom2_x:projected_mom2_y:projected_mom2_z:projected_pca_rel1_x:projected_pca_rel1_y:projected_pca_rel1_z:projected_pca_rel2_x:projected_pca_rel2_y:projected_pca_rel2_z:projected_pair_dca:projected_pathlength_x:projected_pathlength_y:projected_pathlength_z:projected_pathlength:quality1:quality2:cosThetaReco:track1_silicon_clusters:track2_silicon_clusters:track1_mvtx_clusters:track1_mvtx_states:track1_intt_clusters:track1_intt_states:track2_mvtx_clusters:track2_mvtx_states:track2_intt_clusters:track2_intt_states:runNumber:eventNumber"); -*/ - getNodes(topNode); recomass = new TH1D("recomass", "recomass", 1000, 0.0, 1); // root histogram arguments: name,title,bins,minvalx,maxvalx From e9f85e6ea61a233ca0420c846a5cb63ba1b249f3 Mon Sep 17 00:00:00 2001 From: Joseph Clement Date: Tue, 24 Feb 2026 14:47:35 -0500 Subject: [PATCH 279/393] add default to not abort when abort enabled but only fail MBD cut --- offline/packages/jetbackground/TimingCut.cc | 2 +- offline/packages/jetbackground/TimingCut.h | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/offline/packages/jetbackground/TimingCut.cc b/offline/packages/jetbackground/TimingCut.cc index 719fc8181c..e2949bbe7b 100644 --- a/offline/packages/jetbackground/TimingCut.cc +++ b/offline/packages/jetbackground/TimingCut.cc @@ -203,7 +203,7 @@ int TimingCut::process_event(PHCompositeNode *topNode) passMbdt = Pass_Mbd_dt(corrMaxJett, mbd_time); } - bool failAnyCut = !passDeltat || !passLeadt || !passMbdt; + bool failAnyCut = !passDeltat || !passLeadt || (!passMbdt && _abortFailMbd); if (failAnyCut && _doAbort) { diff --git a/offline/packages/jetbackground/TimingCut.h b/offline/packages/jetbackground/TimingCut.h index d932c4cac5..5fa3a134bc 100644 --- a/offline/packages/jetbackground/TimingCut.h +++ b/offline/packages/jetbackground/TimingCut.h @@ -67,6 +67,9 @@ class TimingCut : public SubsysReco void set_min_dphi(float new_min_dphi) { _min_dphi = new_min_dphi; } float get_min_dphi() { return _min_dphi; } + void set_abortFailMbd(bool abortFailMbd) { _abortFailMbd = abortFailMbd; } + bool get_abortFailMbd() { return _abortFailMbd; } + int Init(PHCompositeNode *topNode) override; int process_event(PHCompositeNode *topNode) override; @@ -100,6 +103,7 @@ class TimingCut : public SubsysReco private: bool _doAbort; + bool _abortFailMbd = false; bool _missingInfoWarningPrinted = false; std::string _jetNodeName; std::string _ohTowerName; From 4955f457fc6a9eff49888319bdf746f9a9b64fe7 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 24 Feb 2026 17:12:08 -0500 Subject: [PATCH 280/393] add MB to Detroit to make clear these are MinBias --- offline/framework/frog/CreateFileList.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/framework/frog/CreateFileList.pl b/offline/framework/frog/CreateFileList.pl index bc8135ec6d..e0eaa402f3 100755 --- a/offline/framework/frog/CreateFileList.pl +++ b/offline/framework/frog/CreateFileList.pl @@ -64,7 +64,7 @@ "23" => "cosmic field off", "24" => "AMPT", "25" => "EPOS", - "26" => "JS pythia8 Detroit", + "26" => "JS pythia8 Detroit (MB)", "27" => "JS pythia8 Photonjet ptmin = 5GeV", "28" => "JS pythia8 Photonjet ptmin = 10GeV", "29" => "JS pythia8 Photonjet ptmin = 20GeV", From e04bec167cc4a025bb18b9dac007ed3c9b739bd8 Mon Sep 17 00:00:00 2001 From: emclaughlin2 Date: Wed, 25 Feb 2026 12:56:51 -0500 Subject: [PATCH 281/393] Update waveform fitting to return fit status and towerinfo objects to save fit status and remove isbadtime flag --- offline/QA/Jet/CaloStatusMapperDefs.h | 7 ---- offline/packages/CaloBase/TowerInfo.h | 4 +-- offline/packages/CaloBase/TowerInfov2.h | 6 ++-- offline/packages/CaloBase/TowerInfov4.h | 6 ++-- offline/packages/CaloReco/CaloTowerBuilder.cc | 1 + offline/packages/CaloReco/CaloTowerStatus.cc | 9 ++--- .../packages/CaloReco/CaloWaveformFitting.cc | 36 ++++++++++++------- .../CaloReco/CaloWaveformProcessing.cc | 5 ++- .../NodeDump/DumpTowerInfoContainer.cc | 1 - .../packages/jetbackground/SubtractTowers.cc | 6 ++-- 10 files changed, 41 insertions(+), 40 deletions(-) diff --git a/offline/QA/Jet/CaloStatusMapperDefs.h b/offline/QA/Jet/CaloStatusMapperDefs.h index c77d1b765c..08f8289fe0 100644 --- a/offline/QA/Jet/CaloStatusMapperDefs.h +++ b/offline/QA/Jet/CaloStatusMapperDefs.h @@ -59,7 +59,6 @@ namespace CaloStatusMapperDefs { Good, Hot, - BadTime, BadChi, NotInstr, NoCalib, @@ -74,7 +73,6 @@ namespace CaloStatusMapperDefs static std::map mapStatLabels = { {Stat::Good, "Good"}, {Stat::Hot, "Hot"}, - {Stat::BadTime, "BadTime"}, {Stat::BadChi, "BadChi"}, {Stat::NotInstr, "NotInstr"}, {Stat::NoCalib, "NoCalib"}, @@ -173,10 +171,6 @@ namespace CaloStatusMapperDefs { status = Stat::Hot; } - else if (tower->get_isBadTime()) - { - status = Stat::BadTime; - } else if (tower->get_isBadChi2()) { status = Stat::BadChi; @@ -204,7 +198,6 @@ namespace CaloStatusMapperDefs { bool skip = false; if ((label == "Hot") || - (label == "BadTime") || (label == "BadChi") || (label == "NoCalib") || (label == "NotInstr") || diff --git a/offline/packages/CaloBase/TowerInfo.h b/offline/packages/CaloBase/TowerInfo.h index 821da289d7..2ec6402f2b 100644 --- a/offline/packages/CaloBase/TowerInfo.h +++ b/offline/packages/CaloBase/TowerInfo.h @@ -30,8 +30,8 @@ class TowerInfo : public PHObject virtual float get_pedestal() { return std::numeric_limits::quiet_NaN(); } virtual void set_isHot(bool /*isHot*/) { return; } virtual bool get_isHot() const { return false; } - virtual void set_isBadTime(bool /*isBadTime*/) { return; } - virtual bool get_isBadTime() const { return false; } + virtual void set_FitStatus(bool /*fitstatus*/) { return; } + virtual bool get_FitStatus() const { return false; } virtual void set_isBadChi2(bool /*isBadChi2*/) { return; } virtual bool get_isBadChi2() const { return false; } virtual void set_isNotInstr(bool /*isNotInstr*/) { return; } diff --git a/offline/packages/CaloBase/TowerInfov2.h b/offline/packages/CaloBase/TowerInfov2.h index 8d064d840f..dd8889ff48 100644 --- a/offline/packages/CaloBase/TowerInfov2.h +++ b/offline/packages/CaloBase/TowerInfov2.h @@ -24,8 +24,8 @@ class TowerInfov2 : public TowerInfov1 void set_isHot(bool isHot) override { set_status_bit(0, isHot); } bool get_isHot() const override { return get_status_bit(0); } - void set_isBadTime(bool isBadTime) override { set_status_bit(1, isBadTime); } - bool get_isBadTime() const override { return get_status_bit(1); } + void set_FitStatus(bool fitstatus) override { set_status_bit(1, fitstatus); } + bool get_FitStatus() const override { return get_status_bit(1); } void set_isBadChi2(bool isBadChi2) override { set_status_bit(2, isBadChi2); } bool get_isBadChi2() const override { return get_status_bit(2); } @@ -45,7 +45,7 @@ class TowerInfov2 : public TowerInfov1 void set_isSaturated(bool isSaturated) override { set_status_bit(7, isSaturated); } bool get_isSaturated() const override { return get_status_bit(7); } - bool get_isGood() const override { return !(get_isHot() || get_isBadChi2() || get_isNoCalib()); } + bool get_isGood() const override { return !(get_isHot() || get_isBadChi2() || get_isNoCalib() || get_isNotInstr()); } uint8_t get_status() const override { return _status; } diff --git a/offline/packages/CaloBase/TowerInfov4.h b/offline/packages/CaloBase/TowerInfov4.h index 09bd986298..6a44ca385b 100644 --- a/offline/packages/CaloBase/TowerInfov4.h +++ b/offline/packages/CaloBase/TowerInfov4.h @@ -58,8 +58,8 @@ class TowerInfov4 : public TowerInfo void set_isHot(bool isHot) override { set_status_bit(0, isHot); } bool get_isHot() const override { return get_status_bit(0); } - void set_isBadTime(bool isBadTime) override { set_status_bit(1, isBadTime); } - bool get_isBadTime() const override { return get_status_bit(1); } + void set_FitStatus(bool fitstatus) override { set_status_bit(1, fitstatus); } + bool get_FitStatus() const override { return get_status_bit(1); } void set_isBadChi2(bool isBadChi2) override { set_status_bit(2, isBadChi2); } bool get_isBadChi2() const override { return get_status_bit(2); } @@ -79,7 +79,7 @@ class TowerInfov4 : public TowerInfo void set_isSaturated(bool isSaturated) override { set_status_bit(7, isSaturated); } bool get_isSaturated() const override { return get_status_bit(7); } - bool get_isGood() const override { return !(get_isHot() || get_isBadChi2() || get_isNoCalib()); } + bool get_isGood() const override { return !(get_isHot() || get_isBadChi2() || get_isNoCalib() || get_isNotInstr()); } uint8_t get_status() const override { return status; } diff --git a/offline/packages/CaloReco/CaloTowerBuilder.cc b/offline/packages/CaloReco/CaloTowerBuilder.cc index 5082b9e9c3..ae029e759e 100644 --- a/offline/packages/CaloReco/CaloTowerBuilder.cc +++ b/offline/packages/CaloReco/CaloTowerBuilder.cc @@ -240,6 +240,7 @@ int CaloTowerBuilder::process_sim() { towerinfo->set_isRecovered(true); } + towerinfo->set_FitStatus(static_cast(processed_waveforms.at(i).at(5))); int n_samples = waveforms.at(i).size(); if (n_samples == m_nzerosuppsamples || SZS) { diff --git a/offline/packages/CaloReco/CaloTowerStatus.cc b/offline/packages/CaloReco/CaloTowerStatus.cc index 86eb680e3e..9ca24be054 100644 --- a/offline/packages/CaloReco/CaloTowerStatus.cc +++ b/offline/packages/CaloReco/CaloTowerStatus.cc @@ -123,7 +123,7 @@ int CaloTowerStatus::InitRun(PHCompositeNode *topNode) m_cdbttree_time = new CDBTTree(calibdir); if (Verbosity() > 0) { - std::cout << "CaloTowerStatus::InitRun Found " << m_calibName_time << " not Doing isBadTime" << std::endl; + std::cout << "CaloTowerStatus::InitRun Found " << m_calibName_time << std::endl; } } else @@ -144,7 +144,7 @@ int CaloTowerStatus::InitRun(PHCompositeNode *topNode) m_doTime = false; if (Verbosity() > 1) { - std::cout << "CaloTowerStatus::InitRun no timing info, " << m_calibName_time << " not found, not doing isBadTime" << std::endl; + std::cout << "CaloTowerStatus::InitRun no timing info, " << m_calibName_time << " not found" << std::endl; } } } @@ -259,7 +259,6 @@ int CaloTowerStatus::process_event(PHCompositeNode * /*topNode*/) { // only reset what we will set m_raw_towers->get_tower_at_channel(channel)->set_isHot(false); - m_raw_towers->get_tower_at_channel(channel)->set_isBadTime(false); m_raw_towers->get_tower_at_channel(channel)->set_isBadChi2(false); if (m_doHotChi2) @@ -283,10 +282,6 @@ int CaloTowerStatus::process_event(PHCompositeNode * /*topNode*/) { m_raw_towers->get_tower_at_channel(channel)->set_isHot(true); } - if (!m_raw_towers->get_tower_at_channel(channel)->get_isZS() && std::fabs(time - mean_time) > time_cut && m_doTime) - { - m_raw_towers->get_tower_at_channel(channel)->set_isBadTime(true); - } if (( hotMap_val == 1 || // dead std::fabs(z_score) > z_score_threshold || // hot or cold (hotMap_val == 3 && z_score >= -1 * z_score_threshold_default)) // cold part 2 diff --git a/offline/packages/CaloReco/CaloWaveformFitting.cc b/offline/packages/CaloReco/CaloWaveformFitting.cc index ba59367542..72e6211f04 100644 --- a/offline/packages/CaloReco/CaloWaveformFitting.cc +++ b/offline/packages/CaloReco/CaloWaveformFitting.cc @@ -78,6 +78,7 @@ std::vector> CaloWaveformFitting::calo_processing_templatefit v.push_back(std::numeric_limits::quiet_NaN()); } v.push_back(0); + v.push_back(0); } else { @@ -119,6 +120,7 @@ std::vector> CaloWaveformFitting::calo_processing_templatefit v.push_back(std::numeric_limits::quiet_NaN()); } v.push_back(0); + v.push_back(0); } else { @@ -165,10 +167,10 @@ std::vector> CaloWaveformFitting::calo_processing_templatefit } fitter->FitFCN(*EPChi2, nullptr, data.Size(), true); ROOT::Fit::FitResult fitres = fitter->Result(); - // get the result status + // get the fit status code (0 means successful fit) + int validfit = fitres.Status(); /* - bool validfit = fitres.IsValid(); - if(!validfit) + if(validfit != 0) { std::cout<<"invalid fit"<> CaloWaveformFitting::calo_processing_templatefit recoverFitter->Config().ParSettings(1).SetLimits(-1 * m_peakTimeTemp, size1 - m_peakTimeTemp); // set lim on time par recoverFitter->FitFCN(*recoverEPChi2, nullptr, recoverData.Size(), true); ROOT::Fit::FitResult recover_fitres = recoverFitter->Result(); + int recover_validfit = recover_fitres.Status(); double recover_chi2min = recover_fitres.MinFcnValue(); recover_chi2min /= size1 - 3; // divide by the number of dof if (recover_chi2min < _chi2lowthreshold && recover_f->GetParameter(2) < _bfr_highpedestalthreshold && recover_f->GetParameter(2) > _bfr_lowpedestalthreshold) @@ -254,6 +257,7 @@ std::vector> CaloWaveformFitting::calo_processing_templatefit } v.push_back(recover_chi2min); v.push_back(1); + v.push_back(recover_validfit); } else { @@ -263,6 +267,7 @@ std::vector> CaloWaveformFitting::calo_processing_templatefit } v.push_back(chi2min); v.push_back(0); + v.push_back(validfit); } recover_f->Delete(); delete recoverFitFunction; @@ -277,6 +282,7 @@ std::vector> CaloWaveformFitting::calo_processing_templatefit } v.push_back(chi2min); v.push_back(0); + v.push_back(validfit); } h->Delete(); f->Delete(); @@ -295,7 +301,7 @@ std::vector> CaloWaveformFitting::calo_processing_templatefit { const std::vector &tv = chnlvector.at(i); int size2 = tv.size(); - for (int q = 5; q > 0; q--) + for (int q = 6; q > 0; q--) { fit_params_tmp.push_back(tv.at(size2 - q)); } @@ -434,7 +440,7 @@ std::vector> CaloWaveformFitting::calo_processing_fast(const } } amp -= ped; - std::vector val = {amp, time, ped, chi2, 0}; + std::vector val = {amp, time, ped, chi2, 0, 0}; fit_values.push_back(val); val.clear(); } @@ -457,7 +463,7 @@ std::vector> CaloWaveformFitting::calo_processing_nyquist(con { chi2 = 1000000; } - fit_values.push_back({v.at(1) - v.at(0), std::numeric_limits::quiet_NaN(), v.at(0), chi2, 0}); + fit_values.push_back({v.at(1) - v.at(0), std::numeric_limits::quiet_NaN(), v.at(0), chi2, 0, 0}); continue; } @@ -532,7 +538,7 @@ std::vector CaloWaveformFitting::NyquistInterpolation(std::vector float diff = vec_signal_samples[i] - template_function(xval, par); chi2 += diff * diff; } - std::vector val = {max - pedestal, maxpos, pedestal, chi2, 0}; + std::vector val = {max - pedestal, maxpos, pedestal, chi2, 0, 0}; return val; } @@ -720,7 +726,7 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con { chi2 = 1000000; } - fit_values.push_back({amp, time, ped, chi2, 0}); + fit_values.push_back({amp, time, ped, chi2, 0, 0}); continue; } @@ -761,7 +767,7 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con { chi2 = 1000000; } - fit_values.push_back({amp, time, ped, chi2, 0}); + fit_values.push_back({amp, time, ped, chi2, 0, 0}); continue; } @@ -794,6 +800,7 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con double fit_time = 0; double fit_ped = 0; double chi2val = 0; + int validfit = 0; int npar = 0; if (m_funcfit_type == POWERLAWEXP) @@ -820,7 +827,7 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con f.SetParLimits(4, pedestal - std::abs(maxheight - pedestal), pedestal + std::abs(maxheight - pedestal)); // Perform fit - h.Fit(&f, "QRN0W", "", 0, nsamples); + TFitResultPtr fitres = h.Fit(&f, "SQRN0W", "", 0, nsamples); // Calculate peak amplitude and time from fit parameters // Peak height is (p0 * Power(p2/p3, p2)) / exp(p2) @@ -838,6 +845,7 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con chi2val += diff * diff; } } + validfit = fitres.Status(); } else if(m_funcfit_type == POWERLAWDOUBLEEXP) { @@ -867,7 +875,7 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con f.SetParLimits(6, risetime * 0.5, risetime * 4); // Perform fit - h.Fit(&f, "QRN0W", "", 0, nsamples); + TFitResultPtr fitres = h.Fit(&f, "SQRN0W", "", 0, nsamples); // Find peak by evaluating the function double peakpos1 = f.GetParameter(3); @@ -888,6 +896,7 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con chi2val += diff * diff; } } + validfit = fitres.Status(); } else if(m_funcfit_type == FERMIEXP) { @@ -911,7 +920,7 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con f.FixParameter(2, 0.2); - h.Fit(&f, "QRN0W", "", 0, nsamples); + TFitResultPtr fitres = h.Fit(&f, "SQRN0W", "", 0, nsamples); fit_time = f.GetParameter(1); fit_amp = f.GetParameter(0); @@ -926,6 +935,7 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con chi2val += diff * diff; } } + validfit = fitres.Status(); } int ndf = ndata - npar; @@ -939,7 +949,7 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con } fit_values.push_back({static_cast(fit_amp), static_cast(fit_time), - static_cast(fit_ped), static_cast(chi2val), 0}); + static_cast(fit_ped), static_cast(chi2val), 0, validfit}); } return fit_values; diff --git a/offline/packages/CaloReco/CaloWaveformProcessing.cc b/offline/packages/CaloReco/CaloWaveformProcessing.cc index 057e427627..ad4993aca4 100644 --- a/offline/packages/CaloReco/CaloWaveformProcessing.cc +++ b/offline/packages/CaloReco/CaloWaveformProcessing.cc @@ -135,6 +135,7 @@ std::vector> CaloWaveformProcessing::calo_processing_ONNX(con val.push_back(std::numeric_limits::quiet_NaN()); } val.push_back(0); + val.push_back(0); fit_values.push_back(val); } else @@ -177,6 +178,7 @@ std::vector> CaloWaveformProcessing::calo_processing_ONNX(con val.push_back(std::numeric_limits::quiet_NaN()); } val.push_back(0); + val.push_back(0); fit_values.push_back(val); } else @@ -195,12 +197,13 @@ std::vector> CaloWaveformProcessing::calo_processing_ONNX(con } val.push_back(2000); val.push_back(0); + val.push_back(0); fit_values.push_back(val); } else { float v_diff = v[1] - v[0]; - std::vector val1{v_diff, std::numeric_limits::quiet_NaN(), v[1], std::numeric_limits::quiet_NaN(), 0}; + std::vector val1{v_diff, std::numeric_limits::quiet_NaN(), v[1], std::numeric_limits::quiet_NaN(), 0, 0}; fit_values.push_back(val1); } } diff --git a/offline/packages/NodeDump/DumpTowerInfoContainer.cc b/offline/packages/NodeDump/DumpTowerInfoContainer.cc index 21f8c99c19..7ae0ae0230 100644 --- a/offline/packages/NodeDump/DumpTowerInfoContainer.cc +++ b/offline/packages/NodeDump/DumpTowerInfoContainer.cc @@ -41,7 +41,6 @@ int DumpTowerInfoContainer::process_Node(PHNode *myNode) *fout << "chi2: " << rawtwr->get_chi2() << std::endl; *fout << "pedestal: " << rawtwr->get_pedestal() << std::endl; *fout << "isHot: " << rawtwr->get_isHot() << std::endl; - *fout << "isBadTime: " << rawtwr->get_isBadTime() << std::endl; *fout << "isNotInstr: " << rawtwr->get_isNotInstr() << std::endl; *fout << "isGood: " << rawtwr->get_isGood() << std::endl; *fout << "status: " << static_cast(rawtwr->get_status()) << std::endl; diff --git a/offline/packages/jetbackground/SubtractTowers.cc b/offline/packages/jetbackground/SubtractTowers.cc index 3d0ee5532e..1c6c51a0db 100644 --- a/offline/packages/jetbackground/SubtractTowers.cc +++ b/offline/packages/jetbackground/SubtractTowers.cc @@ -166,7 +166,7 @@ int SubtractTowers::process_event(PHCompositeNode *topNode) } float new_energy = raw_energy - UE; // if a tower is masked, leave it at zero - if (tower->get_isHot() || tower->get_isNoCalib() || tower->get_isNotInstr() || tower->get_isBadChi2()) + if (!tower->get_isGood()) { new_energy = 0; } @@ -259,7 +259,7 @@ int SubtractTowers::process_event(PHCompositeNode *topNode) } float new_energy = raw_energy - UE; // if a tower is masked, leave it at zero - if (tower->get_isHot() || tower->get_isNoCalib() || tower->get_isNotInstr() || tower->get_isBadChi2()) + if (!tower->get_isGood()) { new_energy = 0; } @@ -348,7 +348,7 @@ int SubtractTowers::process_event(PHCompositeNode *topNode) } float new_energy = raw_energy - UE; // if a tower is masked, leave it at zero - if (tower->get_isHot() || tower->get_isNoCalib() || tower->get_isNotInstr() || tower->get_isBadChi2()) + if (!tower->get_isGood()) { new_energy = 0; } From 8df20942102f6823d1a8aa0c4ddf83dadea748ad Mon Sep 17 00:00:00 2001 From: emclaughlin2 Date: Wed, 25 Feb 2026 14:06:50 -0500 Subject: [PATCH 282/393] Further updates: add fitstatus setter to process data in calotowerbuilder, remove unused time variables in calotowerstatus, use TFitResult* instead of TFitResultPtr object to get status of functional fit results --- offline/packages/CaloReco/CaloTowerBuilder.cc | 1 + offline/packages/CaloReco/CaloTowerStatus.cc | 6 ------ offline/packages/CaloReco/CaloWaveformFitting.cc | 14 ++++++++------ 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/offline/packages/CaloReco/CaloTowerBuilder.cc b/offline/packages/CaloReco/CaloTowerBuilder.cc index ae029e759e..7f77e48252 100644 --- a/offline/packages/CaloReco/CaloTowerBuilder.cc +++ b/offline/packages/CaloReco/CaloTowerBuilder.cc @@ -513,6 +513,7 @@ int CaloTowerBuilder::process_event(PHCompositeNode *topNode) { towerinfo->set_isRecovered(true); } + towerinfo->set_FitStatus(static_cast(processed_waveforms.at(i).at(5))); int n_samples = waveforms.at(idx).size(); if (n_samples == m_nzerosuppsamples || SZS) { diff --git a/offline/packages/CaloReco/CaloTowerStatus.cc b/offline/packages/CaloReco/CaloTowerStatus.cc index 9ca24be054..6a98789c2f 100644 --- a/offline/packages/CaloReco/CaloTowerStatus.cc +++ b/offline/packages/CaloReco/CaloTowerStatus.cc @@ -252,7 +252,6 @@ int CaloTowerStatus::process_event(PHCompositeNode * /*topNode*/) { unsigned int ntowers = m_raw_towers->size(); float fraction_badChi2 = 0; - float mean_time = 0; int hotMap_val = 0; float z_score = 0; for (unsigned int channel = 0; channel < ntowers; channel++) @@ -265,17 +264,12 @@ int CaloTowerStatus::process_event(PHCompositeNode * /*topNode*/) { fraction_badChi2 = m_cdbInfo_vec[channel].fraction_badChi2; } - if (m_doTime) - { - mean_time = m_cdbInfo_vec[channel].mean_time; - } if (m_doHotMap) { hotMap_val = m_cdbInfo_vec[channel].hotMap_val; z_score = m_cdbInfo_vec[channel].z_score; } float chi2 = m_raw_towers->get_tower_at_channel(channel)->get_chi2(); - float time = m_raw_towers->get_tower_at_channel(channel)->get_time(); float adc = m_raw_towers->get_tower_at_channel(channel)->get_energy(); if (fraction_badChi2 > fraction_badChi2_threshold && m_doHotChi2) diff --git a/offline/packages/CaloReco/CaloWaveformFitting.cc b/offline/packages/CaloReco/CaloWaveformFitting.cc index 72e6211f04..18698ce71d 100644 --- a/offline/packages/CaloReco/CaloWaveformFitting.cc +++ b/offline/packages/CaloReco/CaloWaveformFitting.cc @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -172,11 +173,12 @@ std::vector> CaloWaveformFitting::calo_processing_templatefit /* if(validfit != 0) { - std::cout<<"invalid fit"<> CaloWaveformFitting::calo_processing_funcfit(con chi2val += diff * diff; } } - validfit = fitres.Status(); + validfit = fitres.Get()->Status(); } else if(m_funcfit_type == POWERLAWDOUBLEEXP) { @@ -896,7 +898,7 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con chi2val += diff * diff; } } - validfit = fitres.Status(); + validfit = fitres.Get()->Status(); } else if(m_funcfit_type == FERMIEXP) { @@ -935,7 +937,7 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con chi2val += diff * diff; } } - validfit = fitres.Status(); + validfit = fitres.Get()->Status(); } int ndf = ndata - npar; @@ -949,7 +951,7 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con } fit_values.push_back({static_cast(fit_amp), static_cast(fit_time), - static_cast(fit_ped), static_cast(chi2val), 0, validfit}); + static_cast(fit_ped), static_cast(chi2val), 0, static_cast(validfit)}); } return fit_values; From 8af50390f772fb46a1489a9c07a74d25ba6f67ad Mon Sep 17 00:00:00 2001 From: emclaughlin2 Date: Wed, 25 Feb 2026 14:10:04 -0500 Subject: [PATCH 283/393] Change to correct index mapping when setting FitStatus flag for use in all calorimeters --- offline/packages/CaloReco/CaloTowerBuilder.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/CaloReco/CaloTowerBuilder.cc b/offline/packages/CaloReco/CaloTowerBuilder.cc index 7f77e48252..2d0f31a017 100644 --- a/offline/packages/CaloReco/CaloTowerBuilder.cc +++ b/offline/packages/CaloReco/CaloTowerBuilder.cc @@ -513,7 +513,7 @@ int CaloTowerBuilder::process_event(PHCompositeNode *topNode) { towerinfo->set_isRecovered(true); } - towerinfo->set_FitStatus(static_cast(processed_waveforms.at(i).at(5))); + towerinfo->set_FitStatus(static_cast(processed_waveforms.at(idx).at(5))); int n_samples = waveforms.at(idx).size(); if (n_samples == m_nzerosuppsamples || SZS) { From bab80cba89128593a2b47f511bc549a75a3dc0dd Mon Sep 17 00:00:00 2001 From: emclaughlin2 Date: Wed, 25 Feb 2026 14:20:29 -0500 Subject: [PATCH 284/393] Add protections for null value returned from fit result --- offline/packages/CaloReco/CaloWaveformFitting.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/offline/packages/CaloReco/CaloWaveformFitting.cc b/offline/packages/CaloReco/CaloWaveformFitting.cc index 18698ce71d..307b487d1a 100644 --- a/offline/packages/CaloReco/CaloWaveformFitting.cc +++ b/offline/packages/CaloReco/CaloWaveformFitting.cc @@ -169,7 +169,8 @@ std::vector> CaloWaveformFitting::calo_processing_templatefit fitter->FitFCN(*EPChi2, nullptr, data.Size(), true); ROOT::Fit::FitResult fitres = fitter->Result(); // get the fit status code (0 means successful fit) - int validfit = fitres.Status(); + int validfit = 1; + if (fitres) { validfit = fitres.Status(); } /* if(validfit != 0) { @@ -244,7 +245,8 @@ std::vector> CaloWaveformFitting::calo_processing_templatefit recoverFitter->Config().ParSettings(1).SetLimits(-1 * m_peakTimeTemp, size1 - m_peakTimeTemp); // set lim on time par recoverFitter->FitFCN(*recoverEPChi2, nullptr, recoverData.Size(), true); ROOT::Fit::FitResult recover_fitres = recoverFitter->Result(); - int recover_validfit = recover_fitres.Status(); + int recover_validfit = 1; + if (recover_fitres) { recover_validfit = recover_fitres.Status(); } double recover_chi2min = recover_fitres.MinFcnValue(); recover_chi2min /= size1 - 3; // divide by the number of dof if (recover_chi2min < _chi2lowthreshold && recover_f->GetParameter(2) < _bfr_highpedestalthreshold && recover_f->GetParameter(2) > _bfr_lowpedestalthreshold) @@ -847,7 +849,7 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con chi2val += diff * diff; } } - validfit = fitres.Get()->Status(); + if (fitres.Get()) { validfit = fitres.Get()->Status(); } } else if(m_funcfit_type == POWERLAWDOUBLEEXP) { @@ -898,7 +900,7 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con chi2val += diff * diff; } } - validfit = fitres.Get()->Status(); + if (fitres.Get()) { validfit = fitres.Get()->Status(); } } else if(m_funcfit_type == FERMIEXP) { @@ -937,7 +939,7 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con chi2val += diff * diff; } } - validfit = fitres.Get()->Status(); + if (fitres.Get()) { validfit = fitres.Get()->Status(); } } int ndf = ndata - npar; From f71dca342607aadfe3c5efbd2619e5881a05c8e9 Mon Sep 17 00:00:00 2001 From: emclaughlin2 Date: Wed, 25 Feb 2026 14:27:37 -0500 Subject: [PATCH 285/393] Fix fit result extraction for template fit and recovery template fit --- offline/packages/CaloReco/CaloWaveformFitting.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/offline/packages/CaloReco/CaloWaveformFitting.cc b/offline/packages/CaloReco/CaloWaveformFitting.cc index 307b487d1a..3ea4e36cf1 100644 --- a/offline/packages/CaloReco/CaloWaveformFitting.cc +++ b/offline/packages/CaloReco/CaloWaveformFitting.cc @@ -169,8 +169,7 @@ std::vector> CaloWaveformFitting::calo_processing_templatefit fitter->FitFCN(*EPChi2, nullptr, data.Size(), true); ROOT::Fit::FitResult fitres = fitter->Result(); // get the fit status code (0 means successful fit) - int validfit = 1; - if (fitres) { validfit = fitres.Status(); } + int validfit = fitres.Status(); /* if(validfit != 0) { @@ -245,8 +244,7 @@ std::vector> CaloWaveformFitting::calo_processing_templatefit recoverFitter->Config().ParSettings(1).SetLimits(-1 * m_peakTimeTemp, size1 - m_peakTimeTemp); // set lim on time par recoverFitter->FitFCN(*recoverEPChi2, nullptr, recoverData.Size(), true); ROOT::Fit::FitResult recover_fitres = recoverFitter->Result(); - int recover_validfit = 1; - if (recover_fitres) { recover_validfit = recover_fitres.Status(); } + int recover_validfit = recover_fitres.Status(); double recover_chi2min = recover_fitres.MinFcnValue(); recover_chi2min /= size1 - 3; // divide by the number of dof if (recover_chi2min < _chi2lowthreshold && recover_f->GetParameter(2) < _bfr_highpedestalthreshold && recover_f->GetParameter(2) > _bfr_lowpedestalthreshold) From c1bb2fe05eebb4bfbcb66bc946903d70e62953ca Mon Sep 17 00:00:00 2001 From: Joseph Clement Date: Wed, 25 Feb 2026 15:39:44 -0500 Subject: [PATCH 286/393] use calib name from DB --- offline/packages/jetbackground/TimingCut.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/offline/packages/jetbackground/TimingCut.cc b/offline/packages/jetbackground/TimingCut.cc index e2949bbe7b..b706c635a1 100644 --- a/offline/packages/jetbackground/TimingCut.cc +++ b/offline/packages/jetbackground/TimingCut.cc @@ -41,11 +41,11 @@ int TimingCut::Init(PHCompositeNode *topNode) return Fun4AllReturnCodes::ABORTRUN; } - _fitFile = new CDBTF(CDBInterface::instance()->getUrl("t_ohfrac_calib_Default")); + _fitFile = new CDBTF(CDBInterface::instance()->getUrl("OHCAL_JET_TIME_FRACTION")); if(_fitFile) { _fitFile->LoadCalibrations(); - _fitFunc = _fitFile->getTF("t_ohcal_calib_function_Default"); + _fitFunc = _fitFile->getTF("JET_TIMING_CALO_FRACTION_CALIB_fullrange"); if(!_fitFunc) { std::cout << "ERROR: NO CALIBRATION TF1 FOUND FOR TIMING CUT OHCAL FRACTION CORRECTION! This should never happen. ABORT RUN!" << std::endl; From 47d12f1bb92ad0c8faa0df773166cee078d073c1 Mon Sep 17 00:00:00 2001 From: Joseph Clement Date: Thu, 26 Feb 2026 14:20:45 -0500 Subject: [PATCH 287/393] Implement suggested fixes from coderabbit and Chris for timing cut module. --- offline/packages/jetbackground/TimingCut.cc | 20 ++++--- offline/packages/jetbackground/TimingCut.h | 60 ++++++++++----------- 2 files changed, 44 insertions(+), 36 deletions(-) diff --git a/offline/packages/jetbackground/TimingCut.cc b/offline/packages/jetbackground/TimingCut.cc index b706c635a1..c4c23a1a36 100644 --- a/offline/packages/jetbackground/TimingCut.cc +++ b/offline/packages/jetbackground/TimingCut.cc @@ -41,11 +41,13 @@ int TimingCut::Init(PHCompositeNode *topNode) return Fun4AllReturnCodes::ABORTRUN; } - _fitFile = new CDBTF(CDBInterface::instance()->getUrl("OHCAL_JET_TIME_FRACTION")); - if(_fitFile) + std::string fitUrl = CDBInterface::instance()->getUrl("OHCAL_JET_TIME_FRACTION"); + if(!fitUrl.empty()) { - _fitFile->LoadCalibrations(); - _fitFunc = _fitFile->getTF("JET_TIMING_CALO_FRACTION_CALIB_fullrange"); + CDBTF* fitFile = new CDBTF(fitUrl); + fitFile->LoadCalibrations(); + _fitFunc = (TF1*)fitFile->getTF("JET_TIMING_CALO_FRACTION_CALIB_fullrange")->Clone(); + delete fitFile; if(!_fitFunc) { std::cout << "ERROR: NO CALIBRATION TF1 FOUND FOR TIMING CUT OHCAL FRACTION CORRECTION! This should never happen. ABORT RUN!" << std::endl; @@ -125,10 +127,16 @@ int TimingCut::process_event(PHCompositeNode *topNode) { unsigned int channel = comp.second; TowerInfo* tower = towersOH->get_tower_at_channel(channel); + if(!tower) + { + std::cout << "Component tower missing! This should not happen (something is wrong, check your inputs). Abort event!" << std::endl; + return Fun4AllReturnCodes::ABORTEVENT; + } jetOHFrac += tower->get_energy(); } } - jetOHFrac /= jet->get_e(); + jetOHFrac /= jet->get_e(); //We actually want this to be NaN when jet->get_e() == 0, because that case should fail. + //NaN always compares to false } else { @@ -166,7 +174,7 @@ int TimingCut::process_event(PHCompositeNode *topNode) return Fun4AllReturnCodes::ABORTEVENT; } - float corrMaxJett = Correct_Time_Ohfrac(maxJett, maxJetOHFrac); + float corrMaxJett = Correct_Time_Ohfrac(maxJett, maxJetOHFrac); //likewise, intentional NaNs here. float corrSubJett = Correct_Time_Ohfrac(subJett, subJetOHFrac); bool passDeltat = Pass_Delta_t(corrMaxJett, corrSubJett, maxJetPhi, subJetPhi); diff --git a/offline/packages/jetbackground/TimingCut.h b/offline/packages/jetbackground/TimingCut.h index 5fa3a134bc..c0db8a4ab0 100644 --- a/offline/packages/jetbackground/TimingCut.h +++ b/offline/packages/jetbackground/TimingCut.h @@ -23,35 +23,6 @@ class TimingCut : public SubsysReco ~TimingCut() override = default; - float Correct_Time_Ohfrac(float t, float ohfrac) - { - float corrt = t - _fitFunc->Eval(ohfrac); - return corrt; - } - - float calc_dphi(float maxJetPhi, float subJetPhi) - { - float dPhi = std::abs(maxJetPhi - subJetPhi); - if(dPhi>M_PI) dPhi -= M_PI; - return dPhi; - } - - bool Pass_Delta_t(float lead_time, float sub_time, float maxJetPhi, float subJetPhi) - { - float dPhi = calc_dphi(maxJetPhi, subJetPhi); - return (std::abs(lead_time - sub_time) < _dt_width && dPhi > _min_dphi); - } - - bool Pass_Lead_t(float lead_time) - { - return std::abs(lead_time + _t_shift) < _t_width; - } - - bool Pass_Mbd_dt(float lead_time, float mbd_time) - { - return std::abs(lead_time - mbd_time) < _mbd_dt_width; - } - void set_t_shift(float new_shift) { _t_shift = new_shift; } float get_t_shift() { return _t_shift; } @@ -102,6 +73,36 @@ class TimingCut : public SubsysReco } private: + + float Correct_Time_Ohfrac(float t, float ohfrac) + { + float corrt = t - _fitFunc->Eval(ohfrac); + return corrt; + } + + float calc_dphi(float maxJetPhi, float subJetPhi) + { + float dPhi = std::abs(maxJetPhi - subJetPhi); + if(dPhi>M_PI) dPhi -= M_PI; + return dPhi; + } + + bool Pass_Delta_t(float lead_time, float sub_time, float maxJetPhi, float subJetPhi) + { + float dPhi = calc_dphi(maxJetPhi, subJetPhi); + return (std::abs(lead_time - sub_time) < _dt_width && dPhi > _min_dphi); + } + + bool Pass_Lead_t(float lead_time) + { + return std::abs(lead_time + _t_shift) < _t_width; + } + + bool Pass_Mbd_dt(float lead_time, float mbd_time) + { + return std::abs(lead_time - mbd_time) < _mbd_dt_width; + } + bool _doAbort; bool _abortFailMbd = false; bool _missingInfoWarningPrinted = false; @@ -113,7 +114,6 @@ class TimingCut : public SubsysReco float _t_shift{0.0}; float _mbd_dt_width{3.0}; float _min_dphi{3*M_PI/4}; - CDBTF* _fitFile{nullptr}; TF1* _fitFunc{nullptr}; }; From 7f2886ad4d1bb46b5d9a06d653a29509411d6cc8 Mon Sep 17 00:00:00 2001 From: rosstom Date: Thu, 26 Feb 2026 16:15:06 -0500 Subject: [PATCH 288/393] Return NAN for TrackSeed calls to get seed indices --- offline/packages/trackbase_historic/TrackSeed.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/offline/packages/trackbase_historic/TrackSeed.h b/offline/packages/trackbase_historic/TrackSeed.h index 3d99703500..4289bf4ce6 100644 --- a/offline/packages/trackbase_historic/TrackSeed.h +++ b/offline/packages/trackbase_historic/TrackSeed.h @@ -49,8 +49,8 @@ class TrackSeed : public PHObject virtual float get_py() const { return NAN; } virtual short int get_crossing() const { return 0; } - virtual unsigned int get_silicon_seed_index() const { return 0; } - virtual unsigned int get_tpc_seed_index() const { return 0; } + virtual unsigned int get_silicon_seed_index() const { return NAN; } + virtual unsigned int get_tpc_seed_index() const { return NAN; } virtual short int get_crossing_estimate() const { return 0; } virtual bool empty_cluster_keys() const { return true; } From f5df20f116bd0ccbc0c20caccaeefd15194319c2 Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Thu, 26 Feb 2026 17:24:14 -0500 Subject: [PATCH 289/393] CaloTowerStatus - Remove Remnants of Timing Status - `meanTime` calib is no longer used in CaloTowerStatus due to removal of the isBadTime method --- offline/packages/CaloReco/CaloTowerStatus.cc | 42 +------------------- offline/packages/CaloReco/CaloTowerStatus.h | 26 ------------ 2 files changed, 1 insertion(+), 67 deletions(-) diff --git a/offline/packages/CaloReco/CaloTowerStatus.cc b/offline/packages/CaloReco/CaloTowerStatus.cc index 6a98789c2f..81013f9790 100644 --- a/offline/packages/CaloReco/CaloTowerStatus.cc +++ b/offline/packages/CaloReco/CaloTowerStatus.cc @@ -48,7 +48,6 @@ CaloTowerStatus::~CaloTowerStatus() std::cout << "CaloTowerStatus::~CaloTowerStatus() Calling dtor" << std::endl; } delete m_cdbttree_chi2; - delete m_cdbttree_time; delete m_cdbttree_hotMap; } @@ -114,41 +113,6 @@ int CaloTowerStatus::InitRun(PHCompositeNode *topNode) } } - m_calibName_time = m_detector + "_meanTime"; - m_fieldname_time = "time"; - - calibdir = CDBInterface::instance()->getUrl(m_calibName_time); - if (!calibdir.empty()) - { - m_cdbttree_time = new CDBTTree(calibdir); - if (Verbosity() > 0) - { - std::cout << "CaloTowerStatus::InitRun Found " << m_calibName_time << std::endl; - } - } - else - { - if (use_directURL_time) - { - calibdir = m_directURL_time; - std::cout << "CaloTowerStatus::InitRun: Using default time " << calibdir << std::endl; - m_cdbttree_time = new CDBTTree(calibdir); - } - else - { - if (m_doAbortNoTime) - { - std::cout << "CaloTowerStatus::InitRun: No time calibration found for " << m_calibName_time << " and abort mode is set. Exiting." << std::endl; - gSystem->Exit(1); - } - m_doTime = false; - if (Verbosity() > 1) - { - std::cout << "CaloTowerStatus::InitRun no timing info, " << m_calibName_time << " not found" << std::endl; - } - } - } - m_calibName_hotMap = m_detector + "nome"; if (m_dettype == CaloTowerDefs::CEMC || m_dettype == CaloTowerDefs::SEPD) { @@ -191,7 +155,7 @@ int CaloTowerStatus::InitRun(PHCompositeNode *topNode) if (Verbosity() > 0) { - std::cout << "CaloTowerStatus::Init " << m_detector << " doing time status =" << std::boolalpha << m_doTime << " doing hotBadChi2=" << std::boolalpha << m_doHotChi2 << " doing hot map=" << std::boolalpha << m_doHotMap << std::endl; + std::cout << "CaloTowerStatus::Init " << m_detector << " doing hotBadChi2=" << std::boolalpha << m_doHotChi2 << " doing hot map=" << std::boolalpha << m_doHotMap << std::endl; } PHNodeIterator iter(topNode); @@ -235,10 +199,6 @@ void CaloTowerStatus::LoadCalib() { m_cdbInfo_vec[channel].fraction_badChi2 = m_cdbttree_chi2->GetFloatValue(key, m_fieldname_chi2); } - if (m_doTime) - { - m_cdbInfo_vec[channel].mean_time = m_cdbttree_time->GetFloatValue(key, m_fieldname_time); - } if (m_doHotMap) { m_cdbInfo_vec[channel].hotMap_val = m_cdbttree_hotMap->GetIntValue(key, m_fieldname_hotMap); diff --git a/offline/packages/CaloReco/CaloTowerStatus.h b/offline/packages/CaloReco/CaloTowerStatus.h index 646116368d..1c50486281 100644 --- a/offline/packages/CaloReco/CaloTowerStatus.h +++ b/offline/packages/CaloReco/CaloTowerStatus.h @@ -68,23 +68,12 @@ class CaloTowerStatus : public SubsysReco z_score_threshold = threshold; return; } - void set_time_cut(float threshold) - { - time_cut = threshold; - return; - } void set_directURL_hotMap(const std::string &str) { m_directURL_hotMap = str; use_directURL_hotMap = true; return; } - void set_directURL_time(const std::string &str) - { - m_directURL_time = str; - use_directURL_time = true; - return; - } void set_directURL_chi2(const std::string &str) { m_directURL_chi2 = str; @@ -96,11 +85,6 @@ class CaloTowerStatus : public SubsysReco m_doAbortNoHotMap = status; return; } - void set_doAbortNoTime(bool status = true) - { - m_doAbortNoTime = status; - return; - } void set_doAbortNoChi2(bool status = true) { m_doAbortNoChi2 = status; @@ -109,7 +93,6 @@ class CaloTowerStatus : public SubsysReco void set_doAbortMissingCalib(bool status = true) { m_doAbortNoHotMap = status; - m_doAbortNoTime = status; m_doAbortNoChi2 = status; return; } @@ -118,21 +101,16 @@ class CaloTowerStatus : public SubsysReco TowerInfoContainer *m_raw_towers{nullptr}; CDBTTree *m_cdbttree_chi2{nullptr}; - CDBTTree *m_cdbttree_time{nullptr}; CDBTTree *m_cdbttree_hotMap{nullptr}; bool m_doHotChi2{true}; - bool m_doTime{true}; bool m_doHotMap{true}; bool m_doAbortNoHotMap{false}; - bool m_doAbortNoTime{false}; bool m_doAbortNoChi2{false}; CaloTowerDefs::DetectorSystem m_dettype{CaloTowerDefs::DETECTOR_INVALID}; std::string m_detector; - std::string m_fieldname_time; - std::string m_calibName_time; std::string m_fieldname_chi2; std::string m_calibName_chi2; std::string m_fieldname_hotMap; @@ -141,10 +119,8 @@ class CaloTowerStatus : public SubsysReco std::string m_inputNodePrefix{"TOWERS_"}; std::string m_inputNode; - std::string m_directURL_time; std::string m_directURL_hotMap; std::string m_directURL_chi2; - bool use_directURL_time{false}; bool use_directURL_hotMap{false}; bool use_directURL_chi2{false}; @@ -154,14 +130,12 @@ class CaloTowerStatus : public SubsysReco float fraction_badChi2_threshold = {0.01}; float z_score_threshold = {5}; float z_score_threshold_default = {5}; - float time_cut = 2; // number of samples from the mean time for the channel in the run void LoadCalib(); struct CDBInfo { float fraction_badChi2{0}; - float mean_time{0}; float z_score{0}; int hotMap_val{0}; }; From d619a978916db9fb454ad3725d25662a77a87a3c Mon Sep 17 00:00:00 2001 From: Nikhil Kumar Date: Thu, 26 Feb 2026 18:21:24 -0500 Subject: [PATCH 290/393] Turn skimming on by default Request from Blair to skim by default. --- .../Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h index ec03c20839..5c955f358e 100644 --- a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h +++ b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h @@ -51,19 +51,19 @@ class CaloStatusSkimmer : public SubsysReco { uint32_t n_skimcounter{0}; uint32_t n_notowernodecounter{0}; - bool b_do_skim_EMCal{false}; + bool b_do_skim_EMCal{true}; uint16_t m_EMC_skim_threshold{192}; // skim if nchannels >= this many not-instrumented (empty/missing packet) channels in EMCal - bool b_do_skim_HCal{false}; + bool b_do_skim_HCal{true}; uint16_t m_HCal_skim_threshold{192}; // skim if nchannels >= this many not-instrumented (empty/missing packet) channels in HCal - bool b_do_skim_sEPD{false}; + bool b_do_skim_sEPD{true}; uint16_t m_sEPD_skim_threshold{1}; // skim if nchannels >= this many not-instrumented (empty/missing packet) channels in sEPD - bool b_do_skim_ZDC{false}; + bool b_do_skim_ZDC{true}; uint16_t m_ZDC_skim_threshold{1}; // skim if nchannels >= this many not-instrumented (empty/missing packet) channels in ZDC }; From 4b73dffc279e56f8d6f9173989a82bc2d6be9f6c Mon Sep 17 00:00:00 2001 From: rosstom Date: Thu, 26 Feb 2026 18:35:32 -0500 Subject: [PATCH 291/393] Using max unsigned int instead of NAN --- offline/packages/trackbase_historic/TrackSeed.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/offline/packages/trackbase_historic/TrackSeed.h b/offline/packages/trackbase_historic/TrackSeed.h index 4289bf4ce6..371bf557ab 100644 --- a/offline/packages/trackbase_historic/TrackSeed.h +++ b/offline/packages/trackbase_historic/TrackSeed.h @@ -49,8 +49,8 @@ class TrackSeed : public PHObject virtual float get_py() const { return NAN; } virtual short int get_crossing() const { return 0; } - virtual unsigned int get_silicon_seed_index() const { return NAN; } - virtual unsigned int get_tpc_seed_index() const { return NAN; } + virtual unsigned int get_silicon_seed_index() const { return std::numeric_limits::max(); } + virtual unsigned int get_tpc_seed_index() const { return std::numeric_limits::max(); } virtual short int get_crossing_estimate() const { return 0; } virtual bool empty_cluster_keys() const { return true; } From 31c5c2aab67b6307d55a6847c8e296bbcefd2175 Mon Sep 17 00:00:00 2001 From: Joseph Clement Date: Thu, 26 Feb 2026 19:42:04 -0500 Subject: [PATCH 292/393] fix dphi calculation, guard against memory leaks and nullptr dereference --- offline/packages/jetbackground/TimingCut.cc | 7 ++++--- offline/packages/jetbackground/TimingCut.h | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/offline/packages/jetbackground/TimingCut.cc b/offline/packages/jetbackground/TimingCut.cc index c4c23a1a36..24dfb03c11 100644 --- a/offline/packages/jetbackground/TimingCut.cc +++ b/offline/packages/jetbackground/TimingCut.cc @@ -46,13 +46,14 @@ int TimingCut::Init(PHCompositeNode *topNode) { CDBTF* fitFile = new CDBTF(fitUrl); fitFile->LoadCalibrations(); - _fitFunc = (TF1*)fitFile->getTF("JET_TIMING_CALO_FRACTION_CALIB_fullrange")->Clone(); - delete fitFile; - if(!_fitFunc) + TF1* tmp = fitFile->getTF("JET_TIMING_CALO_FRACTION_CALIB_fullrange"); + if(!tmp) { std::cout << "ERROR: NO CALIBRATION TF1 FOUND FOR TIMING CUT OHCAL FRACTION CORRECTION! This should never happen. ABORT RUN!" << std::endl; return Fun4AllReturnCodes::ABORTRUN; } + _fitFunc = std::unique_ptr((TF1*)tmp->Clone()); + delete fitFile; } else { diff --git a/offline/packages/jetbackground/TimingCut.h b/offline/packages/jetbackground/TimingCut.h index c0db8a4ab0..000dc196a7 100644 --- a/offline/packages/jetbackground/TimingCut.h +++ b/offline/packages/jetbackground/TimingCut.h @@ -12,6 +12,7 @@ #include #include #include +#include class CDBTF; class PHCompositeNode; @@ -83,7 +84,7 @@ class TimingCut : public SubsysReco float calc_dphi(float maxJetPhi, float subJetPhi) { float dPhi = std::abs(maxJetPhi - subJetPhi); - if(dPhi>M_PI) dPhi -= M_PI; + if(dPhi>M_PI) dPhi = 2*M_PI - dPhi; return dPhi; } @@ -114,7 +115,7 @@ class TimingCut : public SubsysReco float _t_shift{0.0}; float _mbd_dt_width{3.0}; float _min_dphi{3*M_PI/4}; - TF1* _fitFunc{nullptr}; + std::unique_ptr _fitFunc{nullptr}; }; #endif From 35f1556f5000291337dba26ac2525e8f4b49e612 Mon Sep 17 00:00:00 2001 From: mchiu-bnl Date: Thu, 26 Feb 2026 21:12:18 -0500 Subject: [PATCH 293/393] added get_pederr(), etc --- offline/packages/mbd/MbdCalib.cc | 2 +- offline/packages/mbd/MbdCalib.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/offline/packages/mbd/MbdCalib.cc b/offline/packages/mbd/MbdCalib.cc index e8d10ba00a..578fead8ac 100644 --- a/offline/packages/mbd/MbdCalib.cc +++ b/offline/packages/mbd/MbdCalib.cc @@ -1540,7 +1540,7 @@ int MbdCalib::Download_Pileup(const std::string& dbase_location) if (Verbosity() > 0) { - if (feech < 2 || feech >= MbdDefs::MBD_N_PMT - 2) + if (feech < 2 || feech >= MbdDefs::MBD_N_FEECH - 2) { std::cout << feech << "\t" << _pileup_p0[feech] << "\t" << _pileup_p0err[feech] << "\t" << _pileup_p1[feech] << "\t" << _pileup_p1err[feech] diff --git a/offline/packages/mbd/MbdCalib.h b/offline/packages/mbd/MbdCalib.h index 6f0a6e579a..65b5a52fee 100644 --- a/offline/packages/mbd/MbdCalib.h +++ b/offline/packages/mbd/MbdCalib.h @@ -35,7 +35,9 @@ class MbdCalib float get_tq0(const int ipmt) const { return _tqfit_t0mean[ipmt]; } float get_t0corr() const { return _t0corrmean; } float get_ped(const int ifeech) const { return _pedmean[ifeech]; } + float get_pederr(const int ifeech) const { return _pedmeanerr[ifeech]; } float get_pedrms(const int ifeech) const { return _pedsigma[ifeech]; } + float get_pedrmserr(const int ifeech) const { return _pedsigmaerr[ifeech]; } int get_sampmax(const int ifeech) const { return _sampmax[ifeech]; } int get_status(const int ifeech) const { return _mbdstatus[ifeech]; } From 37ff672c2080c2cb37f8ab4c1e373e03f90a7d94 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Fri, 27 Feb 2026 08:57:37 -0500 Subject: [PATCH 294/393] add cluster map name setter --- offline/packages/trackreco/PHMicromegasTpcTrackMatching.cc | 4 ++-- offline/packages/trackreco/PHMicromegasTpcTrackMatching.h | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/offline/packages/trackreco/PHMicromegasTpcTrackMatching.cc b/offline/packages/trackreco/PHMicromegasTpcTrackMatching.cc index 197d7039e3..a6294c7ff0 100644 --- a/offline/packages/trackreco/PHMicromegasTpcTrackMatching.cc +++ b/offline/packages/trackreco/PHMicromegasTpcTrackMatching.cc @@ -889,12 +889,12 @@ int PHMicromegasTpcTrackMatching::GetNodes(PHCompositeNode* topNode) } else { - _cluster_map = findNode::getClass(topNode, "TRKR_CLUSTER"); + _cluster_map = findNode::getClass(topNode, _clustermap_name); } if (!_cluster_map) { - std::cerr << PHWHERE << " ERROR: Can't find node TRKR_CLUSTER" << std::endl; + std::cerr << PHWHERE << " ERROR: Can't find node " << _clustermap_name << std::endl; return Fun4AllReturnCodes::ABORTEVENT; } diff --git a/offline/packages/trackreco/PHMicromegasTpcTrackMatching.h b/offline/packages/trackreco/PHMicromegasTpcTrackMatching.h index 58d2004041..7f9f8e2611 100644 --- a/offline/packages/trackreco/PHMicromegasTpcTrackMatching.h +++ b/offline/packages/trackreco/PHMicromegasTpcTrackMatching.h @@ -42,13 +42,13 @@ class PHMicromegasTpcTrackMatching : public SubsysReco void set_pt_cut( const float pt) { _pt_cut = pt; } void set_dphi_cut( const float dphi) { _dphi_cut = dphi; } void SetIteration(int iter) { _n_iteration = iter; } - + void set_clustermap_name(const std::string& name) { _clustermap_name = name; } void zeroField(const bool flag) { _zero_field = flag; } int Init(PHCompositeNode* topNode) override; int InitRun(PHCompositeNode* topNode) override; int process_event(PHCompositeNode*) override; int End(PHCompositeNode*) override; - + // deprecated calls inline void set_sc_calib_mode(const bool) {} inline void set_collision_rate(const double) {} @@ -89,6 +89,8 @@ class PHMicromegasTpcTrackMatching : public SubsysReco TrackSeedContainer* _tpc_track_map{nullptr}; TrackSeedContainer* _si_track_map{nullptr}; + std::string _clustermap_name = "TRKR_CLUSTER"; + //! default rphi search window for each layer std::array _rphi_search_win{0.25, 13.0}; From 5ca6985357ee2e10b8fb661dcd3d609d39301bbe Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Fri, 27 Feb 2026 09:01:45 -0500 Subject: [PATCH 295/393] fixes bounds for histogram --- offline/QA/Tracking/SiliconSeedsQA.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/offline/QA/Tracking/SiliconSeedsQA.cc b/offline/QA/Tracking/SiliconSeedsQA.cc index 012caf26ff..6f2ba5e91a 100644 --- a/offline/QA/Tracking/SiliconSeedsQA.cc +++ b/offline/QA/Tracking/SiliconSeedsQA.cc @@ -233,7 +233,7 @@ void SiliconSeedsQA::createHistos() } { - h_ntrack1d = new TH1F(std::string(getHistoPrefix() + "nrecotracks1d").c_str(), "Number of reconstructed tracks;Number of silicon tracklets;Entries", 50, 0, 200); + h_ntrack1d = new TH1F(std::string(getHistoPrefix() + "nrecotracks1d").c_str(), "Number of reconstructed tracks;Number of silicon tracklets;Entries", 500, 0, 2000); hm->registerHisto(h_ntrack1d); } @@ -304,7 +304,7 @@ void SiliconSeedsQA::createHistos() // vertex { - h_nvertex = new TH1F(std::string(getHistoPrefix() + "nrecovertices").c_str(), "Num of reco vertices per event;Number of vertices;Entries", 20, 0, 20); + h_nvertex = new TH1F(std::string(getHistoPrefix() + "nrecovertices").c_str(), "Num of reco vertices per event;Number of vertices;Entries", 60, 0, 60); hm->registerHisto(h_nvertex); } From 74aacf800079855e7fbd702cc6ad7e043fe27eaf Mon Sep 17 00:00:00 2001 From: Nikhil Kumar Date: Fri, 27 Feb 2026 12:10:41 -0500 Subject: [PATCH 296/393] do away with bools Check if the threshold is greater than 0, and If it is 0 do not skim. Modify methods to only take thresholds. --- .../CaloStatusSkimmer/CaloStatusSkimmer.cc | 8 ++++---- .../CaloStatusSkimmer/CaloStatusSkimmer.h | 17 +++++------------ 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc index 0447bf5ba6..73dce5e912 100644 --- a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc +++ b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.cc @@ -23,7 +23,7 @@ CaloStatusSkimmer::CaloStatusSkimmer(const std::string &name) int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) { n_eventcounter++; - if (b_do_skim_EMCal) + if (m_EMC_skim_threshold > 0) { TowerInfoContainer *towers = findNode::getClass(topNode, "TOWERS_CEMC"); @@ -58,7 +58,7 @@ int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) } } - if (b_do_skim_HCal) + if (m_HCal_skim_threshold > 0) { TowerInfoContainer *hcalin_towers = findNode::getClass(topNode, "TOWERS_HCALIN"); TowerInfoContainer *hcalout_towers = findNode::getClass(topNode, "TOWERS_HCALOUT"); @@ -107,7 +107,7 @@ int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) } } - if (b_do_skim_sEPD) + if (m_sEPD_skim_threshold > 0) { TowerInfoContainer *sepd_towers = findNode::getClass(topNode, "TOWERS_SEPD"); @@ -143,7 +143,7 @@ int CaloStatusSkimmer::process_event(PHCompositeNode *topNode) } } - if (b_do_skim_ZDC) + if (m_ZDC_skim_threshold > 0) { TowerInfoContainer *zdc_towers = findNode::getClass(topNode, "TOWERS_ZDC"); diff --git a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h index 5c955f358e..433b8d08c0 100644 --- a/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h +++ b/offline/packages/Skimmers/CaloStatusSkimmer/CaloStatusSkimmer.h @@ -26,23 +26,19 @@ class CaloStatusSkimmer : public SubsysReco { /// Called at the end of all processing. int End(PHCompositeNode *topNode) override; - void do_skim_EMCal(bool do_skim, uint16_t threshold) { - b_do_skim_EMCal = do_skim; + void do_skim_EMCal( uint16_t threshold) { m_EMC_skim_threshold = threshold; } - void do_skim_HCal(bool do_skim, uint16_t threshold) { - b_do_skim_HCal = do_skim; + void do_skim_HCal( uint16_t threshold) { m_HCal_skim_threshold = threshold; } - void do_skim_sEPD(bool do_skim, uint16_t threshold) { - b_do_skim_sEPD = do_skim; + void do_skim_sEPD( uint16_t threshold) { m_sEPD_skim_threshold = threshold; } - void do_skim_ZDC(bool do_skim, uint16_t threshold) { - b_do_skim_ZDC = do_skim; + void do_skim_ZDC( uint16_t threshold) { m_ZDC_skim_threshold = threshold; } @@ -51,19 +47,16 @@ class CaloStatusSkimmer : public SubsysReco { uint32_t n_skimcounter{0}; uint32_t n_notowernodecounter{0}; - bool b_do_skim_EMCal{true}; + // If the threshold is set to 0, then the skimming for that subsystem is disabled. If threshold is > 0, then the event is skimmed if nchannels >= threshold not-instrumented (empty/missing packet) channels in that subsystem. uint16_t m_EMC_skim_threshold{192}; // skim if nchannels >= this many not-instrumented (empty/missing packet) channels in EMCal - bool b_do_skim_HCal{true}; uint16_t m_HCal_skim_threshold{192}; // skim if nchannels >= this many not-instrumented (empty/missing packet) channels in HCal - bool b_do_skim_sEPD{true}; uint16_t m_sEPD_skim_threshold{1}; // skim if nchannels >= this many not-instrumented (empty/missing packet) channels in sEPD - bool b_do_skim_ZDC{true}; uint16_t m_ZDC_skim_threshold{1}; // skim if nchannels >= this many not-instrumented (empty/missing packet) channels in ZDC }; From e7eb4c1d00ac3156c095199c472076cad28cd064 Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Fri, 27 Feb 2026 17:24:50 -0500 Subject: [PATCH 297/393] EventPlaneReco - Adjust Centrality Binning - Ensure that calibrations are performed on 1% centrality binning (previously 10%) - Use isHot flag is used over the isGood for the sEPD Bad Channels - sEPD Channels don't use the isBadChi2 check that's part of the isGood check (only the isHot which covers the basic dead/hot/cold cases) --- offline/packages/eventplaneinfo/EventPlaneRecov2.cc | 6 +++--- offline/packages/eventplaneinfo/EventPlaneRecov2.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/offline/packages/eventplaneinfo/EventPlaneRecov2.cc b/offline/packages/eventplaneinfo/EventPlaneRecov2.cc index 9635e0f3d6..64408c36f2 100644 --- a/offline/packages/eventplaneinfo/EventPlaneRecov2.cc +++ b/offline/packages/eventplaneinfo/EventPlaneRecov2.cc @@ -199,7 +199,7 @@ void EventPlaneRecov2::print_correction_data() int n = m_harmonics[h_idx]; std::cout << std::format("\n>>> HARMONIC n = {} <<<\n", n); - // Iterate through Centrality Bins (0-7) + // Iterate through Centrality Bins (0-79) for (size_t cent = 0; cent < m_bins_cent; ++cent) { std::cout << std::format("\n Centrality Bin: {}\n", cent); @@ -331,7 +331,7 @@ int EventPlaneRecov2::process_sEPD(PHCompositeNode* topNode) // skip bad channels // skip channels with very low charge - if (!tower->get_isGood() || charge < m_sepd_min_channel_charge) + if (tower->get_isHot() || charge < m_sepd_min_channel_charge) { continue; } @@ -389,7 +389,7 @@ int EventPlaneRecov2::process_sEPD(PHCompositeNode* topNode) void EventPlaneRecov2::correct_QVecs() { - size_t cent_bin = static_cast(m_cent / 10.0); + size_t cent_bin = static_cast(m_cent); if (cent_bin >= m_bins_cent) { cent_bin = m_bins_cent - 1; // Clamp max diff --git a/offline/packages/eventplaneinfo/EventPlaneRecov2.h b/offline/packages/eventplaneinfo/EventPlaneRecov2.h index 217faddf88..699d664a4c 100644 --- a/offline/packages/eventplaneinfo/EventPlaneRecov2.h +++ b/offline/packages/eventplaneinfo/EventPlaneRecov2.h @@ -115,7 +115,7 @@ class EventPlaneRecov2 : public SubsysReco std::array, 2> X_matrix{}; }; - static constexpr size_t m_bins_cent {8}; + static constexpr size_t m_bins_cent {80}; static constexpr std::array m_harmonics = {2, 3, 4}; // Holds all correction data From afb23ff00a611f9333353ddf0a0780a25fa994eb Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Fri, 27 Feb 2026 17:29:44 -0500 Subject: [PATCH 298/393] EventPlaneReco - Adjust var naming - Use consistent naming convention as that for QVecCalib module in the `sepd_eventplanecalib` package --- offline/packages/eventplaneinfo/EventPlaneRecov2.cc | 8 ++++---- offline/packages/eventplaneinfo/EventPlaneRecov2.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/offline/packages/eventplaneinfo/EventPlaneRecov2.cc b/offline/packages/eventplaneinfo/EventPlaneRecov2.cc index 64408c36f2..2b43109734 100644 --- a/offline/packages/eventplaneinfo/EventPlaneRecov2.cc +++ b/offline/packages/eventplaneinfo/EventPlaneRecov2.cc @@ -145,7 +145,7 @@ void EventPlaneRecov2::LoadCalib() std::string NS_yy_avg_name = std::format("Q_NS_yy_{}_avg", n); std::string NS_xy_avg_name = std::format("Q_NS_xy_{}_avg", n); - for (size_t cent_bin = 0; cent_bin < m_bins_cent; ++cent_bin) + for (size_t cent_bin = 0; cent_bin < m_cent_bins; ++cent_bin) { int key = cent_bin; @@ -200,7 +200,7 @@ void EventPlaneRecov2::print_correction_data() std::cout << std::format("\n>>> HARMONIC n = {} <<<\n", n); // Iterate through Centrality Bins (0-79) - for (size_t cent = 0; cent < m_bins_cent; ++cent) + for (size_t cent = 0; cent < m_cent_bins; ++cent) { std::cout << std::format("\n Centrality Bin: {}\n", cent); std::cout << std::format(" {:->30}\n", ""); @@ -390,9 +390,9 @@ int EventPlaneRecov2::process_sEPD(PHCompositeNode* topNode) void EventPlaneRecov2::correct_QVecs() { size_t cent_bin = static_cast(m_cent); - if (cent_bin >= m_bins_cent) + if (cent_bin >= m_cent_bins) { - cent_bin = m_bins_cent - 1; // Clamp max + cent_bin = m_cent_bins - 1; // Clamp max } size_t south_idx = static_cast(Subdetector::S); diff --git a/offline/packages/eventplaneinfo/EventPlaneRecov2.h b/offline/packages/eventplaneinfo/EventPlaneRecov2.h index 699d664a4c..905e83b7bc 100644 --- a/offline/packages/eventplaneinfo/EventPlaneRecov2.h +++ b/offline/packages/eventplaneinfo/EventPlaneRecov2.h @@ -115,14 +115,14 @@ class EventPlaneRecov2 : public SubsysReco std::array, 2> X_matrix{}; }; - static constexpr size_t m_bins_cent {80}; + static constexpr size_t m_cent_bins {80}; static constexpr std::array m_harmonics = {2, 3, 4}; // Holds all correction data // key: [Harmonic][Cent][Subdetector] // Harmonics {2,3,4} -> 3 elements // Subdetectors {S,N,NS} -> 3 elements - std::array, m_bins_cent>, m_harmonics.size()> m_correction_data; + std::array, m_cent_bins>, m_harmonics.size()> m_correction_data; // sEPD Q Vectors // key: [Harmonic][Subdetector] From d906123775233c0361ceb08b9726d48436bb1f7e Mon Sep 17 00:00:00 2001 From: Joseph Clement Date: Fri, 27 Feb 2026 18:26:58 -0500 Subject: [PATCH 299/393] More nullptr guards and explicit treatment of NaN cases for Timingcut module --- offline/packages/jetbackground/TimingCut.cc | 23 +++++++++++++++++++-- offline/packages/jetbackground/TimingCut.h | 8 +++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/offline/packages/jetbackground/TimingCut.cc b/offline/packages/jetbackground/TimingCut.cc index 24dfb03c11..29f6e7d469 100644 --- a/offline/packages/jetbackground/TimingCut.cc +++ b/offline/packages/jetbackground/TimingCut.cc @@ -136,8 +136,15 @@ int TimingCut::process_event(PHCompositeNode *topNode) jetOHFrac += tower->get_energy(); } } - jetOHFrac /= jet->get_e(); //We actually want this to be NaN when jet->get_e() == 0, because that case should fail. - //NaN always compares to false + float jetE = jet->get_e(); + if(jetE == 0) + { + jetOHFrac = std::numeric_limits::quiet_NaN(); + } + else + { + jetOHFrac /= jetE; + } } else { @@ -175,8 +182,20 @@ int TimingCut::process_event(PHCompositeNode *topNode) return Fun4AllReturnCodes::ABORTEVENT; } + if(!std::isfinite(maxJetOHFrac) || !std::isfinite(subJetOHFrac)) + { + if(Verbosity() > 1) + { + std::cout << "Warning: bad OH fraction for leading or subleading jet; this event will automatically fail cuts." << std::endl; + } + maxJetOHFrac = std::numeric_limits::quiet_NaN(); + subJetOHFrac = std::numeric_limits::quiet_NaN(); + } + float corrMaxJett = Correct_Time_Ohfrac(maxJett, maxJetOHFrac); //likewise, intentional NaNs here. float corrSubJett = Correct_Time_Ohfrac(subJett, subJetOHFrac); + + bool passDeltat = Pass_Delta_t(corrMaxJett, corrSubJett, maxJetPhi, subJetPhi); bool passLeadt = Pass_Lead_t(corrMaxJett); diff --git a/offline/packages/jetbackground/TimingCut.h b/offline/packages/jetbackground/TimingCut.h index 000dc196a7..743f8fac6b 100644 --- a/offline/packages/jetbackground/TimingCut.h +++ b/offline/packages/jetbackground/TimingCut.h @@ -77,6 +77,14 @@ class TimingCut : public SubsysReco float Correct_Time_Ohfrac(float t, float ohfrac) { + if(!_fitFunc) + { + if(Verbosity() > 0) + { + std::cout << "ERROR: mising fit function. All events will fail!" << std::endl; + } + return std::numeric_limits::quiet_NaN(); + } float corrt = t - _fitFunc->Eval(ohfrac); return corrt; } From f00f62ae243e3e6557479222560893767caf5d9f Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Fri, 27 Feb 2026 18:55:48 -0500 Subject: [PATCH 300/393] Cleanup - Replace EventPlaneReco with EventPlaneRecov2 - Remove EventPlaneCalibration (old approach) --- .../eventplaneinfo/EventPlaneCalibration.cc | 840 ------------ .../eventplaneinfo/EventPlaneCalibration.h | 121 -- .../packages/eventplaneinfo/EventPlaneReco.cc | 1198 +++++++---------- .../packages/eventplaneinfo/EventPlaneReco.h | 217 +-- .../eventplaneinfo/EventPlaneRecov2.cc | 637 --------- .../eventplaneinfo/EventPlaneRecov2.h | 134 -- offline/packages/eventplaneinfo/Makefile.am | 8 +- 7 files changed, 640 insertions(+), 2515 deletions(-) delete mode 100644 offline/packages/eventplaneinfo/EventPlaneCalibration.cc delete mode 100644 offline/packages/eventplaneinfo/EventPlaneCalibration.h delete mode 100644 offline/packages/eventplaneinfo/EventPlaneRecov2.cc delete mode 100644 offline/packages/eventplaneinfo/EventPlaneRecov2.h diff --git a/offline/packages/eventplaneinfo/EventPlaneCalibration.cc b/offline/packages/eventplaneinfo/EventPlaneCalibration.cc deleted file mode 100644 index 5e5fb01264..0000000000 --- a/offline/packages/eventplaneinfo/EventPlaneCalibration.cc +++ /dev/null @@ -1,840 +0,0 @@ -#include "EventPlaneCalibration.h" - -#include "Eventplaneinfo.h" -#include "EventplaneinfoMap.h" -#include "EventplaneinfoMapv1.h" -#include "Eventplaneinfov1.h" - -#include -#include -#include - -//#include - -//#include - -#include - -#include -#include -#include - -#include -#include - -#include -#include - -#include - -#include -#include // for SubsysReco - -#include -#include -#include // for PHNode -#include -#include // for PHObject -#include -#include // for PHWHERE -#include - -#include -#include - -#include -#include -#include -#include // for exit -#include -#include -#include // for _Rb_tree_const_iterator -#include // for pair -#include // for vector - -EventPlaneCalibration::EventPlaneCalibration(const std::string &name) : SubsysReco(name) { - south_q.resize(m_MaxOrder); - north_q.resize(m_MaxOrder); - northsouth_q.resize(m_MaxOrder); - south_q_subtract.resize(m_MaxOrder); - north_q_subtract.resize(m_MaxOrder); - northsouth_q_subtract.resize(m_MaxOrder); - shift_north.resize(m_MaxOrder); - shift_south.resize(m_MaxOrder); - shift_northsouth.resize(m_MaxOrder); - tmp_south_psi.resize(m_MaxOrder); - tmp_north_psi.resize(m_MaxOrder); - tmp_northsouth_psi.resize(m_MaxOrder); - - for (auto &vec : south_q) { - vec.resize(2); - } - - for (auto &vec : north_q) { - vec.resize(2); - } - - for (auto &vec : northsouth_q) { - vec.resize(2); - } - - for (auto &vec : south_q_subtract) { - vec.resize(2); - } - - for (auto &vec : north_q_subtract) { - vec.resize(2); - } - - for (auto &vec : northsouth_q_subtract) { - vec.resize(2); - } -} - -int EventPlaneCalibration::InitRun(PHCompositeNode *topNode) { - - if (_isSim) { - m_runNo = 0; - } - if (!_default_calib) { - recoConsts *rc = recoConsts::instance(); - m_runNo = rc->get_IntFlag("RUNNUMBER"); - } - - if (Verbosity() > 0) { - std::cout << "======================= EventPlaneCalibration:InitRun() " - "=======================" - << std::endl; - std::cout << PHWHERE << "RUNNUMBER " << m_runNo << std::endl; - } - - if (OutFileName.empty()) - { - OutFileName = std::format("eventplane_correction_histograms_run_{}.root",m_runNo); - } - cdbhistosOut = new CDBHistos(OutFileName); - - //-----------------------------------load calibration - //histograms-----------------------------------------// - // Create and register recentering histograms - for (unsigned int order = 0; order < m_MaxOrder; order++) { - - tprof_mean_cos_south_epd[order] = new TProfile2D( - std::format("tprof_mean_cos_south_epd_order_{}", order).c_str(), - "", 125 * 40, 0, 25000, 20, -100, 100, -1e10, 1e10); - tprof_mean_sin_south_epd[order] = new TProfile2D( - std::format("tprof_mean_sin_south_epd_order_{}", order).c_str(), - "", 125 * 40, 0, 25000, 20, -100, 100, -1e10, 1e10); - tprof_mean_cos_north_epd[order] = new TProfile2D( - std::format("tprof_mean_cos_north_epd_order_{}", order).c_str(), - "", 125 * 40, 0, 25000, 20, -100, 100, -1e10, 1e10); - tprof_mean_sin_north_epd[order] = new TProfile2D( - std::format("tprof_mean_sin_north_epd_order_{}", order).c_str(), - "", 125 * 40, 0, 25000, 20, -100, 100, -1e10, 1e10); - - tprof_mean_cos_northsouth_epd[order] = new TProfile2D( - std::format("tprof_mean_cos_northsouth_epd_order_{}", order).c_str(), - "", 125 * 40, 0, 25000, 20, -100, 100, -1e10, 1e10); - tprof_mean_sin_northsouth_epd[order] = new TProfile2D( - std::format("tprof_mean_sin_northsouth_epd_order_{}", order).c_str(), - "", 125 * 40, 0, 25000, 20, -100, 100, -1e10, 1e10); - - cdbhistosOut->registerHisto(tprof_mean_cos_south_epd[order]); - cdbhistosOut->registerHisto(tprof_mean_sin_south_epd[order]); - cdbhistosOut->registerHisto(tprof_mean_cos_north_epd[order]); - cdbhistosOut->registerHisto(tprof_mean_sin_north_epd[order]); - cdbhistosOut->registerHisto(tprof_mean_cos_northsouth_epd[order]); - cdbhistosOut->registerHisto(tprof_mean_sin_northsouth_epd[order]); - } - - CDBHistos *cdbhistosIn = new CDBHistos(OutFileName); - cdbhistosIn->LoadCalibrations(); - - // Create and register shifting histograms - for (unsigned int order = 0; order < m_MaxOrder; order++) { - for (int p = 0; p < _imax; p++) { - tprof_cos_north_epd_shift[order][p] = new TProfile2D( - std::format("tprof_cos_north_epd_shift_order_{}_{}", order, p).c_str(), - "", 125 * 40, 0, 25000, 20, -100, 100, -1e10, 1e10); - tprof_sin_north_epd_shift[order][p] = new TProfile2D( - std::format("tprof_sin_north_epd_shift_order_{}_{}", order, p).c_str(), - "", 125 * 40, 0, 25000, 20, -100, 100, -1e10, 1e10); - tprof_cos_south_epd_shift[order][p] = new TProfile2D( - std::format("tprof_cos_south_epd_shift_order_{}_{}", order, p).c_str(), - "", 125 * 40, 0, 25000, 20, -100, 100, -1e10, 1e10); - tprof_sin_south_epd_shift[order][p] = new TProfile2D( - std::format("tprof_sin_south_epd_shift_order_{}_{}", order, p).c_str(), - "", 125 * 40, 0, 25000, 20, -100, 100, -1e10, 1e10); - - tprof_cos_northsouth_epd_shift[order][p] = new TProfile2D( - std::format("tprof_cos_northsouth_epd_shift_order_{}_{}", order, p).c_str(), - "", 125 * 40, 0, 25000, 20, -100, 100, -1e10, 1e10); - tprof_sin_northsouth_epd_shift[order][p] = new TProfile2D( - std::format("tprof_sin_northsouth_epd_shift_order_{}_{}", order, p).c_str(), - "", 125 * 40, 0, 25000, 20, -100, 100, -1e10, 1e10); - - cdbhistosOut->registerHisto(tprof_cos_north_epd_shift[order][p]); - cdbhistosOut->registerHisto(tprof_sin_north_epd_shift[order][p]); - cdbhistosOut->registerHisto(tprof_cos_south_epd_shift[order][p]); - cdbhistosOut->registerHisto(tprof_sin_south_epd_shift[order][p]); - cdbhistosOut->registerHisto(tprof_cos_northsouth_epd_shift[order][p]); - cdbhistosOut->registerHisto(tprof_sin_northsouth_epd_shift[order][p]); - } - } - - // Get recentering histograms - for (unsigned int order = 0; order < m_MaxOrder; order++) { - tprof_mean_cos_south_epd_input[order] = - dynamic_cast(cdbhistosIn->getHisto( - std::format("tprof_mean_cos_south_epd_order_{}", order), false)); - tprof_mean_sin_south_epd_input[order] = - dynamic_cast(cdbhistosIn->getHisto( - std::format("tprof_mean_sin_south_epd_order_{}", order), false)); - tprof_mean_cos_north_epd_input[order] = - dynamic_cast(cdbhistosIn->getHisto( - std::format("tprof_mean_cos_north_epd_order_{}", order), false)); - tprof_mean_sin_north_epd_input[order] = - dynamic_cast(cdbhistosIn->getHisto( - std::format("tprof_mean_sin_north_epd_order_{}", order), false)); - tprof_mean_cos_northsouth_epd_input[order] = - dynamic_cast(cdbhistosIn->getHisto( - std::format("tprof_mean_cos_northsouth_epd_order_{}", order), - false)); - tprof_mean_sin_northsouth_epd_input[order] = - dynamic_cast(cdbhistosIn->getHisto( - std::format("tprof_mean_sin_northsouth_epd_order_{}", order), - false)); - } - - // Get shifting histograms - for (unsigned int order = 0; order < m_MaxOrder; order++) { - for (int p = 0; p < _imax; p++) { - tprof_cos_north_epd_shift_input[order][p] = - dynamic_cast(cdbhistosIn->getHisto( - std::format("tprof_cos_north_epd_shift_order_{}_{}", order, p), - false)); - tprof_sin_north_epd_shift_input[order][p] = - dynamic_cast(cdbhistosIn->getHisto( - std::format("tprof_sin_north_epd_shift_order_{}_{}", order, p), - false)); - tprof_cos_south_epd_shift_input[order][p] = - dynamic_cast(cdbhistosIn->getHisto( - std::format("tprof_cos_south_epd_shift_order_{}_{}", order, p), - false)); - tprof_sin_south_epd_shift_input[order][p] = - dynamic_cast(cdbhistosIn->getHisto( - std::format("tprof_sin_south_epd_shift_order_{}_{}", order, p), - false)); - tprof_cos_northsouth_epd_shift_input[order][p] = - dynamic_cast(cdbhistosIn->getHisto( - std::format("tprof_cos_northsouth_epd_shift_order_{}_{}", order, - p), - false)); - tprof_sin_northsouth_epd_shift_input[order][p] = - dynamic_cast(cdbhistosIn->getHisto( - std::format("tprof_sin_northsouth_epd_shift_order_{}_{}", order, - p), - false)); - } - } - - cdbhistosIn->Print(); - - return CreateNodes(topNode); -} - -int EventPlaneCalibration::process_event(PHCompositeNode *topNode) { - if (Verbosity() > 1) { - std::cout << "EventPlaneCalibration::process_event -- entered" << std::endl; - } - - //--------------------------------- - // Get Objects off of the Node Tree - //--------------------------------- - - MbdVertexMap *mbdvtxmap = - findNode::getClass(topNode, "MbdVertexMap"); - if (!mbdvtxmap) { - std::cout << PHWHERE << "::ERROR - cannot find MbdVertexMap" << std::endl; - exit(-1); - } - - MbdVertex *mvertex = nullptr; - if (mbdvtxmap) { - for (MbdVertexMap::ConstIter mbditer = mbdvtxmap->begin(); - mbditer != mbdvtxmap->end(); ++mbditer) { - mvertex = mbditer->second; - } - if (mvertex) { - _mbdvtx = mvertex->get_z(); - } - } - - EventplaneinfoMap *epmap = - findNode::getClass(topNode, "EventplaneinfoMap"); - if (!epmap) { - std::cout << PHWHERE << "::ERROR - cannot find EventplaneinfoMap" - << std::endl; - exit(-1); - } - - Gl1Packet *gl1PacketInfo = findNode::getClass(topNode, 14001); - if (!gl1PacketInfo) { - std::cout << PHWHERE << "GlobalQA::process_event: GL1Packet node is missing" - << std::endl; - } - - uint64_t triggervec = 0; - if (gl1PacketInfo) { - triggervec = gl1PacketInfo->getScaledVector(); - } - - if (_sepdEpReco) { - - TowerInfoContainer *epd_towerinfo = - findNode::getClass(topNode, "TOWERINFO_CALIB_SEPD"); - if (!epd_towerinfo) { - epd_towerinfo = findNode::getClass( - topNode, "TOWERINFO_CALIB_EPD"); - if (!epd_towerinfo) { - std::cout << PHWHERE - << "::ERROR - cannot find sEPD Calibrated TowerInfoContainer" - << std::endl; - exit(-1); - } - } - - EpdGeom *_epdgeom = findNode::getClass(topNode, "TOWERGEOM_EPD"); - if (!_epdgeom) { - std::cout << PHWHERE << "::ERROR - cannot find TOWERGEOM_EPD" - << std::endl; - exit(-1); - } - - ResetMe(); - - if ((triggervec >> 0xAU) & 0x1U) { - - if ((std::fabs(_mbdvtx) < _mbd_vertex_cut)) { - - unsigned int ntowers = epd_towerinfo->size(); - for (unsigned int ch = 0; ch < ntowers; ch++) { - TowerInfo *_tower = epd_towerinfo->get_tower_at_channel(ch); - float epd_e = _tower->get_energy(); - bool isZS = _tower->get_isZS(); - if (!isZS) // exclude ZS - { - unsigned int key = TowerInfoDefs::encode_epd(ch); - int arm = TowerInfoDefs::get_epd_arm(key); - if (arm == 0) { - _ssum += epd_e; - } else if (arm == 1) { - _nsum += epd_e; - } - } - } - - if (_ssum > _epd_charge_min && _nsum > _epd_charge_min && - _ssum < _epd_charge_max && _nsum < _epd_charge_max) { - _do_ep = true; - } - - if (_do_ep) { - for (unsigned int ch = 0; ch < ntowers; ch++) { - TowerInfo *_tower = epd_towerinfo->get_tower_at_channel(ch); - float epd_e = _tower->get_energy(); - bool isZS = _tower->get_isZS(); - if (!isZS) // exclude ZS - { - if (epd_e < 0.2) // expecting Nmips - { - continue; - } - unsigned int key = TowerInfoDefs::encode_epd(ch); - float tile_phi = _epdgeom->get_phi(key); - int arm = TowerInfoDefs::get_epd_arm(key); - float truncated_e = - (epd_e < _epd_e) ? epd_e : _epd_e; // set cutoff at _epd_e - if (arm == 0) { - for (unsigned int order = 0; order < m_MaxOrder; order++) { - double Cosine = cos(tile_phi * (double)(order + 1)); - double Sine = sin(tile_phi * (double)(order + 1)); - south_q[order][0] += truncated_e * Cosine; // south Qn,x - south_q[order][1] += truncated_e * Sine; // south Qn,y - } - } else if (arm == 1) { - for (unsigned int order = 0; order < m_MaxOrder; order++) { - double Cosine = cos(tile_phi * (double)(order + 1)); - double Sine = sin(tile_phi * (double)(order + 1)); - north_q[order][0] += truncated_e * Cosine; // north Qn,x - north_q[order][1] += truncated_e * Sine; // north Qn,y - } - } - for (unsigned int order = 0; order < m_MaxOrder; order++) { - double Cosine = cos(tile_phi * (double)(order + 1)); - double Sine = sin(tile_phi * (double)(order + 1)); - northsouth_q[order][0] += - truncated_e * Cosine; // northsouth Qn,x - northsouth_q[order][1] += truncated_e * Sine; // northsouth Qn,y - } - } - } - - _totalcharge = _nsum + _ssum; - - // Filled during first run - for (unsigned int order = 0; order < m_MaxOrder; order++) { - // Fill recentering histograms by order - tprof_mean_cos_south_epd[order]->Fill(_ssum, _mbdvtx, - south_q[order][0] / _ssum); - tprof_mean_sin_south_epd[order]->Fill(_ssum, _mbdvtx, - south_q[order][1] / _ssum); - tprof_mean_cos_north_epd[order]->Fill(_nsum, _mbdvtx, - north_q[order][0] / _nsum); - tprof_mean_sin_north_epd[order]->Fill(_nsum, _mbdvtx, - north_q[order][1] / _nsum); - tprof_mean_cos_northsouth_epd[order]->Fill( - _totalcharge, _mbdvtx, northsouth_q[order][0] / _totalcharge); - tprof_mean_sin_northsouth_epd[order]->Fill( - _totalcharge, _mbdvtx, northsouth_q[order][1] / _totalcharge); - } - - // Get recentering histograms and do recentering - // Recentering: subtract Qn,x and Qn,y values averaged over all events - for (unsigned int order = 0; order < m_MaxOrder; order++) { - if (tprof_mean_cos_south_epd_input[order]) // check if recentering - // histograms exist - { - - // south - TAxis *south_xaxis = - tprof_mean_cos_south_epd_input[order]->GetXaxis(); - TAxis *south_yaxis = - tprof_mean_cos_south_epd_input[order]->GetYaxis(); - int xbin_south = south_xaxis->FindBin(_ssum); - int ybin_south = south_yaxis->FindBin(_mbdvtx); - - double event_ave_cos_south = - tprof_mean_cos_south_epd_input[order]->GetBinContent( - xbin_south, ybin_south); - double event_ave_sin_south = - tprof_mean_sin_south_epd_input[order]->GetBinContent( - xbin_south, ybin_south); - south_q_subtract[order][0] = _ssum * event_ave_cos_south; - south_q_subtract[order][1] = _ssum * event_ave_sin_south; - south_q[order][0] -= south_q_subtract[order][0]; - south_q[order][1] -= south_q_subtract[order][1]; - - // north - TAxis *north_xaxis = - tprof_mean_cos_north_epd_input[order]->GetXaxis(); - TAxis *north_yaxis = - tprof_mean_cos_north_epd_input[order]->GetYaxis(); - int xbin_north = north_xaxis->FindBin(_nsum); - int ybin_north = north_yaxis->FindBin(_mbdvtx); - - double event_ave_cos_north = - tprof_mean_cos_north_epd_input[order]->GetBinContent( - xbin_north, ybin_north); - double event_ave_sin_north = - tprof_mean_sin_north_epd_input[order]->GetBinContent( - xbin_north, ybin_north); - north_q_subtract[order][0] = _nsum * event_ave_cos_north; - north_q_subtract[order][1] = _nsum * event_ave_sin_north; - north_q[order][0] -= north_q_subtract[order][0]; - north_q[order][1] -= north_q_subtract[order][1]; - - // northsouth - TAxis *northsouth_xaxis = - tprof_mean_cos_northsouth_epd_input[order]->GetXaxis(); - TAxis *northsouth_yaxis = - tprof_mean_cos_northsouth_epd_input[order]->GetYaxis(); - int xbin_northsouth = northsouth_xaxis->FindBin(_totalcharge); - int ybin_northsouth = northsouth_yaxis->FindBin(_mbdvtx); - - double event_ave_cos_northsouth = - tprof_mean_cos_northsouth_epd_input[order]->GetBinContent( - xbin_northsouth, ybin_northsouth); - double event_ave_sin_northsouth = - tprof_mean_sin_northsouth_epd_input[order]->GetBinContent( - xbin_northsouth, ybin_northsouth); - northsouth_q_subtract[order][0] = - _totalcharge * event_ave_cos_northsouth; - northsouth_q_subtract[order][1] = - _totalcharge * event_ave_sin_northsouth; - northsouth_q[order][0] -= northsouth_q_subtract[order][0]; - northsouth_q[order][1] -= northsouth_q_subtract[order][1]; - } - } - - // Get recentered psi_n - Eventplaneinfo *epinfo = new Eventplaneinfov1(); - for (unsigned int order = 0; order < m_MaxOrder; order++) { - double n = order + 1.0; - if (tprof_mean_cos_south_epd_input[order]) // if present, Qs are - // recentered - { - tmp_south_psi[order] = - epinfo->GetPsi(south_q[order][0], south_q[order][1], n); - tmp_north_psi[order] = - epinfo->GetPsi(north_q[order][0], north_q[order][1], n); - tmp_northsouth_psi[order] = epinfo->GetPsi( - northsouth_q[order][0], northsouth_q[order][1], n); - } else { - tmp_south_psi[order] = NAN; - tmp_north_psi[order] = NAN; - tmp_northsouth_psi[order] = NAN; - } - } - - // Filled during second run - for (unsigned int order = 0; order < m_MaxOrder; order++) { - if (tprof_mean_cos_south_epd_input[order]) // if present, Qs are - // recentered - { - // Fill shifting histograms by order and terms - for (int p = 0; p < _imax; p++) { - double terms = p + 1.0; - double n = order + 1.0; - double tmp = (n * terms); - - tprof_cos_south_epd_shift[order][p]->Fill( - _ssum, _mbdvtx, - cos(tmp * tmp_south_psi[order])); // south - tprof_sin_south_epd_shift[order][p]->Fill( - _ssum, _mbdvtx, - sin(tmp * tmp_south_psi[order])); // south - tprof_cos_north_epd_shift[order][p]->Fill( - _nsum, _mbdvtx, - cos(tmp * tmp_north_psi[order])); // north - tprof_sin_north_epd_shift[order][p]->Fill( - _nsum, _mbdvtx, - sin(tmp * tmp_north_psi[order])); // north - tprof_cos_northsouth_epd_shift[order][p]->Fill( - _totalcharge, _mbdvtx, - cos(tmp * tmp_northsouth_psi[order])); // northsouth - // - tprof_sin_northsouth_epd_shift[order][p]->Fill( - _totalcharge, _mbdvtx, - sin(tmp * tmp_northsouth_psi[order])); // northsouth - // - } - } - } - - // Get shifting histograms and calculate shift - for (unsigned int order = 0; order < m_MaxOrder; order++) { - for (int p = 0; p < _imax; p++) { - if (tprof_cos_south_epd_shift_input[order] - [p]) // check if shifting - // histograms exist - { - double terms = p + 1.0; - double n = order + 1.0; - double tmp = (n * terms); - double prefactor = 2.0 / terms; - - // south - TAxis *south_xaxis = - tprof_cos_south_epd_shift_input[order][p]->GetXaxis(); - TAxis *south_yaxis = - tprof_cos_south_epd_shift_input[order][p]->GetYaxis(); - int xbin_south = south_xaxis->FindBin(_ssum); - int ybin_south = south_yaxis->FindBin(_mbdvtx); - - // north - TAxis *north_xaxis = - tprof_cos_north_epd_shift_input[order][p]->GetXaxis(); - TAxis *north_yaxis = - tprof_cos_north_epd_shift_input[order][p]->GetYaxis(); - int xbin_north = north_xaxis->FindBin(_nsum); - int ybin_north = north_yaxis->FindBin(_mbdvtx); - - // // northsouth - TAxis *northsouth_xaxis = - tprof_cos_northsouth_epd_shift_input[order][p]->GetXaxis(); - TAxis *northsouth_yaxis = - tprof_cos_northsouth_epd_shift_input[order][p]->GetYaxis(); - int xbin_northsouth = northsouth_xaxis->FindBin(_totalcharge); - int ybin_northsouth = northsouth_yaxis->FindBin(_mbdvtx); - - // Equation (6) of arxiv:nucl-ex/9805001 - // i = terms; n = order; i*n = tmp - // (2 / i ) * * - // sin(i*n*psi_n) - * - // cos(i*n*psi_n) - - // north - shift_north[order] += - prefactor * - (tprof_cos_north_epd_shift_input[order][p]->GetBinContent( - xbin_north, ybin_north) * - sin(tmp * tmp_north_psi[order]) - - tprof_sin_north_epd_shift_input[order][p]->GetBinContent( - xbin_north, ybin_north) * - cos(tmp * tmp_north_psi[order])); - - // south - shift_south[order] += - prefactor * - (tprof_cos_south_epd_shift_input[order][p]->GetBinContent( - xbin_south, ybin_south) * - sin(tmp * tmp_south_psi[order]) - - tprof_sin_south_epd_shift_input[order][p]->GetBinContent( - xbin_south, ybin_south) * - cos(tmp * tmp_south_psi[order])); - - // // northsouth - shift_northsouth[order] += - prefactor * - (tprof_cos_northsouth_epd_shift_input[order][p] - ->GetBinContent(xbin_northsouth, ybin_northsouth) * - sin(tmp * tmp_northsouth_psi[order]) - - tprof_sin_northsouth_epd_shift_input[order][p] - ->GetBinContent(xbin_northsouth, ybin_northsouth) * - cos(tmp * tmp_northsouth_psi[order])); - } - } - } - - // n * deltapsi_n = (2 / i ) * * sin(i*n*psi_n) - - // * cos(i*n*psi_n) Divide out n - for (unsigned int order = 0; order < m_MaxOrder; order++) { - double n = order + 1.0; - shift_north[order] /= n; - shift_south[order] /= n; - shift_northsouth[order] /= n; - } - - // Now add shift to psi_n to flatten it - for (unsigned int order = 0; order < m_MaxOrder; order++) { - if (tprof_cos_north_epd_shift_input[0][0]) { - tmp_south_psi[order] += shift_south[order]; - tmp_north_psi[order] += shift_north[order]; - tmp_northsouth_psi[order] += shift_northsouth[order]; - } - } - - // Now enforce the range - for (unsigned int order = 0; order < m_MaxOrder; order++) { - if (tprof_cos_north_epd_shift_input[0][0]) { - double range = M_PI / (double)(order + 1); - if (tmp_south_psi[order] < -1.0 * range) { - tmp_south_psi[order] += 2.0 * range; - } - if (tmp_south_psi[order] > range) { - tmp_south_psi[order] -= 2.0 * range; - } - if (tmp_north_psi[order] < -1.0 * range) { - tmp_north_psi[order] += 2.0 * range; - } - if (tmp_north_psi[order] > range) { - tmp_north_psi[order] -= 2.0 * range; - } - if (tmp_northsouth_psi[order] < -1.0 * range) { - tmp_northsouth_psi[order] += 2.0 * range; - } - if (tmp_northsouth_psi[order] > range) { - tmp_northsouth_psi[order] -= 2.0 * range; - } - } - } - - for (unsigned int order = 0; order < m_MaxOrder; order++) { - south_Qvec.emplace_back(south_q[order][0], south_q[order][1]); - north_Qvec.emplace_back(north_q[order][0], north_q[order][1]); - northsouth_Qvec.emplace_back(northsouth_q[order][0], - northsouth_q[order][1]); - } - - if (epd_towerinfo) { - Eventplaneinfo *sepds = new Eventplaneinfov1(); - sepds->set_qvector(south_Qvec); - sepds->set_shifted_psi(tmp_south_psi); - epmap->insert(sepds, EventplaneinfoMap::sEPDS); - - Eventplaneinfo *sepdn = new Eventplaneinfov1(); - sepdn->set_qvector(north_Qvec); - sepdn->set_shifted_psi(tmp_north_psi); - epmap->insert(sepdn, EventplaneinfoMap::sEPDN); - - Eventplaneinfo *sepdns = new Eventplaneinfov1(); - sepdns->set_qvector(northsouth_Qvec); - sepdns->set_shifted_psi(tmp_northsouth_psi); - epmap->insert(sepdns, EventplaneinfoMap::sEPDNS); - - if (Verbosity() > 1) { - sepds->identify(); - sepdn->identify(); - sepdns->identify(); - } - } - } - } - } - } - - if (_mbdEpReco) { - ResetMe(); - - MbdPmtContainer *mbdpmts = - findNode::getClass(topNode, "MbdPmtContainer"); - if (!mbdpmts) { - std::cout << PHWHERE << "::ERROR - cannot find MbdPmtContainer" - << std::endl; - exit(-1); - } - - MbdGeom *mbdgeom = findNode::getClass(topNode, "MbdGeom"); - if (!mbdgeom) { - std::cout << PHWHERE << "::ERROR - cannot find MbdGeom" << std::endl; - exit(-1); - } - - if (mbdpmts) { - if (Verbosity()) { - std::cout << "EventPlaneCalibration::process_event - mbdpmts" << std::endl; - } - - for (int ipmt = 0; ipmt < mbdpmts->get_npmt(); ipmt++) { - float mbd_q = mbdpmts->get_pmt(ipmt)->get_q(); - _mbdQ += mbd_q; - } - - for (int ipmt = 0; ipmt < mbdpmts->get_npmt(); ipmt++) { - float mbd_q = mbdpmts->get_pmt(ipmt)->get_q(); - float phi = mbdgeom->get_phi(ipmt); - int arm = mbdgeom->get_arm(ipmt); - - if (_mbdQ < _mbd_e) { - continue; - } - - if (arm == 0) { - for (unsigned int order = 0; order < m_MaxOrder; order++) { - double Cosine = cos(phi * (double)(order + 1)); - double Sine = sin(phi * (double)(order + 1)); - south_q[order][0] += mbd_q * Cosine; // south Qn,x - south_q[order][1] += mbd_q * Sine; // south Qn,y - } - } else if (arm == 1) { - for (unsigned int order = 0; order < m_MaxOrder; order++) { - double Cosine = cos(phi * (double)(order + 1)); - double Sine = sin(phi * (double)(order + 1)); - north_q[order][0] += mbd_q * Cosine; // north Qn,x - north_q[order][1] += mbd_q * Sine; // north Qn,y - } - } - } - } - - for (unsigned int order = 0; order < m_MaxOrder; order++) { - south_Qvec.emplace_back(south_q[order][0], south_q[order][1]); - north_Qvec.emplace_back(north_q[order][0], north_q[order][1]); - } - - if (mbdpmts) { - Eventplaneinfo *mbds = new Eventplaneinfov1(); - mbds->set_qvector(south_Qvec); - epmap->insert(mbds, EventplaneinfoMap::MBDS); - - Eventplaneinfo *mbdn = new Eventplaneinfov1(); - mbdn->set_qvector(north_Qvec); - epmap->insert(mbdn, EventplaneinfoMap::MBDN); - - if (Verbosity() > 1) { - mbds->identify(); - mbdn->identify(); - } - } - - ResetMe(); - } - - if (Verbosity()) { - epmap->identify(); - } - - return Fun4AllReturnCodes::EVENT_OK; -} - -int EventPlaneCalibration::CreateNodes(PHCompositeNode *topNode) { - PHNodeIterator iter(topNode); - - PHCompositeNode *dstNode = - dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); - if (!dstNode) { - std::cout << PHWHERE << "DST Node missing, doing nothing." << std::endl; - return Fun4AllReturnCodes::ABORTRUN; - } - - PHCompositeNode *globalNode = dynamic_cast( - iter.findFirst("PHCompositeNode", "GLOBAL")); - if (!globalNode) { - globalNode = new PHCompositeNode("GLOBAL"); - dstNode->addNode(globalNode); - } - - EventplaneinfoMap *eps = - findNode::getClass(topNode, "EventplaneinfoMap"); - if (!eps) { - eps = new EventplaneinfoMapv1(); - PHIODataNode *EpMapNode = - new PHIODataNode(eps, "EventplaneinfoMap", "PHObject"); - globalNode->addNode(EpMapNode); - } - return Fun4AllReturnCodes::EVENT_OK; -} - -void EventPlaneCalibration::ResetMe() { - for (auto &vec : south_q) { - std::fill(vec.begin(), vec.end(), 0.); - } - - for (auto &vec : north_q) { - std::fill(vec.begin(), vec.end(), 0.); - } - - for (auto &vec : northsouth_q) { - std::fill(vec.begin(), vec.end(), 0.); - } - - south_Qvec.clear(); - north_Qvec.clear(); - northsouth_Qvec.clear(); - - for (auto &vec : south_q_subtract) { - std::fill(vec.begin(), vec.end(), 0.); - } - - for (auto &vec : north_q_subtract) { - std::fill(vec.begin(), vec.end(), 0.); - } - - for (auto &vec : northsouth_q_subtract) { - std::fill(vec.begin(), vec.end(), 0.); - } - - std::fill(shift_north.begin(), shift_north.end(), 0.); - std::fill(shift_south.begin(), shift_south.end(), 0.); - std::fill(shift_northsouth.begin(), shift_northsouth.end(), 0.); - - std::fill(tmp_south_psi.begin(), tmp_south_psi.end(), NAN); - std::fill(tmp_north_psi.begin(), tmp_north_psi.end(), NAN); - std::fill(tmp_northsouth_psi.begin(), tmp_northsouth_psi.end(), NAN); - - _nsum = 0.; - _ssum = 0.; - _do_ep = false; - _mbdQ = 0.; - _totalcharge = 0.; -} - -int EventPlaneCalibration::End(PHCompositeNode * /*topNode*/) { - - cdbhistosOut->WriteCDBHistos(); - delete cdbhistosOut; - - std::cout << " EventPlaneCalibration::End() " << std::endl; - return Fun4AllReturnCodes::EVENT_OK; -} diff --git a/offline/packages/eventplaneinfo/EventPlaneCalibration.h b/offline/packages/eventplaneinfo/EventPlaneCalibration.h deleted file mode 100644 index 94875c08d2..0000000000 --- a/offline/packages/eventplaneinfo/EventPlaneCalibration.h +++ /dev/null @@ -1,121 +0,0 @@ -// Tell emacs that this is a C++ source -// -*- C++ -*-. -#ifndef EVENTPLANEINFO_EVENTPLANECALIBRATION_H -#define EVENTPLANEINFO_EVENTPLANECALIBRATION_H - -//=========================================================== -/// \author Ejiro Umaka -//=========================================================== - -#include - -#include // for string -#include // for vector - -class CDBHistos; -class TProfile2D; - -class PHCompositeNode; - -class EventPlaneCalibration : public SubsysReco { -public: - EventPlaneCalibration(const std::string &name = "EventPlaneCalibration"); - ~EventPlaneCalibration() override = default; - int InitRun(PHCompositeNode *topNode) override; - int process_event(PHCompositeNode *topNode) override; - int End(PHCompositeNode * /*topNode*/) override; - - void ResetMe(); - void set_sepd_epreco(bool sepdEpReco) { _sepdEpReco = sepdEpReco; } - void set_default_calibfile(bool default_calib) { - _default_calib = default_calib; - } - void set_mbd_epreco(bool mbdEpReco) { _mbdEpReco = mbdEpReco; } - void set_isSim(bool isSim) { _isSim = isSim; } - void set_sEPD_Mip_cut(const float e) { _epd_e = e; } - void set_sEPD_Charge_cut(const float c) { _epd_charge_min = c; } - void set_MBD_Min_Qcut(const float f) { _mbd_e = f; } - void set_MBD_Vetex_cut(const float v) { _mbd_vertex_cut = v; } - void set_Ep_orders(const unsigned int n) { m_MaxOrder = n; } - void set_outfilename(const std::string &name) {OutFileName = name;} - -private: - int CreateNodes(PHCompositeNode *topNode); - unsigned int m_MaxOrder{3}; - int m_runNo{0}; - std::string OutFileName; - CDBHistos *cdbhistosOut{nullptr}; - - std::vector> south_q; - std::vector> north_q; - std::vector> northsouth_q; - - std::vector> south_Qvec; - std::vector> north_Qvec; - std::vector> northsouth_Qvec; - - // recentering utility - std::vector> south_q_subtract; - std::vector> north_q_subtract; - std::vector> northsouth_q_subtract; - - // shifting utility - std::vector shift_north; - std::vector shift_south; - std::vector shift_northsouth; - std::vector tmp_south_psi; - std::vector tmp_north_psi; - std::vector tmp_northsouth_psi; - - // recentering histograms - - TProfile2D *tprof_mean_cos_north_epd[6]{}; - TProfile2D *tprof_mean_sin_north_epd[6]{}; - TProfile2D *tprof_mean_cos_south_epd[6]{}; - TProfile2D *tprof_mean_sin_south_epd[6]{}; - TProfile2D *tprof_mean_cos_northsouth_epd[6]{}; - TProfile2D *tprof_mean_sin_northsouth_epd[6]{}; - - TProfile2D *tprof_mean_cos_north_epd_input[6]{}; - TProfile2D *tprof_mean_sin_north_epd_input[6]{}; - TProfile2D *tprof_mean_cos_south_epd_input[6]{}; - TProfile2D *tprof_mean_sin_south_epd_input[6]{}; - TProfile2D *tprof_mean_cos_northsouth_epd_input[6]{}; - TProfile2D *tprof_mean_sin_northsouth_epd_input[6]{}; - - // shifting histograms - const int _imax{12}; - - TProfile2D *tprof_cos_north_epd_shift[6][12]{}; - TProfile2D *tprof_sin_north_epd_shift[6][12]{}; - TProfile2D *tprof_cos_south_epd_shift[6][12]{}; - TProfile2D *tprof_sin_south_epd_shift[6][12]{}; - TProfile2D *tprof_cos_northsouth_epd_shift[6][12]{}; - TProfile2D *tprof_sin_northsouth_epd_shift[6][12]{}; - - TProfile2D *tprof_cos_north_epd_shift_input[6][12]{}; - TProfile2D *tprof_sin_north_epd_shift_input[6][12]{}; - TProfile2D *tprof_cos_south_epd_shift_input[6][12]{}; - TProfile2D *tprof_sin_south_epd_shift_input[6][12]{}; - TProfile2D *tprof_cos_northsouth_epd_shift_input[6][12]{}; - TProfile2D *tprof_sin_northsouth_epd_shift_input[6][12]{}; - - bool _mbdEpReco{false}; - bool _sepdEpReco{false}; - bool _isSim{false}; - bool _do_ep{false}; - bool _default_calib{false}; - - float _nsum{0.0}; - float _ssum{0.0}; - float _mbdvtx{999.0}; - float _epd_charge_min{5.0}; - float _epd_charge_max{10000.0}; - float _epd_e{10.0}; - float _mbd_e{10.0}; - float _mbdQ{0.0}; - double _totalcharge{0.0}; - float _mbd_vertex_cut{60.0}; -}; - -#endif // EVENTPLANEINFO_EVENTPLANECALIBRATION_H diff --git a/offline/packages/eventplaneinfo/EventPlaneReco.cc b/offline/packages/eventplaneinfo/EventPlaneReco.cc index f0c9f73dd4..58833f0df1 100644 --- a/offline/packages/eventplaneinfo/EventPlaneReco.cc +++ b/offline/packages/eventplaneinfo/EventPlaneReco.cc @@ -1,803 +1,637 @@ #include "EventPlaneReco.h" -#include "Eventplaneinfo.h" -#include "EventplaneinfoMap.h" #include "EventplaneinfoMapv1.h" -#include "Eventplaneinfov1.h" +#include "Eventplaneinfov2.h" #include #include #include +// -- Centrality +#include + +// -- sEPD #include -#include -#include -#include -#include +#include // for CDBTTree -#include -#include -#include -#include +// -- event +#include -#include -#include #include #include -#include // for SubsysReco -#include -#include -#include // for PHNode -#include -#include // for PHObject #include -#include // for PHWHERE -#include +#include +#include -#include +// -- root includes -- +#include +#include -#include // for array -#include -#include -#include // for exit -#include +// c++ includes -- +#include +#include +#include #include -#include // for _Rb_tree_const_iterator -#include // for pair -#include // for vector - -EventPlaneReco::EventPlaneReco(const std::string &name) : SubsysReco(name) { - - south_q.resize(m_MaxOrder); - north_q.resize(m_MaxOrder); - northsouth_q.resize(m_MaxOrder); +#include +#include - south_q_subtract.resize(m_MaxOrder); - north_q_subtract.resize(m_MaxOrder); - northsouth_q_subtract.resize(m_MaxOrder); +//____________________________________________________________________________.. +EventPlaneReco::EventPlaneReco(const std::string &name): + SubsysReco(name) +{ +} - shift_north.resize(m_MaxOrder); - shift_south.resize(m_MaxOrder); - shift_northsouth.resize(m_MaxOrder); - tmp_south_psi.resize(m_MaxOrder); - tmp_north_psi.resize(m_MaxOrder); - tmp_northsouth_psi.resize(m_MaxOrder); +//____________________________________________________________________________.. +int EventPlaneReco::Init(PHCompositeNode *topNode) +{ + std::string calibdir = CDBInterface::instance()->getUrl(m_calibName); - for (auto &vec : south_q) { - vec.resize(2); + if (!m_directURL_EventPlaneCalib.empty()) + { + m_cdbttree = new CDBTTree(m_directURL_EventPlaneCalib); + std::cout << PHWHERE << " Custom Event Plane Calib Found: " << m_directURL_EventPlaneCalib << std::endl; } - - for (auto &vec : north_q) { - vec.resize(2); + else if (!calibdir.empty()) + { + m_cdbttree = new CDBTTree(calibdir); + std::cout << PHWHERE << " Event Plane Calib Found: " << calibdir << std::endl; } - - for (auto &vec : northsouth_q) { - vec.resize(2); + else if (m_doAbortNoEventPlaneCalib) + { + std::cout << PHWHERE << " Error: No Event Plane Calib Found and m_doAbortNoEventPlaneCalib is true. Aborting." << std::endl; + return Fun4AllReturnCodes::ABORTRUN; } - - for (auto &vec : south_q_subtract) { - vec.resize(2); + else + { + std::cout << PHWHERE << " Error: No Event Plane Calib Found. Skipping Event Plane Calibrations." << std::endl; + m_doNotCalib = true; } - for (auto &vec : north_q_subtract) { - vec.resize(2); + if (!m_doNotCalib) + { + LoadCalib(); } - for (auto &vec : northsouth_q_subtract) { - vec.resize(2); + if (Verbosity() > 0) + { + print_correction_data(); } - ring_q_north.resize(nRings); - ring_q_south.resize(nRings); - - for (auto &rq : ring_q_north) { - rq.resize(m_MaxOrder, std::vector(2, 0.0)); - } - for (auto &rq : ring_q_south) { - rq.resize(m_MaxOrder, std::vector(2, 0.0)); - } + CreateNodes(topNode); - all_ring_Qvecs_north.assign( - nRings, std::vector>(m_MaxOrder, {0.0, 0.0})); + return Fun4AllReturnCodes::EVENT_OK; +} - all_ring_Qvecs_south.assign( - nRings, std::vector>(m_MaxOrder, {0.0, 0.0})); +std::array, 2> EventPlaneReco::calculate_flattening_matrix(double xx, double yy, double xy, int n, int cent_bin, const std::string& det_label) +{ + std::array, 2> mat{}; + + double D_arg = (xx * yy) - (xy * xy); + if (D_arg <= 0) + { + std::cout << PHWHERE << "Invalid D-term " << D_arg << " for n=" << n << ", cent bin=" << cent_bin << ", det=" << det_label << std::endl; + // Return Identity Matrix to preserve Recentered vector + mat[0][0] = 1.0; + mat[1][1] = 1.0; + return mat; + } + double D = std::sqrt(D_arg); + + double N_term = D * (xx + yy + (2 * D)); + if (N_term <= 0) + { + std::cout << PHWHERE << "Invalid N-term " << N_term << " for n=" << n << ", cent bin=" << cent_bin << ", det=" << det_label << std::endl; + // Return Identity Matrix to preserve Recentered vector + mat[0][0] = 1.0; + mat[1][1] = 1.0; + return mat; + } + double inv_sqrt_N = 1.0 / std::sqrt(N_term); + + mat[0][0] = inv_sqrt_N * (yy + D); + mat[0][1] = -inv_sqrt_N * xy; + mat[1][0] = mat[0][1]; + mat[1][1] = inv_sqrt_N * (xx + D); + return mat; } -int EventPlaneReco::InitRun(PHCompositeNode *topNode) { +//____________________________________________________________________________.. +void EventPlaneReco::LoadCalib() +{ + size_t south_idx = static_cast(Subdetector::S); + size_t north_idx = static_cast(Subdetector::N); + size_t ns_idx = static_cast(Subdetector::NS); - FileName = "EVENTPLANE_CORRECTION"; - if (_isSim) { - FileName = "EVENTPLANE_CORRECTION_SIM"; - } + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + int n = m_harmonics[h_idx]; - std::string calibdir = CDBInterface::instance()->getUrl(FileName); + std::string S_x_avg_name = std::format("Q_S_x_{}_avg", n); + std::string S_y_avg_name = std::format("Q_S_y_{}_avg", n); + std::string N_x_avg_name = std::format("Q_N_x_{}_avg", n); + std::string N_y_avg_name = std::format("Q_N_y_{}_avg", n); - if (calibdir.empty()) { - std::cout << PHWHERE << "No Eventplane calibration file for domain " - << FileName << " found" << std::endl; - std::cout << PHWHERE - << "Will only produce raw Q vectors and event plane angles " - << std::endl; - } + std::string S_xx_avg_name = std::format("Q_S_xx_{}_avg", n); + std::string S_yy_avg_name = std::format("Q_S_yy_{}_avg", n); + std::string S_xy_avg_name = std::format("Q_S_xy_{}_avg", n); + std::string N_xx_avg_name = std::format("Q_N_xx_{}_avg", n); + std::string N_yy_avg_name = std::format("Q_N_yy_{}_avg", n); + std::string N_xy_avg_name = std::format("Q_N_xy_{}_avg", n); - CDBHistos *cdbhistosIn = new CDBHistos(calibdir); - cdbhistosIn->LoadCalibrations(); - - // Get phiweights - h_phi_weight_south_input = - dynamic_cast(cdbhistosIn->getHisto("h_phi_weight_south", false)); - h_phi_weight_north_input = - dynamic_cast(cdbhistosIn->getHisto("h_phi_weight_north", false)); - - // Get recentering histograms - for (unsigned int order = 0; order < m_MaxOrder; order++) { - tprof_mean_cos_south_epd_input[order] = - dynamic_cast(cdbhistosIn->getHisto( - std::format("tprof_mean_cos_south_epd_order_{}", order), false)); - tprof_mean_sin_south_epd_input[order] = - dynamic_cast(cdbhistosIn->getHisto( - std::format("tprof_mean_sin_south_epd_order_{}", order), false)); - tprof_mean_cos_north_epd_input[order] = - dynamic_cast(cdbhistosIn->getHisto( - std::format("tprof_mean_cos_north_epd_order_{}", order), false)); - tprof_mean_sin_north_epd_input[order] = - dynamic_cast(cdbhistosIn->getHisto( - std::format("tprof_mean_sin_north_epd_order_{}", order), false)); - tprof_mean_cos_northsouth_epd_input[order] = - dynamic_cast(cdbhistosIn->getHisto( - std::format("tprof_mean_cos_northsouth_epd_order_{}", order), - false)); - tprof_mean_sin_northsouth_epd_input[order] = - dynamic_cast(cdbhistosIn->getHisto( - std::format("tprof_mean_sin_northsouth_epd_order_{}", order), - false)); - } + std::string NS_xx_avg_name = std::format("Q_NS_xx_{}_avg", n); + std::string NS_yy_avg_name = std::format("Q_NS_yy_{}_avg", n); + std::string NS_xy_avg_name = std::format("Q_NS_xy_{}_avg", n); - // Get shifting histograms - for (unsigned int order = 0; order < m_MaxOrder; order++) { - for (int p = 0; p < _imax; p++) { - tprof_cos_north_epd_shift_input[order][p] = - dynamic_cast(cdbhistosIn->getHisto( - std::format("tprof_cos_north_epd_shift_order_{}_{}", order, p), - false)); - tprof_sin_north_epd_shift_input[order][p] = - dynamic_cast(cdbhistosIn->getHisto( - std::format("tprof_sin_north_epd_shift_order_{}_{}", order, p), - false)); - tprof_cos_south_epd_shift_input[order][p] = - dynamic_cast(cdbhistosIn->getHisto( - std::format("tprof_cos_south_epd_shift_order_{}_{}", order, p), - false)); - tprof_sin_south_epd_shift_input[order][p] = - dynamic_cast(cdbhistosIn->getHisto( - std::format("tprof_sin_south_epd_shift_order_{}_{}", order, p), - false)); - tprof_cos_northsouth_epd_shift_input[order][p] = - dynamic_cast(cdbhistosIn->getHisto( - std::format("tprof_cos_northsouth_epd_shift_order_{}_{}", order, - p), - false)); - tprof_sin_northsouth_epd_shift_input[order][p] = - dynamic_cast(cdbhistosIn->getHisto( - std::format("tprof_sin_northsouth_epd_shift_order_{}_{}", order, - p), - false)); - } - } + for (size_t cent_bin = 0; cent_bin < m_cent_bins; ++cent_bin) + { + int key = cent_bin; - if (Verbosity() > 1) { - cdbhistosIn->Print(); - } + // South + auto& dataS = m_correction_data[h_idx][cent_bin][south_idx]; + dataS.avg_Q.x = m_cdbttree->GetDoubleValue(key, S_x_avg_name); + dataS.avg_Q.y = m_cdbttree->GetDoubleValue(key, S_y_avg_name); - return CreateNodes(topNode); -} + dataS.avg_Q_xx = m_cdbttree->GetDoubleValue(key, S_xx_avg_name); + dataS.avg_Q_yy = m_cdbttree->GetDoubleValue(key, S_yy_avg_name); + dataS.avg_Q_xy = m_cdbttree->GetDoubleValue(key, S_xy_avg_name); -int EventPlaneReco::process_event(PHCompositeNode *topNode) { - if (Verbosity() > 1) { - std::cout << "EventPlaneReco::process_event -- entered" << std::endl; - } + dataS.X_matrix = calculate_flattening_matrix(dataS.avg_Q_xx, dataS.avg_Q_yy, dataS.avg_Q_xy, n, cent_bin, "South"); - //--------------------------------- - // Get Objects off of the Node Tree - //--------------------------------- - - if (_isSim) { - // Use GlobalVertexMap for simulation - GlobalVertexMap *vertexmap = - findNode::getClass(topNode, "GlobalVertexMap"); - if (!vertexmap) { - std::cout << PHWHERE << "::ERROR - cannot find GlobalVertexMap" - << std::endl; - exit(-1); - } + // North + auto& dataN = m_correction_data[h_idx][cent_bin][north_idx]; + dataN.avg_Q.x = m_cdbttree->GetDoubleValue(key, N_x_avg_name); + dataN.avg_Q.y = m_cdbttree->GetDoubleValue(key, N_y_avg_name); - if (!vertexmap->empty()) { - GlobalVertex *vtx = vertexmap->begin()->second; - if (vtx) { - _mbdvtx = vtx->get_z(); - } - } - } else { - // Use MbdVertexMap for data - MbdVertexMap *mbdvtxmap = - findNode::getClass(topNode, "MbdVertexMap"); - if (!mbdvtxmap) { - std::cout << PHWHERE << "::ERROR - cannot find MbdVertexMap" << std::endl; - exit(-1); - } + dataN.avg_Q_xx = m_cdbttree->GetDoubleValue(key, N_xx_avg_name); + dataN.avg_Q_yy = m_cdbttree->GetDoubleValue(key, N_yy_avg_name); + dataN.avg_Q_xy = m_cdbttree->GetDoubleValue(key, N_xy_avg_name); - MbdVertex *mvertex = nullptr; - if (mbdvtxmap) { - for (MbdVertexMap::ConstIter mbditer = mbdvtxmap->begin(); - mbditer != mbdvtxmap->end(); ++mbditer) { - mvertex = mbditer->second; - } - if (mvertex) { - _mbdvtx = mvertex->get_z(); - } - } - } + dataN.X_matrix = calculate_flattening_matrix(dataN.avg_Q_xx, dataN.avg_Q_yy, dataN.avg_Q_xy, n, cent_bin, "North"); - EventplaneinfoMap *epmap = - findNode::getClass(topNode, "EventplaneinfoMap"); - if (!epmap) { - std::cout << PHWHERE << "::ERROR - cannot find EventplaneinfoMap" - << std::endl; - exit(-1); - } + // North South + // Note: We do NOT load avg_Q (x,y) for NS because NS is recentered by summing the recentered S and N vectors. + auto& dataNS = m_correction_data[h_idx][cent_bin][ns_idx]; - if (_sepdEpReco) { - - TowerInfoContainer *epd_towerinfo = - findNode::getClass(topNode, "TOWERINFO_CALIB_SEPD"); - if (!epd_towerinfo) { - epd_towerinfo = findNode::getClass( - topNode, "TOWERINFO_CALIB_EPD"); - if (!epd_towerinfo) { - std::cout << PHWHERE - << "::ERROR - cannot find sEPD Calibrated TowerInfoContainer" - << std::endl; - exit(-1); - } - } + dataNS.avg_Q_xx = m_cdbttree->GetDoubleValue(key, NS_xx_avg_name); + dataNS.avg_Q_yy = m_cdbttree->GetDoubleValue(key, NS_yy_avg_name); + dataNS.avg_Q_xy = m_cdbttree->GetDoubleValue(key, NS_xy_avg_name); - EpdGeom *_epdgeom = findNode::getClass(topNode, "TOWERGEOM_EPD"); - if (!_epdgeom) { - std::cout << PHWHERE << "::ERROR - cannot find TOWERGEOM_EPD" - << std::endl; - exit(-1); + dataNS.X_matrix = calculate_flattening_matrix(dataNS.avg_Q_xx, dataNS.avg_Q_yy, dataNS.avg_Q_xy, n, cent_bin, "NorthSouth"); } + } + delete m_cdbttree; + m_cdbttree = nullptr; +} - ResetMe(); - - if ((std::fabs(_mbdvtx) < _mbd_vertex_cut)) { - - unsigned int ntowers = epd_towerinfo->size(); - for (unsigned int ch = 0; ch < ntowers; ch++) { - TowerInfo *_tower = epd_towerinfo->get_tower_at_channel(ch); - float epd_e = _tower->get_energy(); - bool isZS = _tower->get_isZS(); - if (!isZS) // exclude ZS +//____________________________________________________________________________.. +void EventPlaneReco::print_correction_data() +{ + std::cout << std::format("\n{:=>60}\n", ""); + std::cout << std::format("{:^60}\n", "EVENT PLANE CORRECTION DATA SUMMARY"); + std::cout << std::format("{:=>60}\n", ""); + + // Iterate through harmonics {2, 3, 4} + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + int n = m_harmonics[h_idx]; + std::cout << std::format("\n>>> HARMONIC n = {} <<<\n", n); + + // Iterate through Centrality Bins (0-79) + for (size_t cent = 0; cent < m_cent_bins; ++cent) + { + std::cout << std::format("\n Centrality Bin: {}\n", cent); + std::cout << std::format(" {:->30}\n", ""); + + // Header with fixed column widths + std::cout << std::format(" {:<12} {:>10} {:>10} {:>10} {:>10} {:>10}\n", + "Detector", "Avg Qx", "Avg Qy", "Avg Qxx", "Avg Qyy", "Avg Qxy"); + + // Iterate through Subdetectors {S, N} + for (size_t det_idx = 0; det_idx < 3; ++det_idx) + { + std::string det_name; + if (det_idx == 0) { - unsigned int key = TowerInfoDefs::encode_epd(ch); - int arm = TowerInfoDefs::get_epd_arm(key); - if (arm == 0) { - _ssum += epd_e; - } else if (arm == 1) { - _nsum += epd_e; - } + det_name = "South"; + } + else if (det_idx == 1) + { + det_name = "North"; + } + else + { + det_name = "NorthSouth"; } - } - if (_ssum > _epd_charge_min && _nsum > _epd_charge_min && - _ssum < _epd_charge_max && _nsum < _epd_charge_max) { - _do_ep = true; - } + const auto& data = m_correction_data[h_idx][cent][det_idx]; - if (_do_ep) { - - // Apply phi weights in builiding ring Q-vectors - for (unsigned int ch = 0; ch < ntowers; ch++) { - TowerInfo *_tower = epd_towerinfo->get_tower_at_channel(ch); - float epd_e = _tower->get_energy(); - bool isZS = _tower->get_isZS(); - if (!isZS) // exclude ZS - { - if (epd_e < 0.2) // expecting Nmips - { - continue; - } - unsigned int key = TowerInfoDefs::encode_epd(ch); - float tile_phi = _epdgeom->get_phi(key); - int arm = TowerInfoDefs::get_epd_arm(key); - int rbin = TowerInfoDefs::get_epd_rbin(key); - int phibin = TowerInfoDefs::get_epd_phibin(key); - - float truncated_e = - (epd_e < _epd_e) ? epd_e : _epd_e; // set cutoff at _epd_e - - float TileWeight = truncated_e; // default - - if (h_phi_weight_south_input && h_phi_weight_north_input) { - if (arm == 0) { - TileWeight = - truncated_e * h_phi_weight_south_input->GetBinContent( - phibin + 1); // scale by 1/ - } else if (arm == 1) { - TileWeight = - truncated_e * h_phi_weight_north_input->GetBinContent( - phibin + 1); // scale by 1/ - } - } - - for (unsigned int order = 0; order < m_MaxOrder; ++order) { - double Cosine = cos(tile_phi * (double)(order + 1)); - double Sine = sin(tile_phi * (double)(order + 1)); - - // Arm-specific Q-vectors - if (arm == 0) { - south_q[order][0] += truncated_e * Cosine; - south_q[order][1] += truncated_e * Sine; - ring_q_south[rbin][order][0] += TileWeight * Cosine; - ring_q_south[rbin][order][1] += TileWeight * Sine; - - } else if (arm == 1) { - north_q[order][0] += truncated_e * Cosine; - north_q[order][1] += truncated_e * Sine; - ring_q_north[rbin][order][0] += TileWeight * Cosine; - ring_q_north[rbin][order][1] += TileWeight * Sine; - } - - // Combined Q-vectors - northsouth_q[order][0] += truncated_e * Cosine; - northsouth_q[order][1] += truncated_e * Sine; - } - } - } + // For NS, Avg Qx/Qy will be 0.0 because they are not loaded from CDB. + // This is expected behavior. + std::cout << std::format(" {:<12} {:>10.6f} {:>10.6f} {:>10.6f} {:>10.6f} {:>10.6f}\n", + det_name, + data.avg_Q.x, data.avg_Q.y, + data.avg_Q_xx, data.avg_Q_yy, data.avg_Q_xy); - _totalcharge = _nsum + _ssum; - - // Get recentering histograms and do recentering - // Recentering: subtract Qn,x and Qn,y values averaged over all events - for (unsigned int order = 0; order < m_MaxOrder; order++) { - if (tprof_mean_cos_south_epd_input[order]) // check if recentering - // histograms exist - { - // south - TAxis *south_xaxis = - tprof_mean_cos_south_epd_input[order]->GetXaxis(); - TAxis *south_yaxis = - tprof_mean_cos_south_epd_input[order]->GetYaxis(); - int xbin_south = south_xaxis->FindBin(_ssum); - int ybin_south = south_yaxis->FindBin(_mbdvtx); - - double event_ave_cos_south = - tprof_mean_cos_south_epd_input[order]->GetBinContent( - xbin_south, ybin_south); - double event_ave_sin_south = - tprof_mean_sin_south_epd_input[order]->GetBinContent( - xbin_south, ybin_south); - south_q_subtract[order][0] = _ssum * event_ave_cos_south; - south_q_subtract[order][1] = _ssum * event_ave_sin_south; - south_q[order][0] -= south_q_subtract[order][0]; - south_q[order][1] -= south_q_subtract[order][1]; - - // north - TAxis *north_xaxis = - tprof_mean_cos_north_epd_input[order]->GetXaxis(); - TAxis *north_yaxis = - tprof_mean_cos_north_epd_input[order]->GetYaxis(); - int xbin_north = north_xaxis->FindBin(_nsum); - int ybin_north = north_yaxis->FindBin(_mbdvtx); - - double event_ave_cos_north = - tprof_mean_cos_north_epd_input[order]->GetBinContent( - xbin_north, ybin_north); - double event_ave_sin_north = - tprof_mean_sin_north_epd_input[order]->GetBinContent( - xbin_north, ybin_north); - north_q_subtract[order][0] = _nsum * event_ave_cos_north; - north_q_subtract[order][1] = _nsum * event_ave_sin_north; - north_q[order][0] -= north_q_subtract[order][0]; - north_q[order][1] -= north_q_subtract[order][1]; - - // northsouth - TAxis *northsouth_xaxis = - tprof_mean_cos_northsouth_epd_input[order]->GetXaxis(); - TAxis *northsouth_yaxis = - tprof_mean_cos_northsouth_epd_input[order]->GetYaxis(); - int xbin_northsouth = northsouth_xaxis->FindBin(_totalcharge); - int ybin_northsouth = northsouth_yaxis->FindBin(_mbdvtx); - - double event_ave_cos_northsouth = - tprof_mean_cos_northsouth_epd_input[order]->GetBinContent( - xbin_northsouth, ybin_northsouth); - double event_ave_sin_northsouth = - tprof_mean_sin_northsouth_epd_input[order]->GetBinContent( - xbin_northsouth, ybin_northsouth); - northsouth_q_subtract[order][0] = - _totalcharge * event_ave_cos_northsouth; - northsouth_q_subtract[order][1] = - _totalcharge * event_ave_sin_northsouth; - northsouth_q[order][0] -= northsouth_q_subtract[order][0]; - northsouth_q[order][1] -= northsouth_q_subtract[order][1]; - } - } + // Print X-Matrix in a bracketed layout + std::cout << std::format(" X-Matrix: [ {:>8.6f}, {:>8.6f} ]\n", + data.X_matrix[0][0], data.X_matrix[0][1]); + std::cout << std::format(" [ {:>8.6f}, {:>8.6f} ]\n", + data.X_matrix[1][0], data.X_matrix[1][1]); + } + } + } + std::cout << std::format("\n{:=>60}\n", ""); +} - // Get recentered psi_n - Eventplaneinfo *epinfo = new Eventplaneinfov1(); - for (unsigned int order = 0; order < m_MaxOrder; order++) { - double n = order + 1.0; - if (tprof_mean_cos_south_epd_input[order]) // if present, Qs are - // recentered - { - tmp_south_psi[order] = - epinfo->GetPsi(south_q[order][0], south_q[order][1], n); - tmp_north_psi[order] = - epinfo->GetPsi(north_q[order][0], north_q[order][1], n); - tmp_northsouth_psi[order] = epinfo->GetPsi( - northsouth_q[order][0], northsouth_q[order][1], n); - } else { - tmp_south_psi[order] = NAN; - tmp_north_psi[order] = NAN; - tmp_northsouth_psi[order] = NAN; - } - } +int EventPlaneReco::CreateNodes(PHCompositeNode *topNode) { + PHNodeIterator iter(topNode); - // Get shifting histograms and calculate shift - for (unsigned int order = 0; order < m_MaxOrder; order++) { - for (int p = 0; p < _imax; p++) { - if (tprof_cos_south_epd_shift_input[order][p]) // check if shifting - // histograms exist - { - double terms = p + 1.0; - double n = order + 1.0; - double tmp = n * terms; - double prefactor = 2.0 / terms; - - // south - TAxis *south_xaxis = - tprof_cos_south_epd_shift_input[order][p]->GetXaxis(); - TAxis *south_yaxis = - tprof_cos_south_epd_shift_input[order][p]->GetYaxis(); - int xbin_south = south_xaxis->FindBin(_ssum); - int ybin_south = south_yaxis->FindBin(_mbdvtx); - - // north - TAxis *north_xaxis = - tprof_cos_north_epd_shift_input[order][p]->GetXaxis(); - TAxis *north_yaxis = - tprof_cos_north_epd_shift_input[order][p]->GetYaxis(); - int xbin_north = north_xaxis->FindBin(_nsum); - int ybin_north = north_yaxis->FindBin(_mbdvtx); - - // // northsouth - TAxis *northsouth_xaxis = - tprof_cos_northsouth_epd_shift_input[order][p]->GetXaxis(); - TAxis *northsouth_yaxis = - tprof_cos_northsouth_epd_shift_input[order][p]->GetYaxis(); - int xbin_northsouth = northsouth_xaxis->FindBin(_totalcharge); - int ybin_northsouth = northsouth_yaxis->FindBin(_mbdvtx); - - // Equation (6) of arxiv:nucl-ex/9805001 - // i = terms; n = order; i*n = tmp - // (2 / i ) * * sin(i*n*psi_n) - // - * cos(i*n*psi_n) - - // north - shift_north[order] += - prefactor * - (tprof_cos_north_epd_shift_input[order][p]->GetBinContent( - xbin_north, ybin_north) * - sin(tmp * tmp_north_psi[order]) - - tprof_sin_north_epd_shift_input[order][p]->GetBinContent( - xbin_north, ybin_north) * - cos(tmp * tmp_north_psi[order])); - - // south - shift_south[order] += - prefactor * - (tprof_cos_south_epd_shift_input[order][p]->GetBinContent( - xbin_south, ybin_south) * - sin(tmp * tmp_south_psi[order]) - - tprof_sin_south_epd_shift_input[order][p]->GetBinContent( - xbin_south, ybin_south) * - cos(tmp * tmp_south_psi[order])); - - // // northsouth - shift_northsouth[order] += - prefactor * - (tprof_cos_northsouth_epd_shift_input[order][p] - ->GetBinContent(xbin_northsouth, ybin_northsouth) * - sin(tmp * tmp_northsouth_psi[order]) - - tprof_sin_northsouth_epd_shift_input[order][p] - ->GetBinContent(xbin_northsouth, ybin_northsouth) * - cos(tmp * tmp_northsouth_psi[order])); - } - } - } + PHCompositeNode *dstNode = dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); + if (!dstNode) + { + std::cout << PHWHERE << "DST Node missing, doing nothing." << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } - // n * deltapsi_n = (2 / i ) * * sin(i*n*psi_n) - - // * cos(i*n*psi_n) Divide out n - for (unsigned int order = 0; order < m_MaxOrder; order++) { - double n = order + 1.0; - shift_north[order] /= n; - shift_south[order] /= n; - shift_northsouth[order] /= n; - } + PHCompositeNode *globalNode = dynamic_cast(iter.findFirst("PHCompositeNode", "GLOBAL")); + if (!globalNode) + { + globalNode = new PHCompositeNode("GLOBAL"); + dstNode->addNode(globalNode); + } - // Now add shift to psi_n to flatten it - for (unsigned int order = 0; order < m_MaxOrder; order++) { - if (tprof_cos_north_epd_shift_input[0][0]) { - tmp_south_psi[order] += shift_south[order]; - tmp_north_psi[order] += shift_north[order]; - tmp_northsouth_psi[order] += shift_northsouth[order]; - } - } + EventplaneinfoMap *eps = findNode::getClass(topNode, "EventplaneinfoMap"); + if (!eps) + { + eps = new EventplaneinfoMapv1(); + PHIODataNode *newNode = new PHIODataNode(eps , "EventplaneinfoMap", "PHObject"); + globalNode->addNode(newNode); + } - // Now enforce the range - for (unsigned int order = 0; order < m_MaxOrder; order++) { - if (tprof_cos_north_epd_shift_input[0][0]) { - double range = M_PI / (double)(order + 1); - if (tmp_south_psi[order] < -1.0 * range) { - tmp_south_psi[order] += 2.0 * range; - } - if (tmp_south_psi[order] > range) { - tmp_south_psi[order] -= 2.0 * range; - } - if (tmp_north_psi[order] < -1.0 * range) { - tmp_north_psi[order] += 2.0 * range; - } - if (tmp_north_psi[order] > range) { - tmp_north_psi[order] -= 2.0 * range; - } - if (tmp_northsouth_psi[order] < -1.0 * range) { - tmp_northsouth_psi[order] += 2.0 * range; - } - if (tmp_northsouth_psi[order] > range) { - tmp_northsouth_psi[order] -= 2.0 * range; - } - } - } + return Fun4AllReturnCodes::EVENT_OK; +} - for (unsigned int order = 0; order < m_MaxOrder; order++) { - south_Qvec.emplace_back(south_q[order][0], south_q[order][1]); - north_Qvec.emplace_back(north_q[order][0], north_q[order][1]); - northsouth_Qvec.emplace_back(northsouth_q[order][0], - northsouth_q[order][1]); - } +//____________________________________________________________________________.. +int EventPlaneReco::process_centrality(PHCompositeNode *topNode) +{ + CentralityInfo* centInfo = findNode::getClass(topNode, "CentralityInfo"); + if (!centInfo) + { + std::cout << PHWHERE << " CentralityInfo is missing doing nothing" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } - for (int rbin = 0; rbin < nRings; ++rbin) { - for (unsigned int order = 0; order < m_MaxOrder; ++order) { - all_ring_Qvecs_north[rbin][order] = std::make_pair( - ring_q_north[rbin][order][0], ring_q_north[rbin][order][1]); - all_ring_Qvecs_south[rbin][order] = std::make_pair( - ring_q_south[rbin][order][0], ring_q_south[rbin][order][1]); - } - } + m_cent = centInfo->get_centile(CentralityInfo::PROP::mbd_NS) * 100; - if (epd_towerinfo) { - Eventplaneinfo *sepds = new Eventplaneinfov1(); - sepds->set_qvector(south_Qvec); - sepds->set_shifted_psi(tmp_south_psi); - epmap->insert(sepds, EventplaneinfoMap::sEPDS); - - Eventplaneinfo *sepdn = new Eventplaneinfov1(); - sepdn->set_qvector(north_Qvec); - sepdn->set_shifted_psi(tmp_north_psi); - epmap->insert(sepdn, EventplaneinfoMap::sEPDN); - - Eventplaneinfo *sepdns = new Eventplaneinfov1(); - sepdns->set_qvector(northsouth_Qvec); - sepdns->set_shifted_psi(tmp_northsouth_psi); - epmap->insert(sepdns, EventplaneinfoMap::sEPDNS); - - Eventplaneinfo *epring_south = new Eventplaneinfov1(); - epring_south->set_ring_qvector(all_ring_Qvecs_south); - epmap->insert(epring_south, EventplaneinfoMap::sEPDRING_SOUTH); - - Eventplaneinfo *epring_north = new Eventplaneinfov1(); - epring_north->set_ring_qvector(all_ring_Qvecs_north); - epmap->insert(epring_north, EventplaneinfoMap::sEPDRING_NORTH); - - if (Verbosity() > 1) { - sepds->identify(); - sepdn->identify(); - sepdns->identify(); - epring_south->identify(); - epring_north->identify(); - } - } - } + if (!std::isfinite(m_cent) || m_cent < 0) + { + if (Verbosity() > 1) + { + std::cout << PHWHERE << " Warning Centrality is out of range. Cent: " << m_cent << ". Cannot calibrate Q vector for this event." << std::endl; } + m_doNotCalibEvent = true; } - if (_mbdEpReco) { - ResetMe(); + return Fun4AllReturnCodes::EVENT_OK; +} - MbdPmtContainer *mbdpmts = - findNode::getClass(topNode, "MbdPmtContainer"); - if (!mbdpmts) { - std::cout << PHWHERE << "::ERROR - cannot find MbdPmtContainer" - << std::endl; - exit(-1); - } +//____________________________________________________________________________.. +int EventPlaneReco::process_sEPD(PHCompositeNode* topNode) +{ + TowerInfoContainer* towerinfosEPD = findNode::getClass(topNode, m_inputNode); + if (!towerinfosEPD) + { + std::cout << PHWHERE << " TOWERINFO_CALIB_SEPD is missing doing nothing" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } - MbdGeom *mbdgeom = findNode::getClass(topNode, "MbdGeom"); - if (!mbdgeom) { - std::cout << PHWHERE << "::ERROR - cannot find MbdGeom" << std::endl; - exit(-1); - } + EpdGeom* epdgeom = findNode::getClass(topNode, "TOWERGEOM_EPD"); + if (!epdgeom) + { + std::cout << PHWHERE << " TOWERGEOM_EPD is missing doing nothing" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } - if (mbdpmts) { - if (Verbosity()) { - std::cout << "EventPlaneReco::process_event - mbdpmts" << std::endl; - } + // sepd + unsigned int nchannels_epd = towerinfosEPD->size(); - for (int ipmt = 0; ipmt < mbdpmts->get_npmt(); ipmt++) { - float mbd_q = mbdpmts->get_pmt(ipmt)->get_q(); - _mbdQ += mbd_q; - } + double sepd_total_charge_south = 0; + double sepd_total_charge_north = 0; - for (int ipmt = 0; ipmt < mbdpmts->get_npmt(); ipmt++) { - float mbd_q = mbdpmts->get_pmt(ipmt)->get_q(); - float phi = mbdgeom->get_phi(ipmt); - int arm = mbdgeom->get_arm(ipmt); + for (unsigned int channel = 0; channel < nchannels_epd; ++channel) + { + TowerInfo* tower = towerinfosEPD->get_tower_at_channel(channel); - if (_mbdQ < _mbd_e) { - continue; - } + unsigned int key = TowerInfoDefs::encode_epd(channel); + double charge = tower->get_energy(); + double phi = epdgeom->get_phi(key); - if (arm == 0) { - for (unsigned int order = 0; order < m_MaxOrder; order++) { - double Cosine = cos(phi * (double)(order + 1)); - double Sine = sin(phi * (double)(order + 1)); - south_q[order][0] += mbd_q * Cosine; // south Qn,x - south_q[order][1] += mbd_q * Sine; // south Qn,y - } - } else if (arm == 1) { - for (unsigned int order = 0; order < m_MaxOrder; order++) { - double Cosine = cos(phi * (double)(order + 1)); - double Sine = sin(phi * (double)(order + 1)); - north_q[order][0] += mbd_q * Cosine; // north Qn,x - north_q[order][1] += mbd_q * Sine; // north Qn,y - } - } - } + // skip bad channels + // skip channels with very low charge + if (tower->get_isHot() || charge < m_sepd_min_channel_charge) + { + continue; } - for (unsigned int order = 0; order < m_MaxOrder; order++) { - south_Qvec.emplace_back(south_q[order][0], south_q[order][1]); - north_Qvec.emplace_back(north_q[order][0], north_q[order][1]); - } + // arm = 0: South + // arm = 1: North + unsigned int arm = TowerInfoDefs::get_epd_arm(key); - if (mbdpmts) { - Eventplaneinfo *mbds = new Eventplaneinfov1(); - mbds->set_qvector(south_Qvec); - epmap->insert(mbds, EventplaneinfoMap::MBDS); + // sepd charge sums + double& sepd_total_charge = (arm == 0) ? sepd_total_charge_south : sepd_total_charge_north; - Eventplaneinfo *mbdn = new Eventplaneinfov1(); - mbdn->set_qvector(north_Qvec); - epmap->insert(mbdn, EventplaneinfoMap::MBDN); + // Compute total charge for the respective sEPD arm + sepd_total_charge += charge; - if (Verbosity() > 1) { - mbds->identify(); - mbdn->identify(); - } + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + int n = m_harmonics[h_idx]; + QVec q_n = {charge * std::cos(n * phi), charge * std::sin(n * phi)}; + m_Q_raw[h_idx][arm].x += q_n.x; + m_Q_raw[h_idx][arm].y += q_n.y; + } + } + + // ensure both total charges are nonzero + if (sepd_total_charge_south == 0 || sepd_total_charge_north == 0) + { + if (Verbosity() > 1) + { + std::cout << PHWHERE << " Error: Total sEPD Charge is Zero: " + << "South = " << sepd_total_charge_south + << ", North = " << sepd_total_charge_north << std::endl; } - ResetMe(); + // ensure raw Q vec is reset + m_Q_raw = {}; + m_doNotCalibEvent = true; + return Fun4AllReturnCodes::EVENT_OK; } - if (Verbosity()) { - epmap->identify(); + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + m_Q_raw[h_idx][0].x /= sepd_total_charge_south; + m_Q_raw[h_idx][0].y /= sepd_total_charge_south; + + m_Q_raw[h_idx][1].x /= sepd_total_charge_north; + m_Q_raw[h_idx][1].y /= sepd_total_charge_north; + + // NEW: Calculate Raw NS (Sum of Raw S + Raw N) + m_Q_raw[h_idx][2].x = m_Q_raw[h_idx][0].x + m_Q_raw[h_idx][1].x; + m_Q_raw[h_idx][2].y = m_Q_raw[h_idx][0].y + m_Q_raw[h_idx][1].y; } return Fun4AllReturnCodes::EVENT_OK; } -int EventPlaneReco::CreateNodes(PHCompositeNode *topNode) { - PHNodeIterator iter(topNode); - - PHCompositeNode *dstNode = - dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); - if (!dstNode) { - std::cout << PHWHERE << "DST Node missing, doing nothing." << std::endl; - return Fun4AllReturnCodes::ABORTRUN; +void EventPlaneReco::correct_QVecs() +{ + size_t cent_bin = static_cast(m_cent); + if (cent_bin >= m_cent_bins) + { + cent_bin = m_cent_bins - 1; // Clamp max } - PHCompositeNode *globalNode = dynamic_cast( - iter.findFirst("PHCompositeNode", "GLOBAL")); - if (!globalNode) { - globalNode = new PHCompositeNode("GLOBAL"); - dstNode->addNode(globalNode); - } + size_t south_idx = static_cast(Subdetector::S); + size_t north_idx = static_cast(Subdetector::N); + size_t ns_idx = static_cast(Subdetector::NS); - EventplaneinfoMap *eps = - findNode::getClass(topNode, "EventplaneinfoMap"); - if (!eps) { - eps = new EventplaneinfoMapv1(); - PHIODataNode *EpMapNode = - new PHIODataNode(eps, "EventplaneinfoMap", "PHObject"); - globalNode->addNode(EpMapNode); + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + auto& dataS = m_correction_data[h_idx][cent_bin][south_idx]; + auto& dataN = m_correction_data[h_idx][cent_bin][north_idx]; + auto& dataNS = m_correction_data[h_idx][cent_bin][ns_idx]; + + double Q_S_x_avg = dataS.avg_Q.x; + double Q_S_y_avg = dataS.avg_Q.y; + double Q_N_x_avg = dataN.avg_Q.x; + double Q_N_y_avg = dataN.avg_Q.y; + + QVec q_S = m_Q_raw[h_idx][south_idx]; + QVec q_N = m_Q_raw[h_idx][north_idx]; + + // Apply Recentering + QVec q_S_recenter = {q_S.x - Q_S_x_avg, q_S.y - Q_S_y_avg}; + QVec q_N_recenter = {q_N.x - Q_N_x_avg, q_N.y - Q_N_y_avg}; + QVec q_NS_recenter = {q_S_recenter.x + q_N_recenter.x, q_S_recenter.y + q_N_recenter.y}; + + m_Q_recentered[h_idx][south_idx] = q_S_recenter; + m_Q_recentered[h_idx][north_idx] = q_N_recenter; + m_Q_recentered[h_idx][ns_idx] = q_NS_recenter; + + // Flattening Matrix + const auto &X_S = dataS.X_matrix; + const auto &X_N = dataN.X_matrix; + const auto &X_NS = dataNS.X_matrix; + + // Apply Flattening + double Q_S_x_flat = X_S[0][0] * q_S_recenter.x + X_S[0][1] * q_S_recenter.y; + double Q_S_y_flat = X_S[1][0] * q_S_recenter.x + X_S[1][1] * q_S_recenter.y; + double Q_N_x_flat = X_N[0][0] * q_N_recenter.x + X_N[0][1] * q_N_recenter.y; + double Q_N_y_flat = X_N[1][0] * q_N_recenter.x + X_N[1][1] * q_N_recenter.y; + + double Q_NS_x_flat = X_NS[0][0] * q_NS_recenter.x + X_NS[0][1] * q_NS_recenter.y; + double Q_NS_y_flat = X_NS[1][0] * q_NS_recenter.x + X_NS[1][1] * q_NS_recenter.y; + + QVec q_S_flat = {Q_S_x_flat, Q_S_y_flat}; + QVec q_N_flat = {Q_N_x_flat, Q_N_y_flat}; + QVec q_NS_flat = {Q_NS_x_flat, Q_NS_y_flat}; + + m_Q_flat[h_idx][south_idx] = q_S_flat; + m_Q_flat[h_idx][north_idx] = q_N_flat; + m_Q_flat[h_idx][ns_idx] = q_NS_flat; } - return Fun4AllReturnCodes::EVENT_OK; } -void EventPlaneReco::ResetMe() { - for (auto &vec : south_q) { - std::fill(vec.begin(), vec.end(), 0.); - } +void EventPlaneReco::print_QVectors() +{ + std::string header_text = std::format("EVENT Q-VECTOR SUMMARY (Event: {}, CENTRALITY: {:.0f}%)", m_globalEvent, m_cent); + + std::cout << std::format("\n{:*>100}\n", ""); + std::cout << std::format("{:^100}\n", header_text); + std::cout << std::format("{:*>100}\n", ""); + + // Table Header + std::cout << std::format(" {:<10} {:<10} | {:>21} | {:>21} | {:>21}\n", + "Harmonic", "Detector", "Raw (x, y)", "Recentered (x, y)", "Flattened (x, y)"); + std::cout << std::format(" {:-<100}\n", ""); + + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + int n = m_harmonics[h_idx]; + + for (size_t det_idx = 0; det_idx < 3; ++det_idx) + { + std::string det_name; + if (det_idx == 0) + { + det_name = "South"; + } + else if (det_idx == 1) + { + det_name = "North"; + } + else + { + det_name = "NorthSouth"; + } - for (auto &vec : north_q) { - std::fill(vec.begin(), vec.end(), 0.); - } + const auto& raw = m_Q_raw[h_idx][det_idx]; + const auto& rec = m_Q_recentered[h_idx][det_idx]; + const auto& flat = m_Q_flat[h_idx][det_idx]; - for (auto &vec : northsouth_q) { - std::fill(vec.begin(), vec.end(), 0.); - } + std::string h_label = (det_idx == 0) ? std::format("n={}", n) : ""; + + // Groups x and y into (val, val) pairs for better scannability + std::string raw_str = std::format("({:>8.5f}, {:>8.5f})", raw.x, raw.y); + std::string rec_str = std::format("({:>8.5f}, {:>8.5f})", rec.x, rec.y); + std::string flat_str = std::format("({:>8.5f}, {:>8.5f})", flat.x, flat.y); - for (auto &order_vec : ring_q_north) { - for (auto &xy_vec : order_vec) { - std::fill(xy_vec.begin(), xy_vec.end(), 0.0); + std::cout << std::format(" {:<10} {:<10} | {:<21} | {:<21} | {:10}\n", + h_label, det_name, raw_str, rec_str, flat_str); + } + if (h_idx < m_harmonics.size() - 1) + { + std::cout << std::format(" {:.>100}\n", ""); } } + std::cout << std::format("{:*>100}\n\n", ""); +} - for (auto &order_vec : ring_q_south) { - for (auto &xy_vec : order_vec) { - std::fill(xy_vec.begin(), xy_vec.end(), 0.0); - } +int EventPlaneReco::FillNode(PHCompositeNode *topNode) +{ + EventplaneinfoMap *epmap = findNode::getClass(topNode, "EventplaneinfoMap"); + if (!epmap) + { + std::cout << PHWHERE << " EventplaneinfoMap is missing doing nothing" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; } - south_Qvec.clear(); - north_Qvec.clear(); - northsouth_Qvec.clear(); + size_t vec_size = static_cast(*std::ranges::max_element(m_harmonics)); - for (auto &ring : all_ring_Qvecs_north) { - for (auto &q : ring) { - q = {0.0, 0.0}; - } + std::vector> south_Qvec_raw(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); + std::vector> south_Qvec_recentered(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); + std::vector> south_Qvec(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); + + std::vector> north_Qvec_raw(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); + std::vector> north_Qvec_recentered(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); + std::vector> north_Qvec(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); + + std::vector> northsouth_Qvec_raw(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); + std::vector> northsouth_Qvec_recentered(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); + std::vector> northsouth_Qvec(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); + + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + int n = m_harmonics[h_idx]; + int idx = n - 1; + + // Fallback logic: Use raw if calibration failed or centrality is out of range + const auto& Q_S = (m_doNotCalib || m_doNotCalibEvent) ? m_Q_raw[h_idx][0] : m_Q_flat[h_idx][0]; + const auto& Q_N = (m_doNotCalib || m_doNotCalibEvent) ? m_Q_raw[h_idx][1] : m_Q_flat[h_idx][1]; + const auto& Q_NS = (m_doNotCalib || m_doNotCalibEvent) ? m_Q_raw[h_idx][2] : m_Q_flat[h_idx][2]; + + const auto& Q_S_raw = m_Q_raw[h_idx][0]; + const auto& Q_S_recentered = m_Q_recentered[h_idx][0]; + + const auto& Q_N_raw = m_Q_raw[h_idx][1]; + const auto& Q_N_recentered = m_Q_recentered[h_idx][1]; + + const auto& Q_NS_raw = m_Q_raw[h_idx][2]; + const auto& Q_NS_recentered = m_Q_recentered[h_idx][2]; + + // South + south_Qvec_raw[idx] = {Q_S_raw.x, Q_S_raw.y}; + south_Qvec_recentered[idx] = {Q_S_recentered.x, Q_S_recentered.y}; + south_Qvec[idx] = {Q_S.x, Q_S.y}; + + // North + north_Qvec_raw[idx] = {Q_N_raw.x, Q_N_raw.y}; + north_Qvec_recentered[idx] = {Q_N_recentered.x, Q_N_recentered.y}; + north_Qvec[idx] = {Q_N.x, Q_N.y}; + + // Combined (North + South) + northsouth_Qvec_raw[idx] = {Q_NS_raw.x, Q_NS_raw.y}; + northsouth_Qvec_recentered[idx] = {Q_NS_recentered.x, Q_NS_recentered.y}; + northsouth_Qvec[idx] = {Q_NS.x, Q_NS.y}; } - for (auto &ring : all_ring_Qvecs_south) { - for (auto &q : ring) { - q = {0.0, 0.0}; - } + // Helper lambda to fill nodes using the class's GetPsi method + auto create_and_fill = [&](const std::vector>& qvecs_raw, const std::vector>& qvecs_recentered, const std::vector>& qvecs) { + auto node = std::make_unique(); + node->set_qvector_raw(qvecs_raw); + node->set_qvector_recentered(qvecs_recentered); + node->set_qvector(qvecs); + + std::vector psi_vec(vec_size, std::numeric_limits::quiet_NaN()); + for (int n : m_harmonics) { + psi_vec[n-1] = node->GetPsi(qvecs[n-1].first, qvecs[n-1].second, n); + } + node->set_shifted_psi(psi_vec); + return node; + }; + + epmap->insert(create_and_fill(south_Qvec_raw, south_Qvec_recentered, south_Qvec).release(), EventplaneinfoMap::sEPDS); + epmap->insert(create_and_fill(north_Qvec_raw, north_Qvec_recentered, north_Qvec).release(), EventplaneinfoMap::sEPDN); + epmap->insert(create_and_fill(northsouth_Qvec_raw, northsouth_Qvec_recentered, northsouth_Qvec).release(), EventplaneinfoMap::sEPDNS); + + return Fun4AllReturnCodes::EVENT_OK; +} + +//____________________________________________________________________________.. +int EventPlaneReco::process_event(PHCompositeNode *topNode) +{ + EventHeader *eventInfo = findNode::getClass(topNode, "EventHeader"); + if (!eventInfo) + { + return Fun4AllReturnCodes::ABORTRUN; } - for (auto &vec : south_q_subtract) { - std::fill(vec.begin(), vec.end(), 0.); + m_globalEvent = eventInfo->get_EvtSequence(); + + int ret = process_centrality(topNode); + if (ret) + { + return ret; } - for (auto &vec : north_q_subtract) { - std::fill(vec.begin(), vec.end(), 0.); + ret = process_sEPD(topNode); + if (ret) + { + return ret; } - for (auto &vec : northsouth_q_subtract) { - std::fill(vec.begin(), vec.end(), 0.); + // Calibrate Q Vectors + if (!m_doNotCalib && !m_doNotCalibEvent) + { + correct_QVecs(); } - std::fill(shift_north.begin(), shift_north.end(), 0.); - std::fill(shift_south.begin(), shift_south.end(), 0.); - std::fill(shift_northsouth.begin(), shift_northsouth.end(), 0.); + ret = FillNode(topNode); + if (ret) + { + return ret; + } - std::fill(tmp_south_psi.begin(), tmp_south_psi.end(), NAN); - std::fill(tmp_north_psi.begin(), tmp_north_psi.end(), NAN); - std::fill(tmp_northsouth_psi.begin(), tmp_northsouth_psi.end(), NAN); + if (Verbosity() > 1) + { + print_QVectors(); + } - _nsum = 0.; - _ssum = 0.; - _do_ep = false; - _mbdQ = 0.; - _totalcharge = 0.; + return Fun4AllReturnCodes::EVENT_OK; } -int EventPlaneReco::End(PHCompositeNode * /*topNode*/) { +//____________________________________________________________________________.. +int EventPlaneReco::ResetEvent(PHCompositeNode */*topNode*/) +{ + m_doNotCalibEvent = false; + + m_Q_raw = {}; + m_Q_recentered = {}; + m_Q_flat = {}; - std::cout << " EventPlaneReco::End() " << std::endl; return Fun4AllReturnCodes::EVENT_OK; } diff --git a/offline/packages/eventplaneinfo/EventPlaneReco.h b/offline/packages/eventplaneinfo/EventPlaneReco.h index ce4259c95e..0f356e6033 100644 --- a/offline/packages/eventplaneinfo/EventPlaneReco.h +++ b/offline/packages/eventplaneinfo/EventPlaneReco.h @@ -1,107 +1,134 @@ -// Tell emacs that this is a C++ source -// -*- C++ -*-. #ifndef EVENTPLANEINFO_EVENTPLANERECO_H #define EVENTPLANEINFO_EVENTPLANERECO_H -//=========================================================== -/// \author Ejiro Umaka -//=========================================================== - #include -#include // for string -#include // for vector -class TProfile2D; -class TH1; +#include +#include +#include +class CDBTTree; class PHCompositeNode; -class EventPlaneReco : public SubsysReco { -public: - EventPlaneReco(const std::string &name = "EventPlaneReco"); +class EventPlaneReco : public SubsysReco +{ + public: + + explicit EventPlaneReco(const std::string &name = "EventPlaneReco"); ~EventPlaneReco() override = default; - int InitRun(PHCompositeNode *topNode) override; + + // Explicitly disable copying and moving + EventPlaneReco(const EventPlaneReco&) = delete; + EventPlaneReco& operator=(const EventPlaneReco&) = delete; + EventPlaneReco(EventPlaneReco&&) = delete; + EventPlaneReco& operator=(EventPlaneReco&&) = delete; + + /** Called during initialization. + Typically this is where you can book histograms, and e.g. + register them to Fun4AllServer (so they can be output to file + using Fun4AllServer::dumpHistos() method). + */ + int Init(PHCompositeNode *topNode) override; + + /** Called for each event. + This is where you do the real work. + */ int process_event(PHCompositeNode *topNode) override; - int End(PHCompositeNode * /*topNode*/) override; - - void ResetMe(); - void set_sepd_epreco(bool sepdEpReco) { _sepdEpReco = sepdEpReco; } - void set_mbd_epreco(bool mbdEpReco) { _mbdEpReco = mbdEpReco; } - void set_isSim(bool isSim) { _isSim = isSim; } - void set_sEPD_Mip_cut(const float e) { _epd_e = e; } - void set_sEPD_Charge_cut(const float c) { _epd_charge_min = c; } - void set_MBD_Min_Qcut(const float f) { _mbd_e = f; } - void set_MBD_Vertex_cut(const float v) { _mbd_vertex_cut = v; } - void set_Ep_orders(const unsigned int n) { m_MaxOrder = n; } - -private: - int CreateNodes(PHCompositeNode *topNode); - unsigned int m_MaxOrder{3}; - static const int nRings {16}; - - std::string FileName; - - std::vector> south_q; - std::vector> north_q; - std::vector> northsouth_q; - std::vector>> ring_q_north; - std::vector>> ring_q_south; - std::vector> south_Qvec; - std::vector> north_Qvec; - std::vector> northsouth_Qvec; - std::vector>> all_ring_Qvecs_north; - std::vector>> all_ring_Qvecs_south; - - // const int phibins{24}; - TH1* h_phi_weight_south_input{nullptr}; - TH1* h_phi_weight_north_input{nullptr}; - - // recentering utility - std::vector> south_q_subtract; - std::vector> north_q_subtract; - std::vector> northsouth_q_subtract; - - // shifting utility - std::vector shift_north; - std::vector shift_south; - std::vector shift_northsouth; - std::vector tmp_south_psi; - std::vector tmp_north_psi; - std::vector tmp_northsouth_psi; - - // recentering histograms - TProfile2D *tprof_mean_cos_north_epd_input[6]{}; - TProfile2D *tprof_mean_sin_north_epd_input[6]{}; - TProfile2D *tprof_mean_cos_south_epd_input[6]{}; - TProfile2D *tprof_mean_sin_south_epd_input[6]{}; - TProfile2D *tprof_mean_cos_northsouth_epd_input[6]{}; - TProfile2D *tprof_mean_sin_northsouth_epd_input[6]{}; - - // shifting histograms - const int _imax{12}; - TProfile2D *tprof_cos_north_epd_shift_input[6][12]{}; - TProfile2D *tprof_sin_north_epd_shift_input[6][12]{}; - TProfile2D *tprof_cos_south_epd_shift_input[6][12]{}; - TProfile2D *tprof_sin_south_epd_shift_input[6][12]{}; - TProfile2D *tprof_cos_northsouth_epd_shift_input[6][12]{}; - TProfile2D *tprof_sin_northsouth_epd_shift_input[6][12]{}; - - bool _mbdEpReco{false}; - bool _sepdEpReco{false}; - bool _isSim{false}; - bool _do_ep{false}; - - float _nsum{0.0}; - float _ssum{0.0}; - float _mbdvtx{999.0}; - float _epd_charge_min{5.0}; - float _epd_charge_max{10000.0}; - float _epd_e{10.0}; - float _mbd_e{10.0}; - float _mbdQ{0.0}; - double _totalcharge{0.0}; - float _mbd_vertex_cut{60.0}; -}; -#endif // EVENTPLANEINFO_EVENTPLANERECO_H + /// Clean up internals after each event. + int ResetEvent(PHCompositeNode *topNode) override; + + + void set_inputNode(const std::string &inputNode) + { + m_inputNode = inputNode; + } + + void set_directURL_EventPlaneCalib(const std::string &directURL_EventPlaneCalib) + { + m_directURL_EventPlaneCalib = directURL_EventPlaneCalib; + } + + void set_doAbortNoEventPlaneCalib(bool status = true) + { + m_doAbortNoEventPlaneCalib = status; + } + + void set_sepd_min_channel_charge(double sepd_min_channel_charge) + { + m_sepd_min_channel_charge = sepd_min_channel_charge; + } + + private: + + static int CreateNodes(PHCompositeNode *topNode); + + std::array, 2> calculate_flattening_matrix(double xx, double yy, double xy, int n, int cent_bin, const std::string& det_label); + void LoadCalib(); + + void print_correction_data(); + void print_QVectors(); + + int process_centrality(PHCompositeNode *topNode); + int process_sEPD(PHCompositeNode *topNode); + void correct_QVecs(); + + int FillNode(PHCompositeNode *topNode); + + std::string m_directURL_EventPlaneCalib; + bool m_doAbortNoEventPlaneCalib{false}; + bool m_doNotCalib{false}; + bool m_doNotCalibEvent{false}; + + double m_cent{0.0}; + double m_globalEvent{0}; + double m_sepd_min_channel_charge{0.2}; + + std::string m_calibName{"SEPD_EventPlaneCalib"}; + std::string m_inputNode{"TOWERINFO_CALIB_SEPD"}; + + CDBTTree *m_cdbttree {nullptr}; + + enum class Subdetector + { + S, + N, + NS + }; + + struct QVec + { + double x{0.0}; + double y{0.0}; + }; + + struct CorrectionData + { + // Averages of Qx, Qy, Qx^2, Qy^2, Qxy + QVec avg_Q{}; + double avg_Q_xx{0.0}; + double avg_Q_yy{0.0}; + double avg_Q_xy{0.0}; + + // Correction matrix + std::array, 2> X_matrix{}; + }; + + static constexpr size_t m_cent_bins {80}; + static constexpr std::array m_harmonics = {2, 3, 4}; + + // Holds all correction data + // key: [Harmonic][Cent][Subdetector] + // Harmonics {2,3,4} -> 3 elements + // Subdetectors {S,N,NS} -> 3 elements + std::array, m_cent_bins>, m_harmonics.size()> m_correction_data; + + // sEPD Q Vectors + // key: [Harmonic][Subdetector] + // Subdetectors {S,N,NS} -> 3 elements + std::array, m_harmonics.size()> m_Q_raw{}; + std::array, m_harmonics.size()> m_Q_recentered{}; + std::array, m_harmonics.size()> m_Q_flat{}; +}; +#endif diff --git a/offline/packages/eventplaneinfo/EventPlaneRecov2.cc b/offline/packages/eventplaneinfo/EventPlaneRecov2.cc deleted file mode 100644 index 2b43109734..0000000000 --- a/offline/packages/eventplaneinfo/EventPlaneRecov2.cc +++ /dev/null @@ -1,637 +0,0 @@ -#include "EventPlaneRecov2.h" - -#include "EventplaneinfoMapv1.h" -#include "Eventplaneinfov2.h" - -#include -#include -#include - -// -- Centrality -#include - -// -- sEPD -#include - -#include // for CDBTTree - -// -- event -#include - -#include - -#include - -#include -#include -#include - -// -- root includes -- -#include -#include - -// c++ includes -- -#include -#include -#include -#include -#include -#include - -//____________________________________________________________________________.. -EventPlaneRecov2::EventPlaneRecov2(const std::string &name): - SubsysReco(name) -{ -} - -//____________________________________________________________________________.. -int EventPlaneRecov2::Init(PHCompositeNode *topNode) -{ - std::string calibdir = CDBInterface::instance()->getUrl(m_calibName); - - if (!m_directURL_EventPlaneCalib.empty()) - { - m_cdbttree = new CDBTTree(m_directURL_EventPlaneCalib); - std::cout << PHWHERE << " Custom Event Plane Calib Found: " << m_directURL_EventPlaneCalib << std::endl; - } - else if (!calibdir.empty()) - { - m_cdbttree = new CDBTTree(calibdir); - std::cout << PHWHERE << " Event Plane Calib Found: " << calibdir << std::endl; - } - else if (m_doAbortNoEventPlaneCalib) - { - std::cout << PHWHERE << " Error: No Event Plane Calib Found and m_doAbortNoEventPlaneCalib is true. Aborting." << std::endl; - return Fun4AllReturnCodes::ABORTRUN; - } - else - { - std::cout << PHWHERE << " Error: No Event Plane Calib Found. Skipping Event Plane Calibrations." << std::endl; - m_doNotCalib = true; - } - - if (!m_doNotCalib) - { - LoadCalib(); - } - - if (Verbosity() > 0) - { - print_correction_data(); - } - - CreateNodes(topNode); - - return Fun4AllReturnCodes::EVENT_OK; -} - -std::array, 2> EventPlaneRecov2::calculate_flattening_matrix(double xx, double yy, double xy, int n, int cent_bin, const std::string& det_label) -{ - std::array, 2> mat{}; - - double D_arg = (xx * yy) - (xy * xy); - if (D_arg <= 0) - { - std::cout << PHWHERE << "Invalid D-term " << D_arg << " for n=" << n << ", cent bin=" << cent_bin << ", det=" << det_label << std::endl; - // Return Identity Matrix to preserve Recentered vector - mat[0][0] = 1.0; - mat[1][1] = 1.0; - return mat; - } - double D = std::sqrt(D_arg); - - double N_term = D * (xx + yy + (2 * D)); - if (N_term <= 0) - { - std::cout << PHWHERE << "Invalid N-term " << N_term << " for n=" << n << ", cent bin=" << cent_bin << ", det=" << det_label << std::endl; - // Return Identity Matrix to preserve Recentered vector - mat[0][0] = 1.0; - mat[1][1] = 1.0; - return mat; - } - double inv_sqrt_N = 1.0 / std::sqrt(N_term); - - mat[0][0] = inv_sqrt_N * (yy + D); - mat[0][1] = -inv_sqrt_N * xy; - mat[1][0] = mat[0][1]; - mat[1][1] = inv_sqrt_N * (xx + D); - return mat; -} - -//____________________________________________________________________________.. -void EventPlaneRecov2::LoadCalib() -{ - size_t south_idx = static_cast(Subdetector::S); - size_t north_idx = static_cast(Subdetector::N); - size_t ns_idx = static_cast(Subdetector::NS); - - for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) - { - int n = m_harmonics[h_idx]; - - std::string S_x_avg_name = std::format("Q_S_x_{}_avg", n); - std::string S_y_avg_name = std::format("Q_S_y_{}_avg", n); - std::string N_x_avg_name = std::format("Q_N_x_{}_avg", n); - std::string N_y_avg_name = std::format("Q_N_y_{}_avg", n); - - std::string S_xx_avg_name = std::format("Q_S_xx_{}_avg", n); - std::string S_yy_avg_name = std::format("Q_S_yy_{}_avg", n); - std::string S_xy_avg_name = std::format("Q_S_xy_{}_avg", n); - std::string N_xx_avg_name = std::format("Q_N_xx_{}_avg", n); - std::string N_yy_avg_name = std::format("Q_N_yy_{}_avg", n); - std::string N_xy_avg_name = std::format("Q_N_xy_{}_avg", n); - - std::string NS_xx_avg_name = std::format("Q_NS_xx_{}_avg", n); - std::string NS_yy_avg_name = std::format("Q_NS_yy_{}_avg", n); - std::string NS_xy_avg_name = std::format("Q_NS_xy_{}_avg", n); - - for (size_t cent_bin = 0; cent_bin < m_cent_bins; ++cent_bin) - { - int key = cent_bin; - - // South - auto& dataS = m_correction_data[h_idx][cent_bin][south_idx]; - dataS.avg_Q.x = m_cdbttree->GetDoubleValue(key, S_x_avg_name); - dataS.avg_Q.y = m_cdbttree->GetDoubleValue(key, S_y_avg_name); - - dataS.avg_Q_xx = m_cdbttree->GetDoubleValue(key, S_xx_avg_name); - dataS.avg_Q_yy = m_cdbttree->GetDoubleValue(key, S_yy_avg_name); - dataS.avg_Q_xy = m_cdbttree->GetDoubleValue(key, S_xy_avg_name); - - dataS.X_matrix = calculate_flattening_matrix(dataS.avg_Q_xx, dataS.avg_Q_yy, dataS.avg_Q_xy, n, cent_bin, "South"); - - // North - auto& dataN = m_correction_data[h_idx][cent_bin][north_idx]; - dataN.avg_Q.x = m_cdbttree->GetDoubleValue(key, N_x_avg_name); - dataN.avg_Q.y = m_cdbttree->GetDoubleValue(key, N_y_avg_name); - - dataN.avg_Q_xx = m_cdbttree->GetDoubleValue(key, N_xx_avg_name); - dataN.avg_Q_yy = m_cdbttree->GetDoubleValue(key, N_yy_avg_name); - dataN.avg_Q_xy = m_cdbttree->GetDoubleValue(key, N_xy_avg_name); - - dataN.X_matrix = calculate_flattening_matrix(dataN.avg_Q_xx, dataN.avg_Q_yy, dataN.avg_Q_xy, n, cent_bin, "North"); - - // North South - // Note: We do NOT load avg_Q (x,y) for NS because NS is recentered by summing the recentered S and N vectors. - auto& dataNS = m_correction_data[h_idx][cent_bin][ns_idx]; - - dataNS.avg_Q_xx = m_cdbttree->GetDoubleValue(key, NS_xx_avg_name); - dataNS.avg_Q_yy = m_cdbttree->GetDoubleValue(key, NS_yy_avg_name); - dataNS.avg_Q_xy = m_cdbttree->GetDoubleValue(key, NS_xy_avg_name); - - dataNS.X_matrix = calculate_flattening_matrix(dataNS.avg_Q_xx, dataNS.avg_Q_yy, dataNS.avg_Q_xy, n, cent_bin, "NorthSouth"); - } - } - delete m_cdbttree; - m_cdbttree = nullptr; -} - -//____________________________________________________________________________.. -void EventPlaneRecov2::print_correction_data() -{ - std::cout << std::format("\n{:=>60}\n", ""); - std::cout << std::format("{:^60}\n", "EVENT PLANE CORRECTION DATA SUMMARY"); - std::cout << std::format("{:=>60}\n", ""); - - // Iterate through harmonics {2, 3, 4} - for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) - { - int n = m_harmonics[h_idx]; - std::cout << std::format("\n>>> HARMONIC n = {} <<<\n", n); - - // Iterate through Centrality Bins (0-79) - for (size_t cent = 0; cent < m_cent_bins; ++cent) - { - std::cout << std::format("\n Centrality Bin: {}\n", cent); - std::cout << std::format(" {:->30}\n", ""); - - // Header with fixed column widths - std::cout << std::format(" {:<12} {:>10} {:>10} {:>10} {:>10} {:>10}\n", - "Detector", "Avg Qx", "Avg Qy", "Avg Qxx", "Avg Qyy", "Avg Qxy"); - - // Iterate through Subdetectors {S, N} - for (size_t det_idx = 0; det_idx < 3; ++det_idx) - { - std::string det_name; - if (det_idx == 0) - { - det_name = "South"; - } - else if (det_idx == 1) - { - det_name = "North"; - } - else - { - det_name = "NorthSouth"; - } - - const auto& data = m_correction_data[h_idx][cent][det_idx]; - - // For NS, Avg Qx/Qy will be 0.0 because they are not loaded from CDB. - // This is expected behavior. - std::cout << std::format(" {:<12} {:>10.6f} {:>10.6f} {:>10.6f} {:>10.6f} {:>10.6f}\n", - det_name, - data.avg_Q.x, data.avg_Q.y, - data.avg_Q_xx, data.avg_Q_yy, data.avg_Q_xy); - - // Print X-Matrix in a bracketed layout - std::cout << std::format(" X-Matrix: [ {:>8.6f}, {:>8.6f} ]\n", - data.X_matrix[0][0], data.X_matrix[0][1]); - std::cout << std::format(" [ {:>8.6f}, {:>8.6f} ]\n", - data.X_matrix[1][0], data.X_matrix[1][1]); - } - } - } - std::cout << std::format("\n{:=>60}\n", ""); -} - -int EventPlaneRecov2::CreateNodes(PHCompositeNode *topNode) { - PHNodeIterator iter(topNode); - - PHCompositeNode *dstNode = dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); - if (!dstNode) - { - std::cout << PHWHERE << "DST Node missing, doing nothing." << std::endl; - return Fun4AllReturnCodes::ABORTRUN; - } - - PHCompositeNode *globalNode = dynamic_cast(iter.findFirst("PHCompositeNode", "GLOBAL")); - if (!globalNode) - { - globalNode = new PHCompositeNode("GLOBAL"); - dstNode->addNode(globalNode); - } - - EventplaneinfoMap *eps = findNode::getClass(topNode, "EventplaneinfoMap"); - if (!eps) - { - eps = new EventplaneinfoMapv1(); - PHIODataNode *newNode = new PHIODataNode(eps , "EventplaneinfoMap", "PHObject"); - globalNode->addNode(newNode); - } - - return Fun4AllReturnCodes::EVENT_OK; -} - -//____________________________________________________________________________.. -int EventPlaneRecov2::process_centrality(PHCompositeNode *topNode) -{ - CentralityInfo* centInfo = findNode::getClass(topNode, "CentralityInfo"); - if (!centInfo) - { - std::cout << PHWHERE << " CentralityInfo is missing doing nothing" << std::endl; - return Fun4AllReturnCodes::ABORTRUN; - } - - m_cent = centInfo->get_centile(CentralityInfo::PROP::mbd_NS) * 100; - - if (!std::isfinite(m_cent) || m_cent < 0) - { - if (Verbosity() > 1) - { - std::cout << PHWHERE << " Warning Centrality is out of range. Cent: " << m_cent << ". Cannot calibrate Q vector for this event." << std::endl; - } - m_doNotCalibEvent = true; - } - - return Fun4AllReturnCodes::EVENT_OK; -} - -//____________________________________________________________________________.. -int EventPlaneRecov2::process_sEPD(PHCompositeNode* topNode) -{ - TowerInfoContainer* towerinfosEPD = findNode::getClass(topNode, m_inputNode); - if (!towerinfosEPD) - { - std::cout << PHWHERE << " TOWERINFO_CALIB_SEPD is missing doing nothing" << std::endl; - return Fun4AllReturnCodes::ABORTRUN; - } - - EpdGeom* epdgeom = findNode::getClass(topNode, "TOWERGEOM_EPD"); - if (!epdgeom) - { - std::cout << PHWHERE << " TOWERGEOM_EPD is missing doing nothing" << std::endl; - return Fun4AllReturnCodes::ABORTRUN; - } - - // sepd - unsigned int nchannels_epd = towerinfosEPD->size(); - - double sepd_total_charge_south = 0; - double sepd_total_charge_north = 0; - - for (unsigned int channel = 0; channel < nchannels_epd; ++channel) - { - TowerInfo* tower = towerinfosEPD->get_tower_at_channel(channel); - - unsigned int key = TowerInfoDefs::encode_epd(channel); - double charge = tower->get_energy(); - double phi = epdgeom->get_phi(key); - - // skip bad channels - // skip channels with very low charge - if (tower->get_isHot() || charge < m_sepd_min_channel_charge) - { - continue; - } - - // arm = 0: South - // arm = 1: North - unsigned int arm = TowerInfoDefs::get_epd_arm(key); - - // sepd charge sums - double& sepd_total_charge = (arm == 0) ? sepd_total_charge_south : sepd_total_charge_north; - - // Compute total charge for the respective sEPD arm - sepd_total_charge += charge; - - for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) - { - int n = m_harmonics[h_idx]; - QVec q_n = {charge * std::cos(n * phi), charge * std::sin(n * phi)}; - m_Q_raw[h_idx][arm].x += q_n.x; - m_Q_raw[h_idx][arm].y += q_n.y; - } - } - - // ensure both total charges are nonzero - if (sepd_total_charge_south == 0 || sepd_total_charge_north == 0) - { - if (Verbosity() > 1) - { - std::cout << PHWHERE << " Error: Total sEPD Charge is Zero: " - << "South = " << sepd_total_charge_south - << ", North = " << sepd_total_charge_north << std::endl; - } - - // ensure raw Q vec is reset - m_Q_raw = {}; - m_doNotCalibEvent = true; - return Fun4AllReturnCodes::EVENT_OK; - } - - for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) - { - m_Q_raw[h_idx][0].x /= sepd_total_charge_south; - m_Q_raw[h_idx][0].y /= sepd_total_charge_south; - - m_Q_raw[h_idx][1].x /= sepd_total_charge_north; - m_Q_raw[h_idx][1].y /= sepd_total_charge_north; - - // NEW: Calculate Raw NS (Sum of Raw S + Raw N) - m_Q_raw[h_idx][2].x = m_Q_raw[h_idx][0].x + m_Q_raw[h_idx][1].x; - m_Q_raw[h_idx][2].y = m_Q_raw[h_idx][0].y + m_Q_raw[h_idx][1].y; - } - - return Fun4AllReturnCodes::EVENT_OK; -} - -void EventPlaneRecov2::correct_QVecs() -{ - size_t cent_bin = static_cast(m_cent); - if (cent_bin >= m_cent_bins) - { - cent_bin = m_cent_bins - 1; // Clamp max - } - - size_t south_idx = static_cast(Subdetector::S); - size_t north_idx = static_cast(Subdetector::N); - size_t ns_idx = static_cast(Subdetector::NS); - - for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) - { - auto& dataS = m_correction_data[h_idx][cent_bin][south_idx]; - auto& dataN = m_correction_data[h_idx][cent_bin][north_idx]; - auto& dataNS = m_correction_data[h_idx][cent_bin][ns_idx]; - - double Q_S_x_avg = dataS.avg_Q.x; - double Q_S_y_avg = dataS.avg_Q.y; - double Q_N_x_avg = dataN.avg_Q.x; - double Q_N_y_avg = dataN.avg_Q.y; - - QVec q_S = m_Q_raw[h_idx][south_idx]; - QVec q_N = m_Q_raw[h_idx][north_idx]; - - // Apply Recentering - QVec q_S_recenter = {q_S.x - Q_S_x_avg, q_S.y - Q_S_y_avg}; - QVec q_N_recenter = {q_N.x - Q_N_x_avg, q_N.y - Q_N_y_avg}; - QVec q_NS_recenter = {q_S_recenter.x + q_N_recenter.x, q_S_recenter.y + q_N_recenter.y}; - - m_Q_recentered[h_idx][south_idx] = q_S_recenter; - m_Q_recentered[h_idx][north_idx] = q_N_recenter; - m_Q_recentered[h_idx][ns_idx] = q_NS_recenter; - - // Flattening Matrix - const auto &X_S = dataS.X_matrix; - const auto &X_N = dataN.X_matrix; - const auto &X_NS = dataNS.X_matrix; - - // Apply Flattening - double Q_S_x_flat = X_S[0][0] * q_S_recenter.x + X_S[0][1] * q_S_recenter.y; - double Q_S_y_flat = X_S[1][0] * q_S_recenter.x + X_S[1][1] * q_S_recenter.y; - double Q_N_x_flat = X_N[0][0] * q_N_recenter.x + X_N[0][1] * q_N_recenter.y; - double Q_N_y_flat = X_N[1][0] * q_N_recenter.x + X_N[1][1] * q_N_recenter.y; - - double Q_NS_x_flat = X_NS[0][0] * q_NS_recenter.x + X_NS[0][1] * q_NS_recenter.y; - double Q_NS_y_flat = X_NS[1][0] * q_NS_recenter.x + X_NS[1][1] * q_NS_recenter.y; - - QVec q_S_flat = {Q_S_x_flat, Q_S_y_flat}; - QVec q_N_flat = {Q_N_x_flat, Q_N_y_flat}; - QVec q_NS_flat = {Q_NS_x_flat, Q_NS_y_flat}; - - m_Q_flat[h_idx][south_idx] = q_S_flat; - m_Q_flat[h_idx][north_idx] = q_N_flat; - m_Q_flat[h_idx][ns_idx] = q_NS_flat; - } -} - -void EventPlaneRecov2::print_QVectors() -{ - std::string header_text = std::format("EVENT Q-VECTOR SUMMARY (Event: {}, CENTRALITY: {:.0f}%)", m_globalEvent, m_cent); - - std::cout << std::format("\n{:*>100}\n", ""); - std::cout << std::format("{:^100}\n", header_text); - std::cout << std::format("{:*>100}\n", ""); - - // Table Header - std::cout << std::format(" {:<10} {:<10} | {:>21} | {:>21} | {:>21}\n", - "Harmonic", "Detector", "Raw (x, y)", "Recentered (x, y)", "Flattened (x, y)"); - std::cout << std::format(" {:-<100}\n", ""); - - for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) - { - int n = m_harmonics[h_idx]; - - for (size_t det_idx = 0; det_idx < 3; ++det_idx) - { - std::string det_name; - if (det_idx == 0) - { - det_name = "South"; - } - else if (det_idx == 1) - { - det_name = "North"; - } - else - { - det_name = "NorthSouth"; - } - - const auto& raw = m_Q_raw[h_idx][det_idx]; - const auto& rec = m_Q_recentered[h_idx][det_idx]; - const auto& flat = m_Q_flat[h_idx][det_idx]; - - std::string h_label = (det_idx == 0) ? std::format("n={}", n) : ""; - - // Groups x and y into (val, val) pairs for better scannability - std::string raw_str = std::format("({:>8.5f}, {:>8.5f})", raw.x, raw.y); - std::string rec_str = std::format("({:>8.5f}, {:>8.5f})", rec.x, rec.y); - std::string flat_str = std::format("({:>8.5f}, {:>8.5f})", flat.x, flat.y); - - std::cout << std::format(" {:<10} {:<10} | {:<21} | {:<21} | {:10}\n", - h_label, det_name, raw_str, rec_str, flat_str); - } - if (h_idx < m_harmonics.size() - 1) - { - std::cout << std::format(" {:.>100}\n", ""); - } - } - std::cout << std::format("{:*>100}\n\n", ""); -} - -int EventPlaneRecov2::FillNode(PHCompositeNode *topNode) -{ - EventplaneinfoMap *epmap = findNode::getClass(topNode, "EventplaneinfoMap"); - if (!epmap) - { - std::cout << PHWHERE << " EventplaneinfoMap is missing doing nothing" << std::endl; - return Fun4AllReturnCodes::ABORTRUN; - } - - size_t vec_size = static_cast(*std::ranges::max_element(m_harmonics)); - - std::vector> south_Qvec_raw(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); - std::vector> south_Qvec_recentered(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); - std::vector> south_Qvec(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); - - std::vector> north_Qvec_raw(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); - std::vector> north_Qvec_recentered(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); - std::vector> north_Qvec(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); - - std::vector> northsouth_Qvec_raw(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); - std::vector> northsouth_Qvec_recentered(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); - std::vector> northsouth_Qvec(vec_size, {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}); - - for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) - { - int n = m_harmonics[h_idx]; - int idx = n - 1; - - // Fallback logic: Use raw if calibration failed or centrality is out of range - const auto& Q_S = (m_doNotCalib || m_doNotCalibEvent) ? m_Q_raw[h_idx][0] : m_Q_flat[h_idx][0]; - const auto& Q_N = (m_doNotCalib || m_doNotCalibEvent) ? m_Q_raw[h_idx][1] : m_Q_flat[h_idx][1]; - const auto& Q_NS = (m_doNotCalib || m_doNotCalibEvent) ? m_Q_raw[h_idx][2] : m_Q_flat[h_idx][2]; - - const auto& Q_S_raw = m_Q_raw[h_idx][0]; - const auto& Q_S_recentered = m_Q_recentered[h_idx][0]; - - const auto& Q_N_raw = m_Q_raw[h_idx][1]; - const auto& Q_N_recentered = m_Q_recentered[h_idx][1]; - - const auto& Q_NS_raw = m_Q_raw[h_idx][2]; - const auto& Q_NS_recentered = m_Q_recentered[h_idx][2]; - - // South - south_Qvec_raw[idx] = {Q_S_raw.x, Q_S_raw.y}; - south_Qvec_recentered[idx] = {Q_S_recentered.x, Q_S_recentered.y}; - south_Qvec[idx] = {Q_S.x, Q_S.y}; - - // North - north_Qvec_raw[idx] = {Q_N_raw.x, Q_N_raw.y}; - north_Qvec_recentered[idx] = {Q_N_recentered.x, Q_N_recentered.y}; - north_Qvec[idx] = {Q_N.x, Q_N.y}; - - // Combined (North + South) - northsouth_Qvec_raw[idx] = {Q_NS_raw.x, Q_NS_raw.y}; - northsouth_Qvec_recentered[idx] = {Q_NS_recentered.x, Q_NS_recentered.y}; - northsouth_Qvec[idx] = {Q_NS.x, Q_NS.y}; - } - - // Helper lambda to fill nodes using the class's GetPsi method - auto create_and_fill = [&](const std::vector>& qvecs_raw, const std::vector>& qvecs_recentered, const std::vector>& qvecs) { - auto node = std::make_unique(); - node->set_qvector_raw(qvecs_raw); - node->set_qvector_recentered(qvecs_recentered); - node->set_qvector(qvecs); - - std::vector psi_vec(vec_size, std::numeric_limits::quiet_NaN()); - for (int n : m_harmonics) { - psi_vec[n-1] = node->GetPsi(qvecs[n-1].first, qvecs[n-1].second, n); - } - node->set_shifted_psi(psi_vec); - return node; - }; - - epmap->insert(create_and_fill(south_Qvec_raw, south_Qvec_recentered, south_Qvec).release(), EventplaneinfoMap::sEPDS); - epmap->insert(create_and_fill(north_Qvec_raw, north_Qvec_recentered, north_Qvec).release(), EventplaneinfoMap::sEPDN); - epmap->insert(create_and_fill(northsouth_Qvec_raw, northsouth_Qvec_recentered, northsouth_Qvec).release(), EventplaneinfoMap::sEPDNS); - - return Fun4AllReturnCodes::EVENT_OK; -} - -//____________________________________________________________________________.. -int EventPlaneRecov2::process_event(PHCompositeNode *topNode) -{ - EventHeader *eventInfo = findNode::getClass(topNode, "EventHeader"); - if (!eventInfo) - { - return Fun4AllReturnCodes::ABORTRUN; - } - - m_globalEvent = eventInfo->get_EvtSequence(); - - int ret = process_centrality(topNode); - if (ret) - { - return ret; - } - - ret = process_sEPD(topNode); - if (ret) - { - return ret; - } - - // Calibrate Q Vectors - if (!m_doNotCalib && !m_doNotCalibEvent) - { - correct_QVecs(); - } - - ret = FillNode(topNode); - if (ret) - { - return ret; - } - - if (Verbosity() > 1) - { - print_QVectors(); - } - - return Fun4AllReturnCodes::EVENT_OK; -} - -//____________________________________________________________________________.. -int EventPlaneRecov2::ResetEvent(PHCompositeNode */*topNode*/) -{ - m_doNotCalibEvent = false; - - m_Q_raw = {}; - m_Q_recentered = {}; - m_Q_flat = {}; - - return Fun4AllReturnCodes::EVENT_OK; -} diff --git a/offline/packages/eventplaneinfo/EventPlaneRecov2.h b/offline/packages/eventplaneinfo/EventPlaneRecov2.h deleted file mode 100644 index 905e83b7bc..0000000000 --- a/offline/packages/eventplaneinfo/EventPlaneRecov2.h +++ /dev/null @@ -1,134 +0,0 @@ -#ifndef EVENTPLANEINFO_EVENTPLANERECOV2_H -#define EVENTPLANEINFO_EVENTPLANERECOV2_H - -#include - - -#include -#include -#include - -class CDBTTree; -class PHCompositeNode; - -class EventPlaneRecov2 : public SubsysReco -{ - public: - - explicit EventPlaneRecov2(const std::string &name = "EventPlaneRecov2"); - ~EventPlaneRecov2() override = default; - - // Explicitly disable copying and moving - EventPlaneRecov2(const EventPlaneRecov2&) = delete; - EventPlaneRecov2& operator=(const EventPlaneRecov2&) = delete; - EventPlaneRecov2(EventPlaneRecov2&&) = delete; - EventPlaneRecov2& operator=(EventPlaneRecov2&&) = delete; - - /** Called during initialization. - Typically this is where you can book histograms, and e.g. - register them to Fun4AllServer (so they can be output to file - using Fun4AllServer::dumpHistos() method). - */ - int Init(PHCompositeNode *topNode) override; - - /** Called for each event. - This is where you do the real work. - */ - int process_event(PHCompositeNode *topNode) override; - - /// Clean up internals after each event. - int ResetEvent(PHCompositeNode *topNode) override; - - - void set_inputNode(const std::string &inputNode) - { - m_inputNode = inputNode; - } - - void set_directURL_EventPlaneCalib(const std::string &directURL_EventPlaneCalib) - { - m_directURL_EventPlaneCalib = directURL_EventPlaneCalib; - } - - void set_doAbortNoEventPlaneCalib(bool status = true) - { - m_doAbortNoEventPlaneCalib = status; - } - - void set_sepd_min_channel_charge(double sepd_min_channel_charge) - { - m_sepd_min_channel_charge = sepd_min_channel_charge; - } - - private: - - static int CreateNodes(PHCompositeNode *topNode); - - std::array, 2> calculate_flattening_matrix(double xx, double yy, double xy, int n, int cent_bin, const std::string& det_label); - void LoadCalib(); - - void print_correction_data(); - void print_QVectors(); - - int process_centrality(PHCompositeNode *topNode); - int process_sEPD(PHCompositeNode *topNode); - void correct_QVecs(); - - int FillNode(PHCompositeNode *topNode); - - std::string m_directURL_EventPlaneCalib; - bool m_doAbortNoEventPlaneCalib{false}; - bool m_doNotCalib{false}; - bool m_doNotCalibEvent{false}; - - double m_cent{0.0}; - double m_globalEvent{0}; - double m_sepd_min_channel_charge{0.2}; - - std::string m_calibName{"SEPD_EventPlaneCalib"}; - std::string m_inputNode{"TOWERINFO_CALIB_SEPD"}; - - CDBTTree *m_cdbttree {nullptr}; - - enum class Subdetector - { - S, - N, - NS - }; - - struct QVec - { - double x{0.0}; - double y{0.0}; - }; - - struct CorrectionData - { - // Averages of Qx, Qy, Qx^2, Qy^2, Qxy - QVec avg_Q{}; - double avg_Q_xx{0.0}; - double avg_Q_yy{0.0}; - double avg_Q_xy{0.0}; - - // Correction matrix - std::array, 2> X_matrix{}; - }; - - static constexpr size_t m_cent_bins {80}; - static constexpr std::array m_harmonics = {2, 3, 4}; - - // Holds all correction data - // key: [Harmonic][Cent][Subdetector] - // Harmonics {2,3,4} -> 3 elements - // Subdetectors {S,N,NS} -> 3 elements - std::array, m_cent_bins>, m_harmonics.size()> m_correction_data; - - // sEPD Q Vectors - // key: [Harmonic][Subdetector] - // Subdetectors {S,N,NS} -> 3 elements - std::array, m_harmonics.size()> m_Q_raw{}; - std::array, m_harmonics.size()> m_Q_recentered{}; - std::array, m_harmonics.size()> m_Q_flat{}; -}; -#endif diff --git a/offline/packages/eventplaneinfo/Makefile.am b/offline/packages/eventplaneinfo/Makefile.am index 786a285bee..188447cd06 100644 --- a/offline/packages/eventplaneinfo/Makefile.am +++ b/offline/packages/eventplaneinfo/Makefile.am @@ -29,14 +29,12 @@ libeventplaneinfo_la_LIBADD = \ -lglobalvertex_io pkginclude_HEADERS = \ - EventPlaneCalibration.h \ Eventplaneinfo.h \ Eventplaneinfov1.h \ Eventplaneinfov2.h \ EventplaneinfoMap.h \ EventplaneinfoMapv1.h \ - EventPlaneReco.h \ - EventPlaneRecov2.h + EventPlaneReco.h ROOTDICTS = \ Eventplaneinfo_Dict.cc \ @@ -58,9 +56,7 @@ libeventplaneinfo_io_la_SOURCES = \ EventplaneinfoMapv1.cc libeventplaneinfo_la_SOURCES = \ - EventPlaneCalibration.cc \ - EventPlaneReco.cc \ - EventPlaneRecov2.cc + EventPlaneReco.cc # Rule for generating table CINT dictionaries. %_Dict.cc: %.h %LinkDef.h From 47961e58413a0b65324c07a8df95d88aca56d356 Mon Sep 17 00:00:00 2001 From: "Blair D. Seidlitz" Date: Mon, 2 Mar 2026 00:02:34 -0500 Subject: [PATCH 301/393] changing majic param, will improve code later --- offline/packages/CaloReco/CaloWaveformFitting.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/CaloReco/CaloWaveformFitting.cc b/offline/packages/CaloReco/CaloWaveformFitting.cc index 3ea4e36cf1..341860c754 100644 --- a/offline/packages/CaloReco/CaloWaveformFitting.cc +++ b/offline/packages/CaloReco/CaloWaveformFitting.cc @@ -920,7 +920,7 @@ std::vector> CaloWaveformFitting::calo_processing_funcfit(con f.SetParLimits(3, 0.5, 4.0); f.SetParLimits(4, pedestal-500, pedestal+500); - f.FixParameter(2, 0.2); + f.FixParameter(2, 0.1); TFitResultPtr fitres = h.Fit(&f, "SQRN0W", "", 0, nsamples); From 5f88c000295f34eec8dcb565ea43d8240f6079b9 Mon Sep 17 00:00:00 2001 From: Anthony Denis Frawley Date: Mon, 2 Mar 2026 14:37:35 -0500 Subject: [PATCH 302/393] Remove diagnostic outputs --- .../KshortReconstruction.cc | 83 +------------------ 1 file changed, 1 insertion(+), 82 deletions(-) diff --git a/offline/packages/TrackingDiagnostics/KshortReconstruction.cc b/offline/packages/TrackingDiagnostics/KshortReconstruction.cc index 6676d64c9e..f197a3172e 100644 --- a/offline/packages/TrackingDiagnostics/KshortReconstruction.cc +++ b/offline/packages/TrackingDiagnostics/KshortReconstruction.cc @@ -125,7 +125,7 @@ int KshortReconstruction::process_event(PHCompositeNode* topNode) Acts::Vector3 dcaVals1 = calculateDca(tr1, mom1, pos1); if (fabs(dcaVals1(0)) < this_dca_cut || fabs(dcaVals1(1)) < this_dca_cut) { - std::cout << " tr1 failed dca cuts " << std::endl; + // std::cout << " tr1 failed dca cuts " << std::endl; continue; } // look for close DCA matches with all other such tracks @@ -134,35 +134,17 @@ int KshortReconstruction::process_event(PHCompositeNode* topNode) auto id2 = tr2_it->first; auto *tr2 = tr2_it->second; - bool diag = false; - // dca xy and dca z cut here compare to track dca cut Acts::Vector3 pos2(tr2->get_x(), tr2->get_y(), tr2->get_z()); Acts::Vector3 mom2(tr2->get_px(), tr2->get_py(), tr2->get_pz()); Acts::Vector3 dcaVals2 = calculateDca(tr2, mom2, pos2); - if( fabs(1.0 - std::tan(dcaVals1(2))) < 0.1 && abs(dcaVals2(2)-dcaVals1(2)) < 0.1 ) - { - // diag = true; - // std::cout << "*** Found phi values of interest " << std::endl; - } - if(diag) { std::cout << " tr1: id, dca3dxy1,dca3dz1,phi1: " << tr1->get_id() << " " << dcaVals1(0) << " " << dcaVals1(1) << " " << dcaVals1(2) << std::endl; } - if(diag) { std::cout << " tr2: id,dca3dxy2,dca3dz2,phi2: " << tr2->get_id() << " " << dcaVals2(0) << " " << dcaVals2(1) << " " << dcaVals2(2) << std::endl; } - if (tr2->get_quality() > _qual_cut) { - if(diag) - { - std::cout << " tr2 failed quality cut " << tr2->get_quality() << std::endl; - } continue; } if (tr2->get_pt() < track_pt_cut) { - if(diag) - { - std::cout << " tr2 failed pT cut " << tr2->get_pt() << std::endl; - } continue; } @@ -182,10 +164,6 @@ int KshortReconstruction::process_event(PHCompositeNode* topNode) } if (_require_mvtx) { - if(diag) - { - std::cout << " tr2 failed mvtx cut " << std::endl; - } continue; } } @@ -224,10 +202,6 @@ int KshortReconstruction::process_event(PHCompositeNode* topNode) if (fabs(dcaVals2(0)) < this_dca_cut2 || fabs(dcaVals2(1)) < this_dca_cut2) { - if(diag) - { - std::cout << " tr2 failed dca cut " << std::endl; - } continue; } @@ -256,7 +230,6 @@ int KshortReconstruction::process_event(PHCompositeNode* topNode) // This presently assumes straight line tracks to get a rough answer // Should update to use circles instead? findPcaTwoTracks(pos1, pos2, mom1, mom2, pca_rel1, pca_rel2, pair_dca); - if(diag) { std::cout << " pair dca " << pair_dca << " pca_rel1 " << pca_rel1(0) << " " << pca_rel1(1) << " " << pca_rel1(2) << std::endl; } // tracks with small relative pca are k short candidates if (abs(pair_dca) < pair_dca_cut) { @@ -303,12 +276,6 @@ int KshortReconstruction::process_event(PHCompositeNode* topNode) fillHistogram(projected_mom1, projected_mom2, recomass, invariantMass, invariantPt, invariantPhi, rapidity, pseudorapidity,decaymassa, decaymassb); fillNtp(tr1, tr2, decaymassa, decaymassb, dcaVals1, dcaVals2, pca_rel1, pca_rel2, pair_dca, invariantMass, invariantPt, invariantPhi, rapidity, pseudorapidity, projected_pos1, projected_pos2, projected_mom1, projected_mom2, pca_rel1_proj, pca_rel2_proj, pair_dca_proj, track1_silicon_cluster_size, track2_silicon_cluster_size, track1_mvtx_cluster_size, track1_mvtx_state_size, track1_intt_cluster_size, track1_intt_state_size, track2_mvtx_cluster_size, track2_mvtx_state_size, track2_intt_cluster_size, track2_intt_state_size, m_runNumber, m_evtNumber); - if(diag) - { - std::cout << "Accepted Track Pair" << " id1 " << id1 << " id2 " << id2 << " crossing1 " << crossing1 << " crossing2 " << crossing2 << std::endl; - std::cout << " invariant mass: " << invariantMass << " decaymassa " << decaymassa << " decaymassb " << decaymassb << std::endl; - } - if (Verbosity() > 1) { std::cout << "Accepted Track Pair" << " id1 " << id1 << " id2 " << id2 << " crossing1 " << crossing1 << " crossing2 " << crossing2 << std::endl; @@ -509,40 +476,6 @@ void KshortReconstruction::fillHistogram(Eigen::Vector3d mom1, Eigen::Vector3d m } } -/* - -void KshortReconstruction::fillHistogram(Eigen::Vector3d mom1, Eigen::Vector3d mom2, TH1* massreco, double& invariantMass, double& invariantPt, float& invariantPhi, float& rapidity, float& pseudorapidity) -{ - double E1 = sqrt(pow(mom1(0), 2) + pow(mom1(1), 2) + pow(mom1(2), 2) + pow(decaymass, 2)); - double E2 = sqrt(pow(mom2(0), 2) + pow(mom2(1), 2) + pow(mom2(2), 2) + pow(decaymass, 2)); - - TLorentzVector v1(mom1(0), mom1(1), mom1(2), E1); - TLorentzVector v2(mom2(0), mom2(1), mom2(2), E2); - - TLorentzVector tsum; - tsum = v1 + v2; - - rapidity = tsum.Rapidity(); - pseudorapidity = tsum.Eta(); - invariantMass = tsum.M(); - invariantPt = tsum.Pt(); - invariantPhi = tsum.Phi(); - - if (Verbosity() > 2) - { - std::cout << "px1: " << mom1(0) << " py1: " << mom1(1) << " pz1: " << mom1(2) << " E1: " << E1 << std::endl; - std::cout << "px2: " << mom2(0) << " py2: " << mom2(1) << " pz2: " << mom2(2) << " E2: " << E2 << std::endl; - std::cout << "tsum: " << tsum(0) << " " << tsum(1) << " " << tsum(2) << " " << tsum(3) << std::endl; - std::cout << "invariant mass: " << invariantMass << " invariant Pt: " << invariantPt << " invariantPhi: " << invariantPhi << std::endl; - } - - if (invariantPt > invariant_pt_cut) - { - massreco->Fill(invariantMass); - } -} -*/ - bool KshortReconstruction::projectTrackToPoint(SvtxTrack* track, Eigen::Vector3d PCA, Eigen::Vector3d& pos, Eigen::Vector3d& mom) { bool ret = true; @@ -792,13 +725,6 @@ KshortReconstruction::KshortReconstruction(const std::string& name) Acts::Vector3 KshortReconstruction::calculateDca(SvtxTrack* track, const Acts::Vector3& momentum, Acts::Vector3 position) { - - /* - std::cout << " Input: pos(0) " << position(0) << " pos(1) " << position(1) << " pos(2) " << position(2) - << " mom(0) " << momentum(0) << " mom(1) " << momentum(1) << " mom(2) " << momentum(2) - << std::endl; - */ - // For the purposes of this module, we set default values to prevent this track from being rejected if the dca calc fails Acts::Vector3 r = momentum.cross(Acts::Vector3(0., 0., 1.)); float phi = std::atan2(r(1), r(0)); @@ -836,13 +762,6 @@ Acts::Vector3 KshortReconstruction::calculateDca(SvtxTrack* track, const Acts::V outVals(0) = abs(dca3dxy); outVals(1) = abs(dca3dz); outVals(2) = phi; - /* - std::cout << " calculateDca: dca3dxy " << outVals(0) << " dca3dz " << outVals(1) << " phi " << outVals(2) << std::endl - << " vertex(0) " << vertex(0) << " vertex(1) " << vertex(1) << " vertex(2) " << vertex(2) << std::endl - << " position(0) " << position(0) << " position(1) " << position(1) << " position(2) " << position(2) << std::endl - << " momentum(0) " << momentum(0) << " momentum(1) " << momentum(1) << " momentum(2) " << momentum(2) - << std::endl; - */ if (Verbosity() > 4) { From 37a1689869c7e090405ac006c98da4e2261498fe Mon Sep 17 00:00:00 2001 From: mchiu-bnl Date: Mon, 2 Mar 2026 15:10:51 -0500 Subject: [PATCH 303/393] added fit info --- offline/packages/mbd/Makefile.am | 16 +++- offline/packages/mbd/MbdRawContainerV2.cc | 64 ++++++++++++++ offline/packages/mbd/MbdRawContainerV2.h | 79 +++++++++++++++++ .../packages/mbd/MbdRawContainerV2LinkDef.h | 5 ++ offline/packages/mbd/MbdRawHit.h | 23 +++++ offline/packages/mbd/MbdRawHitV2.cc | 23 +++++ offline/packages/mbd/MbdRawHitV2.h | 88 +++++++++++++++++++ offline/packages/mbd/MbdRawHitV2LinkDef.h | 5 ++ 8 files changed, 301 insertions(+), 2 deletions(-) create mode 100644 offline/packages/mbd/MbdRawContainerV2.cc create mode 100644 offline/packages/mbd/MbdRawContainerV2.h create mode 100644 offline/packages/mbd/MbdRawContainerV2LinkDef.h create mode 100644 offline/packages/mbd/MbdRawHitV2.cc create mode 100644 offline/packages/mbd/MbdRawHitV2.h create mode 100644 offline/packages/mbd/MbdRawHitV2LinkDef.h diff --git a/offline/packages/mbd/Makefile.am b/offline/packages/mbd/Makefile.am index 111f9b31df..be588c0adb 100644 --- a/offline/packages/mbd/Makefile.am +++ b/offline/packages/mbd/Makefile.am @@ -49,8 +49,10 @@ pkginclude_HEADERS = \ MbdPmtHitV1.h \ MbdRawContainer.h \ MbdRawContainerV1.h \ + MbdRawContainerV2.h \ MbdRawHit.h \ MbdRawHitV1.h \ + MbdRawHitV2.h \ MbdReturnCodes.h \ MbdRunningStats.h \ MbdCalib.h \ @@ -70,8 +72,10 @@ pkginclude_HEADERS = \ MbdPmtSimHitV1.h \ MbdRawContainer.h \ MbdRawContainerV1.h \ + MbdRawContainerV2.h \ MbdRawHit.h \ MbdRawHitV1.h \ + MbdRawHitV2.h \ MbdRunningStats.h \ MbdSig.h \ MbdEvent.h \ @@ -97,8 +101,10 @@ ROOTDICTS = \ MbdPmtHitV1_Dict.cc \ MbdRawContainer_Dict.cc \ MbdRawContainerV1_Dict.cc \ + MbdRawContainerV2_Dict.cc \ MbdRawHit_Dict.cc \ - MbdRawHitV1_Dict.cc + MbdRawHitV1_Dict.cc \ + MbdRawHitV2_Dict.cc else ROOTDICTS = \ @@ -116,8 +122,10 @@ ROOTDICTS = \ MbdPmtSimContainerV1_Dict.cc \ MbdRawHit_Dict.cc \ MbdRawHitV1_Dict.cc \ + MbdRawHitV2_Dict.cc \ MbdRawContainer_Dict.cc \ - MbdRawContainerV1_Dict.cc + MbdRawContainerV1_Dict.cc \ + MbdRawContainerV2_Dict.cc endif pcmdir = $(libdir) @@ -138,8 +146,10 @@ libmbd_io_la_SOURCES = \ MbdPmtContainerV1.cc \ MbdRawHit.cc \ MbdRawHitV1.cc \ + MbdRawHitV2.cc \ MbdRawContainer.cc \ MbdRawContainerV1.cc \ + MbdRawContainerV2.cc \ MbdRunningStats.cc \ MbdCalib.cc \ MbdSig.cc @@ -160,8 +170,10 @@ libmbd_io_la_SOURCES = \ MbdPmtSimContainerV1.cc \ MbdRawHit.cc \ MbdRawHitV1.cc \ + MbdRawHitV2.cc \ MbdRawContainer.cc \ MbdRawContainerV1.cc \ + MbdRawContainerV2.cc \ MbdRunningStats.cc \ MbdSig.cc diff --git a/offline/packages/mbd/MbdRawContainerV2.cc b/offline/packages/mbd/MbdRawContainerV2.cc new file mode 100644 index 0000000000..9b7236de4a --- /dev/null +++ b/offline/packages/mbd/MbdRawContainerV2.cc @@ -0,0 +1,64 @@ +#include "MbdRawContainerV2.h" +#include "MbdRawHitV2.h" +#include "MbdReturnCodes.h" +#include "MbdDefs.h" + +#include + +#include + +MbdRawContainerV2::MbdRawContainerV2() : MbdRawHits(new TClonesArray("MbdRawHitV2", MbdDefs::MBD_N_PMT)) +{ + // MbdRawHit is class for single hit (members: pmt,adc,ttdc,qtdc), do not mix + // with TClonesArray *MbdRawHits + +} + +MbdRawContainerV2::~MbdRawContainerV2() +{ + delete MbdRawHits; +} + +int MbdRawContainerV2::isValid() const +{ + if (npmt <= 0) + { + return 0; + } + return 1; +} + +void MbdRawContainerV2::Reset() +{ + MbdRawHits->Clear(); + npmt = 0; +} + +void MbdRawContainerV2::identify(std::ostream &out) const +{ + out << "identify yourself: I am a MbdRawContainerV2 object" << std::endl; +} + +//______________________________________ +void MbdRawContainerV2::set_clocks(const Int_t ievt, const UShort_t iclk, const UShort_t ifemclk) +{ + evt = ievt; + clk = iclk; + femclk = ifemclk; +} + +Int_t MbdRawContainerV2::get_evt() const +{ + return evt; +} + +UShort_t MbdRawContainerV2::get_clock() const +{ + return clk; +} + +UShort_t MbdRawContainerV2::get_femclock() const +{ + return femclk; +} + diff --git a/offline/packages/mbd/MbdRawContainerV2.h b/offline/packages/mbd/MbdRawContainerV2.h new file mode 100644 index 0000000000..1b028863ea --- /dev/null +++ b/offline/packages/mbd/MbdRawContainerV2.h @@ -0,0 +1,79 @@ +#ifndef MBD_MBDRAWCONTAINERV2_H__ +#define MBD_MBDRAWCONTAINERV2_H__ + +#include "MbdRawContainer.h" + +#include + +#include + +/// +class MbdRawContainerV2 : public MbdRawContainer +{ +public: + /// ctor + MbdRawContainerV2(); + + /// dtor + virtual ~MbdRawContainerV2(); + + /// Clear Event + void Reset() override; + + /** identify Function from PHObject + @param os Output Stream + */ + void identify(std::ostream &out = std::cout) const override; + + /// isValid returns non zero if object contains vailid data + int isValid() const override; + + /** Add Mbd data containing evt, clk, and femclk + @param ievt Event number + @param iclk XMIT clock + @param ifemclk FEM clock + */ + virtual void set_clocks(const Int_t ievt, const UShort_t iclk, const UShort_t ifemclk) override; + + /** get Event Number + */ + virtual Int_t get_evt() const override; + + /** get XMIT Clock Counter + */ + virtual UShort_t get_clock() const override; + + /** get FEM Clock Counter + */ + virtual UShort_t get_femclock() const override; + + /** set number of pmts for Mbd + @param ival Number of Mbd Pmt's + */ + void set_npmt(const Short_t ival) override + { + npmt = ival; + return; + } + + /// get Number of Mbd Pmt's + Short_t get_npmt() const override { return MbdRawHits->GetEntries(); } + + /** get MbdRawPmt of Pmt iPmt in TClonesArray + @param iPmt no of Pmt in TClonesArray + */ + MbdRawHit *get_pmt(const int iPmt) const override { return (MbdRawHit*)MbdRawHits->ConstructedAt(iPmt); } + +private: + TClonesArray *GetMbdRawHits() const { return MbdRawHits; } + + Int_t evt{-1}; + UShort_t clk{0}; + UShort_t femclk{0}; + Short_t npmt = 0; + TClonesArray *MbdRawHits = nullptr; + + ClassDefOverride(MbdRawContainerV2, 1) +}; + +#endif diff --git a/offline/packages/mbd/MbdRawContainerV2LinkDef.h b/offline/packages/mbd/MbdRawContainerV2LinkDef.h new file mode 100644 index 0000000000..2c3bf0df5d --- /dev/null +++ b/offline/packages/mbd/MbdRawContainerV2LinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class MbdRawContainerV2 + ; + +#endif diff --git a/offline/packages/mbd/MbdRawHit.h b/offline/packages/mbd/MbdRawHit.h index 45bd089d5b..d0818e0a30 100644 --- a/offline/packages/mbd/MbdRawHit.h +++ b/offline/packages/mbd/MbdRawHit.h @@ -40,11 +40,34 @@ class MbdRawHit : public PHObject return MbdReturnCodes::MBD_INVALID_FLOAT; } + virtual Float_t get_chi2ndf() const + { + PHOOL_VIRTUAL_WARNING; + return MbdReturnCodes::MBD_INVALID_FLOAT; + } + + virtual UShort_t get_fitinfo() const + { + PHOOL_VIRTUAL_WARNING; + //return MbdReturnCodes::MBD_INVALID_USHORT; + return 0; //chiu + } + virtual void set_pmt(const Short_t /*pmt*/, const Float_t /*adc*/, const Float_t /*ttdc*/, const Float_t /*qtdc*/) { PHOOL_VIRTUAL_WARNING; } + virtual void set_chi2ndf(const Double_t /*chi2ndf*/) + { + PHOOL_VIRTUAL_WARNING; + } + + virtual void set_fitinfo(const UShort_t /*fitinfo*/) + { + PHOOL_VIRTUAL_WARNING; + } + virtual void identify(std::ostream& out = std::cout) const override; virtual int isValid() const override { return 0; } diff --git a/offline/packages/mbd/MbdRawHitV2.cc b/offline/packages/mbd/MbdRawHitV2.cc new file mode 100644 index 0000000000..2f4b6ca5bc --- /dev/null +++ b/offline/packages/mbd/MbdRawHitV2.cc @@ -0,0 +1,23 @@ +#include "MbdRawHitV2.h" + +void MbdRawHitV2::Reset() +{ + Clear(); +} + +void MbdRawHitV2::Clear(Option_t* /*unused*/) +{ + std::cout << "clearing " << bpmt << std::endl; + bpmt = -1; + fitstat = 0; + badc = std::numeric_limits::quiet_NaN(); + bttdc = std::numeric_limits::quiet_NaN(); + bqtdc = std::numeric_limits::quiet_NaN(); +} + +void MbdRawHitV2::identify(std::ostream& out) const +{ + out << "identify yourself: I am a MbdRawHitV2 object" << std::endl; + out << "Pmt: " << bpmt << ", adc: " << badc << ", ttdc: " + << bttdc << ", bqtdc: " << bqtdc << std::endl; +} diff --git a/offline/packages/mbd/MbdRawHitV2.h b/offline/packages/mbd/MbdRawHitV2.h new file mode 100644 index 0000000000..61e57fd6be --- /dev/null +++ b/offline/packages/mbd/MbdRawHitV2.h @@ -0,0 +1,88 @@ +#ifndef __MBD_MBDRAWHITV2_H__ +#define __MBD_MBDRAWHITV2_H__ + +#include "MbdRawHit.h" + +#include +#include +#include + +class MbdRawHitV2 : public MbdRawHit +{ + public: + MbdRawHitV2() = default; + ~MbdRawHitV2() override = default; + + //! Just does a clear + void Reset() override; + + //! Clear is used by TClonesArray to reset the tower to initial state without calling destructor/constructor + void Clear(Option_t* = "") override; + + //! PMT number + Short_t get_pmt() const override { return bpmt; } + + //! ADC + Float_t get_adc() const override { return badc; } + + //! TDC from time channel + Float_t get_ttdc() const override { return bttdc; } + + //! TDC from charge channel + Float_t get_qtdc() const override { return bqtdc; } + + //! Chi2/NDF from charge channel waveform fit + Float_t get_chi2ndf() const override { return (fitstat&0xfff)/100.; } + + //! Info about charge channel waveform fit + UShort_t get_fitinfo() const override { return (fitstat>>12); } + + //! Set PMT data values + void set_pmt(const Short_t pmt, const Float_t a, const Float_t tt, const Float_t tq) override + { + bpmt = pmt; + badc = a; + bttdc = tt; + bqtdc = tq; + } + + //! Store chi2/ndf (encoded in fitstat) + void set_chi2ndf(const Double_t chi2ndf) override + { + unsigned short us_chi2ndf = static_cast( chi2ndf*100. ); + if ( chi2ndf>40.95 ) + { + us_chi2ndf = 4095; + } + fitstat &= 0xf000; + fitstat |= us_chi2ndf; + } + + //! Store fitinfo (encoded in fitstat) + void set_fitinfo(const UShort_t fitinfo) override + { + fitstat &= 0xfff; + fitstat |= (fitinfo<<12); + } + + //! Prints out exact identity of object + void identify(std::ostream& out = std::cout) const override; + + //! isValid returns non zero if object contains valid data + virtual int isValid() const override + { + if (std::isnan(get_ttdc())) return 0; + return 1; + } + + private: + Short_t bpmt; + UShort_t fitstat; //waveform fit status + Float_t badc; + Float_t bttdc; + Float_t bqtdc; + + ClassDefOverride(MbdRawHitV2, 1) +}; + +#endif diff --git a/offline/packages/mbd/MbdRawHitV2LinkDef.h b/offline/packages/mbd/MbdRawHitV2LinkDef.h new file mode 100644 index 0000000000..8936852bfe --- /dev/null +++ b/offline/packages/mbd/MbdRawHitV2LinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class MbdRawHitV2 + ; + +#endif From 6e6503f5c5261d3b311e0464287d2133361c2d98 Mon Sep 17 00:00:00 2001 From: mchiu-bnl Date: Mon, 2 Mar 2026 16:23:39 -0500 Subject: [PATCH 304/393] added info on waveform fit to RawHit output object, added refits to waveforms to check for better alternative fit --- offline/packages/mbd/MbdCalib.cc | 55 +++--- offline/packages/mbd/MbdEvent.cc | 18 +- offline/packages/mbd/MbdRawHit.h | 3 +- offline/packages/mbd/MbdReco.cc | 4 +- offline/packages/mbd/MbdReturnCodes.h | 5 +- offline/packages/mbd/MbdSig.cc | 234 +++++++++++++++++--------- offline/packages/mbd/MbdSig.h | 10 +- 7 files changed, 212 insertions(+), 117 deletions(-) diff --git a/offline/packages/mbd/MbdCalib.cc b/offline/packages/mbd/MbdCalib.cc index 578fead8ac..82d87b7671 100644 --- a/offline/packages/mbd/MbdCalib.cc +++ b/offline/packages/mbd/MbdCalib.cc @@ -79,13 +79,7 @@ int MbdCalib::Download_All() // if rc flag MBD_CALDIR does not exist, we create it and set it to an empty string if (!_rc->FlagExist("MBD_CALDIR")) { - std::string sampmax_url = _cdb->getUrl("MBD_SAMPMAX"); - if (Verbosity() > 0) - { - std::cout << "sampmax_url " << sampmax_url << std::endl; - } - Download_SampMax(sampmax_url); - + // Always load Status std::string status_url = _cdb->getUrl("MBD_STATUS"); if ( ! status_url.empty() ) { @@ -99,6 +93,14 @@ int MbdCalib::Download_All() if ( !_rawdstflag ) { + // sampmax and ped will be calculated on the fly if calibs don't exist + std::string sampmax_url = _cdb->getUrl("MBD_SAMPMAX"); + if (Verbosity() > 0) + { + std::cout << "sampmax_url " << sampmax_url << std::endl; + } + Download_SampMax(sampmax_url); + std::string ped_url = _cdb->getUrl("MBD_PED"); if (Verbosity() > 0) { @@ -106,7 +108,6 @@ int MbdCalib::Download_All() } Download_Ped(ped_url); - std::string pileup_url = _cdb->getUrl("MBD_PILEUP"); if ( pileup_url.empty() ) { @@ -135,29 +136,29 @@ int MbdCalib::Download_All() } } - std::string qfit_url = _cdb->getUrl("MBD_QFIT"); - if (Verbosity() > 0) + if ( !_fitsonly ) { - std::cout << "qfit_url " << qfit_url << std::endl; - } - Download_Gains(qfit_url); + std::string qfit_url = _cdb->getUrl("MBD_QFIT"); + if (Verbosity() > 0) + { + std::cout << "qfit_url " << qfit_url << std::endl; + } + Download_Gains(qfit_url); - std::string tt_t0_url = _cdb->getUrl("MBD_TT_T0"); - if ( Verbosity() > 0 ) - { - std::cout << "tt_t0_url " << tt_t0_url << std::endl; - } - Download_TTT0(tt_t0_url); + std::string tt_t0_url = _cdb->getUrl("MBD_TT_T0"); + if ( Verbosity() > 0 ) + { + std::cout << "tt_t0_url " << tt_t0_url << std::endl; + } + Download_TTT0(tt_t0_url); - std::string tq_t0_url = _cdb->getUrl("MBD_TQ_T0"); - if (Verbosity() > 0) - { - std::cout << "tq_t0_url " << tq_t0_url << std::endl; - } - Download_TQT0(tq_t0_url); + std::string tq_t0_url = _cdb->getUrl("MBD_TQ_T0"); + if (Verbosity() > 0) + { + std::cout << "tq_t0_url " << tq_t0_url << std::endl; + } + Download_TQT0(tq_t0_url); - if ( !_fitsonly ) - { std::string t0corr_url = _cdb->getUrl("MBD_T0CORR"); if ( Verbosity() > 0 ) { diff --git a/offline/packages/mbd/MbdEvent.cc b/offline/packages/mbd/MbdEvent.cc index e5ae966587..b97d750f29 100644 --- a/offline/packages/mbd/MbdEvent.cc +++ b/offline/packages/mbd/MbdEvent.cc @@ -156,7 +156,7 @@ int MbdEvent::InitRun() { // Download calibrations int status = _mbdcal->Download_All(); - if ( status < 0 && _calpass==0 ) // only abort for normal processing + if ( status < 0 && _calpass==0 && _fitsonly ) // only abort for production waveform pass { return Fun4AllReturnCodes::ABORTRUN; } @@ -444,13 +444,18 @@ int MbdEvent::SetRawData(std::array< CaloPacket *,2> &dstp, MbdRawContainer *bbc return Fun4AllReturnCodes::DISCARDEVENT; } + int evtseq = 0; + if ( gl1raw != nullptr ) + { + evtseq = gl1raw->getEvtSequence(); + } + // Only use MBDNS triggered events for MBD calibrations if ( _calpass>0 && gl1raw != nullptr ) { const uint64_t MBDTRIGS = 0x7c00; // MBDNS trigger bits //uint64_t trigvec = gl1raw->getTriggerVector(); // raw trigger only (obsolete, was only available in run1) uint64_t strig = gl1raw->getScaledVector(); // scaled trigger only - int evtseq = gl1raw->getEvtSequence(); if ( Verbosity() ) { static int counter = 0; @@ -528,6 +533,7 @@ int MbdEvent::SetRawData(std::array< CaloPacket *,2> &dstp, MbdRawContainer *bbc if ( _nsamples > 0 && _nsamples <= 30 ) { _mbdsig[feech].SetXY(m_samp[feech], m_adc[feech]); + _mbdsig[feech].SetEvtNum( evtseq ); } /* else @@ -658,6 +664,7 @@ int MbdEvent::SetRawData(Event *event, MbdRawContainer *bbcraws, MbdPmtContainer _mbdsig[feech].SetNSamples( _nsamples ); _mbdsig[feech].SetXY(m_samp[feech], m_adc[feech]); + _mbdsig[feech].SetEvtNum( m_evt ); //_mbdsig[feech].Print(); } @@ -760,7 +767,7 @@ int MbdEvent::ProcessPackets(MbdRawContainer *bbcraws) m_ampl[ifeech] = _mbdsig[ifeech].GetAmpl(); // in adc units if (do_templatefit) { - //std::cout << "fittemplate" << std::endl; + //std::cout << "fittemplate " << ifeech << std::endl; _mbdsig[ifeech].FitTemplate( _mbdcal->get_sampmax(ifeech) ); /* @@ -784,6 +791,8 @@ int MbdEvent::ProcessPackets(MbdRawContainer *bbcraws) { int feech = _mbdgeom->get_feech(ipmt); bbcraws->get_pmt(ipmt)->set_pmt(ipmt, m_ampl[feech], m_ttdc[ipmt], m_qtdc[ipmt]); + bbcraws->get_pmt(ipmt)->set_chi2ndf( _mbdsig[feech].GetChi2NDF() ); + bbcraws->get_pmt(ipmt)->set_fitinfo( _mbdsig[feech].GetFitInfo() ); } bbcraws->set_npmt(MbdDefs::BBC_N_PMT); // this would need to be changed if we zero-suppressed bbcraws->set_clocks(m_evt, m_clk, m_femclk); @@ -901,7 +910,10 @@ int MbdEvent::ProcessRawContainer(MbdRawContainer *bbcraws, MbdPmtContainer *bbc // Copy to output for (int ipmt = 0; ipmt < MbdDefs::BBC_N_PMT; ipmt++) { + int feech = _mbdgeom->get_feech(ipmt); bbcpmts->get_pmt(ipmt)->set_pmt(ipmt, m_pmtq[ipmt], m_pmttt[ipmt], m_pmttq[ipmt]); + bbcraws->get_pmt(ipmt)->set_chi2ndf( _mbdsig[feech].GetChi2NDF() ); + bbcraws->get_pmt(ipmt)->set_fitinfo( _mbdsig[feech].GetFitInfo() ); } bbcpmts->set_npmt(MbdDefs::BBC_N_PMT); diff --git a/offline/packages/mbd/MbdRawHit.h b/offline/packages/mbd/MbdRawHit.h index d0818e0a30..510a68b32f 100644 --- a/offline/packages/mbd/MbdRawHit.h +++ b/offline/packages/mbd/MbdRawHit.h @@ -49,8 +49,7 @@ class MbdRawHit : public PHObject virtual UShort_t get_fitinfo() const { PHOOL_VIRTUAL_WARNING; - //return MbdReturnCodes::MBD_INVALID_USHORT; - return 0; //chiu + return 0; } virtual void set_pmt(const Short_t /*pmt*/, const Float_t /*adc*/, const Float_t /*ttdc*/, const Float_t /*qtdc*/) diff --git a/offline/packages/mbd/MbdReco.cc b/offline/packages/mbd/MbdReco.cc index fe4dc62049..5ae4a67271 100644 --- a/offline/packages/mbd/MbdReco.cc +++ b/offline/packages/mbd/MbdReco.cc @@ -2,7 +2,7 @@ #include "MbdEvent.h" #include "MbdGeomV1.h" #include "MbdOutV2.h" -#include "MbdRawContainerV1.h" +#include "MbdRawContainerV2.h" #include "MbdPmtContainerV1.h" #include "MbdPmtSimContainerV1.h" @@ -262,7 +262,7 @@ int MbdReco::createNodes(PHCompositeNode *topNode) if (!m_mbdraws) { std::cout << "Creating MbdRawContainer Node " << std::endl; - m_mbdraws = new MbdRawContainerV1(); + m_mbdraws = new MbdRawContainerV2(); PHIODataNode *MbdRawContainerNode = new PHIODataNode(m_mbdraws, "MbdRawContainer", "PHObject"); bbcNode->addNode(MbdRawContainerNode); } diff --git a/offline/packages/mbd/MbdReturnCodes.h b/offline/packages/mbd/MbdReturnCodes.h index c9b1aea40e..ee808346fa 100644 --- a/offline/packages/mbd/MbdReturnCodes.h +++ b/offline/packages/mbd/MbdReturnCodes.h @@ -8,8 +8,9 @@ namespace MbdReturnCodes { - const short MBD_INVALID_SHORT = std::numeric_limits::min(); //-9999; - const int MBD_INVALID_INT = std::numeric_limits::min(); //-9999; + const short MBD_INVALID_SHORT = std::numeric_limits::min(); + const unsigned short MBD_INVALID_USHORT = std::numeric_limits::min(); + const int MBD_INVALID_INT = std::numeric_limits::min(); const float MBD_INVALID_FLOAT = std::numeric_limits::quiet_NaN(); } // namespace MbdReturnCodes diff --git a/offline/packages/mbd/MbdSig.cc b/offline/packages/mbd/MbdSig.cc index 155d731719..a896146770 100644 --- a/offline/packages/mbd/MbdSig.cc +++ b/offline/packages/mbd/MbdSig.cc @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -80,10 +81,6 @@ void MbdSig::Init() ped_fcn = new TF1("ped_fcn","[0]",0,2); ped_fcn->SetLineColor(3); - // Set tail function - ped_tail = new TF1("ped_tail","[0]+[1]*exp(-[2]*x)",0,2); - ped_tail->SetLineColor(2); - name = "h_chi2ndf"; name += _ch; h_chi2ndf = new TH1F(name,name,2000,0,100); @@ -157,7 +154,7 @@ MbdSig::~MbdSig() delete template_fcn; delete twotemplate_fcn; delete ped_fcn; - delete ped_tail; + delete fit_pileup; delete h_chi2ndf; if ( _pedstudyflag ) { @@ -237,8 +234,6 @@ void MbdSig::SetY(const Float_t* y, const int invert) Remove_Pileup(); } } - - _evt_counter++; } void MbdSig::SetXY(const Float_t* x, const Float_t* y, const int invert) @@ -320,18 +315,17 @@ void MbdSig::SetXY(const Float_t* x, const Float_t* y, const int invert) */ } - _evt_counter++; _verbose = 0; } void MbdSig::Remove_Pileup() { - //_verbose = 100; _verbose = 0; /* - if ( (_ch==238&&_evt_counter==7104) || (_ch==255&&_evt_counter==7762) ) + if ( _ch==46 && (_evt_counter>200910 && _evt_counter<200920)) { + std::cout << PHWHERE << "\t" << _evt_counter << "\t" << _ch << std::endl; _verbose = 100; } */ @@ -352,6 +346,7 @@ void MbdSig::Remove_Pileup() { TString name = "fit_pileup"; name += _ch; fit_pileup = new TF1(name,"pol3",0,16000); + fit_pileup->SetLineColor(7); for (int ipar=0; ipar<4; ipar++) { fit_pileup->SetParameter( ipar, _mbdcal->get_pileup(_ch,ipar+1) ); @@ -421,7 +416,6 @@ void MbdSig::Remove_Pileup() PadUpdate(); //gSubPulse->Print("ALL"); } - } else { @@ -429,8 +423,9 @@ void MbdSig::Remove_Pileup() if ( fit_pileup == nullptr ) { TString name = "fit_pileup"; name += _ch; - fit_pileup = new TF1(name,"gaus",-0.1,4.1); - fit_pileup->SetLineColor(2); + //fit_pileup = new TF1(name,"gaus",-0.1,4.1); + fit_pileup = new TF1(name, this, &MbdSig::SignalTail, -0.1, 4.1, 3, "MbdSig", "SignalTail"); + fit_pileup->SetLineColor(6); } fit_pileup->SetRange(-0.1,4.1); @@ -704,6 +699,17 @@ int MbdSig::CalcEventPed0_PreSamp(const int presample, const int nsamps) ped_fcn->SetRange(minsamp-0.1,maxsamp+0.1); ped_fcn->SetParameter(0,1500.); + gRawPulse->Fit( ped_fcn, "RNQ" ); + double chi2 = ped_fcn->GetChisquare(); + double ndf = ped_fcn->GetNDF(); + + /* + if ( chi2/ndf>4 ) + { + _verbose=100; + } + */ + if ( _verbose ) { gRawPulse->Fit( ped_fcn, "RQ" ); @@ -716,15 +722,6 @@ int MbdSig::CalcEventPed0_PreSamp(const int presample, const int nsamps) PadUpdate(); } } - else - { - //std::cout << PHWHERE << std::endl; - gRawPulse->Fit( ped_fcn, "RNQ" ); - - } - - double chi2 = ped_fcn->GetChisquare(); - double ndf = ped_fcn->GetNDF(); if ( chi2/ndf < 4.0 ) { @@ -1110,6 +1107,21 @@ void MbdSig::PadUpdate() const } } +Double_t MbdSig::SignalTail(const Double_t* x, const Double_t* par) +{ + // par[0] is the amplitude (relative to the spline amplitude) + // par[1] is the time + // x[0] units are in sample number + Double_t xx = x[0]-par[1]; + if ( xx<0. ) + { + return par[0]; + } + Double_t f = par[0]*TMath::Gaus(x[0],par[1],par[2]); + + return f; +} + Double_t MbdSig::TwoTemplateFcn(const Double_t* x, const Double_t* par) { Double_t f = TemplateFcn(x,par) + TemplateFcn(x,par+2); @@ -1209,11 +1221,13 @@ Double_t MbdSig::TemplateFcn(const Double_t* x, const Double_t* par) } // reject points with very bad rms in shape + /* if (template_yrms[ilow] >= 1.0 || template_yrms[ihigh] >= 1.0) { TF1::RejectPoint(); // return f; } + */ // Reject points where ADC saturates int samp_point = static_cast(x[0]); @@ -1231,8 +1245,16 @@ Double_t MbdSig::TemplateFcn(const Double_t* x, const Double_t* par) } // sampmax>0 means fit to the peak near sampmax +// fitmode: +// 0 - no info or no fit +// 1 - regular template fit (shortened) +// 2 - two template fit +// 3 - two template fit, neg ampl 2nd template +// 4 - saturated template fit +// 5 - saturated and shortened template fit int MbdSig::FitTemplate( const Int_t sampmax ) { + //_verbose = 100; //std::cout << PHWHERE << std::endl; /* if ( _evt_counter==2142 && _ch==92 ) @@ -1242,6 +1264,11 @@ int MbdSig::FitTemplate( const Int_t sampmax ) } */ + // Reset Fit Quality Parameters + f_chi2 = 0.; + f_ndf = 0.; + f_fitmode = 0; + // Check if channel is empty if (gSubPulse->GetN() == 0) { @@ -1262,9 +1289,9 @@ int MbdSig::FitTemplate( const Int_t sampmax ) nsaturated++; } } + /* - //if ( nsaturated>2 && _ch==185 ) - if ( nsaturated>2 ) + if ( nsaturated>0 ) { _verbose = 12; } @@ -1294,8 +1321,7 @@ int MbdSig::FitTemplate( const Int_t sampmax ) } } - //gSubPulse->GetPoint(sampmax, x_at_max, ymax); - if ( nsaturated<=3 ) + if ( nsaturated==0 ) { x_at_max -= 2.0; } @@ -1331,14 +1357,17 @@ int MbdSig::FitTemplate( const Int_t sampmax ) return 1; } + // Start with fit over early part of waveform to reduce pileup and afterpulse effects template_fcn->SetParameters(ymax, x_at_max); - if ( nsaturated<=3 ) + if ( nsaturated==0 ) { template_fcn->SetRange(0, x_at_max+4.2); + f_fitmode = 1; } else { - template_fcn->SetRange(0, sampmax + nsaturated - 0.5); + template_fcn->SetRange(0, sampmax + nsaturated + 0.5); + f_fitmode = 4; } if (_verbose == 0) @@ -1367,25 +1396,36 @@ int MbdSig::FitTemplate( const Int_t sampmax ) if ( (f_chi2/f_ndf) < 5. && f_ndf>6. ) { h_chi2ndf->Fill( f_chi2/f_ndf ); + _verbose = 0; return 1; } - // fit was out of time, likely from pileup, try two waveforms - if ( (f_time<(sampmax-2.5) || f_time>sampmax) && (nsaturated<=3) ) + /* + _verbose = 100; + if ( _verbose ) + { + PrintResiduals(gSubPulse,template_fcn); + } + */ + + // fit was bad, refit with two templates + if ( nsaturated==0 ) { //_verbose = 100; + f_fitmode = 2; if ( _verbose ) { - std::cout << "BADTIME " << _evt_counter << "\t" << _ch << "\t" << sampmax << "\t" << f_ampl << "\t" << f_time << std::endl; + std::cout << "BADTIME " << _evt_counter << "\t" << _ch << "\t" << sampmax << "\t" << f_ampl << "\t" << f_time + << "\t" << f_chi2/f_ndf << std::endl; gSubPulse->Draw("ap"); template_fcn->Draw("same"); PadUpdate(); } twotemplate_fcn->SetParameters(ymax,x_at_max,ymax,10); - twotemplate_fcn->SetRange(0,_nsamples); + twotemplate_fcn->SetRange(0,_nsamples-0.9); if (_verbose == 0) { @@ -1393,7 +1433,7 @@ int MbdSig::FitTemplate( const Int_t sampmax ) } else { - std::cout << "doing fit1 " << x_at_max << "\t" << ymax << std::endl; + std::cout << "doing 2wave fit " << x_at_max << "\t" << ymax << std::endl; gSubPulse->Fit(twotemplate_fcn, "R"); gSubPulse->Draw("ap"); gSubPulse->GetHistogram()->SetTitle(gSubPulse->GetName()); @@ -1402,55 +1442,65 @@ int MbdSig::FitTemplate( const Int_t sampmax ) //gSubPulse->Print("ALL"); } - //PadUpdate(); - - // Get fit parameters - f_ampl = twotemplate_fcn->GetParameter(0); - f_time = twotemplate_fcn->GetParameter(1); - f_chi2 = twotemplate_fcn->GetChisquare(); - f_ndf = twotemplate_fcn->GetNDF(); - - // Good fit - if ( (f_chi2/f_ndf) < 5. && f_ndf>6. ) + // Check two component fit + Double_t ampl1 = twotemplate_fcn->GetParameter(0); + Double_t time1 = twotemplate_fcn->GetParameter(1); + Double_t ampl2 = twotemplate_fcn->GetParameter(2); + Double_t time2 = twotemplate_fcn->GetParameter(3); + Double_t newchi2 = twotemplate_fcn->GetChisquare(); + Double_t newndf = twotemplate_fcn->GetNDF(); + Double_t newchi2ndf = newchi2/newndf; + + // bad two component fit, use original fit + if ( time2>15. || ampl1<0 || ampl2<0. || newchi2ndf>(f_chi2/f_ndf) ) { + if (_verbose) + { + std::cout << "Using original " << newchi2ndf << std::endl; + PrintResiduals(gSubPulse,twotemplate_fcn); + } + f_fitmode = 3; h_chi2ndf->Fill( f_chi2/f_ndf ); _verbose = 0; return 1; } - } - // refit with new range to exclude after-pulses - template_fcn->SetParameters(ymax, x_at_max); - //template_fcn->SetParameters( f_ampl, f_time ); + // Get new fit parameters (pick fit closest in time to first fit + if ( std::abs(f_time-time1) < std::abs(f_time-time2) ) + { + f_ampl = ampl1; + f_time = time1; + } + else + { + f_ampl = ampl2; + f_time = time2; + } - if ( nsaturated<=3 ) - { - template_fcn->SetRange(0, x_at_max+4.2); - //template_fcn->SetRange( 0., f_time+4.0 ); - } - else - { - template_fcn->SetRange( 0., f_time+nsaturated+0.8 ); + f_chi2 = newchi2; + f_ndf = newndf; + + // poor fit + if ( _verbose && (f_chi2/f_ndf) > 5. && f_ndf>6. ) + { + std::cout << "double fit high chi2/ndf " << f_chi2/f_ndf << std::endl; + PrintResiduals(gSubPulse,twotemplate_fcn); + PadUpdate(); + } + + h_chi2ndf->Fill( f_chi2/f_ndf ); + _verbose = 0; + return 1; } + // Try a refit of saturated waveform with different range + template_fcn->SetParameters(ymax, x_at_max); + template_fcn->SetRange( 0., _nsamples-0.5 ); + if (_verbose == 0) { //std::cout << PHWHERE << std::endl; - int fit_status = gSubPulse->Fit(template_fcn, "RNQ"); - if ( fit_status<0 && _verbose>0 ) - { - std::cout << PHWHERE << "\t" << fit_status << std::endl; - gSubPulse->Print("ALL"); - gSubPulse->Draw("ap"); - gSubPulse->Fit(template_fcn, "R"); - std::cout << "ampl time before refit " << _ch << "\t" << f_ampl << "\t" << f_time << std::endl; - f_ampl = template_fcn->GetParameter(0); - f_time = template_fcn->GetParameter(1); - std::cout << "ampl time after refit " << _ch << "\t" << f_ampl << "\t" << f_time << std::endl; - PadUpdate(); - std::string junk; - std::cin >> junk; - } + gSubPulse->Fit(template_fcn, "RNQ"); } else { @@ -1462,19 +1512,21 @@ int MbdSig::FitTemplate( const Int_t sampmax ) std::cout << "ampl time after refit " << f_ampl << "\t" << f_time << std::endl; } - f_ampl = template_fcn->GetParameter(0); - f_time = template_fcn->GetParameter(1); - f_chi2 = template_fcn->GetChisquare(); - f_ndf = template_fcn->GetNDF(); + // pick lower chi2/ndf of two saturated fits + Double_t newchi2 = template_fcn->GetChisquare(); + Double_t newndf = template_fcn->GetNDF(); + if ( (newchi2/newndf)GetParameter(0); + f_time = template_fcn->GetParameter(1); + f_chi2 = newchi2; + f_ndf = newndf; + f_fitmode = 5; + } h_chi2ndf->Fill( f_chi2/f_ndf ); - //if ( f_time<0 || f_time>30 ) - //if ( (_ch==185||_ch==155||_ch==249) && (fabs(f_ampl) > 44000.) ) - //double chi2 = template_fcn->GetChisquare(); - //double ndf = template_fcn->GetNDF(); - //if ( (_ch==185||_ch==155||_ch==249) && (fabs(chi2/ndf) > 100.) && nsaturated > 3) - if (_verbose > 0 && fabs(f_ampl) > 0.) + if (_verbose > 0 && std::abs(f_ampl) > 0.) { _verbose = 12; std::cout << "FitTemplate " << _ch << "\t" << f_ampl << "\t" << f_time << std::endl; @@ -1485,6 +1537,9 @@ int MbdSig::FitTemplate( const Int_t sampmax ) gPad->SetGridy(1); template_fcn->SetLineColor(4); template_fcn->Draw("same"); + + PrintResiduals(gSubPulse,template_fcn); + PadUpdate(); } @@ -1544,3 +1599,22 @@ int MbdSig::SetTemplate(const std::vector& shape, const std::vectorGetRange(smin,smax); + + double x{0}; + double y{0}; + for (double samp=0; samp<=smax; samp+=1.0) + { + g->GetPoint(int(samp),x,y); + double yerr = g->GetErrorY(int(samp)); + double resid = (y - f->Eval(x))/yerr; + std::cout << samp << "\t" << x << "\t" << resid << "\t" << y << "\t" << f->Eval(x) << "\t" << yerr << std::endl; + } +} + diff --git a/offline/packages/mbd/MbdSig.h b/offline/packages/mbd/MbdSig.h index bafdd9339c..73d3d1791b 100644 --- a/offline/packages/mbd/MbdSig.h +++ b/offline/packages/mbd/MbdSig.h @@ -31,6 +31,7 @@ class MbdSig void SetNSamples( const int s ) { _nsamples = s; } void SetY(const Float_t *y, const int invert = 1); void SetXY(const Float_t *x, const Float_t *y, const int invert = 1); + void SetEvtNum(const int evtnum) { _evt_counter = evtnum; } int GetNSamples() { return _nsamples; } @@ -41,6 +42,10 @@ class MbdSig Double_t GetAmpl() { return f_ampl; } Double_t GetTime() { return f_time; } Double_t GetIntegral() { return f_integral; } + Double_t GetChi2() { return f_chi2; } + Double_t GetNDF() { return f_ndf; } + Double_t GetChi2NDF() { return f_chi2/f_ndf; } + UShort_t GetFitInfo() { return f_fitmode; } /** * Fill hists from data between minsamp and maxsamp bins @@ -110,11 +115,14 @@ class MbdSig // Double_t FitPulse(); void SetTimeOffset(const Double_t o) { f_time_offset = o; } + Double_t SignalTail(const Double_t *x, const Double_t *par); Double_t TemplateFcn(const Double_t *x, const Double_t *par); Double_t TwoTemplateFcn(const Double_t *x, const Double_t *par); TF1 *GetTemplateFcn() { return template_fcn; } void SetMinMaxFitTime(const Double_t mintime, const Double_t maxtime); + void PrintResiduals(TGraphErrors *g, TF1 *f); + void WritePedHist(); void WritePedvsEvent(); void WriteChi2Hist(); @@ -147,6 +155,7 @@ class MbdSig Double_t f_integral{0.}; /** integral */ + UShort_t f_fitmode{0}; Double_t f_chi2{0.}; Double_t f_ndf{0.}; @@ -163,7 +172,6 @@ class MbdSig TH1 *hPedEvt{nullptr}; //! evt-by-event pedestal TGraphErrors *gPedvsEvent{nullptr}; //! Keep track of pedestal vs evtnum TF1 *ped_fcn{nullptr}; - TF1 *ped_tail{nullptr}; //! tail of prev signal Double_t ped0{0.}; //! Double_t ped0rms{0.}; //! int use_ped0{0}; //! whether to apply ped0 From 4a0fe1f55baabba3a4f05d10e419a87e3e2282bc Mon Sep 17 00:00:00 2001 From: Joseph Clement Date: Mon, 2 Mar 2026 18:17:26 -0500 Subject: [PATCH 305/393] remove smart pointer in Timingcut module, make destructor safely delete fit function to prevent leaking memory --- offline/packages/jetbackground/TimingCut.cc | 11 ++++++++++- offline/packages/jetbackground/TimingCut.h | 4 ++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/offline/packages/jetbackground/TimingCut.cc b/offline/packages/jetbackground/TimingCut.cc index 29f6e7d469..41d8dc571d 100644 --- a/offline/packages/jetbackground/TimingCut.cc +++ b/offline/packages/jetbackground/TimingCut.cc @@ -33,6 +33,15 @@ TimingCut::TimingCut(const std::string &jetNodeName, const std::string &name, co SetDefaultParams(); } +TimingCut::~TimingCut() +{ + if(_fitFunc) + { + delete _fitFunc; + _fitFunc = nullptr; + } +} + //____________________________________________________________________________.. int TimingCut::Init(PHCompositeNode *topNode) { @@ -52,7 +61,7 @@ int TimingCut::Init(PHCompositeNode *topNode) std::cout << "ERROR: NO CALIBRATION TF1 FOUND FOR TIMING CUT OHCAL FRACTION CORRECTION! This should never happen. ABORT RUN!" << std::endl; return Fun4AllReturnCodes::ABORTRUN; } - _fitFunc = std::unique_ptr((TF1*)tmp->Clone()); + _fitFunc = (TF1*)tmp->Clone(); delete fitFile; } else diff --git a/offline/packages/jetbackground/TimingCut.h b/offline/packages/jetbackground/TimingCut.h index 743f8fac6b..a6c56433e8 100644 --- a/offline/packages/jetbackground/TimingCut.h +++ b/offline/packages/jetbackground/TimingCut.h @@ -22,7 +22,7 @@ class TimingCut : public SubsysReco public: explicit TimingCut(const std::string &jetNodeName, const std::string &name = "TimingCutModule", bool doAbort = false, const std::string &ohTowerName = "TOWERINFO_CALIB_HCALOUT"); - ~TimingCut() override = default; + ~TimingCut() override; void set_t_shift(float new_shift) { _t_shift = new_shift; } float get_t_shift() { return _t_shift; } @@ -123,7 +123,7 @@ class TimingCut : public SubsysReco float _t_shift{0.0}; float _mbd_dt_width{3.0}; float _min_dphi{3*M_PI/4}; - std::unique_ptr _fitFunc{nullptr}; + TF1* _fitFunc{nullptr}; }; #endif From 979697c730795d74b7f32641729e9562e4d43f57 Mon Sep 17 00:00:00 2001 From: mchiu-bnl Date: Mon, 2 Mar 2026 21:21:42 -0500 Subject: [PATCH 306/393] rabbit fixes --- offline/packages/mbd/MbdRawContainerV2.h | 7 ++++++- offline/packages/mbd/MbdRawHitV1.cc | 2 +- offline/packages/mbd/MbdRawHitV2.cc | 2 +- offline/packages/mbd/MbdRawHitV2.h | 7 ++++--- offline/packages/mbd/MbdSig.cc | 25 ++++++++++++++++-------- offline/packages/mbd/MbdSig.h | 2 +- 6 files changed, 30 insertions(+), 15 deletions(-) diff --git a/offline/packages/mbd/MbdRawContainerV2.h b/offline/packages/mbd/MbdRawContainerV2.h index 1b028863ea..199ab4cc73 100644 --- a/offline/packages/mbd/MbdRawContainerV2.h +++ b/offline/packages/mbd/MbdRawContainerV2.h @@ -52,7 +52,12 @@ class MbdRawContainerV2 : public MbdRawContainer */ void set_npmt(const Short_t ival) override { - npmt = ival; + if ( ival != MbdRawHits->GetEntries() ) + { + std::cout << "ERROR, " << ival << " differs from " << MbdRawHits->GetEntries() << std::endl; + std::cout << " Setting npmt to " << MbdRawHits->GetEntries() << std::endl; + } + npmt = MbdRawHits->GetEntries(); return; } diff --git a/offline/packages/mbd/MbdRawHitV1.cc b/offline/packages/mbd/MbdRawHitV1.cc index 6f4eec2001..2ea6b34c01 100644 --- a/offline/packages/mbd/MbdRawHitV1.cc +++ b/offline/packages/mbd/MbdRawHitV1.cc @@ -7,7 +7,7 @@ void MbdRawHitV1::Reset() void MbdRawHitV1::Clear(Option_t* /*unused*/) { - std::cout << "clearing " << bpmt << std::endl; + //std::cout << "clearing " << bpmt << std::endl; bpmt = -1; badc = std::numeric_limits::quiet_NaN(); bttdc = std::numeric_limits::quiet_NaN(); diff --git a/offline/packages/mbd/MbdRawHitV2.cc b/offline/packages/mbd/MbdRawHitV2.cc index 2f4b6ca5bc..695003cfb1 100644 --- a/offline/packages/mbd/MbdRawHitV2.cc +++ b/offline/packages/mbd/MbdRawHitV2.cc @@ -7,7 +7,7 @@ void MbdRawHitV2::Reset() void MbdRawHitV2::Clear(Option_t* /*unused*/) { - std::cout << "clearing " << bpmt << std::endl; + //std::cout << "clearing " << bpmt << std::endl; bpmt = -1; fitstat = 0; badc = std::numeric_limits::quiet_NaN(); diff --git a/offline/packages/mbd/MbdRawHitV2.h b/offline/packages/mbd/MbdRawHitV2.h index 61e57fd6be..4bc88f871d 100644 --- a/offline/packages/mbd/MbdRawHitV2.h +++ b/offline/packages/mbd/MbdRawHitV2.h @@ -49,10 +49,11 @@ class MbdRawHitV2 : public MbdRawHit //! Store chi2/ndf (encoded in fitstat) void set_chi2ndf(const Double_t chi2ndf) override { - unsigned short us_chi2ndf = static_cast( chi2ndf*100. ); - if ( chi2ndf>40.95 ) + UShort_t us_chi2ndf = 0; + if (std::isfinite(chi2ndf) && chi2ndf > 0.) { - us_chi2ndf = 4095; + const Double_t clipped = (chi2ndf > 40.95) ? 40.95 : chi2ndf; + us_chi2ndf = static_cast(clipped * 100.); } fitstat &= 0xf000; fitstat |= us_chi2ndf; diff --git a/offline/packages/mbd/MbdSig.cc b/offline/packages/mbd/MbdSig.cc index a896146770..65de1006fc 100644 --- a/offline/packages/mbd/MbdSig.cc +++ b/offline/packages/mbd/MbdSig.cc @@ -1391,11 +1391,16 @@ int MbdSig::FitTemplate( const Int_t sampmax ) f_time = template_fcn->GetParameter(1); f_chi2 = template_fcn->GetChisquare(); f_ndf = template_fcn->GetNDF(); + Double_t chi2ndf = 1e9; + if ( f_ndf>0. ) + { + chi2ndf = f_chi2/f_ndf; + } // Good fit - if ( (f_chi2/f_ndf) < 5. && f_ndf>6. ) + if ( f_ndf>6. && chi2ndf<5. ) { - h_chi2ndf->Fill( f_chi2/f_ndf ); + h_chi2ndf->Fill( chi2ndf ); _verbose = 0; return 1; @@ -1417,8 +1422,8 @@ int MbdSig::FitTemplate( const Int_t sampmax ) if ( _verbose ) { - std::cout << "BADTIME " << _evt_counter << "\t" << _ch << "\t" << sampmax << "\t" << f_ampl << "\t" << f_time - << "\t" << f_chi2/f_ndf << std::endl; + std::cout << "BADFIT " << _evt_counter << "\t" << _ch << "\t" << sampmax << "\t" << f_ampl << "\t" << f_time + << "\t" << chi2ndf << std::endl; gSubPulse->Draw("ap"); template_fcn->Draw("same"); PadUpdate(); @@ -1449,10 +1454,14 @@ int MbdSig::FitTemplate( const Int_t sampmax ) Double_t time2 = twotemplate_fcn->GetParameter(3); Double_t newchi2 = twotemplate_fcn->GetChisquare(); Double_t newndf = twotemplate_fcn->GetNDF(); - Double_t newchi2ndf = newchi2/newndf; + Double_t newchi2ndf = 0.; + if ( newndf>0.) + { + newchi2ndf = newchi2/newndf; + } // bad two component fit, use original fit - if ( time2>15. || ampl1<0 || ampl2<0. || newchi2ndf>(f_chi2/f_ndf) ) + if ( time2>15. || ampl1<0 || ampl2<0. || newchi2ndf>chi2ndf) { if (_verbose) { @@ -1460,7 +1469,7 @@ int MbdSig::FitTemplate( const Int_t sampmax ) PrintResiduals(gSubPulse,twotemplate_fcn); } f_fitmode = 3; - h_chi2ndf->Fill( f_chi2/f_ndf ); + h_chi2ndf->Fill( chi2ndf ); _verbose = 0; return 1; } @@ -1481,7 +1490,7 @@ int MbdSig::FitTemplate( const Int_t sampmax ) f_ndf = newndf; // poor fit - if ( _verbose && (f_chi2/f_ndf) > 5. && f_ndf>6. ) + if ( _verbose && f_ndf>6. && (f_chi2/f_ndf) > 5. ) { std::cout << "double fit high chi2/ndf " << f_chi2/f_ndf << std::endl; PrintResiduals(gSubPulse,twotemplate_fcn); diff --git a/offline/packages/mbd/MbdSig.h b/offline/packages/mbd/MbdSig.h index 73d3d1791b..69d5ca7bfd 100644 --- a/offline/packages/mbd/MbdSig.h +++ b/offline/packages/mbd/MbdSig.h @@ -44,7 +44,7 @@ class MbdSig Double_t GetIntegral() { return f_integral; } Double_t GetChi2() { return f_chi2; } Double_t GetNDF() { return f_ndf; } - Double_t GetChi2NDF() { return f_chi2/f_ndf; } + Double_t GetChi2NDF() { return (f_ndf > 0.) ? (f_chi2 / f_ndf) : std::numeric_limits::quiet_NaN(); } UShort_t GetFitInfo() { return f_fitmode; } /** From 04ac52fe260bf87b258ede2ba04f983b3c322fbe Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Tue, 3 Mar 2026 15:39:41 -0500 Subject: [PATCH 307/393] suppress verbosity --- offline/packages/trackreco/DSTClusterPruning.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/offline/packages/trackreco/DSTClusterPruning.cc b/offline/packages/trackreco/DSTClusterPruning.cc index 36bbe4fd0f..890e465b96 100644 --- a/offline/packages/trackreco/DSTClusterPruning.cc +++ b/offline/packages/trackreco/DSTClusterPruning.cc @@ -185,8 +185,11 @@ void DSTClusterPruning::prune_clusters() { if (!trackseed) { - std::cout << "No TrackSeed" << std::endl; - continue; + if(Verbosity() > 1) + { + std::cout << "No TrackSeed" << std::endl; + } + continue; } for (auto key_iter = trackseed->begin_cluster_keys(); key_iter != trackseed->end_cluster_keys(); ++key_iter) From 5f13771a3b560c7d606232c0cfe5a12f1a3b644b Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Sat, 28 Feb 2026 16:13:55 -0500 Subject: [PATCH 308/393] EventPlaneReco: Implement trigonometry cache for Q-vector calculation * Pre-calculate cos(n*phi) and sin(n*phi) values during InitRun * Store cached values in a nested vector indexed by harmonic and channel * Replace per-tower std::cos and std::sin calls in process_sEPD with cache lookups * Significant reduction in CPU overhead per event --- .../packages/eventplaneinfo/EventPlaneReco.cc | 47 ++++++++++++++----- .../packages/eventplaneinfo/EventPlaneReco.h | 11 +++++ 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/offline/packages/eventplaneinfo/EventPlaneReco.cc b/offline/packages/eventplaneinfo/EventPlaneReco.cc index 58833f0df1..900501c164 100644 --- a/offline/packages/eventplaneinfo/EventPlaneReco.cc +++ b/offline/packages/eventplaneinfo/EventPlaneReco.cc @@ -85,6 +85,37 @@ int EventPlaneReco::Init(PHCompositeNode *topNode) return Fun4AllReturnCodes::EVENT_OK; } +int EventPlaneReco::InitRun(PHCompositeNode* topNode) +{ + EpdGeom* epdgeom = findNode::getClass(topNode, "TOWERGEOM_EPD"); + if (!epdgeom) + { + std::cout << PHWHERE << " Error: TOWERGEOM_EPD is missing. Cannot build trig cache." << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + m_trig_cache.assign(m_harmonics.size(), std::vector>(SEPD_CHANNELS)); + + for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) + { + int n = m_harmonics[h_idx]; + for (int channel = 0; channel < SEPD_CHANNELS; ++channel) + { + unsigned int key = TowerInfoDefs::encode_epd(channel); + double phi = epdgeom->get_phi(key); + + m_trig_cache[h_idx][channel] = {std::cos(n * phi), std::sin(n * phi)}; + } + } + + if (Verbosity() > 0) + { + std::cout << PHWHERE << " Trigonometry cache initialized for " << SEPD_CHANNELS << " sEPD channels." << std::endl; + } + + return Fun4AllReturnCodes::EVENT_OK; +} + std::array, 2> EventPlaneReco::calculate_flattening_matrix(double xx, double yy, double xy, int n, int cent_bin, const std::string& det_label) { std::array, 2> mat{}; @@ -308,13 +339,6 @@ int EventPlaneReco::process_sEPD(PHCompositeNode* topNode) return Fun4AllReturnCodes::ABORTRUN; } - EpdGeom* epdgeom = findNode::getClass(topNode, "TOWERGEOM_EPD"); - if (!epdgeom) - { - std::cout << PHWHERE << " TOWERGEOM_EPD is missing doing nothing" << std::endl; - return Fun4AllReturnCodes::ABORTRUN; - } - // sepd unsigned int nchannels_epd = towerinfosEPD->size(); @@ -327,7 +351,6 @@ int EventPlaneReco::process_sEPD(PHCompositeNode* topNode) unsigned int key = TowerInfoDefs::encode_epd(channel); double charge = tower->get_energy(); - double phi = epdgeom->get_phi(key); // skip bad channels // skip channels with very low charge @@ -348,10 +371,10 @@ int EventPlaneReco::process_sEPD(PHCompositeNode* topNode) for (size_t h_idx = 0; h_idx < m_harmonics.size(); ++h_idx) { - int n = m_harmonics[h_idx]; - QVec q_n = {charge * std::cos(n * phi), charge * std::sin(n * phi)}; - m_Q_raw[h_idx][arm].x += q_n.x; - m_Q_raw[h_idx][arm].y += q_n.y; + const auto& [cached_cos, cached_sin] = m_trig_cache[h_idx][channel]; + + m_Q_raw[h_idx][arm].x += charge * cached_cos; + m_Q_raw[h_idx][arm].y += charge * cached_sin; } } diff --git a/offline/packages/eventplaneinfo/EventPlaneReco.h b/offline/packages/eventplaneinfo/EventPlaneReco.h index 0f356e6033..d5fe492c3b 100644 --- a/offline/packages/eventplaneinfo/EventPlaneReco.h +++ b/offline/packages/eventplaneinfo/EventPlaneReco.h @@ -7,6 +7,7 @@ #include #include #include +#include class CDBTTree; class PHCompositeNode; @@ -31,6 +32,11 @@ class EventPlaneReco : public SubsysReco */ int Init(PHCompositeNode *topNode) override; + /** Called during initialization. + * geometry is available + */ + int InitRun(PHCompositeNode *topNode) override; + /** Called for each event. This is where you do the real work. */ @@ -130,5 +136,10 @@ class EventPlaneReco : public SubsysReco std::array, m_harmonics.size()> m_Q_raw{}; std::array, m_harmonics.size()> m_Q_recentered{}; std::array, m_harmonics.size()> m_Q_flat{}; + + // [Harmonic Index][Channel Index] -> {cos, sin} + std::vector>> m_trig_cache; + + static constexpr int SEPD_CHANNELS = 744; }; #endif From 4a6fc72df6dedffae09c9fb2bf918b2b026aa2f5 Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Sat, 28 Feb 2026 22:16:30 -0500 Subject: [PATCH 309/393] Cleanup includes - cleanup unused includes and redundant forward declarations --- offline/packages/eventplaneinfo/EventPlaneReco.cc | 8 +------- offline/packages/eventplaneinfo/EventPlaneReco.h | 1 - offline/packages/eventplaneinfo/EventplaneinfoMapv1.cc | 1 - offline/packages/eventplaneinfo/Eventplaneinfov1.h | 2 -- 4 files changed, 1 insertion(+), 11 deletions(-) diff --git a/offline/packages/eventplaneinfo/EventPlaneReco.cc b/offline/packages/eventplaneinfo/EventPlaneReco.cc index 900501c164..b0bf6ec639 100644 --- a/offline/packages/eventplaneinfo/EventPlaneReco.cc +++ b/offline/packages/eventplaneinfo/EventPlaneReco.cc @@ -26,17 +26,11 @@ #include #include -// -- root includes -- -#include -#include - // c++ includes -- -#include -#include -#include #include #include #include +#include //____________________________________________________________________________.. EventPlaneReco::EventPlaneReco(const std::string &name): diff --git a/offline/packages/eventplaneinfo/EventPlaneReco.h b/offline/packages/eventplaneinfo/EventPlaneReco.h index d5fe492c3b..267b52b9c8 100644 --- a/offline/packages/eventplaneinfo/EventPlaneReco.h +++ b/offline/packages/eventplaneinfo/EventPlaneReco.h @@ -6,7 +6,6 @@ #include #include -#include #include class CDBTTree; diff --git a/offline/packages/eventplaneinfo/EventplaneinfoMapv1.cc b/offline/packages/eventplaneinfo/EventplaneinfoMapv1.cc index a0888d4d18..4aeffdd8c9 100644 --- a/offline/packages/eventplaneinfo/EventplaneinfoMapv1.cc +++ b/offline/packages/eventplaneinfo/EventplaneinfoMapv1.cc @@ -3,7 +3,6 @@ #include "Eventplaneinfo.h" #include "EventplaneinfoMap.h" -#include // for reverse_iterator #include // for pair, make_pair EventplaneinfoMapv1::~EventplaneinfoMapv1() diff --git a/offline/packages/eventplaneinfo/Eventplaneinfov1.h b/offline/packages/eventplaneinfo/Eventplaneinfov1.h index 571997b63b..5a109898ce 100644 --- a/offline/packages/eventplaneinfo/Eventplaneinfov1.h +++ b/offline/packages/eventplaneinfo/Eventplaneinfov1.h @@ -11,8 +11,6 @@ #include // for pair, make_pair #include -class PHObject; - class Eventplaneinfov1 : public Eventplaneinfo { public: From e294d8840abad9fd7a6b0d814af818bb260d271e Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Sun, 1 Mar 2026 12:25:18 -0500 Subject: [PATCH 310/393] =?UTF-8?q?Skip=20Q=20Vec=20Calib=20for=20(?= =?UTF-8?q?=E2=89=A580%=20centrality)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Peripheral events (≥80% centrality) silently use bin 79 calibration data. - Setting m_doNotCalibEvent = true for out-of-range centrality and storing raw Q-vectors --- offline/packages/eventplaneinfo/EventPlaneReco.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/offline/packages/eventplaneinfo/EventPlaneReco.cc b/offline/packages/eventplaneinfo/EventPlaneReco.cc index b0bf6ec639..4cf2624d18 100644 --- a/offline/packages/eventplaneinfo/EventPlaneReco.cc +++ b/offline/packages/eventplaneinfo/EventPlaneReco.cc @@ -407,9 +407,19 @@ int EventPlaneReco::process_sEPD(PHCompositeNode* topNode) void EventPlaneReco::correct_QVecs() { size_t cent_bin = static_cast(m_cent); + + // Skip calibration for out-of-range centrality if (cent_bin >= m_cent_bins) { - cent_bin = m_cent_bins - 1; // Clamp max + if (Verbosity() > 2) + { + std::cout << PHWHERE << " Warning: Centrality " << m_cent + << "% exceeds calibration range (0-" << m_cent_bins - 1 + << "). Using raw Q-vectors." << std::endl; + } + + m_doNotCalibEvent = true; + return; } size_t south_idx = static_cast(Subdetector::S); From f84a5ad6b659f992cc3a6d81b544ae75ecffebec Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Sun, 1 Mar 2026 12:31:49 -0500 Subject: [PATCH 311/393] Guard channel loop against trig-cache bounds - Ensure channel count does not exceed trig-cache size - Prevent potential out-of-bounds read --- offline/packages/eventplaneinfo/EventPlaneReco.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/offline/packages/eventplaneinfo/EventPlaneReco.cc b/offline/packages/eventplaneinfo/EventPlaneReco.cc index 4cf2624d18..df68ff20f0 100644 --- a/offline/packages/eventplaneinfo/EventPlaneReco.cc +++ b/offline/packages/eventplaneinfo/EventPlaneReco.cc @@ -334,12 +334,21 @@ int EventPlaneReco::process_sEPD(PHCompositeNode* topNode) } // sepd - unsigned int nchannels_epd = towerinfosEPD->size(); + const unsigned int nchannels_epd = towerinfosEPD->size(); + const unsigned int channel_limit = std::min(nchannels_epd, static_cast(SEPD_CHANNELS)); + + if (nchannels_epd != channel_limit && Verbosity() > 1) + { + std::cout << PHWHERE + << " Warning: sEPD channel count (" << nchannels_epd + << ") exceeds trig cache size (" << SEPD_CHANNELS + << "); truncating iteration." << std::endl; + } double sepd_total_charge_south = 0; double sepd_total_charge_north = 0; - for (unsigned int channel = 0; channel < nchannels_epd; ++channel) + for (unsigned int channel = 0; channel < channel_limit; ++channel) { TowerInfo* tower = towerinfosEPD->get_tower_at_channel(channel); From f0d5a456bd8b3b818f62b45765687ac871b95a36 Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Sun, 1 Mar 2026 12:35:58 -0500 Subject: [PATCH 312/393] Propagate CreateNodes failure from Init. --- offline/packages/eventplaneinfo/EventPlaneReco.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/offline/packages/eventplaneinfo/EventPlaneReco.cc b/offline/packages/eventplaneinfo/EventPlaneReco.cc index df68ff20f0..82361e74c6 100644 --- a/offline/packages/eventplaneinfo/EventPlaneReco.cc +++ b/offline/packages/eventplaneinfo/EventPlaneReco.cc @@ -74,9 +74,7 @@ int EventPlaneReco::Init(PHCompositeNode *topNode) print_correction_data(); } - CreateNodes(topNode); - - return Fun4AllReturnCodes::EVENT_OK; + return CreateNodes(topNode); } int EventPlaneReco::InitRun(PHCompositeNode* topNode) From af96639cc72d8940048b1bcb3e67be2131330f5d Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Sun, 1 Mar 2026 22:56:02 -0500 Subject: [PATCH 313/393] EventPlaneReco - Output Node Name Flexibility - Keep the default output node name unchanged ("EventplaneinfoMap") - Allow adjusting of the output node name if needed --- offline/packages/eventplaneinfo/EventPlaneReco.cc | 6 +++--- offline/packages/eventplaneinfo/EventPlaneReco.h | 8 +++++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/offline/packages/eventplaneinfo/EventPlaneReco.cc b/offline/packages/eventplaneinfo/EventPlaneReco.cc index 82361e74c6..0179e08926 100644 --- a/offline/packages/eventplaneinfo/EventPlaneReco.cc +++ b/offline/packages/eventplaneinfo/EventPlaneReco.cc @@ -286,11 +286,11 @@ int EventPlaneReco::CreateNodes(PHCompositeNode *topNode) { dstNode->addNode(globalNode); } - EventplaneinfoMap *eps = findNode::getClass(topNode, "EventplaneinfoMap"); + EventplaneinfoMap *eps = findNode::getClass(topNode, m_EventPlaneInfoNodeName); if (!eps) { eps = new EventplaneinfoMapv1(); - PHIODataNode *newNode = new PHIODataNode(eps , "EventplaneinfoMap", "PHObject"); + PHIODataNode *newNode = new PHIODataNode(eps , m_EventPlaneInfoNodeName, "PHObject"); globalNode->addNode(newNode); } @@ -537,7 +537,7 @@ void EventPlaneReco::print_QVectors() int EventPlaneReco::FillNode(PHCompositeNode *topNode) { - EventplaneinfoMap *epmap = findNode::getClass(topNode, "EventplaneinfoMap"); + EventplaneinfoMap *epmap = findNode::getClass(topNode, m_EventPlaneInfoNodeName); if (!epmap) { std::cout << PHWHERE << " EventplaneinfoMap is missing doing nothing" << std::endl; diff --git a/offline/packages/eventplaneinfo/EventPlaneReco.h b/offline/packages/eventplaneinfo/EventPlaneReco.h index 267b52b9c8..231d30a8bb 100644 --- a/offline/packages/eventplaneinfo/EventPlaneReco.h +++ b/offline/packages/eventplaneinfo/EventPlaneReco.h @@ -65,9 +65,14 @@ class EventPlaneReco : public SubsysReco m_sepd_min_channel_charge = sepd_min_channel_charge; } + void set_EventPlaneInfoNodeName(const std::string &name) + { + m_EventPlaneInfoNodeName = name; + } + private: - static int CreateNodes(PHCompositeNode *topNode); + int CreateNodes(PHCompositeNode *topNode); std::array, 2> calculate_flattening_matrix(double xx, double yy, double xy, int n, int cent_bin, const std::string& det_label); void LoadCalib(); @@ -92,6 +97,7 @@ class EventPlaneReco : public SubsysReco std::string m_calibName{"SEPD_EventPlaneCalib"}; std::string m_inputNode{"TOWERINFO_CALIB_SEPD"}; + std::string m_EventPlaneInfoNodeName{"EventplaneinfoMap"}; CDBTTree *m_cdbttree {nullptr}; From 88201372242a36404a8d4d3330870f65fee09afe Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Tue, 3 Mar 2026 16:01:00 -0500 Subject: [PATCH 314/393] clang-tidy fixes - Address the following existing clang-tidy warnings: - [hicpp-special-member-functions] - [hicpp-use-equals-default] - [modernize-use-equals-default] - [performance-unnecessary-value-param] - [modernize-use-using] - [readability-avoid-const-params-in-decls] --- offline/packages/eventplaneinfo/Eventplaneinfo.h | 15 +++++++++++---- .../packages/eventplaneinfo/EventplaneinfoMap.h | 14 ++++++++++---- .../packages/eventplaneinfo/EventplaneinfoMapv1.h | 6 ++++++ .../packages/eventplaneinfo/Eventplaneinfov1.h | 13 +++++++++---- .../packages/eventplaneinfo/Eventplaneinfov2.h | 6 +++--- 5 files changed, 39 insertions(+), 15 deletions(-) diff --git a/offline/packages/eventplaneinfo/Eventplaneinfo.h b/offline/packages/eventplaneinfo/Eventplaneinfo.h index af903b6d06..c01756deca 100644 --- a/offline/packages/eventplaneinfo/Eventplaneinfo.h +++ b/offline/packages/eventplaneinfo/Eventplaneinfo.h @@ -13,7 +13,7 @@ class Eventplaneinfo : public PHObject { public: - ~Eventplaneinfo() override {} + ~Eventplaneinfo() override = default; void identify(std::ostream& os = std::cout) const override { @@ -22,23 +22,30 @@ class Eventplaneinfo : public PHObject PHObject* CloneMe() const override { return nullptr; } - virtual void set_qvector(std::vector> /*Qvec*/) { return; } + virtual void set_qvector(const std::vector>& /*Qvec*/) { return; } virtual void set_qvector_raw(const std::vector>& /*Qvec*/) { return; } virtual void set_qvector_recentered(const std::vector>& /*Qvec*/) { return; } - virtual void set_shifted_psi(std::vector /*Psi_Shifted*/) { return; } + virtual void set_shifted_psi(const std::vector& /*Psi_Shifted*/) { return; } virtual std::pair get_qvector(int /*order*/) const { return std::make_pair(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); } virtual std::pair get_qvector_raw(int /*order*/) const { return std::make_pair(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); } virtual std::pair get_qvector_recentered(int /*order*/) const { return std::make_pair(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); } virtual double get_psi(int /*order*/) const { return std::numeric_limits::quiet_NaN(); } virtual double get_shifted_psi(int /*order*/) const { return std::numeric_limits::quiet_NaN(); } virtual double GetPsi(const double /*Qx*/, const double /*Qy*/, const unsigned int /*order*/) const { return std::numeric_limits::quiet_NaN(); } - virtual void set_ring_qvector(std::vector>> /*RingQvecs*/) { return; } + virtual void set_ring_qvector(const std::vector>>& /*RingQvecs*/) { return; } virtual std::pair get_ring_qvector(int /*rbin*/, int /*order*/) const { return std::make_pair(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); } virtual double get_ring_psi(int /*rbin*/, int /*order*/) const { return std::numeric_limits::quiet_NaN(); } protected: Eventplaneinfo() = default; + // Rule of Five: Protected allows derived classes to copy/move, + // but prevents "slicing" at the base class level. + Eventplaneinfo(const Eventplaneinfo&) = default; + Eventplaneinfo& operator=(const Eventplaneinfo&) = default; + Eventplaneinfo(Eventplaneinfo&&) = default; + Eventplaneinfo& operator=(Eventplaneinfo&&) = default; + private: ClassDefOverride(Eventplaneinfo, 1); }; diff --git a/offline/packages/eventplaneinfo/EventplaneinfoMap.h b/offline/packages/eventplaneinfo/EventplaneinfoMap.h index 247a62a1f6..ee16720cff 100644 --- a/offline/packages/eventplaneinfo/EventplaneinfoMap.h +++ b/offline/packages/eventplaneinfo/EventplaneinfoMap.h @@ -25,10 +25,10 @@ class EventplaneinfoMap : public PHObject sEPDRING_NORTH = 200 }; - typedef std::map::const_iterator ConstIter; - typedef std::map::iterator Iter; + using ConstIter = std::map::const_iterator; + using Iter = std::map::iterator; - ~EventplaneinfoMap() override {} + ~EventplaneinfoMap() override = default; void identify(std::ostream& os = std::cout) const override { os << "EventplaneinfoMap base class" << std::endl; } virtual bool empty() const {return true;} @@ -47,7 +47,13 @@ class EventplaneinfoMap : public PHObject virtual Iter end(); protected: - EventplaneinfoMap() {} + EventplaneinfoMap() = default; + + // Rule of Five: Protected to support derived classes + EventplaneinfoMap(const EventplaneinfoMap&) = default; + EventplaneinfoMap& operator=(const EventplaneinfoMap&) = default; + EventplaneinfoMap(EventplaneinfoMap&&) = default; + EventplaneinfoMap& operator=(EventplaneinfoMap&&) = default; private: ClassDefOverride(EventplaneinfoMap, 1); diff --git a/offline/packages/eventplaneinfo/EventplaneinfoMapv1.h b/offline/packages/eventplaneinfo/EventplaneinfoMapv1.h index 5aac01a4ce..b4f10f3bed 100644 --- a/offline/packages/eventplaneinfo/EventplaneinfoMapv1.h +++ b/offline/packages/eventplaneinfo/EventplaneinfoMapv1.h @@ -16,6 +16,12 @@ class EventplaneinfoMapv1 : public EventplaneinfoMap EventplaneinfoMapv1() = default; ~EventplaneinfoMapv1() override; + // Rule of Five: Explicitly delete to prevent shallow copy/double free + EventplaneinfoMapv1(const EventplaneinfoMapv1&) = delete; + EventplaneinfoMapv1& operator=(const EventplaneinfoMapv1&) = delete; + EventplaneinfoMapv1(EventplaneinfoMapv1&&) = delete; + EventplaneinfoMapv1& operator=(EventplaneinfoMapv1&&) = delete; + void identify(std::ostream& os = std::cout) const override; void Reset() override { clear(); } // cppcheck-suppress [virtualCallInConstructor] diff --git a/offline/packages/eventplaneinfo/Eventplaneinfov1.h b/offline/packages/eventplaneinfo/Eventplaneinfov1.h index 5a109898ce..1950e2ef31 100644 --- a/offline/packages/eventplaneinfo/Eventplaneinfov1.h +++ b/offline/packages/eventplaneinfo/Eventplaneinfov1.h @@ -17,17 +17,22 @@ class Eventplaneinfov1 : public Eventplaneinfo Eventplaneinfov1() = default; ~Eventplaneinfov1() override = default; + Eventplaneinfov1(const Eventplaneinfov1&) = default; + Eventplaneinfov1& operator=(const Eventplaneinfov1&) = default; + Eventplaneinfov1(Eventplaneinfov1&&) = default; + Eventplaneinfov1& operator=(Eventplaneinfov1&&) = default; + void identify(std::ostream& os = std::cout) const override; void Reset() override { *this = Eventplaneinfov1(); } PHObject* CloneMe() const override { return new Eventplaneinfov1(*this); } - void set_qvector(std::vector> Qvec) override { mQvec = Qvec; } - void set_shifted_psi(std::vector Psi_Shifted) override { mPsi_Shifted = Psi_Shifted; } + void set_qvector(const std::vector>& Qvec) override { mQvec = Qvec; } + void set_shifted_psi(const std::vector& Psi_Shifted) override { mPsi_Shifted = Psi_Shifted; } std::pair get_qvector(int order) const override { return std::make_pair(mQvec[order - 1].first, mQvec[order - 1].second); } - void set_ring_qvector(std::vector>> Qvec) override { ring_Qvec = Qvec; } + void set_ring_qvector(const std::vector>>& Qvec) override { ring_Qvec = Qvec; } std::pair get_ring_qvector(int ring_index, int order) const override { return ring_Qvec[ring_index][order - 1]; } double get_ring_psi(int ring_index, int order) const override {return GetPsi(ring_Qvec[ring_index][order - 1].first,ring_Qvec[ring_index][order - 1].second,order);} - double GetPsi(const double Qx, const double Qy, const unsigned int order) const override; + double GetPsi(double Qx, double Qy, unsigned int order) const override; double get_psi(int order) const override { return GetPsi(mQvec[order - 1].first, mQvec[order - 1].second, order);} double get_shifted_psi(int order) const override { return mPsi_Shifted[order - 1]; } diff --git a/offline/packages/eventplaneinfo/Eventplaneinfov2.h b/offline/packages/eventplaneinfo/Eventplaneinfov2.h index bd6cb553c8..b6f5bf7793 100644 --- a/offline/packages/eventplaneinfo/Eventplaneinfov2.h +++ b/offline/packages/eventplaneinfo/Eventplaneinfov2.h @@ -28,14 +28,14 @@ class Eventplaneinfov2 : public Eventplaneinfo void Reset() override { *this = Eventplaneinfov2(); } PHObject* CloneMe() const override { return new Eventplaneinfov2(*this); } - void set_qvector(std::vector> Qvec) override { mQvec = Qvec; } + void set_qvector(const std::vector>& Qvec) override { mQvec = Qvec; } void set_qvector_raw(const std::vector>& Qvec) override { mQvec_raw = Qvec; } void set_qvector_recentered(const std::vector>& Qvec) override { mQvec_recentered = Qvec; } - void set_shifted_psi(std::vector Psi_Shifted) override { mPsi_Shifted = Psi_Shifted; } + void set_shifted_psi(const std::vector& Psi_Shifted) override { mPsi_Shifted = Psi_Shifted; } std::pair get_qvector(int order) const override { return safe_qvec(mQvec, order); } std::pair get_qvector_raw(int order) const override { return safe_qvec(mQvec_raw, order); } std::pair get_qvector_recentered(int order) const override { return safe_qvec(mQvec_recentered, order); } - void set_ring_qvector(std::vector>> Qvec) override { ring_Qvec = Qvec; } + void set_ring_qvector(const std::vector>>& Qvec) override { ring_Qvec = Qvec; } std::pair get_ring_qvector(int ring_index, int order) const override { if (ring_index < 0 || static_cast(ring_index) >= ring_Qvec.size()) From 5108c85ecf99a4a93d57a617bc8cd74b02a44d0f Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 3 Mar 2026 16:54:32 -0500 Subject: [PATCH 315/393] allow integer node names upon creation --- offline/framework/phool/PHIODataNode.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/offline/framework/phool/PHIODataNode.h b/offline/framework/phool/PHIODataNode.h index 46be461793..3ee60a8e4c 100644 --- a/offline/framework/phool/PHIODataNode.h +++ b/offline/framework/phool/PHIODataNode.h @@ -23,6 +23,7 @@ class PHIODataNode : public PHDataNode T *operator*() { return this->getData(); } PHIODataNode(T *, const std::string &); PHIODataNode(T *, const std::string &, const std::string &); + PHIODataNode(T *, const int, const std::string &); virtual ~PHIODataNode() = default; typedef PHTypedNodeIterator iterator; void BufferSize(int size) { buffersize = size; } @@ -54,6 +55,16 @@ PHIODataNode::PHIODataNode(T *d, const std::string &n, this->objectclass = TO->GetName(); } +template +PHIODataNode::PHIODataNode(T *d, const int id, + const std::string &objtype) + : PHDataNode(d, std::to_string(id), objtype) +{ + this->type = "PHIODataNode"; + TObject *TO = static_cast(d); + this->objectclass = TO->GetName(); +} + template bool PHIODataNode::write(PHIOManager *IOManager, const std::string &path) { From 9c385955d57be4f64962e3e5a86a17e5807ed6f8 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 3 Mar 2026 16:55:46 -0500 Subject: [PATCH 316/393] keep single packets (for zdc raw data --- .../fun4allraw/SingleTriggeredInput.cc | 274 ++++++++++-------- .../fun4allraw/SingleTriggeredInput.h | 18 +- 2 files changed, 166 insertions(+), 126 deletions(-) diff --git a/offline/framework/fun4allraw/SingleTriggeredInput.cc b/offline/framework/fun4allraw/SingleTriggeredInput.cc index 80e9f49a64..999ca40531 100644 --- a/offline/framework/fun4allraw/SingleTriggeredInput.cc +++ b/offline/framework/fun4allraw/SingleTriggeredInput.cc @@ -26,7 +26,7 @@ #include // for pair #include -SingleTriggeredInput::SingleTriggeredInput(const std::string &name) +SingleTriggeredInput::SingleTriggeredInput(const std::string& name) : Fun4AllBase(name) { m_bclkarray.fill(std::numeric_limits::max()); @@ -35,7 +35,7 @@ SingleTriggeredInput::SingleTriggeredInput(const std::string &name) SingleTriggeredInput::~SingleTriggeredInput() { - std::set evtset; + std::set evtset; for (auto& [pid, dq] : m_PacketEventDeque) { while (!dq.empty()) @@ -44,7 +44,7 @@ SingleTriggeredInput::~SingleTriggeredInput() dq.pop_front(); } } - for (auto *evt : evtset) + for (auto* evt : evtset) { delete evt; } @@ -64,7 +64,7 @@ bool SingleTriggeredInput::CheckFemDiffIdx(int pid, size_t index, const std::deq return false; } - Packet* pkt_prev = events[index-1]->getPacket(pid); + Packet* pkt_prev = events[index - 1]->getPacket(pid); Packet* pkt_curr = events[index]->getPacket(pid); if (!pkt_prev || !pkt_curr) { @@ -73,7 +73,8 @@ bool SingleTriggeredInput::CheckFemDiffIdx(int pid, size_t index, const std::deq return false; } - auto get_majority_femclk = [](Packet* pkt) -> uint16_t { + auto get_majority_femclk = [](Packet* pkt) -> uint16_t + { int nmod = pkt->iValue(0, "NRMODULES"); std::map counts; for (int j = 0; j < nmod; ++j) @@ -85,7 +86,9 @@ bool SingleTriggeredInput::CheckFemDiffIdx(int pid, size_t index, const std::deq { return std::numeric_limits::max(); } - return std::max_element(counts.begin(), counts.end(), [](const auto& a, const auto& b) { return a.second < b.second; })->first; + return std::max_element(counts.begin(), counts.end(), [](const auto& a, const auto& b) + { return a.second < b.second; }) + ->first; }; uint16_t clk_prev = get_majority_femclk(pkt_prev); @@ -108,38 +111,38 @@ bool SingleTriggeredInput::CheckPoolAlignment(int pid, const std::array bad_diff_indices; for (size_t i = 0; i < n; ++i) { - if ( sebdiff[i] != gl1diff[i] ) + if (sebdiff[i] != gl1diff[i]) { - if ( !m_packetclk_copy_runs ) + if (!m_packetclk_copy_runs) { - //backup procedure to recover stuck 16bit XMIT clock - size_t idxcheck = i == 0 ? i+1 : i; + // backup procedure to recover stuck 16bit XMIT clock + size_t idxcheck = i == 0 ? i + 1 : i; bool passFemDiffCheckIdx = CheckFemDiffIdx(pid, idxcheck, m_PacketEventDeque[pid], gl1diff[idxcheck]); - if ( passFemDiffCheckIdx ) + if (passFemDiffCheckIdx) { m_OverrideWithRepClock.insert(pid); continue; } - } + } bad_diff_indices.push_back(i); } } if (bad_diff_indices.empty()) { - if ( Verbosity() > 0 ) + if (Verbosity() > 0) { std::cout << Name() << " recovered from bad XMIT clocks. Merging pool" << std::endl; } @@ -147,14 +150,14 @@ bool SingleTriggeredInput::CheckPoolAlignment(int pid, const std::array=5) + if (bad_diff_indices.size() >= 5) { std::cout << std::endl; std::cout << "----------------- " << Name() << " -----------------" << std::endl; std::cout << "More than 5 diffs are bad.. try shifting algorithm" << std::endl; move_to_shift_algo = true; } - if(!move_to_shift_algo) + if (!move_to_shift_algo) { std::cout << std::endl; std::cout << "----------------- " << Name() << " -----------------" << std::endl; @@ -164,23 +167,23 @@ bool SingleTriggeredInput::CheckPoolAlignment(int pid, const std::array=5) + if (length >= 5) { std::cout << Name() << ": length of bad diffs >=5 with bad_diff_indices.size() " << bad_diff_indices.size() << ". This should not have happened.. rejecting pool" << std::endl; return false; } - if(start==static_cast(pooldepth - 1)) + if (start == static_cast(pooldepth - 1)) { bad_indices.push_back(start); - CurrentPoolLastDiffBad= true; + CurrentPoolLastDiffBad = true; } - else if (start==0) + else if (start == 0) { if (PrevPoolLastDiffBad) { @@ -202,14 +205,14 @@ bool SingleTriggeredInput::CheckPoolAlignment(int pid, const std::array(pooldepth - 1) && start >0) + else if (start < static_cast(pooldepth - 1) && start > 0) { - if(length==1) + if (length == 1) { std::cout << Name() << ": Isolated bad diff[" << start << "] - rejecting pool" << std::endl; return false; } - if(length>=2) + if (length >= 2) { for (int j = start; j < end; ++j) { @@ -219,7 +222,7 @@ bool SingleTriggeredInput::CheckPoolAlignment(int pid, const std::array::max()); - static bool firstclockarray=true; - if(firstclockarray){ + static bool firstclockarray = true; + if (firstclockarray) + { std::cout << "first clock call pid " << pid << " m_bclkarray_map[pid][0] : " << m_bclkarray_map[pid][0] << std::endl; - firstclockarray=false; + firstclockarray = false; } - if ( representative_pid == -1 ) + if (representative_pid == -1) { representative_pid = pid; } } - if ( !allPacketEventDequeEmpty ) + if (!allPacketEventDequeEmpty) { return 0; } @@ -381,11 +385,11 @@ int SingleTriggeredInput::FillEventVector() if (gl1) { int nskip = gl1->GetGl1SkipArray()[i]; - if(nskip >0) + if (nskip > 0) { skiptrace = true; } - + while (nskip > 0) { Event* skip_evt = GetEventIterator()->getNextEvent(); @@ -399,7 +403,7 @@ int SingleTriggeredInput::FillEventVector() } skip_evt = GetEventIterator()->getNextEvent(); } - + if (skip_evt->getEvtType() != DATAEVENT) { delete skip_evt; @@ -434,7 +438,7 @@ int SingleTriggeredInput::FillEventVector() nskip--; } - if(skiptrace) + if (skiptrace) { evt = GetEventIterator()->getNextEvent(); while (!evt) @@ -468,12 +472,12 @@ int SingleTriggeredInput::FillEventVector() int gl1pid = Gl1Input()->m_bclkdiffarray_map.begin()->first; uint64_t gl1_diff = gl1->m_bclkdiffarray_map[gl1pid][i]; - bool clockconsistency=true; + bool clockconsistency = true; if (seb_diff != gl1_diff) { - clockconsistency=false; + clockconsistency = false; int clockconstcount = 0; - while(!clockconsistency && clockconstcount<5) + while (!clockconsistency && clockconstcount < 5) { std::cout << Name() << ": Still inconsistent clock diff after Gl1 drop. gl1diff vs sebdiff : " << gl1_diff << " vs " << seb_diff << std::endl; delete pkt; @@ -500,9 +504,9 @@ int SingleTriggeredInput::FillEventVector() uint64_t seb_diff_next = m_bclkdiffarray_map[representative_pid][i]; uint64_t gl1_diff_next = gl1->m_bclkdiffarray_map[gl1pid][i]; std::cout << "seb_diff_next : " << seb_diff_next << " , gl1_diff_next : " << gl1_diff_next << std::endl; - if(seb_diff_next == gl1_diff_next) + if (seb_diff_next == gl1_diff_next) { - clockconsistency=true; + clockconsistency = true; std::cout << Name() << " : recovered by additional skip in skiptrace" << std::endl; } clockconstcount++; @@ -536,22 +540,22 @@ int SingleTriggeredInput::FillEventVector() continue; } evt->convert(); - + if (firstcall) { std::cout << "Creating DSTs first call" << std::endl; CreateDSTNodes(evt); int run = evt->getRunNumber(); - m_packetclk_copy_runs = (run >= 44000 && run < 56079); + m_packetclk_copy_runs = (run >= 44000 && run < 56079); firstcall = false; } for (int pid : m_PacketSet) { - Event *thisevt = evt; + Event* thisevt = evt; if (m_PacketShiftOffset[pid] == 1) { - if (i==0) + if (i == 0) { thisevt = m_PacketEventBackup[pid]; m_ShiftedEvents[pid] = evt; @@ -560,13 +564,13 @@ int SingleTriggeredInput::FillEventVector() { thisevt = m_ShiftedEvents[pid]; m_ShiftedEvents[pid] = evt; - if (i == pooldepth -1) + if (i == pooldepth - 1) { m_PacketEventBackup[pid] = evt; } } } - + Packet* pkt = thisevt->getPacket(pid); if (!pkt) { @@ -594,7 +598,7 @@ int SingleTriggeredInput::FillEventVector() return minSize; } -uint64_t SingleTriggeredInput::GetClock(Event *evt, int pid) +uint64_t SingleTriggeredInput::GetClock(Event* evt, int pid) { Packet* packet = evt->getPacket(pid); if (!packet) @@ -625,20 +629,19 @@ void SingleTriggeredInput::FillPacketClock(Event* evt, Packet* pkt, size_t event auto& clkarray = m_bclkarray_map[pid]; auto& diffarray = m_bclkdiffarray_map[pid]; - // Special handling for FEM-copied clocks if (m_packetclk_copy_runs && m_CorrectCopiedClockPackets.contains(pid)) { if (event_index == 0) { - clkarray[event_index+1] = m_PreviousValidBCOMap[pid]; + clkarray[event_index + 1] = m_PreviousValidBCOMap[pid]; } - else if (event_index >=1) + else if (event_index >= 1) { Event* shifted_evt = m_PacketEventDeque[pid][event_index - 1]; - clkarray[event_index+1] = GetClock(shifted_evt, pid); + clkarray[event_index + 1] = GetClock(shifted_evt, pid); } - + uint64_t prev = clkarray[event_index]; uint64_t curr = clkarray[event_index + 1]; @@ -654,7 +657,6 @@ void SingleTriggeredInput::FillPacketClock(Event* evt, Packet* pkt, size_t event return; } - uint64_t clk = GetClock(evt, pid); if (clk == std::numeric_limits::max()) { @@ -665,7 +667,7 @@ void SingleTriggeredInput::FillPacketClock(Event* evt, Packet* pkt, size_t event clkarray[event_index + 1] = clk; uint64_t prev = clkarray[event_index]; - if(prev == std::numeric_limits::max()) + if (prev == std::numeric_limits::max()) { static std::unordered_set warned; @@ -689,7 +691,7 @@ void SingleTriggeredInput::FillPacketClock(Event* evt, Packet* pkt, size_t event { int packet_number = pkt->iValue(0); gl1->SetPacketNumbers(gl1->GetCurrentPacketNumber(), packet_number); - if ( event_index < pooldepth ) + if (event_index < pooldepth) { gl1->SetGl1PacketNumber(event_index, packet_number); } @@ -697,7 +699,7 @@ void SingleTriggeredInput::FillPacketClock(Event* evt, Packet* pkt, size_t event int skip_count = 0; if (gl1->GetLastPacketNumber() != 0) { - int diff = gl1->GetCurrentPacketNumber() - gl1->GetLastPacketNumber() ; + int diff = gl1->GetCurrentPacketNumber() - gl1->GetLastPacketNumber(); skip_count = diff - 1; } @@ -715,7 +717,8 @@ void SingleTriggeredInput::FillPool() return; } - bool all_packets_bad = !m_PacketAlignmentProblem.empty() && std::all_of(m_PacketAlignmentProblem.begin(), m_PacketAlignmentProblem.end(), [](const std::pair &entry) -> bool { return entry.second;}); + bool all_packets_bad = !m_PacketAlignmentProblem.empty() && std::all_of(m_PacketAlignmentProblem.begin(), m_PacketAlignmentProblem.end(), [](const std::pair& entry) -> bool + { return entry.second; }); if (all_packets_bad) { std::cout << Name() << ": ALL packets are marked as bad. Stop combining for this SEB." << std::endl; @@ -738,9 +741,8 @@ void SingleTriggeredInput::FillPool() int gl1pid = Gl1Input()->m_bclkdiffarray_map.begin()->first; const auto& gl1diff = Gl1Input()->m_bclkdiffarray_map.at(gl1pid); - bool allgl1max = std::all_of(gl1diff.begin(), gl1diff.end(), [](uint64_t val) { - return val == std::numeric_limits::max(); - }); + bool allgl1max = std::all_of(gl1diff.begin(), gl1diff.end(), [](uint64_t val) + { return val == std::numeric_limits::max(); }); if (allgl1max) { std::cout << Name() << " : GL1 clock diffs all filled with max 64 bit values for PID " << gl1pid << " return and try next pool" << std::endl; @@ -751,13 +753,13 @@ void SingleTriggeredInput::FillPool() for (const auto& [pid, sebdiff] : m_bclkdiffarray_map) { size_t packetpoolsize = m_PacketEventDeque[pid].size(); - if(packetpoolsize==0) + if (packetpoolsize == 0) { std::cout << Name() << ": packet pool size is zero.... something is wrong" << std::endl; return; } - if(m_PacketAlignmentProblem[pid]) + if (m_PacketAlignmentProblem[pid]) { continue; } @@ -768,22 +770,23 @@ void SingleTriggeredInput::FillPool() bool PrevPoolLastDiffBad = m_PrevPoolLastDiffBad[pid]; bool aligned = false; - if( packetpoolsize < pooldepth && FilesDone() ) + if (packetpoolsize < pooldepth && FilesDone()) { aligned = true; } - else + else { aligned = CheckPoolAlignment(pid, sebdiff, gl1diff, bad_indices, shift, CurrentPoolLastDiffBad, PrevPoolLastDiffBad); } - + if (aligned) { m_PrevPoolLastDiffBad[pid] = CurrentPoolLastDiffBad; if (!bad_indices.empty()) { std::cout << Name() << ": Packet " << pid << " has bad indices: "; - for (int bi : bad_indices){ + for (int bi : bad_indices) + { std::cout << bi << " "; m_DitchPackets[pid].insert(bi); } @@ -795,12 +798,13 @@ void SingleTriggeredInput::FillPool() uint64_t gl1_clk = Gl1Input()->m_bclkarray_map[gl1pid][i]; uint64_t seb_clk = m_bclkarray_map[pid][i]; std::cout << "pool index i " << i << ", gl1 / seb : " << gl1_clk << " / " << seb_clk; - if(im_bclkdiffarray_map[gl1pid][i]; uint64_t seb_diff = m_bclkdiffarray_map[pid][i]; std::cout << " -> diff of gl1 vs seb : " << gl1_diff << " " << seb_diff << std::endl; } - else if(i==pooldepth) + else if (i == pooldepth) { std::cout << std::endl; } @@ -810,11 +814,11 @@ void SingleTriggeredInput::FillPool() if (shift == -1) { std::cout << Name() << ": Packet " << pid << " shifted by -1 with dropping the first seb event" << std::endl; - if(m_PacketShiftOffset[pid] == -1) + if (m_PacketShiftOffset[pid] == -1) { std::cout << "Packet " << pid << " requires an additional shift -1. Lets not handle this for the moment.. stop combining" << std::endl; m_PacketAlignmentProblem[pid] = true; - } + } if (!m_PacketEventDeque[pid].empty()) { @@ -828,12 +832,12 @@ void SingleTriggeredInput::FillPool() for (size_t i = 0; i < packetpoolsize - 1; ++i) { - m_bclkarray_map[pid][i] = m_bclkarray_map[pid][i+1]; + m_bclkarray_map[pid][i] = m_bclkarray_map[pid][i + 1]; } for (size_t i = 0; i < packetpoolsize; ++i) { - m_bclkdiffarray_map[pid][i] = ComputeClockDiff(m_bclkarray_map[pid][i+1], m_bclkarray_map[pid][i]); + m_bclkdiffarray_map[pid][i] = ComputeClockDiff(m_bclkarray_map[pid][i + 1], m_bclkarray_map[pid][i]); } Event* evt = GetEventIterator()->getNextEvent(); if (evt) @@ -861,7 +865,7 @@ void SingleTriggeredInput::FillPool() else if (shift == 1) { std::cout << Name() << ": Packet " << pid << " requires shift +1 (insert dummy at front)" << std::endl; - + if (m_packetclk_copy_runs) { std::cout << Name() << " : runs where clocks are copied from the first XMIT. Checking FEM clock diff" << std::endl; @@ -879,7 +883,7 @@ void SingleTriggeredInput::FillPool() std::cout << Name() << " : Packet identified as misaligned also with FEMs. Do normal recovery process" << std::endl; } - if(m_PacketShiftOffset[pid] == 1) + if (m_PacketShiftOffset[pid] == 1) { std::cout << "Packet " << pid << " requires an additional shift +1. Lets not handle this for the moment.. stop combining" << std::endl; m_PacketAlignmentProblem[pid] = true; @@ -887,11 +891,11 @@ void SingleTriggeredInput::FillPool() for (size_t i = pooldepth; i > 0; --i) { - m_bclkarray_map[pid][i] = m_bclkarray_map[pid][i-1]; + m_bclkarray_map[pid][i] = m_bclkarray_map[pid][i - 1]; } - for (size_t i = 1 ; i < pooldepth; ++i) + for (size_t i = 1; i < pooldepth; ++i) { - m_bclkdiffarray_map[pid][i] = ComputeClockDiff(m_bclkarray_map[pid][i+1], m_bclkarray_map[pid][i]); + m_bclkdiffarray_map[pid][i] = ComputeClockDiff(m_bclkarray_map[pid][i + 1], m_bclkarray_map[pid][i]); } m_bclkarray_map[pid][0] = 0; @@ -901,7 +905,7 @@ void SingleTriggeredInput::FillPool() if (!m_PacketEventDeque[pid].empty()) { m_PacketEventBackup[pid] = m_PacketEventDeque[pid].back(); - Event* dummy_event = m_PacketEventDeque[pid][0]; + Event* dummy_event = m_PacketEventDeque[pid][0]; m_PacketEventDeque[pid].push_front(dummy_event); m_PacketEventDeque[pid].pop_back(); } @@ -924,12 +928,13 @@ void SingleTriggeredInput::FillPool() uint64_t gl1_clk = Gl1Input()->m_bclkarray_map[gl1pid][i]; uint64_t seb_clk = m_bclkarray_map[pid][i]; std::cout << "pool index i " << i << ", gl1 / seb : " << gl1_clk << " / " << seb_clk; - if(im_bclkdiffarray_map[gl1pid][i]; uint64_t seb_diff = m_bclkdiffarray_map[pid][i]; std::cout << " -- diff of gl1 vs seb : " << gl1_diff << " " << seb_diff << std::endl; } - else if(i==pooldepth) + else if (i == pooldepth) { std::cout << std::endl; } @@ -944,10 +949,10 @@ void SingleTriggeredInput::FillPool() if (m_PacketAlignmentFailCount[pid] >= m_max_alignment_retries) { std::cout << Name() << ": Max retries reached — permanently ditching packet " << pid << std::endl; - m_PacketAlignmentFailCount[pid] = 0; + m_PacketAlignmentFailCount[pid] = 0; m_PacketAlignmentProblem[pid] = true; } - + m_PrevPoolLastDiffBad[pid] = false; } } @@ -956,7 +961,7 @@ void SingleTriggeredInput::FillPool() return; } -void SingleTriggeredInput::CreateDSTNodes(Event *evt) +void SingleTriggeredInput::CreateDSTNodes(Event* evt) { std::string CompositeNodeName = "Packets"; if (KeepMyPackets()) @@ -964,31 +969,62 @@ void SingleTriggeredInput::CreateDSTNodes(Event *evt) CompositeNodeName = "PacketsKeep"; } PHNodeIterator iter(m_topNode); - PHCompositeNode *dstNode = dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); + PHCompositeNode* dstNode = dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); if (!dstNode) { dstNode = new PHCompositeNode("DST"); m_topNode->addNode(dstNode); } PHNodeIterator iterDst(dstNode); - PHCompositeNode *detNode = dynamic_cast(iterDst.findFirst("PHCompositeNode", CompositeNodeName)); - if (!detNode) + PHCompositeNode* detNode{nullptr}; + PHCompositeNode* detNodeKeep{nullptr}; + if (m_KeepPacketSet.empty()) { - detNode = new PHCompositeNode(CompositeNodeName); - dstNode->addNode(detNode); + detNode = dynamic_cast(iterDst.findFirst("PHCompositeNode", CompositeNodeName)); + if (!detNode) + { + detNode = new PHCompositeNode(CompositeNodeName); + dstNode->addNode(detNode); + } + } + else + { + // if we want to keep a few packets, we need two detNodes, Packet and PacketKeep + // this construct here allows for the KeepMyPackets flag to take effect, then both + // node pointers detNode and detNodeKeep point to the same (so KeepMyPackets has precedence) + detNode = dynamic_cast(iterDst.findFirst("PHCompositeNode", CompositeNodeName)); + if (!detNode) + { + detNode = new PHCompositeNode(CompositeNodeName); + dstNode->addNode(detNode); + } + detNodeKeep = dynamic_cast(iterDst.findFirst("PHCompositeNode", "PacketsKeep")); + if (!detNode) + { + detNodeKeep = new PHCompositeNode("PacketsKeep"); + dstNode->addNode(detNodeKeep); + } } - std::vector pktvec = evt->getPacketVector(); - for (auto *piter : pktvec) + + std::vector pktvec = evt->getPacketVector(); + for (auto* piter : pktvec) { int packet_id = piter->getIdentifier(); m_PacketSet.insert(packet_id); std::string PacketNodeName = std::to_string(packet_id); - CaloPacket *calopacket = findNode::getClass(detNode, PacketNodeName); + CaloPacket* calopacket = findNode::getClass(detNode, packet_id); if (!calopacket) { calopacket = new CaloPacketv1(); - PHIODataNode *newNode = new PHIODataNode(calopacket, PacketNodeName, "PHObject"); - detNode->addNode(newNode); + PHIODataNode* newNode = new PHIODataNode(calopacket, packet_id, "PHObject"); + if (m_KeepPacketSet.contains(packet_id)) + { + detNodeKeep->addNode(newNode); + } + else + { + detNode->addNode(newNode); + } } m_PacketShiftOffset.try_emplace(packet_id, 0); delete piter; @@ -1031,8 +1067,10 @@ bool SingleTriggeredInput::FemClockAlignment(int pid, const std::deque& } int majority_clk = std::max_element( - clk_count.begin(), clk_count.end(), - [](const auto& a, const auto& b) { return a.second < b.second; })->first; + clk_count.begin(), clk_count.end(), + [](const auto& a, const auto& b) + { return a.second < b.second; }) + ->first; if (clk_count[majority_clk] < 2) { @@ -1040,7 +1078,6 @@ bool SingleTriggeredInput::FemClockAlignment(int pid, const std::deque& return false; } - if (i >= 1 && prev_clk != std::numeric_limits::max() && gl1diff[i] != std::numeric_limits::max()) { uint16_t fem_diff = static_cast(ComputeClockDiff(majority_clk, prev_clk) & 0xFFFFU); @@ -1059,9 +1096,9 @@ bool SingleTriggeredInput::FemClockAlignment(int pid, const std::deque& return true; } -int SingleTriggeredInput::FemEventNrClockCheck(OfflinePacket *pkt) +int SingleTriggeredInput::FemEventNrClockCheck(OfflinePacket* pkt) { - CaloPacket *calopkt = dynamic_cast(pkt); + CaloPacket* calopkt = dynamic_cast(pkt); if (!calopkt) { return 0; @@ -1099,7 +1136,7 @@ int SingleTriggeredInput::FemEventNrClockCheck(OfflinePacket *pkt) } } } - else + else { for (int j = 0; j < nrModules; j++) { @@ -1147,7 +1184,7 @@ int SingleTriggeredInput::FemEventNrClockCheck(OfflinePacket *pkt) for (const auto iterA : ClockMap) { std::cout << "Clock : 0x" << std::hex << iterA.first << std::dec - << " shows up " << iterA.second << " times" << std::endl; + << " shows up " << iterA.second << " times" << std::endl; } } return -1; @@ -1158,8 +1195,8 @@ int SingleTriggeredInput::FemEventNrClockCheck(OfflinePacket *pkt) void SingleTriggeredInput::dumpdeque() { - const auto *iter1 = clkdiffbegin(); - const auto *iter2 = Gl1Input()->clkdiffbegin(); + const auto* iter1 = clkdiffbegin(); + const auto* iter2 = Gl1Input()->clkdiffbegin(); while (iter1 != clkdiffend()) { std::cout << Name() << " clk: 0x" << std::hex << *iter1 @@ -1191,11 +1228,11 @@ int SingleTriggeredInput::ReadEvent() std::cout << "deque size: " << size << std::endl; } - auto *ref_evt = m_PacketEventDeque.begin()->second.front(); + auto* ref_evt = m_PacketEventDeque.begin()->second.front(); RunNumber(ref_evt->getRunNumber()); uint64_t event_number = ref_evt->getEvtSequence(); - if(event_number % 10000==0) + if (event_number % 10000 == 0) { std::cout << "processed events : " << event_number << std::endl; } @@ -1204,12 +1241,13 @@ int SingleTriggeredInput::ReadEvent() bool all_packets_unshifted = std::all_of( m_PacketShiftOffset.begin(), m_PacketShiftOffset.end(), - [](const std::pair& p) { return p.second == 0; }); + [](const std::pair& p) + { return p.second == 0; }); std::set events_to_delete; for (auto& [pid, dq] : m_PacketEventDeque) { - if(m_PacketAlignmentProblem[pid]) + if (m_PacketAlignmentProblem[pid]) { continue; } @@ -1225,7 +1263,7 @@ int SingleTriggeredInput::ReadEvent() return -1; } - CaloPacket *newhit = findNode::getClass(m_topNode, packet_id); + CaloPacket* newhit = findNode::getClass(m_topNode, packet_id); newhit->Reset(); if (m_DitchPackets.contains(packet_id) && m_DitchPackets[packet_id].contains(0)) { @@ -1253,7 +1291,7 @@ int SingleTriggeredInput::ReadEvent() { uint64_t prev_packet_clock = m_PreviousValidBCOMap[packet_id]; newhit->setBCO(prev_packet_clock); - m_PreviousValidBCOMap[packet_id] = GetClock(evt,packet_id); + m_PreviousValidBCOMap[packet_id] = GetClock(evt, packet_id); } else { @@ -1292,7 +1330,7 @@ int SingleTriggeredInput::ReadEvent() int iret = FemEventNrClockCheck(newhit); if (iret < 0) { - std::cout << Name() <<" : failed on FemEventNrClockCheck reset calo packet " << std::endl; + std::cout << Name() << " : failed on FemEventNrClockCheck reset calo packet " << std::endl; newhit->Reset(); } @@ -1302,7 +1340,7 @@ int SingleTriggeredInput::ReadEvent() } } - for(Event *evtdelete : events_to_delete) + for (Event* evtdelete : events_to_delete) { delete evtdelete; } diff --git a/offline/framework/fun4allraw/SingleTriggeredInput.h b/offline/framework/fun4allraw/SingleTriggeredInput.h index d7d825b02a..cad0d64bf0 100644 --- a/offline/framework/fun4allraw/SingleTriggeredInput.h +++ b/offline/framework/fun4allraw/SingleTriggeredInput.h @@ -17,6 +17,7 @@ #include #include #include +#include #include class Event; @@ -58,15 +59,16 @@ class SingleTriggeredInput : public Fun4AllBase, public InputFileHandler virtual std::array::const_iterator beginclock() { return m_bclkarray.begin(); } virtual void KeepPackets() { m_KeepPacketsFlag = true; } virtual bool KeepMyPackets() const { return m_KeepPacketsFlag; } + virtual void KeepPacket(const int packetnum) { m_KeepPacketSet.insert(packetnum); } void topNode(PHCompositeNode *topNode) { m_topNode = topNode; } PHCompositeNode *topNode() { return m_topNode; } virtual void FakeProblemEvent(const int ievent) { m_ProblemEvent = ievent; } virtual int FemEventNrClockCheck(OfflinePacket *calopkt); void dumpdeque(); int checkfirstsebevent(); - virtual bool CheckFemDiffIdx(int pid, size_t index, const std::deque& events, uint64_t gl1diffidx); - virtual bool CheckPoolAlignment(int pid, const std::array& sebdiff, const std::array& gl1diff, std::vector& bad_indices, int& shift, bool& CurrentPoolLastDiffBad, bool PrevPoolLastDiffBad); - virtual bool FemClockAlignment(int pid, const std::deque& events, const std::array& gl1diff); + virtual bool CheckFemDiffIdx(int pid, size_t index, const std::deque &events, uint64_t gl1diffidx); + virtual bool CheckPoolAlignment(int pid, const std::array &sebdiff, const std::array &gl1diff, std::vector &bad_indices, int &shift, bool &CurrentPoolLastDiffBad, bool PrevPoolLastDiffBad); + virtual bool FemClockAlignment(int pid, const std::deque &events, const std::array &gl1diff); protected: PHCompositeNode *m_topNode{nullptr}; @@ -76,17 +78,16 @@ class SingleTriggeredInput : public Fun4AllBase, public InputFileHandler // the accompanying diff to the previous beam clock with this event, so any mismatch // gives us the event index in the deque which is off std::deque m_EventDeque; - std::map> m_PacketEventDeque; - std::map m_PacketEventBackup; + std::map> m_PacketEventDeque; + std::map m_PacketEventBackup; std::map m_PacketShiftOffset; std::array m_bclkarray{}; // keep the last bco from previous loop std::array m_bclkdiffarray{}; std::map> m_bclkarray_map; - std::map> m_bclkdiffarray_map; + std::map> m_bclkdiffarray_map; std::set m_PacketSet; static uint64_t ComputeClockDiff(uint64_t curr, uint64_t prev) { return (curr - prev) & 0xFFFFFFFF; } - private: Eventiterator *m_EventIterator{nullptr}; SingleTriggeredInput *m_Gl1Input{nullptr}; @@ -104,6 +105,7 @@ class SingleTriggeredInput : public Fun4AllBase, public InputFileHandler bool firstclockcheck{true}; bool m_KeepPacketsFlag{false}; bool m_packetclk_copy_runs{false}; + int64_t eventcounter{0}; std::set m_CorrectCopiedClockPackets; std::map> m_DitchPackets; std::set m_FEMEventNrSet; @@ -112,7 +114,7 @@ class SingleTriggeredInput : public Fun4AllBase, public InputFileHandler std::map m_PacketAlignmentProblem; std::map m_PrevPoolLastDiffBad; std::map m_PreviousValidBCOMap; - long long eventcounter{0}; + std::unordered_set m_KeepPacketSet; }; #endif From d271e6eaa70cc63c8bdd5a995192c9fb47abfa65 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 3 Mar 2026 17:10:23 -0500 Subject: [PATCH 317/393] thanks rabbit --- offline/framework/fun4allraw/SingleTriggeredInput.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/framework/fun4allraw/SingleTriggeredInput.cc b/offline/framework/fun4allraw/SingleTriggeredInput.cc index 999ca40531..9302b9ecc0 100644 --- a/offline/framework/fun4allraw/SingleTriggeredInput.cc +++ b/offline/framework/fun4allraw/SingleTriggeredInput.cc @@ -999,7 +999,7 @@ void SingleTriggeredInput::CreateDSTNodes(Event* evt) dstNode->addNode(detNode); } detNodeKeep = dynamic_cast(iterDst.findFirst("PHCompositeNode", "PacketsKeep")); - if (!detNode) + if (!detNodeKeep) { detNodeKeep = new PHCompositeNode("PacketsKeep"); dstNode->addNode(detNodeKeep); From c5e71449bb66e65b42e72e17120565120e1e2854 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 3 Mar 2026 18:05:09 -0500 Subject: [PATCH 318/393] fix clang-tidy --- offline/framework/fun4allraw/SingleTriggeredInput.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/offline/framework/fun4allraw/SingleTriggeredInput.cc b/offline/framework/fun4allraw/SingleTriggeredInput.cc index 9302b9ecc0..f2d3b34ef1 100644 --- a/offline/framework/fun4allraw/SingleTriggeredInput.cc +++ b/offline/framework/fun4allraw/SingleTriggeredInput.cc @@ -1011,7 +1011,6 @@ void SingleTriggeredInput::CreateDSTNodes(Event* evt) { int packet_id = piter->getIdentifier(); m_PacketSet.insert(packet_id); - std::string PacketNodeName = std::to_string(packet_id); CaloPacket* calopacket = findNode::getClass(detNode, packet_id); if (!calopacket) { From 9a58c6cc3f143ccac2a5d0b63603d025ad451a0c Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Wed, 4 Mar 2026 15:31:12 -0500 Subject: [PATCH 319/393] fix clang-tidy warnings --- offline/packages/TrackingDiagnostics/KshortReconstruction.cc | 2 +- offline/packages/TrackingDiagnostics/KshortReconstruction.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/offline/packages/TrackingDiagnostics/KshortReconstruction.cc b/offline/packages/TrackingDiagnostics/KshortReconstruction.cc index f197a3172e..0dd6d3c89c 100644 --- a/offline/packages/TrackingDiagnostics/KshortReconstruction.cc +++ b/offline/packages/TrackingDiagnostics/KshortReconstruction.cc @@ -394,7 +394,7 @@ void KshortReconstruction::fillNtp(SvtxTrack* track1, SvtxTrack* track2, float m float cos_theta_reco = pathLength_proj.dot(projected_momentum) / (projected_momentum.norm() * pathLength_proj.norm()); - float reco_info[] = {(float) track1->get_id(), (float) mass1, (float) track1->get_crossing(), track1->get_x(), track1->get_y(), track1->get_z(), track1->get_px(), track1->get_py(), track1->get_pz(), (float) dcavals1(0), (float) dcavals1(1), (float) dcavals1(2), (float) pca_rel1(0), (float) pca_rel1(1), (float) pca_rel1(2), (float) eta1, (float) track1->get_charge(), (float) tpcClusters1, (float) track2->get_id(), (float) mass2, (float) track2->get_crossing(), track2->get_x(), track2->get_y(), track2->get_z(), track2->get_px(), track2->get_py(), track2->get_pz(), (float) dcavals2(0), (float) dcavals2(1), (float) dcavals2(2), (float) pca_rel2(0), (float) pca_rel2(1), (float) pca_rel2(2), (float) eta2, (float) track2->get_charge(), (float) tpcClusters2, (float) ntracks_vertex, (float) vertex(0), (float) vertex(1), (float) vertex(2), (float) pair_dca, (float) invariantMass, (float) invariantPt, invariantPhi, (float) pathLength(0), (float) pathLength(1), (float) pathLength(2), mag_pathLength, rapidity, pseudorapidity, (float) projected_pos1(0), (float) projected_pos1(1), (float) projected_pos1(2), (float) projected_pos2(0), (float) projected_pos2(1), (float) projected_pos2(2), (float) projected_mom1(0), (float) projected_mom1(1), (float) projected_mom1(2), (float) projected_mom2(0), (float) projected_mom2(1), (float) projected_mom2(2), (float) pca_rel1_proj(0), (float) pca_rel1_proj(1), (float) pca_rel1_proj(2), (float) pca_rel2_proj(0), (float) pca_rel2_proj(1), (float) pca_rel2_proj(2), (float) pair_dca_proj, (float) pathLength_proj(0), (float) pathLength_proj(1), (float) pathLength_proj(2), mag_pathLength_proj, track1->get_quality(), track2->get_quality(), cos_theta_reco, (float) track1_silicon_cluster_size, (float) track2_silicon_cluster_size, (float) track1_mvtx_cluster_size, (float) track1_mvtx_state_size, (float) track1_intt_cluster_size, (float) track1_intt_state_size, (float) track2_mvtx_cluster_size, (float) track2_mvtx_state_size, (float) track2_intt_cluster_size, (float) track2_intt_state_size, (float) runNumber, (float) eventNumber}; + float reco_info[] = {(float) track1->get_id(), mass1, (float) track1->get_crossing(), track1->get_x(), track1->get_y(), track1->get_z(), track1->get_px(), track1->get_py(), track1->get_pz(), (float) dcavals1(0), (float) dcavals1(1), (float) dcavals1(2), (float) pca_rel1(0), (float) pca_rel1(1), (float) pca_rel1(2), (float) eta1, (float) track1->get_charge(), (float) tpcClusters1, (float) track2->get_id(), mass2, (float) track2->get_crossing(), track2->get_x(), track2->get_y(), track2->get_z(), track2->get_px(), track2->get_py(), track2->get_pz(), (float) dcavals2(0), (float) dcavals2(1), (float) dcavals2(2), (float) pca_rel2(0), (float) pca_rel2(1), (float) pca_rel2(2), (float) eta2, (float) track2->get_charge(), (float) tpcClusters2, (float) ntracks_vertex, (float) vertex(0), (float) vertex(1), (float) vertex(2), (float) pair_dca, (float) invariantMass, (float) invariantPt, invariantPhi, (float) pathLength(0), (float) pathLength(1), (float) pathLength(2), mag_pathLength, rapidity, pseudorapidity, (float) projected_pos1(0), (float) projected_pos1(1), (float) projected_pos1(2), (float) projected_pos2(0), (float) projected_pos2(1), (float) projected_pos2(2), (float) projected_mom1(0), (float) projected_mom1(1), (float) projected_mom1(2), (float) projected_mom2(0), (float) projected_mom2(1), (float) projected_mom2(2), (float) pca_rel1_proj(0), (float) pca_rel1_proj(1), (float) pca_rel1_proj(2), (float) pca_rel2_proj(0), (float) pca_rel2_proj(1), (float) pca_rel2_proj(2), (float) pair_dca_proj, (float) pathLength_proj(0), (float) pathLength_proj(1), (float) pathLength_proj(2), mag_pathLength_proj, track1->get_quality(), track2->get_quality(), cos_theta_reco, (float) track1_silicon_cluster_size, (float) track2_silicon_cluster_size, (float) track1_mvtx_cluster_size, (float) track1_mvtx_state_size, (float) track1_intt_cluster_size, (float) track1_intt_state_size, (float) track2_mvtx_cluster_size, (float) track2_mvtx_state_size, (float) track2_intt_cluster_size, (float) track2_intt_state_size, (float) runNumber, (float) eventNumber}; ntp_reco_info->Fill(reco_info); } diff --git a/offline/packages/TrackingDiagnostics/KshortReconstruction.h b/offline/packages/TrackingDiagnostics/KshortReconstruction.h index 2057ed18e2..9499c9bab8 100644 --- a/offline/packages/TrackingDiagnostics/KshortReconstruction.h +++ b/offline/packages/TrackingDiagnostics/KshortReconstruction.h @@ -44,7 +44,7 @@ class KshortReconstruction : public SubsysReco // void fillNtp(SvtxTrack* track1, SvtxTrack* track2, Acts::Vector3 dcavals1, Acts::Vector3 dcavals2, Acts::Vector3 pca_rel1, Acts::Vector3 pca_rel2, double pair_dca, double invariantMass, double invariantPt, float invariantPhi, float rapidity, float pseudorapidity, Eigen::Vector3d projected_pos1, Eigen::Vector3d projected_pos2, Eigen::Vector3d projected_mom1, Eigen::Vector3d projected_mom2, Acts::Vector3 pca_rel1_proj, Acts::Vector3 pca_rel2_proj, double pair_dca_proj,unsigned int track1_silicon_cluster_size, unsigned int track2_silicon_cluster_size, unsigned int track1_mvtx_cluster_size, unsigned int track1_mvtx_state_size, unsigned int track1_intt_cluster_size, unsigned int track1_intt_state_size, unsigned int track2_mvtx_cluster_size, unsigned int track2_mvtx_state_size, unsigned int track2_intt_cluster_size, unsigned int track2_intt_state_size, int runNumber, int eventNumber); - void fillHistogram(Eigen::Vector3d mom1, Eigen::Vector3d mom2, TH1* massreco, double& invariantMass, double& invariantPt, float& invariantPhi, float& rapidity, float& pseudorapidity, float& decaymass1, float& decaymass2); + void fillHistogram(Eigen::Vector3d mom1, Eigen::Vector3d mom2, TH1* massreco, double& invariantMass, double& invariantPt, float& invariantPhi, float& rapidity, float& pseudorapidity, float& decaymassa, float& decaymassb); // void fillHistogram(Eigen::Vector3d mom1, Eigen::Vector3d mom2, TH1* massreco, double& invariantMass, double& invariantPt, float& invariantPhi, float& rapidity, float& pseudorapidity); From 01ba052b95b51785b2e81d114aa77c2e5e02b4b4 Mon Sep 17 00:00:00 2001 From: JAEBEOm PARK Date: Wed, 4 Mar 2026 18:33:46 -0500 Subject: [PATCH 320/393] added functionality to reject particles from hadron decays + speed up filtering process --- .../HepMCTrigger/HepMCParticleTrigger.cc | 104 +++++++++++++++--- .../HepMCTrigger/HepMCParticleTrigger.h | 13 ++- 2 files changed, 98 insertions(+), 19 deletions(-) diff --git a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc index 81d594e528..eccb80ce6c 100644 --- a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc +++ b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.cc @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include //____________________________________________________________________________.. // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) @@ -267,11 +269,6 @@ void HepMCParticleTrigger::SetAbsEtaHighLow(double ptHigh, double ptLow) } bool HepMCParticleTrigger::isGoodEvent(HepMC::GenEvent* e1) { - // this is really just the call to actually evaluate and return the filter - /*if (this->threshold == 0) - { - return true; - }*/ std::vector n_trigger_particles = getParticles(e1); for (auto ntp : n_trigger_particles) { @@ -286,21 +283,46 @@ bool HepMCParticleTrigger::isGoodEvent(HepMC::GenEvent* e1) std::vector HepMCParticleTrigger::getParticles(HepMC::GenEvent* e1) { std::vector n_trigger{}; - std::map particle_types; + std::unordered_set particle_pids; + particle_pids.reserve(_theParticles.size()); + for (auto it : _theParticles) + { + particle_pids.insert(std::abs(it)); + } + std::unordered_map particle_types; + particle_types.reserve(particle_pids.size()); + for (HepMC::GenEvent::particle_const_iterator iter = e1->particles_begin(); iter != e1->particles_end(); ++iter) { - if (m_doStableParticleOnly && ((*iter)->end_vertex() || (*iter)->status() != 1)) + const HepMC::GenParticle *g = *iter; + if (m_doStableParticleOnly && (g->end_vertex() || g->status() != 1)) + { + continue; + } + + int pid = std::abs(g->pdg_id()); + auto ipidx = particle_pids.find(pid); + if(ipidx == particle_pids.end()) { continue; } - auto p = (*iter)->momentum(); + + if (m_rejectFromHadronDecay) + { + if(IsFromHadronDecay(g)) + { + continue; + } + } + + auto p = g->momentum(); float px = p.px(); float py = p.py(); float pz = p.pz(); float p_M = std::sqrt(std::pow(px, 2) + std::pow(py, 2) + std::pow(pz, 2)); float pt = std::sqrt(std::pow(px, 2) + std::pow(py, 2)); - int pid = std::abs((*iter)->pdg_id()); double eta = p.eta(); + if ((_doEtaHighCut || _doBothEtaCut) && eta > _theEtaHigh) { continue; @@ -341,22 +363,25 @@ std::vector HepMCParticleTrigger::getParticles(HepMC::GenEvent* e1) { continue; } - if (particle_types.contains(pid)) - { - particle_types[pid]++; - } - else + + particle_types[pid]++; + + if(particle_types.size() == particle_pids.size()) { - particle_types[pid] = 1; + break; } } + n_trigger.reserve(_theParticles.size()); - for (auto p : _theParticles) + + for (auto it : _theParticles) { - n_trigger.push_back(particleAboveThreshold(particle_types, p)); // make sure we have at least one of each required particle + auto ptid = particle_types.find(std::abs(it)); + n_trigger.push_back((ptid != particle_types.end()) ? ptid->second : 0); } return n_trigger; } + int HepMCParticleTrigger::particleAboveThreshold(const std::map& n_particles, int trigger_particle) { // search through for the number of identified trigger particles passing cuts @@ -367,3 +392,48 @@ int HepMCParticleTrigger::particleAboveThreshold(const std::map& n_par } return 0; } + +bool HepMCParticleTrigger::IsFromHadronDecay(const HepMC::GenParticle* gp) +{ + if (!gp) + { + return false; + } + + const HepMC::GenVertex* vtx = gp->production_vertex(); + if (!vtx) + { + return false; + } + + for (auto it = vtx->particles_in_const_begin(); it != vtx->particles_in_const_end(); ++it) + { + const HepMC::GenParticle* mom = *it; + if (!mom) + { + continue; + } + + if (IsHadronPDG(mom->pdg_id())) + { + return true; + } + } + return false; +} + + +bool HepMCParticleTrigger::IsHadronPDG(int _pdg) +{ + if(IsIonPDG(_pdg)) + { + return false; + } + + if(std::abs(_pdg) < 100 ) + { + return false; + } + + return true; +} diff --git a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h index e0494cb3e7..22bcf241d4 100644 --- a/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h +++ b/generators/Herwig/HepMCTrigger/HepMCParticleTrigger.h @@ -16,6 +16,7 @@ class PHCompositeNode; namespace HepMC { class GenEvent; + class GenParticle; } class HepMCParticleTrigger : public SubsysReco @@ -65,10 +66,15 @@ class HepMCParticleTrigger : public SubsysReco void SetPzLow(double); void SetPzHighLow(double, double); + void SetRejectFromHadronDecay(bool b) {m_rejectFromHadronDecay = b;} void SetStableParticleOnly(bool b) { m_doStableParticleOnly = b; } + int getNevts(){return this->n_evts;} int getNgood(){return this->n_good;} + bool IsFromHadronDecay(const HepMC::GenParticle* gp); + bool IsIonPDG(int _pdg) { return (std::abs(_pdg) >= 1000000000); } + private: bool isGoodEvent(HepMC::GenEvent* e1); std::vector getParticles(HepMC::GenEvent* e1); @@ -76,14 +82,15 @@ class HepMCParticleTrigger : public SubsysReco // std::vector _theParentsi {}; std::vector _theParticles{}; bool m_doStableParticleOnly{true}; + bool m_rejectFromHadronDecay{true}; float threshold{0.}; int goal_event_number{1000}; bool set_event_limit{false}; int n_evts{0}; int n_good{0}; - float _theEtaHigh{1.1}; - float _theEtaLow{-1.1}; + float _theEtaHigh{2.0}; + float _theEtaLow{-2.0}; float _thePtHigh{999.9}; float _thePtLow{-999.9}; float _thePHigh{999.9}; @@ -110,6 +117,8 @@ class HepMCParticleTrigger : public SubsysReco bool _doPzHighCut{false}; bool _doPzLowCut{false}; bool _doBothPzCut{false}; + + bool IsHadronPDG(int _pdg); }; #endif // HEPMCPARTICLETRIGGER_H From a41f4ee984f8f25b6fc344486ec87bde9f25aedf Mon Sep 17 00:00:00 2001 From: bkimelman <120117749+bkimelman@users.noreply.github.com> Date: Wed, 4 Mar 2026 19:18:58 -0600 Subject: [PATCH 321/393] JetCalib Constituents Propagate constituents from uncalibrated jet to calibrated one --- offline/packages/jetbase/JetCalib.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/offline/packages/jetbase/JetCalib.cc b/offline/packages/jetbase/JetCalib.cc index cc2fdd11b9..a6c9b8cf4d 100644 --- a/offline/packages/jetbase/JetCalib.cc +++ b/offline/packages/jetbase/JetCalib.cc @@ -244,6 +244,7 @@ int JetCalib::process_event(PHCompositeNode *topNode) calib_jet->set_py(calib_pt * std::sin(phi)); calib_jet->set_pz(calib_pt * std::sinh(eta)); calib_jet->set_id(ijet); + calib_jet->insert_comp(jet->get_comp_vec(), true); calib_jet->set_isCalib(1); ijet++; } From 645cbf251110d3f353145b3a18f0c6b5e1903c49 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Wed, 4 Mar 2026 20:45:54 -0500 Subject: [PATCH 322/393] revert ntuple contents to float --- offline/packages/tpc/Tpc3DClusterizer.cc | 2 +- offline/packages/tpc/TpcCombinedRawDataUnpacker.cc | 6 +++--- offline/packages/tpc/TpcCombinedRawDataUnpackerDebug.cc | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/offline/packages/tpc/Tpc3DClusterizer.cc b/offline/packages/tpc/Tpc3DClusterizer.cc index bdbfbb99e4..ac2add2c37 100644 --- a/offline/packages/tpc/Tpc3DClusterizer.cc +++ b/offline/packages/tpc/Tpc3DClusterizer.cc @@ -657,7 +657,7 @@ void Tpc3DClusterizer::calc_cluster_parameter(std::vector &clusHi << std::endl; */ // if (m_output){ - double fX[20] = {0}; + float fX[20] = {0}; int n = 0; fX[n++] = m_event; fX[n++] = m_seed; diff --git a/offline/packages/tpc/TpcCombinedRawDataUnpacker.cc b/offline/packages/tpc/TpcCombinedRawDataUnpacker.cc index 5abec18a2c..f5e436c6d7 100644 --- a/offline/packages/tpc/TpcCombinedRawDataUnpacker.cc +++ b/offline/packages/tpc/TpcCombinedRawDataUnpacker.cc @@ -449,7 +449,7 @@ int TpcCombinedRawDataUnpacker::process_event(PHCompositeNode* topNode) if (m_writeTree) { - double fXh[18]; + float fXh[18]; int nh = 0; fXh[nh++] = _ievent - 1; @@ -547,7 +547,7 @@ int TpcCombinedRawDataUnpacker::process_event(PHCompositeNode* topNode) if (m_writeTree) { - double fXh[11]; + float fXh[11]; int nh = 0; fXh[nh++] = _ievent - 1; @@ -629,7 +629,7 @@ int TpcCombinedRawDataUnpacker::process_event(PHCompositeNode* topNode) if (m_writeTree) { - double fXh[18]; + float fXh[18]; int nh = 0; fXh[nh++] = _ievent - 1; diff --git a/offline/packages/tpc/TpcCombinedRawDataUnpackerDebug.cc b/offline/packages/tpc/TpcCombinedRawDataUnpackerDebug.cc index c7dfe58261..2e2cc693e6 100644 --- a/offline/packages/tpc/TpcCombinedRawDataUnpackerDebug.cc +++ b/offline/packages/tpc/TpcCombinedRawDataUnpackerDebug.cc @@ -278,7 +278,7 @@ int TpcCombinedRawDataUnpackerDebug::process_event(PHCompositeNode* topNode) unsigned int phibin = layergeom->get_phibin(phi, side); if (m_writeTree) { - double fX[12]; + float fX[12]; int n = 0; fX[n++] = _ievent - 1; @@ -487,7 +487,7 @@ int TpcCombinedRawDataUnpackerDebug::process_event(PHCompositeNode* topNode) } if (m_writeTree) { - double fXh[18]; + float fXh[18]; int nh = 0; fXh[nh++] = _ievent - 1; @@ -716,7 +716,7 @@ int TpcCombinedRawDataUnpackerDebug::process_event(PHCompositeNode* topNode) #endif if (m_writeTree) { - double fXh[18]; + float fXh[18]; int nh = 0; fXh[nh++] = _ievent - 1; From 6ff05b1ff14050b9efdaf89d2e5cb9745498d26e Mon Sep 17 00:00:00 2001 From: Anthony Denis Frawley Date: Thu, 5 Mar 2026 00:21:33 -0500 Subject: [PATCH 323/393] Implement some coderabbit suggestions. --- .../KshortReconstruction.cc | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/offline/packages/TrackingDiagnostics/KshortReconstruction.cc b/offline/packages/TrackingDiagnostics/KshortReconstruction.cc index f197a3172e..11f88aec21 100644 --- a/offline/packages/TrackingDiagnostics/KshortReconstruction.cc +++ b/offline/packages/TrackingDiagnostics/KshortReconstruction.cc @@ -361,14 +361,14 @@ void KshortReconstruction::fillNtp(SvtxTrack* track1, SvtxTrack* track2, float m double py1 = track1->get_py(); double pz1 = track1->get_pz(); auto *tpcSeed1 = track1->get_tpc_seed(); - size_t tpcClusters1 = tpcSeed1->size_cluster_keys(); + size_t tpcClusters1 = tpcSeed1 ? tpcSeed1->size_cluster_keys() : 0; double eta1 = asinh(pz1 / sqrt(pow(px1, 2) + pow(py1, 2))); double px2 = track2->get_px(); double py2 = track2->get_py(); double pz2 = track2->get_pz(); auto *tpcSeed2 = track2->get_tpc_seed(); - size_t tpcClusters2 = tpcSeed2->size_cluster_keys(); + size_t tpcClusters2 = tpcSeed2 ? tpcSeed2->size_cluster_keys() : 0; double eta2 = asinh(pz2 / sqrt(pow(px2, 2) + pow(py2, 2))); auto vtxid = track1->get_vertex_id(); @@ -391,8 +391,12 @@ void KshortReconstruction::fillNtp(SvtxTrack* track1, SvtxTrack* track2, float m float mag_pathLength_proj = sqrt(pow(pathLength_proj(0), 2) + pow(pathLength_proj(1), 2) + pow(pathLength_proj(2), 2)); Acts::Vector3 projected_momentum = projected_mom1 + projected_mom2; - float cos_theta_reco = pathLength_proj.dot(projected_momentum) / (projected_momentum.norm() * pathLength_proj.norm()); - + const double denom = projected_momentum.norm() * pathLength_proj.norm(); + float cos_theta_reco = 0.0; + if (denom > 1e-12) + { + cos_theta_reco = pathLength_proj.dot(projected_momentum) / denom; + } float reco_info[] = {(float) track1->get_id(), (float) mass1, (float) track1->get_crossing(), track1->get_x(), track1->get_y(), track1->get_z(), track1->get_px(), track1->get_py(), track1->get_pz(), (float) dcavals1(0), (float) dcavals1(1), (float) dcavals1(2), (float) pca_rel1(0), (float) pca_rel1(1), (float) pca_rel1(2), (float) eta1, (float) track1->get_charge(), (float) tpcClusters1, (float) track2->get_id(), (float) mass2, (float) track2->get_crossing(), track2->get_x(), track2->get_y(), track2->get_z(), track2->get_px(), track2->get_py(), track2->get_pz(), (float) dcavals2(0), (float) dcavals2(1), (float) dcavals2(2), (float) pca_rel2(0), (float) pca_rel2(1), (float) pca_rel2(2), (float) eta2, (float) track2->get_charge(), (float) tpcClusters2, (float) ntracks_vertex, (float) vertex(0), (float) vertex(1), (float) vertex(2), (float) pair_dca, (float) invariantMass, (float) invariantPt, invariantPhi, (float) pathLength(0), (float) pathLength(1), (float) pathLength(2), mag_pathLength, rapidity, pseudorapidity, (float) projected_pos1(0), (float) projected_pos1(1), (float) projected_pos1(2), (float) projected_pos2(0), (float) projected_pos2(1), (float) projected_pos2(2), (float) projected_mom1(0), (float) projected_mom1(1), (float) projected_mom1(2), (float) projected_mom2(0), (float) projected_mom2(1), (float) projected_mom2(2), (float) pca_rel1_proj(0), (float) pca_rel1_proj(1), (float) pca_rel1_proj(2), (float) pca_rel2_proj(0), (float) pca_rel2_proj(1), (float) pca_rel2_proj(2), (float) pair_dca_proj, (float) pathLength_proj(0), (float) pathLength_proj(1), (float) pathLength_proj(2), mag_pathLength_proj, track1->get_quality(), track2->get_quality(), cos_theta_reco, (float) track1_silicon_cluster_size, (float) track2_silicon_cluster_size, (float) track1_mvtx_cluster_size, (float) track1_mvtx_state_size, (float) track1_intt_cluster_size, (float) track1_intt_state_size, (float) track2_mvtx_cluster_size, (float) track2_mvtx_state_size, (float) track2_intt_cluster_size, (float) track2_intt_state_size, (float) runNumber, (float) eventNumber}; @@ -636,15 +640,21 @@ void KshortReconstruction::findPcaTwoTracks(const Acts::Vector3& pos1, const Act } // get the points at which the normal to the lines intersect the lines, where the lines are perpendicular - double X = b1.dot(b2) - (b1.dot(b1) * b2.dot(b2) / b2.dot(b1)); - double Y = (a2.dot(b2) - a1.dot(b2)) - ((a2.dot(b1) - a1.dot(b1)) * b2.dot(b2) / b2.dot(b1)); - double c = Y / X; - double F = b1.dot(b1) / b2.dot(b1); - double G = -(a2.dot(b1) - a1.dot(b1)) / b2.dot(b1); - double d = (c * F) + G; - - // then the points of closest approach are: + // coderabbit suggestion + const double b1b1 = b1.dot(b1); + const double b2b2 = b2.dot(b2); + const double b1b2 = b1.dot(b2); + const double denom = b1b1 * b2b2 - b1b2 * b1b2; + if (std::abs(denom) < 1e-12) + { + return; + } + const Eigen::Vector3d w0 = a1 - a2; + const double c = (b1b2 * b2.dot(w0) - b2b2 * b1.dot(w0)) / denom; + const double d = (b1b1 * b2.dot(w0) - b1b2 * b1.dot(w0)) / denom; + + // then the points of closest approach are: pca1 = a1 + c * b1; pca2 = a2 + d * b2; From 378a198b99318b47020589d44f3025747f8bb152 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Thu, 5 Mar 2026 08:37:17 -0500 Subject: [PATCH 324/393] clang-tidy --- offline/packages/tpc/Tpc3DClusterizer.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/tpc/Tpc3DClusterizer.cc b/offline/packages/tpc/Tpc3DClusterizer.cc index ac2add2c37..71a0b0f7c0 100644 --- a/offline/packages/tpc/Tpc3DClusterizer.cc +++ b/offline/packages/tpc/Tpc3DClusterizer.cc @@ -571,7 +571,7 @@ void Tpc3DClusterizer::calc_cluster_parameter(std::vector &clusHi clus->setHitX(clus->getNhits() - 1, r * cos(phi)); clus->setHitY(clus->getNhits() - 1, r * sin(phi)); clus->setHitZ(clus->getNhits() - 1, hitZ); - clus->setHitAdc(clus->getNhits() - 1, (double) adc); + clus->setHitAdc(clus->getNhits() - 1, adc); rSum += r * adc; phiSum += phi * adc; From 629b41567d9b581bf03d6d680499b44c4a3c17fa Mon Sep 17 00:00:00 2001 From: mchiu-bnl Date: Thu, 5 Mar 2026 12:42:40 -0500 Subject: [PATCH 325/393] implement dummy get_chi2ndf, get_fitinfo --- offline/packages/mbd/MbdRawHitV1.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/offline/packages/mbd/MbdRawHitV1.h b/offline/packages/mbd/MbdRawHitV1.h index ddb5e593e7..3b33d62e2c 100644 --- a/offline/packages/mbd/MbdRawHitV1.h +++ b/offline/packages/mbd/MbdRawHitV1.h @@ -39,6 +39,18 @@ class MbdRawHitV1 : public MbdRawHit bqtdc = tq; } + //! dummy method, only exists in V2 + void set_chi2ndf(const Double_t /*chi2ndf*/) override + { + return; + } + + //! dummy method, only exists in V2 + void set_fitinfo(const UShort_t /*fitinfo*/) override + { + return; + } + //! Prints out exact identity of object void identify(std::ostream& out = std::cout) const override; From 693abaada34bc4f97c293359f10ed1bd3e1a4bfa Mon Sep 17 00:00:00 2001 From: mchiu-bnl Date: Thu, 5 Mar 2026 13:06:45 -0500 Subject: [PATCH 326/393] limit number of times virtual function spits out warning --- offline/packages/mbd/MbdRawHit.h | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/offline/packages/mbd/MbdRawHit.h b/offline/packages/mbd/MbdRawHit.h index 510a68b32f..862194352b 100644 --- a/offline/packages/mbd/MbdRawHit.h +++ b/offline/packages/mbd/MbdRawHit.h @@ -42,13 +42,23 @@ class MbdRawHit : public PHObject virtual Float_t get_chi2ndf() const { - PHOOL_VIRTUAL_WARNING; + static int ctr = 0; + if ( ctr<3 ) + { + PHOOL_VIRTUAL_WARNING; + ctr++; + } return MbdReturnCodes::MBD_INVALID_FLOAT; } virtual UShort_t get_fitinfo() const { - PHOOL_VIRTUAL_WARNING; + static int ctr = 0; + if ( ctr<3 ) + { + PHOOL_VIRTUAL_WARNING; + ctr++; + } return 0; } @@ -59,12 +69,22 @@ class MbdRawHit : public PHObject virtual void set_chi2ndf(const Double_t /*chi2ndf*/) { - PHOOL_VIRTUAL_WARNING; + static int ctr = 0; + if ( ctr<3 ) + { + PHOOL_VIRTUAL_WARNING; + ctr++; + } } virtual void set_fitinfo(const UShort_t /*fitinfo*/) { - PHOOL_VIRTUAL_WARNING; + static int ctr = 0; + if ( ctr<3 ) + { + PHOOL_VIRTUAL_WARNING; + ctr++; + } } virtual void identify(std::ostream& out = std::cout) const override; From a15f76e587f55a7d0a894ce80e9daa35a1a44a36 Mon Sep 17 00:00:00 2001 From: cdean-github Date: Fri, 6 Mar 2026 10:49:05 -0500 Subject: [PATCH 327/393] Kshort and KFP updates --- .../KFParticle_sPHENIX/KFParticle_Tools.cc | 4 + .../KFParticle_truthAndDetTools.cc | 6 +- .../KshortReconstruction.cc | 158 +++++++++++++++--- .../KshortReconstruction.h | 31 +++- 4 files changed, 174 insertions(+), 25 deletions(-) diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc b/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc index 7d48ed6b75..9bb76608ee 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc @@ -1162,6 +1162,10 @@ float KFParticle_Tools::get_dEdx(PHCompositeNode *topNode, const KFParticle &dau { m_dst_trackmap = findNode::getClass(topNode, m_trk_map_node_name); m_cluster_map = findNode::getClass(topNode, "TRKR_CLUSTER"); + if (!m_cluster_map) + { + m_cluster_map = findNode::getClass(topNode, "TRKR_CLUSTER_SEED"); + } m_geom_container = findNode::getClass(topNode, "TPCGEOMCONTAINER"); auto *geometry = findNode::getClass(topNode, "ActsGeometry"); if (!m_cluster_map || !m_geom_container || !geometry) diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_truthAndDetTools.cc b/offline/packages/KFParticle_sPHENIX/KFParticle_truthAndDetTools.cc index f8373c9e6f..14b353ff43 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_truthAndDetTools.cc +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_truthAndDetTools.cc @@ -1299,7 +1299,11 @@ void KFParticle_truthAndDetTools::fillDetectorBranch(PHCompositeNode *topNode, dst_clustermap = findNode::getClass(topNode, "TRKR_CLUSTER"); if (!dst_clustermap) { - std::cout << "KFParticle detector info: TRKR_CLUSTER does not exist" << std::endl; + dst_clustermap = findNode::getClass(topNode, "TRKR_CLUSTER_SEED"); + if (!dst_clustermap) + { + std::cout << "KFParticle detector info: TRKR_CLUSTER does not exist" << std::endl; + } } track = getTrack(daughter.Id(), dst_trackmap); diff --git a/offline/packages/TrackingDiagnostics/KshortReconstruction.cc b/offline/packages/TrackingDiagnostics/KshortReconstruction.cc index 53afae2b1e..9d1e868aa7 100644 --- a/offline/packages/TrackingDiagnostics/KshortReconstruction.cc +++ b/offline/packages/TrackingDiagnostics/KshortReconstruction.cc @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -24,6 +25,7 @@ #include #pragma GCC diagnostic pop +#include #include #include #include @@ -56,11 +58,57 @@ int KshortReconstruction::process_event(PHCompositeNode* topNode) m_runNumber = m_evtNumber = -1; } + //Truth matching setup. Setting IDs and getting nodes + if (m_truth_match) + { + if (m_used_string) + { + m_mother_id = getMotherPDG(); + } + + m_truthinfo = findNode::getClass(topNode, "G4TruthInfo"); + + if (!m_truthinfo) //Missing truth info container. Disable truth matching + { + m_truth_match = false; + } + + } + + // Loop over tracks and check for close DCA match with all other tracks for (auto tr1_it = m_svtxTrackMap->begin(); tr1_it != m_svtxTrackMap->end(); ++tr1_it) { + auto id1 = tr1_it->first; auto *tr1 = tr1_it->second; + + //Truth matching. Let's see if this track came from the right mother + if (m_truth_match) + { + truth_particle_1 = getTruthTrack(tr1, topNode); + + if (truth_particle_1 == nullptr) + { + continue; + } + + int parent_id = truth_particle_1->get_parent_id(); + if (parent_id == 0) //Particle is primary. Trying to access its parent returns nullptr + { + continue; + } + + PHG4Particle *g4mother = m_truthinfo->GetParticle(parent_id); + + if (g4mother == nullptr || (abs(g4mother->get_pid()) != abs(m_mother_id))) //PID check + { + continue; + } + + truth_mother_id_particle_1 = g4mother->get_barcode(); + } + if (tr1->get_quality() > _qual_cut) { continue; @@ -134,6 +182,37 @@ int KshortReconstruction::process_event(PHCompositeNode* topNode) auto id2 = tr2_it->first; auto *tr2 = tr2_it->second; + //Truth matching. Let's see if this track came from the right mother + if (m_truth_match) + { + truth_particle_2 = getTruthTrack(tr2, topNode); + + if (truth_particle_2 == nullptr) + { + continue; + } + + int parent_id = truth_particle_2->get_parent_id(); + if (parent_id == 0) //Particle is primary. Trying to access its parent returns nullptr + { + continue; + } + PHG4Particle *g4mother = m_truthinfo->GetParticle(parent_id); + + if (g4mother == nullptr || (abs(g4mother->get_pid()) != abs(m_mother_id))) //PID check + { + continue; + } + + truth_mother_id_particle_2 = g4mother->get_barcode(); + + //Check that the two tracks came from the same mother + if (truth_mother_id_particle_1 != truth_mother_id_particle_2) + { + continue; + } + } + // dca xy and dca z cut here compare to track dca cut Acts::Vector3 pos2(tr2->get_x(), tr2->get_y(), tr2->get_z()); Acts::Vector3 mom2(tr2->get_px(), tr2->get_py(), tr2->get_pz()); @@ -361,14 +440,14 @@ void KshortReconstruction::fillNtp(SvtxTrack* track1, SvtxTrack* track2, float m double py1 = track1->get_py(); double pz1 = track1->get_pz(); auto *tpcSeed1 = track1->get_tpc_seed(); - size_t tpcClusters1 = tpcSeed1 ? tpcSeed1->size_cluster_keys() : 0; + size_t tpcClusters1 = tpcSeed1->size_cluster_keys(); double eta1 = asinh(pz1 / sqrt(pow(px1, 2) + pow(py1, 2))); double px2 = track2->get_px(); double py2 = track2->get_py(); double pz2 = track2->get_pz(); auto *tpcSeed2 = track2->get_tpc_seed(); - size_t tpcClusters2 = tpcSeed2 ? tpcSeed2->size_cluster_keys() : 0; + size_t tpcClusters2 = tpcSeed2->size_cluster_keys(); double eta2 = asinh(pz2 / sqrt(pow(px2, 2) + pow(py2, 2))); auto vtxid = track1->get_vertex_id(); @@ -391,14 +470,10 @@ void KshortReconstruction::fillNtp(SvtxTrack* track1, SvtxTrack* track2, float m float mag_pathLength_proj = sqrt(pow(pathLength_proj(0), 2) + pow(pathLength_proj(1), 2) + pow(pathLength_proj(2), 2)); Acts::Vector3 projected_momentum = projected_mom1 + projected_mom2; - const double denom = projected_momentum.norm() * pathLength_proj.norm(); - float cos_theta_reco = 0.0; - if (denom > 1e-12) - { - cos_theta_reco = pathLength_proj.dot(projected_momentum) / denom; - } + float cos_theta_reco = pathLength_proj.dot(projected_momentum) / (projected_momentum.norm() * pathLength_proj.norm()); + - float reco_info[] = {(float) track1->get_id(), mass1, (float) track1->get_crossing(), track1->get_x(), track1->get_y(), track1->get_z(), track1->get_px(), track1->get_py(), track1->get_pz(), (float) dcavals1(0), (float) dcavals1(1), (float) dcavals1(2), (float) pca_rel1(0), (float) pca_rel1(1), (float) pca_rel1(2), (float) eta1, (float) track1->get_charge(), (float) tpcClusters1, (float) track2->get_id(), mass2, (float) track2->get_crossing(), track2->get_x(), track2->get_y(), track2->get_z(), track2->get_px(), track2->get_py(), track2->get_pz(), (float) dcavals2(0), (float) dcavals2(1), (float) dcavals2(2), (float) pca_rel2(0), (float) pca_rel2(1), (float) pca_rel2(2), (float) eta2, (float) track2->get_charge(), (float) tpcClusters2, (float) ntracks_vertex, (float) vertex(0), (float) vertex(1), (float) vertex(2), (float) pair_dca, (float) invariantMass, (float) invariantPt, invariantPhi, (float) pathLength(0), (float) pathLength(1), (float) pathLength(2), mag_pathLength, rapidity, pseudorapidity, (float) projected_pos1(0), (float) projected_pos1(1), (float) projected_pos1(2), (float) projected_pos2(0), (float) projected_pos2(1), (float) projected_pos2(2), (float) projected_mom1(0), (float) projected_mom1(1), (float) projected_mom1(2), (float) projected_mom2(0), (float) projected_mom2(1), (float) projected_mom2(2), (float) pca_rel1_proj(0), (float) pca_rel1_proj(1), (float) pca_rel1_proj(2), (float) pca_rel2_proj(0), (float) pca_rel2_proj(1), (float) pca_rel2_proj(2), (float) pair_dca_proj, (float) pathLength_proj(0), (float) pathLength_proj(1), (float) pathLength_proj(2), mag_pathLength_proj, track1->get_quality(), track2->get_quality(), cos_theta_reco, (float) track1_silicon_cluster_size, (float) track2_silicon_cluster_size, (float) track1_mvtx_cluster_size, (float) track1_mvtx_state_size, (float) track1_intt_cluster_size, (float) track1_intt_state_size, (float) track2_mvtx_cluster_size, (float) track2_mvtx_state_size, (float) track2_intt_cluster_size, (float) track2_intt_state_size, (float) runNumber, (float) eventNumber}; + float reco_info[] = {(float) track1->get_id(), (float) mass1, (float) track1->get_crossing(), track1->get_x(), track1->get_y(), track1->get_z(), track1->get_px(), track1->get_py(), track1->get_pz(), (float) dcavals1(0), (float) dcavals1(1), (float) dcavals1(2), (float) pca_rel1(0), (float) pca_rel1(1), (float) pca_rel1(2), (float) eta1, (float) track1->get_charge(), (float) tpcClusters1, (float) track2->get_id(), (float) mass2, (float) track2->get_crossing(), track2->get_x(), track2->get_y(), track2->get_z(), track2->get_px(), track2->get_py(), track2->get_pz(), (float) dcavals2(0), (float) dcavals2(1), (float) dcavals2(2), (float) pca_rel2(0), (float) pca_rel2(1), (float) pca_rel2(2), (float) eta2, (float) track2->get_charge(), (float) tpcClusters2, (float) ntracks_vertex, (float) vertex(0), (float) vertex(1), (float) vertex(2), (float) pair_dca, (float) invariantMass, (float) invariantPt, invariantPhi, (float) pathLength(0), (float) pathLength(1), (float) pathLength(2), mag_pathLength, rapidity, pseudorapidity, (float) projected_pos1(0), (float) projected_pos1(1), (float) projected_pos1(2), (float) projected_pos2(0), (float) projected_pos2(1), (float) projected_pos2(2), (float) projected_mom1(0), (float) projected_mom1(1), (float) projected_mom1(2), (float) projected_mom2(0), (float) projected_mom2(1), (float) projected_mom2(2), (float) pca_rel1_proj(0), (float) pca_rel1_proj(1), (float) pca_rel1_proj(2), (float) pca_rel2_proj(0), (float) pca_rel2_proj(1), (float) pca_rel2_proj(2), (float) pair_dca_proj, (float) pathLength_proj(0), (float) pathLength_proj(1), (float) pathLength_proj(2), mag_pathLength_proj, track1->get_quality(), track2->get_quality(), cos_theta_reco, (float) track1_silicon_cluster_size, (float) track2_silicon_cluster_size, (float) track1_mvtx_cluster_size, (float) track1_mvtx_state_size, (float) track1_intt_cluster_size, (float) track1_intt_state_size, (float) track2_mvtx_cluster_size, (float) track2_mvtx_state_size, (float) track2_intt_cluster_size, (float) track2_intt_state_size, (float) runNumber, (float) eventNumber}; ntp_reco_info->Fill(reco_info); } @@ -640,21 +715,15 @@ void KshortReconstruction::findPcaTwoTracks(const Acts::Vector3& pos1, const Act } // get the points at which the normal to the lines intersect the lines, where the lines are perpendicular + double X = b1.dot(b2) - (b1.dot(b1) * b2.dot(b2) / b2.dot(b1)); + double Y = (a2.dot(b2) - a1.dot(b2)) - ((a2.dot(b1) - a1.dot(b1)) * b2.dot(b2) / b2.dot(b1)); + double c = Y / X; - // coderabbit suggestion - const double b1b1 = b1.dot(b1); - const double b2b2 = b2.dot(b2); - const double b1b2 = b1.dot(b2); - const double denom = b1b1 * b2b2 - b1b2 * b1b2; - if (std::abs(denom) < 1e-12) - { - return; - } - const Eigen::Vector3d w0 = a1 - a2; - const double c = (b1b2 * b2.dot(w0) - b2b2 * b1.dot(w0)) / denom; - const double d = (b1b1 * b2.dot(w0) - b1b2 * b1.dot(w0)) / denom; - - // then the points of closest approach are: + double F = b1.dot(b1) / b2.dot(b1); + double G = -(a2.dot(b1) - a1.dot(b1)) / b2.dot(b1); + double d = (c * F) + G; + + // then the points of closest approach are: pca1 = a1 + c * b1; pca2 = a2 + d * b2; @@ -851,3 +920,46 @@ int KshortReconstruction::getNodes(PHCompositeNode* topNode) return Fun4AllReturnCodes::EVENT_OK; } + +int KshortReconstruction::getMotherPDG() +{ + return TDatabasePDG::Instance()->GetParticle(m_mother_name.c_str())->PdgCode(); +} + +PHG4Particle *KshortReconstruction::getTruthTrack(SvtxTrack *thisTrack, PHCompositeNode *topNode) +{ + /* + * There are two methods for getting the truth rack from the reco track + * 1. (recommended) Use the reco -> truth tables (requires SvtxPHG4ParticleMap). Introduced Summer of 2022 + * 2. Get truth track via nClusters. Older method and will work with older DSTs + */ + + PHG4Particle *particle = nullptr; + + SvtxPHG4ParticleMap *dst_reco_truth_map = findNode::getClass(topNode, "SvtxPHG4ParticleMap"); + if (dst_reco_truth_map) + { + std::map> truth_set = dst_reco_truth_map->get(thisTrack->get_id()); + if (!truth_set.empty()) + { + std::pair> best_weight = *truth_set.rbegin(); + int best_truth_id = *best_weight.second.rbegin(); + particle = m_truthinfo->GetParticle(best_truth_id); + } + } + else + { + if (!m_svtx_evalstack) + { + m_svtx_evalstack = new SvtxEvalStack(topNode); + trackeval = m_svtx_evalstack->get_track_eval(); + //trutheval = m_svtx_evalstack->get_truth_eval(); + //vertexeval = m_svtx_evalstack->get_vertex_eval(); + } + + m_svtx_evalstack->next_event(topNode); + + particle = trackeval->max_truth_particle_by_nclusters(thisTrack); + } + return particle; +} diff --git a/offline/packages/TrackingDiagnostics/KshortReconstruction.h b/offline/packages/TrackingDiagnostics/KshortReconstruction.h index 9499c9bab8..7eed20507c 100644 --- a/offline/packages/TrackingDiagnostics/KshortReconstruction.h +++ b/offline/packages/TrackingDiagnostics/KshortReconstruction.h @@ -5,6 +5,11 @@ #include +#include +#include +#include +#include + #include class TFile; @@ -39,12 +44,17 @@ class KshortReconstruction : public SubsysReco void set_output_file(const std::string& outputfile) { filepath = outputfile; } void save_tracks(bool save = true) { m_save_tracks = save; } + //Truth matching code + void truthMatch(bool match = true) { m_truth_match = match; } + void setMotherID(std::string id = "K_S0") { m_mother_name = id; m_used_string = true; } + void setMotherID(int id = 310) { m_mother_id = id; m_used_string = false; } + private: void fillNtp(SvtxTrack* track1, SvtxTrack* track2, float mass1, float mass2, Acts::Vector3 dcavals1, Acts::Vector3 dcavals2, Acts::Vector3 pca_rel1, Acts::Vector3 pca_rel2, double pair_dca, double invariantMass, double invariantPt, float invariantPhi, float rapidity, float pseudorapidity, Eigen::Vector3d projected_pos1, Eigen::Vector3d projected_pos2, Eigen::Vector3d projected_mom1, Eigen::Vector3d projected_mom2, Acts::Vector3 pca_rel1_proj, Acts::Vector3 pca_rel2_proj, double pair_dca_proj,unsigned int track1_silicon_cluster_size, unsigned int track2_silicon_cluster_size, unsigned int track1_mvtx_cluster_size, unsigned int track1_mvtx_state_size, unsigned int track1_intt_cluster_size, unsigned int track1_intt_state_size, unsigned int track2_mvtx_cluster_size, unsigned int track2_mvtx_state_size, unsigned int track2_intt_cluster_size, unsigned int track2_intt_state_size, int runNumber, int eventNumber); // void fillNtp(SvtxTrack* track1, SvtxTrack* track2, Acts::Vector3 dcavals1, Acts::Vector3 dcavals2, Acts::Vector3 pca_rel1, Acts::Vector3 pca_rel2, double pair_dca, double invariantMass, double invariantPt, float invariantPhi, float rapidity, float pseudorapidity, Eigen::Vector3d projected_pos1, Eigen::Vector3d projected_pos2, Eigen::Vector3d projected_mom1, Eigen::Vector3d projected_mom2, Acts::Vector3 pca_rel1_proj, Acts::Vector3 pca_rel2_proj, double pair_dca_proj,unsigned int track1_silicon_cluster_size, unsigned int track2_silicon_cluster_size, unsigned int track1_mvtx_cluster_size, unsigned int track1_mvtx_state_size, unsigned int track1_intt_cluster_size, unsigned int track1_intt_state_size, unsigned int track2_mvtx_cluster_size, unsigned int track2_mvtx_state_size, unsigned int track2_intt_cluster_size, unsigned int track2_intt_state_size, int runNumber, int eventNumber); - void fillHistogram(Eigen::Vector3d mom1, Eigen::Vector3d mom2, TH1* massreco, double& invariantMass, double& invariantPt, float& invariantPhi, float& rapidity, float& pseudorapidity, float& decaymassa, float& decaymassb); + void fillHistogram(Eigen::Vector3d mom1, Eigen::Vector3d mom2, TH1* massreco, double& invariantMass, double& invariantPt, float& invariantPhi, float& rapidity, float& pseudorapidity, float& decaymass1, float& decaymass2); // void fillHistogram(Eigen::Vector3d mom1, Eigen::Vector3d mom2, TH1* massreco, double& invariantMass, double& invariantPt, float& invariantPhi, float& rapidity, float& pseudorapidity); @@ -83,6 +93,25 @@ class KshortReconstruction : public SubsysReco bool m_save_tracks {false}; SvtxTrackMap *m_output_trackMap {nullptr}; std::string m_output_trackMap_node_name {"KshortReconstruction_SvtxTrackMap"}; + + //Truth matching code + bool m_truth_match {false}; + bool m_used_string {false}; + std::string m_mother_name {"K_S0"}; + int m_mother_id {310}; + + PHG4Particle *truth_particle_1 {nullptr}; + PHG4Particle *truth_particle_2 {nullptr}; + int truth_mother_id_particle_1 {0}; + int truth_mother_id_particle_2 {0}; + + PHG4TruthInfoContainer *m_truthinfo {nullptr}; + SvtxEvalStack *m_svtx_evalstack {nullptr}; + SvtxTrackEval *trackeval {nullptr}; + + int getMotherPDG(); + PHG4Particle *getTruthTrack(SvtxTrack *thisTrack, PHCompositeNode *topNode); + }; #endif // KSHORTRECONSTRUCTION_H From add82a131d1c1ee8e459990658c6928a018cc877 Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Mon, 9 Mar 2026 16:16:17 -0400 Subject: [PATCH 328/393] Eventplaneinfo - order (int -> unsigned int) - Reduce the number of static_casts by changing the type of `order` from int to unsigned int - Improve readability --- .../packages/eventplaneinfo/Eventplaneinfo.h | 14 +++++------ .../eventplaneinfo/Eventplaneinfov1.h | 10 ++++---- .../eventplaneinfo/Eventplaneinfov2.h | 24 +++++++++---------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/offline/packages/eventplaneinfo/Eventplaneinfo.h b/offline/packages/eventplaneinfo/Eventplaneinfo.h index c01756deca..04b085a393 100644 --- a/offline/packages/eventplaneinfo/Eventplaneinfo.h +++ b/offline/packages/eventplaneinfo/Eventplaneinfo.h @@ -26,15 +26,15 @@ class Eventplaneinfo : public PHObject virtual void set_qvector_raw(const std::vector>& /*Qvec*/) { return; } virtual void set_qvector_recentered(const std::vector>& /*Qvec*/) { return; } virtual void set_shifted_psi(const std::vector& /*Psi_Shifted*/) { return; } - virtual std::pair get_qvector(int /*order*/) const { return std::make_pair(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); } - virtual std::pair get_qvector_raw(int /*order*/) const { return std::make_pair(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); } - virtual std::pair get_qvector_recentered(int /*order*/) const { return std::make_pair(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); } - virtual double get_psi(int /*order*/) const { return std::numeric_limits::quiet_NaN(); } - virtual double get_shifted_psi(int /*order*/) const { return std::numeric_limits::quiet_NaN(); } + virtual std::pair get_qvector(unsigned int /*order*/) const { return std::make_pair(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); } + virtual std::pair get_qvector_raw(unsigned int /*order*/) const { return std::make_pair(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); } + virtual std::pair get_qvector_recentered(unsigned int /*order*/) const { return std::make_pair(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); } + virtual double get_psi(unsigned int /*order*/) const { return std::numeric_limits::quiet_NaN(); } + virtual double get_shifted_psi(unsigned int /*order*/) const { return std::numeric_limits::quiet_NaN(); } virtual double GetPsi(const double /*Qx*/, const double /*Qy*/, const unsigned int /*order*/) const { return std::numeric_limits::quiet_NaN(); } virtual void set_ring_qvector(const std::vector>>& /*RingQvecs*/) { return; } - virtual std::pair get_ring_qvector(int /*rbin*/, int /*order*/) const { return std::make_pair(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); } - virtual double get_ring_psi(int /*rbin*/, int /*order*/) const { return std::numeric_limits::quiet_NaN(); } + virtual std::pair get_ring_qvector(int /*rbin*/, unsigned int /*order*/) const { return std::make_pair(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); } + virtual double get_ring_psi(int /*rbin*/, unsigned int /*order*/) const { return std::numeric_limits::quiet_NaN(); } protected: Eventplaneinfo() = default; diff --git a/offline/packages/eventplaneinfo/Eventplaneinfov1.h b/offline/packages/eventplaneinfo/Eventplaneinfov1.h index 1950e2ef31..2b027323ea 100644 --- a/offline/packages/eventplaneinfo/Eventplaneinfov1.h +++ b/offline/packages/eventplaneinfo/Eventplaneinfov1.h @@ -28,13 +28,13 @@ class Eventplaneinfov1 : public Eventplaneinfo void set_qvector(const std::vector>& Qvec) override { mQvec = Qvec; } void set_shifted_psi(const std::vector& Psi_Shifted) override { mPsi_Shifted = Psi_Shifted; } - std::pair get_qvector(int order) const override { return std::make_pair(mQvec[order - 1].first, mQvec[order - 1].second); } + std::pair get_qvector(unsigned int order) const override { return std::make_pair(mQvec[order - 1].first, mQvec[order - 1].second); } void set_ring_qvector(const std::vector>>& Qvec) override { ring_Qvec = Qvec; } - std::pair get_ring_qvector(int ring_index, int order) const override { return ring_Qvec[ring_index][order - 1]; } - double get_ring_psi(int ring_index, int order) const override {return GetPsi(ring_Qvec[ring_index][order - 1].first,ring_Qvec[ring_index][order - 1].second,order);} + std::pair get_ring_qvector(int ring_index, unsigned int order) const override { return ring_Qvec[ring_index][order - 1]; } + double get_ring_psi(int ring_index, unsigned int order) const override {return GetPsi(ring_Qvec[ring_index][order - 1].first,ring_Qvec[ring_index][order - 1].second,order);} double GetPsi(double Qx, double Qy, unsigned int order) const override; - double get_psi(int order) const override { return GetPsi(mQvec[order - 1].first, mQvec[order - 1].second, order);} - double get_shifted_psi(int order) const override { return mPsi_Shifted[order - 1]; } + double get_psi(unsigned int order) const override { return GetPsi(mQvec[order - 1].first, mQvec[order - 1].second, order);} + double get_shifted_psi(unsigned int order) const override { return mPsi_Shifted[order - 1]; } private: std::vector> mQvec; diff --git a/offline/packages/eventplaneinfo/Eventplaneinfov2.h b/offline/packages/eventplaneinfo/Eventplaneinfov2.h index b6f5bf7793..5ad62fe979 100644 --- a/offline/packages/eventplaneinfo/Eventplaneinfov2.h +++ b/offline/packages/eventplaneinfo/Eventplaneinfov2.h @@ -32,11 +32,11 @@ class Eventplaneinfov2 : public Eventplaneinfo void set_qvector_raw(const std::vector>& Qvec) override { mQvec_raw = Qvec; } void set_qvector_recentered(const std::vector>& Qvec) override { mQvec_recentered = Qvec; } void set_shifted_psi(const std::vector& Psi_Shifted) override { mPsi_Shifted = Psi_Shifted; } - std::pair get_qvector(int order) const override { return safe_qvec(mQvec, order); } - std::pair get_qvector_raw(int order) const override { return safe_qvec(mQvec_raw, order); } - std::pair get_qvector_recentered(int order) const override { return safe_qvec(mQvec_recentered, order); } + std::pair get_qvector(unsigned int order) const override { return safe_qvec(mQvec, order); } + std::pair get_qvector_raw(unsigned int order) const override { return safe_qvec(mQvec_raw, order); } + std::pair get_qvector_recentered(unsigned int order) const override { return safe_qvec(mQvec_recentered, order); } void set_ring_qvector(const std::vector>>& Qvec) override { ring_Qvec = Qvec; } - std::pair get_ring_qvector(int ring_index, int order) const override + std::pair get_ring_qvector(int ring_index, unsigned int order) const override { if (ring_index < 0 || static_cast(ring_index) >= ring_Qvec.size()) { @@ -44,21 +44,21 @@ class Eventplaneinfov2 : public Eventplaneinfo } return safe_qvec(ring_Qvec[ring_index], order); } - double get_ring_psi(int ring_index, int order) const override + double get_ring_psi(int ring_index, unsigned int order) const override { auto q = get_ring_qvector(ring_index, order); - return GetPsi(q.first, q.second, static_cast(order)); + return GetPsi(q.first, q.second, order); } double GetPsi(double Qx, double Qy, unsigned int order) const override; - double get_psi(int order) const override + double get_psi(unsigned int order) const override { auto q = get_qvector(order); - return GetPsi(q.first, q.second, static_cast(order)); + return GetPsi(q.first, q.second, order); } - double get_shifted_psi(int order) const override + double get_shifted_psi(unsigned int order) const override { - if (order <= 0 || static_cast(order) > mPsi_Shifted.size()) + if (order <= 0 || order > mPsi_Shifted.size()) { return std::numeric_limits::quiet_NaN(); } @@ -66,9 +66,9 @@ class Eventplaneinfov2 : public Eventplaneinfo } private: - static std::pair safe_qvec(const std::vector>& v, int order) + static std::pair safe_qvec(const std::vector>& v, unsigned int order) { - if (order <= 0 || static_cast(order) > v.size()) + if (order <= 0 || order > v.size()) { return {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}; } From dee334d6eec96ab0102f7f66ffd0dbd402670220 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Mon, 9 Mar 2026 19:08:39 -0400 Subject: [PATCH 329/393] syncing mod works --- offline/packages/bcolumicount/BcoInfo.cc | 26 +++++ offline/packages/bcolumicount/BcoInfo.h | 44 +++++++ .../packages/bcolumicount/BcoInfoLinkDef.h | 5 + offline/packages/bcolumicount/BcoInfov1.cc | 25 ++++ offline/packages/bcolumicount/BcoInfov1.h | 48 ++++++++ .../packages/bcolumicount/BcoInfov1LinkDef.h | 5 + offline/packages/bcolumicount/BcoLumiReco.cc | 107 ++++++++++++++++++ offline/packages/bcolumicount/BcoLumiReco.h | 31 +++++ offline/packages/bcolumicount/Makefile.am | 80 +++++++++++++ offline/packages/bcolumicount/autogen.sh | 8 ++ offline/packages/bcolumicount/configure.ac | 20 ++++ 11 files changed, 399 insertions(+) create mode 100644 offline/packages/bcolumicount/BcoInfo.cc create mode 100644 offline/packages/bcolumicount/BcoInfo.h create mode 100644 offline/packages/bcolumicount/BcoInfoLinkDef.h create mode 100644 offline/packages/bcolumicount/BcoInfov1.cc create mode 100644 offline/packages/bcolumicount/BcoInfov1.h create mode 100644 offline/packages/bcolumicount/BcoInfov1LinkDef.h create mode 100644 offline/packages/bcolumicount/BcoLumiReco.cc create mode 100644 offline/packages/bcolumicount/BcoLumiReco.h create mode 100644 offline/packages/bcolumicount/Makefile.am create mode 100755 offline/packages/bcolumicount/autogen.sh create mode 100644 offline/packages/bcolumicount/configure.ac diff --git a/offline/packages/bcolumicount/BcoInfo.cc b/offline/packages/bcolumicount/BcoInfo.cc new file mode 100644 index 0000000000..f816401b49 --- /dev/null +++ b/offline/packages/bcolumicount/BcoInfo.cc @@ -0,0 +1,26 @@ +#include "BcoInfo.h" + +#include + +#include + +class PHObject; + +void BcoInfo::Reset() +{ + std::cout << PHWHERE << "ERROR Reset() not implemented by daughter class" << std::endl; + return; +} + +void BcoInfo::identify(std::ostream& os) const +{ + os << "identify yourself: virtual BcoInfo Object" << std::endl; + return; +} + +int BcoInfo::isValid() const +{ + std::cout << PHWHERE << "isValid not implemented by daughter class" << std::endl; + return 0; +} + diff --git a/offline/packages/bcolumicount/BcoInfo.h b/offline/packages/bcolumicount/BcoInfo.h new file mode 100644 index 0000000000..be1b0bdbf3 --- /dev/null +++ b/offline/packages/bcolumicount/BcoInfo.h @@ -0,0 +1,44 @@ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef BCOLLUMICOUNT_BCOINFO_H +#define BCOLLUMICOUNT_BCOINFO_H + +#include + +#include +#include + +/// +class BcoInfo : public PHObject +{ + public: + /// ctor - daughter class copy ctor needs this + BcoInfo() = default; + /// dtor + ~BcoInfo() override = default; + /// Clear Sync + void Reset() override; + + /** identify Function from PHObject + @param os Output Stream + */ + void identify(std::ostream& os = std::cout) const override; + + /// isValid returns non zero if object contains valid data + int isValid() const override; + + uint64_t get_previous_bco() const {return 0;} + uint64_t get_current_bco() const {return 0;} + uint64_t get_future_bco() const {return 0;} + + void set_previous_bco(uint64_t /*val*/) {return;} + void set_current_bco(uint64_t /*val*/) {return;} + void set_future_bco(uint64_t /*val*/) {return;} + + + private: + + ClassDefOverride(BcoInfo, 1) +}; + +#endif diff --git a/offline/packages/bcolumicount/BcoInfoLinkDef.h b/offline/packages/bcolumicount/BcoInfoLinkDef.h new file mode 100644 index 0000000000..54907ed5fe --- /dev/null +++ b/offline/packages/bcolumicount/BcoInfoLinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class BcoInfo + ; + +#endif diff --git a/offline/packages/bcolumicount/BcoInfov1.cc b/offline/packages/bcolumicount/BcoInfov1.cc new file mode 100644 index 0000000000..1d0516f375 --- /dev/null +++ b/offline/packages/bcolumicount/BcoInfov1.cc @@ -0,0 +1,25 @@ +#include "BcoInfov1.h" + +void BcoInfov1::Reset() +{ + bco.fill(0); + return; +} + +void BcoInfov1::identify(std::ostream& out) const +{ + out << "identify yourself: I am an BcoInfov1 Object\n"; + out << std::hex; + out << "bco prev event: 0x" << get_previous_bco() << "\n" + << "bco curr event: 0x" << get_current_bco() << "\n" + << "bco futu event: 0x" << get_future_bco() + << std::dec + << std::endl; + + return; +} + +int BcoInfov1::isValid() const +{ + return (bco[2] ? 1 : 0); // return 1 if future bco is not zero +} diff --git a/offline/packages/bcolumicount/BcoInfov1.h b/offline/packages/bcolumicount/BcoInfov1.h new file mode 100644 index 0000000000..03308d0b38 --- /dev/null +++ b/offline/packages/bcolumicount/BcoInfov1.h @@ -0,0 +1,48 @@ +// Tell emacs that this is a C++ source +// -*- C++ -*-. +#ifndef BCOLUMICOUNT_BCOINFOV1_H +#define BCOLUMICOUNT_BCOINFOV1_H + +#include "BcoInfo.h" + +#include +#include + +class PHObject; + +class BcoInfov1 : public BcoInfo +{ + public: + /// ctor + BcoInfov1() = default; + + /// dtor + ~BcoInfov1() override = default; + + /// Clear Event + void Reset() override; + + /** identify Function from PHObject + @param os Output Stream + */ + void identify(std::ostream& out = std::cout) const override; + + /// isValid returns non zero if object contains valid data + int isValid() const override; + + uint64_t get_previous_bco() const {return bco[0];} + uint64_t get_current_bco() const {return bco[1];} + uint64_t get_future_bco() const {return bco[2];} + + void set_previous_bco(uint64_t val) {bco[0] = val;} + void set_current_bco(uint64_t val) {bco[1] = val;} + void set_future_bco(uint64_t val) {bco[2] = val;} + + + private: + std::array bco{0}; + + ClassDefOverride(BcoInfov1, 1) +}; + +#endif diff --git a/offline/packages/bcolumicount/BcoInfov1LinkDef.h b/offline/packages/bcolumicount/BcoInfov1LinkDef.h new file mode 100644 index 0000000000..41672f57b9 --- /dev/null +++ b/offline/packages/bcolumicount/BcoInfov1LinkDef.h @@ -0,0 +1,5 @@ +#ifdef __CINT__ + +#pragma link C++ class BcoInfov1 + ; + +#endif diff --git a/offline/packages/bcolumicount/BcoLumiReco.cc b/offline/packages/bcolumicount/BcoLumiReco.cc new file mode 100644 index 0000000000..fd9625bfd9 --- /dev/null +++ b/offline/packages/bcolumicount/BcoLumiReco.cc @@ -0,0 +1,107 @@ +#include "BcoLumiReco.h" + +#include +#include + +#include +#include +#include // for SubsysReco + +#include +#include +#include // for PHNode +#include // for PHNodeIterator +#include // for PHObject +#include +#include // for PHWHERE +#include + +#include +#include + +#include + +BcoLumiReco::BcoLumiReco(const std::string &name) + : SubsysReco(name) +{ + return; +} + +int BcoLumiReco::Init(PHCompositeNode *topNode) +{ + int iret = CreateNodeTree(topNode); + return iret; +} + +int BcoLumiReco::InitRun(PHCompositeNode */*topNode*/) +{ + return Fun4AllReturnCodes::EVENT_OK; +} + +int BcoLumiReco::CreateNodeTree(PHCompositeNode *topNode) +{ + PHNodeIterator iter(topNode); + PHCompositeNode *dstNode; + dstNode = dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); + if (!dstNode) + { + std::cout << PHWHERE << " DST Node is missing doing nothing" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + + return Fun4AllReturnCodes::EVENT_OK; +} + +int BcoLumiReco::process_event(PHCompositeNode *topNode) +{ + static bool ifirst = true; + if (ifirst) // abort first event + { + ifirst = false; + return Fun4AllReturnCodes::ABORTEVENT; + } +// Fun4AllServer *se = Fun4AllServer::instance(); + SyncObject *syncobject = findNode::getClass(topNode, syncdefs::SYNCNODENAME); + if (!synccopy) + { + synccopy = dynamic_cast (syncobject->CloneMe()); // clone for second event + tmpsync = dynamic_cast (synccopy->CloneMe()); // just to create this object + return Fun4AllReturnCodes::ABORTEVENT; // and abort + } + Event* evt = findNode::getClass(topNode,"PRDF"); + if (evt) + { + evt->identify(); + Packet *packet = evt->getPacket(14001); +uint64_t gtm_bco = packet->lValue(0, "BCO"); +push(gtm_bco); +delete packet; + } + std::cout << "current event is: " << syncobject->EventNumber() << "\n"; + std::cout << "saving as event: " << synccopy->EventNumber() << "\n"; + *tmpsync = *syncobject; // save current version + *syncobject = *synccopy; + *synccopy = *tmpsync; + if (Verbosity() > 100) + { + std::cout << "current sync object\n"; + syncobject->identify(); + std::cout << "next sync object\n"; + synccopy->identify(); + } + std::cout << std::hex; + std::cout << "previous bco: " << get_previous_bco() << "\n"; + std::cout << "current bco: " << get_current_bco() << "\n"; + std::cout << "future bco: " << get_future_bco() << std::endl; + std::cout << std::dec; + return Fun4AllReturnCodes::EVENT_OK; +} + +void BcoLumiReco::push(uint64_t value) +{ + bco[0] = bco[1]; + bco[1] = bco[2]; + bco[2] = value; +} + + diff --git a/offline/packages/bcolumicount/BcoLumiReco.h b/offline/packages/bcolumicount/BcoLumiReco.h new file mode 100644 index 0000000000..20763cc94f --- /dev/null +++ b/offline/packages/bcolumicount/BcoLumiReco.h @@ -0,0 +1,31 @@ +#ifndef BCOLUMICOUNT_BCOLUMIRECO_H +#define BCOLUMICOUNT_BCOLUMIRECO_H + +#include + +#include +#include + +class SyncObject; + +class BcoLumiReco : public SubsysReco +{ + public: + BcoLumiReco(const std::string &name = "BCOLUMIRECO"); + ~BcoLumiReco() override = default; + + int Init(PHCompositeNode *topNode) override; + int InitRun(PHCompositeNode *topNode) override; + int process_event(PHCompositeNode *topNode) override; + void push(uint64_t value); + uint64_t get_previous_bco() {return bco[0];} + uint64_t get_current_bco() const {return bco[1];} + uint64_t get_future_bco() const {return bco[2];} + private: + static int CreateNodeTree(PHCompositeNode *topNode); + SyncObject *synccopy {nullptr}; + SyncObject *tmpsync {nullptr}; + std::array bco; +}; + +#endif // BCOLUMICOUNT_BCOLUMIRECO_H diff --git a/offline/packages/bcolumicount/Makefile.am b/offline/packages/bcolumicount/Makefile.am new file mode 100644 index 0000000000..a4d0391cdd --- /dev/null +++ b/offline/packages/bcolumicount/Makefile.am @@ -0,0 +1,80 @@ +AUTOMAKE_OPTIONS = foreign + +lib_LTLIBRARIES = \ + libbcolumicount_io.la \ + libbcolumicount.la + +AM_CPPFLAGS = \ + -I$(includedir) \ + -isystem$(OFFLINE_MAIN)/include \ + -isystem$(ROOTSYS)/include + +AM_LDFLAGS = \ + -L$(libdir) \ + -L$(OFFLINE_MAIN)/lib \ + -L$(OFFLINE_MAIN)/lib64 + +libbcolumicount_io_la_LIBADD = \ + -lphool + +libbcolumicount_la_LIBADD = \ + libbcolumicount_io.la \ + -lfun4all \ + -lffaobjects \ + -lSubsysReco + +ROOTDICTS = \ + BcoInfo_Dict.cc \ + BcoInfov1_Dict.cc + +pcmdir = $(libdir) +# more elegant way to create pcm files (without listing them) +nobase_dist_pcm_DATA = $(ROOTDICTS:.cc=_rdict.pcm) + +pkginclude_HEADERS = \ + BcoInfo.h \ + BcoInfov1.h \ + BcoLumiReco.h + + +libbcolumicount_io_la_SOURCES = \ + $(ROOTDICTS) \ + BcoInfo.cc \ + BcoInfov1.cc + +libbcolumicount_la_SOURCES = \ + BcoLumiReco.cc + +BUILT_SOURCES = testexternals.cc + +noinst_PROGRAMS = \ + testexternals \ + testexternals_io + +testexternals_SOURCES = \ + testexternals.cc + +testexternals_LDADD = \ + libbcolumicount.la + +testexternals_io_SOURCES = \ + testexternals.cc + +testexternals_io_LDADD = \ + libbcolumicount_io.la + +testexternals.cc: + echo "//*** this is a generated file. Do not commit, do not edit" > $@ + echo "int main()" >> $@ + echo "{" >> $@ + echo " return 0;" >> $@ + echo "}" >> $@ + +%_Dict.cc: %.h %LinkDef.h + rootcint -f $@ @CINTDEFS@ $(DEFAULT_INCLUDES) $(AM_CPPFLAGS) $^ + +#just to get the dependency +%_Dict_rdict.pcm: %_Dict.cc ; + +clean-local: + rm -f $(BUILT_SOURCES) diff --git a/offline/packages/bcolumicount/autogen.sh b/offline/packages/bcolumicount/autogen.sh new file mode 100755 index 0000000000..dea267bbfd --- /dev/null +++ b/offline/packages/bcolumicount/autogen.sh @@ -0,0 +1,8 @@ +#!/bin/sh +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +(cd $srcdir; aclocal -I ${OFFLINE_MAIN}/share;\ +libtoolize --force; automake -a --add-missing; autoconf) + +$srcdir/configure "$@" diff --git a/offline/packages/bcolumicount/configure.ac b/offline/packages/bcolumicount/configure.ac new file mode 100644 index 0000000000..ea3c13cc92 --- /dev/null +++ b/offline/packages/bcolumicount/configure.ac @@ -0,0 +1,20 @@ +AC_INIT(bcolumicount,[1.0]) +AC_CONFIG_SRCDIR([configure.ac]) + +AM_INIT_AUTOMAKE + +LT_INIT([disable-static]) + +AC_PROG_CXX(CC g++) + +dnl no point in suppressing warnings people should +dnl at least see them, so here we go for g++: -Wall +if test $ac_cv_prog_gxx = yes; then + CXXFLAGS="$CXXFLAGS -Wall -Werror -Wextra -Wshadow" +fi + +CINTDEFS=" -noIncludePaths -inlineInputHeader " +AC_SUBST(CINTDEFS) + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT From 68be6e0eb33749bc204285a46ff05fc4329d4ea8 Mon Sep 17 00:00:00 2001 From: cdean-github Date: Tue, 10 Mar 2026 08:31:31 -0400 Subject: [PATCH 330/393] CD: KshortReco CodeRabbit suggestions --- .../HFTrackEfficiency/HFTrackEfficiency.cc | 7 ++++ .../HFTrackEfficiency/HFTrackEfficiency.h | 1 + .../KshortReconstruction.cc | 33 ++++++++++++++----- .../KshortReconstruction.h | 2 +- 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc b/offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc index 01975c66f4..1eddbed38d 100644 --- a/offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc +++ b/offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc @@ -38,6 +38,7 @@ #include #include + //____________________________________________________________________________.. HFTrackEfficiency::HFTrackEfficiency(const std::string &name) : SubsysReco(name) @@ -218,6 +219,8 @@ bool HFTrackEfficiency::findTracks(PHCompositeNode *topNode, Decay decay) m_primary_vtx_x = thisVtx->point3d().x(); m_primary_vtx_y = thisVtx->point3d().y(); m_primary_vtx_z = thisVtx->point3d().z(); + + if (m_primary_vtx_x == 0 && m_primary_vtx_y == 0 && m_primary_vtx_z == 0) m_is_primary = true; } for (unsigned int i = 1; i < decay.size(); ++i) @@ -290,6 +293,8 @@ bool HFTrackEfficiency::findTracks(PHCompositeNode *topNode, Decay decay) daughterG4->identify(); } + m_is_primary = m_truthInfo->is_sPHENIX_primary(motherG4); + CLHEP::Hep3Vector *mother3Vector = new CLHEP::Hep3Vector(motherG4->get_px(), motherG4->get_py(), motherG4->get_pz()); motherTrueLV->setVectM((*mother3Vector), getParticleMass(decay[0].second)); m_true_mother_pT = motherTrueLV->perp(); @@ -429,6 +434,7 @@ void HFTrackEfficiency::initializeBranches() m_tree->SetAutoSave(-5e6); // Save the output file every 5MB m_tree->Branch("all_tracks_reconstructed", &m_all_tracks_reconstructed, "all_tracks_reconstructed/O"); + m_tree->Branch("is_primary", &m_is_primary, "is_primary/O"); m_tree->Branch("true_mother_mass", &m_true_mother_mass, "true_mother_mass/F"); m_tree->Branch("reco_mother_mass", &m_reco_mother_mass, "reco_mother_mass/F"); m_tree->Branch("true_mother_pT", &m_true_mother_pT, "true_mother_pT/F"); @@ -465,6 +471,7 @@ void HFTrackEfficiency::initializeBranches() void HFTrackEfficiency::resetBranches() { m_all_tracks_reconstructed = false; + m_is_primary = false; m_true_mother_mass = std::numeric_limits::quiet_NaN(); m_reco_mother_mass = std::numeric_limits::quiet_NaN(); m_true_mother_pT = std::numeric_limits::quiet_NaN(); diff --git a/offline/packages/HFTrackEfficiency/HFTrackEfficiency.h b/offline/packages/HFTrackEfficiency/HFTrackEfficiency.h index ddd346c7a4..ce1ac40be3 100644 --- a/offline/packages/HFTrackEfficiency/HFTrackEfficiency.h +++ b/offline/packages/HFTrackEfficiency/HFTrackEfficiency.h @@ -89,6 +89,7 @@ class HFTrackEfficiency : public SubsysReco static const int m_maxTracks{5}; bool m_all_tracks_reconstructed{false}; + bool m_is_primary{false}; float m_true_mother_mass{std::numeric_limits::quiet_NaN()}; float m_reco_mother_mass{std::numeric_limits::quiet_NaN()}; float m_true_mother_pT{std::numeric_limits::quiet_NaN()}; diff --git a/offline/packages/TrackingDiagnostics/KshortReconstruction.cc b/offline/packages/TrackingDiagnostics/KshortReconstruction.cc index 9d1e868aa7..cb344e7851 100644 --- a/offline/packages/TrackingDiagnostics/KshortReconstruction.cc +++ b/offline/packages/TrackingDiagnostics/KshortReconstruction.cc @@ -715,15 +715,21 @@ void KshortReconstruction::findPcaTwoTracks(const Acts::Vector3& pos1, const Act } // get the points at which the normal to the lines intersect the lines, where the lines are perpendicular - double X = b1.dot(b2) - (b1.dot(b1) * b2.dot(b2) / b2.dot(b1)); - double Y = (a2.dot(b2) - a1.dot(b2)) - ((a2.dot(b1) - a1.dot(b1)) * b2.dot(b2) / b2.dot(b1)); - double c = Y / X; - double F = b1.dot(b1) / b2.dot(b1); - double G = -(a2.dot(b1) - a1.dot(b1)) / b2.dot(b1); - double d = (c * F) + G; + // coderabbit suggestion + const double b1b1 = b1.dot(b1); + const double b2b2 = b2.dot(b2); + const double b1b2 = b1.dot(b2); + const double denom = b1b1 * b2b2 - b1b2 * b1b2; + if (std::abs(denom) < 1e-12) + { + return; + } + const Eigen::Vector3d w0 = a1 - a2; + const double c = (b1b2 * b2.dot(w0) - b2b2 * b1.dot(w0)) / denom; + const double d = (b1b1 * b2.dot(w0) - b1b2 * b1.dot(w0)) / denom; - // then the points of closest approach are: + // then the points of closest approach are: pca1 = a1 + c * b1; pca2 = a2 + d * b2; @@ -923,7 +929,16 @@ int KshortReconstruction::getNodes(PHCompositeNode* topNode) int KshortReconstruction::getMotherPDG() { - return TDatabasePDG::Instance()->GetParticle(m_mother_name.c_str())->PdgCode(); + TParticlePDG* particle = TDatabasePDG::Instance()->GetParticle(m_mother_name.c_str()); + if (!particle) + { + if (Verbosity() > 2) + { + std::cout << "Error: Unknown particle name '" << m_mother_name << "'" << std::endl; + } + return -1; // or throw exception + } + return particle->PdgCode(); } PHG4Particle *KshortReconstruction::getTruthTrack(SvtxTrack *thisTrack, PHCompositeNode *topNode) @@ -937,7 +952,7 @@ PHG4Particle *KshortReconstruction::getTruthTrack(SvtxTrack *thisTrack, PHCompos PHG4Particle *particle = nullptr; SvtxPHG4ParticleMap *dst_reco_truth_map = findNode::getClass(topNode, "SvtxPHG4ParticleMap"); - if (dst_reco_truth_map) + if (dst_reco_truth_map && dst_reco_truth_map->processed()) { std::map> truth_set = dst_reco_truth_map->get(thisTrack->get_id()); if (!truth_set.empty()) diff --git a/offline/packages/TrackingDiagnostics/KshortReconstruction.h b/offline/packages/TrackingDiagnostics/KshortReconstruction.h index 7eed20507c..16ce14aca3 100644 --- a/offline/packages/TrackingDiagnostics/KshortReconstruction.h +++ b/offline/packages/TrackingDiagnostics/KshortReconstruction.h @@ -46,7 +46,7 @@ class KshortReconstruction : public SubsysReco //Truth matching code void truthMatch(bool match = true) { m_truth_match = match; } - void setMotherID(std::string id = "K_S0") { m_mother_name = id; m_used_string = true; } + void setMotherID(const std::string id = "K_S0") { m_mother_name = id; m_used_string = true; } void setMotherID(int id = 310) { m_mother_id = id; m_used_string = false; } private: From b0fe3635d480da680bee769b9fa0512837db4ae3 Mon Sep 17 00:00:00 2001 From: Cameron Dean <59485912+cdean-github@users.noreply.github.com> Date: Tue, 10 Mar 2026 08:40:06 -0400 Subject: [PATCH 331/393] Update offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc b/offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc index 1eddbed38d..1f503dcc01 100644 --- a/offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc +++ b/offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc @@ -219,8 +219,13 @@ bool HFTrackEfficiency::findTracks(PHCompositeNode *topNode, Decay decay) m_primary_vtx_x = thisVtx->point3d().x(); m_primary_vtx_y = thisVtx->point3d().y(); m_primary_vtx_z = thisVtx->point3d().z(); - - if (m_primary_vtx_x == 0 && m_primary_vtx_y == 0 && m_primary_vtx_z == 0) m_is_primary = true; + constexpr float epsilon = 1e-6f; + if (std::abs(m_primary_vtx_x) < epsilon && + std::abs(m_primary_vtx_y) < epsilon && + std::abs(m_primary_vtx_z) < epsilon) + { + m_is_primary = true; + } } for (unsigned int i = 1; i < decay.size(); ++i) From b401831b8e19877c1940cfed299c41fc0507f3ca Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Tue, 10 Mar 2026 08:54:57 -0400 Subject: [PATCH 332/393] revert IO object to float --- offline/packages/tpc/LaserEventInfo.h | 4 ++-- offline/packages/tpc/LaserEventInfov1.cc | 2 +- offline/packages/tpc/LaserEventInfov1.h | 6 +++--- offline/packages/tpc/LaserEventInfov2.cc | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/offline/packages/tpc/LaserEventInfo.h b/offline/packages/tpc/LaserEventInfo.h index 5379862549..48e5379b70 100644 --- a/offline/packages/tpc/LaserEventInfo.h +++ b/offline/packages/tpc/LaserEventInfo.h @@ -32,8 +32,8 @@ class LaserEventInfo : public PHObject virtual int getPeakSample(const bool /*side*/) const { return std::numeric_limits::max(); } virtual void setPeakSample(const bool /*side*/, const int /*sample*/) {} - virtual double getPeakWidth(const bool /*side*/) const { return std::numeric_limits::quiet_NaN(); } - virtual void setPeakWidth(const bool /*side*/, const double /*width*/) {} + virtual float getPeakWidth(const bool /*side*/) const { return std::numeric_limits::quiet_NaN(); } + virtual void setPeakWidth(const bool /*side*/, const float /*width*/) {} protected: LaserEventInfo() = default; diff --git a/offline/packages/tpc/LaserEventInfov1.cc b/offline/packages/tpc/LaserEventInfov1.cc index 9e68e0baba..448cbb7e2b 100644 --- a/offline/packages/tpc/LaserEventInfov1.cc +++ b/offline/packages/tpc/LaserEventInfov1.cc @@ -20,7 +20,7 @@ void LaserEventInfov1::Reset() for (int i = 0; i < 2; i++) { m_peakSample[i] = std::numeric_limits::max(); - m_peakWidth[i] = std::numeric_limits::quiet_NaN(); + m_peakWidth[i] = std::numeric_limits::quiet_NaN(); } return; diff --git a/offline/packages/tpc/LaserEventInfov1.h b/offline/packages/tpc/LaserEventInfov1.h index e032736b01..7497fdd780 100644 --- a/offline/packages/tpc/LaserEventInfov1.h +++ b/offline/packages/tpc/LaserEventInfov1.h @@ -23,14 +23,14 @@ class LaserEventInfov1 : public LaserEventInfo int getPeakSample(const bool side) const override { return m_peakSample[side]; } void setPeakSample(const bool side, const int sample) override { m_peakSample[side] = sample; } - double getPeakWidth(const bool side) const override { return m_peakWidth[side]; } - void setPeakWidth(const bool side, const double width) override { m_peakWidth[side] = width; } + float getPeakWidth(const bool side) const override { return m_peakWidth[side]; } + void setPeakWidth(const bool side, const float width) override { m_peakWidth[side] = width; } protected: bool m_isLaserEvent{false}; int m_peakSample[2] = {std::numeric_limits::max(), std::numeric_limits::max()}; - double m_peakWidth[2] = {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}; + float m_peakWidth[2] = {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}; ClassDefOverride(LaserEventInfov1, 1); }; diff --git a/offline/packages/tpc/LaserEventInfov2.cc b/offline/packages/tpc/LaserEventInfov2.cc index ae40a14c62..c5f2ab60f4 100644 --- a/offline/packages/tpc/LaserEventInfov2.cc +++ b/offline/packages/tpc/LaserEventInfov2.cc @@ -24,7 +24,7 @@ void LaserEventInfov2::Reset() for (int i = 0; i < 2; i++) { m_peakSample[i] = std::numeric_limits::max(); - m_peakWidth[i] = std::numeric_limits::quiet_NaN(); + m_peakWidth[i] = std::numeric_limits::quiet_NaN(); } return; From f73307c2e4ae9abf0a511a40bebbb46d9570348d Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 10 Mar 2026 14:32:09 -0400 Subject: [PATCH 333/393] bcolumicount functional --- offline/packages/bcolumicount/BcoInfo.h | 12 +-- offline/packages/bcolumicount/BcoInfov1.cc | 8 +- offline/packages/bcolumicount/BcoInfov1.h | 12 +-- offline/packages/bcolumicount/BcoLumiCheck.cc | 76 +++++++++++++++++++ offline/packages/bcolumicount/BcoLumiCheck.h | 24 ++++++ offline/packages/bcolumicount/BcoLumiReco.cc | 39 +++++++--- offline/packages/bcolumicount/BcoLumiReco.h | 2 +- offline/packages/bcolumicount/Makefile.am | 3 + 8 files changed, 150 insertions(+), 26 deletions(-) create mode 100644 offline/packages/bcolumicount/BcoLumiCheck.cc create mode 100644 offline/packages/bcolumicount/BcoLumiCheck.h diff --git a/offline/packages/bcolumicount/BcoInfo.h b/offline/packages/bcolumicount/BcoInfo.h index be1b0bdbf3..f7abf37893 100644 --- a/offline/packages/bcolumicount/BcoInfo.h +++ b/offline/packages/bcolumicount/BcoInfo.h @@ -27,13 +27,13 @@ class BcoInfo : public PHObject /// isValid returns non zero if object contains valid data int isValid() const override; - uint64_t get_previous_bco() const {return 0;} - uint64_t get_current_bco() const {return 0;} - uint64_t get_future_bco() const {return 0;} + virtual uint64_t get_previous_bco() const {return 0;} + virtual uint64_t get_current_bco() const {return 0;} + virtual uint64_t get_future_bco() const {return 0;} - void set_previous_bco(uint64_t /*val*/) {return;} - void set_current_bco(uint64_t /*val*/) {return;} - void set_future_bco(uint64_t /*val*/) {return;} + virtual void set_previous_bco(uint64_t /*val*/) {return;} + virtual void set_current_bco(uint64_t /*val*/) {return;} + virtual void set_future_bco(uint64_t /*val*/) {return;} private: diff --git a/offline/packages/bcolumicount/BcoInfov1.cc b/offline/packages/bcolumicount/BcoInfov1.cc index 1d0516f375..2533d03155 100644 --- a/offline/packages/bcolumicount/BcoInfov1.cc +++ b/offline/packages/bcolumicount/BcoInfov1.cc @@ -10,9 +10,9 @@ void BcoInfov1::identify(std::ostream& out) const { out << "identify yourself: I am an BcoInfov1 Object\n"; out << std::hex; - out << "bco prev event: 0x" << get_previous_bco() << "\n" - << "bco curr event: 0x" << get_current_bco() << "\n" - << "bco futu event: 0x" << get_future_bco() + out << "bco previous event: 0x" << get_previous_bco() << "\n" + << "bco current event: 0x" << get_current_bco() << "\n" + << "bco future event: 0x" << get_future_bco() << std::dec << std::endl; @@ -23,3 +23,5 @@ int BcoInfov1::isValid() const { return (bco[2] ? 1 : 0); // return 1 if future bco is not zero } + + diff --git a/offline/packages/bcolumicount/BcoInfov1.h b/offline/packages/bcolumicount/BcoInfov1.h index 03308d0b38..645461c279 100644 --- a/offline/packages/bcolumicount/BcoInfov1.h +++ b/offline/packages/bcolumicount/BcoInfov1.h @@ -30,13 +30,13 @@ class BcoInfov1 : public BcoInfo /// isValid returns non zero if object contains valid data int isValid() const override; - uint64_t get_previous_bco() const {return bco[0];} - uint64_t get_current_bco() const {return bco[1];} - uint64_t get_future_bco() const {return bco[2];} + uint64_t get_previous_bco() const override {return bco[0];} + uint64_t get_current_bco() const override {return bco[1];} + uint64_t get_future_bco() const override {return bco[2];} - void set_previous_bco(uint64_t val) {bco[0] = val;} - void set_current_bco(uint64_t val) {bco[1] = val;} - void set_future_bco(uint64_t val) {bco[2] = val;} + void set_previous_bco(uint64_t val) override {bco[0] = val;} + void set_current_bco(uint64_t val) override {bco[1] = val;} + void set_future_bco(uint64_t val) override {bco[2] = val;} private: diff --git a/offline/packages/bcolumicount/BcoLumiCheck.cc b/offline/packages/bcolumicount/BcoLumiCheck.cc new file mode 100644 index 0000000000..c0a632b266 --- /dev/null +++ b/offline/packages/bcolumicount/BcoLumiCheck.cc @@ -0,0 +1,76 @@ +#include "BcoLumiCheck.h" + +#include "BcoInfov1.h" + +#include +#include + +#include + +#include +#include +#include // for SubsysReco + +#include +#include +#include // for PHNode +#include // for PHNodeIterator +#include // for PHObject +#include +#include // for PHWHERE +#include + +#include +#include + +#include + +BcoLumiCheck::BcoLumiCheck(const std::string &name) + : SubsysReco(name) +{ + return; +} + +int BcoLumiCheck::Init(PHCompositeNode *topNode) +{ + int iret = CreateNodeTree(topNode); + return iret; +} + +int BcoLumiCheck::InitRun(PHCompositeNode */*topNode*/) +{ + return Fun4AllReturnCodes::EVENT_OK; +} + +int BcoLumiCheck::CreateNodeTree(PHCompositeNode *topNode) +{ + PHNodeIterator iter(topNode); + PHCompositeNode *dstNode; + dstNode = dynamic_cast(iter.findFirst("PHCompositeNode", "DST")); + if (!dstNode) + { + std::cout << PHWHERE << " DST Node is missing doing nothing" << std::endl; + return Fun4AllReturnCodes::ABORTRUN; + } + return Fun4AllReturnCodes::EVENT_OK; +} + +int BcoLumiCheck::process_event(PHCompositeNode *topNode) +{ + BcoInfo *bcoinfo = findNode::getClass(topNode,"BCOINFO"); + SyncObject *syncobject = findNode::getClass(topNode, syncdefs::SYNCNODENAME); + Gl1Packet *gl1packet = findNode::getClass(topNode, 14001); + if (gl1packet) + { + std::cout << "Event No: " << syncobject->EventNumber() << std::endl; +std::cout << std::hex << "gl1: bco 0x" << gl1packet->lValue(0, "BCO") << std::endl; + if (bcoinfo) + { + std::cout << "prev bco: 0x" << bcoinfo->get_previous_bco() << std::endl; + std::cout << "curr bco: 0x" << bcoinfo->get_current_bco() << std::endl; + std::cout << "futu bco: 0x" << bcoinfo->get_future_bco() << std::endl; + } + std::cout << std::dec; + } + return Fun4AllReturnCodes::EVENT_OK; +} diff --git a/offline/packages/bcolumicount/BcoLumiCheck.h b/offline/packages/bcolumicount/BcoLumiCheck.h new file mode 100644 index 0000000000..07a08cb4cc --- /dev/null +++ b/offline/packages/bcolumicount/BcoLumiCheck.h @@ -0,0 +1,24 @@ +#ifndef BCOLUMICOUNT_BCOLUMICHECK_H +#define BCOLUMICOUNT_BCOLUMICHECK_H + +#include + +#include +#include + +class SyncObject; + +class BcoLumiCheck : public SubsysReco +{ + public: + BcoLumiCheck(const std::string &name = "BCOLUMICHECK"); + ~BcoLumiCheck() override = default; + + int Init(PHCompositeNode *topNode) override; + int InitRun(PHCompositeNode *topNode) override; + int process_event(PHCompositeNode *topNode) override; + private: + static int CreateNodeTree(PHCompositeNode *topNode); +}; + +#endif // BCOLUMICOUNT_BCOLUMICHECK_H diff --git a/offline/packages/bcolumicount/BcoLumiReco.cc b/offline/packages/bcolumicount/BcoLumiReco.cc index fd9625bfd9..a5d3db7dd4 100644 --- a/offline/packages/bcolumicount/BcoLumiReco.cc +++ b/offline/packages/bcolumicount/BcoLumiReco.cc @@ -1,5 +1,7 @@ #include "BcoLumiReco.h" +#include "BcoInfov1.h" + #include #include @@ -48,13 +50,34 @@ int BcoLumiReco::CreateNodeTree(PHCompositeNode *topNode) std::cout << PHWHERE << " DST Node is missing doing nothing" << std::endl; return Fun4AllReturnCodes::ABORTRUN; } - + BcoInfo *bcoinfo = findNode::getClass(topNode,"BCOINFO"); + if (!bcoinfo) + { + bcoinfo = new BcoInfov1(); + PHIODataNode *newnode = new PHIODataNode(bcoinfo,"BCOINFO","PHObject"); + dstNode->addNode(newnode); + } return Fun4AllReturnCodes::EVENT_OK; } int BcoLumiReco::process_event(PHCompositeNode *topNode) { static bool ifirst = true; + Event* evt = findNode::getClass(topNode,"PRDF"); + if (evt) + { + evt->identify(); + if (evt->getEvtType() != DATAEVENT) + { + return Fun4AllReturnCodes::ABORTEVENT; + } + Packet *packet = evt->getPacket(14001); + uint64_t gtm_bco = packet->lValue(0, "BCO"); + std::cout << std::hex << "packet ival: 0x" << packet->lValue(0, "BCO") + << " uint64_t: 0x" << gtm_bco << std::dec << std::endl; + push(gtm_bco); + delete packet; + } if (ifirst) // abort first event { ifirst = false; @@ -68,15 +91,8 @@ int BcoLumiReco::process_event(PHCompositeNode *topNode) tmpsync = dynamic_cast (synccopy->CloneMe()); // just to create this object return Fun4AllReturnCodes::ABORTEVENT; // and abort } - Event* evt = findNode::getClass(topNode,"PRDF"); - if (evt) - { - evt->identify(); - Packet *packet = evt->getPacket(14001); -uint64_t gtm_bco = packet->lValue(0, "BCO"); -push(gtm_bco); -delete packet; - } + BcoInfo *bcoinfo = findNode::getClass(topNode,"BCOINFO"); + std::cout << "current event is: " << syncobject->EventNumber() << "\n"; std::cout << "saving as event: " << synccopy->EventNumber() << "\n"; *tmpsync = *syncobject; // save current version @@ -94,6 +110,9 @@ delete packet; std::cout << "current bco: " << get_current_bco() << "\n"; std::cout << "future bco: " << get_future_bco() << std::endl; std::cout << std::dec; + bcoinfo->set_previous_bco(get_previous_bco()); + bcoinfo->set_current_bco(get_current_bco()); + bcoinfo->set_future_bco(get_future_bco()); return Fun4AllReturnCodes::EVENT_OK; } diff --git a/offline/packages/bcolumicount/BcoLumiReco.h b/offline/packages/bcolumicount/BcoLumiReco.h index 20763cc94f..1a21df9a1c 100644 --- a/offline/packages/bcolumicount/BcoLumiReco.h +++ b/offline/packages/bcolumicount/BcoLumiReco.h @@ -25,7 +25,7 @@ class BcoLumiReco : public SubsysReco static int CreateNodeTree(PHCompositeNode *topNode); SyncObject *synccopy {nullptr}; SyncObject *tmpsync {nullptr}; - std::array bco; + std::array bco {0}; }; #endif // BCOLUMICOUNT_BCOLUMIRECO_H diff --git a/offline/packages/bcolumicount/Makefile.am b/offline/packages/bcolumicount/Makefile.am index a4d0391cdd..3833324d98 100644 --- a/offline/packages/bcolumicount/Makefile.am +++ b/offline/packages/bcolumicount/Makefile.am @@ -21,6 +21,7 @@ libbcolumicount_la_LIBADD = \ libbcolumicount_io.la \ -lfun4all \ -lffaobjects \ + -lffarawobjects \ -lSubsysReco ROOTDICTS = \ @@ -34,6 +35,7 @@ nobase_dist_pcm_DATA = $(ROOTDICTS:.cc=_rdict.pcm) pkginclude_HEADERS = \ BcoInfo.h \ BcoInfov1.h \ + BcoLumiCheck.h \ BcoLumiReco.h @@ -43,6 +45,7 @@ libbcolumicount_io_la_SOURCES = \ BcoInfov1.cc libbcolumicount_la_SOURCES = \ + BcoLumiCheck.cc \ BcoLumiReco.cc BUILT_SOURCES = testexternals.cc From ac9de81b3227ce081239dc062d0353839e800e93 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 10 Mar 2026 14:54:48 -0400 Subject: [PATCH 334/393] add event number to bco info --- offline/packages/bcolumicount/BcoInfo.cc | 1 - offline/packages/bcolumicount/BcoInfo.h | 20 +++-- offline/packages/bcolumicount/BcoInfov1.cc | 14 +-- offline/packages/bcolumicount/BcoInfov1.h | 22 +++-- offline/packages/bcolumicount/BcoLumiCheck.cc | 18 ++-- offline/packages/bcolumicount/BcoLumiCheck.h | 3 +- offline/packages/bcolumicount/BcoLumiReco.cc | 89 ++++++++++--------- offline/packages/bcolumicount/BcoLumiReco.h | 25 ++++-- 8 files changed, 113 insertions(+), 79 deletions(-) diff --git a/offline/packages/bcolumicount/BcoInfo.cc b/offline/packages/bcolumicount/BcoInfo.cc index f816401b49..d775db903f 100644 --- a/offline/packages/bcolumicount/BcoInfo.cc +++ b/offline/packages/bcolumicount/BcoInfo.cc @@ -23,4 +23,3 @@ int BcoInfo::isValid() const std::cout << PHWHERE << "isValid not implemented by daughter class" << std::endl; return 0; } - diff --git a/offline/packages/bcolumicount/BcoInfo.h b/offline/packages/bcolumicount/BcoInfo.h index f7abf37893..46548d48f4 100644 --- a/offline/packages/bcolumicount/BcoInfo.h +++ b/offline/packages/bcolumicount/BcoInfo.h @@ -27,17 +27,23 @@ class BcoInfo : public PHObject /// isValid returns non zero if object contains valid data int isValid() const override; - virtual uint64_t get_previous_bco() const {return 0;} - virtual uint64_t get_current_bco() const {return 0;} - virtual uint64_t get_future_bco() const {return 0;} + virtual uint64_t get_previous_bco() const { return 0; } + virtual uint64_t get_current_bco() const { return 0; } + virtual uint64_t get_future_bco() const { return 0; } - virtual void set_previous_bco(uint64_t /*val*/) {return;} - virtual void set_current_bco(uint64_t /*val*/) {return;} - virtual void set_future_bco(uint64_t /*val*/) {return;} + virtual void set_previous_bco(uint64_t /*val*/) { return; } + virtual void set_current_bco(uint64_t /*val*/) { return; } + virtual void set_future_bco(uint64_t /*val*/) { return; } + virtual int get_previous_evtno() const { return 0; } + virtual int get_current_evtno() const { return 0; } + virtual int get_future_evtno() const { return 0; } - private: + virtual void set_previous_evtno(int /*val*/) { return; } + virtual void set_current_evtno(int /*val*/) { return; } + virtual void set_future_evtno(int /*val*/) { return; } + private: ClassDefOverride(BcoInfo, 1) }; diff --git a/offline/packages/bcolumicount/BcoInfov1.cc b/offline/packages/bcolumicount/BcoInfov1.cc index 2533d03155..d8e5bbf656 100644 --- a/offline/packages/bcolumicount/BcoInfov1.cc +++ b/offline/packages/bcolumicount/BcoInfov1.cc @@ -10,11 +10,15 @@ void BcoInfov1::identify(std::ostream& out) const { out << "identify yourself: I am an BcoInfov1 Object\n"; out << std::hex; - out << "bco previous event: 0x" << get_previous_bco() << "\n" - << "bco current event: 0x" << get_current_bco() << "\n" - << "bco future event: 0x" << get_future_bco() + out << "previous event: " << get_previous_evtno() << std::hex + << " bco: 0x" << get_previous_bco() << "\n" << std::dec - << std::endl; + << "current event: " << get_current_evtno() << std::hex + << " bco: 0x" << get_current_bco() << "\n" + << std::dec + << "future event: " << get_future_evtno() << std::hex + << " bco: 0x" << get_future_bco() << std::dec + << std::endl; return; } @@ -23,5 +27,3 @@ int BcoInfov1::isValid() const { return (bco[2] ? 1 : 0); // return 1 if future bco is not zero } - - diff --git a/offline/packages/bcolumicount/BcoInfov1.h b/offline/packages/bcolumicount/BcoInfov1.h index 645461c279..5f5a9a7252 100644 --- a/offline/packages/bcolumicount/BcoInfov1.h +++ b/offline/packages/bcolumicount/BcoInfov1.h @@ -30,17 +30,25 @@ class BcoInfov1 : public BcoInfo /// isValid returns non zero if object contains valid data int isValid() const override; - uint64_t get_previous_bco() const override {return bco[0];} - uint64_t get_current_bco() const override {return bco[1];} - uint64_t get_future_bco() const override {return bco[2];} + uint64_t get_previous_bco() const override { return bco[0]; } + uint64_t get_current_bco() const override { return bco[1]; } + uint64_t get_future_bco() const override { return bco[2]; } - void set_previous_bco(uint64_t val) override {bco[0] = val;} - void set_current_bco(uint64_t val) override {bco[1] = val;} - void set_future_bco(uint64_t val) override {bco[2] = val;} + void set_previous_bco(uint64_t val) override { bco[0] = val; } + void set_current_bco(uint64_t val) override { bco[1] = val; } + void set_future_bco(uint64_t val) override { bco[2] = val; } + int get_previous_evtno() const override { return evtno[0]; } + int get_current_evtno() const override { return evtno[1]; } + int get_future_evtno() const override { return evtno[2]; } + + void set_previous_evtno(int val) override { evtno[0] = val; } + void set_current_evtno(int val) override { evtno[1] = val; } + void set_future_evtno(int val) override { evtno[2] = val; } private: - std::array bco{0}; + std::array bco{0}; + std::array evtno{0}; ClassDefOverride(BcoInfov1, 1) }; diff --git a/offline/packages/bcolumicount/BcoLumiCheck.cc b/offline/packages/bcolumicount/BcoLumiCheck.cc index c0a632b266..f2b4a9d9b6 100644 --- a/offline/packages/bcolumicount/BcoLumiCheck.cc +++ b/offline/packages/bcolumicount/BcoLumiCheck.cc @@ -37,7 +37,7 @@ int BcoLumiCheck::Init(PHCompositeNode *topNode) return iret; } -int BcoLumiCheck::InitRun(PHCompositeNode */*topNode*/) +int BcoLumiCheck::InitRun(PHCompositeNode * /*topNode*/) { return Fun4AllReturnCodes::EVENT_OK; } @@ -57,20 +57,22 @@ int BcoLumiCheck::CreateNodeTree(PHCompositeNode *topNode) int BcoLumiCheck::process_event(PHCompositeNode *topNode) { - BcoInfo *bcoinfo = findNode::getClass(topNode,"BCOINFO"); + BcoInfo *bcoinfo = findNode::getClass(topNode, "BCOINFO"); SyncObject *syncobject = findNode::getClass(topNode, syncdefs::SYNCNODENAME); Gl1Packet *gl1packet = findNode::getClass(topNode, 14001); if (gl1packet) { - std::cout << "Event No: " << syncobject->EventNumber() << std::endl; -std::cout << std::hex << "gl1: bco 0x" << gl1packet->lValue(0, "BCO") << std::endl; + std::cout << "Event No: " << syncobject->EventNumber() << std::hex + << " gl1: bco 0x" << gl1packet->lValue(0, "BCO") << std::dec << std::endl; if (bcoinfo) { - std::cout << "prev bco: 0x" << bcoinfo->get_previous_bco() << std::endl; - std::cout << "curr bco: 0x" << bcoinfo->get_current_bco() << std::endl; - std::cout << "futu bco: 0x" << bcoinfo->get_future_bco() << std::endl; + std::cout << "prev event: " << bcoinfo->get_previous_evtno() << std::hex + << " bco: 0x" << bcoinfo->get_previous_bco() << std::dec << std::endl; + std::cout << "curr event: " << bcoinfo->get_current_evtno() << std::hex + << " bco: 0x" << bcoinfo->get_current_bco() << std::dec << std::endl; + std::cout << "futu event: " << bcoinfo->get_future_evtno() << std::hex + << " bco: 0x" << bcoinfo->get_future_bco() << std::dec << std::endl; } - std::cout << std::dec; } return Fun4AllReturnCodes::EVENT_OK; } diff --git a/offline/packages/bcolumicount/BcoLumiCheck.h b/offline/packages/bcolumicount/BcoLumiCheck.h index 07a08cb4cc..89fd0ae306 100644 --- a/offline/packages/bcolumicount/BcoLumiCheck.h +++ b/offline/packages/bcolumicount/BcoLumiCheck.h @@ -17,8 +17,9 @@ class BcoLumiCheck : public SubsysReco int Init(PHCompositeNode *topNode) override; int InitRun(PHCompositeNode *topNode) override; int process_event(PHCompositeNode *topNode) override; + private: static int CreateNodeTree(PHCompositeNode *topNode); }; -#endif // BCOLUMICOUNT_BCOLUMICHECK_H +#endif // BCOLUMICOUNT_BCOLUMICHECK_H diff --git a/offline/packages/bcolumicount/BcoLumiReco.cc b/offline/packages/bcolumicount/BcoLumiReco.cc index a5d3db7dd4..5d6cfc2d65 100644 --- a/offline/packages/bcolumicount/BcoLumiReco.cc +++ b/offline/packages/bcolumicount/BcoLumiReco.cc @@ -35,11 +35,6 @@ int BcoLumiReco::Init(PHCompositeNode *topNode) return iret; } -int BcoLumiReco::InitRun(PHCompositeNode */*topNode*/) -{ - return Fun4AllReturnCodes::EVENT_OK; -} - int BcoLumiReco::CreateNodeTree(PHCompositeNode *topNode) { PHNodeIterator iter(topNode); @@ -50,11 +45,11 @@ int BcoLumiReco::CreateNodeTree(PHCompositeNode *topNode) std::cout << PHWHERE << " DST Node is missing doing nothing" << std::endl; return Fun4AllReturnCodes::ABORTRUN; } - BcoInfo *bcoinfo = findNode::getClass(topNode,"BCOINFO"); + BcoInfo *bcoinfo = findNode::getClass(topNode, "BCOINFO"); if (!bcoinfo) { bcoinfo = new BcoInfov1(); - PHIODataNode *newnode = new PHIODataNode(bcoinfo,"BCOINFO","PHObject"); + PHIODataNode *newnode = new PHIODataNode(bcoinfo, "BCOINFO", "PHObject"); dstNode->addNode(newnode); } return Fun4AllReturnCodes::EVENT_OK; @@ -63,7 +58,8 @@ int BcoLumiReco::CreateNodeTree(PHCompositeNode *topNode) int BcoLumiReco::process_event(PHCompositeNode *topNode) { static bool ifirst = true; - Event* evt = findNode::getClass(topNode,"PRDF"); + SyncObject *syncobject = findNode::getClass(topNode, syncdefs::SYNCNODENAME); + Event *evt = findNode::getClass(topNode, "PRDF"); if (evt) { evt->identify(); @@ -73,54 +69,67 @@ int BcoLumiReco::process_event(PHCompositeNode *topNode) } Packet *packet = evt->getPacket(14001); uint64_t gtm_bco = packet->lValue(0, "BCO"); - std::cout << std::hex << "packet ival: 0x" << packet->lValue(0, "BCO") - << " uint64_t: 0x" << gtm_bco << std::dec << std::endl; - push(gtm_bco); + if (Verbosity() > 1) + { + std::cout << std::hex << "packet ival: 0x" << packet->lValue(0, "BCO") + << " uint64_t: 0x" << gtm_bco << std::dec << std::endl; + } + push_bco(gtm_bco); delete packet; } - if (ifirst) // abort first event + if (syncobject) + { + push_evtno(syncobject->EventNumber()); + } + if (ifirst) // abort first event since it does not have a previous bco { ifirst = false; return Fun4AllReturnCodes::ABORTEVENT; - } -// Fun4AllServer *se = Fun4AllServer::instance(); - SyncObject *syncobject = findNode::getClass(topNode, syncdefs::SYNCNODENAME); - if (!synccopy) + } + if (!m_synccopy) { - synccopy = dynamic_cast (syncobject->CloneMe()); // clone for second event - tmpsync = dynamic_cast (synccopy->CloneMe()); // just to create this object - return Fun4AllReturnCodes::ABORTEVENT; // and abort + m_synccopy = dynamic_cast(syncobject->CloneMe()); // clone for second event + m_tmpsync = dynamic_cast(m_synccopy->CloneMe()); // just to create this object + return Fun4AllReturnCodes::ABORTEVENT; // and abort } - BcoInfo *bcoinfo = findNode::getClass(topNode,"BCOINFO"); + BcoInfo *bcoinfo = findNode::getClass(topNode, "BCOINFO"); - std::cout << "current event is: " << syncobject->EventNumber() << "\n"; - std::cout << "saving as event: " << synccopy->EventNumber() << "\n"; - *tmpsync = *syncobject; // save current version - *syncobject = *synccopy; - *synccopy = *tmpsync; - if (Verbosity() > 100) + if (Verbosity() > 0) { - std::cout << "current sync object\n"; - syncobject->identify(); - std::cout << "next sync object\n"; - synccopy->identify(); + std::cout << "current event is: " << syncobject->EventNumber() << "\n"; + std::cout << "saving as event: " << m_synccopy->EventNumber() << "\n"; + } + // here we store the current sync object and overwrite its content with the cached copy + *m_tmpsync = *syncobject; // save current version in tmp + *syncobject = *m_synccopy; // copy previously cached version + *m_synccopy = *m_tmpsync; // cache current version + if (Verbosity() > 0) + { + std::cout << std::hex; + std::cout << "previous bco: " << get_previous_bco() << "\n"; + std::cout << "current bco: " << get_current_bco() << "\n"; + std::cout << "future bco: " << get_future_bco() << std::endl; + std::cout << std::dec; } - std::cout << std::hex; - std::cout << "previous bco: " << get_previous_bco() << "\n"; - std::cout << "current bco: " << get_current_bco() << "\n"; - std::cout << "future bco: " << get_future_bco() << std::endl; - std::cout << std::dec; bcoinfo->set_previous_bco(get_previous_bco()); bcoinfo->set_current_bco(get_current_bco()); bcoinfo->set_future_bco(get_future_bco()); + bcoinfo->set_previous_evtno(get_previous_evtno()); + bcoinfo->set_current_evtno(get_current_evtno()); + bcoinfo->set_future_evtno(get_future_evtno()); return Fun4AllReturnCodes::EVENT_OK; } -void BcoLumiReco::push(uint64_t value) +void BcoLumiReco::push_bco(uint64_t value) { - bco[0] = bco[1]; - bco[1] = bco[2]; - bco[2] = value; + m_bco[0] = m_bco[1]; + m_bco[1] = m_bco[2]; + m_bco[2] = value; } - +void BcoLumiReco::push_evtno(int value) +{ + m_evtno[0] = m_evtno[1]; + m_evtno[1] = m_evtno[2]; + m_evtno[2] = value; +} diff --git a/offline/packages/bcolumicount/BcoLumiReco.h b/offline/packages/bcolumicount/BcoLumiReco.h index 1a21df9a1c..6db4ea5fbc 100644 --- a/offline/packages/bcolumicount/BcoLumiReco.h +++ b/offline/packages/bcolumicount/BcoLumiReco.h @@ -15,17 +15,24 @@ class BcoLumiReco : public SubsysReco ~BcoLumiReco() override = default; int Init(PHCompositeNode *topNode) override; - int InitRun(PHCompositeNode *topNode) override; int process_event(PHCompositeNode *topNode) override; - void push(uint64_t value); - uint64_t get_previous_bco() {return bco[0];} - uint64_t get_current_bco() const {return bco[1];} - uint64_t get_future_bco() const {return bco[2];} + + void push_bco(uint64_t value); + uint64_t get_previous_bco() { return m_bco[0]; } + uint64_t get_current_bco() const { return m_bco[1]; } + uint64_t get_future_bco() const { return m_bco[2]; } + + void push_evtno(int value); + int get_previous_evtno() { return m_evtno[0]; } + int get_current_evtno() const { return m_evtno[1]; } + int get_future_evtno() const { return m_evtno[2]; } + private: static int CreateNodeTree(PHCompositeNode *topNode); - SyncObject *synccopy {nullptr}; - SyncObject *tmpsync {nullptr}; - std::array bco {0}; + SyncObject *m_synccopy{nullptr}; + SyncObject *m_tmpsync{nullptr}; + std::array m_bco{0}; + std::array m_evtno{0}; }; -#endif // BCOLUMICOUNT_BCOLUMIRECO_H +#endif // BCOLUMICOUNT_BCOLUMIRECO_H From 20be46141935944e320121788619e6934a8aa281 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 10 Mar 2026 15:06:39 -0400 Subject: [PATCH 335/393] cleanup --- offline/packages/bcolumicount/BcoLumiReco.cc | 5 ++++- offline/packages/bcolumicount/Makefile.am | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/offline/packages/bcolumicount/BcoLumiReco.cc b/offline/packages/bcolumicount/BcoLumiReco.cc index 5d6cfc2d65..6dfc57cc95 100644 --- a/offline/packages/bcolumicount/BcoLumiReco.cc +++ b/offline/packages/bcolumicount/BcoLumiReco.cc @@ -62,7 +62,10 @@ int BcoLumiReco::process_event(PHCompositeNode *topNode) Event *evt = findNode::getClass(topNode, "PRDF"); if (evt) { - evt->identify(); + if (Verbosity() > 1) + { + evt->identify(); + } if (evt->getEvtType() != DATAEVENT) { return Fun4AllReturnCodes::ABORTEVENT; diff --git a/offline/packages/bcolumicount/Makefile.am b/offline/packages/bcolumicount/Makefile.am index 3833324d98..70afc9b224 100644 --- a/offline/packages/bcolumicount/Makefile.am +++ b/offline/packages/bcolumicount/Makefile.am @@ -19,7 +19,6 @@ libbcolumicount_io_la_LIBADD = \ libbcolumicount_la_LIBADD = \ libbcolumicount_io.la \ - -lfun4all \ -lffaobjects \ -lffarawobjects \ -lSubsysReco From a95c3e8e05ac4efd4610c9a8fb88637fc2c58019 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 10 Mar 2026 15:15:18 -0400 Subject: [PATCH 336/393] include what you use --- offline/packages/bcolumicount/BcoInfo.cc | 2 -- offline/packages/bcolumicount/BcoInfov1.h | 2 -- offline/packages/bcolumicount/BcoLumiCheck.cc | 9 +-------- offline/packages/bcolumicount/BcoLumiCheck.h | 3 --- offline/packages/bcolumicount/BcoLumiReco.cc | 6 +++--- offline/packages/bcolumicount/BcoLumiReco.h | 2 ++ 6 files changed, 6 insertions(+), 18 deletions(-) diff --git a/offline/packages/bcolumicount/BcoInfo.cc b/offline/packages/bcolumicount/BcoInfo.cc index d775db903f..3fc672a599 100644 --- a/offline/packages/bcolumicount/BcoInfo.cc +++ b/offline/packages/bcolumicount/BcoInfo.cc @@ -4,8 +4,6 @@ #include -class PHObject; - void BcoInfo::Reset() { std::cout << PHWHERE << "ERROR Reset() not implemented by daughter class" << std::endl; diff --git a/offline/packages/bcolumicount/BcoInfov1.h b/offline/packages/bcolumicount/BcoInfov1.h index 5f5a9a7252..78b2a3f348 100644 --- a/offline/packages/bcolumicount/BcoInfov1.h +++ b/offline/packages/bcolumicount/BcoInfov1.h @@ -8,8 +8,6 @@ #include #include -class PHObject; - class BcoInfov1 : public BcoInfo { public: diff --git a/offline/packages/bcolumicount/BcoLumiCheck.cc b/offline/packages/bcolumicount/BcoLumiCheck.cc index f2b4a9d9b6..3ba12f1776 100644 --- a/offline/packages/bcolumicount/BcoLumiCheck.cc +++ b/offline/packages/bcolumicount/BcoLumiCheck.cc @@ -1,6 +1,6 @@ #include "BcoLumiCheck.h" -#include "BcoInfov1.h" +#include "BcoInfo.h" #include #include @@ -8,20 +8,13 @@ #include #include -#include #include // for SubsysReco #include -#include #include // for PHNode #include // for PHNodeIterator -#include // for PHObject #include #include // for PHWHERE -#include - -#include -#include #include diff --git a/offline/packages/bcolumicount/BcoLumiCheck.h b/offline/packages/bcolumicount/BcoLumiCheck.h index 89fd0ae306..75477dea98 100644 --- a/offline/packages/bcolumicount/BcoLumiCheck.h +++ b/offline/packages/bcolumicount/BcoLumiCheck.h @@ -3,11 +3,8 @@ #include -#include #include -class SyncObject; - class BcoLumiCheck : public SubsysReco { public: diff --git a/offline/packages/bcolumicount/BcoLumiReco.cc b/offline/packages/bcolumicount/BcoLumiReco.cc index 6dfc57cc95..5947eea3ca 100644 --- a/offline/packages/bcolumicount/BcoLumiReco.cc +++ b/offline/packages/bcolumicount/BcoLumiReco.cc @@ -1,12 +1,12 @@ #include "BcoLumiReco.h" +#include "BcoInfo.h" #include "BcoInfov1.h" #include #include #include -#include #include // for SubsysReco #include @@ -16,11 +16,11 @@ #include // for PHObject #include #include // for PHWHERE -#include #include #include - +#include // for Packet +# #include BcoLumiReco::BcoLumiReco(const std::string &name) diff --git a/offline/packages/bcolumicount/BcoLumiReco.h b/offline/packages/bcolumicount/BcoLumiReco.h index 6db4ea5fbc..c2657d20c4 100644 --- a/offline/packages/bcolumicount/BcoLumiReco.h +++ b/offline/packages/bcolumicount/BcoLumiReco.h @@ -4,8 +4,10 @@ #include #include +#include #include +class PHCompositeNode; class SyncObject; class BcoLumiReco : public SubsysReco From dbd254b4c4f0416e42b29df4782209ade3a83c23 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 10 Mar 2026 15:28:12 -0400 Subject: [PATCH 337/393] add bcolumicount_io to lib dep of g4dst --- simulation/g4simulation/g4dst/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/simulation/g4simulation/g4dst/Makefile.am b/simulation/g4simulation/g4dst/Makefile.am index 7ea76582d4..3bb3eb1a17 100644 --- a/simulation/g4simulation/g4dst/Makefile.am +++ b/simulation/g4simulation/g4dst/Makefile.am @@ -11,6 +11,7 @@ lib_LTLIBRARIES = \ libg4dst_la_LDFLAGS = \ -L$(libdir) \ -L$(OFFLINE_MAIN)/lib \ + -lbcolumicount_io \ -lcalo_io \ -lcalotrigger_io \ -lcentrality_io \ From 56be16346d622149b4042ade3bcc64f4ebb16971 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 10 Mar 2026 15:54:54 -0400 Subject: [PATCH 338/393] fix Reset and hex output --- offline/packages/bcolumicount/BcoInfov1.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/offline/packages/bcolumicount/BcoInfov1.cc b/offline/packages/bcolumicount/BcoInfov1.cc index d8e5bbf656..28e206413f 100644 --- a/offline/packages/bcolumicount/BcoInfov1.cc +++ b/offline/packages/bcolumicount/BcoInfov1.cc @@ -3,13 +3,13 @@ void BcoInfov1::Reset() { bco.fill(0); + evtno.fill(0); return; } void BcoInfov1::identify(std::ostream& out) const { out << "identify yourself: I am an BcoInfov1 Object\n"; - out << std::hex; out << "previous event: " << get_previous_evtno() << std::hex << " bco: 0x" << get_previous_bco() << "\n" << std::dec @@ -19,7 +19,6 @@ void BcoInfov1::identify(std::ostream& out) const << "future event: " << get_future_evtno() << std::hex << " bco: 0x" << get_future_bco() << std::dec << std::endl; - return; } From ecbd7812f80b31abc540f36c81a2eceef4dd93a8 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 10 Mar 2026 16:12:18 -0400 Subject: [PATCH 339/393] delete cloned objects --- offline/packages/bcolumicount/BcoLumiReco.cc | 6 ++++++ offline/packages/bcolumicount/BcoLumiReco.h | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/offline/packages/bcolumicount/BcoLumiReco.cc b/offline/packages/bcolumicount/BcoLumiReco.cc index 5947eea3ca..bf8ea87224 100644 --- a/offline/packages/bcolumicount/BcoLumiReco.cc +++ b/offline/packages/bcolumicount/BcoLumiReco.cc @@ -29,6 +29,12 @@ BcoLumiReco::BcoLumiReco(const std::string &name) return; } +BcoLumiReco::~BcoLumiReco() +{ + delete m_synccopy; + delete m_tmpsync; +} + int BcoLumiReco::Init(PHCompositeNode *topNode) { int iret = CreateNodeTree(topNode); diff --git a/offline/packages/bcolumicount/BcoLumiReco.h b/offline/packages/bcolumicount/BcoLumiReco.h index c2657d20c4..c0c0ab6a3a 100644 --- a/offline/packages/bcolumicount/BcoLumiReco.h +++ b/offline/packages/bcolumicount/BcoLumiReco.h @@ -14,7 +14,7 @@ class BcoLumiReco : public SubsysReco { public: BcoLumiReco(const std::string &name = "BCOLUMIRECO"); - ~BcoLumiReco() override = default; + ~BcoLumiReco() override; int Init(PHCompositeNode *topNode) override; int process_event(PHCompositeNode *topNode) override; From 21724b056f311fdb1b6c780cb9a1f3b8624ea8b3 Mon Sep 17 00:00:00 2001 From: Cheng-Wei Shih Date: Wed, 11 Mar 2026 01:02:54 -0400 Subject: [PATCH 340/393] Update the way how we load the INTT DAC values, it was from CDB. Now we read the values from PSQL. --- .../intt/InttCombinedRawDataDecoder.cc | 46 ++++++++++--- .../intt/InttCombinedRawDataDecoder.h | 20 ++++-- offline/packages/intt/InttOdbcQuery.cc | 69 +++++++++++++++++++ offline/packages/intt/InttOdbcQuery.h | 9 +++ 4 files changed, 128 insertions(+), 16 deletions(-) diff --git a/offline/packages/intt/InttCombinedRawDataDecoder.cc b/offline/packages/intt/InttCombinedRawDataDecoder.cc index 18db00ef01..657a670fdc 100644 --- a/offline/packages/intt/InttCombinedRawDataDecoder.cc +++ b/offline/packages/intt/InttCombinedRawDataDecoder.cc @@ -35,8 +35,9 @@ InttCombinedRawDataDecoder::InttCombinedRawDataDecoder(std::string const& name) : SubsysReco(name) - , m_calibinfoDAC({"INTT_DACMAP", CDB}) + // , m_calibinfoDAC({"INTT_DACMAP", CDB}) , m_calibinfoBCO({"INTT_BCOMAP", CDB}) + , m_DACValues(0) { // Do nothing // Consider calling LoadHotChannelMapRemote() @@ -128,17 +129,29 @@ int InttCombinedRawDataDecoder::InitRun(PHCompositeNode* topNode) } /////////////////////////////////////// - std::cout << "calibinfo DAC : " << m_calibinfoDAC.first << " " << (m_calibinfoDAC.second == CDB ? "CDB" : "FILE") << std::endl; - m_dacmap.Verbosity(Verbosity()); - if (m_calibinfoDAC.second == CDB) + if ( DACValue_set_count == 1 && (m_DACValues.size() != 8 || std::find(m_DACValues.begin(), m_DACValues.end(), -1) != m_DACValues.end()) ) { - m_dacmap.LoadFromCDB(m_calibinfoDAC.first); + std::cout << PHWHERE << ", " << "INTT DAC values retrieved from intt_setting table not properly set, exiting." << std::endl; + gSystem->Exit(1); + exit(1); } - else - { - m_dacmap.LoadFromFile(m_calibinfoDAC.first); + + if (DACValue_set_count == 0){ + std::cout << PHWHERE << ", " << "INTT DAC values not set, used the default setting {30, 45, 60, 90, 120, 150, 180, 210} " << std::endl; + m_DACValues = default_DACValues; } + // std::cout << "calibinfo DAC : " << m_calibinfoDAC.first << " " << (m_calibinfoDAC.second == CDB ? "CDB" : "FILE") << std::endl; + // m_dacmap.Verbosity(Verbosity()); + // if (m_calibinfoDAC.second == CDB) + // { + // m_dacmap.LoadFromCDB(m_calibinfoDAC.first); + // } + // else + // { + // m_dacmap.LoadFromFile(m_calibinfoDAC.first); + // } + /////////////////////////////////////// std::cout << "calibinfo BCO : " << m_calibinfoBCO.first << " " << (m_calibinfoBCO.second == CDB ? "CDB" : "FILE") << std::endl; m_bcomap.Verbosity(Verbosity()); @@ -429,7 +442,9 @@ int InttCombinedRawDataDecoder::process_event(PHCompositeNode* topNode) //////////////////////// // dac conversion - int dac = m_dacmap.GetDAC(raw, adc); + // int dac = m_dacmap.GetDAC(raw, adc); + int dac = (adc >= 0 && adc <= 7) ? m_DACValues[adc] : -1; + // std::cout<< PHWHERE << "\n" << "ADC value: " << adc << ", converted DAC value: " << dac << std::endl; hit = new TrkrHitv2; //--hit->setAdc(adc); @@ -441,3 +456,16 @@ int InttCombinedRawDataDecoder::process_event(PHCompositeNode* topNode) return Fun4AllReturnCodes::EVENT_OK; } + + +void InttCombinedRawDataDecoder::set_DACValues(std::vector input_dac_vec) +{ + m_DACValues = input_dac_vec; + DACValue_set_count = 1; + std::cout< #include #include +#include #include #include #include @@ -40,10 +41,10 @@ class InttCombinedRawDataDecoder : public SubsysReco /// Depreciated; use LoadHotChannelMap(const std::string&); int LoadHotChannelMapRemote(std::string const& s = "INTT_HotChannelMap") {return LoadBadChannelMap(s);} - void SetCalibDAC(std::string const& calibname = "INTT_DACMAP", const CalibRef& calibref = CDB) - { - m_calibinfoDAC = std::pair(calibname, calibref); - } + // void SetCalibDAC(std::string const& calibname = "INTT_DACMAP", const CalibRef& calibref = CDB) + // { + // m_calibinfoDAC = std::pair(calibname, calibref); + // } void SetCalibBCO(std::string const& calibname = "INTT_BCOMAP", const CalibRef& calibref = CDB) { @@ -60,6 +61,7 @@ class InttCombinedRawDataDecoder : public SubsysReco void set_bcoFilter(bool flag) {m_bcoFilter = flag; } void set_SaturatedChipRejection(bool flag){m_SaturatedChipRejection = flag;} // note : this is for removing a fraction of the saturated chips void set_HighChipMultiplicityCut(int cut){HighChipMultiplicityCut = cut;} + void set_DACValues(std::vector input_dac_vec); private: InttEventInfo* intt_event_header = nullptr; @@ -68,13 +70,17 @@ class InttCombinedRawDataDecoder : public SubsysReco bool m_writeInttEventHeader = false; bool m_bcoFilter = false; bool m_SaturatedChipRejection = true; // note : true as default - std::pair m_calibinfoDAC; + // std::pair m_calibinfoDAC; std::pair m_calibinfoBCO; InttBadChannelMap m_badmap; - InttDacMap m_dacmap; + // InttDacMap m_dacmap; InttBCOMap m_bcomap; + std::vector m_DACValues; + const std::vector default_DACValues = {30, 45, 60, 90, 120, 150, 180, 210}; // note : this is the setting used by most of the physics runs + int DACValue_set_count = 0; + int m_inttFeeOffset = 23; //23 is the offset for INTT in streaming mode bool m_outputBcoDiff = false; bool m_triggeredMode = false; diff --git a/offline/packages/intt/InttOdbcQuery.cc b/offline/packages/intt/InttOdbcQuery.cc index 51587c00a2..c43881b729 100644 --- a/offline/packages/intt/InttOdbcQuery.cc +++ b/offline/packages/intt/InttOdbcQuery.cc @@ -19,8 +19,11 @@ int InttOdbcQuery::Query(int runnumber) // statement will be deleted by DBInterface odbc::Statement* statement = DBInterface::instance()->getStatement("daq"); + m_intt_dac_values.clear(); + int iret = 0; iret += (QueryStreaming(statement, runnumber) != 0); + iret += (QueryAllDACValues(statement, runnumber) != 0); //... m_query_successful = (iret == 0); @@ -104,3 +107,69 @@ int InttOdbcQuery::QueryType(odbc::Statement *statement, int runnumber) return 0; } + +int InttOdbcQuery::QuerySingleDACValue(odbc::Statement *statement, int runnumber, int adc_value, int &DAC_value) // adc_value should be from 0 to 7 +{ + std::unique_ptr result_set; + std::string column_name = "dac" + std::to_string(adc_value); + DAC_value = -1; + + + try + { + std::string sql = "SELECT " + column_name + " From intt_setting WHERE runnumber = " + std::to_string(runnumber) + ";"; + result_set = std::unique_ptr(statement->executeQuery(sql)); + if (result_set && result_set->next()) + { + DAC_value = result_set->getInt(column_name.c_str()); + } + } + catch (odbc::SQLException& e) + { + std::cerr << PHWHERE << "\n" + << "\tSQL Exception:\n" + << "\t" << e.getMessage() << std::endl; + return 1; + } + + if (m_verbosity) + { + std::cout << column_name << " of run " << runnumber <<" is " << DAC_value << std::endl; + } + + return 0; +} + +int InttOdbcQuery::QueryAllDACValues(odbc::Statement *statement, int runnumber) +{ + int error_count = 0; + + for (int i = 0; i < 8; ++i) + { + int DAC_value = -1; + + error_count += QuerySingleDACValue(statement, runnumber, i, DAC_value); + + m_intt_dac_values.push_back(DAC_value); + } + + if (error_count != 0 || m_intt_dac_values.size() != 8 || std::find(m_intt_dac_values.begin(), m_intt_dac_values.end(), -1) != m_intt_dac_values.end()) + { + std::cerr << PHWHERE << "\n" + << "\tError retrieving DAC values. error_count: " << error_count + << ", size of m_intt_dac_values: " << m_intt_dac_values.size() << std::endl; + std:: cout << "In the dac map: "; + for (size_t i = 0; i < m_intt_dac_values.size(); ++i) + { + std::cout << "dac" << i << ": " << m_intt_dac_values[i] << ", "; + } + std::cout << std::endl; + + std::cout << "We then use the default mapping of intt_dac_values: {30, 45, 60, 90, 120, 150, 180, 210} for this run, runnumber : "<< runnumber << std::endl; + m_intt_dac_values = default_intt_dac_values; + + return error_count; + } + + return 0; +} \ No newline at end of file diff --git a/offline/packages/intt/InttOdbcQuery.h b/offline/packages/intt/InttOdbcQuery.h index 775e2e0ca4..dd03066cc0 100644 --- a/offline/packages/intt/InttOdbcQuery.h +++ b/offline/packages/intt/InttOdbcQuery.h @@ -1,9 +1,11 @@ #ifndef INTT_ODBC_QUERY_H #define INTT_ODBC_QUERY_H +#include #include #include #include +#include namespace odbc { @@ -22,12 +24,16 @@ class InttOdbcQuery int Query(int); bool IsStreaming() {return m_is_streaming;} + std::vector GetInttDACValues() {return m_intt_dac_values;} const std::string &Type() {return m_type;} private: int QueryStreaming(odbc::Statement *, int); int QueryType(odbc::Statement *, int); + int QuerySingleDACValue(odbc::Statement *statement, int runnumber, int adc_value, int &DAC_value); + int QueryAllDACValues(odbc::Statement *statement, int runnumber); + static const int m_MAX_NUM_RETRIES = 3000; static const int m_MIN_SLEEP_DUR = 200; // milliseconds static const int m_MAX_SLEEP_DUR = 3000; // milliseconds @@ -38,6 +44,9 @@ class InttOdbcQuery bool m_is_streaming{false}; std::string m_type; std::array, 8> m_file_set; + + std::vector m_intt_dac_values; + const std::vector default_intt_dac_values{30, 45, 60, 90, 120, 150, 180, 210}; // note : most of physics runs have this setting. }; #endif//INTT_ODBC_QUERY_H From 42ed1e514d564a5fec291a4a8f8db865b30b5c79 Mon Sep 17 00:00:00 2001 From: Cheng-Wei Shih Date: Wed, 11 Mar 2026 11:43:30 -0400 Subject: [PATCH 341/393] Update the way how we load the INTT DAC values, for mass production, the new method. --- .../intt/InttCombinedRawDataDecoder.cc | 124 +++++++++++++++--- .../intt/InttCombinedRawDataDecoder.h | 11 +- 2 files changed, 117 insertions(+), 18 deletions(-) diff --git a/offline/packages/intt/InttCombinedRawDataDecoder.cc b/offline/packages/intt/InttCombinedRawDataDecoder.cc index 657a670fdc..ae05b62251 100644 --- a/offline/packages/intt/InttCombinedRawDataDecoder.cc +++ b/offline/packages/intt/InttCombinedRawDataDecoder.cc @@ -18,7 +18,12 @@ #include #include +#include +#include +#include + +#include #include #include // for PHIODataNode #include @@ -37,7 +42,7 @@ InttCombinedRawDataDecoder::InttCombinedRawDataDecoder(std::string const& name) : SubsysReco(name) // , m_calibinfoDAC({"INTT_DACMAP", CDB}) , m_calibinfoBCO({"INTT_BCOMAP", CDB}) - , m_DACValues(0) + , m_intt_dac_values(0) { // Do nothing // Consider calling LoadHotChannelMapRemote() @@ -129,17 +134,14 @@ int InttCombinedRawDataDecoder::InitRun(PHCompositeNode* topNode) } /////////////////////////////////////// - if ( DACValue_set_count == 1 && (m_DACValues.size() != 8 || std::find(m_DACValues.begin(), m_DACValues.end(), -1) != m_DACValues.end()) ) - { - std::cout << PHWHERE << ", " << "INTT DAC values retrieved from intt_setting table not properly set, exiting." << std::endl; - gSystem->Exit(1); - exit(1); - } - + recoConsts *rc = recoConsts::instance(); + int run_number = rc->get_IntFlag("RUNNUMBER"); + + odbc::Statement* statement = DBInterface::instance()->getStatement("daq"); if (DACValue_set_count == 0){ - std::cout << PHWHERE << ", " << "INTT DAC values not set, used the default setting {30, 45, 60, 90, 120, 150, 180, 210} " << std::endl; - m_DACValues = default_DACValues; - } + std::cout<< PHWHERE << ", " << "No manual setting for DAC values. Querying INTT DAC values from intt_setting table for run number " << run_number << std::endl; + InttCombinedRawDataDecoder::QueryAllDACValues(statement, run_number); + } // std::cout << "calibinfo DAC : " << m_calibinfoDAC.first << " " << (m_calibinfoDAC.second == CDB ? "CDB" : "FILE") << std::endl; // m_dacmap.Verbosity(Verbosity()); @@ -443,8 +445,12 @@ int InttCombinedRawDataDecoder::process_event(PHCompositeNode* topNode) //////////////////////// // dac conversion // int dac = m_dacmap.GetDAC(raw, adc); - int dac = (adc >= 0 && adc <= 7) ? m_DACValues[adc] : -1; - // std::cout<< PHWHERE << "\n" << "ADC value: " << adc << ", converted DAC value: " << dac << std::endl; + int dac = (adc >= 0 && adc <= 7) ? m_intt_dac_values[adc] : -1; + + if (Verbosity() > 100000){ + std::cout<< PHWHERE << "\n" << "ADC value: " << adc << ", converted DAC value: " << dac << std::endl; + } + hit = new TrkrHitv2; //--hit->setAdc(adc); @@ -460,12 +466,98 @@ int InttCombinedRawDataDecoder::process_event(PHCompositeNode* topNode) void InttCombinedRawDataDecoder::set_DACValues(std::vector input_dac_vec) { - m_DACValues = input_dac_vec; + m_intt_dac_values = input_dac_vec; DACValue_set_count = 1; + int count_minus = 0; std::cout<Exit(1); + } +} + + +int InttCombinedRawDataDecoder::QuerySingleDACValue(odbc::Statement *statement, int runnumber, int adc_value, int &DAC_value) // adc_value should be from 0 to 7 +{ + std::unique_ptr result_set; + std::string column_name = "dac" + std::to_string(adc_value); + DAC_value = -1; + + + try + { + std::string sql = "SELECT " + column_name + " From intt_setting WHERE runnumber = " + std::to_string(runnumber) + ";"; + result_set = std::unique_ptr(statement->executeQuery(sql)); + if (result_set && result_set->next()) + { + DAC_value = result_set->getInt(column_name.c_str()); + } + } + catch (odbc::SQLException& e) + { + std::cerr << PHWHERE << "\n" + << "\tSQL Exception:\n" + << "\t" << e.getMessage() << std::endl; + return 1; + } + + if (Verbosity()) + { + std::cout << column_name << " of run " << runnumber <<" is " << DAC_value << std::endl; + } + + return 0; +} + +int InttCombinedRawDataDecoder::QueryAllDACValues(odbc::Statement *statement, int runnumber) +{ + int error_count = 0; + + for (int i = 0; i < 8; ++i) + { + int DAC_value = -1; + + error_count += QuerySingleDACValue(statement, runnumber, i, DAC_value); + + m_intt_dac_values.push_back(DAC_value); + } + + if (error_count != 0 || m_intt_dac_values.size() != 8 || std::find(m_intt_dac_values.begin(), m_intt_dac_values.end(), -1) != m_intt_dac_values.end()) + { + std::cerr << PHWHERE << "\n" + << "\tError retrieving DAC values. error_count: " << error_count + << ", size of m_intt_dac_values: " << m_intt_dac_values.size() << std::endl; + std:: cout << "In the dac map: "; + for (size_t i = 0; i < m_intt_dac_values.size(); ++i) + { + std::cout << "dac" << i << ": " << m_intt_dac_values[i] << ", "; + } + std::cout << std::endl; + std::cout<< " The DAC values should be 8 integers and all should be positive. Exiting."<< std::endl; + std::cout<< " Please contact the INTT group if the run you analyzed doesn't appear in the intt_setting table."<< std::endl; + + exit(1); + gSystem->Exit(1); + + return error_count; + } + + return 0; } \ No newline at end of file diff --git a/offline/packages/intt/InttCombinedRawDataDecoder.h b/offline/packages/intt/InttCombinedRawDataDecoder.h index 6c71b42880..0b2f5904ee 100644 --- a/offline/packages/intt/InttCombinedRawDataDecoder.h +++ b/offline/packages/intt/InttCombinedRawDataDecoder.h @@ -18,6 +18,11 @@ class PHCompositeNode; class InttEventInfo; +namespace odbc +{ + class Statement; +} // namespace odbc + class InttCombinedRawDataDecoder : public SubsysReco { public: @@ -64,6 +69,9 @@ class InttCombinedRawDataDecoder : public SubsysReco void set_DACValues(std::vector input_dac_vec); private: + int QuerySingleDACValue(odbc::Statement *statement, int runnumber, int adc_value, int &DAC_value); + int QueryAllDACValues(odbc::Statement *statement, int runnumber); + InttEventInfo* intt_event_header = nullptr; std::string m_InttRawNodeName = "INTTRAWHIT"; bool m_runStandAlone = false; @@ -77,8 +85,7 @@ class InttCombinedRawDataDecoder : public SubsysReco // InttDacMap m_dacmap; InttBCOMap m_bcomap; - std::vector m_DACValues; - const std::vector default_DACValues = {30, 45, 60, 90, 120, 150, 180, 210}; // note : this is the setting used by most of the physics runs + std::vector m_intt_dac_values; int DACValue_set_count = 0; int m_inttFeeOffset = 23; //23 is the offset for INTT in streaming mode From 9f3e5f0e3003501bf980188bae7842227864c6a1 Mon Sep 17 00:00:00 2001 From: Cheng-Wei Shih Date: Wed, 11 Mar 2026 11:59:59 -0400 Subject: [PATCH 342/393] revert the modification on the InttOdbcQuery --- offline/packages/intt/InttOdbcQuery.cc | 69 -------------------------- offline/packages/intt/InttOdbcQuery.h | 9 ---- 2 files changed, 78 deletions(-) diff --git a/offline/packages/intt/InttOdbcQuery.cc b/offline/packages/intt/InttOdbcQuery.cc index c43881b729..51587c00a2 100644 --- a/offline/packages/intt/InttOdbcQuery.cc +++ b/offline/packages/intt/InttOdbcQuery.cc @@ -19,11 +19,8 @@ int InttOdbcQuery::Query(int runnumber) // statement will be deleted by DBInterface odbc::Statement* statement = DBInterface::instance()->getStatement("daq"); - m_intt_dac_values.clear(); - int iret = 0; iret += (QueryStreaming(statement, runnumber) != 0); - iret += (QueryAllDACValues(statement, runnumber) != 0); //... m_query_successful = (iret == 0); @@ -107,69 +104,3 @@ int InttOdbcQuery::QueryType(odbc::Statement *statement, int runnumber) return 0; } - -int InttOdbcQuery::QuerySingleDACValue(odbc::Statement *statement, int runnumber, int adc_value, int &DAC_value) // adc_value should be from 0 to 7 -{ - std::unique_ptr result_set; - std::string column_name = "dac" + std::to_string(adc_value); - DAC_value = -1; - - - try - { - std::string sql = "SELECT " + column_name + " From intt_setting WHERE runnumber = " + std::to_string(runnumber) + ";"; - result_set = std::unique_ptr(statement->executeQuery(sql)); - if (result_set && result_set->next()) - { - DAC_value = result_set->getInt(column_name.c_str()); - } - } - catch (odbc::SQLException& e) - { - std::cerr << PHWHERE << "\n" - << "\tSQL Exception:\n" - << "\t" << e.getMessage() << std::endl; - return 1; - } - - if (m_verbosity) - { - std::cout << column_name << " of run " << runnumber <<" is " << DAC_value << std::endl; - } - - return 0; -} - -int InttOdbcQuery::QueryAllDACValues(odbc::Statement *statement, int runnumber) -{ - int error_count = 0; - - for (int i = 0; i < 8; ++i) - { - int DAC_value = -1; - - error_count += QuerySingleDACValue(statement, runnumber, i, DAC_value); - - m_intt_dac_values.push_back(DAC_value); - } - - if (error_count != 0 || m_intt_dac_values.size() != 8 || std::find(m_intt_dac_values.begin(), m_intt_dac_values.end(), -1) != m_intt_dac_values.end()) - { - std::cerr << PHWHERE << "\n" - << "\tError retrieving DAC values. error_count: " << error_count - << ", size of m_intt_dac_values: " << m_intt_dac_values.size() << std::endl; - std:: cout << "In the dac map: "; - for (size_t i = 0; i < m_intt_dac_values.size(); ++i) - { - std::cout << "dac" << i << ": " << m_intt_dac_values[i] << ", "; - } - std::cout << std::endl; - - std::cout << "We then use the default mapping of intt_dac_values: {30, 45, 60, 90, 120, 150, 180, 210} for this run, runnumber : "<< runnumber << std::endl; - m_intt_dac_values = default_intt_dac_values; - - return error_count; - } - - return 0; -} \ No newline at end of file diff --git a/offline/packages/intt/InttOdbcQuery.h b/offline/packages/intt/InttOdbcQuery.h index dd03066cc0..775e2e0ca4 100644 --- a/offline/packages/intt/InttOdbcQuery.h +++ b/offline/packages/intt/InttOdbcQuery.h @@ -1,11 +1,9 @@ #ifndef INTT_ODBC_QUERY_H #define INTT_ODBC_QUERY_H -#include #include #include #include -#include namespace odbc { @@ -24,16 +22,12 @@ class InttOdbcQuery int Query(int); bool IsStreaming() {return m_is_streaming;} - std::vector GetInttDACValues() {return m_intt_dac_values;} const std::string &Type() {return m_type;} private: int QueryStreaming(odbc::Statement *, int); int QueryType(odbc::Statement *, int); - int QuerySingleDACValue(odbc::Statement *statement, int runnumber, int adc_value, int &DAC_value); - int QueryAllDACValues(odbc::Statement *statement, int runnumber); - static const int m_MAX_NUM_RETRIES = 3000; static const int m_MIN_SLEEP_DUR = 200; // milliseconds static const int m_MAX_SLEEP_DUR = 3000; // milliseconds @@ -44,9 +38,6 @@ class InttOdbcQuery bool m_is_streaming{false}; std::string m_type; std::array, 8> m_file_set; - - std::vector m_intt_dac_values; - const std::vector default_intt_dac_values{30, 45, 60, 90, 120, 150, 180, 210}; // note : most of physics runs have this setting. }; #endif//INTT_ODBC_QUERY_H From ea2074408a35cf5a68653dd33dad6487878287bb Mon Sep 17 00:00:00 2001 From: devloom Date: Wed, 11 Mar 2026 12:38:23 -0400 Subject: [PATCH 343/393] add laser cluster alignment --- offline/packages/tpc/LaserClusterizer.cc | 34 ++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/offline/packages/tpc/LaserClusterizer.cc b/offline/packages/tpc/LaserClusterizer.cc index cdf18687df..12b65747f1 100644 --- a/offline/packages/tpc/LaserClusterizer.cc +++ b/offline/packages/tpc/LaserClusterizer.cc @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -818,6 +819,35 @@ namespace clus->setSDWeightedIT(sqrt(sigmaWeightedIT / adcSum)); } + + // Get surface of max ADC hit + alignmentTransformationContainer::use_alignment = false; + Acts::Vector3 ideal(clusX, clusY, clusZ); + TrkrDefs::subsurfkey subsurfkey = 0; + + Surface surface = my_data.tGeometry->get_tpc_surface_from_coords( + maxKey, + ideal, + subsurfkey); + + if (!surface) + { + return; + } + + // Convert from ideal TPC coordinates to surface coordinates + Acts::Vector3 local = surface->transform(my_data.tGeometry->geometry().getGeoContext()).inverse() * (ideal * Acts::UnitConstants::cm); + local /= Acts::UnitConstants::cm; + + // Convert back to TPC coordinates with alignment applied + alignmentTransformationContainer::use_alignment = true; + Acts::Vector3 global = surface->transform(my_data.tGeometry->geometry().getGeoContext()) * (local * Acts::UnitConstants::cm); + global /= Acts::UnitConstants::cm; + clus->setX(global(0)); + clus->setY(global(1)); + clus->setZ(global(2)); + + const auto ckey = TrkrDefs::genClusKey(maxKey, my_data.cluster_vector.size()); my_data.cluster_vector.push_back(clus); my_data.cluster_key_vector.push_back(ckey); @@ -995,6 +1025,7 @@ int LaserClusterizer::InitRun(PHCompositeNode *topNode) // get the first layer to get the clock freq AdcClockPeriod = m_geom_container->GetFirstLayerCellGeom()->get_zstep(); m_tdriftmax = AdcClockPeriod * NZBinsSide; + return Fun4AllReturnCodes::EVENT_OK; } @@ -1146,6 +1177,9 @@ int LaserClusterizer::process_event(PHCompositeNode *topNode) thread_pair.data.peakTimeBin = m_laserEventInfo->getPeakSample(s); thread_pair.data.layerMin = 3; thread_pair.data.layerMax = 3; + // ******************** // + // m_tdriftmax = m_tGeometry->get_max_driftlength() / m_tGeometry->get_drift_velocity(); + // ******************** // thread_pair.data.tdriftmax = m_tdriftmax; thread_pair.data.eventNum = m_event; thread_pair.data.Verbosity = Verbosity(); From e4e8392f8e3351083374537bbe7ea1296d3187f3 Mon Sep 17 00:00:00 2001 From: devloom Date: Wed, 11 Mar 2026 12:42:39 -0400 Subject: [PATCH 344/393] clean up --- offline/packages/tpc/LaserClusterizer.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/offline/packages/tpc/LaserClusterizer.cc b/offline/packages/tpc/LaserClusterizer.cc index 12b65747f1..a7e74672ec 100644 --- a/offline/packages/tpc/LaserClusterizer.cc +++ b/offline/packages/tpc/LaserClusterizer.cc @@ -1177,9 +1177,6 @@ int LaserClusterizer::process_event(PHCompositeNode *topNode) thread_pair.data.peakTimeBin = m_laserEventInfo->getPeakSample(s); thread_pair.data.layerMin = 3; thread_pair.data.layerMax = 3; - // ******************** // - // m_tdriftmax = m_tGeometry->get_max_driftlength() / m_tGeometry->get_drift_velocity(); - // ******************** // thread_pair.data.tdriftmax = m_tdriftmax; thread_pair.data.eventNum = m_event; thread_pair.data.Verbosity = Verbosity(); From d106696e01fd8899ac922f90d91026475045bfa3 Mon Sep 17 00:00:00 2001 From: devloom Date: Wed, 11 Mar 2026 16:37:35 -0400 Subject: [PATCH 345/393] rabbit suggestions --- offline/packages/tpc/LaserClusterizer.cc | 30 ++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/offline/packages/tpc/LaserClusterizer.cc b/offline/packages/tpc/LaserClusterizer.cc index a7e74672ec..9a2b265f57 100644 --- a/offline/packages/tpc/LaserClusterizer.cc +++ b/offline/packages/tpc/LaserClusterizer.cc @@ -444,6 +444,7 @@ namespace double maxAdc = 0.0; TrkrDefs::hitsetkey maxKey = 0; + TrkrDefs::hitsetkey secondmaxKey = 0; unsigned int nHits = clusHits.size(); @@ -556,6 +557,7 @@ namespace if (adc > maxAdc) { maxAdc = adc; + secondmaxKey = maxKey; maxKey = spechitkey.second; } } @@ -820,9 +822,10 @@ namespace } + pthread_mutex_lock(&mythreadlock); // Get surface of max ADC hit alignmentTransformationContainer::use_alignment = false; - Acts::Vector3 ideal(clusX, clusY, clusZ); + Acts::Vector3 ideal(clus->getX(), clus->getY(), clus->getZ()); TrkrDefs::subsurfkey subsurfkey = 0; Surface surface = my_data.tGeometry->get_tpc_surface_from_coords( @@ -832,7 +835,29 @@ namespace if (!surface) { - return; + // try second maximum ADC hit + if (secondmaxKey != 0) + { + surface = my_data.tGeometry->get_tpc_surface_from_coords( + secondmaxKey, + ideal, + subsurfkey); + } + + // if still no surface, skip this cluster + if (!surface) + { + // clean up + alignmentTransformationContainer::use_alignment = true; + delete fit3D; + if (my_data.hitHist) + { + delete my_data.hitHist; + my_data.hitHist = nullptr; + } + pthread_mutex_unlock(&mythreadlock); + return; + } } // Convert from ideal TPC coordinates to surface coordinates @@ -846,6 +871,7 @@ namespace clus->setX(global(0)); clus->setY(global(1)); clus->setZ(global(2)); + pthread_mutex_unlock(&mythreadlock); const auto ckey = TrkrDefs::genClusKey(maxKey, my_data.cluster_vector.size()); From 65e3ae26766581484c60aaaf272c0ff82be5b1f9 Mon Sep 17 00:00:00 2001 From: Mughal789 Date: Wed, 11 Mar 2026 17:43:44 -0400 Subject: [PATCH 346/393] Implement BCO matching and move cout statements under verbosity --- .../KFParticle_sPHENIX/KFParticle_nTuple.cc | 17 +++++- .../KFParticle_sPHENIX/KFParticle_nTuple.h | 9 +++ .../KFParticle_sPHENIX/KFParticle_sPHENIX.cc | 56 +++++++++++++++++++ .../KFParticle_sPHENIX/KFParticle_sPHENIX.h | 6 ++ 4 files changed, 87 insertions(+), 1 deletion(-) diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc b/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc index b4659e1b8d..44ffbbedda 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc @@ -303,7 +303,9 @@ void KFParticle_nTuple::initializeBranches(PHCompositeNode* topNode) m_tree->Branch("runNumber", &m_runNumber, "runNumber/I"); m_tree->Branch("eventNumber", &m_evtNumber, "eventNumber/I"); - m_tree->Branch("BCO", &m_bco, "BCO/L"); + m_tree->Branch("event_bco", &m_event_bco, "event_bco/L"); //adding for the current event BCO, not shifted + m_tree->Branch("BCO", &m_bco, "BCO/L"); //already there, this is shifted BCO + m_tree->Branch("last_event_bco", &m_last_event_bco, "last_event_bco/L"); //BCO for the last event if (m_get_trigger_info) { @@ -674,10 +676,23 @@ void KFParticle_nTuple::fillBranch(PHCompositeNode* topNode, } m_bco = gl1packet->lValue(0, "BCO") + m_calculated_daughter_bunch_crossing[0]; //m_bco = m_trigger_info_available ? gl1packet->lValue(0, "BCO") + m_calculated_daughter_bunch_crossing[0] : 0; + + //moving this logic to KFParticle_sPHENIX.cc in process_event, will be removed later + /* + //BCO for the last event try + if (m_runNumber != m_prev_runNumber || m_evtNumber != m_prev_evtNumber) + { + m_last_event_bco = m_prev_event_bco; + m_prev_event_bco = m_bco; + m_prev_runNumber = m_runNumber; + m_prev_evtNumber = m_evtNumber; + } //end BCO for last event + */ } else { m_runNumber = m_evtNumber = m_bco = -1; + // m_last_event_bco = -1; //add for last event BCO } if (m_trigger_info_available) diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.h b/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.h index 4798e24942..7c3f4088fe 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.h +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.h @@ -35,6 +35,13 @@ class KFParticle_nTuple : public KFParticle_truthAndDetTools, public KFParticle_ std::vector daughters, std::vector intermediates); + // pass event-level BCO values from KFParticle_sPHENIX + void set_event_bcos(const int64_t this_bco, const int64_t last_bco) + { + m_event_bco = this_bco; + m_last_event_bco = last_bco; + } + float calc_secondary_vertex_mass_noPID(std::vector kfp_daughters); bool fillConditionMet() const; @@ -219,6 +226,8 @@ class KFParticle_nTuple : public KFParticle_truthAndDetTools, public KFParticle_ int m_runNumber{-1}; int m_evtNumber{-1}; int64_t m_bco{-1}; + int64_t m_event_bco{-1};//current event BCO + int64_t m_last_event_bco{-1}; //only keeping this, BCO for the last event bool m_trigger_info_available{false}; }; diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc index 8c049f30d6..93ee223686 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc @@ -29,6 +29,8 @@ #include #include +#include +#include #include #include @@ -150,7 +152,60 @@ int KFParticle_sPHENIX::process_event(PHCompositeNode *topNode) } return Fun4AllReturnCodes::EVENT_OK; } + + // Adding BCO Matching + auto* evtHeader = findNode::getClass(topNode, "EventHeader"); // event header node + auto* gl1packet = findNode::getClass(topNode, "GL1RAWHIT"); // gl1 packet node + if (!gl1packet) + { + gl1packet = findNode::getClass(topNode, "GL1Packet"); + } + + if (evtHeader && gl1packet) + { + const int64_t run = evtHeader->get_RunNumber(); + const int64_t evn = evtHeader->get_EvtSequence(); + m_this_event_bco = static_cast(gl1packet->lValue(0, "BCO")); + + if (Verbosity() >= VERBOSITY_SOME) + { + std::cout << "Event start | run: " << run << " event: " << evn << " this_event_bco: " << m_this_event_bco << std::endl; + } + + if (run != m_prev_runNumber || evn != m_prev_eventNumber) + { + + if (Verbosity() >= VERBOSITY_SOME) + { + std::cout << "New event detected" << std::endl; + std::cout << "Previous event BCO: " << m_prev_event_bco << std::endl; + } + m_last_event_bco = m_prev_event_bco; + m_prev_event_bco = m_this_event_bco; + + m_prev_runNumber = run; + m_prev_eventNumber = evn; + + if (Verbosity() >= VERBOSITY_SOME) + { + std::cout << "Updated values | last_event_bco: " << m_last_event_bco + << " stored_prev_event_bco: " << m_prev_event_bco + << std::endl; + } + } + } + else + { + + if (Verbosity() >= VERBOSITY_SOME) + { + std::cout << "EventHeader or GL1 packet not found" << std::endl; + } + m_this_event_bco = -1; + m_last_event_bco = -1; + } +// End BCO matching here if (!m_use_fake_pv) { if (m_use_mbd_vertex) @@ -205,6 +260,7 @@ int KFParticle_sPHENIX::process_event(PHCompositeNode *topNode) if (m_save_output) { + set_event_bcos(m_this_event_bco, m_last_event_bco); //filling nTuple for BCO Matching fillBranch(topNode, mother[i], vertex_kfparticle[i], daughters[i], intermediates[i]); } if (m_save_dst) diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h index d5905d443c..5b0ceca785 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h @@ -422,6 +422,12 @@ class KFParticle_sPHENIX : public SubsysReco, public KFParticle_nTuple, public K bool m_save_dst; bool m_save_output; int candidateCounter = 0; + //Adding member variables for BCO matching + int64_t m_this_event_bco{-1}; + int64_t m_last_event_bco{-1}; + int64_t m_prev_event_bco{-1}; + int64_t m_prev_runNumber{-1}; + int64_t m_prev_eventNumber{-1}; //till here std::string m_outfile_name; TFile *m_outfile; std::string m_decayDescriptor; From 960d444b2a3a6eefc2b624a417b5d551c26b96cd Mon Sep 17 00:00:00 2001 From: Mughal789 Date: Wed, 11 Mar 2026 17:49:20 -0400 Subject: [PATCH 347/393] Implement BCO matching and move cout statements under verbosity --- .../packages/KFParticle_sPHENIX/KFParticle_nTuple.cc | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc b/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc index 44ffbbedda..f6ae689aa9 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc @@ -677,22 +677,10 @@ void KFParticle_nTuple::fillBranch(PHCompositeNode* topNode, m_bco = gl1packet->lValue(0, "BCO") + m_calculated_daughter_bunch_crossing[0]; //m_bco = m_trigger_info_available ? gl1packet->lValue(0, "BCO") + m_calculated_daughter_bunch_crossing[0] : 0; - //moving this logic to KFParticle_sPHENIX.cc in process_event, will be removed later - /* - //BCO for the last event try - if (m_runNumber != m_prev_runNumber || m_evtNumber != m_prev_evtNumber) - { - m_last_event_bco = m_prev_event_bco; - m_prev_event_bco = m_bco; - m_prev_runNumber = m_runNumber; - m_prev_evtNumber = m_evtNumber; - } //end BCO for last event - */ } else { m_runNumber = m_evtNumber = m_bco = -1; - // m_last_event_bco = -1; //add for last event BCO } if (m_trigger_info_available) From 1bda69061a2b6b1a7020f41386871ec5c2b9682f Mon Sep 17 00:00:00 2001 From: Mughal789 Date: Wed, 11 Mar 2026 18:16:41 -0400 Subject: [PATCH 348/393] Reset cached previous-event state on run change or invalid event to avoid propagating stale BCO history. --- offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc index 93ee223686..15a0a5f33e 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc @@ -181,7 +181,8 @@ int KFParticle_sPHENIX::process_event(PHCompositeNode *topNode) std::cout << "New event detected" << std::endl; std::cout << "Previous event BCO: " << m_prev_event_bco << std::endl; } - m_last_event_bco = m_prev_event_bco; + // m_last_event_bco = m_prev_event_bco; + m_last_event_bco = (run == m_prev_runNumber) ? m_prev_event_bco : -1; m_prev_event_bco = m_this_event_bco; m_prev_runNumber = run; @@ -204,6 +205,10 @@ int KFParticle_sPHENIX::process_event(PHCompositeNode *topNode) } m_this_event_bco = -1; m_last_event_bco = -1; + m_prev_event_bco = -1; + m_prev_runNumber = -1; + m_prev_eventNumber = -1; + } // End BCO matching here if (!m_use_fake_pv) From 5e6433bf8929cdae63c442fa6ec2f6e91083dbb2 Mon Sep 17 00:00:00 2001 From: devloom Date: Wed, 11 Mar 2026 18:25:02 -0400 Subject: [PATCH 349/393] fix max logic --- offline/packages/tpc/LaserClusterizer.cc | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/offline/packages/tpc/LaserClusterizer.cc b/offline/packages/tpc/LaserClusterizer.cc index 9a2b265f57..fbb09a1fa2 100644 --- a/offline/packages/tpc/LaserClusterizer.cc +++ b/offline/packages/tpc/LaserClusterizer.cc @@ -444,6 +444,7 @@ namespace double maxAdc = 0.0; TrkrDefs::hitsetkey maxKey = 0; + double secondmaxAdc = 0.0; TrkrDefs::hitsetkey secondmaxKey = 0; unsigned int nHits = clusHits.size(); @@ -556,10 +557,18 @@ namespace if (adc > maxAdc) { - maxAdc = adc; + secondmaxAdc = maxAdc; secondmaxKey = maxKey; + maxAdc = adc; maxKey = spechitkey.second; } + else if (adc > secondmaxAdc) + { + secondmaxAdc = adc; + secondmaxKey = spechitkey.second; + } + + } if (nHits == 0) @@ -824,6 +833,7 @@ namespace pthread_mutex_lock(&mythreadlock); // Get surface of max ADC hit + bool alignmentflag = alignmentTransformationContainer::use_alignment; alignmentTransformationContainer::use_alignment = false; Acts::Vector3 ideal(clus->getX(), clus->getY(), clus->getZ()); TrkrDefs::subsurfkey subsurfkey = 0; @@ -848,7 +858,7 @@ namespace if (!surface) { // clean up - alignmentTransformationContainer::use_alignment = true; + alignmentTransformationContainer::use_alignment = alignmentflag; delete fit3D; if (my_data.hitHist) { @@ -871,6 +881,8 @@ namespace clus->setX(global(0)); clus->setY(global(1)); clus->setZ(global(2)); + + alignmentTransformationContainer::use_alignment = alignmentflag; pthread_mutex_unlock(&mythreadlock); @@ -878,6 +890,7 @@ namespace my_data.cluster_vector.push_back(clus); my_data.cluster_key_vector.push_back(ckey); + delete fit3D; if (my_data.hitHist) From de9a1074fb3d37fdb7d411a1138e55c89e864404 Mon Sep 17 00:00:00 2001 From: devloom Date: Wed, 11 Mar 2026 18:35:45 -0400 Subject: [PATCH 350/393] free memory --- offline/packages/tpc/LaserClusterizer.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/offline/packages/tpc/LaserClusterizer.cc b/offline/packages/tpc/LaserClusterizer.cc index fbb09a1fa2..8ecd28688e 100644 --- a/offline/packages/tpc/LaserClusterizer.cc +++ b/offline/packages/tpc/LaserClusterizer.cc @@ -859,6 +859,7 @@ namespace { // clean up alignmentTransformationContainer::use_alignment = alignmentflag; + delete clus; delete fit3D; if (my_data.hitHist) { @@ -881,7 +882,7 @@ namespace clus->setX(global(0)); clus->setY(global(1)); clus->setZ(global(2)); - + alignmentTransformationContainer::use_alignment = alignmentflag; pthread_mutex_unlock(&mythreadlock); From 0d1b523a7101ac51afd933972ebfd408353f7bfa Mon Sep 17 00:00:00 2001 From: Cheng-Wei Shih Date: Wed, 11 Mar 2026 22:29:35 -0400 Subject: [PATCH 351/393] Update the way how we load the INTT DAC values, for mass production, the new method2 --- .../intt/InttCombinedRawDataDecoder.cc | 83 ++++++++----------- .../intt/InttCombinedRawDataDecoder.h | 1 - 2 files changed, 34 insertions(+), 50 deletions(-) diff --git a/offline/packages/intt/InttCombinedRawDataDecoder.cc b/offline/packages/intt/InttCombinedRawDataDecoder.cc index ae05b62251..8757bf3727 100644 --- a/offline/packages/intt/InttCombinedRawDataDecoder.cc +++ b/offline/packages/intt/InttCombinedRawDataDecoder.cc @@ -140,7 +140,25 @@ int InttCombinedRawDataDecoder::InitRun(PHCompositeNode* topNode) odbc::Statement* statement = DBInterface::instance()->getStatement("daq"); if (DACValue_set_count == 0){ std::cout<< PHWHERE << ", " << "No manual setting for DAC values. Querying INTT DAC values from intt_setting table for run number " << run_number << std::endl; - InttCombinedRawDataDecoder::QueryAllDACValues(statement, run_number); + int error_count = InttCombinedRawDataDecoder::QueryAllDACValues(statement, run_number); + + if (error_count != 0 || m_intt_dac_values.size() != 8 || std::find(m_intt_dac_values.begin(), m_intt_dac_values.end(), -1) != m_intt_dac_values.end()) + { + std::cerr << PHWHERE << "\n" + << "\tError retrieving DAC values. error_count: " << error_count + << ", size of m_intt_dac_values: " << m_intt_dac_values.size() << std::endl; + std:: cout << "In the dac map: "; + for (size_t i = 0; i < m_intt_dac_values.size(); ++i) + { + std::cout << "dac" << i << ": " << m_intt_dac_values[i] << ", "; + } + std::cout << std::endl; + std::cout<< " The DAC values should be 8 integers and all should be positive. Exiting."<< std::endl; + std::cout<< " Please contact the INTT group if the run you analyzed doesn't appear in the intt_setting table."<< std::endl; + + exit(1); + gSystem->Exit(1); + } } // std::cout << "calibinfo DAC : " << m_calibinfoDAC.first << " " << (m_calibinfoDAC.second == CDB ? "CDB" : "FILE") << std::endl; @@ -493,21 +511,29 @@ void InttCombinedRawDataDecoder::set_DACValues(std::vector input_dac_vec) } } - -int InttCombinedRawDataDecoder::QuerySingleDACValue(odbc::Statement *statement, int runnumber, int adc_value, int &DAC_value) // adc_value should be from 0 to 7 +int InttCombinedRawDataDecoder::QueryAllDACValues(odbc::Statement *statement, int runnumber) { + std::unique_ptr result_set; - std::string column_name = "dac" + std::to_string(adc_value); - DAC_value = -1; - + m_intt_dac_values.clear(); try { - std::string sql = "SELECT " + column_name + " From intt_setting WHERE runnumber = " + std::to_string(runnumber) + ";"; + std::string sql = "SELECT dac0, dac1, dac2, dac3, dac4, dac5, dac6, dac7 From intt_setting WHERE runnumber = " + std::to_string(runnumber) + ";"; result_set = std::unique_ptr(statement->executeQuery(sql)); if (result_set && result_set->next()) { - DAC_value = result_set->getInt(column_name.c_str()); + for (int i = 0; i < 8; i++) + { + std::string column_name = "dac" + std::to_string(i); + int DAC_value = -1; + + DAC_value = result_set->getInt(column_name.c_str()); + + m_intt_dac_values.push_back(DAC_value); + + std::cout<< PHWHERE << ", retrieved DAC value for " << column_name << ": " << DAC_value << std::endl; + } } } catch (odbc::SQLException& e) @@ -518,46 +544,5 @@ int InttCombinedRawDataDecoder::QuerySingleDACValue(odbc::Statement *statement, return 1; } - if (Verbosity()) - { - std::cout << column_name << " of run " << runnumber <<" is " << DAC_value << std::endl; - } - - return 0; -} - -int InttCombinedRawDataDecoder::QueryAllDACValues(odbc::Statement *statement, int runnumber) -{ - int error_count = 0; - - for (int i = 0; i < 8; ++i) - { - int DAC_value = -1; - - error_count += QuerySingleDACValue(statement, runnumber, i, DAC_value); - - m_intt_dac_values.push_back(DAC_value); - } - - if (error_count != 0 || m_intt_dac_values.size() != 8 || std::find(m_intt_dac_values.begin(), m_intt_dac_values.end(), -1) != m_intt_dac_values.end()) - { - std::cerr << PHWHERE << "\n" - << "\tError retrieving DAC values. error_count: " << error_count - << ", size of m_intt_dac_values: " << m_intt_dac_values.size() << std::endl; - std:: cout << "In the dac map: "; - for (size_t i = 0; i < m_intt_dac_values.size(); ++i) - { - std::cout << "dac" << i << ": " << m_intt_dac_values[i] << ", "; - } - std::cout << std::endl; - std::cout<< " The DAC values should be 8 integers and all should be positive. Exiting."<< std::endl; - std::cout<< " Please contact the INTT group if the run you analyzed doesn't appear in the intt_setting table."<< std::endl; - - exit(1); - gSystem->Exit(1); - - return error_count; - } - return 0; } \ No newline at end of file diff --git a/offline/packages/intt/InttCombinedRawDataDecoder.h b/offline/packages/intt/InttCombinedRawDataDecoder.h index 0b2f5904ee..c38badefeb 100644 --- a/offline/packages/intt/InttCombinedRawDataDecoder.h +++ b/offline/packages/intt/InttCombinedRawDataDecoder.h @@ -69,7 +69,6 @@ class InttCombinedRawDataDecoder : public SubsysReco void set_DACValues(std::vector input_dac_vec); private: - int QuerySingleDACValue(odbc::Statement *statement, int runnumber, int adc_value, int &DAC_value); int QueryAllDACValues(odbc::Statement *statement, int runnumber); InttEventInfo* intt_event_header = nullptr; From bd8068e579a4ef9044af889e6c6dc076ab266853 Mon Sep 17 00:00:00 2001 From: cdean-github Date: Thu, 12 Mar 2026 06:07:00 -0400 Subject: [PATCH 352/393] CD: Jenkins requests --- .../HFTrackEfficiency/HFTrackEfficiency.cc | 15 ++++++++------- .../TrackingDiagnostics/KshortReconstruction.h | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc b/offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc index 1f503dcc01..e87d8c500b 100644 --- a/offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc +++ b/offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc @@ -219,13 +219,14 @@ bool HFTrackEfficiency::findTracks(PHCompositeNode *topNode, Decay decay) m_primary_vtx_x = thisVtx->point3d().x(); m_primary_vtx_y = thisVtx->point3d().y(); m_primary_vtx_z = thisVtx->point3d().z(); - constexpr float epsilon = 1e-6f; - if (std::abs(m_primary_vtx_x) < epsilon && - std::abs(m_primary_vtx_y) < epsilon && - std::abs(m_primary_vtx_z) < epsilon) - { - m_is_primary = true; - } + + constexpr float epsilon = 1e-6F; + if (std::abs(m_primary_vtx_x) < epsilon && + std::abs(m_primary_vtx_y) < epsilon && + std::abs(m_primary_vtx_z) < epsilon) + { + m_is_primary = true; + } } for (unsigned int i = 1; i < decay.size(); ++i) diff --git a/offline/packages/TrackingDiagnostics/KshortReconstruction.h b/offline/packages/TrackingDiagnostics/KshortReconstruction.h index 16ce14aca3..95eba65b02 100644 --- a/offline/packages/TrackingDiagnostics/KshortReconstruction.h +++ b/offline/packages/TrackingDiagnostics/KshortReconstruction.h @@ -46,7 +46,7 @@ class KshortReconstruction : public SubsysReco //Truth matching code void truthMatch(bool match = true) { m_truth_match = match; } - void setMotherID(const std::string id = "K_S0") { m_mother_name = id; m_used_string = true; } + void setMotherID(const std::string &id = "K_S0") { m_mother_name = id; m_used_string = true; } void setMotherID(int id = 310) { m_mother_id = id; m_used_string = false; } private: From 8ed52b3cfc21bf23d919a358d4b307ed74a969a8 Mon Sep 17 00:00:00 2001 From: Usman <94740481+Mughal789@users.noreply.github.com> Date: Thu, 12 Mar 2026 09:47:22 -0400 Subject: [PATCH 353/393] Update offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h index 5b0ceca785..46aa1e4cef 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h @@ -424,7 +424,7 @@ class KFParticle_sPHENIX : public SubsysReco, public KFParticle_nTuple, public K int candidateCounter = 0; //Adding member variables for BCO matching int64_t m_this_event_bco{-1}; - int64_t m_last_event_bco{-1}; + int64_t m_last_event_bco_sPHENIX{-1}; int64_t m_prev_event_bco{-1}; int64_t m_prev_runNumber{-1}; int64_t m_prev_eventNumber{-1}; //till here From b26fd44f55ab85578be70c46cc2948bbe5ba6d00 Mon Sep 17 00:00:00 2001 From: Mughal789 Date: Thu, 12 Mar 2026 12:50:13 -0400 Subject: [PATCH 354/393] fix missing GL1 fallback in KFParticle_nTuple fillBranch --- .../KFParticle_sPHENIX/KFParticle_nTuple.cc | 36 +++++++++++++------ .../KFParticle_sPHENIX/KFParticle_nTuple.h | 1 - .../KFParticle_sPHENIX/KFParticle_sPHENIX.cc | 9 +++-- .../KFParticle_sPHENIX/KFParticle_sPHENIX.h | 3 +- 4 files changed, 32 insertions(+), 17 deletions(-) diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc b/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc index f6ae689aa9..88216d356d 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc @@ -663,25 +663,41 @@ void KFParticle_nTuple::fillBranch(PHCompositeNode* topNode, PHNode* evtNode = nodeIter.findFirst("EventHeader"); - if (evtNode) + if (evtNode) + { + EventHeader* evtHeader = findNode::getClass(topNode, "EventHeader"); + if (evtHeader) { - EventHeader* evtHeader = findNode::getClass(topNode, "EventHeader"); m_runNumber = evtHeader->get_RunNumber(); m_evtNumber = evtHeader->get_EvtSequence(); + } + else + { + m_runNumber = -1; + m_evtNumber = -1; + } - auto* gl1packet = findNode::getClass(topNode, "GL1RAWHIT"); - if (!gl1packet) - { - gl1packet = findNode::getClass(topNode, "GL1Packet"); - } - m_bco = gl1packet->lValue(0, "BCO") + m_calculated_daughter_bunch_crossing[0]; - //m_bco = m_trigger_info_available ? gl1packet->lValue(0, "BCO") + m_calculated_daughter_bunch_crossing[0] : 0; + auto* gl1packet = findNode::getClass(topNode, "GL1RAWHIT"); + if (!gl1packet) + { + gl1packet = findNode::getClass(topNode, "GL1Packet"); + } + if (gl1packet) + { + m_bco = gl1packet->lValue(0, "BCO") + m_calculated_daughter_bunch_crossing[0]; } else { - m_runNumber = m_evtNumber = m_bco = -1; + m_bco = -1; } +} + else + { + m_runNumber = -1; + m_evtNumber = -1; + m_bco = -1; + } if (m_trigger_info_available) { diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.h b/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.h index 7c3f4088fe..f63e60a021 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.h +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.h @@ -9,7 +9,6 @@ #include #include // for string #include - class PHCompositeNode; class TTree; diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc index 15a0a5f33e..151a97f494 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc @@ -166,7 +166,7 @@ int KFParticle_sPHENIX::process_event(PHCompositeNode *topNode) { const int64_t run = evtHeader->get_RunNumber(); const int64_t evn = evtHeader->get_EvtSequence(); - m_this_event_bco = static_cast(gl1packet->lValue(0, "BCO")); + m_this_event_bco = static_cast(gl1packet->lValue(0, "BCO")); if (Verbosity() >= VERBOSITY_SOME) { @@ -181,9 +181,9 @@ int KFParticle_sPHENIX::process_event(PHCompositeNode *topNode) std::cout << "New event detected" << std::endl; std::cout << "Previous event BCO: " << m_prev_event_bco << std::endl; } - // m_last_event_bco = m_prev_event_bco; - m_last_event_bco = (run == m_prev_runNumber) ? m_prev_event_bco : -1; - m_prev_event_bco = m_this_event_bco; + //m_last_event_bco = m_prev_event_bco; + m_last_event_bco = (run == m_prev_runNumber) ? m_prev_event_bco : -1; + m_prev_event_bco = m_this_event_bco; m_prev_runNumber = run; m_prev_eventNumber = evn; @@ -208,7 +208,6 @@ int KFParticle_sPHENIX::process_event(PHCompositeNode *topNode) m_prev_event_bco = -1; m_prev_runNumber = -1; m_prev_eventNumber = -1; - } // End BCO matching here if (!m_use_fake_pv) diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h index 46aa1e4cef..175d5143f2 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h @@ -44,6 +44,7 @@ #include #include // for pair #include // for vector +#include //include for new member added class PHCompositeNode; class TFile; @@ -424,7 +425,7 @@ class KFParticle_sPHENIX : public SubsysReco, public KFParticle_nTuple, public K int candidateCounter = 0; //Adding member variables for BCO matching int64_t m_this_event_bco{-1}; - int64_t m_last_event_bco_sPHENIX{-1}; + int64_t m_last_event_bco{-1}; int64_t m_prev_event_bco{-1}; int64_t m_prev_runNumber{-1}; int64_t m_prev_eventNumber{-1}; //till here From 58657424ae3201f439fb2c6cb842290c5692ff8c Mon Sep 17 00:00:00 2001 From: devloom Date: Thu, 12 Mar 2026 19:22:21 -0400 Subject: [PATCH 355/393] empty commit From 00bd415c70c0426dd28119501288368c7b66cb41 Mon Sep 17 00:00:00 2001 From: Cheng-Wei Shih Date: Thu, 12 Mar 2026 21:54:56 -0400 Subject: [PATCH 356/393] Add null check for DBInterface::instance()->getStatement() --- offline/packages/intt/InttCombinedRawDataDecoder.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/offline/packages/intt/InttCombinedRawDataDecoder.cc b/offline/packages/intt/InttCombinedRawDataDecoder.cc index 8757bf3727..c90e24433f 100644 --- a/offline/packages/intt/InttCombinedRawDataDecoder.cc +++ b/offline/packages/intt/InttCombinedRawDataDecoder.cc @@ -138,6 +138,16 @@ int InttCombinedRawDataDecoder::InitRun(PHCompositeNode* topNode) int run_number = rc->get_IntFlag("RUNNUMBER"); odbc::Statement* statement = DBInterface::instance()->getStatement("daq"); + if (!statement) + { + std::cerr << PHWHERE << "\n" + << "\tCould not get ODBC statement for 'daq' database\n" + << "\tExiting\n" + << std::flush; + exit(1); + gSystem->Exit(1); + } + if (DACValue_set_count == 0){ std::cout<< PHWHERE << ", " << "No manual setting for DAC values. Querying INTT DAC values from intt_setting table for run number " << run_number << std::endl; int error_count = InttCombinedRawDataDecoder::QueryAllDACValues(statement, run_number); From be7309c08fe17ebe0854c8733a4d069f09e2ca54 Mon Sep 17 00:00:00 2001 From: Cheng-Wei Shih Date: Thu, 12 Mar 2026 22:23:05 -0400 Subject: [PATCH 357/393] Have an universal way to check the DAC-value vector. --- offline/packages/intt/InttCombinedRawDataDecoder.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/offline/packages/intt/InttCombinedRawDataDecoder.cc b/offline/packages/intt/InttCombinedRawDataDecoder.cc index c90e24433f..4049db7bfa 100644 --- a/offline/packages/intt/InttCombinedRawDataDecoder.cc +++ b/offline/packages/intt/InttCombinedRawDataDecoder.cc @@ -152,7 +152,13 @@ int InttCombinedRawDataDecoder::InitRun(PHCompositeNode* topNode) std::cout<< PHWHERE << ", " << "No manual setting for DAC values. Querying INTT DAC values from intt_setting table for run number " << run_number << std::endl; int error_count = InttCombinedRawDataDecoder::QueryAllDACValues(statement, run_number); - if (error_count != 0 || m_intt_dac_values.size() != 8 || std::find(m_intt_dac_values.begin(), m_intt_dac_values.end(), -1) != m_intt_dac_values.end()) + int count_minus = 0; + for (const auto& dac_value : m_intt_dac_values) + { + if (dac_value <= 0) {count_minus++;} + } + + if (error_count != 0 || m_intt_dac_values.size() != 8 || count_minus != 0) { std::cerr << PHWHERE << "\n" << "\tError retrieving DAC values. error_count: " << error_count @@ -506,7 +512,7 @@ void InttCombinedRawDataDecoder::set_DACValues(std::vector input_dac_vec) } std::cout << std::endl; - if ( m_intt_dac_values.size() != 8 || count_minus != 0){ + if (m_intt_dac_values.size() != 8 || count_minus != 0){ std::cerr << PHWHERE << "\n" << "\tError: DAC values were set by user, but it should be 8 integers and all should be positive. Please check your input. Exiting. \n" << "\tThe current input DAC values are: "; From 3745b3f89a402fb1eec593d83f708f32cbf1ea69 Mon Sep 17 00:00:00 2001 From: Cheng-Wei Shih Date: Thu, 12 Mar 2026 22:59:37 -0400 Subject: [PATCH 358/393] To check if the row is not found in the table --- .../intt/InttCombinedRawDataDecoder.cc | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/offline/packages/intt/InttCombinedRawDataDecoder.cc b/offline/packages/intt/InttCombinedRawDataDecoder.cc index 4049db7bfa..72c7e931dd 100644 --- a/offline/packages/intt/InttCombinedRawDataDecoder.cc +++ b/offline/packages/intt/InttCombinedRawDataDecoder.cc @@ -537,19 +537,20 @@ int InttCombinedRawDataDecoder::QueryAllDACValues(odbc::Statement *statement, in { std::string sql = "SELECT dac0, dac1, dac2, dac3, dac4, dac5, dac6, dac7 From intt_setting WHERE runnumber = " + std::to_string(runnumber) + ";"; result_set = std::unique_ptr(statement->executeQuery(sql)); - if (result_set && result_set->next()) + + if (!(result_set && result_set->next())) { - for (int i = 0; i < 8; i++) - { - std::string column_name = "dac" + std::to_string(i); - int DAC_value = -1; - - DAC_value = result_set->getInt(column_name.c_str()); - - m_intt_dac_values.push_back(DAC_value); - - std::cout<< PHWHERE << ", retrieved DAC value for " << column_name << ": " << DAC_value << std::endl; - } + std::cerr << PHWHERE << "\n" + << "\tNo DAC row found in intt_setting for run " << runnumber << std::endl; + return 1; + } + for (int i = 0; i < 8; i++) + { + std::string column_name = "dac" + std::to_string(i); + int DAC_value = -1; + DAC_value = result_set->getInt(column_name.c_str()); + m_intt_dac_values.push_back(DAC_value); + std::cout << PHWHERE << ", retrieved DAC value for " << column_name << ": " << DAC_value << std::endl; } } catch (odbc::SQLException& e) From 92ff610bec299e9b02f86f28dba8bd71b49dc022 Mon Sep 17 00:00:00 2001 From: Mughal789 Date: Fri, 13 Mar 2026 11:39:51 -0400 Subject: [PATCH 359/393] Fix uint64_t initialization --- .../KFParticle_sPHENIX/KFParticle_nTuple.cc | 62 +++++++++---------- .../KFParticle_sPHENIX/KFParticle_nTuple.h | 6 +- .../KFParticle_sPHENIX/KFParticle_sPHENIX.h | 7 ++- 3 files changed, 39 insertions(+), 36 deletions(-) diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc b/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc index 88216d356d..b3b119e4f6 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc @@ -663,41 +663,41 @@ void KFParticle_nTuple::fillBranch(PHCompositeNode* topNode, PHNode* evtNode = nodeIter.findFirst("EventHeader"); - if (evtNode) - { - EventHeader* evtHeader = findNode::getClass(topNode, "EventHeader"); - if (evtHeader) - { - m_runNumber = evtHeader->get_RunNumber(); - m_evtNumber = evtHeader->get_EvtSequence(); - } - else - { - m_runNumber = -1; - m_evtNumber = -1; - } - - auto* gl1packet = findNode::getClass(topNode, "GL1RAWHIT"); - if (!gl1packet) - { - gl1packet = findNode::getClass(topNode, "GL1Packet"); - } - - if (gl1packet) - { - m_bco = gl1packet->lValue(0, "BCO") + m_calculated_daughter_bunch_crossing[0]; + if (evtNode) + { + EventHeader* evtHeader = findNode::getClass(topNode, "EventHeader"); + if (evtHeader) + { + m_runNumber = evtHeader->get_RunNumber(); + m_evtNumber = evtHeader->get_EvtSequence(); + } + else + { + m_runNumber = -1; + m_evtNumber = -1; + } + + auto* gl1packet = findNode::getClass(topNode, "GL1RAWHIT"); + if (!gl1packet) + { + gl1packet = findNode::getClass(topNode, "GL1Packet"); + } + + if (gl1packet) + { + m_bco = gl1packet->lValue(0, "BCO") + m_calculated_daughter_bunch_crossing[0]; + } + else + { + m_bco = -1; + } } else { - m_bco = -1; + m_runNumber = -1; + m_evtNumber = -1; + m_bco = -1; } -} - else - { - m_runNumber = -1; - m_evtNumber = -1; - m_bco = -1; - } if (m_trigger_info_available) { diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.h b/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.h index f63e60a021..45256fc1cc 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.h +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.h @@ -9,6 +9,8 @@ #include #include // for string #include +#include // fixed width integer types used for BCO counters + class PHCompositeNode; class TTree; @@ -225,8 +227,8 @@ class KFParticle_nTuple : public KFParticle_truthAndDetTools, public KFParticle_ int m_runNumber{-1}; int m_evtNumber{-1}; int64_t m_bco{-1}; - int64_t m_event_bco{-1};//current event BCO - int64_t m_last_event_bco{-1}; //only keeping this, BCO for the last event + uint64_t m_event_bco{0};//current event BCO + uint64_t m_last_event_bco{0}; //only keeping this, BCO for the last event bool m_trigger_info_available{false}; }; diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h index 175d5143f2..0812ed8f14 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.h @@ -45,6 +45,7 @@ #include // for pair #include // for vector #include //include for new member added +#include // fixed width integer types used for BCO counters class PHCompositeNode; class TFile; @@ -424,9 +425,9 @@ class KFParticle_sPHENIX : public SubsysReco, public KFParticle_nTuple, public K bool m_save_output; int candidateCounter = 0; //Adding member variables for BCO matching - int64_t m_this_event_bco{-1}; - int64_t m_last_event_bco{-1}; - int64_t m_prev_event_bco{-1}; + uint64_t m_this_event_bco{0}; + uint64_t m_last_event_bco{0}; + uint64_t m_prev_event_bco{0}; int64_t m_prev_runNumber{-1}; int64_t m_prev_eventNumber{-1}; //till here std::string m_outfile_name; From ef8b389830cfe352b575c09549ee141cd7ffa112 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Fri, 13 Mar 2026 17:18:00 -0400 Subject: [PATCH 360/393] fix clang-tidy --- .../KFParticle_sPHENIX/KFParticle_sPHENIX.cc | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc index 151a97f494..db46bffafe 100644 --- a/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc +++ b/offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc @@ -137,14 +137,17 @@ int KFParticle_sPHENIX::InitRun(PHCompositeNode *topNode) int KFParticle_sPHENIX::process_event(PHCompositeNode *topNode) { - std::vector mother, vertex_kfparticle; - std::vector> daughters, intermediates; - int nPVs, multiplicity; + std::vector mother; + std::vector vertex_kfparticle; + std::vector> daughters; + std::vector> intermediates; + int nPVs; + int multiplicity; SvtxTrackMap *check_trackmap = findNode::getClass(topNode, m_trk_map_node_name); multiplicity = check_trackmap->size(); - if (check_trackmap->size() == 0) + if (check_trackmap->empty()) { if (Verbosity() >= VERBOSITY_SOME) { @@ -215,7 +218,7 @@ int KFParticle_sPHENIX::process_event(PHCompositeNode *topNode) if (m_use_mbd_vertex) { MbdVertexMap* check_vertexmap = findNode::getClass(topNode, "MbdVertexMap"); - if (check_vertexmap->size() == 0) + if (check_vertexmap->empty()) { if (Verbosity() >= VERBOSITY_SOME) { @@ -227,7 +230,7 @@ int KFParticle_sPHENIX::process_event(PHCompositeNode *topNode) else { SvtxVertexMap* check_vertexmap = findNode::getClass(topNode, m_vtx_map_node_name); - if (check_vertexmap->size() == 0) + if (check_vertexmap->empty()) { if (Verbosity() >= VERBOSITY_SOME) { @@ -248,7 +251,7 @@ int KFParticle_sPHENIX::process_event(PHCompositeNode *topNode) vertex_kfparticle = mother; } - if (mother.size() != 0) + if (!mother.empty()) { for (unsigned int i = 0; i < mother.size(); ++i) { @@ -538,7 +541,7 @@ int KFParticle_sPHENIX::parseDecayDescriptor() setNumberOfTracks(nTracks); setDaughters(daughter_list); - if (intermediates_name.size() > 0) + if (!intermediates_name.empty()) { hasIntermediateStates(); setIntermediateStates(intermediate_list); @@ -554,15 +557,14 @@ int KFParticle_sPHENIX::parseDecayDescriptor() } return 0; } - else + + if (Verbosity() >= VERBOSITY_SOME) { - if (Verbosity() >= VERBOSITY_SOME) - { - std::cout << "KFParticle: Your decay descriptor, " << Name() << " cannot be parsed" - << "\nExiting!" << std::endl; - } - return Fun4AllReturnCodes::ABORTRUN; + std::cout << "KFParticle: Your decay descriptor, " << Name() << " cannot be parsed" + << "\nExiting!" << std::endl; } + return Fun4AllReturnCodes::ABORTRUN; + } void KFParticle_sPHENIX::getField() From 5a9c3c96c5819cb0586e2b51e4449634580bb5ce Mon Sep 17 00:00:00 2001 From: Cheng-Wei Shih Date: Sat, 14 Mar 2026 04:42:55 -0400 Subject: [PATCH 361/393] cosmetics update --- offline/packages/intt/InttCombinedRawDataDecoder.cc | 4 ++-- offline/packages/intt/InttCombinedRawDataDecoder.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/offline/packages/intt/InttCombinedRawDataDecoder.cc b/offline/packages/intt/InttCombinedRawDataDecoder.cc index 72c7e931dd..401a20629b 100644 --- a/offline/packages/intt/InttCombinedRawDataDecoder.cc +++ b/offline/packages/intt/InttCombinedRawDataDecoder.cc @@ -498,7 +498,7 @@ int InttCombinedRawDataDecoder::process_event(PHCompositeNode* topNode) } -void InttCombinedRawDataDecoder::set_DACValues(std::vector input_dac_vec) +void InttCombinedRawDataDecoder::set_DACValues(const std::vector& input_dac_vec) { m_intt_dac_values = input_dac_vec; DACValue_set_count = 1; @@ -548,7 +548,7 @@ int InttCombinedRawDataDecoder::QueryAllDACValues(odbc::Statement *statement, in { std::string column_name = "dac" + std::to_string(i); int DAC_value = -1; - DAC_value = result_set->getInt(column_name.c_str()); + DAC_value = result_set->getInt(column_name); m_intt_dac_values.push_back(DAC_value); std::cout << PHWHERE << ", retrieved DAC value for " << column_name << ": " << DAC_value << std::endl; } diff --git a/offline/packages/intt/InttCombinedRawDataDecoder.h b/offline/packages/intt/InttCombinedRawDataDecoder.h index c38badefeb..3bbdfe502d 100644 --- a/offline/packages/intt/InttCombinedRawDataDecoder.h +++ b/offline/packages/intt/InttCombinedRawDataDecoder.h @@ -66,7 +66,7 @@ class InttCombinedRawDataDecoder : public SubsysReco void set_bcoFilter(bool flag) {m_bcoFilter = flag; } void set_SaturatedChipRejection(bool flag){m_SaturatedChipRejection = flag;} // note : this is for removing a fraction of the saturated chips void set_HighChipMultiplicityCut(int cut){HighChipMultiplicityCut = cut;} - void set_DACValues(std::vector input_dac_vec); + void set_DACValues(const std::vector& input_dac_vec); private: int QueryAllDACValues(odbc::Statement *statement, int runnumber); From 2cec1df2b8f48113244281a7c380446d739a0072 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Mon, 16 Mar 2026 12:36:41 -0400 Subject: [PATCH 362/393] fix clang-tidy --- offline/packages/TrackingDiagnostics/KshortReconstruction.cc | 2 +- offline/packages/TrackingDiagnostics/KshortReconstruction.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/offline/packages/TrackingDiagnostics/KshortReconstruction.cc b/offline/packages/TrackingDiagnostics/KshortReconstruction.cc index cb344e7851..6efbebf100 100644 --- a/offline/packages/TrackingDiagnostics/KshortReconstruction.cc +++ b/offline/packages/TrackingDiagnostics/KshortReconstruction.cc @@ -473,7 +473,7 @@ void KshortReconstruction::fillNtp(SvtxTrack* track1, SvtxTrack* track2, float m float cos_theta_reco = pathLength_proj.dot(projected_momentum) / (projected_momentum.norm() * pathLength_proj.norm()); - float reco_info[] = {(float) track1->get_id(), (float) mass1, (float) track1->get_crossing(), track1->get_x(), track1->get_y(), track1->get_z(), track1->get_px(), track1->get_py(), track1->get_pz(), (float) dcavals1(0), (float) dcavals1(1), (float) dcavals1(2), (float) pca_rel1(0), (float) pca_rel1(1), (float) pca_rel1(2), (float) eta1, (float) track1->get_charge(), (float) tpcClusters1, (float) track2->get_id(), (float) mass2, (float) track2->get_crossing(), track2->get_x(), track2->get_y(), track2->get_z(), track2->get_px(), track2->get_py(), track2->get_pz(), (float) dcavals2(0), (float) dcavals2(1), (float) dcavals2(2), (float) pca_rel2(0), (float) pca_rel2(1), (float) pca_rel2(2), (float) eta2, (float) track2->get_charge(), (float) tpcClusters2, (float) ntracks_vertex, (float) vertex(0), (float) vertex(1), (float) vertex(2), (float) pair_dca, (float) invariantMass, (float) invariantPt, invariantPhi, (float) pathLength(0), (float) pathLength(1), (float) pathLength(2), mag_pathLength, rapidity, pseudorapidity, (float) projected_pos1(0), (float) projected_pos1(1), (float) projected_pos1(2), (float) projected_pos2(0), (float) projected_pos2(1), (float) projected_pos2(2), (float) projected_mom1(0), (float) projected_mom1(1), (float) projected_mom1(2), (float) projected_mom2(0), (float) projected_mom2(1), (float) projected_mom2(2), (float) pca_rel1_proj(0), (float) pca_rel1_proj(1), (float) pca_rel1_proj(2), (float) pca_rel2_proj(0), (float) pca_rel2_proj(1), (float) pca_rel2_proj(2), (float) pair_dca_proj, (float) pathLength_proj(0), (float) pathLength_proj(1), (float) pathLength_proj(2), mag_pathLength_proj, track1->get_quality(), track2->get_quality(), cos_theta_reco, (float) track1_silicon_cluster_size, (float) track2_silicon_cluster_size, (float) track1_mvtx_cluster_size, (float) track1_mvtx_state_size, (float) track1_intt_cluster_size, (float) track1_intt_state_size, (float) track2_mvtx_cluster_size, (float) track2_mvtx_state_size, (float) track2_intt_cluster_size, (float) track2_intt_state_size, (float) runNumber, (float) eventNumber}; + float reco_info[] = {(float) track1->get_id(), mass1, (float) track1->get_crossing(), track1->get_x(), track1->get_y(), track1->get_z(), track1->get_px(), track1->get_py(), track1->get_pz(), (float) dcavals1(0), (float) dcavals1(1), (float) dcavals1(2), (float) pca_rel1(0), (float) pca_rel1(1), (float) pca_rel1(2), (float) eta1, (float) track1->get_charge(), (float) tpcClusters1, (float) track2->get_id(), mass2, (float) track2->get_crossing(), track2->get_x(), track2->get_y(), track2->get_z(), track2->get_px(), track2->get_py(), track2->get_pz(), (float) dcavals2(0), (float) dcavals2(1), (float) dcavals2(2), (float) pca_rel2(0), (float) pca_rel2(1), (float) pca_rel2(2), (float) eta2, (float) track2->get_charge(), (float) tpcClusters2, (float) ntracks_vertex, (float) vertex(0), (float) vertex(1), (float) vertex(2), (float) pair_dca, (float) invariantMass, (float) invariantPt, invariantPhi, (float) pathLength(0), (float) pathLength(1), (float) pathLength(2), mag_pathLength, rapidity, pseudorapidity, (float) projected_pos1(0), (float) projected_pos1(1), (float) projected_pos1(2), (float) projected_pos2(0), (float) projected_pos2(1), (float) projected_pos2(2), (float) projected_mom1(0), (float) projected_mom1(1), (float) projected_mom1(2), (float) projected_mom2(0), (float) projected_mom2(1), (float) projected_mom2(2), (float) pca_rel1_proj(0), (float) pca_rel1_proj(1), (float) pca_rel1_proj(2), (float) pca_rel2_proj(0), (float) pca_rel2_proj(1), (float) pca_rel2_proj(2), (float) pair_dca_proj, (float) pathLength_proj(0), (float) pathLength_proj(1), (float) pathLength_proj(2), mag_pathLength_proj, track1->get_quality(), track2->get_quality(), cos_theta_reco, (float) track1_silicon_cluster_size, (float) track2_silicon_cluster_size, (float) track1_mvtx_cluster_size, (float) track1_mvtx_state_size, (float) track1_intt_cluster_size, (float) track1_intt_state_size, (float) track2_mvtx_cluster_size, (float) track2_mvtx_state_size, (float) track2_intt_cluster_size, (float) track2_intt_state_size, (float) runNumber, (float) eventNumber}; ntp_reco_info->Fill(reco_info); } diff --git a/offline/packages/TrackingDiagnostics/KshortReconstruction.h b/offline/packages/TrackingDiagnostics/KshortReconstruction.h index 95eba65b02..27d6e3f601 100644 --- a/offline/packages/TrackingDiagnostics/KshortReconstruction.h +++ b/offline/packages/TrackingDiagnostics/KshortReconstruction.h @@ -54,7 +54,7 @@ class KshortReconstruction : public SubsysReco // void fillNtp(SvtxTrack* track1, SvtxTrack* track2, Acts::Vector3 dcavals1, Acts::Vector3 dcavals2, Acts::Vector3 pca_rel1, Acts::Vector3 pca_rel2, double pair_dca, double invariantMass, double invariantPt, float invariantPhi, float rapidity, float pseudorapidity, Eigen::Vector3d projected_pos1, Eigen::Vector3d projected_pos2, Eigen::Vector3d projected_mom1, Eigen::Vector3d projected_mom2, Acts::Vector3 pca_rel1_proj, Acts::Vector3 pca_rel2_proj, double pair_dca_proj,unsigned int track1_silicon_cluster_size, unsigned int track2_silicon_cluster_size, unsigned int track1_mvtx_cluster_size, unsigned int track1_mvtx_state_size, unsigned int track1_intt_cluster_size, unsigned int track1_intt_state_size, unsigned int track2_mvtx_cluster_size, unsigned int track2_mvtx_state_size, unsigned int track2_intt_cluster_size, unsigned int track2_intt_state_size, int runNumber, int eventNumber); - void fillHistogram(Eigen::Vector3d mom1, Eigen::Vector3d mom2, TH1* massreco, double& invariantMass, double& invariantPt, float& invariantPhi, float& rapidity, float& pseudorapidity, float& decaymass1, float& decaymass2); + void fillHistogram(Eigen::Vector3d mom1, Eigen::Vector3d mom2, TH1* massreco, double& invariantMass, double& invariantPt, float& invariantPhi, float& rapidity, float& pseudorapidity, float& decaymassa, float& decaymassb); // void fillHistogram(Eigen::Vector3d mom1, Eigen::Vector3d mom2, TH1* massreco, double& invariantMass, double& invariantPt, float& invariantPhi, float& rapidity, float& pseudorapidity); From c7440ec0cb80778b043b335ae12fff5d9ab29a11 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Mon, 16 Mar 2026 16:09:35 -0400 Subject: [PATCH 363/393] make listPayloadIOVs useful --- offline/database/sphenixnpc/CDBUtils.cc | 30 +++++++++++++++++++++---- offline/database/sphenixnpc/CDBUtils.h | 12 +++++----- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/offline/database/sphenixnpc/CDBUtils.cc b/offline/database/sphenixnpc/CDBUtils.cc index 080812b419..1c01b501d3 100644 --- a/offline/database/sphenixnpc/CDBUtils.cc +++ b/offline/database/sphenixnpc/CDBUtils.cc @@ -75,23 +75,45 @@ int CDBUtils::createPayloadType(const std::string &pt) return cdbclient->createDomain(pt); } -void CDBUtils::listPayloadIOVs(uint64_t iov) +auto CDBUtils::PayloadIOVsCommon(uint64_t iov, const std::string ptype) { + std::map> iovs; nlohmann::json resp = cdbclient->getPayloadIOVs(iov); if (resp["code"] != 0) { std::cout << resp["msg"] << std::endl; - return; + return iovs; } nlohmann::json payload_iovs = resp["msg"]; - std::map> iovs; for (auto &[pt, val] : payload_iovs.items()) { std::string url = val["payload_url"]; uint64_t bts = val["minor_iov_start"]; uint64_t ets = val["minor_iov_end"]; - iovs.insert(std::make_pair(pt, std::make_tuple(url, bts, ets))); + if (ets >= iov) + { + if (!ptype.empty()) + { + if (ptype != pt) + { + continue; + } + } + iovs.insert(std::make_pair(pt, std::make_tuple(url, bts, ets))); + } } + return iovs; +} + +auto CDBUtils::returnPayloadIOVs(uint64_t iov, const std::string ptype) +{ + auto iovs = PayloadIOVsCommon(iov,ptype); + return iovs; +} + +void CDBUtils::listPayloadIOVs(uint64_t iov, const std::string ptype) +{ + auto iovs = PayloadIOVsCommon(iov,ptype); for (const auto &it : iovs) { std::cout << it.first << ": " << std::get<0>(it.second) diff --git a/offline/database/sphenixnpc/CDBUtils.h b/offline/database/sphenixnpc/CDBUtils.h index 393036236c..133fbc34fb 100644 --- a/offline/database/sphenixnpc/CDBUtils.h +++ b/offline/database/sphenixnpc/CDBUtils.h @@ -27,11 +27,9 @@ class CDBUtils int insertPayload(const std::string &pl_type, const std::string &file_url, uint64_t iov_start); int insertPayload(const std::string &pl_type, const std::string &file_url, uint64_t iov_start, uint64_t iov_end); int cloneGlobalTag(const std::string &source, const std::string &target); - int deleteGlobalTag(const std::string &); void listGlobalTags(); void listPayloadTypes(); - void listPayloadIOVs(uint64_t iov); void clearCache(); bool isGlobalTagSet(); void Verbosity(int i); @@ -39,9 +37,13 @@ class CDBUtils int deletePayloadIOV(const std::string &pl_type, uint64_t iov_start); int deletePayloadIOV(const std::string &pl_type, uint64_t iov_start, uint64_t iov_end); - private: - int m_Verbosity = 0; - SphenixClient *cdbclient = nullptr; + auto returnPayloadIOVs(uint64_t iov, const std::string ptype = ""); + auto PayloadIOVsCommon(uint64_t iov, const std::string ptype = ""); + void listPayloadIOVs(uint64_t iov, const std::string ptype = ""); + +private: + int m_Verbosity {0}; + SphenixClient *cdbclient {nullptr}; std::string m_CachedGlobalTag; std::set m_PayloadTypeCache; }; From 193a51c1763400515054aa28ed7d5e1d0eb23e0d Mon Sep 17 00:00:00 2001 From: JAEBEOm PARK Date: Mon, 16 Mar 2026 16:13:26 -0400 Subject: [PATCH 364/393] Add subtracted iso --- .../packages/CaloReco/PhotonClusterBuilder.cc | 52 ++++++++++++++++++- .../packages/CaloReco/PhotonClusterBuilder.h | 5 ++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/offline/packages/CaloReco/PhotonClusterBuilder.cc b/offline/packages/CaloReco/PhotonClusterBuilder.cc index edcf5f4418..8171c2cbce 100644 --- a/offline/packages/CaloReco/PhotonClusterBuilder.cc +++ b/offline/packages/CaloReco/PhotonClusterBuilder.cc @@ -117,6 +117,19 @@ int PhotonClusterBuilder::InitRun(PHCompositeNode* topNode) return Fun4AllReturnCodes::ABORTRUN; } + if (m_do_subtracted_iso) + { + m_emc_sub1_tower_container = findNode::getClass(topNode, "TOWERINFO_CALIB_CEMC_RETOWER_SUB1"); + m_ihcal_sub1_tower_container = findNode::getClass(topNode, "TOWERINFO_CALIB_HCALIN_SUB1"); + m_ohcal_sub1_tower_container = findNode::getClass(topNode, "TOWERINFO_CALIB_HCALOUT_SUB1"); + + if (!m_emc_sub1_tower_container || !m_ihcal_sub1_tower_container || !m_ohcal_sub1_tower_container) + { + std::cout << Name() << ": subtracted isolation enabled but one or more SUB1 tower nodes are missing; " + << "iso_sub_* values will remain at " << m_subtracted_iso_defval << std::endl; + } + } + CreateNodes(topNode); return Fun4AllReturnCodes::EVENT_OK; } @@ -323,7 +336,7 @@ void PhotonClusterBuilder::calculate_shower_shapes(RawCluster* rc, PhotonCluster nsaturated++; } } - + int totalphibins = 256; auto dphiwrap = [totalphibins](int towerphi, int maxiphi_arg) { @@ -435,7 +448,7 @@ void PhotonClusterBuilder::calculate_shower_shapes(RawCluster* rc, PhotonCluster float e72 = 0; float detacog = std::abs(maxieta - avg_eta); float dphicog = std::abs(maxiphi - avg_phi); - float drad = std::sqrt(dphicog*dphicog + detacog*detacog); + float drad = std::sqrt(dphicog * dphicog + detacog * detacog); int signphi = (avg_phi - std::floor(avg_phi)) > 0.5 ? 1 : -1; @@ -767,6 +780,41 @@ void PhotonClusterBuilder::calculate_shower_shapes(RawCluster* rc, PhotonCluster photon->set_shower_shape_parameter("iso_02_emcal", emcal_et_02 - ET); photon->set_shower_shape_parameter("iso_01_emcal", emcal_et_01 - ET); photon->set_shower_shape_parameter("iso_005_emcal", emcal_et_005 - ET); + + photon->set_shower_shape_parameter("iso_sub_04_emcal", m_subtracted_iso_defval); + photon->set_shower_shape_parameter("iso_sub_04_hcalin", m_subtracted_iso_defval); + photon->set_shower_shape_parameter("iso_sub_04_hcalout", m_subtracted_iso_defval); + photon->set_shower_shape_parameter("iso_sub_03_emcal", m_subtracted_iso_defval); + photon->set_shower_shape_parameter("iso_sub_03_hcalin", m_subtracted_iso_defval); + photon->set_shower_shape_parameter("iso_sub_03_hcalout", m_subtracted_iso_defval); + photon->set_shower_shape_parameter("iso_sub_02_emcal", m_subtracted_iso_defval); + photon->set_shower_shape_parameter("iso_sub_01_emcal", m_subtracted_iso_defval); + photon->set_shower_shape_parameter("iso_sub_005_emcal", m_subtracted_iso_defval); + + if (m_do_subtracted_iso && m_emc_sub1_tower_container && m_ihcal_sub1_tower_container && m_ohcal_sub1_tower_container) + { + const float sub_emcal_et_04 = calculate_layer_et(cluster_eta, cluster_phi, 0.4, m_emc_sub1_tower_container, m_geomIH, RawTowerDefs::CalorimeterId::HCALIN, m_vertex); + const float sub_ihcal_et_04 = calculate_layer_et(cluster_eta, cluster_phi, 0.4, m_ihcal_sub1_tower_container, m_geomIH, RawTowerDefs::CalorimeterId::HCALIN, m_vertex); + const float sub_ohcal_et_04 = calculate_layer_et(cluster_eta, cluster_phi, 0.4, m_ohcal_sub1_tower_container, m_geomOH, RawTowerDefs::CalorimeterId::HCALOUT, m_vertex); + + const float sub_emcal_et_03 = calculate_layer_et(cluster_eta, cluster_phi, 0.3, m_emc_sub1_tower_container, m_geomIH, RawTowerDefs::CalorimeterId::HCALIN, m_vertex); + const float sub_ihcal_et_03 = calculate_layer_et(cluster_eta, cluster_phi, 0.3, m_ihcal_sub1_tower_container, m_geomIH, RawTowerDefs::CalorimeterId::HCALIN, m_vertex); + const float sub_ohcal_et_03 = calculate_layer_et(cluster_eta, cluster_phi, 0.3, m_ohcal_sub1_tower_container, m_geomOH, RawTowerDefs::CalorimeterId::HCALOUT, m_vertex); + + const float sub_emcal_et_02 = calculate_layer_et(cluster_eta, cluster_phi, 0.2, m_emc_sub1_tower_container, m_geomIH, RawTowerDefs::CalorimeterId::HCALIN, m_vertex); + const float sub_emcal_et_01 = calculate_layer_et(cluster_eta, cluster_phi, 0.1, m_emc_sub1_tower_container, m_geomIH, RawTowerDefs::CalorimeterId::HCALIN, m_vertex); + const float sub_emcal_et_005 = calculate_layer_et(cluster_eta, cluster_phi, 0.05, m_emc_sub1_tower_container, m_geomIH, RawTowerDefs::CalorimeterId::HCALIN, m_vertex); + + photon->set_shower_shape_parameter("iso_sub_04_emcal", sub_emcal_et_04 - ET); + photon->set_shower_shape_parameter("iso_sub_04_hcalin", sub_ihcal_et_04); + photon->set_shower_shape_parameter("iso_sub_04_hcalout", sub_ohcal_et_04); + photon->set_shower_shape_parameter("iso_sub_03_emcal", sub_emcal_et_03 - ET); + photon->set_shower_shape_parameter("iso_sub_03_hcalin", sub_ihcal_et_03); + photon->set_shower_shape_parameter("iso_sub_03_hcalout", sub_ohcal_et_03); + photon->set_shower_shape_parameter("iso_sub_02_emcal", sub_emcal_et_02 - ET); + photon->set_shower_shape_parameter("iso_sub_01_emcal", sub_emcal_et_01 - ET); + photon->set_shower_shape_parameter("iso_sub_005_emcal", sub_emcal_et_005 - ET); + } } double PhotonClusterBuilder::getTowerEta(RawTowerGeom* tower_geom, double vx, double vy, double vz) diff --git a/offline/packages/CaloReco/PhotonClusterBuilder.h b/offline/packages/CaloReco/PhotonClusterBuilder.h index 1c987f9849..c788220871 100644 --- a/offline/packages/CaloReco/PhotonClusterBuilder.h +++ b/offline/packages/CaloReco/PhotonClusterBuilder.h @@ -53,6 +53,7 @@ class PhotonClusterBuilder : public SubsysReco double deltaR(double eta1, double phi1, double eta2, double phi2); float calculate_layer_et(float seed_eta, float seed_phi, float radius, TowerInfoContainer* towerContainer, RawTowerGeomContainer* geomContainer, RawTowerDefs::CalorimeterId calo_id, float vertex_z); bool m_do_bdt{false}; + bool m_do_subtracted_iso{false}; std::string m_input_cluster_node{"CLUSTERINFO_CEMC"}; std::string m_output_photon_node{"PHOTONCLUSTER_CEMC"}; @@ -61,6 +62,7 @@ class PhotonClusterBuilder : public SubsysReco std::string m_bdt_model_file{"myBDT_5.root"}; std::vector m_bdt_feature_list; float m_vertex{std::numeric_limits::quiet_NaN()}; + float m_subtracted_iso_defval{-999}; RawClusterContainer* m_rawclusters{nullptr}; RawClusterContainer* m_photon_container{nullptr}; @@ -70,6 +72,9 @@ class PhotonClusterBuilder : public SubsysReco RawTowerGeomContainer* m_geomIH{nullptr}; TowerInfoContainer* m_ohcal_tower_container{nullptr}; RawTowerGeomContainer* m_geomOH{nullptr}; + TowerInfoContainer* m_emc_sub1_tower_container{nullptr}; + TowerInfoContainer* m_ihcal_sub1_tower_container{nullptr}; + TowerInfoContainer* m_ohcal_sub1_tower_container{nullptr}; std::unique_ptr m_bdt; }; From 8cfb34773daf361ba5e31612b717a502e604f624 Mon Sep 17 00:00:00 2001 From: JAEBEOm PARK Date: Mon, 16 Mar 2026 16:16:02 -0400 Subject: [PATCH 365/393] Add subtracted iso --- offline/packages/CaloReco/PhotonClusterBuilder.h | 1 + 1 file changed, 1 insertion(+) diff --git a/offline/packages/CaloReco/PhotonClusterBuilder.h b/offline/packages/CaloReco/PhotonClusterBuilder.h index c788220871..b9a9baed50 100644 --- a/offline/packages/CaloReco/PhotonClusterBuilder.h +++ b/offline/packages/CaloReco/PhotonClusterBuilder.h @@ -42,6 +42,7 @@ class PhotonClusterBuilder : public SubsysReco void set_bdt_model_file(const std::string& path) { m_bdt_model_file = path; } void set_bdt_feature_list(const std::vector& features) { m_bdt_feature_list = features; } void set_do_bdt(bool do_bdt) { m_do_bdt = do_bdt; } + void set_do_subtracted_iso(bool do_subtracted_iso) { m_do_subtracted_iso = do_subtracted_iso; } const std::vector& get_bdt_feature_list() const { return m_bdt_feature_list; } private: From 7cb76f940471f85e7580395acea3f885c8825d22 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 17 Mar 2026 09:28:33 -0400 Subject: [PATCH 366/393] fix cppcheck --- offline/database/sphenixnpc/CDBUtils.cc | 6 +++--- offline/database/sphenixnpc/CDBUtils.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/offline/database/sphenixnpc/CDBUtils.cc b/offline/database/sphenixnpc/CDBUtils.cc index 1c01b501d3..4a2865545a 100644 --- a/offline/database/sphenixnpc/CDBUtils.cc +++ b/offline/database/sphenixnpc/CDBUtils.cc @@ -75,7 +75,7 @@ int CDBUtils::createPayloadType(const std::string &pt) return cdbclient->createDomain(pt); } -auto CDBUtils::PayloadIOVsCommon(uint64_t iov, const std::string ptype) +auto CDBUtils::PayloadIOVsCommon(uint64_t iov, const std::string &ptype) { std::map> iovs; nlohmann::json resp = cdbclient->getPayloadIOVs(iov); @@ -105,13 +105,13 @@ auto CDBUtils::PayloadIOVsCommon(uint64_t iov, const std::string ptype) return iovs; } -auto CDBUtils::returnPayloadIOVs(uint64_t iov, const std::string ptype) +auto CDBUtils::returnPayloadIOVs(uint64_t iov, const std::string &ptype) { auto iovs = PayloadIOVsCommon(iov,ptype); return iovs; } -void CDBUtils::listPayloadIOVs(uint64_t iov, const std::string ptype) +void CDBUtils::listPayloadIOVs(uint64_t iov, const std::string &ptype) { auto iovs = PayloadIOVsCommon(iov,ptype); for (const auto &it : iovs) diff --git a/offline/database/sphenixnpc/CDBUtils.h b/offline/database/sphenixnpc/CDBUtils.h index 133fbc34fb..616e115c54 100644 --- a/offline/database/sphenixnpc/CDBUtils.h +++ b/offline/database/sphenixnpc/CDBUtils.h @@ -37,9 +37,9 @@ class CDBUtils int deletePayloadIOV(const std::string &pl_type, uint64_t iov_start); int deletePayloadIOV(const std::string &pl_type, uint64_t iov_start, uint64_t iov_end); - auto returnPayloadIOVs(uint64_t iov, const std::string ptype = ""); - auto PayloadIOVsCommon(uint64_t iov, const std::string ptype = ""); - void listPayloadIOVs(uint64_t iov, const std::string ptype = ""); + auto returnPayloadIOVs(uint64_t iov, const std::string &ptype = ""); + auto PayloadIOVsCommon(uint64_t iov, const std::string &ptype = ""); + void listPayloadIOVs(uint64_t iov, const std::string &ptype = ""); private: int m_Verbosity {0}; From b6159de46060b3b67af32cedf235652a5f439805 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 17 Mar 2026 10:38:13 -0400 Subject: [PATCH 367/393] add new herwig and double interactions --- offline/framework/frog/CreateFileList.pl | 214 ++++++++++++++++++++++- 1 file changed, 212 insertions(+), 2 deletions(-) diff --git a/offline/framework/frog/CreateFileList.pl b/offline/framework/frog/CreateFileList.pl index e0eaa402f3..47dd8f7990 100755 --- a/offline/framework/frog/CreateFileList.pl +++ b/offline/framework/frog/CreateFileList.pl @@ -41,7 +41,7 @@ my %proddesc = ( # "1" => "hijing (0-12fm) pileup 0-12fm DELETED", # "2" => "hijing (0-4.88fm) pileup 0-12fm DELETED", - "3" => "pythia8 pp MB", +# "3" => "pythia8 pp MB", "4" => "hijing (0-20fm) pileup 0-20fm", # "5" => "hijing (0-12fm) pileup 0-20fm DELETED", "6" => "hijing (0-4.88fm) pileup 0-20fm", @@ -77,7 +77,14 @@ "36" => "JS pythia8 Jet ptmin = 5GeV", "37" => "hijing O+O (0-15fm)", "38" => "JS pythia8 Jet ptmin = 60GeV", - "39" => "JS pythia8 Jet ptmin = 12GeV" + "39" => "JS pythia8 Jet ptmin = 12GeV", + "40" => "Herwig Jet ptmin = 5 GeV", + "41" => "Herwig Jet ptmin = 12 GeV", + "42" => "Herwig Jet ptmin = 20 GeV", + "43" => "Herwig Jet ptmin = 40 GeV", + "44" => "Herwig Jet ptmin = 50 GeV", + "45" => "JS pythia8 ptmin = 12GeV + Detroit", + "46" => "JS pythia8 Photonjet ptmin = 10GeV + Detroit" ); my %pileupdesc = ( @@ -1005,6 +1012,209 @@ $pileupstring = $pp_pileupstring; &commonfiletypes(); } + elsif ($prodtype == 40) + { + $embedok = 1; + $filenamestring = "Herwig_Jet5"; + if (! defined $nopileup) + { + if (defined $embed) + { + if ($embed eq "pau") + { + $filenamestring = sprintf("%s_sHijing_pAu_0_10fm%s",$filenamestring, $pAu_pileupstring); + } + elsif ($embed eq "central") + { + $filenamestring = sprintf("%s_sHijing_0_488fm%s",$filenamestring, $AuAu_pileupstring); + } + else + { + $filenamestring = sprintf("%s_sHijing_0_20fm%s",$filenamestring, $AuAu_pileupstring); + } + } + else + { + $filenamestring = sprintf("%s%s",$filenamestring,$pp_pileupstring); + } + } + $pileupstring = $pp_pileupstring; + &commonfiletypes(); + } + elsif ($prodtype == 41) + { + $embedok = 1; + $filenamestring = "Herwig_Jet12"; + if (! defined $nopileup) + { + if (defined $embed) + { + if ($embed eq "pau") + { + $filenamestring = sprintf("%s_sHijing_pAu_0_10fm%s",$filenamestring, $pAu_pileupstring); + } + elsif ($embed eq "central") + { + $filenamestring = sprintf("%s_sHijing_0_488fm%s",$filenamestring, $AuAu_pileupstring); + } + else + { + $filenamestring = sprintf("%s_sHijing_0_20fm%s",$filenamestring, $AuAu_pileupstring); + } + } + else + { + $filenamestring = sprintf("%s%s",$filenamestring,$pp_pileupstring); + } + } + $pileupstring = $pp_pileupstring; + &commonfiletypes(); + } + elsif ($prodtype == 42) + { + $embedok = 1; + $filenamestring = "Herwig_Jet20"; + if (! defined $nopileup) + { + if (defined $embed) + { + if ($embed eq "pau") + { + $filenamestring = sprintf("%s_sHijing_pAu_0_10fm%s",$filenamestring, $pAu_pileupstring); + } + elsif ($embed eq "central") + { + $filenamestring = sprintf("%s_sHijing_0_488fm%s",$filenamestring, $AuAu_pileupstring); + } + else + { + $filenamestring = sprintf("%s_sHijing_0_20fm%s",$filenamestring, $AuAu_pileupstring); + } + } + else + { + $filenamestring = sprintf("%s%s",$filenamestring,$pp_pileupstring); + } + } + $pileupstring = $pp_pileupstring; + &commonfiletypes(); + } + elsif ($prodtype == 43) + { + $embedok = 1; + $filenamestring = "Herwig_Jet40"; + if (! defined $nopileup) + { + if (defined $embed) + { + if ($embed eq "pau") + { + $filenamestring = sprintf("%s_sHijing_pAu_0_10fm%s",$filenamestring, $pAu_pileupstring); + } + elsif ($embed eq "central") + { + $filenamestring = sprintf("%s_sHijing_0_488fm%s",$filenamestring, $AuAu_pileupstring); + } + else + { + $filenamestring = sprintf("%s_sHijing_0_20fm%s",$filenamestring, $AuAu_pileupstring); + } + } + else + { + $filenamestring = sprintf("%s%s",$filenamestring,$pp_pileupstring); + } + } + $pileupstring = $pp_pileupstring; + &commonfiletypes(); + } + elsif ($prodtype == 44) + { + $embedok = 1; + $filenamestring = "Herwig_Jet50"; + if (! defined $nopileup) + { + if (defined $embed) + { + if ($embed eq "pau") + { + $filenamestring = sprintf("%s_sHijing_pAu_0_10fm%s",$filenamestring, $pAu_pileupstring); + } + elsif ($embed eq "central") + { + $filenamestring = sprintf("%s_sHijing_0_488fm%s",$filenamestring, $AuAu_pileupstring); + } + else + { + $filenamestring = sprintf("%s_sHijing_0_20fm%s",$filenamestring, $AuAu_pileupstring); + } + } + else + { + $filenamestring = sprintf("%s%s",$filenamestring,$pp_pileupstring); + } + } + $pileupstring = $pp_pileupstring; + &commonfiletypes(); + } + elsif ($prodtype == 45) + { + $embedok = 1; + $filenamestring = "pythia8_Jet12_pythia8_Detroit"; + if (! defined $nopileup) + { + if (defined $embed) + { + if ($embed eq "pau") + { + $filenamestring = sprintf("%s_sHijing_pAu_0_10fm%s",$filenamestring, $pAu_pileupstring); + } + elsif ($embed eq "central") + { + $filenamestring = sprintf("%s_sHijing_0_488fm%s",$filenamestring, $AuAu_pileupstring); + } + else + { + $filenamestring = sprintf("%s_sHijing_0_20fm%s",$filenamestring, $AuAu_pileupstring); + } + } + else + { + $filenamestring = sprintf("%s%s",$filenamestring,$pp_pileupstring); + } + } + $pileupstring = $pp_pileupstring; + &commonfiletypes(); + } + elsif ($prodtype == 46) + { + $embedok = 1; + $filenamestring = "pythia8_PhotonJet10_pythia8_Detroit"; + if (! defined $nopileup) + { + if (defined $embed) + { + if ($embed eq "pau") + { + $filenamestring = sprintf("%s_sHijing_pAu_0_10fm%s",$filenamestring, $pAu_pileupstring); + } + elsif ($embed eq "central") + { + $filenamestring = sprintf("%s_sHijing_0_488fm%s",$filenamestring, $AuAu_pileupstring); + } + else + { + $filenamestring = sprintf("%s_sHijing_0_20fm%s",$filenamestring, $AuAu_pileupstring); + } + } + else + { + $filenamestring = sprintf("%s%s",$filenamestring,$pp_pileupstring); + } + } + $pileupstring = $pp_pileupstring; + &commonfiletypes(); + } else { From 63192a838a9a3c87eb89b2d4f9703f9e5d6414a0 Mon Sep 17 00:00:00 2001 From: Nikhil Kumar Date: Tue, 17 Mar 2026 12:45:19 -0400 Subject: [PATCH 368/393] Update GlobalVertexv3.cc --- offline/packages/globalvertex/GlobalVertexv3.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/offline/packages/globalvertex/GlobalVertexv3.cc b/offline/packages/globalvertex/GlobalVertexv3.cc index 1504a7cd3d..4eca34c62c 100644 --- a/offline/packages/globalvertex/GlobalVertexv3.cc +++ b/offline/packages/globalvertex/GlobalVertexv3.cc @@ -128,7 +128,12 @@ float GlobalVertexv3::get_position(unsigned int coor) const auto caloit = _vtxs.find(GlobalVertex::VTXTYPE::CALO); if (caloit == _vtxs.end()) { - return std::numeric_limits::quiet_NaN(); + auto truthit = _vtxs.find(GlobalVertex::VTXTYPE::TRUTH); + if (truthit == _vtxs.end()) + { + return std::numeric_limits::quiet_NaN(); + } + return truthit->second[0]->get_position(coor); } return caloit->second[0]->get_position(coor); } From 1643e870621d982ab43b97fb111caed5b57cae1a Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 17 Mar 2026 12:51:09 -0400 Subject: [PATCH 369/393] fix memory leak at exit, use uniq_ptr --- offline/database/sphenixnpc/CDBUtils.cc | 4 ++-- offline/database/sphenixnpc/CDBUtils.h | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/offline/database/sphenixnpc/CDBUtils.cc b/offline/database/sphenixnpc/CDBUtils.cc index 4a2865545a..997b00e5c2 100644 --- a/offline/database/sphenixnpc/CDBUtils.cc +++ b/offline/database/sphenixnpc/CDBUtils.cc @@ -12,12 +12,12 @@ #include // for pair, make_pair CDBUtils::CDBUtils() - : cdbclient(new SphenixClient()) + : cdbclient(std::make_unique()) { } CDBUtils::CDBUtils(const std::string &globaltag) - : cdbclient(new SphenixClient(globaltag)) + : cdbclient(std::make_unique(globaltag)) { } diff --git a/offline/database/sphenixnpc/CDBUtils.h b/offline/database/sphenixnpc/CDBUtils.h index 616e115c54..3c4f877c9d 100644 --- a/offline/database/sphenixnpc/CDBUtils.h +++ b/offline/database/sphenixnpc/CDBUtils.h @@ -2,6 +2,7 @@ #define SPHENIXNPC_CDBUTILS_H #include // for uint64_t +#include #include #include @@ -43,7 +44,7 @@ class CDBUtils private: int m_Verbosity {0}; - SphenixClient *cdbclient {nullptr}; + std::unique_ptr cdbclient; std::string m_CachedGlobalTag; std::set m_PayloadTypeCache; }; From 31baa72e67b5122c70d44e892803a84f96763a70 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 17 Mar 2026 14:26:10 -0400 Subject: [PATCH 370/393] change first OO run from 82374 to 82388 after trigger was finalized --- offline/framework/phool/RunnumberRange.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/framework/phool/RunnumberRange.h b/offline/framework/phool/RunnumberRange.h index 0a447f259b..d582a4e935 100644 --- a/offline/framework/phool/RunnumberRange.h +++ b/offline/framework/phool/RunnumberRange.h @@ -29,7 +29,7 @@ namespace RunnumberRange static const int RUN3AUAU_LAST = 78954; static const int RUN3PP_FIRST = 79146; // first beam data static const int RUN3PP_LAST = 81668; - static const int RUN3OO_FIRST = 82374; + static const int RUN3OO_FIRST = 82388; // after trigger settled down (run 82374 excluded); static const int RUN3OO_LAST = 82703; } From fbdf9c6dea0d2698600252ab07b1cea368a85d78 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 17 Mar 2026 15:07:55 -0400 Subject: [PATCH 371/393] use constexpr instead of static const --- offline/framework/phool/RunnumberRange.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/offline/framework/phool/RunnumberRange.h b/offline/framework/phool/RunnumberRange.h index d582a4e935..ab6593bff5 100644 --- a/offline/framework/phool/RunnumberRange.h +++ b/offline/framework/phool/RunnumberRange.h @@ -20,17 +20,17 @@ */ namespace RunnumberRange { - static const int RUN2PP_FIRST = 47286; - static const int RUN2PP_LAST = 53880; - static const int RUN2AUAU_FIRST = 54128; - static const int RUN2AUAU_LAST = 54974; - static const int RUN3_TPCFW_CLOCK_CHANGE = 58667; - static const int RUN3AUAU_FIRST = 66457; - static const int RUN3AUAU_LAST = 78954; - static const int RUN3PP_FIRST = 79146; // first beam data - static const int RUN3PP_LAST = 81668; - static const int RUN3OO_FIRST = 82388; // after trigger settled down (run 82374 excluded); - static const int RUN3OO_LAST = 82703; + constexpr int RUN2PP_FIRST = 47286; + constexpr int RUN2PP_LAST = 53880; + constexpr int RUN2AUAU_FIRST = 54128; + constexpr int RUN2AUAU_LAST = 54974; + constexpr int RUN3_TPCFW_CLOCK_CHANGE = 58667; + constexpr int RUN3AUAU_FIRST = 66457; + constexpr int RUN3AUAU_LAST = 78954; + constexpr int RUN3PP_FIRST = 79146; // first beam data + constexpr int RUN3PP_LAST = 81668; + constexpr int RUN3OO_FIRST = 82388; // after trigger settled down (run 82374 excluded); + constexpr int RUN3OO_LAST = 82703; } #endif From 6a8cc05188a4aaa3a2ff3caa6a70b3f154651819 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Tue, 17 Mar 2026 15:21:57 -0400 Subject: [PATCH 372/393] fixes --- offline/database/sphenixnpc/CDBUtils.cc | 14 ++++---------- offline/database/sphenixnpc/CDBUtils.h | 4 ++-- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/offline/database/sphenixnpc/CDBUtils.cc b/offline/database/sphenixnpc/CDBUtils.cc index 997b00e5c2..4608605e7c 100644 --- a/offline/database/sphenixnpc/CDBUtils.cc +++ b/offline/database/sphenixnpc/CDBUtils.cc @@ -75,7 +75,7 @@ int CDBUtils::createPayloadType(const std::string &pt) return cdbclient->createDomain(pt); } -auto CDBUtils::PayloadIOVsCommon(uint64_t iov, const std::string &ptype) +std::map> CDBUtils::PayloadIOVs(uint64_t iov, const std::string &ptype) { std::map> iovs; nlohmann::json resp = cdbclient->getPayloadIOVs(iov); @@ -90,11 +90,11 @@ auto CDBUtils::PayloadIOVsCommon(uint64_t iov, const std::string &ptype) std::string url = val["payload_url"]; uint64_t bts = val["minor_iov_start"]; uint64_t ets = val["minor_iov_end"]; - if (ets >= iov) + if (ets > iov) { if (!ptype.empty()) { - if (ptype != pt) + if (pt.find(ptype) == std::string::npos) { continue; } @@ -105,15 +105,9 @@ auto CDBUtils::PayloadIOVsCommon(uint64_t iov, const std::string &ptype) return iovs; } -auto CDBUtils::returnPayloadIOVs(uint64_t iov, const std::string &ptype) -{ - auto iovs = PayloadIOVsCommon(iov,ptype); - return iovs; -} - void CDBUtils::listPayloadIOVs(uint64_t iov, const std::string &ptype) { - auto iovs = PayloadIOVsCommon(iov,ptype); + auto iovs = PayloadIOVs(iov,ptype); for (const auto &it : iovs) { std::cout << it.first << ": " << std::get<0>(it.second) diff --git a/offline/database/sphenixnpc/CDBUtils.h b/offline/database/sphenixnpc/CDBUtils.h index 3c4f877c9d..0e6272fab1 100644 --- a/offline/database/sphenixnpc/CDBUtils.h +++ b/offline/database/sphenixnpc/CDBUtils.h @@ -2,6 +2,7 @@ #define SPHENIXNPC_CDBUTILS_H #include // for uint64_t +#include #include #include #include @@ -38,8 +39,7 @@ class CDBUtils int deletePayloadIOV(const std::string &pl_type, uint64_t iov_start); int deletePayloadIOV(const std::string &pl_type, uint64_t iov_start, uint64_t iov_end); - auto returnPayloadIOVs(uint64_t iov, const std::string &ptype = ""); - auto PayloadIOVsCommon(uint64_t iov, const std::string &ptype = ""); + std::map> PayloadIOVs(uint64_t iov, const std::string &ptype = ""); void listPayloadIOVs(uint64_t iov, const std::string &ptype = ""); private: From 54589d3163e44d4f5ed574bed5989546b28a1989 Mon Sep 17 00:00:00 2001 From: Cheng-Wei Shih Date: Wed, 18 Mar 2026 05:22:21 -0400 Subject: [PATCH 373/393] Add a function to universally mask the INTT chip --- offline/packages/intt/InttCombinedRawDataDecoder.cc | 13 +++++++++++++ offline/packages/intt/InttCombinedRawDataDecoder.h | 4 ++++ 2 files changed, 17 insertions(+) diff --git a/offline/packages/intt/InttCombinedRawDataDecoder.cc b/offline/packages/intt/InttCombinedRawDataDecoder.cc index 401a20629b..4ffd06f8e1 100644 --- a/offline/packages/intt/InttCombinedRawDataDecoder.cc +++ b/offline/packages/intt/InttCombinedRawDataDecoder.cc @@ -351,6 +351,19 @@ int InttCombinedRawDataDecoder::process_event(PHCompositeNode* topNode) continue; } + if (std::find(permanant_mask_chip.begin(), permanant_mask_chip.end(), std::format("{}_{}_{}", raw.felix_server, raw.felix_channel, raw.chip)) != permanant_mask_chip.end()) + { + if (1 < Verbosity()) + { + std::cout + << PHWHERE << "\n" + << "\tMasking permanant bad chip due to timing issues:\n" + << "\t" << raw.felix_server << " " << raw.felix_channel << " " << raw.chip << " " << raw.channel << "\n" + << std::endl; + } + continue; + } + //////////////////////// // bco filter if (m_bcomap.IsBad(raw, bco_full, bco) && m_bcoFilter) diff --git a/offline/packages/intt/InttCombinedRawDataDecoder.h b/offline/packages/intt/InttCombinedRawDataDecoder.h index 3bbdfe502d..642f2edafa 100644 --- a/offline/packages/intt/InttCombinedRawDataDecoder.h +++ b/offline/packages/intt/InttCombinedRawDataDecoder.h @@ -95,6 +95,10 @@ class InttCombinedRawDataDecoder : public SubsysReco std::map evt_ChipHit_count_map; int HighChipMultiplicityCut = 71; + std::vector permanant_mask_chip = { + "2_9_15" // note : FELIX 2, FELIX channel 9, chip 15 (chip ID range: 0 to 25) + }; + }; #endif // INTT_COMBINEDRAWDATADECODER_H From 190096403d27d3945a10b6bace28d4220fb1d320 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Wed, 18 Mar 2026 09:53:31 -0400 Subject: [PATCH 374/393] empty commit to trigger jenkins From ce2fb5e92715feace19bd7d6012e75b950c5dcfe Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Wed, 18 Mar 2026 14:15:48 -0400 Subject: [PATCH 375/393] CaloCDB: Migrate FilterDatasets from CDBUtils to CDBInterface - Removed CDBUtils dependency: Deleted the std::unique_ptr member and removed its associated header from filter-datasets - Integrated CDBInterface: Updated getCalibration to utilize the CDBInterface::instance()->getUrl() method. - Managed Global State via recoConsts: - Updated getCalibration to dynamically set the TIMESTAMP flag in recoConsts for each IOV to ensure the correct calibration version is retrieved. - Initialized the CDB_GLOBALTAG flag within the main function of CaloCDB-FilterDatasets.cc. - Resolved Header Conflicts: Eliminated the destructor requirement that triggered the incomplete type error in the unique_ptr cleanup. --- .../calo_cdb/CaloCDB-FilterDatasets.cc | 5 ++++ calibrations/calorimeter/calo_cdb/Makefile.am | 1 + .../calorimeter/calo_cdb/filter-datasets.cc | 29 +++++-------------- .../calorimeter/calo_cdb/filter-datasets.h | 9 +----- 4 files changed, 15 insertions(+), 29 deletions(-) diff --git a/calibrations/calorimeter/calo_cdb/CaloCDB-FilterDatasets.cc b/calibrations/calorimeter/calo_cdb/CaloCDB-FilterDatasets.cc index 8528cd26ae..31c3ba7798 100644 --- a/calibrations/calorimeter/calo_cdb/CaloCDB-FilterDatasets.cc +++ b/calibrations/calorimeter/calo_cdb/CaloCDB-FilterDatasets.cc @@ -1,5 +1,7 @@ #include "filter-datasets.h" +#include + #include int main(int argc, const char* const argv[]) @@ -28,6 +30,9 @@ int main(int argc, const char* const argv[]) debug = std::stoi(args[3]); } + recoConsts* rc = recoConsts::instance(); + rc->set_StringFlag("CDB_GLOBALTAG", "newcdbtag"); + FilterDatasets filter(debug); filter.process(input_csv, output_dir_path); diff --git a/calibrations/calorimeter/calo_cdb/Makefile.am b/calibrations/calorimeter/calo_cdb/Makefile.am index 9fbea67179..23e990440f 100644 --- a/calibrations/calorimeter/calo_cdb/Makefile.am +++ b/calibrations/calorimeter/calo_cdb/Makefile.am @@ -35,6 +35,7 @@ libcalo_cdb_la_LIBADD = \ -lcalo_io \ -lcdbobjects \ -lsphenixnpc \ + -lffamodules \ -lemcNoisyTowerFinder CaloCDB_GenStatus_SOURCES = CaloCDB-GenStatus.cc diff --git a/calibrations/calorimeter/calo_cdb/filter-datasets.cc b/calibrations/calorimeter/calo_cdb/filter-datasets.cc index 38ce957c4e..9dfbf442e3 100644 --- a/calibrations/calorimeter/calo_cdb/filter-datasets.cc +++ b/calibrations/calorimeter/calo_cdb/filter-datasets.cc @@ -4,11 +4,9 @@ // -- My Utils -- #include "myUtils.h" -// c++ includes -- -#include -#include -#include -#include +// sPHENIX includes -- +#include +#include FilterDatasets::FilterDatasets(Bool_t debug) : m_debug(debug) @@ -30,21 +28,12 @@ void FilterDatasets::readRunInfo(const std::string &line) std::string FilterDatasets::getCalibration(const std::string &pl_type, uint64_t iov) { - if (!uti) - { - uti = std::make_unique(); - } - return uti->getUrl(pl_type, iov); -} + recoConsts *rc = recoConsts::instance(); + // Update the global timestamp flag for the current run in the loop + rc->set_uint64Flag("TIMESTAMP", iov); -int FilterDatasets::setGlobalTag(const std::string &tagname) -{ - if (!uti) - { - uti = std::make_unique(); - } - int iret = uti->setGlobalTag(tagname); - return iret; + // Fetch the calibration URL via CDBInterface + return CDBInterface::instance()->getUrl(pl_type); } void FilterDatasets::analyze(const std::string &input, const std::string &outputDir) @@ -142,8 +131,6 @@ void FilterDatasets::process(const std::string &input, const std::string &output std::cout << "Debug: " << ((m_debug) ? "True" : "False") << std::endl; std::cout << "#############################" << std::endl; - setGlobalTag("newcdbtag"); - std::filesystem::path input_filepath_obj(input); if (!myUtils::readCSV(input_filepath_obj, [this](const std::string &line) { this->readRunInfo(line); })) diff --git a/calibrations/calorimeter/calo_cdb/filter-datasets.h b/calibrations/calorimeter/calo_cdb/filter-datasets.h index c3af89f1de..c4d9fa21f4 100644 --- a/calibrations/calorimeter/calo_cdb/filter-datasets.h +++ b/calibrations/calorimeter/calo_cdb/filter-datasets.h @@ -1,17 +1,13 @@ #ifndef CALOCDB_FILTERDATASETS_H #define CALOCDB_FILTERDATASETS_H -// -- sPHENIX includes -- -#include - // -- ROOT includes -- #include // -- c++ includes -- #include -#include +#include #include -#include #include class FilterDatasets @@ -26,7 +22,6 @@ class FilterDatasets void readRunInfo(const std::string &line); std::string getCalibration(const std::string &pl_type, uint64_t iov); - int setGlobalTag(const std::string &tagname); std::vector> m_runInfo; std::map m_ctr; @@ -37,8 +32,6 @@ class FilterDatasets , "CEMC_ZSCrossCalib", "HCALIN_ZSCrossCalib", "HCALOUT_ZSCrossCalib"}; Bool_t m_debug; - - std::unique_ptr uti{nullptr}; }; #endif From 265c26e9e0cb9eabf26ce52636ed0118253ad750 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Wed, 18 Mar 2026 14:31:31 -0400 Subject: [PATCH 376/393] add fee masking to tpc time builder --- offline/framework/fun4allraw/Makefile.am | 4 +- .../fun4allraw/SingleTpcTimeFrameInput.cc | 37 +++++++++++++++++++ .../fun4allraw/SingleTpcTimeFrameInput.h | 4 +- .../fun4allraw/TpcTimeFrameBuilder.cc | 6 +++ .../fun4allraw/TpcTimeFrameBuilder.h | 16 ++++++++ 5 files changed, 65 insertions(+), 2 deletions(-) diff --git a/offline/framework/fun4allraw/Makefile.am b/offline/framework/fun4allraw/Makefile.am index ef0c1b54a2..7f852ce989 100644 --- a/offline/framework/fun4allraw/Makefile.am +++ b/offline/framework/fun4allraw/Makefile.am @@ -100,7 +100,9 @@ libfun4allraw_la_LIBADD = \ -lfun4all \ -lEvent \ -lphoolraw \ - -lqautils + -lqautils \ + -lffamodules \ + -lcdbobjects BUILT_SOURCES = testexternals.cc diff --git a/offline/framework/fun4allraw/SingleTpcTimeFrameInput.cc b/offline/framework/fun4allraw/SingleTpcTimeFrameInput.cc index 03e83f4cd0..85ebd6f6b2 100644 --- a/offline/framework/fun4allraw/SingleTpcTimeFrameInput.cc +++ b/offline/framework/fun4allraw/SingleTpcTimeFrameInput.cc @@ -13,6 +13,8 @@ #include #include +#include +#include #include // for PHTimer #include @@ -64,6 +66,9 @@ SingleTpcTimeFrameInput::SingleTpcTimeFrameInput(const std::string &name) assert(i <= 20); m_hNorm->GetXaxis()->LabelsOption("v"); hm->registerHisto(m_hNorm); + + + fillBadFeeMap(); } SingleTpcTimeFrameInput::~SingleTpcTimeFrameInput() @@ -293,6 +298,7 @@ void SingleTpcTimeFrameInput::FillPool(const uint64_t targetBCO) m_TpcTimeFrameBuilderMap[packet_id] = new TpcTimeFrameBuilder(packet_id); m_TpcTimeFrameBuilderMap[packet_id]->setVerbosity(Verbosity()); + fillBadFeeMap(); if (!m_digitalCurrentDebugTTreeName.empty()) { m_TpcTimeFrameBuilderMap[packet_id]->SaveDigitalCurrentDebugTTree(m_digitalCurrentDebugTTreeName); @@ -396,3 +402,34 @@ void SingleTpcTimeFrameInput::ConfigureStreamingInputManager() } return; } + +void SingleTpcTimeFrameInput::fillBadFeeMap() +{ +const std::string filename = CDBInterface::instance()->getUrl("TPC_DECODER_BAD_FEE"); + +// map of ebdc to std::set to mask +std::map> maskedFEEs; + +if (filename.empty()) +{ + if (Verbosity() > 0) + { + std::cout << "SingleTpcTimeFrameInput::fillBadFeeMap - no file found for TPC_DECODER_BAD_FEE, not filling bad fee map" << std::endl; + } + return; + } + + CDBTTree cdbtree(filename); + cdbtree.LoadCalibrations(); + + const int nentries = cdbtree.GetSingleIntValue("N_MASKED_FEES"); + + for(int i=0; isetMaskedFEEs(maskedFEEs); + } +} \ No newline at end of file diff --git a/offline/framework/fun4allraw/SingleTpcTimeFrameInput.h b/offline/framework/fun4allraw/SingleTpcTimeFrameInput.h index e1f9ded3dd..bb78722a09 100644 --- a/offline/framework/fun4allraw/SingleTpcTimeFrameInput.h +++ b/offline/framework/fun4allraw/SingleTpcTimeFrameInput.h @@ -41,10 +41,12 @@ class SingleTpcTimeFrameInput : public SingleStreamingInput { m_digitalCurrentDebugTTreeName = name; } + private: const int NTPCPACKETS = 3; + void fillBadFeeMap(); Packet **plist{nullptr}; unsigned int m_NumSpecialEvents{0}; unsigned int m_BcoRange{0}; @@ -53,7 +55,7 @@ class SingleTpcTimeFrameInput : public SingleStreamingInput //! packet ID -> TimeFrame builder std::map m_TpcTimeFrameBuilderMap; std::set m_SelectedPacketIDs; - + TH1 *m_hNorm = nullptr; PHTimer *m_FillPoolTimer = nullptr; diff --git a/offline/framework/fun4allraw/TpcTimeFrameBuilder.cc b/offline/framework/fun4allraw/TpcTimeFrameBuilder.cc index 309e7bf391..9f8721b0a7 100644 --- a/offline/framework/fun4allraw/TpcTimeFrameBuilder.cc +++ b/offline/framework/fun4allraw/TpcTimeFrameBuilder.cc @@ -595,6 +595,12 @@ int TpcTimeFrameBuilder::ProcessPacket(Packet* packet) if ((dma_word_data.dma_header & 0xFF00U) == FEE_MAGIC_KEY) { unsigned int fee_id = dma_word_data.dma_header & 0xffU; + + // for packet id 4XYZ ebdc is XY, endpoint is Z + if (m_maskedFEEs[((m_packet_id / 10) % 100)].contains(fee_id)) + { + continue; + } if (fee_id < MAX_FEECOUNT) { diff --git a/offline/framework/fun4allraw/TpcTimeFrameBuilder.h b/offline/framework/fun4allraw/TpcTimeFrameBuilder.h index 553052b851..79902e9932 100644 --- a/offline/framework/fun4allraw/TpcTimeFrameBuilder.h +++ b/offline/framework/fun4allraw/TpcTimeFrameBuilder.h @@ -40,6 +40,20 @@ class TpcTimeFrameBuilder { m_fastBCOSkip = fastBCOSkip; } + void setMaskedFEEs(const std::map> &maskedFEEs) + { + m_maskedFEEs = maskedFEEs; + + + for(const auto& [ebdc, feeset]: m_maskedFEEs) + { + std::cout << "checking ebdc " << ebdc << std::endl; + for(const auto& feeid : feeset) + { + std::cout << "fee id in set: " << feeid << std::endl; + } + } + } // enable saving of digital current debug TTree with file name `name` void SaveDigitalCurrentDebugTTree(const std::string &name); @@ -371,6 +385,8 @@ class TpcTimeFrameBuilder private: std::vector> m_feeData; + std::map> m_maskedFEEs; + int m_verbosity = 0; int m_packet_id = 0; From 6f1a2fc91dc430145192073be7955df18515c3f4 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Wed, 18 Mar 2026 14:33:24 -0400 Subject: [PATCH 377/393] remove debug statements --- .../framework/fun4allraw/SingleTpcTimeFrameInput.cc | 2 -- offline/framework/fun4allraw/TpcTimeFrameBuilder.h | 10 ---------- 2 files changed, 12 deletions(-) diff --git a/offline/framework/fun4allraw/SingleTpcTimeFrameInput.cc b/offline/framework/fun4allraw/SingleTpcTimeFrameInput.cc index 85ebd6f6b2..ea131cd4bc 100644 --- a/offline/framework/fun4allraw/SingleTpcTimeFrameInput.cc +++ b/offline/framework/fun4allraw/SingleTpcTimeFrameInput.cc @@ -67,8 +67,6 @@ SingleTpcTimeFrameInput::SingleTpcTimeFrameInput(const std::string &name) m_hNorm->GetXaxis()->LabelsOption("v"); hm->registerHisto(m_hNorm); - - fillBadFeeMap(); } SingleTpcTimeFrameInput::~SingleTpcTimeFrameInput() diff --git a/offline/framework/fun4allraw/TpcTimeFrameBuilder.h b/offline/framework/fun4allraw/TpcTimeFrameBuilder.h index 79902e9932..a608687a96 100644 --- a/offline/framework/fun4allraw/TpcTimeFrameBuilder.h +++ b/offline/framework/fun4allraw/TpcTimeFrameBuilder.h @@ -43,16 +43,6 @@ class TpcTimeFrameBuilder void setMaskedFEEs(const std::map> &maskedFEEs) { m_maskedFEEs = maskedFEEs; - - - for(const auto& [ebdc, feeset]: m_maskedFEEs) - { - std::cout << "checking ebdc " << ebdc << std::endl; - for(const auto& feeid : feeset) - { - std::cout << "fee id in set: " << feeid << std::endl; - } - } } // enable saving of digital current debug TTree with file name `name` From 57e77e0ff3b81ffea3f0eebb8bbe5db19a53a724 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Wed, 18 Mar 2026 14:33:50 -0400 Subject: [PATCH 378/393] clang-format --- .../fun4allraw/SingleTpcTimeFrameInput.cc | 21 +++++++------ .../fun4allraw/SingleTpcTimeFrameInput.h | 9 +++--- .../fun4allraw/TpcTimeFrameBuilder.cc | 2 +- .../fun4allraw/TpcTimeFrameBuilder.h | 30 +++++++++---------- 4 files changed, 30 insertions(+), 32 deletions(-) diff --git a/offline/framework/fun4allraw/SingleTpcTimeFrameInput.cc b/offline/framework/fun4allraw/SingleTpcTimeFrameInput.cc index ea131cd4bc..a4f9443c07 100644 --- a/offline/framework/fun4allraw/SingleTpcTimeFrameInput.cc +++ b/offline/framework/fun4allraw/SingleTpcTimeFrameInput.cc @@ -13,8 +13,8 @@ #include #include -#include #include +#include #include // for PHTimer #include @@ -66,7 +66,6 @@ SingleTpcTimeFrameInput::SingleTpcTimeFrameInput(const std::string &name) assert(i <= 20); m_hNorm->GetXaxis()->LabelsOption("v"); hm->registerHisto(m_hNorm); - } SingleTpcTimeFrameInput::~SingleTpcTimeFrameInput() @@ -403,16 +402,16 @@ void SingleTpcTimeFrameInput::ConfigureStreamingInputManager() void SingleTpcTimeFrameInput::fillBadFeeMap() { -const std::string filename = CDBInterface::instance()->getUrl("TPC_DECODER_BAD_FEE"); + const std::string filename = CDBInterface::instance()->getUrl("TPC_DECODER_BAD_FEE"); -// map of ebdc to std::set to mask -std::map> maskedFEEs; + // map of ebdc to std::set to mask + std::map> maskedFEEs; -if (filename.empty()) -{ - if (Verbosity() > 0) + if (filename.empty()) { - std::cout << "SingleTpcTimeFrameInput::fillBadFeeMap - no file found for TPC_DECODER_BAD_FEE, not filling bad fee map" << std::endl; + if (Verbosity() > 0) + { + std::cout << "SingleTpcTimeFrameInput::fillBadFeeMap - no file found for TPC_DECODER_BAD_FEE, not filling bad fee map" << std::endl; } return; } @@ -422,11 +421,11 @@ if (filename.empty()) const int nentries = cdbtree.GetSingleIntValue("N_MASKED_FEES"); - for(int i=0; isetMaskedFEEs(maskedFEEs); } diff --git a/offline/framework/fun4allraw/SingleTpcTimeFrameInput.h b/offline/framework/fun4allraw/SingleTpcTimeFrameInput.h index bb78722a09..a3c279584f 100644 --- a/offline/framework/fun4allraw/SingleTpcTimeFrameInput.h +++ b/offline/framework/fun4allraw/SingleTpcTimeFrameInput.h @@ -41,7 +41,6 @@ class SingleTpcTimeFrameInput : public SingleStreamingInput { m_digitalCurrentDebugTTreeName = name; } - private: const int NTPCPACKETS = 3; @@ -65,14 +64,14 @@ class SingleTpcTimeFrameInput : public SingleStreamingInput // NOLINTNEXTLINE(hicpp-special-member-functions) class TimeTracker - { + { public: - TimeTracker(PHTimer * timer, const std::string & name, TH1* hout) ; - virtual ~TimeTracker() ; + TimeTracker(PHTimer *timer, const std::string &name, TH1 *hout); + virtual ~TimeTracker(); void stop(); private: - PHTimer * m_timer = nullptr; + PHTimer *m_timer = nullptr; std::string m_name; TH1 *m_hNorm = nullptr; bool stopped = false; diff --git a/offline/framework/fun4allraw/TpcTimeFrameBuilder.cc b/offline/framework/fun4allraw/TpcTimeFrameBuilder.cc index 9f8721b0a7..1f76902cb7 100644 --- a/offline/framework/fun4allraw/TpcTimeFrameBuilder.cc +++ b/offline/framework/fun4allraw/TpcTimeFrameBuilder.cc @@ -595,7 +595,7 @@ int TpcTimeFrameBuilder::ProcessPacket(Packet* packet) if ((dma_word_data.dma_header & 0xFF00U) == FEE_MAGIC_KEY) { unsigned int fee_id = dma_word_data.dma_header & 0xffU; - + // for packet id 4XYZ ebdc is XY, endpoint is Z if (m_maskedFEEs[((m_packet_id / 10) % 100)].contains(fee_id)) { diff --git a/offline/framework/fun4allraw/TpcTimeFrameBuilder.h b/offline/framework/fun4allraw/TpcTimeFrameBuilder.h index a608687a96..751818eb97 100644 --- a/offline/framework/fun4allraw/TpcTimeFrameBuilder.h +++ b/offline/framework/fun4allraw/TpcTimeFrameBuilder.h @@ -54,7 +54,7 @@ class TpcTimeFrameBuilder static const uint16_t FEE_PACKET_MAGIC_KEY_1 = 0xfe; static const uint16_t FEE_PACKET_MAGIC_KEY_2 = 0xed; - static const uint16_t FEE_PACKET_MAGIC_KEY_3_DC = 0xdcdc; // Digital Current word[3] + static const uint16_t FEE_PACKET_MAGIC_KEY_3_DC = 0xdcdc; // Digital Current word[3] static const uint16_t FEE_MAGIC_KEY = 0xba00; static const uint16_t GTM_MAGIC_KEY = 0xbb00; @@ -85,8 +85,8 @@ class TpcTimeFrameBuilder int decode_gtm_data(const dma_word >m_word); int process_fee_data(unsigned int fee_id); - void process_fee_data_waveform(const unsigned int & fee_id, std::deque& data_buffer); - void process_fee_data_digital_current(const unsigned int & fee_id, std::deque& data_buffer); + void process_fee_data_waveform(const unsigned int &fee_id, std::deque &data_buffer); + void process_fee_data_digital_current(const unsigned int &fee_id, std::deque &data_buffer); struct gtm_payload { @@ -116,7 +116,7 @@ class TpcTimeFrameBuilder uint16_t data_crc = 0; uint16_t calc_crc = 0; - + uint16_t data_parity = 0; uint16_t calc_parity = 0; @@ -127,18 +127,18 @@ class TpcTimeFrameBuilder { static const int MAX_CHANNELS = 8; - uint64_t gtm_bco {std::numeric_limits::max()}; - uint32_t bx_timestamp_predicted {std::numeric_limits::max()}; + uint64_t gtm_bco{std::numeric_limits::max()}; + uint32_t bx_timestamp_predicted{std::numeric_limits::max()}; - uint16_t fee {std::numeric_limits::max()}; - uint16_t pkt_length {std::numeric_limits::max()}; - uint16_t channel {std::numeric_limits::max()}; + uint16_t fee{std::numeric_limits::max()}; + uint16_t pkt_length{std::numeric_limits::max()}; + uint16_t channel{std::numeric_limits::max()}; // uint16_t sampa_max_channel {std::numeric_limits::max()}; - uint16_t sampa_address {std::numeric_limits::max()}; - uint32_t bx_timestamp {0}; - uint32_t current[MAX_CHANNELS] {0}; - uint32_t nsamples[MAX_CHANNELS] {0}; - uint16_t data_crc {std::numeric_limits::max()}; + uint16_t sampa_address{std::numeric_limits::max()}; + uint32_t bx_timestamp{0}; + uint32_t current[MAX_CHANNELS]{0}; + uint32_t nsamples[MAX_CHANNELS]{0}; + uint16_t data_crc{std::numeric_limits::max()}; uint16_t calc_crc = {std::numeric_limits::max()}; // uint16_t type {std::numeric_limits::max()}; }; @@ -157,7 +157,7 @@ class TpcTimeFrameBuilder std::string m_name; TTree *m_tDigitalCurrent = nullptr; }; - DigitalCurrentDebugTTree * m_digitalCurrentDebugTTree = nullptr; + DigitalCurrentDebugTTree *m_digitalCurrentDebugTTree = nullptr; // ------------------------- // GTM Matcher From ef21e3fa2bdab2fd1baa12689ee1932192ed01cc Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Wed, 18 Mar 2026 14:42:41 -0400 Subject: [PATCH 379/393] refactor everything into the time frame builder --- .../fun4allraw/SingleTpcTimeFrameInput.cc | 35 +------------------ .../fun4allraw/TpcTimeFrameBuilder.cc | 29 +++++++++++++++ .../fun4allraw/TpcTimeFrameBuilder.h | 6 ++-- 3 files changed, 32 insertions(+), 38 deletions(-) diff --git a/offline/framework/fun4allraw/SingleTpcTimeFrameInput.cc b/offline/framework/fun4allraw/SingleTpcTimeFrameInput.cc index a4f9443c07..dd9559b075 100644 --- a/offline/framework/fun4allraw/SingleTpcTimeFrameInput.cc +++ b/offline/framework/fun4allraw/SingleTpcTimeFrameInput.cc @@ -13,8 +13,6 @@ #include #include -#include -#include #include // for PHTimer #include @@ -295,7 +293,7 @@ void SingleTpcTimeFrameInput::FillPool(const uint64_t targetBCO) m_TpcTimeFrameBuilderMap[packet_id] = new TpcTimeFrameBuilder(packet_id); m_TpcTimeFrameBuilderMap[packet_id]->setVerbosity(Verbosity()); - fillBadFeeMap(); + m_TpcTimeFrameBuilderMap[packet_id]->fillBadFeeMap(); if (!m_digitalCurrentDebugTTreeName.empty()) { m_TpcTimeFrameBuilderMap[packet_id]->SaveDigitalCurrentDebugTTree(m_digitalCurrentDebugTTreeName); @@ -399,34 +397,3 @@ void SingleTpcTimeFrameInput::ConfigureStreamingInputManager() } return; } - -void SingleTpcTimeFrameInput::fillBadFeeMap() -{ - const std::string filename = CDBInterface::instance()->getUrl("TPC_DECODER_BAD_FEE"); - - // map of ebdc to std::set to mask - std::map> maskedFEEs; - - if (filename.empty()) - { - if (Verbosity() > 0) - { - std::cout << "SingleTpcTimeFrameInput::fillBadFeeMap - no file found for TPC_DECODER_BAD_FEE, not filling bad fee map" << std::endl; - } - return; - } - - CDBTTree cdbtree(filename); - cdbtree.LoadCalibrations(); - - const int nentries = cdbtree.GetSingleIntValue("N_MASKED_FEES"); - - for (int i = 0; i < nentries; i++) - { - maskedFEEs[cdbtree.GetIntValue(i, "EBDC")].insert(cdbtree.GetIntValue(i, "FEEID")); - } - for (const auto &[packet, tb] : m_TpcTimeFrameBuilderMap) - { - tb->setMaskedFEEs(maskedFEEs); - } -} \ No newline at end of file diff --git a/offline/framework/fun4allraw/TpcTimeFrameBuilder.cc b/offline/framework/fun4allraw/TpcTimeFrameBuilder.cc index 1f76902cb7..fc39fcace7 100644 --- a/offline/framework/fun4allraw/TpcTimeFrameBuilder.cc +++ b/offline/framework/fun4allraw/TpcTimeFrameBuilder.cc @@ -8,6 +8,9 @@ #include #include +#include +#include + #include // for PHTimer #include @@ -2062,3 +2065,29 @@ void TpcTimeFrameBuilder::BcoMatchingInformation::cleanup(uint64_t ref_bco) // clear orphans m_orphans.clear(); } + + +void TpcTimeFrameBuilder::fillBadFeeMap() +{ + const std::string filename = CDBInterface::instance()->getUrl("TPC_DECODER_BAD_FEE"); + + if (filename.empty()) + { + if (m_verbosity > 0) + { + std::cout << "TpcTimeFrameBuilder::fillBadFeeMap - no file found for TPC_DECODER_BAD_FEE, not filling bad fee map" << std::endl; + } + return; + } + + CDBTTree cdbtree(filename); + cdbtree.LoadCalibrations(); + + const int nentries = cdbtree.GetSingleIntValue("N_MASKED_FEES"); + + for (int i = 0; i < nentries; i++) + { + m_maskedFEEs[cdbtree.GetIntValue(i, "EBDC")].insert(cdbtree.GetIntValue(i, "FEEID")); + } + +} \ No newline at end of file diff --git a/offline/framework/fun4allraw/TpcTimeFrameBuilder.h b/offline/framework/fun4allraw/TpcTimeFrameBuilder.h index 751818eb97..3da4ad4d19 100644 --- a/offline/framework/fun4allraw/TpcTimeFrameBuilder.h +++ b/offline/framework/fun4allraw/TpcTimeFrameBuilder.h @@ -40,11 +40,9 @@ class TpcTimeFrameBuilder { m_fastBCOSkip = fastBCOSkip; } - void setMaskedFEEs(const std::map> &maskedFEEs) - { - m_maskedFEEs = maskedFEEs; - } + void fillBadFeeMap(); + // enable saving of digital current debug TTree with file name `name` void SaveDigitalCurrentDebugTTree(const std::string &name); From 9b0ab1c0b8cba7d9dbc235654441a2eb7023421a Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Wed, 18 Mar 2026 14:44:04 -0400 Subject: [PATCH 380/393] remove unnecessary function --- offline/framework/fun4allraw/SingleTpcTimeFrameInput.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/offline/framework/fun4allraw/SingleTpcTimeFrameInput.h b/offline/framework/fun4allraw/SingleTpcTimeFrameInput.h index a3c279584f..8460a6473b 100644 --- a/offline/framework/fun4allraw/SingleTpcTimeFrameInput.h +++ b/offline/framework/fun4allraw/SingleTpcTimeFrameInput.h @@ -44,8 +44,7 @@ class SingleTpcTimeFrameInput : public SingleStreamingInput private: const int NTPCPACKETS = 3; - - void fillBadFeeMap(); + Packet **plist{nullptr}; unsigned int m_NumSpecialEvents{0}; unsigned int m_BcoRange{0}; From f947ccde161a826340a055b40dc4a39e8b5e5fd2 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Wed, 18 Mar 2026 14:44:48 -0400 Subject: [PATCH 381/393] clang-format --- offline/framework/fun4allraw/SingleTpcTimeFrameInput.h | 2 +- offline/framework/fun4allraw/TpcTimeFrameBuilder.cc | 2 -- offline/framework/fun4allraw/TpcTimeFrameBuilder.h | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/offline/framework/fun4allraw/SingleTpcTimeFrameInput.h b/offline/framework/fun4allraw/SingleTpcTimeFrameInput.h index 8460a6473b..e9e10cae59 100644 --- a/offline/framework/fun4allraw/SingleTpcTimeFrameInput.h +++ b/offline/framework/fun4allraw/SingleTpcTimeFrameInput.h @@ -44,7 +44,7 @@ class SingleTpcTimeFrameInput : public SingleStreamingInput private: const int NTPCPACKETS = 3; - + Packet **plist{nullptr}; unsigned int m_NumSpecialEvents{0}; unsigned int m_BcoRange{0}; diff --git a/offline/framework/fun4allraw/TpcTimeFrameBuilder.cc b/offline/framework/fun4allraw/TpcTimeFrameBuilder.cc index fc39fcace7..e068899771 100644 --- a/offline/framework/fun4allraw/TpcTimeFrameBuilder.cc +++ b/offline/framework/fun4allraw/TpcTimeFrameBuilder.cc @@ -2066,7 +2066,6 @@ void TpcTimeFrameBuilder::BcoMatchingInformation::cleanup(uint64_t ref_bco) m_orphans.clear(); } - void TpcTimeFrameBuilder::fillBadFeeMap() { const std::string filename = CDBInterface::instance()->getUrl("TPC_DECODER_BAD_FEE"); @@ -2089,5 +2088,4 @@ void TpcTimeFrameBuilder::fillBadFeeMap() { m_maskedFEEs[cdbtree.GetIntValue(i, "EBDC")].insert(cdbtree.GetIntValue(i, "FEEID")); } - } \ No newline at end of file diff --git a/offline/framework/fun4allraw/TpcTimeFrameBuilder.h b/offline/framework/fun4allraw/TpcTimeFrameBuilder.h index 3da4ad4d19..07e2921310 100644 --- a/offline/framework/fun4allraw/TpcTimeFrameBuilder.h +++ b/offline/framework/fun4allraw/TpcTimeFrameBuilder.h @@ -42,7 +42,7 @@ class TpcTimeFrameBuilder } void fillBadFeeMap(); - + // enable saving of digital current debug TTree with file name `name` void SaveDigitalCurrentDebugTTree(const std::string &name); From ed2c67b8d5759ca1d532fd6f3fa581f169066a1d Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Wed, 18 Mar 2026 15:50:01 -0400 Subject: [PATCH 382/393] cleanup --- .../calorimeter/calo_cdb/CaloCDB-FilterDatasets.cc | 6 ++++-- calibrations/calorimeter/calo_cdb/CaloCDB-GenStatus.cc | 3 ++- .../calo_cdb/{filter-datasets.cc => FilterDatasets.cc} | 8 +++++++- .../calo_cdb/{filter-datasets.h => FilterDatasets.h} | 7 ++----- .../calorimeter/calo_cdb/{genStatus.cc => GenStatus.cc} | 3 +-- .../calorimeter/calo_cdb/{genStatus.h => GenStatus.h} | 0 calibrations/calorimeter/calo_cdb/Makefile.am | 8 ++++---- calibrations/calorimeter/calo_cdb/myUtils.cc | 3 +++ calibrations/calorimeter/calo_cdb/myUtils.h | 7 ++++--- 9 files changed, 27 insertions(+), 18 deletions(-) rename calibrations/calorimeter/calo_cdb/{filter-datasets.cc => FilterDatasets.cc} (96%) rename calibrations/calorimeter/calo_cdb/{filter-datasets.h => FilterDatasets.h} (89%) rename calibrations/calorimeter/calo_cdb/{genStatus.cc => GenStatus.cc} (99%) rename calibrations/calorimeter/calo_cdb/{genStatus.h => GenStatus.h} (100%) diff --git a/calibrations/calorimeter/calo_cdb/CaloCDB-FilterDatasets.cc b/calibrations/calorimeter/calo_cdb/CaloCDB-FilterDatasets.cc index 31c3ba7798..56df96e205 100644 --- a/calibrations/calorimeter/calo_cdb/CaloCDB-FilterDatasets.cc +++ b/calibrations/calorimeter/calo_cdb/CaloCDB-FilterDatasets.cc @@ -1,8 +1,10 @@ -#include "filter-datasets.h" +#include "FilterDatasets.h" #include #include +#include +#include int main(int argc, const char* const argv[]) { @@ -19,7 +21,7 @@ int main(int argc, const char* const argv[]) const std::string& input_csv = args[1]; std::string output_dir_path = "."; - Bool_t debug = false; + bool debug = false; if (args.size() >= 3) { diff --git a/calibrations/calorimeter/calo_cdb/CaloCDB-GenStatus.cc b/calibrations/calorimeter/calo_cdb/CaloCDB-GenStatus.cc index 335563c295..49bf3e3c4f 100644 --- a/calibrations/calorimeter/calo_cdb/CaloCDB-GenStatus.cc +++ b/calibrations/calorimeter/calo_cdb/CaloCDB-GenStatus.cc @@ -1,6 +1,7 @@ -#include "genStatus.h" +#include "GenStatus.h" #include +#include #include int main(int argc, const char* const argv[]) diff --git a/calibrations/calorimeter/calo_cdb/filter-datasets.cc b/calibrations/calorimeter/calo_cdb/FilterDatasets.cc similarity index 96% rename from calibrations/calorimeter/calo_cdb/filter-datasets.cc rename to calibrations/calorimeter/calo_cdb/FilterDatasets.cc index 9dfbf442e3..5ac745f0e8 100644 --- a/calibrations/calorimeter/calo_cdb/filter-datasets.cc +++ b/calibrations/calorimeter/calo_cdb/FilterDatasets.cc @@ -1,5 +1,5 @@ -#include "filter-datasets.h" +#include "FilterDatasets.h" // -- My Utils -- #include "myUtils.h" @@ -8,6 +8,12 @@ #include #include +#include +#include +#include +#include +#include + FilterDatasets::FilterDatasets(Bool_t debug) : m_debug(debug) { diff --git a/calibrations/calorimeter/calo_cdb/filter-datasets.h b/calibrations/calorimeter/calo_cdb/FilterDatasets.h similarity index 89% rename from calibrations/calorimeter/calo_cdb/filter-datasets.h rename to calibrations/calorimeter/calo_cdb/FilterDatasets.h index c4d9fa21f4..c92485e75e 100644 --- a/calibrations/calorimeter/calo_cdb/filter-datasets.h +++ b/calibrations/calorimeter/calo_cdb/FilterDatasets.h @@ -1,9 +1,6 @@ #ifndef CALOCDB_FILTERDATASETS_H #define CALOCDB_FILTERDATASETS_H -// -- ROOT includes -- -#include - // -- c++ includes -- #include #include @@ -13,7 +10,7 @@ class FilterDatasets { public: - explicit FilterDatasets(Bool_t debug = false); + explicit FilterDatasets(bool debug = false); void process(const std::string &input, const std::string &output = "."); @@ -31,7 +28,7 @@ class FilterDatasets , "CEMC_hotTowers_fracBadChi2", "HCALIN_hotTowers_fracBadChi2", "HCALOUT_hotTowers_fracBadChi2" , "CEMC_ZSCrossCalib", "HCALIN_ZSCrossCalib", "HCALOUT_ZSCrossCalib"}; - Bool_t m_debug; + bool m_debug; }; #endif diff --git a/calibrations/calorimeter/calo_cdb/genStatus.cc b/calibrations/calorimeter/calo_cdb/GenStatus.cc similarity index 99% rename from calibrations/calorimeter/calo_cdb/genStatus.cc rename to calibrations/calorimeter/calo_cdb/GenStatus.cc index a49703127a..a5cdf538f6 100644 --- a/calibrations/calorimeter/calo_cdb/genStatus.cc +++ b/calibrations/calorimeter/calo_cdb/GenStatus.cc @@ -1,4 +1,4 @@ -#include "genStatus.h" +#include "GenStatus.h" #include "geometry_constants.h" @@ -15,7 +15,6 @@ // c++ includes -- #include #include -#include #include #include diff --git a/calibrations/calorimeter/calo_cdb/genStatus.h b/calibrations/calorimeter/calo_cdb/GenStatus.h similarity index 100% rename from calibrations/calorimeter/calo_cdb/genStatus.h rename to calibrations/calorimeter/calo_cdb/GenStatus.h diff --git a/calibrations/calorimeter/calo_cdb/Makefile.am b/calibrations/calorimeter/calo_cdb/Makefile.am index 23e990440f..e54424f4ae 100644 --- a/calibrations/calorimeter/calo_cdb/Makefile.am +++ b/calibrations/calorimeter/calo_cdb/Makefile.am @@ -16,8 +16,8 @@ AM_LDFLAGS = \ `root-config --libs` pkginclude_HEADERS = \ - genStatus.h \ - filter-datasets.h \ + GenStatus.h \ + FilterDatasets.h \ geometry_constants.h \ myUtils.h @@ -25,8 +25,8 @@ lib_LTLIBRARIES = \ libcalo_cdb.la libcalo_cdb_la_SOURCES = \ - genStatus.cc \ - filter-datasets.cc \ + GenStatus.cc \ + FilterDatasets.cc \ myUtils.cc libcalo_cdb_la_LIBADD = \ diff --git a/calibrations/calorimeter/calo_cdb/myUtils.cc b/calibrations/calorimeter/calo_cdb/myUtils.cc index 21a37ed595..3f495a4e7d 100644 --- a/calibrations/calorimeter/calo_cdb/myUtils.cc +++ b/calibrations/calorimeter/calo_cdb/myUtils.cc @@ -4,9 +4,12 @@ // root includes -- #include #include +#include +#include // c++ includes -- #include +#include TFitResultPtr myUtils::doGausFit(TH1 *hist, Double_t start, Double_t end, const std::string &name) { diff --git a/calibrations/calorimeter/calo_cdb/myUtils.h b/calibrations/calorimeter/calo_cdb/myUtils.h index 2799ab808f..a44d61984e 100644 --- a/calibrations/calorimeter/calo_cdb/myUtils.h +++ b/calibrations/calorimeter/calo_cdb/myUtils.h @@ -2,18 +2,19 @@ #define CALOCDB_MYUTILS_H // ROOT includes -- +#include #include -#include // -- c++ includes -- #include #include #include -#include #include #include #include +class TH1; + template concept InvocableWithString = std::invocable; @@ -39,7 +40,7 @@ class myUtils * @return true if the file was successfully opened and read, false otherwise. */ template // Using the more general concept for wider applicability - static Bool_t readCSV(const std::filesystem::path& filePath, Callable lineHandler, Bool_t skipHeader = true) + static bool readCSV(const std::filesystem::path& filePath, Callable lineHandler, bool skipHeader = true) { std::ifstream file(filePath); From cea59d00c328005edb502f46033076e322a69f82 Mon Sep 17 00:00:00 2001 From: Joe Osborn Date: Wed, 18 Mar 2026 21:43:34 -0400 Subject: [PATCH 383/393] trigger jenkins From d30a8d5dd4bb978a955a3840ade3f6ccc1cd0a4f Mon Sep 17 00:00:00 2001 From: Apurva Narde <58493193+Steepspace@users.noreply.github.com> Date: Thu, 19 Mar 2026 11:50:19 -0400 Subject: [PATCH 384/393] CaloCDB: Refactor header installation in Makefile.am - Public Headers (pkginclude_HEADERS): Retained GenStatus.h and geometry_constants.h because they are required for external macro execution in `runProd.C`. - Private Headers (noinst_HEADERS): Moved FilterDatasets.h and myUtils.h to noinst_HEADERS to prevent unnecessary global installation of internal utilities. --- calibrations/calorimeter/calo_cdb/Makefile.am | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/calibrations/calorimeter/calo_cdb/Makefile.am b/calibrations/calorimeter/calo_cdb/Makefile.am index e54424f4ae..0107211521 100644 --- a/calibrations/calorimeter/calo_cdb/Makefile.am +++ b/calibrations/calorimeter/calo_cdb/Makefile.am @@ -15,10 +15,14 @@ AM_LDFLAGS = \ -L$(OFFLINE_MAIN)/lib64 \ `root-config --libs` +# Headers installed for use in macros and by other packages pkginclude_HEADERS = \ GenStatus.h \ + geometry_constants.h + +# Headers used only for building this library and its binaries +noinst_HEADERS = \ FilterDatasets.h \ - geometry_constants.h \ myUtils.h lib_LTLIBRARIES = \ From 8aedf7bbd2756209407cc60d0381bfb6d7885220 Mon Sep 17 00:00:00 2001 From: Nikhil Kumar Date: Fri, 20 Mar 2026 00:23:16 -0400 Subject: [PATCH 385/393] Add get_position to truthvertex This was another reason using get_z on the global vertex returned NaN for type=truth. Now it works (tested privately) --- .../packages/globalvertex/TruthVertex_v1.cc | 18 ++++++++++++++++++ offline/packages/globalvertex/TruthVertex_v1.h | 2 ++ 2 files changed, 20 insertions(+) diff --git a/offline/packages/globalvertex/TruthVertex_v1.cc b/offline/packages/globalvertex/TruthVertex_v1.cc index 38e9b2a61b..1c1ad39f4d 100644 --- a/offline/packages/globalvertex/TruthVertex_v1.cc +++ b/offline/packages/globalvertex/TruthVertex_v1.cc @@ -15,3 +15,21 @@ int TruthVertex_v1::isValid() const { return std::isfinite(_z) && std::isfinite(_t); } + +float TruthVertex_v1::get_position(unsigned int coor) const +{ + if (coor == 0) + { + return get_x(); + } + if (coor == 1) + { + return get_y(); + } + if (coor == 2) + { + return get_z(); + } + + return std::numeric_limits::quiet_NaN(); +} \ No newline at end of file diff --git a/offline/packages/globalvertex/TruthVertex_v1.h b/offline/packages/globalvertex/TruthVertex_v1.h index 42b48d9903..ec18a8b053 100644 --- a/offline/packages/globalvertex/TruthVertex_v1.h +++ b/offline/packages/globalvertex/TruthVertex_v1.h @@ -46,6 +46,8 @@ class TruthVertex_v1 : public TruthVertex float get_y_err() const override { return _y_err; } void set_y_err(float y_err) override { _y_err = y_err; } + float get_position(unsigned int coor) const override; + private: unsigned int _id{std::numeric_limits::max()}; float _t{std::numeric_limits::quiet_NaN()}; From c996608763386c4f71bcb6b5a6c8c15cd1b33839 Mon Sep 17 00:00:00 2001 From: Nikhil Kumar <137448289+nk7252@users.noreply.github.com> Date: Fri, 20 Mar 2026 00:30:57 -0400 Subject: [PATCH 386/393] Update offline/packages/globalvertex/TruthVertex_v1.h Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- offline/packages/globalvertex/TruthVertex_v1.h | 1 - 1 file changed, 1 deletion(-) diff --git a/offline/packages/globalvertex/TruthVertex_v1.h b/offline/packages/globalvertex/TruthVertex_v1.h index ec18a8b053..e5148387af 100644 --- a/offline/packages/globalvertex/TruthVertex_v1.h +++ b/offline/packages/globalvertex/TruthVertex_v1.h @@ -47,7 +47,6 @@ class TruthVertex_v1 : public TruthVertex void set_y_err(float y_err) override { _y_err = y_err; } float get_position(unsigned int coor) const override; - private: unsigned int _id{std::numeric_limits::max()}; float _t{std::numeric_limits::quiet_NaN()}; From 25804ae7ac8124b2122796f0bf82458312cfd2df Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Fri, 20 Mar 2026 15:06:34 -0400 Subject: [PATCH 387/393] add flag for double interaction samples --- offline/framework/frog/CreateFileList.pl | 83 ++++++------------------ 1 file changed, 20 insertions(+), 63 deletions(-) diff --git a/offline/framework/frog/CreateFileList.pl b/offline/framework/frog/CreateFileList.pl index 47dd8f7990..6d297598c1 100755 --- a/offline/framework/frog/CreateFileList.pl +++ b/offline/framework/frog/CreateFileList.pl @@ -82,9 +82,7 @@ "41" => "Herwig Jet ptmin = 12 GeV", "42" => "Herwig Jet ptmin = 20 GeV", "43" => "Herwig Jet ptmin = 40 GeV", - "44" => "Herwig Jet ptmin = 50 GeV", - "45" => "JS pythia8 ptmin = 12GeV + Detroit", - "46" => "JS pythia8 Photonjet ptmin = 10GeV + Detroit" + "44" => "Herwig Jet ptmin = 50 GeV" ); my %pileupdesc = ( @@ -112,6 +110,7 @@ my $pmax; my $production; my $momentum; +my $double; # that should teach me a lesson to not give a flag an optional string value # just using embed:s leads to the next ARGV to be used as argument, even if it # is the next option. Sadly getopt swallows the - so parsing this becomes @@ -149,7 +148,7 @@ $iarg++; } @ARGV=@newargs; -GetOptions('embed:s' => \$embed, 'l:i' => \$last_segment, 'momentum:s' => \$momentum, 'n:i' => \$nEvents, "nobkgpileup" => \$nobkgpileup, "nopileup" => \$nopileup, "particle:s" => \$particle, 'pileup:i' => \$pileup, "pmin:i" => \$pmin, "pmax:i"=>\$pmax, "production:s"=>\$production, 'rand' => \$randomize, 'run:i' => \$runnumber, 's:i' => \$start_segment, 'type:i' =>\$prodtype, "verbose" =>\$verbose); +GetOptions('double' => \$double, 'embed:s' => \$embed, 'l:i' => \$last_segment, 'momentum:s' => \$momentum, 'n:i' => \$nEvents, "nobkgpileup" => \$nobkgpileup, "nopileup" => \$nopileup, "particle:s" => \$particle, 'pileup:i' => \$pileup, "pmin:i" => \$pmin, "pmax:i"=>\$pmax, "production:s"=>\$production, 'rand' => \$randomize, 'run:i' => \$runnumber, 's:i' => \$start_segment, 'type:i' =>\$prodtype, "verbose" =>\$verbose); my $filenamestring; my %filetypes = (); my %notlike = (); @@ -215,6 +214,7 @@ } my $embedok = 0; +my $doubleok = 0; if (defined $prodtype) { @@ -683,6 +683,11 @@ { $embedok = 1; $filenamestring = "pythia8_PhotonJet10"; + if (defined $double) + { + $doubleok = 1; + $filenamestring = "pythia8_PhotonJet10_pythia8_Detroit"; + } if (! defined $nopileup) { if (defined $embed) @@ -987,6 +992,11 @@ { $embedok = 1; $filenamestring = "pythia8_Jet12"; + if (defined $double) + { + $doubleok = 1; + $filenamestring = "pythia8_Jet12_pythia8_Detroit"; + } if (! defined $nopileup) { if (defined $embed) @@ -1157,65 +1167,6 @@ $pileupstring = $pp_pileupstring; &commonfiletypes(); } - elsif ($prodtype == 45) - { - $embedok = 1; - $filenamestring = "pythia8_Jet12_pythia8_Detroit"; - if (! defined $nopileup) - { - if (defined $embed) - { - if ($embed eq "pau") - { - $filenamestring = sprintf("%s_sHijing_pAu_0_10fm%s",$filenamestring, $pAu_pileupstring); - } - elsif ($embed eq "central") - { - $filenamestring = sprintf("%s_sHijing_0_488fm%s",$filenamestring, $AuAu_pileupstring); - } - else - { - $filenamestring = sprintf("%s_sHijing_0_20fm%s",$filenamestring, $AuAu_pileupstring); - } - } - else - { - $filenamestring = sprintf("%s%s",$filenamestring,$pp_pileupstring); - } - } - $pileupstring = $pp_pileupstring; - &commonfiletypes(); - } - elsif ($prodtype == 46) - { - $embedok = 1; - $filenamestring = "pythia8_PhotonJet10_pythia8_Detroit"; - if (! defined $nopileup) - { - if (defined $embed) - { - if ($embed eq "pau") - { - $filenamestring = sprintf("%s_sHijing_pAu_0_10fm%s",$filenamestring, $pAu_pileupstring); - } - elsif ($embed eq "central") - { - $filenamestring = sprintf("%s_sHijing_0_488fm%s",$filenamestring, $AuAu_pileupstring); - } - else - { - $filenamestring = sprintf("%s_sHijing_0_20fm%s",$filenamestring, $AuAu_pileupstring); - } - } - else - { - $filenamestring = sprintf("%s%s",$filenamestring,$pp_pileupstring); - } - } - $pileupstring = $pp_pileupstring; - &commonfiletypes(); - } - else { print "no production type $prodtype\n"; @@ -1229,6 +1180,11 @@ print "Embedding not implemented for type $prodtype\n"; exit(1); } +if (defined $double && ! $doubleok) +{ + print "Double interactions not implemented for type $prodtype\n"; + exit(1); +} my $filenamestring_with_runnumber = sprintf("%s\-%010d-",$filenamestring,$runnumber); if ($#ARGV < 0) @@ -1237,6 +1193,7 @@ { print "usage: CreateFileLists.pl -type \n"; print "parameters:\n"; + print "-double : double interactions, pp of your type and Detroit pp\n"; print "-embed : pp embedded into MB AuAu hijing (only for pp types)\n"; print " -embed pau : embedded into pAu (only for pp types)\n"; print " -embed central : embedded into central AuAu\n"; From e4802c58ebbb1eef94d12c654068e828c9ffc927 Mon Sep 17 00:00:00 2001 From: Chris Pinkenburg Date: Fri, 20 Mar 2026 15:22:08 -0400 Subject: [PATCH 388/393] add oo embedded files --- offline/framework/frog/CreateFileList.pl | 54 +++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/offline/framework/frog/CreateFileList.pl b/offline/framework/frog/CreateFileList.pl index 6d297598c1..08ea13e981 100755 --- a/offline/framework/frog/CreateFileList.pl +++ b/offline/framework/frog/CreateFileList.pl @@ -135,7 +135,7 @@ else { push(@newargs, $argument); - if ($ARGV[$iarg+1] ne "pau" && $ARGV[$iarg+1] ne "auau" && $ARGV[$iarg+1] ne "central") + if ($ARGV[$iarg+1] ne "pau" && $ARGV[$iarg+1] ne "auau" && $ARGV[$iarg+1] ne "central" && $ARGV[$iarg+1] ne "oo" ) { push(@newargs,"auau"); } @@ -328,6 +328,10 @@ { $filenamestring = sprintf("%s_sHijing_0_488fm%s",$filenamestring, $AuAu_pileupstring); } + elsif ($embed eq "oo") + { + $filenamestring = sprintf("%s_sHijing_OO_0_15fm%s",$filenamestring, $OO_pileupstring); + } else { $filenamestring = sprintf("%s_sHijing_0_20fm%s",$filenamestring, $AuAu_pileupstring); @@ -357,6 +361,10 @@ { $filenamestring = sprintf("%s_sHijing_0_488fm%s",$filenamestring, $AuAu_pileupstring); } + elsif ($embed eq "oo") + { + $filenamestring = sprintf("%s_sHijing_OO_0_15fm%s",$filenamestring, $OO_pileupstring); + } else { $filenamestring = sprintf("%s_sHijing_0_20fm%s",$filenamestring, $AuAu_pileupstring); @@ -523,6 +531,10 @@ { $filenamestring = sprintf("%s_sHijing_0_488fm%s",$filenamestring, $AuAu_pileupstring); } + elsif ($embed eq "oo") + { + $filenamestring = sprintf("%s_sHijing_OO_0_15fm%s",$filenamestring, $OO_pileupstring); + } else { $filenamestring = sprintf("%s_sHijing_0_20fm%s",$filenamestring, $AuAu_pileupstring); @@ -566,6 +578,10 @@ { $filenamestring = sprintf("%s_sHijing_0_488fm%s",$filenamestring, $AuAu_pileupstring); } + elsif ($embed eq "oo") + { + $filenamestring = sprintf("%s_sHijing_OO_0_15fm%s",$filenamestring, $OO_pileupstring); + } else { $filenamestring = sprintf("%s_sHijing_0_20fm%s",$filenamestring, $AuAu_pileupstring); @@ -666,6 +682,10 @@ { $filenamestring = sprintf("%s_sHijing_0_488fm%s",$filenamestring, $AuAu_pileupstring); } + elsif ($embed eq "oo") + { + $filenamestring = sprintf("%s_sHijing_OO_0_15fm%s",$filenamestring, $OO_pileupstring); + } else { $filenamestring = sprintf("%s_sHijing_0_20fm%s",$filenamestring, $AuAu_pileupstring); @@ -700,6 +720,10 @@ { $filenamestring = sprintf("%s_sHijing_0_488fm%s",$filenamestring, $AuAu_pileupstring); } + elsif ($embed eq "oo") + { + $filenamestring = sprintf("%s_sHijing_OO_0_15fm%s",$filenamestring, $OO_pileupstring); + } else { $filenamestring = sprintf("%s_sHijing_0_20fm%s",$filenamestring, $AuAu_pileupstring); @@ -729,6 +753,10 @@ { $filenamestring = sprintf("%s_sHijing_0_488fm%s",$filenamestring, $AuAu_pileupstring); } + elsif ($embed eq "oo") + { + $filenamestring = sprintf("%s_sHijing_OO_0_15fm%s",$filenamestring, $OO_pileupstring); + } else { $filenamestring = sprintf("%s_sHijing_0_20fm%s",$filenamestring, $AuAu_pileupstring); @@ -845,6 +873,10 @@ { $filenamestring = sprintf("%s_sHijing_0_488fm%s",$filenamestring, $AuAu_pileupstring); } + elsif ($embed eq "oo") + { + $filenamestring = sprintf("%s_sHijing_OO_0_15fm%s",$filenamestring, $OO_pileupstring); + } else { $filenamestring = sprintf("%s_sHijing_0_20fm%s",$filenamestring, $AuAu_pileupstring); @@ -874,6 +906,10 @@ { $filenamestring = sprintf("%s_sHijing_0_488fm%s",$filenamestring, $AuAu_pileupstring); } + elsif ($embed eq "oo") + { + $filenamestring = sprintf("%s_sHijing_OO_0_15fm%s",$filenamestring, $OO_pileupstring); + } else { $filenamestring = sprintf("%s_sHijing_0_20fm%s",$filenamestring, $AuAu_pileupstring); @@ -903,6 +939,10 @@ { $filenamestring = sprintf("%s_sHijing_0_488fm%s",$filenamestring, $AuAu_pileupstring); } + elsif ($embed eq "oo") + { + $filenamestring = sprintf("%s_sHijing_OO_0_15fm%s",$filenamestring, $OO_pileupstring); + } else { $filenamestring = sprintf("%s_sHijing_0_20fm%s",$filenamestring, $AuAu_pileupstring); @@ -932,6 +972,10 @@ { $filenamestring = sprintf("%s_sHijing_0_488fm%s",$filenamestring, $AuAu_pileupstring); } + elsif ($embed eq "oo") + { + $filenamestring = sprintf("%s_sHijing_OO_0_15fm%s",$filenamestring, $OO_pileupstring); + } else { $filenamestring = sprintf("%s_sHijing_0_20fm%s",$filenamestring, $AuAu_pileupstring); @@ -975,6 +1019,10 @@ { $filenamestring = sprintf("%s_sHijing_0_488fm%s",$filenamestring, $AuAu_pileupstring); } + elsif ($embed eq "oo") + { + $filenamestring = sprintf("%s_sHijing_OO_0_15fm%s",$filenamestring, $OO_pileupstring); + } else { $filenamestring = sprintf("%s_sHijing_0_20fm%s",$filenamestring, $AuAu_pileupstring); @@ -1009,6 +1057,10 @@ { $filenamestring = sprintf("%s_sHijing_0_488fm%s",$filenamestring, $AuAu_pileupstring); } + elsif ($embed eq "oo") + { + $filenamestring = sprintf("%s_sHijing_OO_0_15fm%s",$filenamestring, $OO_pileupstring); + } else { $filenamestring = sprintf("%s_sHijing_0_20fm%s",$filenamestring, $AuAu_pileupstring); From 2686fe3eecafbf45ab0e6fd5400d74e0b0a215ed Mon Sep 17 00:00:00 2001 From: Hao-Ren Jheng Date: Sun, 22 Mar 2026 22:33:21 -0400 Subject: [PATCH 389/393] DecayFinder search fix --- offline/packages/decayfinder/DecayFinder.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/offline/packages/decayfinder/DecayFinder.cc b/offline/packages/decayfinder/DecayFinder.cc index 1593387592..e293b6c37e 100644 --- a/offline/packages/decayfinder/DecayFinder.cc +++ b/offline/packages/decayfinder/DecayFinder.cc @@ -361,6 +361,9 @@ bool DecayFinder::findDecay(PHCompositeNode* topNode) exit(1); } + // correct mother PID to search for match + const int mother_id_to_match = m_getChargeConjugate ? std::abs(m_mother_ID) : m_mother_ID; + if (m_truthinfo && !m_geneventmap) // This should use the truth info container if we have no HepMC record { if (Verbosity() >= VERBOSITY_SOME) @@ -374,7 +377,8 @@ bool DecayFinder::findDecay(PHCompositeNode* topNode) { PHG4Particle* g4particle = iter->second; int this_pid = m_getChargeConjugate ? abs(g4particle->get_pid()) : g4particle->get_pid(); - if (this_pid == m_mother_ID) + // if (this_pid == m_mother_ID) + if (this_pid == mother_id_to_match) { if (Verbosity() >= VERBOSITY_MAX) { @@ -455,7 +459,7 @@ bool DecayFinder::findDecay(PHCompositeNode* topNode) for (HepMC::GenEvent::particle_const_iterator p = theEvent->particles_begin(); p != theEvent->particles_end(); ++p) { int this_pid = m_getChargeConjugate ? abs((*p)->pdg_id()) : (*p)->pdg_id(); - if (this_pid == m_mother_ID) + if (this_pid == mother_id_to_match) { if (Verbosity() >= VERBOSITY_MAX) { From de78126e283bf6824684048c6259979c4e221da4 Mon Sep 17 00:00:00 2001 From: Hao-Ren Jheng Date: Sun, 22 Mar 2026 22:39:33 -0400 Subject: [PATCH 390/393] remove comment --- offline/packages/decayfinder/DecayFinder.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/offline/packages/decayfinder/DecayFinder.cc b/offline/packages/decayfinder/DecayFinder.cc index e293b6c37e..a3521df780 100644 --- a/offline/packages/decayfinder/DecayFinder.cc +++ b/offline/packages/decayfinder/DecayFinder.cc @@ -377,7 +377,6 @@ bool DecayFinder::findDecay(PHCompositeNode* topNode) { PHG4Particle* g4particle = iter->second; int this_pid = m_getChargeConjugate ? abs(g4particle->get_pid()) : g4particle->get_pid(); - // if (this_pid == m_mother_ID) if (this_pid == mother_id_to_match) { if (Verbosity() >= VERBOSITY_MAX) From e4ba985f52d1a2d05173420736a81a080d32f6c8 Mon Sep 17 00:00:00 2001 From: cdean-github Date: Mon, 23 Mar 2026 15:38:00 -0400 Subject: [PATCH 391/393] CD: Added new brnanches to HFTrackEfficiency and patched bug --- .../HFTrackEfficiency/HFTrackEfficiency.cc | 50 ++++++++++++------- .../HFTrackEfficiency/HFTrackEfficiency.h | 4 ++ 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc b/offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc index e87d8c500b..09de461fe9 100644 --- a/offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc +++ b/offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc @@ -214,6 +214,7 @@ bool HFTrackEfficiency::findTracks(PHCompositeNode *topNode, Decay decay) m_true_mother_pT = mother->momentum().perp(); m_true_mother_p = std::sqrt(std::pow(mother->momentum().px(), 2) + std::pow(mother->momentum().py(), 2) + std::pow(mother->momentum().pz(), 2)); // Must have an old HepMC build, no mag function m_true_mother_eta = mother->momentum().eta(); + m_true_mother_phi = mother->momentum().phi(); HepMC::GenVertex *thisVtx = mother->production_vertex(); m_primary_vtx_x = thisVtx->point3d().x(); @@ -229,13 +230,17 @@ bool HFTrackEfficiency::findTracks(PHCompositeNode *topNode, Decay decay) } } + int index = -1; + for (unsigned int i = 1; i < decay.size(); ++i) { m_dst_track = nullptr; int truth_ID = -1; + if (std::find(std::begin(trackableParticles), std::end(trackableParticles), std::abs(decay[i].second)) != std::end(trackableParticles)) { + ++index; if (theEvent && decay[i].first.second > -1) { HepMC::GenParticle *daughterHepMC = theEvent->barcode_to_particle(decay[i].first.second); @@ -247,7 +252,7 @@ bool HFTrackEfficiency::findTracks(PHCompositeNode *topNode, Decay decay) daughterTrueLV->setVectM(CLHEP::Hep3Vector(daughterHepMC->momentum().px(), daughterHepMC->momentum().py(), daughterHepMC->momentum().pz()), getParticleMass(decay[i].second)); daughterSumTrueLV += *daughterTrueLV; - m_true_track_PID[i - 1] = daughterHepMC->pdg_id(); + m_true_track_PID[index] = daughterHepMC->pdg_id(); // Now get the decay vertex position HepMC::GenVertex *thisVtx = daughterHepMC->production_vertex(); @@ -306,6 +311,7 @@ bool HFTrackEfficiency::findTracks(PHCompositeNode *topNode, Decay decay) m_true_mother_pT = motherTrueLV->perp(); m_true_mother_p = mother3Vector->mag(); m_true_mother_eta = motherTrueLV->pseudoRapidity(); + m_true_mother_phi = motherTrueLV->phi(); PHG4VtxPoint *thisVtx = m_truthInfo->GetVtx(motherG4->get_vtx_id()); m_primary_vtx_x = thisVtx->get_x(); @@ -321,7 +327,7 @@ bool HFTrackEfficiency::findTracks(PHCompositeNode *topNode, Decay decay) m_secondary_vtx_y = thisVtx->get_y(); m_secondary_vtx_z = thisVtx->get_z(); - m_true_track_PID[i - 1] = daughterG4->get_pid(); + m_true_track_PID[index] = daughterG4->get_pid(); truth_ID = daughterG4->get_track_id(); delete mother3Vector; @@ -329,10 +335,11 @@ bool HFTrackEfficiency::findTracks(PHCompositeNode *topNode, Decay decay) } } - m_true_track_pT[i - 1] = (float) daughterTrueLV->perp(); - m_true_track_eta[i - 1] = (float) daughterTrueLV->pseudoRapidity(); - m_min_true_track_pT = std::min(m_true_track_pT[i - 1], m_min_true_track_pT); - m_max_true_track_pT = std::max(m_true_track_pT[i - 1], m_max_true_track_pT); + m_true_track_pT[index] = (float) daughterTrueLV->perp(); + m_true_track_eta[index] = (float) daughterTrueLV->pseudoRapidity(); + m_true_track_phi[index] = (float) daughterTrueLV->phi(); + m_min_true_track_pT = std::min(m_true_track_pT[index], m_min_true_track_pT); + m_max_true_track_pT = std::max(m_true_track_pT[index], m_max_true_track_pT); if (m_dst_truth_reco_map && truth_ID >= 0) { @@ -350,7 +357,7 @@ bool HFTrackEfficiency::findTracks(PHCompositeNode *topNode, Decay decay) m_dst_track = m_input_trackMap->get(best_reco_id); if (m_dst_track) { - m_used_truth_reco_map[i - 1] = true; + m_used_truth_reco_map[index] = true; recoTrackFound = true; } } @@ -378,24 +385,25 @@ bool HFTrackEfficiency::findTracks(PHCompositeNode *topNode, Decay decay) { m_dst_track->identify(); } - m_reco_track_exists[i - 1] = true; - m_reco_track_pT[i - 1] = m_dst_track->get_pt(); - m_reco_track_eta[i - 1] = m_dst_track->get_eta(); - m_reco_track_chi2nDoF[i - 1] = m_dst_track->get_chisq() / m_dst_track->get_ndf(); + m_reco_track_exists[index] = true; + m_reco_track_pT[index] = m_dst_track->get_pt(); + m_reco_track_eta[index] = m_dst_track->get_eta(); + m_reco_track_phi[index] = m_dst_track->get_phi(); + m_reco_track_chi2nDoF[index] = m_dst_track->get_chisq() / m_dst_track->get_ndf(); if (m_dst_track->get_silicon_seed()) { - m_reco_track_silicon_seeds[i - 1] = static_cast(m_dst_track->get_silicon_seed()->size_cluster_keys()); + m_reco_track_silicon_seeds[index] = static_cast(m_dst_track->get_silicon_seed()->size_cluster_keys()); } else { - m_reco_track_silicon_seeds[i - 1] = 0; + m_reco_track_silicon_seeds[index] = 0; } - m_reco_track_tpc_seeds[i - 1] = static_cast(m_dst_track->get_tpc_seed()->size_cluster_keys()); - m_min_reco_track_pT = std::min(m_reco_track_pT[i - 1], m_min_reco_track_pT); - m_max_reco_track_pT = std::max(m_reco_track_pT[i - 1], m_max_reco_track_pT); + m_reco_track_tpc_seeds[index] = static_cast(m_dst_track->get_tpc_seed()->size_cluster_keys()); + m_min_reco_track_pT = std::min(m_reco_track_pT[index], m_min_reco_track_pT); + m_max_reco_track_pT = std::max(m_reco_track_pT[index], m_max_reco_track_pT); CLHEP::HepLorentzVector *daughterRecoLV = new CLHEP::HepLorentzVector(); - daughterRecoLV->setVectM(CLHEP::Hep3Vector(m_dst_track->get_px(), m_dst_track->get_py(), m_dst_track->get_pz()), getParticleMass(m_true_track_PID[i - 1])); + daughterRecoLV->setVectM(CLHEP::Hep3Vector(m_dst_track->get_px(), m_dst_track->get_py(), m_dst_track->get_pz()), getParticleMass(m_true_track_PID[index])); motherRecoLV += *daughterRecoLV; delete daughterRecoLV; @@ -410,6 +418,7 @@ bool HFTrackEfficiency::findTracks(PHCompositeNode *topNode, Decay decay) if (selectedTracks.size() == m_nDaughters) { m_reco_mother_mass = motherRecoLV.m(); + m_reco_mother_pT = motherRecoLV.perp(); if (m_write_track_map) { m_output_trackMap = findNode::getClass(topNode, outputNodeName); @@ -444,8 +453,10 @@ void HFTrackEfficiency::initializeBranches() m_tree->Branch("true_mother_mass", &m_true_mother_mass, "true_mother_mass/F"); m_tree->Branch("reco_mother_mass", &m_reco_mother_mass, "reco_mother_mass/F"); m_tree->Branch("true_mother_pT", &m_true_mother_pT, "true_mother_pT/F"); + m_tree->Branch("reco_mother_pT", &m_reco_mother_pT, "reco_mother_pT/F"); m_tree->Branch("true_mother_p", &m_true_mother_p, "true_mother_p/F"); m_tree->Branch("true_mother_eta", &m_true_mother_eta, "true_mother_eta/F"); + m_tree->Branch("true_mother_phi", &m_true_mother_phi, "true_mother_phi/F"); m_tree->Branch("min_true_track_pT", &m_min_true_track_pT, "min_true_track_pT/F"); m_tree->Branch("min_reco_track_pT", &m_min_reco_track_pT, "min_reco_track_pT/F"); m_tree->Branch("max_true_track_pT", &m_max_true_track_pT, "max_true_track_pT/F"); @@ -460,6 +471,8 @@ void HFTrackEfficiency::initializeBranches() m_tree->Branch("reco_" + TString(daughter_number) + "_pT", &m_reco_track_pT[iTrack], "reco_" + TString(daughter_number) + "_pT/F"); m_tree->Branch("true_" + TString(daughter_number) + "_eta", &m_true_track_eta[iTrack], "true_" + TString(daughter_number) + "_eta/F"); m_tree->Branch("reco_" + TString(daughter_number) + "_eta", &m_reco_track_eta[iTrack], "reco_" + TString(daughter_number) + "_eta/F"); + m_tree->Branch("true_" + TString(daughter_number) + "_phi", &m_true_track_phi[iTrack], "true_" + TString(daughter_number) + "_phi/F"); + m_tree->Branch("reco_" + TString(daughter_number) + "_phi", &m_reco_track_phi[iTrack], "reco_" + TString(daughter_number) + "_phi/F"); m_tree->Branch("true_" + TString(daughter_number) + "_PID", &m_true_track_PID[iTrack], "true_" + TString(daughter_number) + "_PID/F"); m_tree->Branch("reco_" + TString(daughter_number) + "_chi2nDoF", &m_reco_track_chi2nDoF[iTrack], "reco_" + TString(daughter_number) + "_chi2nDoF/F"); m_tree->Branch("reco_" + TString(daughter_number) + "_silicon_seeds", &m_reco_track_silicon_seeds[iTrack], "reco_" + TString(daughter_number) + "_silicon_seeds/I"); @@ -481,6 +494,7 @@ void HFTrackEfficiency::resetBranches() m_true_mother_mass = std::numeric_limits::quiet_NaN(); m_reco_mother_mass = std::numeric_limits::quiet_NaN(); m_true_mother_pT = std::numeric_limits::quiet_NaN(); + m_reco_mother_pT = std::numeric_limits::quiet_NaN(); m_true_mother_p = std::numeric_limits::quiet_NaN(); m_true_mother_eta = std::numeric_limits::quiet_NaN(); m_min_true_track_pT = std::numeric_limits::max(); @@ -495,6 +509,8 @@ void HFTrackEfficiency::resetBranches() m_reco_track_pT[iTrack] = std::numeric_limits::quiet_NaN(); m_true_track_eta[iTrack] = std::numeric_limits::quiet_NaN(); m_reco_track_eta[iTrack] = std::numeric_limits::quiet_NaN(); + m_true_track_phi[iTrack] = std::numeric_limits::quiet_NaN(); + m_reco_track_phi[iTrack] = std::numeric_limits::quiet_NaN(); m_true_track_PID[iTrack] = std::numeric_limits::quiet_NaN(); m_reco_track_chi2nDoF[iTrack] = std::numeric_limits::quiet_NaN(); m_reco_track_silicon_seeds[iTrack] = 0; diff --git a/offline/packages/HFTrackEfficiency/HFTrackEfficiency.h b/offline/packages/HFTrackEfficiency/HFTrackEfficiency.h index ce1ac40be3..f667c3bc27 100644 --- a/offline/packages/HFTrackEfficiency/HFTrackEfficiency.h +++ b/offline/packages/HFTrackEfficiency/HFTrackEfficiency.h @@ -93,8 +93,10 @@ class HFTrackEfficiency : public SubsysReco float m_true_mother_mass{std::numeric_limits::quiet_NaN()}; float m_reco_mother_mass{std::numeric_limits::quiet_NaN()}; float m_true_mother_pT{std::numeric_limits::quiet_NaN()}; + float m_reco_mother_pT{std::numeric_limits::quiet_NaN()}; float m_true_mother_p{std::numeric_limits::quiet_NaN()}; float m_true_mother_eta{std::numeric_limits::quiet_NaN()}; + float m_true_mother_phi{std::numeric_limits::quiet_NaN()}; float m_min_true_track_pT{std::numeric_limits::max()}; float m_min_reco_track_pT{std::numeric_limits::max()}; float m_max_true_track_pT{std::numeric_limits::min()}; // Apparently min() is still a +ve value @@ -105,6 +107,8 @@ class HFTrackEfficiency : public SubsysReco float m_reco_track_pT[m_maxTracks]{std::numeric_limits::quiet_NaN()}; float m_true_track_eta[m_maxTracks]{std::numeric_limits::quiet_NaN()}; float m_reco_track_eta[m_maxTracks]{std::numeric_limits::quiet_NaN()}; + float m_true_track_phi[m_maxTracks]{std::numeric_limits::quiet_NaN()}; + float m_reco_track_phi[m_maxTracks]{std::numeric_limits::quiet_NaN()}; float m_true_track_PID[m_maxTracks]{std::numeric_limits::quiet_NaN()}; float m_reco_track_chi2nDoF[m_maxTracks]{std::numeric_limits::quiet_NaN()}; int m_reco_track_silicon_seeds[m_maxTracks]{0}; From 02337fe77040b69946d21cf6d2275c89138a310b Mon Sep 17 00:00:00 2001 From: JAEBEOm PARK Date: Wed, 25 Mar 2026 13:21:54 -0400 Subject: [PATCH 392/393] safeguard of calling ZDC tower nodes when not using zdc info --- offline/packages/trigger/MinimumBiasClassifier.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/trigger/MinimumBiasClassifier.cc b/offline/packages/trigger/MinimumBiasClassifier.cc index db3acba38e..35a5cf9e54 100644 --- a/offline/packages/trigger/MinimumBiasClassifier.cc +++ b/offline/packages/trigger/MinimumBiasClassifier.cc @@ -277,7 +277,7 @@ int MinimumBiasClassifier::GetNodes(PHCompositeNode *topNode) return Fun4AllReturnCodes::ABORTRUN; } - if (!m_issim) + if (!m_issim && m_useZDC) { m_zdcinfo = findNode::getClass(topNode, "Zdcinfo"); if (Verbosity()) From 32f97248b704c5181d05c158a975cc168bff55f7 Mon Sep 17 00:00:00 2001 From: JAEBEOm PARK Date: Thu, 26 Mar 2026 17:13:57 -0400 Subject: [PATCH 393/393] fixed m_useZDC option --- offline/packages/trigger/MinimumBiasClassifier.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/offline/packages/trigger/MinimumBiasClassifier.cc b/offline/packages/trigger/MinimumBiasClassifier.cc index 35a5cf9e54..c36a9430e1 100644 --- a/offline/packages/trigger/MinimumBiasClassifier.cc +++ b/offline/packages/trigger/MinimumBiasClassifier.cc @@ -155,7 +155,7 @@ int MinimumBiasClassifier::FillMinimumBiasInfo() { std::cout << "Getting ZDC" << std::endl; } - if (!m_issim && !m_useZDC) + if (!m_issim && m_useZDC) { if (!m_zdcinfo) {