Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-03 08:20:26

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