From 1b90a75c8f40a4488f1294ef710fb4178776832b Mon Sep 17 00:00:00 2001
From: Antonio De Maria <antonio.de.maria@cern.ch>
Date: Sat, 28 Nov 2020 19:42:14 +0100
Subject: [PATCH] adding L1 efficiency histograms for TauTrigger Run3
 monitoring

---
 .../python/TrigTauMonitoringConfigMT.py       |  46 ++++++-
 .../src/TrigTauMonitorAlgorithm.cxx           | 114 ++++++++++++++++--
 .../src/TrigTauMonitorAlgorithm.h             |  19 ++-
 3 files changed, 165 insertions(+), 14 deletions(-)

diff --git a/Trigger/TrigMonitoring/TrigTauMonitoring/python/TrigTauMonitoringConfigMT.py b/Trigger/TrigMonitoring/TrigTauMonitoring/python/TrigTauMonitoringConfigMT.py
index 431108af58d..e94332f19d9 100644
--- a/Trigger/TrigMonitoring/TrigTauMonitoring/python/TrigTauMonitoringConfigMT.py
+++ b/Trigger/TrigMonitoring/TrigTauMonitoring/python/TrigTauMonitoringConfigMT.py
@@ -88,6 +88,14 @@ class TrigTauMonAlgBuilder:
       def isL1Item(self):
         return True if self.chain().startswith('L1') else False
 
+      def L1seed(self):
+        l1seed = ''
+        splits = self.chain().split("_")
+        for split in splits:
+            if split.startswith('L1TAU'):
+                l1seed = split
+        return l1seed
+
       def isRNN(self):
         return True if "RNN" in self.chain() else False
 
@@ -181,9 +189,12 @@ class TrigTauMonAlgBuilder:
 
     self.__logger.info( "Booking all histograms for alg: %s", monAlg.name )
 
+    l1seeds = []
+
     for trigger in triggers:
       info = self.getTrigInfo(trigger)
-
+  
+      l1seeds.append(info.L1seed())
 
       if info.isRNN() is True:
         self.bookRNNInputVars( monAlg, trigger,nProng='1P', online=True )
@@ -199,6 +210,15 @@ class TrigTauMonAlgBuilder:
         self.bookHLTEffHistograms( monAlg, trigger,nProng='1P')
         self.bookHLTEffHistograms( monAlg, trigger,nProng='MP')
 
+    #remove duplicated from L1 seed list
+    l1seeds = list(dict.fromkeys(l1seeds))
+    for l1seed in l1seeds:
+        if not l1seed : 
+            continue
+        self.bookL1EffHistograms( monAlg, l1seed, nProng='1P')
+        self.bookL1EffHistograms( monAlg, l1seed, nProng='MP') 
+   
+
   #
   # Booking HLT efficiencies
   #
@@ -220,6 +240,30 @@ class TrigTauMonAlgBuilder:
     defineEachStepHistograms('tauPt', 'p_{T} [GeV]', 60, 0.0, 300.)
     defineEachStepHistograms('tauEta','#eta', 13, -2.6, 2.6)
     defineEachStepHistograms('tauPhi','#phi', 16, -3.2, 3.2) 
+    defineEachStepHistograms('averageMu', 'average pileup', 10, 0., 80.)
+
+  #
+  # Booking L1 efficiencies
+  #
+ 
+  def bookL1EffHistograms( self, monAlg, L1seed, nProng ):
+
+    monGroupName = L1seed+'_L1_Efficiency_'+nProng
+    monGroupPath = 'L1_Efficiency/'+L1seed+'/L1_Efficiency_'+ nProng
+
+    monGroup = self.helper.addGroup( monAlg, monGroupName,
+                              self.basePath+'/'+monGroupPath )
+
+    def defineEachStepHistograms(xvariable, xlabel, xbins, xmin, xmax):
+
+       monGroup.defineHistogram(monGroupName+'_L1pass,'+monGroupName+'_'+xvariable+';EffL1_'+xvariable+'_wrt_Offline',
+                                title='L1 Efficiency ' +L1seed+' '+nProng+';'+xlabel+';Efficiency',
+                                type='TEfficiency',xbins=xbins,xmin=xmin,xmax=xmax)
+
+    defineEachStepHistograms('tauPt', 'p_{T} [GeV]', 60, 0.0, 300.)
+    defineEachStepHistograms('tauEta','#eta', 13, -2.6, 2.6)
+    defineEachStepHistograms('tauPhi','#phi', 16, -3.2, 3.2)
+    defineEachStepHistograms('averageMu', 'average pileup', 10, 0., 80.)
 
   #
   # Book RNN Variables
