From 0ebc59f8d3629160cfcfcf5840e8411b2135b32f Mon Sep 17 00:00:00 2001
From: William Patrick Mccormack <william.patrick.mc.cormack.iii@cern.ch>
Date: Thu, 17 Dec 2020 19:14:21 +0000
Subject: [PATCH] Adding dEdx and charge particle filter to STDM7

---
 .../python/DerivationFrameworkProdFlags.py    |  1 +
 .../python/SlimmingHelper.py                  | 10 +--
 .../python/InDetTrackParticlesCPContent.py    |  2 +-
 .../python/LowPtRoITrackParticlesCPContent.py |  2 +-
 .../TruthHSDecorator.h                        | 36 +++++++++
 .../python/MCTruthCommon.py                   | 22 ++++++
 .../src/TruthHSDecorator.cxx                  | 76 +++++++++++++++++++
 .../DerivationFrameworkMCTruth_entries.cxx    |  3 +
 .../DerivationFrameworkSM/share/STDM7.py      | 15 +++-
 9 files changed, 157 insertions(+), 10 deletions(-)
 create mode 100644 PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/DerivationFrameworkMCTruth/TruthHSDecorator.h
 create mode 100644 PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/TruthHSDecorator.cxx

diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkCore/python/DerivationFrameworkProdFlags.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkCore/python/DerivationFrameworkProdFlags.py
index 44c02a537d66..6dc4ba159a6a 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkCore/python/DerivationFrameworkProdFlags.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkCore/python/DerivationFrameworkProdFlags.py
@@ -857,6 +857,7 @@ class WriteDAOD_STDM7Stream (JobProperty):
     FileName = ''
     isVirtual = False
     DPDMakerScript = "DerivationFrameworkSM/STDM7.py"
+    nChFilter = -2
     pass
 jobproperties.DerivationFrameworkProdFlags.add_JobProperty(WriteDAOD_STDM7Stream)
 listAODtoDPD.append(WriteDAOD_STDM7Stream.StreamName)
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkCore/python/SlimmingHelper.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkCore/python/SlimmingHelper.py
index 13f87e88f219..e787961b5e0d 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkCore/python/SlimmingHelper.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkCore/python/SlimmingHelper.py
@@ -355,12 +355,12 @@ class SlimmingHelper:
                 elif collectionName=="MET_Reference_AntiKt4EMPFlow":
                         from DerivationFrameworkJetEtMiss.MET_Reference_AntiKt4EMPFlowCPContent import MET_Reference_AntiKt4EMPFlowCPContent
                         items.extend(MET_Reference_AntiKt4EMPFlowCPContent)
-		elif collectionName=="MET_Baseline_AntiKt4EMTopo":
+                elif collectionName=="MET_Baseline_AntiKt4EMTopo":
                         from DerivationFrameworkJetEtMiss.MET_Baseline_AntiKt4EMTopoCPContent import MET_Baseline_AntiKt4EMTopoCPContent
