File indexing completed on 2025-08-06 08:16:39
0001 #include "InttCalib.h"
0002
0003 #include <intt/InttMapping.h>
0004
0005 #include <cdbobjects/CDBTTree.h>
0006
0007 #include <ffarawobjects/Gl1Packet.h>
0008 #include <ffarawobjects/InttRawHit.h>
0009 #include <ffarawobjects/InttRawHitContainer.h>
0010
0011 #include <qautils/QAHistManagerDef.h>
0012
0013 #include <fun4all/Fun4AllHistoManager.h>
0014 #include <fun4all/Fun4AllReturnCodes.h>
0015
0016 #include <phool/getClass.h>
0017 #include <phool/phool.h>
0018
0019 #include <TCanvas.h>
0020 #include <TF1.h>
0021 #include <TFile.h>
0022 #include <TH1.h>
0023 #include <TLine.h>
0024 #include <TPolyLine.h>
0025 #include <TStyle.h>
0026 #include <TText.h>
0027 #include <TTree.h>
0028
0029 #include <algorithm>
0030 #include <cmath>
0031 #include <cstddef> // for size_t
0032 #include <cstdint> // for uint64_t
0033 #include <sstream> // for basic_ostringstream
0034
0035 #include <format>
0036 #include <iostream>
0037 #include <limits>
0038
0039 InttCalib::InttCalib(const std::string &name)
0040 : SubsysReco(name)
0041 {
0042 }
0043
0044 InttCalib::~InttCalib()
0045 {
0046 for (auto &hist : m_hist)
0047 {
0048 delete hist;
0049 }
0050 for (auto &fit : m_fit)
0051 {
0052 delete fit;
0053 }
0054 for (auto &hist : m_hist_fee)
0055 {
0056 delete hist;
0057 }
0058 for (auto &fit : m_fit_fee)
0059 {
0060 delete fit;
0061 }
0062 for (auto &hist : m_hist_half)
0063 {
0064 delete hist;
0065 }
0066 for (auto &hist : m_bco_peak)
0067 {
0068 delete hist;
0069 }
0070 }
0071
0072 int InttCalib::InitRun(PHCompositeNode * )
0073 {
0074 m_evts = 0;
0075 for (auto const &raw : InttNameSpace::AllRawDataChannels())
0076 {
0077 for (int bco = 0; bco < 129; ++bco)
0078 {
0079 m_hitmap[raw.felix_server][raw.felix_channel][raw.chip][raw.channel][bco] = 0;
0080 }
0081 }
0082
0083 m_do_nothing = false;
0084
0085 std::cout << "INITRUNEND" << std::endl;
0086 return Fun4AllReturnCodes::EVENT_OK;
0087 }
0088
0089 int InttCalib::process_event(PHCompositeNode *top_node)
0090 {
0091 if (m_do_nothing)
0092 {
0093 return Fun4AllReturnCodes::EVENT_OK;
0094 }
0095 Gl1Packet *gl1 = findNode::getClass<Gl1Packet>(top_node, "GL1RAWHIT");
0096 uint64_t gl1_bco = (gl1 != nullptr) ? (gl1->getBCO() & 0xFFFFFFFFFFU)
0097 : std::numeric_limits<uint64_t>::max();
0098
0099 if (!gl1)
0100 {
0101 std::cout << PHWHERE << "\n"
0102 << "\tCould not get 'GL1RAWHIT' from node tree" << std::endl;
0103 if (m_streaming)
0104 {
0105 std::cout << "\tRunmode is Streaming \n"
0106 << "\tModule will do nothing" << std::endl;
0107 m_do_nothing = true;
0108 return Fun4AllReturnCodes::EVENT_OK;
0109 }
0110
0111 std::cout << "\tRunmode is Triggered \n"
0112 << "\tModule will process without GL1" << std::endl;
0113 }
0114 InttRawHitContainer *intt_raw_hit_container =
0115 findNode::getClass<InttRawHitContainer>(top_node, m_rawhit_container_name);
0116 if (!intt_raw_hit_container)
0117 {
0118 std::cout << PHWHERE << "\n"
0119 << "\tCould not get 'INTTRAWHIT' from node tree\n"
0120 << "\tModule will do nothing" << std::endl;
0121 m_do_nothing = true;
0122
0123
0124 return Fun4AllReturnCodes::EVENT_OK;
0125 }
0126
0127 for (size_t n = 0, N = intt_raw_hit_container->get_nhits(); n < N; ++n)
0128 {
0129 InttRawHit *intt_raw_hit = intt_raw_hit_container->get_hit(n);
0130 if (!intt_raw_hit)
0131 {
0132 continue;
0133 }
0134
0135 InttNameSpace::RawData_s raw{
0136 .felix_server = intt_raw_hit->get_packetid() - 3001,
0137 .felix_channel = intt_raw_hit->get_fee(),
0138 .chip = (intt_raw_hit->get_chip_id() + 25) % 26,
0139 .channel = intt_raw_hit->get_channel_id(),
0140 };
0141
0142
0143
0144
0145
0146
0147
0148 int bco_diff =
0149 (m_streaming) ?
0150
0151
0152 intt_raw_hit->get_FPHX_BCO() + intt_raw_hit->get_bco() - gl1_bco
0153 :
0154
0155 (intt_raw_hit->get_FPHX_BCO() - (intt_raw_hit->get_bco() & 0x7fU) +
0156 128) %
0157 128;
0158
0159 if (m_streaming && ((intt_raw_hit->get_FPHX_BCO() > 116) ||
0160 (intt_raw_hit->get_FPHX_BCO() < 5)))
0161 {
0162 bco_diff = -999;
0163 }
0164
0165 if (bco_diff > -1)
0166 {
0167 ++m_hitmap[raw.felix_server][raw.felix_channel][raw.chip][raw.channel][bco_diff];
0168 }
0169 ++m_hitmap[raw.felix_server][raw.felix_channel][raw.chip][raw.channel][128];
0170 }
0171
0172 ++m_evts;
0173 if ((Verbosity() > 1) && ((m_evts % 1000) == 0))
0174 {
0175 std::cout << "event: " << m_evts << std::endl;
0176 }
0177 if (m_evts == m_evts_bco && m_evts_bco != 0)
0178 {
0179 ConfigureBcoMap();
0180 MakeBcoMapCdb();
0181 MakeBcoMapPng();
0182 m_do_make_bco = false;
0183 }
0184 return Fun4AllReturnCodes::EVENT_OK;
0185 }
0186
0187 int InttCalib::EndRun(int const run_number)
0188 {
0189 if (m_do_nothing)
0190 {
0191 std::cout << PHWHERE << "\n"
0192 << "\tMember 'm_do_nothing' set\n"
0193 << "\tDoing nothing" << std::endl;
0194 return Fun4AllReturnCodes::EVENT_OK;
0195 }
0196
0197 m_run_num = run_number;
0198 if (m_do_fee)
0199 {
0200 ConfigureHotMap_fee();
0201 MakeHotMapCdb_fee();
0202 MakeHotMapROOT_fee();
0203 }
0204 else
0205 {
0206 ConfigureHotMap_v3();
0207 MakeHotMapCdb_v3();
0208 MakeHotMapPng_v3();
0209 }
0210 if (m_do_make_bco)
0211 {
0212 ConfigureBcoMap();
0213 MakeBcoMapCdb();
0214 MakeBcoMapPng();
0215 }
0216
0217 return Fun4AllReturnCodes::EVENT_OK;
0218 }
0219 int InttCalib::ConfigureHotMap_fee()
0220 {
0221 std::map<double, int> hitrate_pdf[m_MAX_LADDER]{};
0222 std::string name[m_MAX_LADDER];
0223 std::string title[m_MAX_LADDER];
0224 for (int i = 0; i < m_MAX_LADDER; ++i)
0225 {
0226
0227 name[i] = std::format("h_InttCalib_intt{:01d}_fee{}", (i / 14), (i % 14));
0228 title[i] = name[i];
0229 }
0230
0231 for (auto const &raw : InttNameSpace::AllRawDataChannels())
0232 {
0233 double hitrate =
0234 m_hitmap[raw.felix_server][raw.felix_channel][raw.chip][raw.channel][128] / m_evts;
0235 InttNameSpace::Offline_s ofl = InttNameSpace::ToOffline(raw);
0236
0237 int index = GetFeeIndex(raw, ofl);
0238 adjust_hitrate(ofl, hitrate);
0239
0240 ++hitrate_pdf[index][hitrate];
0241 }
0242 std::vector<double> middle_keys(m_MAX_LADDER);
0243 for (int i = 0; i < m_MAX_LADDER; ++i)
0244 {
0245 size_t map_size = hitrate_pdf[i].size();
0246
0247 size_t mid_index = map_size / 2;
0248 double middle_key = 0.;
0249
0250 auto it = hitrate_pdf[i].begin();
0251 std::advance(it, mid_index);
0252 middle_key = it->first;
0253 middle_keys[i] = middle_key;
0254 }
0255 std::sort(middle_keys.begin(), middle_keys.end());
0256 double global_maxbin = 5 * (middle_keys[56] + middle_keys[57]) / 2.0;
0257 for (int i = 0; i < m_MAX_LADDER; ++i)
0258 {
0259 ConfigureHist_v3(m_hist_fee[i], m_fit_fee[i], global_maxbin, hitrate_pdf[i], name[i], title[i]);
0260
0261 double mean = m_fit_fee[i]->GetParameter(1);
0262 double sigma = m_fit_fee[i]->GetParameter(2);
0263 m_mean_fee[i] = mean;
0264 m_sigma_fee[i] = sigma;
0265
0266 m_min_fee[i] = mean - m_NUM_SIGMA_COLD * sigma;
0267 if (m_min_fee[i] <= 0)
0268 {
0269 m_min_fee[i] = -999;
0270 }
0271 m_max_fee[i] = mean + m_NUM_SIGMA_HOT * sigma;
0272 }
0273
0274 return Fun4AllReturnCodes::EVENT_OK;
0275 }
0276
0277 int InttCalib::ConfigureHotMap_v3()
0278 {
0279 std::map<double, int> hitrate_pdf[m_MAX_INDEX]{};
0280 std::string name[m_MAX_INDEX];
0281 std::string title[m_MAX_INDEX];
0282 for (int i = 0; i < m_MAX_INDEX; ++i)
0283 {
0284
0285 name[i] = std::format("h_InttCalib_intt{:01d}", i);
0286 title[i] = name[i];
0287 }
0288
0289 for (auto const &raw : InttNameSpace::AllRawDataChannels())
0290 {
0291 if (m_FELIX_TARGET != -1 && m_FELIX_TARGET != raw.felix_server)
0292 {
0293 continue;
0294 }
0295 double hitrate =
0296 m_hitmap[raw.felix_server][raw.felix_channel][raw.chip][raw.channel][128] / m_evts;
0297 InttNameSpace::Offline_s ofl = InttNameSpace::ToOffline(raw);
0298
0299 int index = GetIndex(raw, ofl);
0300 adjust_hitrate(ofl, hitrate);
0301
0302 ++hitrate_pdf[index][hitrate];
0303 }
0304 std::vector<double> middle_keys(8);
0305 double global_maxbin = 0;
0306 for (int i = 0; i < m_MAX_INDEX; ++i)
0307 {
0308 if (m_FELIX_TARGET != -1 && m_FELIX_TARGET != i)
0309 {
0310 continue;
0311 }
0312 size_t map_size = hitrate_pdf[i].size();
0313
0314 size_t mid_index = map_size / 2;
0315 double middle_key = 0.;
0316
0317 auto it = hitrate_pdf[i].begin();
0318 std::advance(it, mid_index);
0319 middle_key = it->first;
0320 middle_keys[i] = middle_key;
0321 global_maxbin = 5 * middle_key;
0322 }
0323 std::sort(middle_keys.begin(), middle_keys.end());
0324 if (m_FELIX_TARGET == -1)
0325 {
0326 global_maxbin = 5 * (middle_keys[3] + middle_keys[4]) / 2.0;
0327 }
0328 for (int i = 0; i < m_MAX_INDEX; ++i)
0329 {
0330 if (m_FELIX_TARGET != -1 && m_FELIX_TARGET != i)
0331 {
0332 continue;
0333 }
0334 ConfigureHist_v3(m_hist[i], m_fit[i], global_maxbin, hitrate_pdf[i], name[i], title[i]);
0335 QAHistManagerDef::getHistoManager()->registerHisto(m_hist[i]);
0336 QAHistManagerDef::getHistoManager()->registerHisto(m_fit[i]);
0337 int nBins = m_hist[i]->GetNbinsX();
0338 double xMin = m_hist[i]->GetXaxis()->GetXmin();
0339 double xMax = m_hist[i]->GetXaxis()->GetXmax();
0340
0341 m_hist_half[i] =
0342 new TH1D(std::format("h_InttCalib_half_hist_{}", i).c_str(),
0343 "New Histogram with Same Binning", nBins, xMin, xMax);
0344
0345 double mean = m_fit[i]->GetParameter(1);
0346 double sigma = m_fit[i]->GetParameter(2);
0347 m_mean[i] = mean;
0348 m_sigma[i] = sigma;
0349
0350
0351 m_min[i] = mean - m_NUM_SIGMA_COLD * sigma;
0352 if (m_min[i] <= 0)
0353 {
0354 m_min[i] = -999;
0355 }
0356 m_max[i] = mean + m_NUM_SIGMA_HOT * sigma;
0357 }
0358
0359 return Fun4AllReturnCodes::EVENT_OK;
0360 }
0361
0362 int InttCalib::MakeHotMapCdb_fee()
0363 {
0364 if (m_hotmap_cdb_file.empty())
0365 {
0366 return Fun4AllReturnCodes::EVENT_OK;
0367 }
0368
0369 CDBTTree *cdbttree = new CDBTTree(m_hotmap_cdb_file);
0370 int size = 0;
0371 for (auto const &raw : InttNameSpace::AllRawDataChannels())
0372 {
0373 double hitrate =
0374 m_hitmap[raw.felix_server][raw.felix_channel][raw.chip][raw.channel][128] / m_evts;
0375 InttNameSpace::Offline_s ofl = InttNameSpace::ToOffline(raw);
0376
0377 int index = GetFeeIndex(raw, ofl);
0378 adjust_hitrate(ofl, hitrate);
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391 if (hitrate == 0)
0392 {
0393 cdbttree->SetIntValue(size, "felix_server", raw.felix_server);
0394 cdbttree->SetIntValue(size, "felix_channel", raw.felix_channel);
0395 cdbttree->SetIntValue(size, "chip", raw.chip);
0396 cdbttree->SetIntValue(size, "channel", raw.channel);
0397 cdbttree->SetIntValue(size, "flag", 1);
0398 ++size;
0399 continue;
0400 }
0401 if (m_min_fee[index] < hitrate && hitrate < m_max_fee[index])
0402 {
0403 continue;
0404 }
0405 if (hitrate > m_max_fee[index])
0406 {
0407 cdbttree->SetIntValue(size, "felix_server", raw.felix_server);
0408 cdbttree->SetIntValue(size, "felix_channel", raw.felix_channel);
0409 cdbttree->SetIntValue(size, "chip", raw.chip);
0410 cdbttree->SetIntValue(size, "channel", raw.channel);
0411 cdbttree->SetIntValue(size, "flag", 8);
0412 ++size;
0413 continue;
0414 }
0415 if (hitrate < m_min_fee[index])
0416 {
0417 cdbttree->SetIntValue(size, "felix_server", raw.felix_server);
0418 cdbttree->SetIntValue(size, "felix_channel", raw.felix_channel);
0419 cdbttree->SetIntValue(size, "chip", raw.chip);
0420 cdbttree->SetIntValue(size, "channel", raw.channel);
0421 cdbttree->SetIntValue(size, "flag", 4);
0422 ++size;
0423 continue;
0424 }
0425 }
0426 cdbttree->SetSingleIntValue("size", size);
0427 cdbttree->SetSingleIntValue("event", m_evts);
0428 for (int i = 0; i < m_MAX_LADDER; i++)
0429 {
0430 std::string meanname = "mean" + std::to_string(i);
0431 std::string sigmaname = "sigma" + std::to_string(i);
0432 cdbttree->SetSingleDoubleValue(meanname, m_mean_fee[i]);
0433 cdbttree->SetSingleDoubleValue(sigmaname, m_sigma_fee[i]);
0434 }
0435
0436 cdbttree->Commit();
0437 cdbttree->CommitSingle();
0438 cdbttree->WriteCDBTTree();
0439
0440 return Fun4AllReturnCodes::EVENT_OK;
0441 }
0442
0443 int InttCalib::MakeHotMapCdb_v3()
0444 {
0445 if (m_hotmap_cdb_file.empty())
0446 {
0447 return Fun4AllReturnCodes::EVENT_OK;
0448 }
0449
0450 CDBTTree *cdbttree = new CDBTTree(m_hotmap_cdb_file);
0451 int size = 0;
0452 for (auto const &raw : InttNameSpace::AllRawDataChannels())
0453 {
0454 if (m_FELIX_TARGET != -1 && m_FELIX_TARGET != raw.felix_server)
0455 {
0456 continue;
0457 }
0458 double hitrate =
0459 m_hitmap[raw.felix_server][raw.felix_channel][raw.chip][raw.channel][128] / m_evts;
0460 InttNameSpace::Offline_s ofl = InttNameSpace::ToOffline(raw);
0461
0462 int index = GetIndex(raw, ofl);
0463 adjust_hitrate(ofl, hitrate);
0464 if (m_half_min[index] < hitrate && hitrate < m_half_max[index])
0465 {
0466 m_hitmap_half[raw.felix_server][raw.felix_channel][raw.chip]++;
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477 }
0478
0479 if (hitrate == 0)
0480 {
0481 cdbttree->SetIntValue(size, "felix_server", raw.felix_server);
0482 cdbttree->SetIntValue(size, "felix_channel", raw.felix_channel);
0483 cdbttree->SetIntValue(size, "chip", raw.chip);
0484 cdbttree->SetIntValue(size, "channel", raw.channel);
0485 cdbttree->SetIntValue(size, "flag", 1);
0486 ++size;
0487 continue;
0488 }
0489 if (m_min[index] < hitrate && hitrate < m_max[index])
0490 {
0491 continue;
0492 }
0493 if (hitrate > m_max[index])
0494 {
0495 cdbttree->SetIntValue(size, "felix_server", raw.felix_server);
0496 cdbttree->SetIntValue(size, "felix_channel", raw.felix_channel);
0497 cdbttree->SetIntValue(size, "chip", raw.chip);
0498 cdbttree->SetIntValue(size, "channel", raw.channel);
0499 cdbttree->SetIntValue(size, "flag", 8);
0500 ++size;
0501 continue;
0502 }
0503 if (hitrate < m_min[index])
0504 {
0505 cdbttree->SetIntValue(size, "felix_server", raw.felix_server);
0506 cdbttree->SetIntValue(size, "felix_channel", raw.felix_channel);
0507 cdbttree->SetIntValue(size, "chip", raw.chip);
0508 cdbttree->SetIntValue(size, "channel", raw.channel);
0509 cdbttree->SetIntValue(size, "flag", 4);
0510 ++size;
0511 continue;
0512 }
0513 }
0514 cdbttree->SetSingleIntValue("size", size);
0515 cdbttree->SetSingleIntValue("event", m_evts);
0516 for (int i = 0; i < 8; i++)
0517 {
0518 std::string meanname = "mean" + std::to_string(i);
0519 std::string sigmaname = "sigma" + std::to_string(i);
0520 cdbttree->SetSingleDoubleValue(meanname, m_mean[i]);
0521 cdbttree->SetSingleDoubleValue(sigmaname, m_sigma[i]);
0522 }
0523
0524 cdbttree->Commit();
0525 cdbttree->CommitSingle();
0526 cdbttree->WriteCDBTTree();
0527
0528 return Fun4AllReturnCodes::EVENT_OK;
0529 }
0530
0531 int InttCalib::MakeHotMapROOT_fee()
0532 {
0533 const int rows = 8;
0534 const int cols = 14;
0535 const int numHists = rows * cols;
0536 TCanvas *c1 = new TCanvas("c1", "Histograms with Fits", 2000, 1400);
0537 c1->Divide(cols, rows);
0538
0539 gStyle->SetOptStat(0);
0540 gStyle->SetPadTopMargin(0.01);
0541 gStyle->SetPadBottomMargin(0.01);
0542 gStyle->SetPadLeftMargin(0.01);
0543 gStyle->SetPadRightMargin(0.01);
0544
0545 for (int i = 0; i < numHists; ++i)
0546 {
0547 c1->cd(i + 1);
0548 m_hist_fee[i]->Draw();
0549 m_fit_fee[i]->Draw("same");
0550 }
0551 if (!m_hotmap_png_file.empty())
0552 {
0553 c1->SaveAs(m_hotmap_png_file.c_str());
0554 }
0555 return Fun4AllReturnCodes::EVENT_OK;
0556 }
0557
0558 int InttCalib::MakeHotMapPng_v3()
0559 {
0560
0561 gStyle->SetOptStat(0);
0562 TCanvas *cnvs = new TCanvas("hitrate_cnvs",
0563 "hitrate_cnvs",
0564 1280, 720
0565 );
0566 double n_hot = 0;
0567 double n_cold = 0;
0568 double n_dead = 0;
0569 double n_total = 0;
0570 for (auto const &raw : InttNameSpace::AllRawDataChannels())
0571 {
0572 double hitrate =
0573 m_hitmap[raw.felix_server][raw.felix_channel][raw.chip][raw.channel][128] / m_evts;
0574 InttNameSpace::Offline_s ofl = InttNameSpace::ToOffline(raw);
0575
0576 int index = GetIndex(raw, ofl);
0577 adjust_hitrate(ofl, hitrate);
0578
0579 if (!(m_min[index] < hitrate))
0580 {
0581 ++n_cold;
0582 }
0583 if (!(hitrate < m_max[index]))
0584 {
0585 ++n_hot;
0586 }
0587 if (hitrate == 0)
0588 {
0589 ++n_dead;
0590 }
0591 ++n_total;
0592 if (m_hitmap_half[raw.felix_server][raw.felix_channel][raw.chip] > 100)
0593 {
0594 m_hist_half[raw.felix_server]->Fill(hitrate);
0595 }
0596 }
0597 for (int j = 0; j < 8; ++j)
0598 {
0599 std::string name = std::format("hist_pad_{:01d}", j);
0600
0601 cnvs->cd();
0602 TPad *hist_pad = new TPad(
0603 name.c_str(),
0604 name.c_str(),
0605
0606
0607
0608
0609 ((j % 4 + 0.0) / 4.0 * 1.0) + 0.0,
0610
0611 ((1.0 - j / 4) / 2.0 * 0.9) + 0.1,
0612
0613 ((j % 4 + 1.0) / 4.0 * 1.0) + 0.0,
0614
0615 ((2.0 - j / 4) / 2.0 * 0.9) + 0.1
0616 );
0617
0618 hist_pad->SetFillStyle(4000);
0619 hist_pad->Range(0.0, 0.0, 1.0, 1.0);
0620 hist_pad->SetLogy();
0621 hist_pad->Draw();
0622
0623 hist_pad->cd();
0624 double x_max = 0;
0625 double y_max = 0;
0626
0627 for (int i = j; i < j + 1; ++i)
0628 {
0629
0630 if (!m_hist[i])
0631 {
0632 continue;
0633 }
0634 m_hist[i]->SetLineColor(kBlack);
0635 m_hist[i]->SetLineWidth(2);
0636 m_hist_half[i]->SetLineColor(kRed);
0637 m_hist_half[i]->SetLineWidth(3);
0638
0639
0640 m_fit[i]->SetLineColor(kBlue);
0641 m_fit[i]->SetLineWidth(2);
0642
0643 double temp_max;
0644
0645 temp_max = m_hist[i]->GetBinContent(m_hist[i]->GetMaximumBin());
0646 y_max = std::max(y_max, temp_max);
0647
0648 temp_max = m_hist[i]->GetXaxis()->GetBinLowEdge(
0649 m_hist[i]->GetXaxis()->GetNbins() - 1);
0650 temp_max += m_hist[i]->GetXaxis()->GetBinWidth(
0651 m_hist[i]->GetXaxis()->GetNbins() - 1);
0652 x_max = std::max(x_max, temp_max);
0653 }
0654 y_max *= 10;
0655
0656 for (int i = j; i < j + 1; ++i)
0657 {
0658 if (!m_hist[i])
0659 {
0660 continue;
0661 }
0662 m_hist[i]->GetXaxis()->SetRangeUser(0, x_max);
0663 m_hist[i]->GetYaxis()->SetRangeUser(1, y_max);
0664 m_hist[i]->Draw("same");
0665
0666
0667 m_fit[i]->Draw("same");
0668
0669 TLine line;
0670 line.SetLineColor(kRed);
0671 line.SetLineWidth(2);
0672 line.DrawLine(m_max[i], 0, m_max[i], y_max);
0673
0674 TLine line2;
0675 line2.SetLineColor(kBlue);
0676 line2.DrawLine(m_min[i], 0, m_min[i], y_max);
0677 }
0678 }
0679 cnvs->cd();
0680 TPad *legend_pad = new TPad("legend_pad", "legend_pad", 0.9, 0.1, 1.0, 1.0);
0681 legend_pad->SetFillStyle(4000);
0682 legend_pad->Range(0.0, 0.0, 1.0, 1.0);
0683
0684 legend_pad->cd();
0685 for (int i = 0; i < 4; ++i)
0686 {
0687 TText text;
0688 text.SetTextColor(GetFeeColor(i));
0689 text.SetTextAlign(22);
0690 text.SetTextSize(0.15);
0691 if (!m_hist[i])
0692 {
0693 continue;
0694 }
0695 std::string title = m_hist[i]->GetName();
0696 text.DrawText(0.5, (2.0 * i + 1.0) / (2.0 * 4), title.substr(6, 7).c_str());
0697 }
0698
0699 cnvs->cd();
0700 TPad *caption_pad =
0701 new TPad("caption_pad", "caption_pad", 0.0, 0.0, 1.0, 0.1);
0702 caption_pad->SetFillStyle(4000);
0703 caption_pad->Range(0.0, 0.0, 1.0, 1.0);
0704 caption_pad->Draw();
0705
0706 caption_pad->cd();
0707 TText caption;
0708 caption.SetTextColor(kBlack);
0709 caption.SetTextAlign(22);
0710 caption.SetTextSize(0.25);
0711 caption.DrawText(0.5, 0.75, std::format("Run: {:08d} Events: {}", m_run_num, m_evts).c_str());
0712 caption.DrawText(0.5, 0.50,
0713 std::format("Fraction Cold: {:.3f}% Fraction Dead: {:.3f}%", (n_cold * 100 / n_total), (n_dead * 100 / n_total)).c_str());
0714 caption.DrawText(0.5, 0.25, std::format("Fraction Hot: {:.3f}%", (n_hot * 100 / n_total)).c_str());
0715
0716 cnvs->Update();
0717 cnvs->Show();
0718 if (!m_hotmap_png_file.empty())
0719 {
0720 cnvs->SaveAs(m_hotmap_png_file.c_str());
0721 }
0722
0723 delete cnvs;
0724 return Fun4AllReturnCodes::EVENT_OK;
0725 }
0726
0727 int InttCalib::ConfigureBcoMap()
0728 {
0729 for (int felix = 0; felix < 8; felix++)
0730 {
0731 for (int fee = 0; fee < 14; fee++)
0732 {
0733 if (m_FELIX_TARGET != -1 && m_FELIX_TARGET != felix)
0734 {
0735 continue;
0736 }
0737
0738 int chp_most = 0;
0739 int max_hits = 0;
0740 for (int chp = 0; chp < 26; chp++)
0741 {
0742 int chip_total = 0;
0743
0744 for (int chan = 0; chan < 128; chan++)
0745 {
0746 chip_total += m_hitmap[felix][fee][chp][chan][128];
0747 }
0748 if (chip_total > max_hits)
0749 {
0750 max_hits = chip_total;
0751 chp_most = chp;
0752 }
0753 }
0754 for (int chp = 0; chp < 26; chp++)
0755 {
0756
0757 for (int chan = 0; chan < 128; chan++)
0758 {
0759 if (chp != chp_most)
0760 {
0761 for (int bco = 0; bco < 128; ++bco)
0762 {
0763 m_bcorates_fee[felix][fee][bco] +=
0764 m_hitmap[felix][fee][chp][chan][bco];
0765 }
0766 }
0767 }
0768 }
0769 }
0770 }
0771
0772 for (int felix = 0; felix < 8; felix++)
0773 {
0774 if (m_FELIX_TARGET != -1 && m_FELIX_TARGET != felix)
0775 {
0776 continue;
0777 }
0778 for (int fee = 0; fee < 14; fee++)
0779 {
0780 int max_counts = 0;
0781 int bco_peak = 0;
0782 for (int bco = 0; bco < 128; bco++)
0783 {
0784 if (max_counts < m_bcorates_fee[felix][fee][bco])
0785 {
0786 bco_peak = bco;
0787 max_counts = m_bcorates_fee[felix][fee][bco];
0788 }
0789 }
0790
0791 if (max_counts < 50)
0792
0793 {
0794 bco_peak = -1;
0795 }
0796 m_bcopeaks_fee[felix][fee] = bco_peak;
0797 }
0798 }
0799
0800 return Fun4AllReturnCodes::EVENT_OK;
0801 }
0802
0803 int InttCalib::MakeBcoMapCdb()
0804 {
0805 if (m_bcomap_cdb_file.empty())
0806 {
0807 return Fun4AllReturnCodes::EVENT_OK;
0808 }
0809
0810 CDBTTree *cdbttree = new CDBTTree(m_bcomap_cdb_file);
0811
0812 int size = 0;
0813 std::vector<int> bco_temp_container;
0814 bco_temp_container.clear();
0815 for (int felix = 0; felix < 8; felix++)
0816 {
0817 if (m_FELIX_TARGET != -1 && m_FELIX_TARGET != felix)
0818 {
0819 continue;
0820 }
0821 std::string name_bco_peak = "h_InttCalib_BCOOffSet_INTT" + std::to_string(felix);
0822 m_bco_peak[felix] = new TH1I(name_bco_peak.c_str(), name_bco_peak.c_str(), 14, 0, 14);
0823 for (int fee = 0; fee < 14; fee++)
0824 {
0825 int bco = m_bcopeaks_fee[felix][fee];
0826 cdbttree->SetIntValue(size, "felix_server", felix);
0827 cdbttree->SetIntValue(size, "felix_channel", fee);
0828 cdbttree->SetIntValue(size, "bco_diff", bco);
0829 m_bco_peak[felix]->SetBinContent(fee + 1, bco);
0830 bco_temp_container.push_back(bco);
0831 ++size;
0832 }
0833 QAHistManagerDef::getHistoManager()->registerHisto(m_bco_peak[felix]);
0834 }
0835
0836 cdbttree->SetSingleIntValue("size", size);
0837 std::pair<double, double> stats =
0838 CalculateStandardDeviation(bco_temp_container);
0839 m_bco_mean = stats.first;
0840 m_bco_stdDev = stats.second;
0841 int runmode = m_streaming ? 1 : 0;
0842 cdbttree->SetSingleDoubleValue("StdDev", m_bco_stdDev);
0843 cdbttree->SetSingleIntValue("runmode", runmode);
0844 cdbttree->SetSingleIntValue("events", m_evts);
0845 cdbttree->Commit();
0846 cdbttree->CommitSingle();
0847 cdbttree->WriteCDBTTree();
0848 bco_temp_container.clear();
0849 return Fun4AllReturnCodes::EVENT_OK;
0850 }
0851
0852 int InttCalib::MakeBcoMapPng()
0853 {
0854
0855 gStyle->SetOptStat(0);
0856 TCanvas *bco_cnvs = new TCanvas(
0857 "bco_cnvs", "bco_cnvs",
0858 1280, 720
0859 );
0860 bco_cnvs->Draw();
0861
0862 TH1 *bco_hist[112] = {};
0863 for (int i = 0; i < 16; ++i)
0864 {
0865 std::string tpadtitle = std::format("bco_pad_{:02d}", i);
0866 bco_cnvs->cd();
0867 TPad *bco_pdf_pad = new TPad(
0868 tpadtitle.c_str(), tpadtitle.c_str(),
0869
0870 ((i % 4 + 0.0) / 4.0 * 0.9) + 0.0, ((3.0 - i / 4) / 4.0 * 0.9) + 0.1,
0871
0872 ((i % 4 + 1.0) / 4.0 * 0.9) + 0.0, ((4.0 - i / 4) / 4.0 * 0.9) + 0.1);
0873 bco_pdf_pad->SetFillStyle(4000);
0874 bco_pdf_pad->SetLogy();
0875 bco_pdf_pad->SetLeftMargin(0.15);
0876 bco_pdf_pad->SetRightMargin(0.05);
0877 if ((i / 4) % 2)
0878 {
0879 bco_pdf_pad->SetTopMargin(0.0);
0880 bco_pdf_pad->SetBottomMargin(0.15);
0881 }
0882 else
0883 {
0884 bco_pdf_pad->SetTopMargin(0.15);
0885 bco_pdf_pad->SetBottomMargin(0.0);
0886 }
0887 bco_pdf_pad->Range(0.0, 0.0, 1.0, 1.0);
0888 bco_pdf_pad->Draw();
0889
0890 int felix = (i % 4) + (4 * (i / 8));
0891 int fee_index_start = (i / 4) % 2 ? 0 : 7;
0892 int fee_index_end = (i / 4) % 2 ? 7 : 14;
0893 double max = 0;
0894 for (int fee = fee_index_start; fee < fee_index_end; fee++)
0895 {
0896 int h = (felix * 14) + fee;
0897 bco_pdf_pad->cd();
0898 std::string htitle = std::format("h_InttCalib_bco_hist_{:03d}", h);
0899
0900 float min_bin = -0.5;
0901 float max_bin = 127.5;
0902
0903 int nbins = 128;
0904 bco_hist[h] = new TH1D(
0905 htitle.c_str(), htitle.c_str(),
0906 nbins, min_bin, max_bin
0907
0908 );
0909 bco_hist[h]->SetTitle(std::format(";BCO Difference;intt{:01d} ({:01d} - {:02d})", felix, fee, fee).c_str());
0910 bco_hist[h]->GetYaxis()->CenterTitle();
0911 bco_hist[h]->GetYaxis()->SetTitleSize(0.12);
0912 bco_hist[h]->GetYaxis()->SetTitleOffset(0.6);
0913 bco_hist[h]->GetYaxis()->SetLabelSize(0.07);
0914 bco_hist[h]->GetXaxis()->SetTitleSize(0.10);
0915 bco_hist[h]->GetXaxis()->SetTitleOffset(0.6);
0916 bco_hist[h]->GetXaxis()->SetLabelSize(0.07);
0917 bco_hist[h]->SetLineColor(GetFeeColor(fee));
0918 bco_hist[h]->Draw("same");
0919
0920 for (int bco = 0; bco < 128; ++bco)
0921 {
0922 bco_hist[h]->SetBinContent(bco + 1, m_bcorates_fee[felix][fee][bco]);
0923 max = std::max<double>(max, m_bcorates_fee[felix][fee][bco]);
0924 }
0925 }
0926
0927
0928
0929
0930
0931 }
0932
0933
0934 bco_cnvs->cd();
0935 TPad *legend_pad = new TPad("legend_pad", "legend_pad",
0936 0.9, 0.1, 1.0, 1.0
0937 );
0938 legend_pad->SetFillStyle(4000);
0939 legend_pad->Range(0.0, 0.0, 1.0, 1.0);
0940 legend_pad->Draw();
0941 legend_pad->cd();
0942
0943 for (int fee = 0; fee < 7; ++fee)
0944 {
0945 TText legend_text;
0946 legend_text.SetTextAlign(22);
0947 legend_text.SetTextColor(kBlack);
0948 legend_text.SetTextSize(0.1);
0949 legend_text.DrawText(
0950 0.6, (2.0 * fee + 1.0) / 14.0,
0951 std::format("FCh {:01d}, {:02d}", fee, (fee + 7)).c_str());
0952
0953 double x[4] = {-1.0, +1.0, +1.0, -1.0};
0954 double y[4] = {-1.0, -1.0, +1.0, +1.0};
0955 for (int i = 0; i < 4; ++i)
0956 {
0957 x[i] *= 0.1;
0958 x[i] += 0.2;
0959
0960 y[i] *= 0.008;
0961 y[i] += (2.0 * fee + 1.0) / 14.0;
0962 }
0963
0964 TPolyLine box;
0965 box.SetFillColor(GetFeeColor(fee));
0966 box.SetLineColor(kBlack);
0967 box.SetLineWidth(1);
0968 box.DrawPolyLine(4, x, y, "f");
0969 }
0970
0971
0972 bco_cnvs->cd();
0973 TPad *caption_pad = new TPad("caption_pad", "caption_pad",
0974 0.0, 0.0, 1.0, 0.1
0975 );
0976 caption_pad->SetFillStyle(4000);
0977 caption_pad->Range(0.0, 0.0, 1.0, 1.0);
0978 caption_pad->Draw();
0979
0980 caption_pad->cd();
0981 TText caption_text;
0982 caption_text.SetTextAlign(22);
0983 caption_text.SetTextSize(0.40);
0984 caption_text.SetTextColor(kBlack);
0985 caption_text.DrawText(
0986 0.5, 0.75,
0987 std::format("Run: {:08d} Events: {} BCO StdDev: {:.2f} BCO Offset: {:.2f}",
0988 m_run_num, m_evts, m_bco_stdDev, m_bco_mean)
0989 .c_str());
0990
0991 TText caption_tag;
0992 caption_tag.SetTextAlign(22);
0993 caption_tag.SetTextSize(0.40);
0994 if (m_evts < 1000)
0995 {
0996 caption_tag.SetTextColor(kRed);
0997 caption_tag.DrawText(0.5, 0.3, "LOW STATSTICS events < 1000!!");
0998 }
0999 else if (m_bco_stdDev != 0)
1000 {
1001 caption_tag.SetTextColor(kRed);
1002 caption_tag.DrawText(0.5, 0.3, "FEE MISALIGNED!!");
1003 }
1004 else
1005 {
1006 caption_tag.SetTextColor(kBlue);
1007 caption_tag.DrawText(0.5, 0.3, "GOOD");
1008 }
1009
1010 std::map<int, std::vector<int>> maskedLadders;
1011
1012
1013 for (int i = 0; i < 112; ++i)
1014 {
1015 if (bco_hist[i]->GetBinContent(bco_hist[i]->GetMaximumBin()) < 5)
1016 {
1017 int sev = i / 14;
1018 int fee = i % 14;
1019
1020 maskedLadders[sev].push_back(fee);
1021 }
1022 }
1023
1024
1025 std::ostringstream maskedText;
1026 maskedText << "Masked Ladders: ";
1027
1028
1029 for (const auto &entry : maskedLadders)
1030 {
1031 maskedText << "INTT " << entry.first << "(FC ";
1032 for (auto j = 0U; j < entry.second.size(); ++j)
1033 {
1034 maskedText << entry.second[j];
1035 if (j != entry.second.size() - 1)
1036 {
1037 maskedText << ",";
1038 }
1039 }
1040 maskedText << ") ";
1041 }
1042
1043
1044 TText caption_masked;
1045 caption_masked.SetTextAlign(32);
1046 caption_masked.SetTextSize(0.20);
1047 caption_masked.DrawText(0.9, 0.3, maskedText.str().c_str());
1048 bco_cnvs->Update();
1049 bco_cnvs->Show();
1050 if (!m_bcomap_png_file.empty())
1051 {
1052 bco_cnvs->SaveAs(m_bcomap_png_file.c_str());
1053 }
1054
1055 delete bco_cnvs;
1056
1057 return Fun4AllReturnCodes::EVENT_OK;
1058 }
1059
1060 int InttCalib::SaveHitrates()
1061 {
1062 TFile *file = TFile::Open(m_hotmap_png_file.c_str(), "RECREATE");
1063 if (!file)
1064 {
1065 std::cerr << "\n"
1066 << PHWHERE << "\n\tfile\n"
1067 << std::endl;
1068 return 1;
1069 }
1070 file->cd();
1071 TTree *tree = new TTree("hitrate_tree", "hitrate_tree");
1072 tree->SetDirectory(file);
1073
1074 int pid{0};
1075 int fee{0};
1076 int chp{0};
1077 int chn{0};
1078 tree->Branch("pid", &pid);
1079 tree->Branch("fee", &fee);
1080 tree->Branch("chp", &chp);
1081 tree->Branch("chn", &chn);
1082
1083 double hitrate;
1084 tree->Branch("hitrate", &hitrate);
1085
1086 for (auto const &raw : InttNameSpace::AllRawDataChannels())
1087 {
1088 pid = raw.felix_server + 3001;
1089 fee = raw.felix_channel;
1090 chp = raw.chip;
1091 chn = raw.channel;
1092
1093 hitrate = m_hitmap[raw.felix_server][raw.felix_channel][raw.chip][raw.channel][128] / m_evts;
1094 tree->Fill();
1095 }
1096
1097 tree->Write();
1098 file->Write();
1099 file->Close();
1100
1101 return 0;
1102 }
1103
1104 int InttCalib::LoadHitrates()
1105 {
1106 TFile *file = TFile::Open("/sphenix/user/jbertaux/hitrates.root", "READ");
1107 if (!file)
1108 {
1109 std::cerr << "\n"
1110 << PHWHERE << "\n\tfile\n"
1111 << std::endl;
1112 return 1;
1113 }
1114
1115 TTree *tree = dynamic_cast<TTree *>(file->Get("hitrate_tree"));
1116 if (!tree)
1117 {
1118 std::cerr << "\n"
1119 << PHWHERE << "\n\ttree\n"
1120 << std::endl;
1121 return 1;
1122 }
1123
1124 int pid{0};
1125 int fee{0};
1126 int chp{0};
1127 int chn{0};
1128 tree->SetBranchAddress("pid", &pid);
1129 tree->SetBranchAddress("fee", &fee);
1130 tree->SetBranchAddress("chp", &chp);
1131 tree->SetBranchAddress("chn", &chn);
1132
1133 double hitrate;
1134 tree->SetBranchAddress("hitrate", &hitrate);
1135
1136 for (Int_t n = 0, N = tree->GetEntriesFast(); n < N; ++n)
1137 {
1138 tree->GetEntry(n);
1139 InttNameSpace::RawData_s raw{
1140 .felix_server = pid + 3001,
1141 .felix_channel = fee,
1142 .chip = chp,
1143 .channel = chn,
1144 };
1145 m_hitmap[raw.felix_server][raw.felix_channel][raw.chip][raw.channel][128] = hitrate;
1146 }
1147
1148 m_evts = 1.0;
1149
1150 return 0;
1151 }
1152 int InttCalib::ConfigureHist_v3(TH1 *&hist, TF1 *&fit, double maxbin,
1153 std::map<double, int> const &hitrate_map,
1154 std::string const &name,
1155 std::string const &title)
1156 {
1157 size_t map_size = hitrate_map.size();
1158 double global_middle = maxbin / 5;
1159 size_t mid_index = map_size / 2;
1160 double middle_key = 0.;
1161
1162 auto it = hitrate_map.begin();
1163 std::advance(it, mid_index);
1164 middle_key = it->first;
1165
1166
1167 delete hist;
1168 hist = new TH1D(
1169 (name + " hitrates").c_str(),
1170 title.c_str(),
1171 100, std::next(hitrate_map.begin())->first, maxbin
1172 );
1173
1174 TH1 *fit_hist = new TH1D(
1175 (name + " fit_hitrates").c_str(),
1176 (title + " (fit)").c_str(),
1177 100, std::next(hitrate_map.begin())->first, maxbin
1178 );
1179
1180 for (auto const &[hitrate, count] : hitrate_map)
1181 {
1182 for (int i = 0; i < count; ++i)
1183 {
1184 hist->Fill(hitrate);
1185 if (hitrate / global_middle > 0.7)
1186 {
1187 fit_hist->Fill(hitrate);
1188 }
1189 }
1190 }
1191
1192 delete fit;
1193 fit = new TF1(
1194 (name + "_fit").c_str(),
1195 "gaus",
1196 middle_key / 10, maxbin
1197 );
1198
1199 if (Verbosity())
1200 {
1201 fit_hist->Fit(fit, "R");
1202 }
1203 else
1204 {
1205 fit_hist->Fit(fit, "QR");
1206 }
1207
1208 std::cout << "Global middle: " << global_middle << std::endl;
1209 delete fit_hist;
1210 return 0;
1211 }
1212
1213 int InttCalib::adjust_hitrate(InttNameSpace::Offline_s const &ofl,
1214 double &hitrate)
1215 {
1216 hitrate /= (ofl.ladder_z % 2) ? 2.0 : 1.6;
1217 if (ofl.layer < 5)
1218 {
1219 hitrate /= (10.005 / 7.4994);
1220 }
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235 return 0;
1236 }
1237
1238 int InttCalib::GetIndex(InttNameSpace::RawData_s const &raw,
1239 InttNameSpace::Offline_s const & )
1240 {
1241
1242
1243
1244
1245
1246 return raw.felix_server;
1247 }
1248
1249 int InttCalib::GetFeeIndex(InttNameSpace::RawData_s const &raw,
1250 InttNameSpace::Offline_s const & )
1251 {
1252 int index = 0;
1253 index = (raw.felix_server) * 14 + raw.felix_channel;
1254 return index;
1255 }
1256 std::pair<double, double>
1257 InttCalib::CalculateStandardDeviation(const std::vector<int> &data)
1258 {
1259 if (data.empty())
1260 {
1261 return std::make_pair(-1, -1);
1262 }
1263
1264 double sum = 0.0;
1265 int n_masked_ladder = 0;
1266 for (int i : data)
1267 {
1268 if (i == -1)
1269 {
1270 n_masked_ladder++;
1271 continue;
1272 }
1273 sum += i;
1274 }
1275 double mean = sum / static_cast<double>(data.size() - n_masked_ladder);
1276 double sumSquaredDiffs = 0.0;
1277
1278 for (int i : data)
1279 {
1280 if (i == -1)
1281 {
1282 continue;
1283 }
1284 sumSquaredDiffs += (i - mean) * (i - mean);
1285
1286 }
1287 double stddev = std::sqrt(sumSquaredDiffs /
1288 static_cast<double>(data.size() - n_masked_ladder));
1289
1290 return std::make_pair(mean, stddev);
1291 }
1292
1293 Color_t InttCalib::GetFeeColor(int fee)
1294 {
1295 switch (fee % 7)
1296 {
1297 case 1:
1298 return kRed;
1299 case 2:
1300 return kGreen;
1301 case 3:
1302 return kBlue;
1303 case 4:
1304 return kOrange;
1305 case 5:
1306 return kMagenta;
1307 case 6:
1308 return kCyan;
1309 default:
1310 break;
1311 }
1312 return kBlack;
1313 }