diff --git a/Trigger/TrigMonitoring/TrigTauMonitoring/src/TrigTauMonitorAlgorithm.cxx b/Trigger/TrigMonitoring/TrigTauMonitoring/src/TrigTauMonitorAlgorithm.cxx
index ac5c9f0e01f..21e8d2ca357 100644
--- a/Trigger/TrigMonitoring/TrigTauMonitoring/src/TrigTauMonitorAlgorithm.cxx
+++ b/Trigger/TrigMonitoring/TrigTauMonitoring/src/TrigTauMonitorAlgorithm.cxx
@@ -52,6 +52,9 @@ StatusCode TrigTauMonitorAlgorithm::fillHistograms( const EventContext& ctx ) co
   ATH_MSG_DEBUG("Chains for Analysis " << m_trigList);
 
   std::vector< std::pair<const xAOD::TauJet*, const TrigCompositeUtils::Decision*>> pairObjs;
+ 
+  std::vector<std::string> L1seed_list;
+  bool fill_l1eff = false;
 
   for(const auto& trigger : m_trigList){
 
@@ -63,10 +66,25 @@ StatusCode TrigTauMonitorAlgorithm::fillHistograms( const EventContext& ctx ) co
        return StatusCode::SUCCESS;                                                                                                                         
     }  
 
-    fillDistributions( pairObjs, trigger );                                                                                                           
-  }
+    if(info.trigL1Item.empty()){ // L1 item not found
+       fill_l1eff = false;
+    }
+    else if (std::find(L1seed_list.begin(), L1seed_list.end(), info.trigL1Item) == L1seed_list.end())
+    {
+        // check if L1 seed has been already filled -> L1 seed must be filled only once for triggers with same L1 seed
+        fill_l1eff = true;
+        L1seed_list.push_back(info.trigL1Item);
+        
+    } else {
+        fill_l1eff = false;
+    }
 
-    return StatusCode::SUCCESS;
+    fillDistributions( ctx, pairObjs, trigger, fill_l1eff, info.trigL1Item);                                                                                                           
+  }
+   
+  L1seed_list.clear();
+  
+  return StatusCode::SUCCESS;
 }
 
 
@@ -108,7 +126,6 @@ StatusCode TrigTauMonitorAlgorithm::executeNavigation( const EventContext& ctx,
       }                     
     }
 
-
     std::pair< const xAOD::TauJet*, const TrigCompositeUtils::Decision * > pair(Tau,dec);
     pairObjs.push_back(pair);
 
@@ -118,7 +135,7 @@ StatusCode TrigTauMonitorAlgorithm::executeNavigation( const EventContext& ctx,
   return StatusCode::SUCCESS;
 }
 