-			items.extend(MET_Baseline_AntiKt4EMTopoCPContent)
-		elif collectionName=="MET_Baseline_AntiKt4EMPFlow":
-			from DerivationFrameworkJetEtMiss.MET_Baseline_AntiKt4EMPFlowCPContent import MET_Baseline_AntiKt4EMPFlowCPContent
-			items.extend(MET_Baseline_AntiKt4EMPFlowCPContent)
+                        items.extend(MET_Baseline_AntiKt4EMTopoCPContent)
+                elif collectionName=="MET_Baseline_AntiKt4EMPFlow":
+                        from DerivationFrameworkJetEtMiss.MET_Baseline_AntiKt4EMPFlowCPContent import MET_Baseline_AntiKt4EMPFlowCPContent
+                        items.extend(MET_Baseline_AntiKt4EMPFlowCPContent)
                 elif collectionName=="AntiKt4TruthJets":
                         from DerivationFrameworkJetEtMiss.AntiKt4TruthJetsCPContent import AntiKt4TruthJetsCPContent
                         items.extend(AntiKt4TruthJetsCPContent)
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkInDet/python/InDetTrackParticlesCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkInDet/python/InDetTrackParticlesCPContent.py
index 843a3cc6003f..5a2493a56d90 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkInDet/python/InDetTrackParticlesCPContent.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkInDet/python/InDetTrackParticlesCPContent.py
@@ -2,5 +2,5 @@
 
 InDetTrackParticlesCPContent = [
 "InDetTrackParticles",
-"InDetTrackParticlesAux.phi.theta.qOverP.z0.d0.chiSquared.numberDoF.expectInnermostPixelLayerHit.expectNextToInnermostPixelLayerHit.numberOfInnermostPixelLayerHits.numberOfNextToInnermostPixelLayerHits.numberOfPixelHits.numberOfPixelHoles.numberOfPixelSharedHits.numberOfPixelDeadSensors.numberOfSCTHits.numberOfSCTHoles.numberOfSCTSharedHits.numberOfSCTDeadSensors.definingParametersCovMatrix"
+"InDetTrackParticlesAux.phi.theta.qOverP.z0.d0.chiSquared.numberDoF.expectInnermostPixelLayerHit.expectNextToInnermostPixelLayerHit.numberOfInnermostPixelLayerHits.numberOfNextToInnermostPixelLayerHits.numberOfPixelHits.numberOfPixelHoles.numberOfPixelSharedHits.numberOfPixelDeadSensors.numberOfSCTHits.numberOfSCTHoles.numberOfSCTSharedHits.numberOfSCTDeadSensors.definingParametersCovMatrix.pixeldEdx.numberOfUsedHitsdEdx.numberOfIBLOverflowsdEdx"
 ]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkInDet/python/LowPtRoITrackParticlesCPContent.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkInDet/python/LowPtRoITrackParticlesCPContent.py
index b4cf10bbad39..c948db2c2978 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkInDet/python/LowPtRoITrackParticlesCPContent.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkInDet/python/LowPtRoITrackParticlesCPContent.py
@@ -2,5 +2,5 @@
 
 LowPtRoITrackParticlesCPContent = [
 "LowPtRoITrackParticles",
-"LowPtRoITrackParticlesAux.phi.theta.qOverP.z0.d0.chiSquared.numberDoF.expectInnermostPixelLayerHit.expectNextToInnermostPixelLayerHit.numberOfInnermostPixelLayerHits.numberOfNextToInnermostPixelLayerHits.numberOfPixelHits.numberOfPixelHoles.numberOfPixelSharedHits.numberOfPixelDeadSensors.numberOfSCTHits.numberOfSCTHoles.numberOfSCTSharedHits.numberOfSCTDeadSensors.definingParametersCovMatrix.truthMatchProbability"
+"LowPtRoITrackParticlesAux.phi.theta.qOverP.z0.d0.chiSquared.numberDoF.expectInnermostPixelLayerHit.expectNextToInnermostPixelLayerHit.numberOfInnermostPixelLayerHits.numberOfNextToInnermostPixelLayerHits.numberOfPixelHits.numberOfPixelHoles.numberOfPixelSharedHits.numberOfPixelDeadSensors.numberOfSCTHits.numberOfSCTHoles.numberOfSCTSharedHits.numberOfSCTDeadSensors.definingParametersCovMatrix.truthMatchProbability.pixeldEdx.numberOfUsedHitsdEdx.numberOfIBLOverflowsdEdx"
 ]
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/DerivationFrameworkMCTruth/TruthHSDecorator.h b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/DerivationFrameworkMCTruth/TruthHSDecorator.h
new file mode 100644
index 000000000000..66fe4cfc1656
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/DerivationFrameworkMCTruth/TruthHSDecorator.h
@@ -0,0 +1,36 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+///////////////////////////////////////////////////////////////////
+// TruthHSDecorator.h, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+
+#ifndef DERIVATIONFRAMEWORK_TRUTHHSDECORATOR_H
+#define DERIVATIONFRAMEWORK_TRUTHHSDECORATOR_H
+
+#include <string>
+
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "DerivationFrameworkInterfaces/IAugmentationTool.h"
+
+namespace DerivationFramework {
+
+  /** This decorator is applied to all truth particles, indicating
+   *    whether or not they come from the hard scatter in the event.
+   *    This is useful for cases where MC has full pileup truth.
+   */
+  class TruthHSDecorator : public AthAlgTool, public IAugmentationTool {
+    public: 
+      TruthHSDecorator(const std::string& t, const std::string& n, const IInterface* p);
+      virtual StatusCode addBranches() const;
+
+    private:
+      //configurables
+      std::string m_truthEventKey; 
+      std::string m_truthParticleKey; 
+      std::string m_decorationName;
+  }; 
+}
+
+#endif // DERIVATIONFRAMEWORK_TruthHSDecorator_H
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/python/MCTruthCommon.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/python/MCTruthCommon.py
index a02f251d1950..77343524f1f0 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/python/MCTruthCommon.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/python/MCTruthCommon.py
@@ -537,6 +537,28 @@ def addLargeRJetD2(kernel=None):
     kernel +=CfgMgr.DerivationFramework__DerivationKernel("TRUTHD2Kernel",
                                                           AugmentationTools = [TruthD2Decorator,TruthD2Decorator_SD] )
 
