Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-12-17 09:21:18

0001 // module definitions
0002 #include "CaloStatusMapper.h"
0003 
0004 // calo base
0005 #include <calobase/TowerInfo.h>
0006 #include <calobase/TowerInfoContainer.h>
0007 
0008 // calo trigger
0009 #include <calotrigger/TriggerAnalyzer.h>
0010 
0011 // f4a includes
0012 #include <fun4all/Fun4AllReturnCodes.h>
0013 #include <fun4all/Fun4AllHistoManager.h>
0014 
0015 // phool includes
0016 #include <phool/getClass.h>
0017 #include <phool/phool.h>
0018 #include <phool/PHCompositeNode.h>
0019 
0020 // qa utilities
0021 #include <qautils/QAHistManagerDef.h>
0022 
0023 // root includes
0024 #include <TH1.h>
0025 #include <TH2.h>
0026 #include <TStyle.h>
0027 
0028 // c++ includes
0029 #include <cassert>
0030 #include <cstddef>
0031 #include <iostream>
0032 
0033 
0034 
0035 // ctor/dtor ==================================================================
0036 
0037 // ----------------------------------------------------------------------------
0038 //! Default module constructor
0039 // ----------------------------------------------------------------------------
0040 CaloStatusMapper::CaloStatusMapper(const std::string& modulename, const bool debug)
0041   : SubsysReco(modulename)
0042 {
0043 
0044   // print debug message
0045   if (debug && (Verbosity() > 1))
0046   {
0047     std::cout << "CaloStatusMapper::CaloStatusMapper(std::string&, bool) Calling ctor" << std::endl;
0048   }
0049 
0050   // make sure node vector is empty
0051   m_inNodes.clear();
0052 
0053 }  // end ctor(std::string&, bool)
0054 
0055 
0056 
0057 // ----------------------------------------------------------------------------
0058 //! Module constructor accepting a configuration
0059 // ----------------------------------------------------------------------------
0060 CaloStatusMapper::CaloStatusMapper(const Config& config)
0061   : SubsysReco(config.moduleName)
0062   , m_config(config)
0063 {
0064 
0065   // print debug message
0066   if (m_config.debug && (Verbosity() > 1))
0067   {
0068     std::cout << "CaloStatusMapper::CaloStatusMapper(Config&) Calling ctor" << std::endl;
0069   }
0070 
0071 }  // end ctor(Config&)
0072 
0073 
0074 
0075 // ----------------------------------------------------------------------------
0076 //! Module destructor
0077 // ----------------------------------------------------------------------------
0078 CaloStatusMapper::~CaloStatusMapper()
0079 {
0080 
0081   // print debug message
0082   if (m_config.debug && (Verbosity() > 1))
0083   {
0084     std::cout << "CaloStatusMapper::~CaloStatusMapper() Calling dtor" << std::endl;
0085   }
0086   delete m_analyzer;
0087 
0088 }  // end dtor
0089 
0090 
0091 
0092 // fun4all methods ============================================================
0093 
0094 // ----------------------------------------------------------------------------
0095 //! Initialize module
0096 // ----------------------------------------------------------------------------
0097 int CaloStatusMapper::Init(PHCompositeNode* /*topNode*/)
0098 {
0099 
0100   if (m_config.debug)
0101   {
0102     std::cout << "CaloStatusMapper::Init(PHCompositeNode*) Initializing" << std::endl;
0103   }
0104 
0105   // initialize trigger analyzer
0106   delete m_analyzer;
0107   m_analyzer = new TriggerAnalyzer();
0108 
0109   // initialize manager/histograms
0110   InitHistManager();
0111   BuildHistograms();
0112 
0113   // make sure event no. is set to 0
0114   m_nEvent = 0;
0115   return Fun4AllReturnCodes::EVENT_OK;
0116 
0117 }  // end 'Init(PHCompositeNode*)'
0118 
0119 
0120 
0121 // ----------------------------------------------------------------------------
0122 //! Grab inputs and fills histograms
0123 // ----------------------------------------------------------------------------
0124 int CaloStatusMapper::process_event(PHCompositeNode* topNode)
0125 {
0126 
0127   if (m_config.debug)
0128   {
0129     std::cout << "CaloStatusMapper::process_event(PHCompositeNode* topNode) Processing Event" << std::endl;
0130   }
0131 
0132   // if needed, check if selected trigger fired
0133   if (m_config.doTrgSelect)
0134   {
0135     m_analyzer->decodeTriggers(topNode);
0136     bool hasTrigger = JetQADefs::DidTriggerFire(m_config.trgToSelect, m_analyzer);
0137     if (!hasTrigger)
0138     {
0139       return Fun4AllReturnCodes::EVENT_OK;
0140     }
0141   }
0142 
0143   // grab input nodes
0144   GrabNodes(topNode);
0145 
0146   float sumCaloE = 0;
0147 
0148   // loop over input nodes
0149   for (size_t iNode = 0; iNode < m_inNodes.size(); ++iNode)
0150   {
0151 
0152     // grab node name & make status base
0153     const std::string nodeName = m_config.inNodeNames[iNode].first;
0154     const std::string statBase = MakeBaseName("Status", nodeName);
0155     const std::string energyBase = MakeBaseName("TowerE", nodeName);
0156 
0157     float totalE = 0;
0158 
0159     // loop over towers
0160     TowerInfoContainer* towers = m_inNodes[iNode];
0161     for (size_t iTower = 0; iTower < towers->size(); ++iTower)
0162     {
0163 
0164       // grab eta, phi indices
0165       const int32_t key = towers->encode_key(iTower);
0166       const int32_t iEta = towers->getTowerEtaBin(key);
0167       const int32_t iPhi = towers->getTowerPhiBin(key);
0168 
0169       // get status
0170       auto *const tower = towers->get_tower_at_channel(iTower);
0171       const auto status = CaloStatusMapperDefs::GetTowerStatus(tower);
0172       if (status == CaloStatusMapperDefs::Stat::Unknown)
0173       {
0174         std::cout << PHWHERE << ": Warning! Tower has an unknown status!\n"
0175                   << "  channel = " << iTower << ", key = " << key << "\n"
0176                   << "  node = " << m_config.inNodeNames[iNode].first
0177                   << std::endl; 
0178         continue;
0179       } 
0180 
0181       // make base eta/phi hist name
0182       const std::string statLabel = CaloStatusMapperDefs::StatLabels().at(status);
0183 
0184       // if not doing optional histograms, skip these status
0185       if (!m_config.doOptHist && CaloStatusMapperDefs::IsStatusSkippable(statLabel))
0186       {
0187         continue;
0188       }
0189 
0190       const std::string perEtaBase = MakeBaseName("NPerEta", nodeName, statLabel);
0191       const std::string perPhiBase = MakeBaseName("NPerPhi", nodeName, statLabel);
0192       const std::string phiEtaBase = MakeBaseName("PhiVsEta", nodeName, statLabel);
0193 
0194       // fill histograms accordingly
0195       m_hists[statBase]->Fill(status);
0196       m_hists[statBase]->AddBinContent(m_totalBin[statBase], 1.0);
0197       m_hists[perEtaBase]->Fill(iEta);
0198       m_hists[perPhiBase]->Fill(iPhi);
0199       m_hists[phiEtaBase]->Fill(iEta, iPhi);
0200 
0201       float towerE = tower->get_energy();
0202       totalE += towerE;
0203     }  // end tower loop
0204 
0205     // fill total tower energy
0206     m_hists[energyBase]->Fill(totalE);
0207 
0208     sumCaloE += totalE;
0209   }  // end node loop
0210 
0211   // fill all calo total energy plot
0212   allCaloEnergy -> Fill(sumCaloE);
0213 
0214   // increment event no. and return
0215   ++m_nEvent;
0216   return Fun4AllReturnCodes::EVENT_OK;
0217 
0218 }  // end 'process_event(PHCompositeNode*)'
0219 
0220 
0221 
0222 // ----------------------------------------------------------------------------
0223 //! Run final calculations
0224 // ----------------------------------------------------------------------------
0225 int CaloStatusMapper::End(PHCompositeNode* /*topNode*/)
0226 {
0227 
0228   if (m_config.debug)
0229   {
0230     std::cout << "CaloStatusMapper::End(PHCompositeNode* topNode) This is the End..." << std::endl;
0231   }
0232 
0233   // normalize avg. status no.s
0234   if (m_config.doNorm)
0235   {
0236     for (const auto& nodeName : m_config.inNodeNames)
0237     {
0238       const std::string statBase = MakeBaseName("Status", nodeName.first);
0239       m_hists[statBase]->Scale(1. / (double) m_nEvent);
0240     }
0241   }
0242 
0243   // register hists and exit
0244   for (const auto& hist : m_hists) {
0245     m_manager->registerHisto(hist.second);
0246   }
0247   m_manager->registerHisto(allCaloEnergy);
0248   return Fun4AllReturnCodes::EVENT_OK;
0249 
0250 }  // end 'End(PHCompositeNode*)'
0251 
0252 
0253 
0254 // private methods ============================================================
0255 
0256 // ----------------------------------------------------------------------------
0257 //! Initialize histogram manager
0258 // ----------------------------------------------------------------------------
0259 void CaloStatusMapper::InitHistManager()
0260 {
0261 
0262   // print debug message
0263   if (m_config.debug && (Verbosity() > 0))
0264   {
0265     std::cout << "CaloStatusMapper::InitHistManager() Initializing histogram manager" << std::endl;
0266   }
0267   
0268   gStyle->SetOptTitle(0);
0269   m_manager = QAHistManagerDef::getHistoManager();
0270   if (!m_manager)
0271   {
0272     std::cerr << PHWHERE << ": PANIC! Couldn't grab histogram manager!" << std::endl;
0273     assert(m_manager);
0274   }
0275   return;
0276 
0277 }  // end 'InitHistManager()'
0278 
0279 
0280 
0281 // ----------------------------------------------------------------------------
0282 //! Build histograms
0283 // ----------------------------------------------------------------------------
0284 void CaloStatusMapper::BuildHistograms()
0285 {
0286 
0287   // print debug message
0288   if (m_config.debug && (Verbosity() > 0))
0289   {
0290     std::cout << "CaloStatusMapper::BuildHistograms() Creating histograms" << std::endl;
0291   }
0292 
0293   // instantiate histogram definitions
0294   const CaloStatusMapperDefs::EMCalHistDef emHistDef;
0295   const CaloStatusMapperDefs::HCalHistDef  hcHistDef;
0296 
0297   // make total calo energy hist
0298   const std::string caloEBase = MakeBaseName("TowerE", "towerinfo_calib_allcalo");
0299   const std::string caloEName = JetQADefs::MakeQAHistName(caloEBase, m_config.moduleName, m_config.histTag);
0300   allCaloEnergy = new TH1F(caloEName.data(), "All Calo Tower Energy Sum; Tower E [GeV]", 320, -200, 3000);
0301 
0302   // loop over input node names
0303   for (const auto& nodeName : m_config.inNodeNames)
0304   {
0305 
0306     // make status hist name
0307     const std::string statBase = MakeBaseName("Status", nodeName.first);
0308     const std::string statName = JetQADefs::MakeQAHistName(statBase, m_config.moduleName, m_config.histTag);
0309 
0310     // create status hist
0311     //   - n.b. calo type doesn't matter here
0312     m_hists[statBase] = emHistDef.MakeStatus1D(statName);
0313 
0314     // make tower energy hist name
0315     const std::string energyBase = MakeBaseName("TowerE", nodeName.first);
0316     const std::string energyName = JetQADefs::MakeQAHistName(energyBase, m_config.moduleName, m_config.histTag);
0317 
0318     // create energy hist
0319     switch (nodeName.second)
0320     {
0321       case CaloStatusMapperDefs::Calo::HCal:
0322         m_hists[energyBase] = hcHistDef.MakeEnergy1D(energyName);
0323         break;
0324       case CaloStatusMapperDefs::Calo::EMCal:
0325           [[fallthrough]];
0326       default:
0327         m_hists[energyBase] = emHistDef.MakeEnergy1D(energyName);
0328         break;
0329     }
0330 
0331     // loop over status labels
0332     for (const auto& statLabel : CaloStatusMapperDefs::StatLabels())
0333     {
0334 
0335       // set relevant bin label for status histogram
0336       m_hists[statBase]->GetXaxis()->SetBinLabel(statLabel.first + 1, statLabel.second.data());
0337 
0338       // if not doing optional histograms, skip these status
0339       if (!m_config.doOptHist && CaloStatusMapperDefs::IsStatusSkippable(statLabel.second))
0340       {
0341         continue;
0342       }
0343 
0344       // make base eta/phi hist name
0345       const std::string perEtaBase = MakeBaseName("NPerEta", nodeName.first, statLabel.second);
0346       const std::string perPhiBase = MakeBaseName("NPerPhi", nodeName.first, statLabel.second);
0347       const std::string phiEtaBase = MakeBaseName("PhiVsEta", nodeName.first, statLabel.second);
0348 
0349       // make full eta/phi hist name
0350       const std::string namePerEta = JetQADefs::MakeQAHistName(perEtaBase, m_config.moduleName, m_config.histTag);
0351       const std::string namePerPhi = JetQADefs::MakeQAHistName(perPhiBase, m_config.moduleName, m_config.histTag);
0352       const std::string namePhiEta = JetQADefs::MakeQAHistName(phiEtaBase, m_config.moduleName, m_config.histTag);
0353 
0354       // make eta/phi hists
0355       switch (nodeName.second)
0356       {
0357         case CaloStatusMapperDefs::Calo::HCal:
0358           m_hists[perEtaBase] = hcHistDef.MakeEta1D(namePerEta);
0359           m_hists[perPhiBase] = hcHistDef.MakePhi1D(namePerPhi);
0360           m_hists[phiEtaBase] = hcHistDef.MakePhiEta2D(namePhiEta);
0361           break;
0362         case CaloStatusMapperDefs::Calo::EMCal:
0363           [[fallthrough]];
0364         default:
0365           m_hists[perEtaBase] = emHistDef.MakeEta1D(namePerEta);
0366           m_hists[perPhiBase] = emHistDef.MakePhi1D(namePerPhi);
0367           m_hists[phiEtaBase] = emHistDef.MakePhiEta2D(namePhiEta);
0368           break;
0369       }
0370 
0371     }  // end status loop
0372     
0373     int totalBin = m_hists[statBase]->GetNbinsX();
0374     m_hists[statBase]->GetXaxis()->SetBinLabel(totalBin, "N_{Total}");
0375     m_totalBin[statBase] = totalBin;
0376   }  // end node loop
0377   return;
0378 
0379 }  // end 'BuildHistograms()'
0380 
0381 
0382 
0383 // ----------------------------------------------------------------------------
0384 //! Grab input nodes
0385 // ----------------------------------------------------------------------------
0386 void CaloStatusMapper::GrabNodes(PHCompositeNode* topNode)
0387 {
0388 
0389   // print debug message
0390   if (m_config.debug && (Verbosity() > 0))
0391   {
0392     std::cout << "CaloStatusMapper::GrabNodes(PHCompositeNode*) Grabbing input nodes" << std::endl;
0393   }
0394 
0395   // make sure node vector is empty
0396   m_inNodes.clear();
0397 
0398   // loop over nodes to grab
0399   for (const auto& inNodeName : m_config.inNodeNames)
0400   {
0401     m_inNodes.push_back(
0402       findNode::getClass<TowerInfoContainer>(topNode, inNodeName.first)
0403     );
0404     if (!m_inNodes.back())
0405     {
0406       std::cerr << PHWHERE << ":" << " PANIC! Not able to grab node " << inNodeName.first << "! Aborting!" << std::endl;
0407       assert(m_inNodes.back());
0408     }
0409   }  // end input node name loop
0410   return;
0411 
0412 }  // end 'GrabNodes(PHCompositeNode*)'
0413 
0414 
0415 
0416 // ----------------------------------------------------------------------------
0417 //! Make base histogram name
0418 // ----------------------------------------------------------------------------
0419 std::string CaloStatusMapper::MakeBaseName(
0420   const std::string& base,
0421   const std::string& node,
0422   const std::string& stat) const
0423 {
0424 
0425   if (m_config.debug && (Verbosity() > 2))
0426   {
0427     std::cout << "CaloStatusMapper::MakeBaseName(std::string& x 3) Making base histogram name" << std::endl;
0428   }
0429 
0430   std::string name = base + "_" + node;
0431   if (!stat.empty())
0432   {
0433     name.insert(0, stat + "_");
0434   }
0435   return name;
0436 
0437 }  // end 'MakeBaseName(std::string& x 3)'
0438 
0439 // end ========================================================================