Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:24:05

0001 #ifndef MACRO_JETQA_C
0002 #define MACRO_JETQA_C
0003 
0004 #include <QA.C>
0005 
0006 #include <jetqa/CaloStatusMapper.h>
0007 #include <jetqa/ConstituentsinJets.h>
0008 #include <jetqa/DijetQA.h>
0009 #include <jetqa/EMClusterKinematics.h>
0010 #include <jetqa/JetKinematicCheck.h>
0011 #include <jetqa/JetQADefs.h>
0012 #include <jetqa/JetSeedCount.h>
0013 #include <jetqa/RhosinEvent.h>
0014 #include <jetqa/StructureinJets.h>
0015 #include <jetqa/TrksInJetQA.h>
0016 #include <jetqa/UEvsEtaCentrality.h>
0017 
0018 #include <fun4all/Fun4AllServer.h>
0019 
0020 #include <map>
0021 #include <optional>
0022 #include <string>
0023 #include <utility>
0024 #include <vector>
0025 
0026 R__LOAD_LIBRARY(libjetqa.so)
0027 
0028 // ----------------------------------------------------------------------------
0029 //! General options for jet QA
0030 // ----------------------------------------------------------------------------
0031 namespace Enable
0032 {
0033   int JETQA_VERBOSITY = 0;  ///< verbosity of jet qa
0034 }
0035 
0036 // ----------------------------------------------------------------------------
0037 //! Namespace to collect various enums, default arguments, etc.
0038 // ----------------------------------------------------------------------------
0039 namespace JetQA
0040 {
0041 
0042   // flags --------------------------------------------------------------------
0043 
0044   ///! Set to true if input jets utilize tracks (e.g. via particle flow)
0045   bool HasTracks = false;
0046 
0047   ///! Set to true if input jets utilize calorimeters(e.g. via particle flow)
0048   bool HasCalos = false;
0049 
0050   ///! Set to true if jets have background subtracted
0051   ///! (e.g. HIJetReco.C output)
0052   bool UseBkgdSub = false;
0053 
0054   ///! Set to true to generate histograms for no trigger selection
0055   bool DoInclusive = true;
0056 
0057   ///! Set to true to generate histograms for a specified set of triggers
0058   bool DoTriggered = true;
0059 
0060   ///! Set to true to use pp-specific options (otherwise assumes AuAU)
0061   bool DoPP = false;
0062 
0063   ///! Set to true to restrict minimum jet pt to trigger threshold
0064   bool RestrictPtToTrig = false;
0065 
0066   ///! Set to true to restrict jet eta acceptance by resolution parameter
0067   bool RestrictEtaByR = true;
0068 
0069   // enums --------------------------------------------------------------------
0070 
0071   ///! enumerates possible jet types
0072   enum Type
0073   {
0074     AntiKtTowerSubR02,
0075     AntiKtTowerSubR03,
0076     AntiKtTowerSubR04,
0077     AntiKtTowerSubR05,
0078     AntiKtTowerR02,
0079     AntiKtTowerR03,
0080     AntiKtTowerR04,
0081     AntiKtTowerR05,
0082     AntiKtTrackR02,
0083     AntiKtTrackR03,
0084     AntiKtTrackR04,
0085     AntiKtTrackR05
0086   };
0087 
0088   ///! enumerates possible jet sources
0089   enum class Source : uint32_t
0090   {
0091     Calos = 0,
0092     Tracks = 1
0093   };
0094 
0095   // constants ----------------------------------------------------------------
0096 
0097   ///! Min jet pt in GeV/c
0098   double MinJetPt = 6.;
0099 
0100   ///! Max jet pt in GeV/c
0101   double MaxJetPt = 100.;
0102 
0103   ///! Min eta acceptance
0104   double MinAcceptEta = -1.1;
0105 
0106   ///! Max eta acceptance
0107   double MaxAcceptEta = 1.1;
0108 
0109   // maps ---------------------------------------------------------------------
0110 
0111   ///! Map from trigger to histogram tag
0112   std::map<uint32_t, std::string> GL1Tag = {
0113       {JetQADefs::GL1::Clock, "clock"},
0114       {JetQADefs::GL1::ZDCS, "zdcs"},
0115       {JetQADefs::GL1::ZDCN, "zdcn"},
0116       {JetQADefs::GL1::ZDCNS, "zdcns"},
0117       {JetQADefs::GL1::HCalSingle, "hcalsingle"},
0118       {JetQADefs::GL1::MBDS, "mbds"},
0119       {JetQADefs::GL1::MBDN, "mbdn"},
0120       {JetQADefs::GL1::MBDNS1, "mbdns1"},
0121       {JetQADefs::GL1::MBDNS2, "mbdns2"},
0122       {JetQADefs::GL1::MBDNSVtx10, "mbdnsvtx10"},
0123       {JetQADefs::GL1::MBDNSVtx30, "mbdnsvtx30"},
0124       {JetQADefs::GL1::MBDNSVtx60, "mbdnsvtx60"},
0125       {JetQADefs::GL1::MBDNSHCalSingle, "mbdnshcalsingle"},
0126       {JetQADefs::GL1::MBDNSJet1, "mbdnsjet1"},
0127       {JetQADefs::GL1::MBDNSJet2, "mbdnsjet2"},
0128       {JetQADefs::GL1::MBDNSJet3, "mbdnsjet3"},
0129       {JetQADefs::GL1::MBDNSJet4, "mbdnsjet4"},
0130       {JetQADefs::GL1::Jet1, "jet1"},
0131       {JetQADefs::GL1::Jet2, "jet2"},
0132       {JetQADefs::GL1::Jet3, "jet3"},
0133       {JetQADefs::GL1::Jet4, "jet4"},
0134       {JetQADefs::GL1::MBDNSPhoton1, "mbdnsphoton1"},
0135       {JetQADefs::GL1::MBDNSPhoton2, "mbdnsphoton2"},
0136       {JetQADefs::GL1::MBDNSPhoton3, "mbdnsphoton3"},
0137       {JetQADefs::GL1::MBDNSPhoton4, "mbdnsphoton4"},
0138       {JetQADefs::GL1::Photon1, "photon1"},
0139       {JetQADefs::GL1::Photon2, "photon2"},
0140       {JetQADefs::GL1::Photon3, "photon3"},
0141       {JetQADefs::GL1::Photon4, "photon4"},
0142       {JetQADefs::GL1::MBDNS2Vtx10, "mbdns2vtx10"},
0143       {JetQADefs::GL1::MBDNS2Vtx30, "mbdns2vtx30"},
0144       {JetQADefs::GL1::MBDNS2Vtx60, "mbdns2vtx60"},
0145       {JetQADefs::GL1::MBDNS2Vtx150, "mbdns2vtx150"},
0146       {JetQADefs::GL1::MBDNS2Photon6Vtx10, "mbdns2photon6vtx10"},
0147       {JetQADefs::GL1::MBDNS2Photon8Vtx10, "mbdns2photon8vtx10"},
0148       {JetQADefs::GL1::MBDNS2Photon10Vtx10, "mbdns2photon10vtx10"},
0149       {JetQADefs::GL1::MBDNS2Photon12Vtx10, "mbdns2photon12vtx10"},
0150       {JetQADefs::GL1::MBDNS2Photon6Vtx150, "mbdns2photon6vtx150"},
0151       {JetQADefs::GL1::MBDNS2Photon8Vtx150, "mbdns2photon8vtx150"},
0152       {JetQADefs::GL1::MBDNS2Photon10Vtx150, "mbdns2photon10vtx150"},
0153       {JetQADefs::GL1::MBDNS2Photon12Vtx150, "mbdns2photon12vtx150"},
0154       {JetQADefs::GL1::Inclusive, "inclusive"}};
0155 
0156   ///! Map from jet type to input node
0157   std::map<uint32_t, std::string> JetInput = {
0158       {Type::AntiKtTowerSubR02, "AntiKt_Tower_r02_Sub1"},
0159       {Type::AntiKtTowerSubR03, "AntiKt_Tower_r03_Sub1"},
0160       {Type::AntiKtTowerSubR04, "AntiKt_Tower_r04_Sub1"},
0161       {Type::AntiKtTowerSubR05, "AntiKt_Tower_r05_Sub1"},
0162       {Type::AntiKtTowerR02, "AntiKt_Tower_r02"},
0163       {Type::AntiKtTowerR03, "AntiKt_Tower_r03"},
0164       {Type::AntiKtTowerR04, "AntiKt_Tower_r04"},
0165       {Type::AntiKtTowerR05, "AntiKt_Tower_r05"},
0166       {Type::AntiKtTrackR02, "AntiKt_Track_r02"},
0167       {Type::AntiKtTrackR03, "AntiKt_Track_r03"},
0168       {Type::AntiKtTrackR04, "AntiKt_Track_r04"},
0169       {Type::AntiKtTrackR05, "AntiKt_Track_r05"}};
0170 
0171   ///! Map from jet type to histogram tag
0172   std::map<uint32_t, std::string> JetTag = {
0173       {Type::AntiKtTowerSubR02, "towersub1_antikt_r02"},
0174       {Type::AntiKtTowerSubR03, "towersub1_antikt_r03"},
0175       {Type::AntiKtTowerSubR04, "towersub1_antikt_r04"},
0176       {Type::AntiKtTowerSubR05, "towersub1_antikt_r05"},
0177       {Type::AntiKtTowerR02, "tower_antikt_r02"},
0178       {Type::AntiKtTowerR03, "tower_antikt_r03"},
0179       {Type::AntiKtTowerR04, "tower_antikt_r04"},
0180       {Type::AntiKtTowerR05, "tower_antikt_r05"},
0181       {Type::AntiKtTrackR02, "track_antikt_r02"},
0182       {Type::AntiKtTrackR03, "track_antikt_r03"},
0183       {Type::AntiKtTrackR04, "track_antikt_r04"},
0184       {Type::AntiKtTrackR05, "track_antikt_r05"}};
0185 
0186   ///! Map from jet type to resolution parameter
0187   std::map<uint32_t, double> JetRes = {
0188       {Type::AntiKtTowerSubR02, 0.2},
0189       {Type::AntiKtTowerSubR03, 0.3},
0190       {Type::AntiKtTowerSubR04, 0.4},
0191       {Type::AntiKtTowerSubR05, 0.5},
0192       {Type::AntiKtTowerR02, 0.2},
0193       {Type::AntiKtTowerR03, 0.3},
0194       {Type::AntiKtTowerR04, 0.4},
0195       {Type::AntiKtTowerR05, 0.5},
0196       {Type::AntiKtTrackR02, 0.2},
0197       {Type::AntiKtTrackR03, 0.3},
0198       {Type::AntiKtTrackR04, 0.4},
0199       {Type::AntiKtTrackR05, 0.5}};
0200 
0201   // methods ------------------------------------------------------------------
0202 
0203   // --------------------------------------------------------------------------
0204   //! Get trigger tag
0205   // --------------------------------------------------------------------------
0206   /*! If a trigger index is provided (i.e. a trigger is being selected),
0207    *  function returns the correpsonding tag. Otherwise (i.e. NO trigger
0208    *  is being selected), returns the inclusive tag.
0209    */
0210   inline std::string GetTriggerTag(std::optional<uint32_t> trg = std::nullopt)
0211   {
0212     std::string tag;
0213     if (trg.has_value())
0214     {
0215       tag.append("_" + GL1Tag[trg.value()]);
0216     }
0217     else
0218     {
0219       tag.append("_" + GL1Tag[JetQADefs::GL1::Inclusive]);
0220     }
0221     return tag;
0222 
0223   }  // end 'GetTriggerTag(std::optional<uint32_t>)'
0224 
0225   // --------------------------------------------------------------------------
0226   //! Get minimum jet pt based on which trigger fired
0227   // --------------------------------------------------------------------------
0228   // FIXME it might be prudent to allow for thresholds to change vs. run
0229   //   number... Before run 46038, the Jet1, 2 thresholds were different
0230   inline double GetMinJetPt(const uint32_t trg = JetQADefs::GL1::MBDNSJet1)
0231   {
0232     // by defult, set min to global constant
0233     double ptJetMin = MinJetPt;
0234 
0235     // if restricting pt to trigger threhsold, pick out relevant threshold
0236     if (RestrictPtToTrig)
0237     {
0238       switch (trg)
0239       {
0240       // Jet4 threshold
0241       case JetQADefs::GL1::MBDNSJet4:
0242         [[fallthrough]];
0243       case JetQADefs::GL1::Jet4:
0244         ptJetMin = 11.;
0245         break;
0246 
0247       // Jet3 threshold
0248       case JetQADefs::GL1::MBDNSJet3:
0249         [[fallthrough]];
0250       case JetQADefs::GL1::Jet3:
0251         ptJetMin = 10.;
0252         break;
0253 
0254       // Jet2 threshold
0255       case JetQADefs::GL1::MBDNSJet2:
0256         [[fallthrough]];
0257       case JetQADefs::GL1::Jet2:
0258         ptJetMin = 9.;
0259         break;
0260 
0261       // Jet1 threshold (default value)
0262       case JetQADefs::GL1::MBDNSJet1:
0263         [[fallthrough]];
0264       case JetQADefs::GL1::Jet1:
0265         [[fallthrough]];
0266       default:
0267         ptJetMin = 6.;
0268         break;
0269       }
0270     }
0271     return ptJetMin;
0272 
0273   }  // end 'GetMinJetPt(uint32_t)'
0274 
0275   // --------------------------------------------------------------------------
0276   //! Get default jet pt range
0277   // --------------------------------------------------------------------------
0278   inline std::pair<double, double> GetJetPtRange(std::optional<uint32_t> trg = std::nullopt)
0279   {
0280     std::pair<double, double> ptJetRange;
0281     if (trg.has_value())
0282     {
0283       ptJetRange = {GetMinJetPt(trg.value()), MaxJetPt};
0284     }
0285     else
0286     {
0287       ptJetRange = {GetMinJetPt(), MaxJetPt};
0288     }
0289     return ptJetRange;
0290 
0291   }  // end 'GetJetPtRange(std::optional<uint32_t>)'
0292 
0293   // --------------------------------------------------------------------------
0294   //! Get default jet eta range
0295   // --------------------------------------------------------------------------
0296   inline std::pair<double, double> GetJetEtaRange(const double res = 0.)
0297   {
0298     // determine relevant min/max
0299     const double etaMin = RestrictEtaByR ? MinAcceptEta + res : MinAcceptEta;
0300     const double etaMax = RestrictEtaByR ? MaxAcceptEta - res : MaxAcceptEta;
0301 
0302     // return range
0303     std::pair<double, double> etaJetRange = {etaMin, etaMax};
0304     return etaJetRange;
0305 
0306   }  // end 'GetJetEtaRange(double)'
0307 
0308   // --------------------------------------------------------------------------
0309   //! Get default list of triggers to analyze
0310   // --------------------------------------------------------------------------
0311   inline std::vector<uint32_t> GetDefaultTriggerList()
0312   {
0313     // default jets for pp
0314     std::vector<uint32_t> vecDefaultTrigsPP = {
0315         JetQADefs::GL1::MBDNS1,
0316         JetQADefs::GL1::MBDNSJet1,
0317         JetQADefs::GL1::MBDNSJet2,
0318         JetQADefs::GL1::MBDNSJet3,
0319         JetQADefs::GL1::MBDNSJet4,
0320         JetQADefs::GL1::Jet1,
0321         JetQADefs::GL1::Jet2,
0322         JetQADefs::GL1::Jet3,
0323         JetQADefs::GL1::Jet4};
0324 
0325     // default triggers for 2025 AuAu
0326     std::vector<uint32_t> vecDefaultTrigsAA = {
0327         JetQADefs::GL1::MBDNS2Vtx10,
0328         JetQADefs::GL1::MBDNS2Vtx150};
0329 
0330     if (JetQA::DoPP)
0331     {
0332       return vecDefaultTrigsPP;
0333     }
0334 
0335     return vecDefaultTrigsAA;
0336 
0337   }  // end 'GetDefaultTriggerList()'
0338 
0339   // --------------------------------------------------------------------------
0340   //! Get list of jets to analyze
0341   // --------------------------------------------------------------------------
0342   inline std::vector<uint32_t> GetJetsToQA(Source source)
0343   {
0344     std::vector<uint32_t> vecJetsToQA;
0345     switch (source)
0346     {
0347     case Source::Calos:
0348       if (UseBkgdSub)
0349       {
0350         vecJetsToQA.insert(vecJetsToQA.end(),
0351                            {Type::AntiKtTowerSubR02,
0352                             Type::AntiKtTowerSubR03,
0353                             Type::AntiKtTowerSubR04,
0354                             Type::AntiKtTowerSubR05});
0355       }
0356       else
0357       {
0358         vecJetsToQA.insert(vecJetsToQA.end(),
0359                            {Type::AntiKtTowerR02,
0360                             Type::AntiKtTowerR03,
0361                             Type::AntiKtTowerR04,
0362                             Type::AntiKtTowerR05});
0363       }
0364       break;
0365 
0366     case Source::Tracks:
0367       vecJetsToQA.insert(vecJetsToQA.end(),
0368                          {Type::AntiKtTrackR02,
0369                           Type::AntiKtTrackR03,
0370                           Type::AntiKtTrackR04,
0371                           Type::AntiKtTrackR05});
0372       break;
0373     }
0374     return vecJetsToQA;
0375 
0376   }  // end 'GetJetsToQA(Source)'
0377 
0378 }  // namespace JetQA
0379 
0380 // ----------------------------------------------------------------------------
0381 //! Create QA modules for all jets, regardless of constituents
0382 // ----------------------------------------------------------------------------
0383 void CommonJetQA(std::optional<uint32_t> trg = std::nullopt)
0384 {
0385   // set verbosity
0386   int verbosity = std::max(Enable::JETQA_VERBOSITY, Enable::QA_VERBOSITY);
0387   if (verbosity > 1)
0388   {
0389     std::cout << ">>> Entering CommonJetQA() with trg="
0390               << (trg.has_value() ? std::to_string(trg.value()) : "none")
0391               << std::endl;
0392   }
0393 
0394   // grab appropriate trigger tag
0395   std::string trig_tag = JetQA::GetTriggerTag(trg);
0396 
0397   // grab default pt, eta ranges
0398   std::pair<double, double> ptJetRange = JetQA::GetJetPtRange(trg);
0399   std::pair<double, double> etaJetMaxRange = JetQA::GetJetEtaRange();
0400 
0401   // connect to f4a server
0402   Fun4AllServer* se = Fun4AllServer::instance();
0403 
0404   // create modules that are independent of/take multiple R values ------------
0405 
0406   // initialize and register mass, eta, and pt qa module
0407   // for calos if need be
0408   if (JetQA::HasCalos)
0409   {
0410     auto vecCalos = JetQA::GetJetsToQA(JetQA::Source::Calos);
0411     if (!vecCalos.empty())
0412     {
0413       JetKinematicCheck* kinematicQA = new JetKinematicCheck(
0414           "JetKinematicCheck" + trig_tag + (JetQA::UseBkgdSub ? "_towersub1_antikt" : "_tower_antikt"),
0415           JetQA::JetInput[vecCalos[0]],
0416           JetQA::JetInput[vecCalos[1]],
0417           JetQA::JetInput[vecCalos[2]],
0418           JetQA::JetInput[vecCalos[3]]);
0419       kinematicQA->Verbosity(verbosity);
0420       kinematicQA->setHistTag("");
0421       kinematicQA->setRestrictEtaRange(JetQA::RestrictEtaByR);
0422       kinematicQA->setPtRange(ptJetRange.first, ptJetRange.second);
0423       kinematicQA->setEtaRange(etaJetMaxRange.first, etaJetMaxRange.second);
0424       if (trg.has_value())
0425       {
0426         kinematicQA->setTrgToSelect(trg.value());
0427       }
0428       se->registerSubsystem(kinematicQA);
0429     }
0430     else
0431     {
0432       std::cerr << ">>> Warning: trying to register JetKinematicCheck for tower jets, but jet list is empty!"
0433                 << std::endl;
0434     }
0435   }
0436 
0437   // initialize and register mass, eta, and pt qa module
0438   // for tracks if need be
0439   if (JetQA::HasTracks)
0440   {
0441     auto vecTrk = JetQA::GetJetsToQA(JetQA::Source::Tracks);
0442     if (!vecTrk.empty())
0443     {
0444       JetKinematicCheck* kinematicQA_Tracks = new JetKinematicCheck(
0445           "JetKinematicCheck" + trig_tag + "_track_antikt",
0446           JetQA::JetInput[vecTrk[0]],
0447           JetQA::JetInput[vecTrk[1]],
0448           JetQA::JetInput[vecTrk[2]],
0449           JetQA::JetInput[vecTrk[3]]);
0450       kinematicQA_Tracks->Verbosity(verbosity);
0451       kinematicQA_Tracks->setHistTag("");
0452       kinematicQA_Tracks->setRestrictEtaRange(JetQA::RestrictEtaByR);
0453       kinematicQA_Tracks->setPtRange(ptJetRange.first, ptJetRange.second);
0454       kinematicQA_Tracks->setEtaRange(etaJetMaxRange.first, etaJetMaxRange.second);
0455       if (trg.has_value())
0456       {
0457         kinematicQA_Tracks->setTrgToSelect(trg.value());
0458       }
0459       se->registerSubsystem(kinematicQA_Tracks);
0460     }
0461     else
0462     {
0463       std::cerr << ">>> Warning: trying to register JetKinematicCheck for track jets, but jet list is empty!"
0464                 << std::endl;
0465     }
0466   }
0467 
0468   // create modules that take single R values ---------------------------------
0469 
0470   // get relevant jets to QA
0471   std::vector<uint32_t> vecJetsToQA;
0472   if (JetQA::HasCalos)
0473   {
0474     auto vecCalJets = JetQA::GetJetsToQA(JetQA::Source::Calos);
0475     vecJetsToQA.insert(vecJetsToQA.end(), vecCalJets.begin(), vecCalJets.end());
0476   }
0477   if (JetQA::HasTracks)
0478   {
0479     auto vecTrkJets = JetQA::GetJetsToQA(JetQA::Source::Tracks);
0480     vecJetsToQA.insert(vecJetsToQA.end(), vecTrkJets.begin(), vecTrkJets.end());
0481   }
0482 
0483   // loop over resolution parameters
0484   for (uint32_t jet : vecJetsToQA)
0485   {
0486     // get R-dependent eta range
0487     std::pair<double, double> etaJetRange = JetQA::GetJetEtaRange(JetQA::JetRes[jet]);
0488 
0489     // intialize and register dijetQA
0490     DijetQA* dijetQA = new DijetQA(
0491         "DijetQA" + trig_tag + "_" + JetQA::JetTag[jet],
0492         JetQA::JetInput[jet]);
0493     dijetQA->Verbosity(verbosity);
0494     dijetQA->setPtLeadRange(ptJetRange.first, ptJetRange.second);
0495     dijetQA->setPtSubRange(1.0, ptJetRange.second);
0496     dijetQA->setEtaRange(etaJetRange.first, etaJetRange.second);
0497     if (trg.has_value())
0498     {
0499       dijetQA->setTrgToSelect(trg.value());
0500     }
0501     se->registerSubsystem(dijetQA);
0502 
0503   }  // end jet loop
0504   return;
0505 
0506 }  // end 'CommonJetQA(std::optional<uint32_t>)'
0507 
0508 // ----------------------------------------------------------------------------
0509 //! Create QA modules for jets with tracks
0510 // ----------------------------------------------------------------------------
0511 void JetsWithTracksQA(std::optional<uint32_t> trg = std::nullopt)
0512 {
0513   // set verbosity
0514   int verbosity = std::max(Enable::JETQA_VERBOSITY, Enable::QA_VERBOSITY);
0515   if (verbosity > 1)
0516   {
0517     std::cout << ">>> Entering JetsWithTracksQA() with trg="
0518               << (trg.has_value() ? std::to_string(trg.value()) : "none")
0519               << std::endl;
0520   }
0521 
0522   // grab appropriate trigger tag
0523   std::string trig_tag = JetQA::GetTriggerTag(trg);
0524 
0525   // grab default pt, eta ranges
0526   std::pair<double, double> ptJetRange = JetQA::GetJetPtRange(trg);
0527   std::pair<double, double> etaJetRange = JetQA::GetJetEtaRange();
0528 
0529   // get list of jet nodes to analyze
0530   std::vector<uint32_t> vecJetsToQA = JetQA::GetJetsToQA(JetQA::Source::Tracks);
0531 
0532   // connect to f4a server
0533   Fun4AllServer* se = Fun4AllServer::instance();
0534 
0535   // initialize and register event-wise rho check
0536   RhosinEvent* evtRhoQA = new RhosinEvent("EventWiseTrackRho" + trig_tag, "");
0537   evtRhoQA->Verbosity(verbosity);
0538   evtRhoQA->add_area_rho_node("EventRho_AREA");
0539   evtRhoQA->add_mult_rho_node("EventRho_MULT");
0540   if (trg.has_value())
0541   {
0542     evtRhoQA->setTrgToSelect(trg.value());
0543   }
0544   se->registerSubsystem(evtRhoQA);
0545 
0546   // create modules that take single R values ---------------------------------
0547 
0548   // loop over resolution parameters
0549   for (uint32_t jet : vecJetsToQA)
0550   {
0551     // intialize and register sum track vs. jet pt qa module
0552     StructureinJets* jetStructQA = new StructureinJets(
0553         "StructureInJets" + trig_tag + "_" + JetQA::JetTag[jet],
0554         JetQA::JetInput[jet],
0555         "SvtxTrackMap",
0556         "");
0557     jetStructQA->Verbosity(verbosity);
0558     jetStructQA->writeToOutputFile(false);
0559     jetStructQA->setTrkPtCut(0.1);
0560     jetStructQA->setTrkQualityCut(100.0);  // set to be big for now, should refine later
0561     jetStructQA->setTrkNSilCut(4);
0562     jetStructQA->setTrkNTPCCut(25);
0563     jetStructQA->setJetRadius(JetQA::JetRes[jet]);
0564     jetStructQA->setJetPtRange(ptJetRange.first, ptJetRange.second);
0565     jetStructQA->setJetEtaRange(etaJetRange.first, etaJetRange.second);
0566     if (trg.has_value())
0567     {
0568       jetStructQA->setTrgToSelect(trg.value());
0569     }
0570     se->registerSubsystem(jetStructQA);
0571 
0572     // initialize and register track jet qa module
0573     TrksInJetQA* trksInJetQA = new TrksInJetQA("TrksInJet" + trig_tag + "_" + JetQA::JetTag[jet]);
0574     trksInJetQA->SetHistSuffix("");
0575     trksInJetQA->Configure(
0576         {.outMode = TrksInJetQA::OutMode::QA,
0577          .verbose = verbosity,
0578          .doDebug = false,
0579          .doInclusive = false,  // n.b. inclusive case covered by track QA
0580          .doInJet = true,
0581          .doHitQA = false,
0582          .doClustQA = true,
0583          .doTrackQA = true,
0584          .doJetQA = true,
0585          .doSubsysHist = false,
0586          .doOptHist = false,  // turn off optional histograms
0587          .rJet = JetQA::JetRes[jet],
0588          .jetInNode = JetQA::JetInput[jet]});
0589     if (trg.has_value())
0590     {
0591       trksInJetQA->SetTrgToSelect(trg.value());
0592     }
0593     se->registerSubsystem(trksInJetQA);
0594 
0595   }  // end jet loop
0596   return;
0597 
0598 }  // end 'JetWithTracksQA(std::optional<uint32_t>)'
0599 
0600 // ----------------------------------------------------------------------------
0601 //! Create QA modules for jets with clusters (Calo)
0602 // ----------------------------------------------------------------------------
0603 void JetsWithCaloQA(std::optional<uint32_t> trg = std::nullopt)
0604 {
0605   // set verbosity
0606   int verbosity = std::max(Enable::JETQA_VERBOSITY, Enable::QA_VERBOSITY);
0607   if (verbosity > 1)
0608   {
0609     std::cout << ">>> Entering JetsWithCaloQA() with trg="
0610               << (trg.has_value() ? std::to_string(trg.value()) : "none")
0611               << std::endl;
0612   }
0613 
0614   // grab appropriate trigger tag
0615   std::string trig_tag = JetQA::GetTriggerTag(trg);
0616 
0617   // grab default pt, eta ranges
0618   std::pair<double, double> ptJetRange = JetQA::GetJetPtRange(trg);
0619   //  std::pair<double, double> etaJetRange = JetQA::GetJetEtaRange();
0620 
0621   // connect to f4a server
0622   Fun4AllServer* se = Fun4AllServer::instance();
0623 
0624   // get list of jet nodes to analyze
0625   std::vector<uint32_t> vecJetsToQA = JetQA::GetJetsToQA(JetQA::Source::Calos);
0626 
0627   // initialize and register emcluster jet kinematic QA
0628   EMClusterKinematics* emclusterJetsQA = new EMClusterKinematics(
0629       "EMClusterKinematics" + trig_tag,
0630       "CLUSTERINFO_CEMC",
0631       "");
0632   emclusterJetsQA->SetDoOptHist(false);
0633   if (trg.has_value())
0634   {
0635     emclusterJetsQA->SetTrgToSelect(trg.value());
0636   }
0637   emclusterJetsQA->Verbosity(verbosity);
0638   se->registerSubsystem(emclusterJetsQA);
0639 
0640   // initialize and register event-wise rho check
0641   RhosinEvent* evtRhoQA = new RhosinEvent("EventWiseCaloRho" + trig_tag, "");
0642   evtRhoQA->Verbosity(verbosity);
0643   evtRhoQA->add_area_rho_node("TowerRho_AREA");
0644   evtRhoQA->add_mult_rho_node("TowerRho_MULT");
0645   if (trg.has_value())
0646   {
0647     evtRhoQA->setTrgToSelect(trg.value());
0648   }
0649   se->registerSubsystem(evtRhoQA);
0650 
0651   // initialize and register jet seed counter qa module
0652   if (!JetQA::DoPP)
0653   {
0654     JetSeedCount* jetSeedQA = new JetSeedCount(
0655         "JetSeedCount" + trig_tag + "_towersub1_antikt_r02",
0656         "AntiKt_Tower_r04",  // n.b. unused in module
0657         "AntiKt_TowerInfo_HIRecoSeedsRaw_r02",
0658         "AntiKt_TowerInfo_HIRecoSeedsSub_r02");
0659     jetSeedQA->Verbosity(verbosity);
0660     jetSeedQA->setHistTag("");
0661     jetSeedQA->setPtRange(ptJetRange.first, ptJetRange.second);
0662     jetSeedQA->setEtaRange(JetQA::MinAcceptEta, JetQA::MaxAcceptEta);
0663     jetSeedQA->setWriteToOutputFile(false);
0664     jetSeedQA->setPPMode(JetQA::DoPP);
0665     if (trg.has_value())
0666     {
0667       jetSeedQA->setTrgToSelect(trg.value());
0668     }
0669     se->registerSubsystem(jetSeedQA);
0670   }
0671 
0672   // register underlying event module
0673   if (!JetQA::DoPP)
0674   {
0675     UEvsEtaCentrality* UEvsEtaCentralityQA = new UEvsEtaCentrality("UEvsEtaCent" + trig_tag);
0676     UEvsEtaCentralityQA->SetConfig(
0677         {
0678             .debug = false,
0679             .histTag = "",
0680         });
0681     if (trg.has_value())
0682     {
0683       UEvsEtaCentralityQA->SetConfig(
0684           {
0685               .doTrgSelect = true,
0686               .trgToSelect = trg.value(),
0687           });
0688     }
0689     se->registerSubsystem(UEvsEtaCentralityQA);
0690   }
0691 
0692   // create modules that take single R values ---------------------------------
0693 
0694   // loop over resolution parameters
0695   for (uint32_t jet : vecJetsToQA)
0696   {
0697     // get R-dependent eta range
0698     std::pair<double, double> etaJetRange = JetQA::GetJetEtaRange(JetQA::JetRes[jet]);
0699 
0700     // initialize and register constituent checks
0701     ConstituentsinJets* jetCstQA = new ConstituentsinJets(
0702         "ConstituentsInJets" + trig_tag + "_" + JetQA::JetTag[jet],
0703         JetQA::JetInput[jet],
0704         "TowerInfoBackground_Sub1",
0705         "",
0706         "TOWERINFO_CALIB_CEMC_RETOWER",
0707         "TOWERINFO_CALIB_HCALIN",
0708         "TOWERINFO_CALIB_HCALOUT");
0709     jetCstQA->Verbosity(verbosity);
0710     jetCstQA->setPtRange(ptJetRange.first, ptJetRange.second);
0711     jetCstQA->setEtaRange(etaJetRange.first, etaJetRange.second);
0712     jetCstQA->setPPMode(JetQA::DoPP);
0713     if (trg.has_value())
0714     {
0715       jetCstQA->setTrgToSelect(trg.value());
0716     }
0717     se->registerSubsystem(jetCstQA);
0718 
0719   }  // end jet loop
0720   return;
0721 
0722 }  // end 'JetsWithCaloQA(std::optional<uint32_t>)'
0723 
0724 // ----------------------------------------------------------------------------
0725 //! Run jet QA
0726 // ----------------------------------------------------------------------------
0727 void Jet_QA(const std::vector<uint32_t>& vecTrigsToUse = JetQA::GetDefaultTriggerList())
0728 {
0729   // if running with calos, instantiate & register the
0730   // CaloStatusMapper QA module
0731   if (JetQA::HasCalos)
0732   {
0733     // set verbosity
0734     int verbosity = std::max(Enable::JETQA_VERBOSITY, Enable::QA_VERBOSITY);
0735 
0736     // connect to f4a server
0737     Fun4AllServer* se = Fun4AllServer::instance();
0738 
0739     // register module
0740     CaloStatusMapper* caloStatusQA = new CaloStatusMapper("CaloStatusMapper");
0741     caloStatusQA->SetConfig(
0742         {
0743             .debug = false,
0744             .doNorm = false,     // do NOT try to normalize histograms
0745             .doOptHist = false,  // turn off extra histograms
0746             .histTag = "",
0747             .doTrgSelect = false  // n.b. differential in trigger not useful here
0748         });
0749 
0750     se->Verbosity(verbosity);
0751     se->registerSubsystem(caloStatusQA);
0752   }
0753 
0754   // run in inclusive mode if needed
0755   if (JetQA::DoInclusive)
0756   {
0757     CommonJetQA();
0758     if (JetQA::HasTracks)
0759     {
0760       JetsWithTracksQA();
0761     }
0762     if (JetQA::HasCalos)
0763     {
0764       JetsWithCaloQA();
0765     }
0766   }
0767 
0768   // run in triggered mode if needed
0769   if (JetQA::DoTriggered)
0770   {
0771     for (uint32_t trg : vecTrigsToUse)
0772     {
0773       CommonJetQA(trg);
0774       if (JetQA::HasTracks)
0775       {
0776         JetsWithTracksQA(trg);
0777       }
0778       if (JetQA::HasCalos)
0779       {
0780         JetsWithCaloQA(trg);
0781       }
0782     }  // end trigger loop
0783   }
0784   return;
0785 
0786 }  // end 'Jet_QA(std::vector<uint32_t>)'
0787 
0788 #endif
0789 
0790 // end ------------------------------------------------------------------------