File indexing completed on 2025-12-19 09:18:41
0001 #include "HCalCosmics.h"
0002
0003 #include <calobase/TowerInfo.h>
0004 #include <calobase/TowerInfoContainer.h>
0005
0006 #include <fun4all/Fun4AllReturnCodes.h>
0007 #include <fun4all/SubsysReco.h>
0008
0009 #include <phool/getClass.h>
0010
0011 #include <Math/SpecFuncMathCore.h>
0012 #include <TF1.h>
0013 #include <TFile.h>
0014 #include <TH1.h>
0015 #include <TH2.h>
0016
0017 #include <algorithm>
0018 #include <cmath>
0019 #include <iostream>
0020
0021 HCalCosmics::HCalCosmics(const std::string &name, const std::string &fname)
0022 : SubsysReco(name)
0023 , outfilename(fname)
0024 {
0025 }
0026
0027 int HCalCosmics::Init(PHCompositeNode * )
0028 {
0029 std::cout << std::endl
0030 << "HCalCosmics::Init" << std::endl;
0031 std::cout << "Node with raw ADC: " << rawprefix + rawdetector << std::endl;
0032 std::cout << "Node with calibrated Energy in eV: " << prefix + detector << std::endl;
0033 std::cout << "Threshold: " << tower_threshold << " " << vert_threshold << " " << veto_threshold << std::endl;
0034 std::cout << "Bin width: " << bin_width << std::endl;
0035
0036 outfile = new TFile(outfilename.c_str(), "RECREATE");
0037
0038 for (int ieta = 0; ieta < n_etabin; ++ieta)
0039 {
0040 for (int iphi = 0; iphi < n_phibin; ++iphi)
0041 {
0042 std::string channel_histname = "h_channel_" + std::to_string(ieta) + "_" + std::to_string(iphi);
0043 h_channel_hist[ieta][iphi] = new TH1F(channel_histname.c_str(), "", 500, 0, 500 * bin_width);
0044
0045 std::string adc_histname = "h_adc_" + std::to_string(ieta) + "_" + std::to_string(iphi);
0046 h_adc_hist[ieta][iphi] = new TH1F(adc_histname.c_str(), "", 500, 0, 16000 * rawbin_width);
0047
0048 std::string adc_ecut_histname = "h_adc_ecut_" + std::to_string(ieta) + "_" + std::to_string(iphi);
0049 h_adc_ecut_hist[ieta][iphi] = new TH1F(adc_ecut_histname.c_str(), "", 500, 0, 16000 * rawbin_width);
0050
0051 std::string time_histname = "h_towertime_" + std::to_string(ieta) + "_" + std::to_string(iphi);
0052 h_towertime_hist[ieta][iphi] = new TH1F(time_histname.c_str(), "", 100, -10, 10);
0053
0054 std::string calibfactor_histname = "h_gain_" + std::to_string(ieta) + "_" + std::to_string(iphi);
0055 h_gain_hist[ieta][iphi] = new TH1F(calibfactor_histname.c_str(), "", 500, 0, 1000);
0056 }
0057 }
0058 h_waveformchi2 = new TH2F("h_waveformchi2", "", 1000, 0, 500 * bin_width, 1000, 0, 1000000);
0059 h_waveformchi2->GetXaxis()->SetTitle("peak (ADC)");
0060 h_waveformchi2->GetYaxis()->SetTitle("chi2");
0061 h_waveformchi2_aftercut = new TH2F("h_waveformchi2_aftercut", "", 1000, 0, 500 * bin_width, 1000, 0, 1000000);
0062 h_waveformchi2_aftercut->GetXaxis()->SetTitle("peak (ADC)");
0063 h_waveformchi2_aftercut->GetYaxis()->SetTitle("chi2");
0064 h_mip = new TH1F("h_mip", "", 500, 0, 500 * bin_width);
0065 h_adc = new TH1F("h_adc", "", 500, 0, 16000 * rawbin_width);
0066 h_adc_ecut = new TH1F("h_adc_ecut", "", 500, 0, 16000 * rawbin_width);
0067 h_gain = new TH1F("h_gain", "", 500, -500, 1000);
0068 h_event = new TH1F("h_event", "", 1, 0, 1);
0069
0070 h_time_energy = new TH2F("h_time_energy", "", 100, -10, 10, 100, -10 * bin_width, 90 * bin_width);
0071
0072 event = 0;
0073 return 0;
0074 }
0075
0076 int HCalCosmics::process_event(PHCompositeNode *topNode)
0077 {
0078 process_towers(topNode);
0079 event++;
0080 h_event->Fill(0);
0081
0082 return Fun4AllReturnCodes::EVENT_OK;
0083 }
0084
0085 int HCalCosmics::process_towers(PHCompositeNode *topNode)
0086 {
0087
0088
0089 std::string rawnode_name = rawprefix + rawdetector;
0090
0091 TowerInfoContainer *rawtowers = findNode::getClass<TowerInfoContainer>(topNode, rawnode_name);
0092 if (!rawtowers)
0093 {
0094 std::cout << std::endl
0095 << "Didn't find node " << rawnode_name << std::endl;
0096 return Fun4AllReturnCodes::EVENT_OK;
0097 }
0098
0099
0100
0101 std::string calibnode_name = prefix + detector;
0102
0103 TowerInfoContainer *towers = findNode::getClass<TowerInfoContainer>(topNode, calibnode_name);
0104 if (!towers)
0105 {
0106 std::cout << std::endl
0107 << "Didn't find node " << calibnode_name << std::endl;
0108 return Fun4AllReturnCodes::EVENT_OK;
0109 }
0110
0111 int size = towers->size();
0112
0113 for (int channel = 0; channel < size; channel++)
0114 {
0115 TowerInfo *tower = towers->get_tower_at_channel(channel);
0116 TowerInfo *rawtower = rawtowers->get_tower_at_channel(channel);
0117 float adc = rawtower->get_energy();
0118 float energy = tower->get_energy();
0119 float chi2 = tower->get_chi2();
0120 float time = tower->get_time();
0121 unsigned int towerkey = towers->encode_key(channel);
0122 int ieta = towers->getTowerEtaBin(towerkey);
0123 int iphi = towers->getTowerPhiBin(towerkey);
0124 m_peak[ieta][iphi] = energy;
0125 m_adc[ieta][iphi] = adc;
0126 m_chi2[ieta][iphi] = chi2;
0127 m_time[ieta][iphi] = time;
0128 h_waveformchi2->Fill(m_peak[ieta][iphi], m_chi2[ieta][iphi]);
0129 if (tower->get_isBadChi2())
0130 {
0131 m_peak[ieta][iphi] = 0;
0132 }
0133 h_waveformchi2_aftercut->Fill(m_peak[ieta][iphi], m_chi2[ieta][iphi]);
0134 h_time_energy->Fill(time, energy);
0135 }
0136
0137 for (int ieta = 0; ieta < n_etabin; ++ieta)
0138 {
0139 for (int iphi = 0; iphi < n_phibin; ++iphi)
0140 {
0141 if (m_peak[ieta][iphi] < tower_threshold)
0142 {
0143 continue;
0144 }
0145 int up = iphi + 1;
0146 int down = iphi - 1;
0147 if (up > 63)
0148 {
0149 up -= 64;
0150 }
0151 if (down < 0)
0152 {
0153 down += 64;
0154 }
0155 if (m_peak[ieta][up] < vert_threshold || m_peak[ieta][down] < vert_threshold)
0156 {
0157 continue;
0158 }
0159 if (ieta != 0 && (m_peak[ieta - 1][up] > veto_threshold ||
0160 m_peak[ieta - 1][iphi] > veto_threshold ||
0161 m_peak[ieta - 1][down] > veto_threshold))
0162 {
0163 continue;
0164 }
0165 if (ieta != 23 && (m_peak[ieta + 1][up] > veto_threshold ||
0166 m_peak[ieta + 1][iphi] > veto_threshold ||
0167 m_peak[ieta + 1][down] > veto_threshold))
0168 {
0169 continue;
0170 }
0171
0172 h_channel_hist[ieta][iphi]->Fill(m_peak[ieta][iphi]);
0173 h_towertime_hist[ieta][iphi]->Fill(m_time[ieta][iphi]);
0174 h_mip->Fill(m_peak[ieta][iphi]);
0175 h_adc_ecut_hist[ieta][iphi]->Fill(m_adc[ieta][iphi]);
0176 h_adc_ecut->Fill(m_adc[ieta][iphi]);
0177
0178 if (m_peak[ieta][iphi] != 0)
0179 {
0180 double gain_fac = m_adc[ieta][iphi] / m_peak[ieta][iphi];
0181 h_gain_hist[ieta][iphi]->Fill(gain_fac);
0182 h_gain->Fill(gain_fac);
0183 }
0184 }
0185 }
0186
0187 for (int ieta = 0; ieta < n_etabin; ++ieta)
0188 {
0189 for (int iphi = 0; iphi < n_phibin; ++iphi)
0190 {
0191 if (m_adc[ieta][iphi] < adc_tower_threshold)
0192 {
0193 continue;
0194 }
0195 int up = iphi + 1;
0196 int down = iphi - 1;
0197 if (up > 63)
0198 {
0199 up -= 64;
0200 }
0201 if (down < 0)
0202 {
0203 down += 64;
0204 }
0205
0206 if (m_adc[ieta][up] < adc_vert_threshold || m_adc[ieta][down] < adc_vert_threshold)
0207 {
0208 continue;
0209 }
0210 if (ieta != 0 && (m_adc[ieta - 1][up] > adc_veto_threshold ||
0211 m_adc[ieta - 1][iphi] > adc_veto_threshold ||
0212 m_adc[ieta - 1][down] > adc_veto_threshold))
0213 {
0214 continue;
0215 }
0216 if (ieta != 23 && (m_adc[ieta + 1][up] > adc_veto_threshold ||
0217 m_adc[ieta + 1][iphi] > adc_veto_threshold ||
0218 m_adc[ieta + 1][down] > adc_veto_threshold))
0219 {
0220 continue;
0221 }
0222 h_adc_hist[ieta][iphi]->Fill(m_adc[ieta][iphi]);
0223 h_adc->Fill(m_adc[ieta][iphi]);
0224 }
0225 }
0226
0227 return Fun4AllReturnCodes::EVENT_OK;
0228 }
0229
0230 int HCalCosmics::End(PHCompositeNode * )
0231 {
0232 std::cout << "HCalCosmics::End" << std::endl;
0233 outfile->cd();
0234 for (auto &ieta : h_channel_hist)
0235 {
0236 for (auto &iphi : ieta)
0237 {
0238 iphi->Write();
0239 delete iphi;
0240 }
0241 }
0242
0243 for (auto &ieta : h_towertime_hist)
0244 {
0245 for (auto &iphi : ieta)
0246 {
0247 iphi->Write();
0248 delete iphi;
0249 }
0250 }
0251
0252 for (auto &ieta : h_adc_hist)
0253 {
0254 for (auto &iphi : ieta)
0255 {
0256 iphi->Write();
0257 delete iphi;
0258 }
0259 }
0260
0261 for (auto &ieta : h_adc_ecut_hist)
0262 {
0263 for (auto &iphi : ieta)
0264 {
0265 iphi->Write();
0266 delete iphi;
0267 }
0268 }
0269
0270 for (auto &ieta : h_gain_hist)
0271 {
0272 for (auto &iphi : ieta)
0273 {
0274 iphi->Write();
0275 delete iphi;
0276 }
0277 }
0278
0279 h_mip->Write();
0280 h_adc->Write();
0281 h_adc_ecut->Write();
0282 h_gain->Write();
0283 h_waveformchi2->Write();
0284 h_waveformchi2_aftercut->Write();
0285 h_time_energy->Write();
0286 h_event->Write();
0287
0288 outfile->Close();
0289 delete outfile;
0290 return 0;
0291 }
0292
0293 double HCalCosmics::gamma_function(const double *x, const double *par)
0294 {
0295 double peak = par[0];
0296 double shift = par[1];
0297 double scale = par[2];
0298 double N = par[3];
0299
0300 if (scale == 0)
0301 {
0302 return 0;
0303 }
0304
0305 double arg_para = (x[0] - shift) / scale;
0306 arg_para = std::max<double>(arg_para, 0);
0307 double peak_para = (peak - shift) / scale;
0308
0309 double numerator = N * pow(arg_para, peak_para) * std::exp(-arg_para);
0310 double denominator = ROOT::Math::tgamma(peak_para + 1) * scale;
0311
0312 if (denominator == 0)
0313 {
0314 return 1e8;
0315 }
0316 double val = numerator / denominator;
0317 if (std::isnan(val))
0318 {
0319 return 0;
0320 }
0321 return val;
0322 }
0323
0324 TF1 *HCalCosmics::fitHist(TH1 *h)
0325 {
0326 TF1 *f_gaus = new TF1("f_gaus", "gaus", 0, 10000);
0327 h->Fit(f_gaus, "QN", "", 0, 10000);
0328
0329 TF1 *f_gamma = new TF1("f_gamma", gamma_function, 0, 5000, 4);
0330 f_gamma->SetParName(0, "Peak(ADC)");
0331 f_gamma->SetParName(1, "Shift");
0332 f_gamma->SetParName(2, "Scale");
0333 f_gamma->SetParName(3, "N");
0334
0335 f_gamma->SetParLimits(0, 1000, 4000);
0336 f_gamma->SetParLimits(1, 500, 2000);
0337 f_gamma->SetParLimits(2, 200, 1000);
0338 f_gamma->SetParLimits(3, 0, 1e9);
0339
0340 f_gamma->SetParameter(0, f_gaus->GetParameter(1));
0341 f_gamma->SetParameter(1, 1300);
0342 f_gamma->SetParameter(2, 1300);
0343 f_gamma->SetParameter(3, 1e6);
0344
0345 h->Fit(f_gamma, "RQN", "", 1000, 5000);
0346
0347 return f_gamma;
0348 }
0349
0350 void HCalCosmics::fitChannels(const std::string &infile, const std::string &outfilename2)
0351 {
0352 TFile *fin = new TFile(infile.c_str(), "READ");
0353 if (!fin)
0354 {
0355 std::cout << "file " << infile << " not found";
0356 return;
0357 }
0358 for (int ieta = 0; ieta < n_etabin; ++ieta)
0359 {
0360 for (int iphi = 0; iphi < n_phibin; ++iphi)
0361 {
0362 std::string channel_histname = "h_channel_" + std::to_string(ieta) + "_" + std::to_string(iphi);
0363 fin->GetObject(channel_histname.c_str(), h_channel_hist[ieta][iphi]);
0364 }
0365 }
0366
0367 if (!h_channel_hist[0][0])
0368 {
0369 std::cout << "no hists in " << infile << std::endl;
0370 return;
0371 }
0372
0373 TFile *outfileFit = new TFile(outfilename2.c_str(), "recreate");
0374
0375 TH2 *h2_peak = new TH2F("h2_peak", "", n_etabin, 0, n_etabin, n_phibin, 0, n_phibin);
0376
0377 TH1 *h_allTow = (TH1 *) h_channel_hist[0][0]->Clone("h_allTow");
0378 h_allTow->Reset();
0379
0380 for (int ieta = 0; ieta < n_etabin; ++ieta)
0381 {
0382 for (int iphi = 0; iphi < n_phibin; ++iphi)
0383 {
0384 TF1 *res = fitHist(h_channel_hist[ieta][iphi]);
0385 h2_peak->SetBinContent(ieta + 1, iphi + 1, res->GetParameter(0));
0386 h_allTow->Add(h_channel_hist[ieta][iphi]);
0387 }
0388 }
0389
0390 TF1 *res = fitHist(h_allTow);
0391 res->Write("f_allTow");
0392
0393 h_allTow->Write();
0394 h2_peak->Write();
0395
0396 outfileFit->Close();
0397 fin->Close();
0398 }