Back to home page

sPhenix code displayed by LXR

 
 

    


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 * /*unused*/)
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     // gSystem->Exit(1);
0123     // exit(1);
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     // Trigger mode BCO Offset
0143     // old convention
0144     // int bco_diff = ((intt_raw_hit->get_bco() & 0x7fU) -
0145     // intt_raw_hit->get_FPHX_BCO() + 128) % 128; int bco_diff =
0146     // (intt_raw_hit->get_FPHX_BCO() - (intt_raw_hit->get_bco() & 0x7fU) + 128)
0147     // % 128;
0148     int bco_diff =
0149         (m_streaming) ?
0150                       // Streaming mode BCO Offset : Hit BCO(FPHX BCO + INTT
0151                       // BCO) - GL1 BCO
0152             intt_raw_hit->get_FPHX_BCO() + intt_raw_hit->get_bco() - gl1_bco
0153                       :
0154                       // Trigger mode BCO Offset
0155             (intt_raw_hit->get_FPHX_BCO() - (intt_raw_hit->get_bco() & 0x7fU) +
0156              128) %
0157                 128;
0158     // Not use the hit from abort gap region
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     // name[i] = std::format("intt{:01d}", (i / 4));
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     // name[i] = std::format("intt{:01d}", % (i / 4));
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     // m_min[i] = mean - m_NUM_SIGMA * sigma;
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     // Example Part How to add channel masking mannually.
0380     //  if( (raw.pid-3001 == 2) && (raw.felix_channel == 9) && (raw.chip == 15))
0381     //  {
0382     //    cdbttree->SetIntValue(size, "felix_server", raw.felix_server);
0383     //    cdbttree->SetIntValue(size, "felix_channel", raw.felix_channel);
0384     //    cdbttree->SetIntValue(size, "chip", raw.chip);
0385     //    cdbttree->SetIntValue(size, "channel", raw.channel);
0386     //    cdbttree->SetIntValue(size, "flag", 4);
0387     //    ++size;
0388     //    continue;
0389     //  }
0390     // End of Example Part
0391     if (hitrate == 0)
0392     {  // dead channel
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     {  // good channel
0403       continue;
0404     }
0405     if (hitrate > m_max_fee[index])
0406     {  // hot channel
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     {  // cold channel
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       // if (m_hitmap_half[raw.felix_server][raw.felix_channel][raw.chip] > 100)
0468       // {
0469       //   cdbttree->SetIntValue(size, "felix_server", raw.felix_server);
0470       //   cdbttree->SetIntValue(size, "felix_channel", raw.felix_channel);
0471       //   cdbttree->SetIntValue(size, "chip", raw.chip);
0472       //   cdbttree->SetIntValue(size, "channel", raw.channel);
0473       //   cdbttree->SetIntValue(size, "flag", 2);
0474       //   ++size;
0475       //   continue;
0476       // }
0477     }
0478 
0479     if (hitrate == 0)
0480     {  // dead channel
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     {  // good channel
0491       continue;
0492     }
0493     if (hitrate > m_max[index])
0494     {  // hot channel
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     {  // cold channel
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   // canvas
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                        // (j % 4 + 0.0) / 4.0 * 0.9 + 0.0, (1.0 - j / 4) / 2.0 *
0606                        // 0.9 + 0.1, // (j % 4 + 1.0) / 4.0 * 0.9 + 0.0, (2.0 - j
0607                        // / 4) / 2.0 * 0.9 + 0.1  //
0608                        // NOLINTNEXTLINE(bugprone-integer-division)
0609         ((j % 4 + 0.0) / 4.0 * 1.0) + 0.0,
0610         // NOLINTNEXTLINE(bugprone-integer-division)
0611         ((1.0 - j / 4) / 2.0 * 0.9) + 0.1,  //
0612                                             // NOLINTNEXTLINE(bugprone-integer-division)
0613         ((j % 4 + 1.0) / 4.0 * 1.0) + 0.0,
0614         // NOLINTNEXTLINE(bugprone-integer-division)
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     // for(int i = j * 4; i < (j + 1) * 4; ++i)
0627     for (int i = j; i < j + 1; ++i)
0628     {
0629       // m_hist[i]->SetLineColor(GetFeeColor(i - j * 4));
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       // m_fit[i]->SetLineColor(GetFeeColor(i - j * 4));
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       // histogram for half entry chips. Not used for now
0666       // m_hist_half[i]->Draw("same");
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       // Find chip with highest total hits for this pid/fee across all channels
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         // Sum hits across all channels for this chip
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         // Sum hits across all channels for this chip
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)  // if max_count is less than 50(masked ladder but
0792                             // somethimes it has few hits), set bco_peak as -1
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   // Canvas
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         // NOLINTNEXTLINE(bugprone-integer-division)
0870         ((i % 4 + 0.0) / 4.0 * 0.9) + 0.0, ((3.0 - i / 4) / 4.0 * 0.9) + 0.1,
0871         // NOLINTNEXTLINE(bugprone-integer-division)
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);  // transparent
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       // float min_bin = (m_streaming) ? -127.5 : -0.5;
0900       float min_bin = -0.5;
0901       float max_bin = 127.5;
0902       // int nbins = (m_streaming) ? 256 : 128;
0903       int nbins = 128;
0904       bco_hist[h] = new TH1D(              //
0905           htitle.c_str(), htitle.c_str(),  //
0906           nbins, min_bin, max_bin          //
0907                                            // 128, -0.5, 127.5                //
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     //  for (InttNameSpace::RawData_s raw = raw_begin; raw <= raw_end; ++raw)
0927     //  {
0928     //    int h = (raw.felix_server) * 14 + raw.felix_channel;
0929     //    bco_hist[h]->GetYaxis()->SetRangeUser(0.1, 10 * max);
0930     //  }
0931   }
0932 
0933   // Legend
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);  // transparent
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   // Caption
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);  // transparent
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;  // To store fee -> fc mappings
1011 
1012   // Iterate through the bco_hist array
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       // Add fc to the corresponding fee in the map
1020       maskedLadders[sev].push_back(fee);
1021     }
1022   }
1023 
1024   // Now, prepare the text to add to the canvas
1025   std::ostringstream maskedText;
1026   maskedText << "Masked Ladders: ";
1027 
1028   // Iterate through the map and create the output text
1029   for (const auto &entry : maskedLadders)
1030   {
1031     maskedText << "INTT " << entry.first << "(FC ";  // Fee numbering starts at 1
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 << ",";  // Add commas between FC values
1038       }
1039     }
1040     maskedText << ") ";
1041   }
1042 
1043   // Print or draw the text on the canvas
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;  // Global middle value is 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   // Make hist
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");  // range, no-draw, log likelihood
1202   }
1203   else
1204   {
1205     fit_hist->Fit(fit, "QR");  // range, no-draw, log likelihood, quiet
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;  // normalize by sensor length
1217   if (ofl.layer < 5)
1218   {
1219     hitrate /= (10.005 / 7.4994);  // Inner = 7.4994, Outer = 10.005
1220   }
1221 
1222   // InttSurveyMap::val_t transform;
1223   // if (m_survey.GetStripTransform(ofl, transform))
1224   // {
1225   //   std::cout << PHWHERE << "\n"
1226   //             << "InttSurveyMap::GetStripTransform failed for\n"
1227   //             << ofl
1228   //             << std::endl;
1229   //   return 1;
1230   // }
1231   // Eigen::Vector3d v = transform.translation() - m_vertex;
1232   // Eigen::Vector3d n{transform.linear()(0, 1), transform.linear()(1, 1),
1233   // transform.linear()(2, 1)}; hitrate *= v.squaredNorm(); hitrate /= (-1.0 *
1234   // n.dot(v) / v.norm());
1235   return 0;
1236 }
1237 
1238 int InttCalib::GetIndex(InttNameSpace::RawData_s const &raw,
1239                         InttNameSpace::Offline_s const & /*ofl*/)
1240 {
1241   // int index = 0;
1242   // index += (raw.felix_server) * 4;
1243   // index += (ofl.layer < 5) ? 0 : 2; // +2 for outer
1244   // index += (ofl.ladder_z % 2) ? 0 : 1; // +1 for type B
1245   // return index;
1246   return raw.felix_server;
1247 }
1248 
1249 int InttCalib::GetFeeIndex(InttNameSpace::RawData_s const &raw,
1250                            InttNameSpace::Offline_s const & /*ofl*/)
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   //  int count = 0;
1278   for (int i : data)
1279   {
1280     if (i == -1)
1281     {
1282       continue;  // do not include maksed ladder for std calculation
1283     }
1284     sumSquaredDiffs += (i - mean) * (i - mean);
1285     //    count++;
1286   }
1287   double stddev = std::sqrt(sumSquaredDiffs /
1288                             static_cast<double>(data.size() - n_masked_ladder));
1289   // return stddev;
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:  // 0
1310     break;
1311   }
1312   return kBlack;
1313 }