+def addTruthHSDeco(kernel=None):
+    #Ensure that we are adding it to something
+    if kernel is None:
+        from DerivationFrameworkCore.DerivationFrameworkMaster import DerivationFrameworkJob
+        kernel = DerivationFrameworkJob
+    if hasattr(kernel,'TRUTHHSKernel'):
+        # Already there!  Carry on...
+        dfcommontruthlog.warning("Attempt to add a duplicate TRUTHHSKernel. Failing.")
+        return
+
+    #Extra classifier for HS variable
+    from DerivationFrameworkMCTruth.DerivationFrameworkMCTruthConf import DerivationFramework__TruthHSDecorator
+    TruthHSDecorator= DerivationFramework__TruthHSDecorator("TruthHSDecorator",
+                                                            TruthParticleKey = "TruthParticles",
+                                                            TruthEventKey = "TruthEvents",
+                                                            DecorationName = "HSBool")
+
+    from AthenaCommon.AppMgr import ToolSvc
+    ToolSvc += TruthHSDecorator
+    kernel +=CfgMgr.DerivationFramework__DerivationKernel("TRUTHHSKernel",
+                                                          AugmentationTools = [TruthHSDecorator] )
+
 
 def addTruthEnergyDensity(kernel=None):
     #Ensure that we are adding it to something
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/TruthHSDecorator.cxx b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/TruthHSDecorator.cxx
new file mode 100644
index 000000000000..78c7d11ae523
--- /dev/null
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/TruthHSDecorator.cxx
@@ -0,0 +1,76 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/////////////////////////////////////////////////////////////////
+// TruthHSDecorator.cxx, (c) ATLAS Detector software
+///////////////////////////////////////////////////////////////////
+// Author: Patrick McCormack (wpmccormack@cern.ch)
+//
+
+#include "DerivationFrameworkMCTruth/TruthHSDecorator.h"
+#include "xAODTruth/TruthEventContainer.h"
+#include "xAODTruth/TruthParticleContainer.h"
+#include <vector>
+#include <string>
+
+namespace DerivationFramework {
+
+  TruthHSDecorator::TruthHSDecorator(const std::string& t,
+      const std::string& n,
+      const IInterface* p) : 
+    AthAlgTool(t,n,p)
+  {
+    declareInterface<DerivationFramework::IAugmentationTool>(this);
+    declareProperty ("TruthParticleKey", m_truthParticleKey = "TruthParticles", "Name of truth particle container key for input");
+    declareProperty ("TruthEventKey", m_truthEventKey = "TruthEvents", "Name of truth event container key for input");
+    declareProperty ("DecorationName", m_decorationName = "HSBool", "Decoration Name");
+
+  }
+
+  StatusCode TruthHSDecorator::addBranches() const
+  {
+
+      // Set up the decorators 
+      SG::AuxElement::Decorator< short > decoratorHS(m_decorationName); 
+
+      const xAOD::TruthParticleContainer* xTruthParticleContainer = 0;
+      if (evtStore()->retrieve(xTruthParticleContainer,m_truthParticleKey).isFailure()) {
+	ATH_MSG_ERROR("could not retrieve TruthParticleContainer " <<m_truthParticleKey);
+	return StatusCode::FAILURE;
+      }
+
+      //Initialize all particles to False before looping over the HS particles
+      for(xAOD::TruthParticleContainer::const_iterator PItr = xTruthParticleContainer->begin(); PItr!=xTruthParticleContainer->end(); ++PItr){
+	
+	decoratorHS(**PItr) = 0;
+
+      }
+
+      //Get TruthEvents
+      const xAOD::TruthEventContainer* xTruthEventContainer = 0;
+      if (evtStore()->retrieve(xTruthEventContainer,m_truthEventKey).isFailure()) {
+	ATH_MSG_ERROR("could not retrieve TruthEventContainer " <<m_truthEventKey);
+	return StatusCode::FAILURE;
+      }
+
+      //Now loop over HS particles
+      for ( const auto* truthevent : *xTruthEventContainer ) {
+
+	typedef std::vector<ElementLink< xAOD::TruthParticleContainer >> Vec_EL_TPC;
+
+        if( ! (truthevent)->isAvailable< Vec_EL_TPC > ("truthParticleLinks") ) continue;
+
+        //const Vec_EL_TPC & truthPartLinks = (truthevent)->auxdata< Vec_EL_TPC >("truthParticleLinks");
+        const Vec_EL_TPC & truthPartLinks = (truthevent)->truthParticleLinks();
+        for(unsigned int tpl = 0; tpl < truthPartLinks.size(); tpl++){
+	  if(!truthPartLinks.at(tpl).isValid()) continue;
+	  const auto  pp = *(truthPartLinks.at(tpl));
+	  pp->auxdecor<short>("HSBool") = 1;
+	}
+
+      }
+
+      return StatusCode::SUCCESS;
+  }
+}
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/components/DerivationFrameworkMCTruth_entries.cxx b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/components/DerivationFrameworkMCTruth_entries.cxx
index 5861919f0994..4a72f5622203 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/components/DerivationFrameworkMCTruth_entries.cxx
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/components/DerivationFrameworkMCTruth_entries.cxx
@@ -15,6 +15,7 @@
 #include "DerivationFrameworkMCTruth/HadronOriginClassifier.h"
 #include "DerivationFrameworkMCTruth/TruthQGDecorationTool.h"
 #include "DerivationFrameworkMCTruth/TruthD2Decorator.h"