-void TrigTauMonitorAlgorithm::fillDistributions(std::vector< std::pair< const xAOD::TauJet*, const TrigCompositeUtils::Decision * >> pairObjs, std::string trigger) const
+void TrigTauMonitorAlgorithm::fillDistributions(const EventContext& ctx, std::vector< std::pair< const xAOD::TauJet*, const TrigCompositeUtils::Decision * >> pairObjs, std::string trigger, const bool fill_l1eff, const std::string trigL1Item) const
 {
   ATH_MSG_DEBUG ("TrigTauMonitorAlgorithm::fillDistributions");
 
@@ -181,11 +198,15 @@ void TrigTauMonitorAlgorithm::fillDistributions(std::vector< std::pair< const xA
     fillbasicVars( trigger, online_tau_vec_1p, true);
     fillbasicVars( trigger, online_tau_vec_mp, true);
   }
-
    
   if(info.isRNN){
-    fillEfficiencies(trigger, offline_tau_vec_1p, online_tau_vec_1p, "1P");
-    fillEfficiencies(trigger, offline_tau_vec_mp, online_tau_vec_mp, "MP");
+    fillHLTEfficiencies(ctx, trigger, offline_tau_vec_1p, online_tau_vec_1p, "1P");
+    fillHLTEfficiencies(ctx, trigger, offline_tau_vec_mp, online_tau_vec_mp, "MP");
+  }
+
+  if(fill_l1eff) {
+    fillL1Efficiencies(ctx, trigger, offline_tau_vec_1p, "1P", trigL1Item);
+    fillL1Efficiencies(ctx, trigger, offline_tau_vec_mp, "MP", trigL1Item);
   }
 
   offline_tau_vec_1p.clear();
@@ -194,7 +215,7 @@ void TrigTauMonitorAlgorithm::fillDistributions(std::vector< std::pair< const xA
   online_tau_vec_mp.clear();
 }
 
-void TrigTauMonitorAlgorithm::fillEfficiencies(const std::string trigger, std::vector<const xAOD::TauJet*> offline_tau_vec, std::vector<const xAOD::TauJet*> online_tau_vec, std::string nProng) const
+void TrigTauMonitorAlgorithm::fillHLTEfficiencies(const EventContext& ctx, const std::string trigger, std::vector<const xAOD::TauJet*> offline_tau_vec, std::vector<const xAOD::TauJet*> online_tau_vec, std::string nProng) const
 {
   ATH_MSG_DEBUG("Fill HLT efficiencies: " << trigger);
 
@@ -205,6 +226,7 @@ void TrigTauMonitorAlgorithm::fillEfficiencies(const std::string trigger, std::v
   auto tauPt = Monitored::Scalar<float>(monGroupName+"_tauPt",0.0);
   auto tauEta = Monitored::Scalar<float>(monGroupName+"_tauEta",0.0);
   auto tauPhi = Monitored::Scalar<float>(monGroupName+"_tauPhi",0.0);
+  auto averageMu = Monitored::Scalar<float>(monGroupName+"_averageMu",0.0); 
   auto HLT_match = Monitored::Scalar<bool>(monGroupName+"_HLTpass",false);
 
   for(auto offline_tau : offline_tau_vec){
@@ -212,15 +234,83 @@ void TrigTauMonitorAlgorithm::fillEfficiencies(const std::string trigger, std::v
        tauPt = offline_tau->pt()/1e3;
        tauEta = offline_tau->eta();
        tauPhi = offline_tau->phi();
+       averageMu = lbAverageInteractionsPerCrossing(ctx);
        HLT_match = HLTMatching(offline_tau, online_tau_vec, 0.2);
 
-       fill(monGroup, tauPt, tauEta, tauPhi, HLT_match);
+       fill(monGroup, tauPt, tauEta, tauPhi, averageMu, HLT_match);
   }
 
   ATH_MSG_DEBUG("After fill HLT efficiencies: " << trigger);
 
 }
 
+void TrigTauMonitorAlgorithm::fillL1Efficiencies(const EventContext& ctx, const std::string trigger, std::vector<const xAOD::TauJet*> offline_tau_vec, std::string nProng, const std::string trigL1Item) const
+{
+  ATH_MSG_DEBUG("Fill L1 efficiencies: " << trigL1Item);
+ 
+  std::string monGroupName = trigL1Item+"_L1_Efficiency_"+nProng;
+
+  auto monGroup = getGroup(monGroupName);
+
+  auto tauPt = Monitored::Scalar<float>(monGroupName+"_tauPt",0.0);
+  auto tauEta = Monitored::Scalar<float>(monGroupName+"_tauEta",0.0);
+  auto tauPhi = Monitored::Scalar<float>(monGroupName+"_tauPhi",0.0);
+  auto averageMu = Monitored::Scalar<float>(monGroupName+"_averageMu",0.0);
+  auto L1_match = Monitored::Scalar<bool>(monGroupName+"_L1pass",false);
+
+  const std::vector<Trig::Feature<TrigRoiDescriptor> > vec_L1roi_EFall =
+       m_trigDecTool->features(trigger,TrigDefs::alsoDeactivateTEs).get<TrigRoiDescriptor>("initialRoI",TrigDefs::alsoDeactivateTEs);
+  std::vector<Trig::Feature<TrigRoiDescriptor> >::const_iterator CI = vec_L1roi_EFall.begin();
+
+  std::vector<const xAOD::EmTauRoI*> L1rois;
+  for (;CI!=vec_L1roi_EFall.end(); ++CI){
+      if(!(CI->cptr())) continue;
+      const xAOD::EmTauRoI *aEmTau_ROI = findLVL1_ROI(ctx, CI->cptr());
+      if(!aEmTau_ROI) continue;
+      L1rois.push_back(aEmTau_ROI);
+  }
+
+  for(auto offline_tau : offline_tau_vec){
+
+       tauPt = offline_tau->pt()/1e3;
+       tauEta = offline_tau->eta();
+       tauPhi = offline_tau->phi();
+       averageMu = lbAverageInteractionsPerCrossing(ctx);
+       L1_match = L1Matching(offline_tau, L1rois, 0.2);
+  
+       fill(monGroup, tauPt, tauEta, tauPhi, averageMu, L1_match);
+  }
+
+  L1rois.clear();
+
+} 
+
+const xAOD::EmTauRoI* TrigTauMonitorAlgorithm::findLVL1_ROI(const EventContext& ctx, const TrigRoiDescriptor* roiDesc) const
+{    
+
+  SG::ReadHandle<xAOD::EmTauRoIContainer> EmTauRoIs(m_l1TauRoIKey, ctx);
+
+  if(!EmTauRoIs.isValid())
+  {
+     ATH_MSG_WARNING("Failed to retrieve offline EmTauRoI ");
+     return 0;
+  }
+
+  unsigned int id = roiDesc->roiWord();
+  for(auto EmTauRoI : *EmTauRoIs)
+  {    
+    if(id== EmTauRoI->roiWord()) 
+    {
+       return EmTauRoI;
+    }
+  }
+
+  return 0;
+   
+}
+
+
+
 void TrigTauMonitorAlgorithm::fillRNNInputVars(const std::string trigger, std::vector<const xAOD::TauJet*> tau_vec,const std::string nProng, bool online) const
 {
   ATH_MSG_DEBUG("Fill RNN input variables: " << trigger);
@@ -507,9 +597,11 @@ void TrigTauMonitorAlgorithm::setTrigInfo(const std::string trigger)
   else if(idwp.find("RNN")!=std::string::npos) isRNN=true;
   else isBDT=true;
 
-  type=names[4];
+  type=names[3];
   if(names[0].find("L1")!=std::string::npos) isL1=true;
 
+  if(names[4].find("L1TAU") !=std::string::npos) l1item =names[4];
+
   TrigInfo info{trigger,idwp,l1item,l1type,type,isL1,isRNN,isBDT,isPerf,hlthr,l1thr,false};
 
   m_trigInfo[trigger] = info;
diff --git a/Trigger/TrigMonitoring/TrigTauMonitoring/src/TrigTauMonitorAlgorithm.h b/Trigger/TrigMonitoring/TrigTauMonitoring/src/TrigTauMonitorAlgorithm.h
index 9f27d6b8006..def74a7a069 100644
--- a/Trigger/TrigMonitoring/TrigTauMonitoring/src/TrigTauMonitorAlgorithm.h
+++ b/Trigger/TrigMonitoring/TrigTauMonitoring/src/TrigTauMonitorAlgorithm.h
@@ -50,8 +50,9 @@ class TrigTauMonitorAlgorithm : public AthMonitorAlgorithm {
   void fillRNNTrack(const std::string trigger, std::vector<const xAOD::TauJet*> tau_vec, bool online) const;
   void fillRNNCluster(const std::string trigger, std::vector<const xAOD::TauJet*> tau_vec, bool online) const;
   void fillbasicVars(const std::string trigger, std::vector<const xAOD::TauJet*> tau_vec, bool online) const;
-  void fillDistributions(std::vector< std::pair< const xAOD::TauJet*, const TrigCompositeUtils::Decision * >> pairObjs, const std::string trigger) const;
-  void fillEfficiencies(const std::string trigger, std::vector<const xAOD::TauJet*> offline_tau_vec, std::vector<const xAOD::TauJet*> online_tau_vec, std::string nProng) const;
+  void fillDistributions(const EventContext& ctx, std::vector< std::pair< const xAOD::TauJet*, const TrigCompositeUtils::Decision * >> pairObjs, const std::string trigger, const bool fill_l1eff, const std::string trigL1Item) const;
+  void fillHLTEfficiencies(const EventContext& ctx,const std::string trigger, std::vector<const xAOD::TauJet*> offline_tau_vec, std::vector<const xAOD::TauJet*> online_tau_vec, std::string nProng) const;
+  void fillL1Efficiencies(const EventContext& ctx, const std::string trigger, std::vector<const xAOD::TauJet*> offline_tau_vec,std::string nProng, const std::string trigL1Item) const;
 
   inline double dR(const double eta1, const double phi1, const double eta2, const double phi2) const
   {
@@ -71,6 +72,20 @@ class TrigTauMonitorAlgorithm : public AthMonitorAlgorithm {
     return false;
   };
 
+  
+  inline bool L1Matching(const xAOD::TauJet* offline_tau, std::vector<const xAOD::EmTauRoI*> L1roi_vec, float threshold) const
+  {
+    for(auto l1roi: L1roi_vec){
+      float deltaR = dR(offline_tau->eta(),offline_tau->phi(), l1roi->eta(),l1roi->phi());
+      if(deltaR < threshold){
+          return true;
+      }
+    }
+    return false;
+  }; 
+
+  const xAOD::EmTauRoI* findLVL1_ROI(const EventContext& ctx, const TrigRoiDescriptor* roiDesc) const;
+ 
   SG::ReadHandleKey< xAOD::TauJetContainer> m_offlineTauJetKey { this, "offlineTauJetKey", "TauJets", "Offline taujet container key" };
   SG::ReadHandleKey< xAOD::EmTauRoIContainer > m_l1TauRoIKey    { this, "l1TauRoIKey","LVL1EmTauRoIs","Tau L1 RoI key"};
   SG::ReadHandleKey< xAOD::TauJetContainer> m_hltTauJetKey { this, "hltTauJetKey", "HLT_TrigTauRecMerged_MVA", "HLT taujet container key" };
-- 
GitLab