Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2026-07-16 08:12:43

0001 #include "sEPDTowerAnalysis.h"
0002 
0003 #include <calobase/TowerInfo.h>
0004 #include <calobase/TowerInfoContainer.h>
0005 #include <calobase/TowerInfoDefs.h>
0006 
0007 #include <fun4all/Fun4AllReturnCodes.h>
0008 #include <phool/PHCompositeNode.h>
0009 #include <phool/getClass.h>
0010 
0011 #include <TFile.h>
0012 #include <TH1F.h>
0013 #include <TH2F.h>
0014 #include <TTree.h>
0015 #include <TLine.h>
0016 #include <TProfile.h>
0017 
0018 #include <iostream>
0019 #include <cmath>
0020 
0021 sEPDTowerAnalysis::sEPDTowerAnalysis(const std::string &name)
0022   : SubsysReco(name)
0023   , m_outputFile("sEPDTowerAnalysis.root")
0024   , m_file(nullptr)
0025   , h_energy_all(nullptr)
0026   , h_energy_all_with_negative(nullptr)
0027   , h_energy_tile(nullptr)
0028   , h_energy_valid_time(nullptr)
0029   , h_energy_nan_time(nullptr)
0030   , h_time_all(nullptr)
0031   , h_chi2_all(nullptr)
0032   , h_pedestal_all(nullptr)
0033   , h_energy_vs_time(nullptr)
0034   , h_energy_vs_chi2(nullptr)
0035   , h_energy_vs_chi2_profile(nullptr)
0036   , h_chi2_vs_energy(nullptr)
0037   , h_chi2_vs_energy_profile(nullptr)
0038   , h_energy_fast(nullptr)
0039   , h_time_fast(nullptr)
0040   , h_chi2_fast(nullptr)
0041   , h_pedestal_fast(nullptr)
0042   , h_energy_vs_chi2_fast(nullptr)
0043   , h_energy_template_vs_fast(nullptr)
0044   , h_energy_template_vs_fast_time_cut1(nullptr)
0045   , h_energy_template_vs_fast_time_cut2(nullptr)
0046   , h_energy_template_vs_fast_fast_time_cut1(nullptr)
0047   , h_energy_template_vs_fast_fast_time_cut2(nullptr)
0048   , h_time_template(nullptr)
0049   , h_time_fast_separate(nullptr)
0050   , h_pedestal_template_vs_fast(nullptr)
0051   , h_time_template_vs_fast(nullptr)
0052   , h_event_summary(nullptr)
0053   , h_energy_categories(nullptr)
0054   , m_tree(nullptr)
0055   , m_event(0)
0056   , m_channel(0)
0057   , m_idx(0)
0058   , m_energy(0)
0059   , m_time(0)
0060   , m_chi2(0)
0061   , m_pedestal(0)
0062   , m_valid_time(false)
0063   , m_energy_fast(0)
0064   , m_time_fast(0)
0065   , m_chi2_fast(0)
0066   , m_pedestal_fast(0)
0067   , m_valid_time_fast(false)
0068   , m_total_channels(0)
0069   , m_channels_with_signal(0)
0070   , m_channels_valid_time(0)
0071   , m_channels_nan_time(0)
0072   , m_channels_zero_suppressed(0)
0073 {
0074 }
0075 
0076 sEPDTowerAnalysis::~sEPDTowerAnalysis()
0077 {
0078   if (m_file)
0079   {
0080     m_file->Close();
0081     delete m_file;
0082   }
0083 }
0084 
0085 int sEPDTowerAnalysis::Init(PHCompositeNode *topNode)
0086 {
0087   m_file = TFile::Open(m_outputFile.c_str(), "RECREATE");
0088 
0089   h_energy_all = new TH1F("h_energy_template", "TEMPLATE Tower Energies (>20 ADC);Energy [ADC];Entries", 480, 20, 500);
0090   h_energy_all_with_negative = new TH1F("h_energy_template_with_negative", "TEMPLATE Tower Energies (incl. negative);Energy [ADC];Entries", 600, -100, 500);
0091   h_energy_valid_time = new TH1F("h_energy_template_valid_time", "TEMPLATE Tower Energies (Valid Time);Energy [ADC];Entries", 500, 0, 500);
0092   h_energy_nan_time = new TH1F("h_energy_template_nan_time", "TEMPLATE Tower Energies (NaN Time);Energy [ADC];Entries", 500, 0, 500);
0093   h_energy_tile = new TH1F("h_energy_template_tile", "TEMPLATE Tile 23;ADC;Entries", 500, 0, 500);
0094   h_time_all = new TH1F("h_time_template", "TEMPLATE Tower Times;Time [samples];Entries", 200, -10, 20);
0095   h_chi2_all = new TH1F("h_chi2_template", "TEMPLATE Tower Chi2;Chi2;Entries", 200, 0, 10000);
0096   h_pedestal_all = new TH1F("h_pedestal_template", "TEMPLATE Tower Pedestals (WARNING: All NaN);Pedestal [ADC];Entries", 500, 0, 5000);
0097   h_energy_vs_time = new TH2F("h_energy_vs_time_template", "TEMPLATE Energy vs Time;Time [samples];Energy [ADC]", 100, -5, 15, 200, 0, 500);
0098   h_energy_vs_chi2 = new TH2F("h_energy_vs_chi2_template", "TEMPLATE Energy vs Chi2;Chi2;Energy [ADC]", 100, 0, 1000, 200, 0, 500);
0099   h_energy_vs_chi2_profile = new TProfile("h_energy_vs_chi2_profile_template", "TEMPLATE Average Energy vs Chi2;Chi2;Average Energy [ADC]", 100, 0, 1000, 0, 500);
0100   h_chi2_vs_energy = new TH2F("h_chi2_vs_energy_template", "TEMPLATE Chi2 vs Energy;Energy [ADC];Chi2", 200, 0, 500, 100, 0, 1000);
0101   h_chi2_vs_energy_profile = new TProfile("h_chi2_vs_energy_profile_template", "TEMPLATE Average Chi2 vs Energy;Energy [ADC];Average Chi2", 200, 0, 500, 0, 1000);
0102 
0103   h_energy_fast = new TH1F("h_energy_fast", "FAST Tower Energies (>20 ADC);Energy [ADC];Entries", 480, 20, 500);
0104   h_time_fast = new TH1F("h_time_fast", "FAST Tower Times;Time [samples];Entries", 200, -10, 20);
0105   h_chi2_fast = new TH1F("h_chi2_fast", "FAST Tower Chi2;Chi2;Entries", 200, 0, 10000);
0106   h_pedestal_fast = new TH1F("h_pedestal_fast", "FAST Tower Pedestals (WARNING: All NaN);Pedestal [ADC];Entries", 500, 0, 5000);
0107   h_energy_vs_chi2_fast = new TH2F("h_energy_vs_chi2_fast", "FAST Energy vs Chi2;Chi2;Energy [ADC]", 100, 0, 1000, 200, 0, 500);
0108 
0109   h_energy_template_vs_fast = new TH2F("h_energy_template_vs_fast", "Energy Correlation: TEMPLATE vs FAST;FAST Energy [ADC];TEMPLATE Energy [ADC]", 200, 0, 500, 200, 0, 500);
0110   h_energy_template_vs_fast_time_cut1 = new TH2F("h_energy_template_vs_fast_time_cut1", "Energy Correlation (-1 < template_time < 0): TEMPLATE vs FAST;FAST Energy [ADC];TEMPLATE Energy [ADC]", 200, 0, 500, 200, 0, 500);
0111   h_energy_template_vs_fast_time_cut2 = new TH2F("h_energy_template_vs_fast_time_cut2", "Energy Correlation (-2 < template_time < -1): TEMPLATE vs FAST;FAST Energy [ADC];TEMPLATE Energy [ADC]", 200, 0, 500, 200, 0, 500);
0112   h_energy_template_vs_fast_fast_time_cut1 = new TH2F("h_energy_template_vs_fast_fast_time_cut1", "Energy Correlation (-1 < fast_time < 0): TEMPLATE vs FAST;FAST Energy [ADC];TEMPLATE Energy [ADC]", 200, 0, 500, 200, 0, 500);
0113   h_energy_template_vs_fast_fast_time_cut2 = new TH2F("h_energy_template_vs_fast_fast_time_cut2", "Energy Correlation (-2 < fast_time < -1): TEMPLATE vs FAST;FAST Energy [ADC];TEMPLATE Energy [ADC]", 200, 0, 500, 200, 0, 500);
0114   h_time_template = new TH1F("h_time_template_comparison", "TEMPLATE Times (for comparison);Time [samples];Entries", 200, -10, 20);
0115   h_time_fast_separate = new TH1F("h_time_fast_comparison", "FAST Times (for comparison);Time [samples];Entries", 200, -10, 20);
0116   h_pedestal_template_vs_fast = new TH2F("h_pedestal_template_vs_fast", "Pedestal Correlation (WARNING: All NaN);FAST Pedestal [ADC];TEMPLATE Pedestal [ADC]", 250, 0, 5000, 250, 0, 5000);
0117   h_time_template_vs_fast = new TH2F("h_time_template_vs_fast", "Time Correlation: TEMPLATE vs FAST;FAST Time [samples];TEMPLATE Time [samples]", 100, -10, 20, 100, -10, 20);
0118 
0119   h_event_summary = new TH1F("h_event_summary", "Event Summary;Category;Count per Event", 6, 0, 6);
0120   h_event_summary->GetXaxis()->SetBinLabel(1, "Total Channels");
0121   h_event_summary->GetXaxis()->SetBinLabel(2, "Energy > 1 ADC");
0122   h_event_summary->GetXaxis()->SetBinLabel(3, "Energy > 5 ADC");
0123   h_event_summary->GetXaxis()->SetBinLabel(4, "Valid Time");
0124   h_event_summary->GetXaxis()->SetBinLabel(5, "NaN Time");
0125   h_event_summary->GetXaxis()->SetBinLabel(6, "Zero Suppressed");
0126 
0127   h_energy_categories = new TH1F("h_energy_categories", "Energy Categories;Energy Range;Channels", 11, 0, 11);
0128   h_energy_categories->GetXaxis()->SetBinLabel(1, "< 0");
0129   h_energy_categories->GetXaxis()->SetBinLabel(2, "0-0.5");
0130   h_energy_categories->GetXaxis()->SetBinLabel(3, "0.5-1");
0131   h_energy_categories->GetXaxis()->SetBinLabel(4, "1-2");
0132   h_energy_categories->GetXaxis()->SetBinLabel(5, "2-5");
0133   h_energy_categories->GetXaxis()->SetBinLabel(6, "5-10");
0134   h_energy_categories->GetXaxis()->SetBinLabel(7, "10-20");
0135   h_energy_categories->GetXaxis()->SetBinLabel(8, "20-50");
0136   h_energy_categories->GetXaxis()->SetBinLabel(9, "50-100");
0137   h_energy_categories->GetXaxis()->SetBinLabel(10, "100-200");
0138   h_energy_categories->GetXaxis()->SetBinLabel(11, "> 200");
0139 
0140   m_tree = new TTree("tower_tree", "sEPD Tower Data");
0141   m_tree->Branch("event", &m_event, "event/I");
0142   m_tree->Branch("channel", &m_channel, "channel/I");
0143   m_tree->Branch("idx", &m_idx, "idx/I");
0144 
0145   m_tree->Branch("energy_template", &m_energy, "energy_template/F");
0146   m_tree->Branch("time_template", &m_time, "time_template/F");
0147   m_tree->Branch("chi2_template", &m_chi2, "chi2_template/F");
0148   m_tree->Branch("pedestal_template", &m_pedestal, "pedestal_template/F");
0149   m_tree->Branch("valid_time_template", &m_valid_time, "valid_time_template/O");
0150 
0151   m_tree->Branch("energy_fast", &m_energy_fast, "energy_fast/F");
0152   m_tree->Branch("time_fast", &m_time_fast, "time_fast/F");
0153   m_tree->Branch("chi2_fast", &m_chi2_fast, "chi2_fast/F");
0154   m_tree->Branch("pedestal_fast", &m_pedestal_fast, "pedestal_fast/F");
0155   m_tree->Branch("valid_time_fast", &m_valid_time_fast, "valid_time_fast/O");
0156 
0157   std::cout << "sEPDTowerAnalysis initialized - output file: " << m_outputFile << std::endl;
0158 
0159   return Fun4AllReturnCodes::EVENT_OK;
0160 }
0161 
0162 int sEPDTowerAnalysis::InitRun(PHCompositeNode *topNode)
0163 {
0164   return Fun4AllReturnCodes::EVENT_OK;
0165 }
0166 
0167 int sEPDTowerAnalysis::process_event(PHCompositeNode *topNode)
0168 {
0169   m_event++;
0170 
0171   std::string template_container = "TOWERS_SEPD";
0172   std::string fast_container = "TOWERS_FAST_SEPD";
0173 
0174   TowerInfoContainer *towers_template = findNode::getClass<TowerInfoContainer>(topNode, template_container);
0175   TowerInfoContainer *towers_fast = findNode::getClass<TowerInfoContainer>(topNode, fast_container);
0176 
0177   if (!towers_template) {
0178     std::cout << "No TEMPLATE towers found (" << template_container << ")!" << std::endl;
0179     return Fun4AllReturnCodes::EVENT_OK;
0180   }
0181 
0182   if (!towers_fast) {
0183     std::cout << "No FAST towers found (" << fast_container << ")!" << std::endl;
0184     return Fun4AllReturnCodes::EVENT_OK;
0185   }
0186 
0187   if (m_event <= 5 || m_event % 1000 == 0) {
0188     std::cout << "Event " << m_event << ": TEMPLATE container " << template_container << " has " << towers_template->size() << " towers" << std::endl;
0189     std::cout << "Event " << m_event << ": FAST container " << fast_container << " has " << towers_fast->size() << " towers" << std::endl;
0190   }
0191 
0192   int event_total = 0;
0193   int event_signal_10 = 0;
0194   int event_signal_50 = 0;
0195   int event_valid_time = 0;
0196   int event_nan_time = 0;
0197   int event_zero_suppressed = 0;
0198   int pedestal_template_count = 0;
0199   int pedestal_fast_count = 0;
0200 
0201   unsigned int ntowers_template = towers_template->size();
0202   unsigned int ntowers_fast = towers_fast->size();
0203 
0204   if (ntowers_template != ntowers_fast) {
0205     std::cout << "WARNING: Container size mismatch! TEMPLATE=" << ntowers_template << ", FAST=" << ntowers_fast << std::endl;
0206     return Fun4AllReturnCodes::EVENT_OK;
0207   }
0208 
0209   for (unsigned int i = 0; i < ntowers_template; i++)
0210   {
0211     TowerInfo *tower_template = towers_template->get_tower_at_channel(i);
0212     TowerInfo *tower_fast = towers_fast->get_tower_at_channel(i);
0213 
0214     if (!tower_template || !tower_fast) continue;
0215 
0216     float energy_template = tower_template->get_energy();
0217     float time_template = tower_template->get_time();
0218     float chi2_template = tower_template->get_chi2();
0219     float pedestal_template = tower_template->get_pedestal();
0220     bool valid_time_template = !std::isnan(time_template);
0221 
0222     float energy_fast = tower_fast->get_energy();
0223     float time_fast = tower_fast->get_time();
0224     float chi2_fast = tower_fast->get_chi2();
0225     float pedestal_fast = tower_fast->get_pedestal();
0226     bool valid_time_fast = !std::isnan(time_fast);
0227 
0228     m_channel = i;
0229     m_idx = i;
0230     m_energy = energy_template;
0231     m_time = time_template;
0232     m_chi2 = chi2_template;
0233     m_pedestal = pedestal_template;
0234     m_valid_time = valid_time_template;
0235     m_energy_fast = energy_fast;
0236     m_time_fast = time_fast;
0237     m_chi2_fast = chi2_fast;
0238     m_pedestal_fast = pedestal_fast;
0239     m_valid_time_fast = valid_time_fast;
0240     m_tree->Fill();
0241 
0242     if (i == 23) {
0243       h_energy_tile->Fill(energy_template);
0244     }
0245 
0246     if (energy_template > 20) {
0247       h_energy_all->Fill(energy_template);
0248     }
0249 
0250     h_energy_all_with_negative->Fill(energy_template);
0251 
0252     if (valid_time_template)
0253     {
0254       h_energy_valid_time->Fill(energy_template);
0255       h_time_all->Fill(time_template);
0256       h_energy_vs_time->Fill(time_template, energy_template);
0257       h_time_template->Fill(time_template);
0258     }
0259     else
0260     {
0261       h_energy_nan_time->Fill(energy_template);
0262     }
0263 
0264     if (!std::isnan(chi2_template))
0265     {
0266       h_chi2_all->Fill(chi2_template);
0267       h_energy_vs_chi2->Fill(chi2_template, energy_template);
0268       h_energy_vs_chi2_profile->Fill(chi2_template, energy_template);
0269       h_chi2_vs_energy->Fill(energy_template, chi2_template);
0270       h_chi2_vs_energy_profile->Fill(energy_template, chi2_template);
0271     }
0272 
0273     if (m_event <= 5) {
0274 
0275       if (i < 5 || i == 100 || i == 200 || i == 400 || i == 700) {
0276         std::cout << "Event " << m_event << " Ch " << i << ": pedestal_template=" << pedestal_template
0277                   << ", pedestal_fast=" << pedestal_fast
0278                   << ", energy_template=" << energy_template
0279                   << ", energy_fast=" << energy_fast << std::endl;
0280       }
0281     }
0282 
0283     if (!std::isnan(pedestal_template))
0284     {
0285       h_pedestal_all->Fill(pedestal_template);
0286       pedestal_template_count++;
0287     }
0288 
0289     if (energy_fast > 20) {
0290       h_energy_fast->Fill(energy_fast);
0291     }
0292 
0293     if (valid_time_fast) {
0294       h_time_fast->Fill(time_fast);
0295       h_time_fast_separate->Fill(time_fast);
0296     }
0297 
0298     if (!std::isnan(chi2_fast)) {
0299       h_chi2_fast->Fill(chi2_fast);
0300       h_energy_vs_chi2_fast->Fill(chi2_fast, energy_fast);
0301     }
0302 
0303     if (!std::isnan(pedestal_fast)) {
0304       h_pedestal_fast->Fill(pedestal_fast);
0305       pedestal_fast_count++;
0306     }
0307 
0308     h_energy_template_vs_fast->Fill(energy_fast, energy_template);
0309 
0310     if (valid_time_template && valid_time_fast) {
0311 
0312       if (time_template > -1.0 && time_template < 0.0) {
0313         h_energy_template_vs_fast_time_cut1->Fill(energy_fast, energy_template);
0314       }
0315       if (time_template > -2.0 && time_template < -1.0) {
0316         h_energy_template_vs_fast_time_cut2->Fill(energy_fast, energy_template);
0317       }
0318 
0319       if (time_fast > -1.0 && time_fast < 0.0) {
0320         h_energy_template_vs_fast_fast_time_cut1->Fill(energy_fast, energy_template);
0321       }
0322       if (time_fast > -2.0 && time_fast < -1.0) {
0323         h_energy_template_vs_fast_fast_time_cut2->Fill(energy_fast, energy_template);
0324       }
0325 
0326       h_time_template_vs_fast->Fill(time_fast, time_template);
0327     }
0328 
0329     if (!std::isnan(pedestal_template) && !std::isnan(pedestal_fast)) {
0330       h_pedestal_template_vs_fast->Fill(pedestal_fast, pedestal_template);
0331     }
0332 
0333     if (energy_template < 0) h_energy_categories->Fill(0.0);
0334     else if (energy_template < 0.5) h_energy_categories->Fill(1.0);
0335     else if (energy_template < 1) h_energy_categories->Fill(2.0);
0336     else if (energy_template < 2) h_energy_categories->Fill(3.0);
0337     else if (energy_template < 5) h_energy_categories->Fill(4.0);
0338     else if (energy_template < 10) h_energy_categories->Fill(5.0);
0339     else if (energy_template < 20) h_energy_categories->Fill(6.0);
0340     else if (energy_template < 50) h_energy_categories->Fill(7.0);
0341     else if (energy_template < 100) h_energy_categories->Fill(8.0);
0342     else if (energy_template < 200) h_energy_categories->Fill(9.0);
0343     else h_energy_categories->Fill(10.0);
0344 
0345     event_total++;
0346     if (energy_template > 1) event_signal_10++;
0347     if (energy_template > 5) event_signal_50++;
0348     if (valid_time_template) event_valid_time++;
0349     else event_nan_time++;
0350     if (!valid_time_template && energy_template < 1) event_zero_suppressed++;
0351 
0352     m_total_channels++;
0353     if (energy_template > 1) m_channels_with_signal++;
0354     if (valid_time_template) m_channels_valid_time++;
0355     else m_channels_nan_time++;
0356     if (!valid_time_template && energy_template < 1) m_channels_zero_suppressed++;
0357   }
0358 
0359   h_event_summary->Fill(0.0, (double)event_total);
0360   h_event_summary->Fill(1.0, (double)event_signal_10);
0361   h_event_summary->Fill(2.0, (double)event_signal_50);
0362   h_event_summary->Fill(3.0, (double)event_valid_time);
0363   h_event_summary->Fill(4.0, (double)event_nan_time);
0364   h_event_summary->Fill(5.0, (double)event_zero_suppressed);
0365 
0366   if (m_event % 100 == 0)
0367   {
0368     std::cout << "Event " << m_event << " summary:" << std::endl;
0369     std::cout << "  Total channels: " << event_total << std::endl;
0370     std::cout << "  Energy > 1 ADC: " << event_signal_10 << " (" << 100.0*event_signal_10/event_total << "%)" << std::endl;
0371     std::cout << "  Energy > 5 ADC: " << event_signal_50 << " (" << 100.0*event_signal_50/event_total << "%)" << std::endl;
0372     std::cout << "  Valid time: " << event_valid_time << " (" << 100.0*event_valid_time/event_total << "%)" << std::endl;
0373     std::cout << "  NaN time: " << event_nan_time << " (" << 100.0*event_nan_time/event_total << "%)" << std::endl;
0374     std::cout << "  Zero suppressed: " << event_zero_suppressed << " (" << 100.0*event_zero_suppressed/event_total << "%)" << std::endl;
0375     std::cout << "  TEMPLATE pedestals filled: " << pedestal_template_count << " (" << 100.0*pedestal_template_count/event_total << "%)" << std::endl;
0376     std::cout << "  FAST pedestals filled: " << pedestal_fast_count << " (" << 100.0*pedestal_fast_count/event_total << "%)" << std::endl;
0377   }
0378 
0379   return Fun4AllReturnCodes::EVENT_OK;
0380 }
0381 
0382 int sEPDTowerAnalysis::End(PHCompositeNode *topNode)
0383 {
0384   std::cout << "\nTOTAL EVENTS PROCESSED: " << m_event << " events" << std::endl;
0385   std::cout << "  Total channels processed: " << m_total_channels << std::endl;
0386   std::cout << "  Channels with signal (>1 ADC): " << m_channels_with_signal << " (" << 100.0*m_channels_with_signal/m_total_channels << "%)" << std::endl;
0387   std::cout << "  Channels with valid time: " << m_channels_valid_time << " (" << 100.0*m_channels_valid_time/m_total_channels << "%)" << std::endl;
0388   std::cout << "  Channels with NaN time: " << m_channels_nan_time << " (" << 100.0*m_channels_nan_time/m_total_channels << "%)" << std::endl;
0389   std::cout << "  Zero suppressed channels: " << m_channels_zero_suppressed << " (" << 100.0*m_channels_zero_suppressed/m_total_channels << "%)" << std::endl;
0390 
0391   std::cout << "\n  TEMPLATE method: " << h_pedestal_all->GetEntries() << " valid pedestals found" << std::endl;
0392   std::cout << "  FAST method: " << h_pedestal_fast->GetEntries() << " valid pedestals found" << std::endl;
0393 
0394   if (h_pedestal_all->GetEntries() == 0 && h_pedestal_fast->GetEntries() == 0) {
0395     std::cout << "\n  WARNING: No valid pedestal values found in either method!" << std::endl;
0396   }
0397 
0398   if (m_file)
0399   {
0400     m_file->cd();
0401 
0402     h_energy_all->Write();
0403     h_energy_all_with_negative->Write();
0404     h_energy_tile->Write();
0405     h_energy_valid_time->Write();
0406     h_energy_nan_time->Write();
0407     h_time_all->Write();
0408     h_chi2_all->Write();
0409     h_pedestal_all->Write();
0410     h_energy_vs_time->Write();
0411 
0412     h_energy_vs_chi2->Write();
0413     h_energy_vs_chi2_profile->SetLineColor(kRed);
0414     h_energy_vs_chi2_profile->SetLineWidth(2);
0415     h_energy_vs_chi2_profile->Write();
0416 
0417     h_chi2_vs_energy->Write();
0418     h_chi2_vs_energy_profile->SetLineColor(kRed);
0419     h_chi2_vs_energy_profile->SetLineWidth(2);
0420     h_chi2_vs_energy_profile->Write();
0421 
0422     h_energy_fast->Write();
0423     h_time_fast->Write();
0424     h_chi2_fast->Write();
0425     h_pedestal_fast->Write();
0426     h_energy_vs_chi2_fast->Write();
0427 
0428     TLine *diagonal_line = new TLine(0, 0, 500, 500);
0429     diagonal_line->SetLineColor(kRed);
0430     diagonal_line->SetLineWidth(2);
0431     diagonal_line->SetLineStyle(2);
0432     h_energy_template_vs_fast->GetListOfFunctions()->Add(diagonal_line);
0433     h_energy_template_vs_fast->Write();
0434 
0435     TLine *diagonal_line_cut1 = new TLine(0, 0, 500, 500);
0436     diagonal_line_cut1->SetLineColor(kRed);
0437     diagonal_line_cut1->SetLineWidth(2);
0438     diagonal_line_cut1->SetLineStyle(2);
0439     h_energy_template_vs_fast_time_cut1->GetListOfFunctions()->Add(diagonal_line_cut1);
0440     h_energy_template_vs_fast_time_cut1->Write();
0441 
0442     TLine *diagonal_line_cut2 = new TLine(0, 0, 500, 500);
0443     diagonal_line_cut2->SetLineColor(kRed);
0444     diagonal_line_cut2->SetLineWidth(2);
0445     diagonal_line_cut2->SetLineStyle(2);
0446     h_energy_template_vs_fast_time_cut2->GetListOfFunctions()->Add(diagonal_line_cut2);
0447     h_energy_template_vs_fast_time_cut2->Write();
0448 
0449     TLine *diagonal_line_fast_cut1 = new TLine(0, 0, 500, 500);
0450     diagonal_line_fast_cut1->SetLineColor(kRed);
0451     diagonal_line_fast_cut1->SetLineWidth(2);
0452     diagonal_line_fast_cut1->SetLineStyle(2);
0453     h_energy_template_vs_fast_fast_time_cut1->GetListOfFunctions()->Add(diagonal_line_fast_cut1);
0454     h_energy_template_vs_fast_fast_time_cut1->Write();
0455 
0456     TLine *diagonal_line_fast_cut2 = new TLine(0, 0, 500, 500);
0457     diagonal_line_fast_cut2->SetLineColor(kRed);
0458     diagonal_line_fast_cut2->SetLineWidth(2);
0459     diagonal_line_fast_cut2->SetLineStyle(2);
0460     h_energy_template_vs_fast_fast_time_cut2->GetListOfFunctions()->Add(diagonal_line_fast_cut2);
0461     h_energy_template_vs_fast_fast_time_cut2->Write();
0462 
0463     h_time_template->Write();
0464     h_time_fast_separate->Write();
0465     h_pedestal_template_vs_fast->Write();
0466     h_time_template_vs_fast->Write();
0467 
0468     h_event_summary->Write();
0469     h_energy_categories->Write();
0470 
0471     m_tree->Write();
0472 
0473     m_file->Close();
0474     std::cout << "\nOutput written to: " << m_outputFile << std::endl;
0475   }
0476 
0477   return Fun4AllReturnCodes::EVENT_OK;
0478 }