+#include "DerivationFrameworkMCTruth/TruthHSDecorator.h"
 #include "../GenFilterTool.h"
 #include "../HardScatterCollectionMaker.h"
 #include "../TruthNavigationDecorator.h"
@@ -44,6 +45,7 @@ DECLARE_TOOL_FACTORY( HardScatterCollectionMaker )
 DECLARE_TOOL_FACTORY( TruthNavigationDecorator )
 DECLARE_TOOL_FACTORY( TruthBornLeptonCollectionMaker )
 DECLARE_TOOL_FACTORY( TruthD2Decorator )
+DECLARE_TOOL_FACTORY( TruthHSDecorator )
 DECLARE_TOOL_FACTORY( TruthLinkRepointTool )
 DECLARE_TOOL_FACTORY( TruthEDDecorator )
 
@@ -68,6 +70,7 @@ DECLARE_FACTORY_ENTRIES( DerivationFrameworkMCTruth) {
    DECLARE_TOOL( TruthNavigationDecorator )
    DECLARE_TOOL( TruthBornLeptonCollectionMaker )
    DECLARE_TOOL( TruthD2Decorator )
+   DECLARE_TOOL( TruthHSDecorator )
    DECLARE_TOOL( TruthLinkRepointTool )
    DECLARE_TOOL( TruthEDDecorator )
 }
diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkSM/share/STDM7.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkSM/share/STDM7.py
index 60d5d4a01290..5f46bc60fd63 100644
--- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkSM/share/STDM7.py
+++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkSM/share/STDM7.py
@@ -67,9 +67,10 @@ truth_cond_hadrons = "( (TruthParticles.status ==1) && (TruthParticles.barcode<2
 
 from DerivationFrameworkMCTruth.DerivationFrameworkMCTruthConf import DerivationFramework__GenericTruthThinning
 
-
 if globalflags.DataSource()=='geant4':
     from DerivationFrameworkSM.STDMCommonTruthTools import *
+    from DerivationFrameworkMCTruth.MCTruthCommon import addTruthHSDeco
+    addTruthHSDeco()
    
     STDM7TruthLepTool = DerivationFramework__GenericTruthThinning(name                         = "STDM7TruthLepTool",
                                                                   ThinningService              = STDM7ThinningHelper.ThinningSvc(),
@@ -97,7 +98,7 @@ if globalflags.DataSource()=='geant4':
                                                                   PreserveGeneratorDescendants = False,
                                                                   PreserveAncestors            = False)
 
-    
+
     ToolSvc += STDM7TruthLepTool
     ToolSvc += STDM7TruthBosTool
     ToolSvc += STDM7PhotonThinning
@@ -111,12 +112,20 @@ if globalflags.DataSource()=='geant4':
 # SKIMMING TOOL 
 #====================================================================
 
+filterVal = derivationFlags.WriteDAOD_STDM7Stream.nChFilter
+
 muonsRequirements = '(Muons.pt >= 4*GeV) && (abs(Muons.eta) < 2.6) && (Muons.DFCommonMuonsPreselection) && (Muons.DFCommonGoodMuon)'
 electronsRequirements = '(Electrons.pt > 11*GeV) && (abs(Electrons.eta) < 2.6) && (Electrons.DFCommonElectronsLHLoose)'
+chargedParticleRequirements = '(TruthParticles.pt > 500) && (TruthParticles.barcode < 200000) && (TruthParticles.status == 1) && (TruthParticles.charge != 0) && (TruthParticles.theta > 0.163803) && (TruthParticles.theta < 2.97779) && (TruthParticles.HSBool)' #the theta cuts correspond to |eta|<2.5.  Often, theta = 0 or pi, so using eta directly causes and Floating Point Exception
 muonOnlySelection = 'count('+muonsRequirements+') >=2'
 electronOnlySelection = 'count('+electronsRequirements+') >= 2'
 electronMuonSelection = '(count('+electronsRequirements+') + count('+muonsRequirements+')) >= 2'
-offlineexpression = '('+muonOnlySelection+' || '+electronOnlySelection+' || '+electronMuonSelection+')'
+
+if filterVal > -1 and globalflags.DataSource()=='geant4':
+    chargedParticleSelection = 'count('+chargedParticleRequirements+') < '+str(filterVal)
+    offlineexpression = '(('+muonOnlySelection+' || '+electronOnlySelection+' || '+electronMuonSelection+') && ('+chargedParticleSelection+'))'
+else:
+    offlineexpression = '('+muonOnlySelection+' || '+electronOnlySelection+' || '+electronMuonSelection+')'
 
 MuonTriggerRequirement=['HLT_2mu6_bUpsimumu_L1BPH-8M15-2MU6_BPH-0DR22-2MU6', 'HLT_2mu10', 'HLT_2mu14', 'HLT_2mu6_10invm30_pt2_z10', 'HLT_mu4_iloose_mu4_11invm60_noos', 'HLT_mu4_iloose_mu4_11invm60_noos_novtx', 'HLT_mu4_iloose_mu4_7invm9_noos', 'HLT_mu4_iloose_mu4_7invm9_noos_novtx', 'HLT_mu6_iloose_mu6_11invm24_noos', 'HLT_mu6_iloose_mu6_11invm24_noos_novtx', 'HLT_mu6_iloose_mu6_24invm60_noos', 'HLT_mu6_iloose_mu6_24invm60_noos_novtx', 'HLT_mu18_mu8noL1', 'HLT_mu20_iloose_L1MU15', 'HLT_2mu6_bBmumu', 'HLT_mu6_mu4_bBmumu', 'HLT_2mu4_bUpsimumu', 'HLT_mu6_mu4_bUpsimumu', 'HLT_2mu6_bUpsimumu', 'HLT_mu4_iloose_mu4_11invm60_noos_L1_MU6_2MU4', 'HLT_mu4_iloose_mu4_11invm60_noos_novtx_L1_MU6_2MU4', 'HLT_mu4_iloose_mu4_7invm9_noos_L1_MU6_2MU4', 'HLT_mu4_iloose_mu4_7invm9_noos_novtx_L1_MU6_2MU4', 'HLT_mu24_imedium', 'HLT_mu26_ivarmedium', 'HLT_mu50', 'HLT_mu24_iloose', 'HLT_mu24_iloose_L1MU15']
 
-- 
GitLab