From f7762f0a52c7dd1e3a19e0689ac7d5d718987f00 Mon Sep 17 00:00:00 2001
From: Tadej Novak <tadej.novak@cern.ch>
Date: Wed, 28 Oct 2020 19:07:05 +0100
Subject: [PATCH 1/4] Support multiple weight variations in CutFlowSvc and
 clients

---
 .../src/AthFilterAlgorithm.cxx                |  9 ++-
 .../AthenaKernel/AthenaKernel/ICutFlowSvc.h   | 19 ++++--
 Control/AthenaPython/python/PyAthenaComps.py  |  2 +-
 Control/AthenaServices/src/DecisionSvc.cxx    |  2 +-
 .../EventBookkeeperTools/CutFlowSvc.h         | 20 ++++++-
 .../EventBookkeeperTools/Root/CutFlowSvc.cxx  | 59 +++++++++++++++----
 .../Root/FilterReporter.cxx                   | 12 ++--
 .../Root/FilterReporterParams.cxx             |  2 +-
 .../src/AllExecutedEventsCounterAlg.cxx       |  7 ++-
 .../Root/SysFilterReporterParams.cxx          |  2 +-
 .../ReweightUtils/src/SumOfWeightsAlg.cxx     |  3 +-
 11 files changed, 99 insertions(+), 38 deletions(-)

diff --git a/Control/AthenaBaseComps/src/AthFilterAlgorithm.cxx b/Control/AthenaBaseComps/src/AthFilterAlgorithm.cxx
index 55868f9d79c3..73e0009f1e15 100644
--- a/Control/AthenaBaseComps/src/AthFilterAlgorithm.cxx
+++ b/Control/AthenaBaseComps/src/AthFilterAlgorithm.cxx
@@ -84,7 +84,7 @@ AthFilterAlgorithm::sysInitialize()
 
   // register ourselves with the cutFlowSvc
   if ( cutFlowSvc().retrieve().isSuccess()) {
-    m_cutID = cutFlowSvc()->registerFilter(this->name(), m_filterDescr);
+    m_cutID = cutFlowSvc()->registerFilter(this->name(), m_filterDescr, false);
     if (0 == m_cutID) {
       ATH_MSG_INFO("problem registering myself with cutflow-svc");
     } else {
@@ -105,15 +105,14 @@ AthFilterAlgorithm::setFilterPassed( bool state ) const
   AthAlgorithm::setFilterPassed(state);
 
   if (state) {
-    double evtWeight=1.0;
-
     const EventContext& ctx = Gaudi::Hive::currentContext();
     SG::ReadHandle<xAOD::EventInfo> evtInfo (m_eventInfoKey, ctx);
     // Only try to access the mcEventWeight if we are running on Monte Carlo, duhhh!
     if ( evtInfo->eventType(xAOD::EventInfo::IS_SIMULATION) ) {
-      evtWeight = evtInfo->mcEventWeight();
+      m_cutFlowSvc->addEvent(m_cutID, evtInfo->mcEventWeights());
+    } else {
+      m_cutFlowSvc->addEvent(m_cutID, 1.0);
     }
-    m_cutFlowSvc->addEvent(m_cutID,evtWeight);
   }
 }
 
diff --git a/Control/AthenaKernel/AthenaKernel/ICutFlowSvc.h b/Control/AthenaKernel/AthenaKernel/ICutFlowSvc.h
index d746fbf06d03..3259e34f7f6c 100644
--- a/Control/AthenaKernel/AthenaKernel/ICutFlowSvc.h
+++ b/Control/AthenaKernel/AthenaKernel/ICutFlowSvc.h
@@ -45,8 +45,10 @@ public:
   /// Register filter in the CutFlowSvc and returns the CutID of the
   /// corresponding EventBookkeeper.
   /// This method should be used by filters that register themselves.
+  /// Systematic variations are optional.
   virtual CutIdentifier registerFilter( const std::string& name,
-                                        const std::string& description ) = 0;
+                                        const std::string& description,
+                                        bool nominalOnly ) = 0;
 
   /// Tells CutFlowSvc that a filter is used directly by an outputStream with
   /// a given logical context. The only foreseen client should the DecisionSvc,
@@ -54,15 +56,22 @@ public:
   virtual CutIdentifier registerTopFilter( const std::string& name,
                                            const std::string& description,
                                            unsigned int logic,
-                                           const std::string& outputStream ) = 0;
+                                           const std::string& outputStream,
+                                           bool nominalOnly ) = 0;
 
   /// Set the description of an existing EventBookkeeper
   virtual void setFilterDescription( CutIdentifier cutID,
                                      const std::string& descr ) = 0;
 
-  /// Tells CutFlowSvc to update the weighted event counter of a CutIdentifier cutID,
-  /// using CutIdentifier returned by selfRegisterFilter
-  virtual void addEvent( CutIdentifier cutID, double weight) = 0;
+  /// Tells CutFlowSvc to update the weighted event counter of a CutIdentifier
+  /// A vector of weights is provided for all systematic variations
+  virtual void addEvent( CutIdentifier cutID,
+                         const std::vector<float>& weights) = 0;
+
+  /// Tells CutFlowSvc to update the weighted event counter of a CutIdentifier
+  /// The same weight is for all systematic variations
+  virtual void addEvent( CutIdentifier cutID,
+                         double weight) = 0;
 
   /// Get number of accepted events for a cut
   virtual uint64_t getNAcceptedEvents( const CutIdentifier cutID ) const = 0;
diff --git a/Control/AthenaPython/python/PyAthenaComps.py b/Control/AthenaPython/python/PyAthenaComps.py
index 60301958e3b0..bbf0313df8ed 100644
--- a/Control/AthenaPython/python/PyAthenaComps.py
+++ b/Control/AthenaPython/python/PyAthenaComps.py
@@ -385,7 +385,7 @@ class AthFilterAlgorithm(Alg):
 
     def sysInitialize(self):
         myName=self.name() if callable(self.name) else self.name 
-        self.cutID = self.cutFlowSvc().registerFilter(myName, self._filter_descr)
+        self.cutID = self.cutFlowSvc().registerFilter(myName, self._filter_descr, True)
         if not self.cutID:
             self.msg.error("could not register filter-cut with cutflowsvc")
             return StatusCode.Failure
diff --git a/Control/AthenaServices/src/DecisionSvc.cxx b/Control/AthenaServices/src/DecisionSvc.cxx
index 0d60e1fe3583..e85a57b8b9bf 100644
--- a/Control/AthenaServices/src/DecisionSvc.cxx
+++ b/Control/AthenaServices/src/DecisionSvc.cxx
@@ -434,7 +434,7 @@ void DecisionSvc::DeclareToCutFlowSvc()
       ATH_MSG_DEBUG("Declaring logic " << logicalKey << " for " << streamName);
       for (auto filter  = (*vec)->begin();
                 filter != (*vec)->end(); ++filter) {
-        if(!m_cutflowSvc.empty()) {m_cutflowSvc->registerTopFilter( (*filter), logicalKey, 2, streamName ); }
+        if(!m_cutflowSvc.empty()) {m_cutflowSvc->registerTopFilter( (*filter), logicalKey, 2, streamName, true ); } // TODO: validate
       }
     }
   }
diff --git a/Event/EventBookkeeperTools/EventBookkeeperTools/CutFlowSvc.h b/Event/EventBookkeeperTools/EventBookkeeperTools/CutFlowSvc.h
index 51350e939193..f10b34efdd98 100644
--- a/Event/EventBookkeeperTools/EventBookkeeperTools/CutFlowSvc.h
+++ b/Event/EventBookkeeperTools/EventBookkeeperTools/CutFlowSvc.h
@@ -69,7 +69,8 @@ public:
   /// corresponding CutBookkeeper.
   /// This method should be used by filters that register themselves.
   virtual CutIdentifier registerFilter(const std::string& name,
-                                       const std::string& description)  override final;
+                                       const std::string& description,
+                                       bool nominalOnly) override final;
 
   /// Tells CutFlowSvc that a filter is used directly by an outputStream with
   /// a given logical context. The only foreseen client should the DecisionSvc,
@@ -77,12 +78,18 @@ public:
   virtual CutIdentifier registerTopFilter(const std::string& name,
                                           const std::string& description,
                                           unsigned int logic,
-                                          const std::string& outputStream) override final;
+                                          const std::string& outputStream,
+                                          bool nominalOnly) override final;
 
   /// Set the description of an existing CutBookkeeper
   virtual void setFilterDescription(CutIdentifier cutID,
                                     const std::string& descr) override final;
 
+  /// Tells CutFlowSvc to update the weighted event counter of a CutIdentifier cutID,
+  /// using CutIdentifier returned by selfRegisterFilter
+  virtual void addEvent(CutIdentifier cutID,
+                        const std::vector<float>& weights) override final;
+
   /// Tells CutFlowSvc to update the weighted event counter of a CutIdentifier cutID,
   /// using CutIdentifier returned by selfRegisterFilter
   virtual void addEvent(CutIdentifier cutID,
@@ -99,6 +106,12 @@ public:
 
 
 private:
+  /// Tells CutFlowSvc to update the weighted event counter of a CutIdentifier cutID
+  /// for a specific index in the cache
+  void addEvent(CutIdentifier cutID,
+                size_t index,
+                double weight);
+
   /// Helper function to determine the processing cycle number from the
   /// input meta-data store
   StatusCode determineCycleNumberFromInput(const std::string& collName);
@@ -130,6 +143,9 @@ private:
 
   /// Mutex to protect adding an event
   mutable std::recursive_mutex m_addEventMutex;
+
+  /// List of nominal-only filters
+  std::unordered_set<CutIdentifier> m_nominalOnlyCuts;
 };
 
 
diff --git a/Event/EventBookkeeperTools/Root/CutFlowSvc.cxx b/Event/EventBookkeeperTools/Root/CutFlowSvc.cxx
index 099b1caf0002..16ea58203867 100644
--- a/Event/EventBookkeeperTools/Root/CutFlowSvc.cxx
+++ b/Event/EventBookkeeperTools/Root/CutFlowSvc.cxx
@@ -62,7 +62,8 @@ CutFlowSvc::initialize()
 
 
 CutIdentifier CutFlowSvc::registerFilter( const std::string& name,
-                                          const std::string& description )
+                                          const std::string& description,
+                                          bool nominalOnly )
 {
   ATH_MSG_DEBUG("Registering filter with name '" << name << "' and description '" << description << "'");
 
@@ -89,6 +90,10 @@ CutIdentifier CutFlowSvc::registerFilter( const std::string& name,
   ATH_MSG_DEBUG("Declaring a new filter with name '" << name << "' and cutID " << cutID );
   container->push_back(std::move(newCbk));
 
+  if (nominalOnly) {
+    m_nominalOnlyCuts.emplace(cutID);
+  }
+
   return cutID;
 }
 
@@ -98,14 +103,15 @@ CutIdentifier CutFlowSvc::registerFilter( const std::string& name,
 CutIdentifier CutFlowSvc::registerTopFilter( const std::string& name,
                                              const std::string& description,
                                              unsigned int logic,
-                                             const std::string& outputStream ) 
+                                             const std::string& outputStream,
+                                             bool nominalOnly ) 
 {
   ATH_MSG_DEBUG("Registering top filter with name '" << name << "' and description '" << description << "'"
                 << ", logic=" << logic << ", outputStream=" << outputStream << ")");
 
   // Call the registerFilter method and get the correct CutBookkeeper
   // from the returned cutID
-  CutIdentifier cutID = registerFilter(name, description);
+  CutIdentifier cutID = registerFilter(name, description, nominalOnly);
   xAOD::CutBookkeeper* cbk = getCutBookkeeper(cutID, 0);
   if (cbk == nullptr) {
     ATH_MSG_ERROR("registerTopFilter: Could not find CutBookkeeper with cutID " << cutID);
@@ -137,26 +143,55 @@ CutFlowSvc::setFilterDescription( CutIdentifier cutID,
 }
 
 
+void
+CutFlowSvc::addEvent( CutIdentifier cutID,
+                      const std::vector<float>& weights )
+{
+  if (weights.size() != m_containers.size()) {
+    ATH_MSG_ERROR("Inconsistent weights and variation sizes " << weights.size() << " and " << m_containers.size());
+    return;
+  }
+
+  for (size_t i = 0; i < m_containers.size(); ++i) {
+    addEvent(cutID, i, weights[i]);
+  }
+}
+
 
 void
-CutFlowSvc::addEvent( CutIdentifier cutID, double weight)
+CutFlowSvc::addEvent( CutIdentifier cutID,
+                      double weight )
 {
-  ATH_MSG_VERBOSE("Adding event with weight " << weight << " to cut " << cutID);
+  if (m_nominalOnlyCuts.count(cutID) == 1) {
+    addEvent(cutID, 0, weight);
+    return;
+  }
 
+  for (size_t i = 0; i < m_containers.size(); ++i) {
+    addEvent(cutID, i, weight);
+  }
+}
+
+
+
+void
+CutFlowSvc::addEvent( CutIdentifier cutID,
+                      size_t index,
+                      double weight )
+{
   std::lock_guard<std::recursive_mutex> lock(m_addEventMutex);
 
-  xAOD::CutBookkeeper* cbk = getCutBookkeeper(cutID, 0);
+  ATH_MSG_VERBOSE("Adding event with weight " << weight << " to cut " << cutID << " for variation " << index);
+
+  xAOD::CutBookkeeper* cbk = getCutBookkeeper(cutID, index);
   if (cbk == nullptr) {
-    ATH_MSG_ERROR("Could not find CutBookkeeper for CutID " << cutID);
+    ATH_MSG_ERROR("Could not find CutBookkeeper for CutID " << cutID << " and variation " << index);
     return;
   }
 
-  ATH_MSG_VERBOSE( "addEvent: have cutID " << cutID
-                   << " and CutBookkeeper name " << cbk->name() );
   cbk->addNAcceptedEvents(1);
   cbk->addSumOfEventWeights(weight);
   cbk->addSumOfEventWeightsSquared(weight*weight);
-  return;
 }
 
 
@@ -294,6 +329,10 @@ const CutBookkeepersLocalCache& CutFlowSvc::getCutBookkeepers() const
 xAOD::CutBookkeeper* CutFlowSvc::getCutBookkeeper(const CutIdentifier cutID,
                                                   size_t index) const
 {
+  if (index >= m_containers.size()) {
+    return nullptr;
+  }
+
   for (xAOD::CutBookkeeper* cbk : *m_containers.at(index)) {
     if (cbk->uniqueIdentifier() == cutID) {
       return cbk;
diff --git a/Event/EventBookkeeperTools/Root/FilterReporter.cxx b/Event/EventBookkeeperTools/Root/FilterReporter.cxx
index 48d69f637a89..c4a60f1243de 100644
--- a/Event/EventBookkeeperTools/Root/FilterReporter.cxx
+++ b/Event/EventBookkeeperTools/Root/FilterReporter.cxx
@@ -27,6 +27,7 @@ FilterReporter (FilterReporterParams& val_params,
                 bool val_passedDefault)
   : m_params (val_params)
   , m_passed (val_passedDefault)
+  , m_eventContext (&Gaudi::Hive::currentContext())
 {
   if (!m_params.m_isInitialized)
   {
@@ -55,10 +56,6 @@ FilterReporter (const FilterReporterParams& val_params,
 FilterReporter ::
 ~FilterReporter () noexcept
 {
-#ifndef XAOD_STANDALONE
-  if (m_eventContext == nullptr)
-    m_eventContext = &Gaudi::Hive::currentContext();
-#endif
   m_params.m_setFilterPassed (m_passed, m_eventContext);
 
   if (m_passed)
@@ -68,14 +65,13 @@ FilterReporter ::
 #ifndef XAOD_STANDALONE
   if (m_passed && m_params.m_cutID != 0)
   {
-    double weight{1.0};
-
     SG::ReadHandle<xAOD::EventInfo> evtInfo (m_params.m_eventInfoKey, *m_eventContext);
     // Only try to access the mcEventWeight if we are running on Monte Carlo
     if (evtInfo.isValid() && evtInfo->eventType(xAOD::EventInfo::IS_SIMULATION)) {
-      weight = evtInfo->mcEventWeight();
+      m_params.m_cutFlowSvc->addEvent (m_params.m_cutID, evtInfo->mcEventWeights());
+    } else {
+      m_params.m_cutFlowSvc->addEvent (m_params.m_cutID, 1.0);
     }
-    m_params.m_cutFlowSvc->addEvent (m_params.m_cutID, weight);
   }
 #endif
 }
diff --git a/Event/EventBookkeeperTools/Root/FilterReporterParams.cxx b/Event/EventBookkeeperTools/Root/FilterReporterParams.cxx
index 07d5c0a69917..5de8580237a6 100644
--- a/Event/EventBookkeeperTools/Root/FilterReporterParams.cxx
+++ b/Event/EventBookkeeperTools/Root/FilterReporterParams.cxx
@@ -37,7 +37,7 @@ initialize (bool enabled)
   {
     ANA_CHECK (m_cutFlowSvc.retrieve());
 
-    m_cutID = m_cutFlowSvc->registerFilter (m_filterKey, m_filterDescription);
+    m_cutID = m_cutFlowSvc->registerFilter (m_filterKey, m_filterDescription, false);
     if (m_cutID == 0)
     {
       ANA_MSG_ERROR ("problem registering myself with the CutFlowSvc");
diff --git a/Event/EventBookkeeperTools/src/AllExecutedEventsCounterAlg.cxx b/Event/EventBookkeeperTools/src/AllExecutedEventsCounterAlg.cxx
index 4cacb8a86a95..79a14ab31406 100644
--- a/Event/EventBookkeeperTools/src/AllExecutedEventsCounterAlg.cxx
+++ b/Event/EventBookkeeperTools/src/AllExecutedEventsCounterAlg.cxx
@@ -25,9 +25,10 @@ StatusCode AllExecutedEventsCounterAlg::initialize()
   ATH_CHECK(m_filterParams.initialize());
 
   m_filterParams.cutFlowSvc()->registerTopFilter(m_filterParams.key(),
-                                              "Number of processed events before any cut",
-                                              xAOD::CutBookkeeper::CutLogic::ALLEVENTSPROCESSED,
-                                              "AllStreams");
+                                                 "Number of processed events before any cut",
+                                                 xAOD::CutBookkeeper::CutLogic::ALLEVENTSPROCESSED,
+                                                 "AllStreams",
+                                                 false);
 
   return StatusCode::SUCCESS;
 }
diff --git a/PhysicsAnalysis/Algorithms/SystematicsHandles/Root/SysFilterReporterParams.cxx b/PhysicsAnalysis/Algorithms/SystematicsHandles/Root/SysFilterReporterParams.cxx
index 3daac19f9e8e..415dedf1bb0e 100644
--- a/PhysicsAnalysis/Algorithms/SystematicsHandles/Root/SysFilterReporterParams.cxx
+++ b/PhysicsAnalysis/Algorithms/SystematicsHandles/Root/SysFilterReporterParams.cxx
@@ -39,7 +39,7 @@ namespace CP
     if (!m_cutFlowSvc.empty())
     {
       ANA_CHECK (m_cutFlowSvc.retrieve());
-      m_cutID = m_cutFlowSvc->registerFilter (m_cutFlowSvc.parentName(), m_filterDescription + " (nominal only)");
+      m_cutID = m_cutFlowSvc->registerFilter (m_cutFlowSvc.parentName(), m_filterDescription + " (nominal only)", false);
       if (m_cutID == 0)
       {
         ANA_MSG_ERROR ("problem registering myself with cutflow-svc");
diff --git a/PhysicsAnalysis/AnalysisCommon/ReweightUtils/src/SumOfWeightsAlg.cxx b/PhysicsAnalysis/AnalysisCommon/ReweightUtils/src/SumOfWeightsAlg.cxx
index 5437a38f071f..c8c47db50d77 100644
--- a/PhysicsAnalysis/AnalysisCommon/ReweightUtils/src/SumOfWeightsAlg.cxx
+++ b/PhysicsAnalysis/AnalysisCommon/ReweightUtils/src/SumOfWeightsAlg.cxx
@@ -51,7 +51,8 @@ StatusCode SumOfWeightsAlg::initialize() {
     CutIdentifier cID = cutFlowSvc()->registerTopFilter( toolName,
                                                          toolName, // description (can be improved FIXME)
                                                          xAOD::CutBookkeeper::CutLogic::ALLEVENTSPROCESSED,
-                                                         "AllStreams");
+                                                         "AllStreams",
+                                                         true);
     m_cutIDs.push_back(cID);
   }
 
-- 
GitLab


From c41e07a310a6b62a1550a465da3b762f9519800d Mon Sep 17 00:00:00 2001
From: Tadej Novak <tadej.novak@cern.ch>
Date: Wed, 28 Oct 2020 18:26:20 +0100
Subject: [PATCH 2/4] Remove legacy EventCounterAlg

---
 .../share/AthenaPoolExample_Write.ref         |   1 +
 .../share/POOLEventSelector_testJobOptions.py |  17 ---
 .../share/xAODEventSelector_testJobOptions.py |  17 ---
 .../python/CutFlowHelpers.py                  |   8 +-
 .../src/EventCounterAlg.cxx                   | 133 ------------------
 .../src/EventCounterAlg.h                     |  83 -----------
 .../EventBookkeeperTools_entries.cxx          |   2 -
 .../share/AnalysisCommon_topOptions.py        |   4 -
 .../share/RecExCommon_topOptions.py           |   6 +-
 9 files changed, 10 insertions(+), 261 deletions(-)
 delete mode 100644 Database/AthenaRoot/AthenaRootComps/share/POOLEventSelector_testJobOptions.py
 delete mode 100644 Database/AthenaRoot/AthenaRootComps/share/xAODEventSelector_testJobOptions.py
 delete mode 100644 Event/EventBookkeeperTools/src/EventCounterAlg.cxx
 delete mode 100644 Event/EventBookkeeperTools/src/EventCounterAlg.h

diff --git a/Database/AthenaPOOL/AthenaPoolExample/AthenaPoolExampleAlgorithms/share/AthenaPoolExample_Write.ref b/Database/AthenaPOOL/AthenaPoolExample/AthenaPoolExampleAlgorithms/share/AthenaPoolExample_Write.ref
index 2becbbbeeee7..73870aa96e19 100644
--- a/Database/AthenaPOOL/AthenaPoolExample/AthenaPoolExampleAlgorithms/share/AthenaPoolExample_Write.ref
+++ b/Database/AthenaPOOL/AthenaPoolExample/AthenaPoolExampleAlgorithms/share/AthenaPoolExample_Write.ref
@@ -1360,6 +1360,7 @@ Domain[ROOT_All]     INFO ->  Deaccess DbDatabase   CREATE    [ROOT_All] ????
 Domain[ROOT_All]     INFO >   Deaccess DbDomain     UPDATE    [ROOT_All] 
 ApplicationMgr       INFO Application Manager Stopped successfully
 IncidentProcAlg1     INFO Finalize
+AllExecutedEvents    INFO accepted 20 out of 20 events for filter AllExecutedEvents (Number of processed events before any cut)
 WriteData            INFO in finalize()
 WriteTag             INFO in finalize()
 MagicWriteTag        INFO in finalize()
diff --git a/Database/AthenaRoot/AthenaRootComps/share/POOLEventSelector_testJobOptions.py b/Database/AthenaRoot/AthenaRootComps/share/POOLEventSelector_testJobOptions.py
deleted file mode 100644
index c03b9bd21742..000000000000
--- a/Database/AthenaRoot/AthenaRootComps/share/POOLEventSelector_testJobOptions.py
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-#this joboption is used in performance monitoring to compare to xAODEventSelector
-
-theApp.EvtMax = -1
-
-import os
-
-jps.AthenaCommonFlags.FilesInput = [os.environ.get("ASG_TEST_FILE_MC","/afs/cern.ch/user/a/asgbase/patspace/xAODs/r7725/mc15_13TeV.410000.PowhegPythiaEvtGen_P2012_ttbar_hdamp172p5_nonallhad.merge.AOD.e3698_s2608_s2183_r7725_r7676/AOD.07915862._000100.pool.root.1")]
-
-
-
-import AthenaPoolCnvSvc.ReadAthenaPool
-
-
-algseq = CfgMgr.AthSequencer("AthAlgSeq")
-algseq += CfgMgr.EventCounterAlg(BookkeepOtherMCEventWeights=True)
diff --git a/Database/AthenaRoot/AthenaRootComps/share/xAODEventSelector_testJobOptions.py b/Database/AthenaRoot/AthenaRootComps/share/xAODEventSelector_testJobOptions.py
deleted file mode 100644
index 224aebf4e92b..000000000000
--- a/Database/AthenaRoot/AthenaRootComps/share/xAODEventSelector_testJobOptions.py
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-#this joboption is used in performance monitoring to compare to POOL
-
-theApp.EvtMax = -1
-
-import os
-
-jps.AthenaCommonFlags.FilesInput = [os.environ.get("ASG_TEST_FILE_MC","/afs/cern.ch/user/a/asgbase/patspace/xAODs/r7725/mc15_13TeV.410000.PowhegPythiaEvtGen_P2012_ttbar_hdamp172p5_nonallhad.merge.AOD.e3698_s2608_s2183_r7725_r7676/AOD.07915862._000100.pool.root.1")]
-
-
-
-import AthenaRootComps.ReadAthenaxAODHybrid
-
-
-algseq = CfgMgr.AthSequencer("AthAlgSeq")
-algseq += CfgMgr.EventCounterAlg(BookkeepOtherMCEventWeights=True)
diff --git a/Event/EventBookkeeperTools/python/CutFlowHelpers.py b/Event/EventBookkeeperTools/python/CutFlowHelpers.py
index dcef71543bda..fa5d50aafd0c 100644
--- a/Event/EventBookkeeperTools/python/CutFlowHelpers.py
+++ b/Event/EventBookkeeperTools/python/CutFlowHelpers.py
@@ -71,7 +71,7 @@ def CreateCutFlowSvc( svcName="CutFlowSvc", seq=None, addMetaDataToAllOutputFile
         seq = CfgMgr.AthSequencer("AthAlgSeq")
         pass
 
-    # First of all, schedule EventCounterAlg
+    # First of all, schedule AllExecutedEventsCounterAlg
     if not hasattr(seq,"AllExecutedEvents"):
         if not seq.isLocked():
             # Need to schedule it after the xAODMaker::EventInfoCnvAlg such that xAOD::EventInfo is present
@@ -82,11 +82,11 @@ def CreateCutFlowSvc( svcName="CutFlowSvc", seq=None, addMetaDataToAllOutputFile
                     if alg.getName() == "xAODMaker::EventInfoCnvAlg": break
                     pass
                 pass
-            msg.debug("Adding EventCounterAlg with name AllExecutedEvents to sequence with name %s at position %i", seq.getName(), index)
-            seq.insert( index, CfgMgr.EventCounterAlg("AllExecutedEvents") )
+            msg.debug("Adding AllExecutedEventsCounterAlg with name AllExecutedEvents to sequence with name %s at position %i", seq.getName(), index)
+            seq.insert( index, CfgMgr.AllExecutedEventsCounterAlg("AllExecutedEvents") )
             pass
         else :
-            msg.info("Could NOT add EventCounterAlg with name AllExecutedEvents to locked sequence with name %s", seq.getName())
+            msg.info("Could NOT add AllExecutedEventsCounterAlg with name AllExecutedEvents to locked sequence with name %s", seq.getName())
             pass
         pass
 
diff --git a/Event/EventBookkeeperTools/src/EventCounterAlg.cxx b/Event/EventBookkeeperTools/src/EventCounterAlg.cxx
deleted file mode 100644
index 8dc1d40a930c..000000000000
--- a/Event/EventBookkeeperTools/src/EventCounterAlg.cxx
+++ /dev/null
@@ -1,133 +0,0 @@
-///////////////////////// -*- C++ -*- /////////////////////////////
-
-/*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
-*/
-
-// EventCounterAlg.cxx
-// Implementation file for class EventCounterAlg
-// Author: S.Binet<binet@cern.ch>
-///////////////////////////////////////////////////////////////////
-
-// EventBookkeeperTools includes
-#include "EventCounterAlg.h"
-
-// STL includes
-//#include <stdio.h>
-//#include <stdlib.h>
-//#include <printf.h>
-#include <iostream>
-
-// EDM includes
-#include "xAODCutFlow/CutBookkeeper.h"
-#include "xAODEventInfo/EventInfo.h"
-#include "StoreGate/ReadHandle.h"
-
-
-
-///////////////////////////////////////////////////////////////////
-// Public methods:
-///////////////////////////////////////////////////////////////////
-
-// Constructors
-////////////////
-EventCounterAlg::EventCounterAlg( const std::string& name,
-                                  ISvcLocator* pSvcLocator ) :
-  ::AthFilterAlgorithm( name, pSvcLocator ),
-  m_trackOtherMCWeights(false),
-  m_eventsProcessed(0),
-  m_mcCutIDs()
-{
-  //
-  // Property declaration
-  //
-  declareProperty( "BookkeepOtherMCEventWeights", m_trackOtherMCWeights=true,
-                   "If true, the non-nominal MC event weights will be bookkept as well" );
-}
-
-
-
-// Destructor
-///////////////
-EventCounterAlg::~EventCounterAlg()
-{}
-
-
-
-// Athena Algorithm's Hooks
-////////////////////////////
-StatusCode EventCounterAlg::initialize()
-{
-  ATH_MSG_DEBUG ("Initializing " << this->name() << "...");
-
-  cutFlowSvc()->registerTopFilter( this->name(),
-                                   "Number of processed events before any cut",
-                                   xAOD::CutBookkeeper::CutLogic::ALLEVENTSPROCESSED,
-                                   "AllStreams");
-
-  return StatusCode::SUCCESS;
-}
-
-
-
-StatusCode EventCounterAlg::finalize()
-{
-  ATH_MSG_DEBUG ("Finalizing " << this->name() << "...");
-  return StatusCode::SUCCESS;
-}
-
-
-
-StatusCode EventCounterAlg::execute()
-{
-  const EventContext& ctx = Gaudi::Hive::currentContext();
-  ATH_MSG_VERBOSE ("Executing " << this->name() << "...");
-
-  setFilterPassed(true);
-
-  // Update also the other counters for the non-nominal MC weights
-  if (m_trackOtherMCWeights) {
-    // Get the EventInfo object
-    SG::ReadHandle<xAOD::EventInfo> evtInfo (eventInfoKey(), ctx);
-    // Only try to access the mcEventWeight is we are running on Monte Carlo, duhhh!
-    if ( !(evtInfo->eventType(xAOD::EventInfo::IS_SIMULATION)) ) {
-      ATH_MSG_DEBUG("We are not running on simulation and thus, nothing to be done here");
-      m_trackOtherMCWeights = false;
-      return StatusCode::SUCCESS;
-    }
-
-    // Get all MC event weights
-    const std::vector<float>& mcWeights = evtInfo->mcEventWeights();
-
-    // Set up everything during the first event
-    if ( m_eventsProcessed == 0 ){
-      const std::size_t nNonNominalMCWeight = mcWeights.size() - 1;
-      m_mcCutIDs.reserve(nNonNominalMCWeight);
-      for ( std::size_t i=1; i<mcWeights.size(); ++i ) {
-        std::stringstream sstm;
-        sstm << this->name() << "_NonNominalMCWeight_" << i;
-        const std::string cutName = sstm.str();
-        std::stringstream sstm2;
-        sstm2 << "non-nominal MC event weight number " << i;
-        const std::string& cutDescription = sstm2.str();
-        CutIdentifier cutID = cutFlowSvc()->registerTopFilter( cutName,
-                                                               cutDescription,
-                                                               xAOD::CutBookkeeper::CutLogic::ALLEVENTSPROCESSED,
-                                                               "AllStreams" );
-        m_mcCutIDs.push_back(cutID);
-      }
-    }
-
-    // Increment the non-nominal MC event weight counters
-    for ( std::size_t i=0; i<m_mcCutIDs.size(); ++i) {
-      const double weight = static_cast<double>(mcWeights[i+1]);
-      const CutIdentifier cutID = m_mcCutIDs[i];
-      cutFlowSvc()->addEvent( cutID, weight );
-    }
-
-    // Increment the event counter
-    m_eventsProcessed += 1;
-  }
-
-  return StatusCode::SUCCESS;
-}
diff --git a/Event/EventBookkeeperTools/src/EventCounterAlg.h b/Event/EventBookkeeperTools/src/EventCounterAlg.h
deleted file mode 100644
index e489cf7ba495..000000000000
--- a/Event/EventBookkeeperTools/src/EventCounterAlg.h
+++ /dev/null
@@ -1,83 +0,0 @@
-///////////////////////// -*- C++ -*- /////////////////////////////
-
-/*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
-*/
-
-// EventCounterAlg.h
-// Header file for class EventCounterAlg
-// Author: S.Binet<binet@cern.ch>
-///////////////////////////////////////////////////////////////////
-#ifndef EVENTBOOKKEEPERTOOLS_EVENTCOUNTERALG_H
-#define EVENTBOOKKEEPERTOOLS_EVENTCOUNTERALG_H 1
-
-// STL includes
-#include <string>
-#include <vector>
-
-// FrameWork includes
-#include "AthenaBaseComps/AthFilterAlgorithm.h"
-#include "StoreGate/ReadHandleKey.h"
-#include "xAODEventInfo/EventInfo.h"
-
-
-class EventCounterAlg
-  : public ::AthFilterAlgorithm
-{
-
-  ///////////////////////////////////////////////////////////////////
-  // Public methods:
-  ///////////////////////////////////////////////////////////////////
- public:
-
-  // Copy constructor:
-
-  /// Constructor with parameters:
-  EventCounterAlg( const std::string& name, ISvcLocator* pSvcLocator );
-
-  /// Destructor:
-  virtual ~EventCounterAlg();
-
-  // Assignment operator:
-  //EventCounterAlg &operator=(const EventCounterAlg &alg);
-
-  // Athena algorithm's Hooks
-  virtual StatusCode  initialize() override;
-  virtual StatusCode  execute() override;
-  virtual StatusCode  finalize() override;
-
-  ///////////////////////////////////////////////////////////////////
-  // Const methods:
-  ///////////////////////////////////////////////////////////////////
-
-  ///////////////////////////////////////////////////////////////////
-  // Non-const methods:
-  ///////////////////////////////////////////////////////////////////
-
-  ///////////////////////////////////////////////////////////////////
-  // Private data:
-  ///////////////////////////////////////////////////////////////////
- private:
-
-  /// Default constructor:
-  EventCounterAlg();
-
-  /// Property to set if all MC event-weights, including the non-nominal ones, should be tracked
-  bool m_trackOtherMCWeights;
-
-  /// An event counter
-  unsigned long m_eventsProcessed;
-
-  /// Keep a vector of all cutIDs for the non-nominal MC event weights
-  std::vector<CutIdentifier> m_mcCutIDs;
-};
-
-// I/O operators
-//////////////////////
-
-///////////////////////////////////////////////////////////////////
-// Inline methods:
-///////////////////////////////////////////////////////////////////
-
-
-#endif //> !EVENTBOOKKEEPERTOOLS_EVENTCOUNTERALG_H
diff --git a/Event/EventBookkeeperTools/src/components/EventBookkeeperTools_entries.cxx b/Event/EventBookkeeperTools/src/components/EventBookkeeperTools_entries.cxx
index 464b2a0f96de..44daab678e59 100644
--- a/Event/EventBookkeeperTools/src/components/EventBookkeeperTools_entries.cxx
+++ b/Event/EventBookkeeperTools/src/components/EventBookkeeperTools_entries.cxx
@@ -3,12 +3,10 @@
 #include <EventBookkeeperTools/CutFlowSvc.h>
 
 #include "../AllExecutedEventsCounterAlg.h"
-#include "../EventCounterAlg.h"
 #include "../TestFilterReentrantAlg.h"
 
 DECLARE_COMPONENT( AllExecutedEventsCounterAlg )
 DECLARE_COMPONENT( BookkeeperDumperTool )
 DECLARE_COMPONENT( BookkeeperTool )
 DECLARE_COMPONENT( CutFlowSvc )
-DECLARE_COMPONENT( EventCounterAlg )
 DECLARE_COMPONENT( TestFilterReentrantAlg )
diff --git a/Reconstruction/RecExample/RecExCommon/share/AnalysisCommon_topOptions.py b/Reconstruction/RecExample/RecExCommon/share/AnalysisCommon_topOptions.py
index af8117f22ff0..5b4dc9e81d2c 100644
--- a/Reconstruction/RecExample/RecExCommon/share/AnalysisCommon_topOptions.py
+++ b/Reconstruction/RecExample/RecExCommon/share/AnalysisCommon_topOptions.py
@@ -377,10 +377,6 @@ if rec.doDPD() and (rec.DPDMakerScripts()!=[] or rec.doDPD.passThroughMode):
         #    pass
         pass
 
-    # #First of all, schedule EventCounterAlg
-    # from EventBookkeeperTools.EventCounterAlg import EventCounterAlg
-    # topSequence+=EventCounterAlg("AllExecutedEvents")
-
     #Then include all requested DPD makers
     logAnaCommon_topOptions.debug( "Content of rec.DPDMakerSkripts = %s", rec.DPDMakerScripts() )
     for DPDMaker in rec.DPDMakerScripts():
diff --git a/Reconstruction/RecExample/RecExCommon/share/RecExCommon_topOptions.py b/Reconstruction/RecExample/RecExCommon/share/RecExCommon_topOptions.py
index f38fbfeedb7a..c3cbe33b32d8 100644
--- a/Reconstruction/RecExample/RecExCommon/share/RecExCommon_topOptions.py
+++ b/Reconstruction/RecExample/RecExCommon/share/RecExCommon_topOptions.py
@@ -981,7 +981,11 @@ if rec.doTrigger and rec.doTriggerFilter() and globalflags.DataSource() == 'data
 ### seq will be our filter sequence
         from AthenaCommon.AlgSequence import AthSequencer
         seq=AthSequencer("AthMasterSeq")
-        seq+=CfgMgr.EventCounterAlg("AllExecutedEventsAthMasterSeq")
+
+        from EventBookkeeperTools.CutFlowHelpers import CreateCutFlowSvc
+        logRecExCommon_topOptions.debug("Calling CreateCutFlowSvc")
+        CreateCutFlowSvc( svcName="CutFlowSvc", seq=seq, addMetaDataToAllOutputFiles=True )
+
         seq+=topSequence.RoIBResultToxAOD
         seq+=topSequence.TrigBSExtraction
         seq+=topSequence.TrigDecMaker
-- 
GitLab


From 6cd9ce758a48a3c43c6189c1400f723694fac0bb Mon Sep 17 00:00:00 2001
From: Tadej Novak <tadej.novak@cern.ch>
Date: Fri, 30 Oct 2020 17:58:45 +0100
Subject: [PATCH 3/4] Write out all CutFlow variations

---
 Event/EventBookkeeperTools/python/CutFlowHelpers.py       | 8 ++++----
 .../python/EventBookkeeperToolsConfig.py                  | 8 ++++----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/Event/EventBookkeeperTools/python/CutFlowHelpers.py b/Event/EventBookkeeperTools/python/CutFlowHelpers.py
index fa5d50aafd0c..deda3827fb64 100644
--- a/Event/EventBookkeeperTools/python/CutFlowHelpers.py
+++ b/Event/EventBookkeeperTools/python/CutFlowHelpers.py
@@ -96,10 +96,10 @@ def CreateCutFlowSvc( svcName="CutFlowSvc", seq=None, addMetaDataToAllOutputFile
         from OutputStreamAthenaPool.MultipleStreamManager import MSMgr
         # Explicitely add file metadata from input and from transient store,
         # but only the ones that we always create.
-        MSMgr.AddMetaDataItemToAllStreams( "xAOD::CutBookkeeperContainer#"+primary_name )
-        MSMgr.AddMetaDataItemToAllStreams( "xAOD::CutBookkeeperAuxContainer#"+primary_name+"Aux.*" )
-        MSMgr.AddMetaDataItemToAllStreams( "xAOD::CutBookkeeperContainer#Incomplete"+primary_name )
-        MSMgr.AddMetaDataItemToAllStreams( "xAOD::CutBookkeeperAuxContainer#Incomplete"+primary_name+"Aux.*" )
+        MSMgr.AddMetaDataItemToAllStreams( "xAOD::CutBookkeeperContainer#"+primary_name+"*" )
+        MSMgr.AddMetaDataItemToAllStreams( "xAOD::CutBookkeeperAuxContainer#"+primary_name+"*Aux.*" )
+        MSMgr.AddMetaDataItemToAllStreams( "xAOD::CutBookkeeperContainer#Incomplete"+primary_name+"*" )
+        MSMgr.AddMetaDataItemToAllStreams( "xAOD::CutBookkeeperAuxContainer#Incomplete"+primary_name+"*Aux.*" )
         pass
 
     return
diff --git a/Event/EventBookkeeperTools/python/EventBookkeeperToolsConfig.py b/Event/EventBookkeeperTools/python/EventBookkeeperToolsConfig.py
index 0465d1f5b3cf..af6472f8988b 100644
--- a/Event/EventBookkeeperTools/python/EventBookkeeperToolsConfig.py
+++ b/Event/EventBookkeeperTools/python/EventBookkeeperToolsConfig.py
@@ -40,8 +40,8 @@ def CutFlowSvcCfg(flags):
 def CutFlowOutputList(flags, base_name='CutBookkeepers'):
     """CutFlow output metadata list"""
     return [
-        'xAOD::CutBookkeeperContainer#' + base_name,
-        'xAOD::CutBookkeeperAuxContainer#' + base_name + 'Aux.*',
-        'xAOD::CutBookkeeperContainer#Incomplete' + base_name,
-        'xAOD::CutBookkeeperAuxContainer#Incomplete' + base_name + 'Aux.*'
+        'xAOD::CutBookkeeperContainer#' + base_name + '*',
+        'xAOD::CutBookkeeperAuxContainer#' + base_name + '*Aux.*',
+        'xAOD::CutBookkeeperContainer#Incomplete' + base_name + '*',
+        'xAOD::CutBookkeeperAuxContainer#Incomplete' + base_name + '*Aux.*'
     ]
-- 
GitLab


From 3f3c2e9f726e5155659ae28ad4cb8bacf01d1d99 Mon Sep 17 00:00:00 2001
From: Tadej Novak <tadej.novak@cern.ch>
Date: Fri, 6 Nov 2020 15:26:44 +0100
Subject: [PATCH 4/4] CutFlowSvc: restore children cuts

---
 .../AthenaKernel/AthenaKernel/ICutFlowSvc.h   |  8 ++++
 .../EventBookkeeperTools/CutFlowSvc.h         |  8 ++++
 .../EventBookkeeperTools/Root/CutFlowSvc.cxx  | 37 +++++++++++++++++--
 3 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/Control/AthenaKernel/AthenaKernel/ICutFlowSvc.h b/Control/AthenaKernel/AthenaKernel/ICutFlowSvc.h
index 3259e34f7f6c..0d1e1ee31676 100644
--- a/Control/AthenaKernel/AthenaKernel/ICutFlowSvc.h
+++ b/Control/AthenaKernel/AthenaKernel/ICutFlowSvc.h
@@ -59,6 +59,14 @@ public:
                                            const std::string& outputStream,
                                            bool nominalOnly ) = 0;
 
+  /// Register cut as child of a filter in the CutFlowSvc and returns the CutID
+  /// of the corresponding EventBookkeeper. This method should be used by
+  /// filters to register their internal cuts that are not the Algs themselves.
+  virtual CutIdentifier registerCut( const std::string& name,
+                                     const std::string& description,
+                                     CutIdentifier parentCutID,
+                                     bool nominalOnly ) = 0;
+
   /// Set the description of an existing EventBookkeeper
   virtual void setFilterDescription( CutIdentifier cutID,
                                      const std::string& descr ) = 0;
diff --git a/Event/EventBookkeeperTools/EventBookkeeperTools/CutFlowSvc.h b/Event/EventBookkeeperTools/EventBookkeeperTools/CutFlowSvc.h
index f10b34efdd98..7004df94c64f 100644
--- a/Event/EventBookkeeperTools/EventBookkeeperTools/CutFlowSvc.h
+++ b/Event/EventBookkeeperTools/EventBookkeeperTools/CutFlowSvc.h
@@ -81,6 +81,14 @@ public:
                                           const std::string& outputStream,
                                           bool nominalOnly) override final;
 
+  /// Register cut as child of a filter in the CutFlowSvc and returns the CutID
+  /// of the corresponding EventBookkeeper. This method should be used by
+  /// filters to register their internal cuts that are not the Algs themselves.
+  virtual CutIdentifier registerCut(const std::string& name,
+                                    const std::string& description,
+                                    CutIdentifier parentCutID,
+                                    bool nominalOnly) override final;
+
   /// Set the description of an existing CutBookkeeper
   virtual void setFilterDescription(CutIdentifier cutID,
                                     const std::string& descr) override final;
diff --git a/Event/EventBookkeeperTools/Root/CutFlowSvc.cxx b/Event/EventBookkeeperTools/Root/CutFlowSvc.cxx
index 16ea58203867..3b366e8d7670 100644
--- a/Event/EventBookkeeperTools/Root/CutFlowSvc.cxx
+++ b/Event/EventBookkeeperTools/Root/CutFlowSvc.cxx
@@ -80,14 +80,14 @@ CutIdentifier CutFlowSvc::registerFilter( const std::string& name,
   for (xAOD::CutBookkeeper* cbk : *container) {
     if (newCbk->isEqualTo(cbk)) {
       ATH_MSG_DEBUG("The CutBookkeeper with name '" << name << "' already exists"
-                    << " and has cutID " << cbk->uniqueIdentifier() << "... Not adding!" );
+                    << " and has CutID " << cbk->uniqueIdentifier() << "... Not adding!" );
       // Return the existing cut ID
       return cbk->uniqueIdentifier();
     }
   }
 
   // If it is a new CutBookkeeper, add it to the container
-  ATH_MSG_DEBUG("Declaring a new filter with name '" << name << "' and cutID " << cutID );
+  ATH_MSG_DEBUG("Declaring a new filter with name '" << name << "' and CutID " << cutID );
   container->push_back(std::move(newCbk));
 
   if (nominalOnly) {
@@ -114,7 +114,7 @@ CutIdentifier CutFlowSvc::registerTopFilter( const std::string& name,
   CutIdentifier cutID = registerFilter(name, description, nominalOnly);
   xAOD::CutBookkeeper* cbk = getCutBookkeeper(cutID, 0);
   if (cbk == nullptr) {
-    ATH_MSG_ERROR("registerTopFilter: Could not find CutBookkeeper with cutID " << cutID);
+    ATH_MSG_ERROR("Could not find CutBookkeeper with CutID " << cutID);
     return 0;
   }
 
@@ -127,6 +127,37 @@ CutIdentifier CutFlowSvc::registerTopFilter( const std::string& name,
 }
 
 
+CutIdentifier CutFlowSvc::registerCut( const std::string& name,
+                                       const std::string& description,
+                                       CutIdentifier parentCutID,
+                                       bool nominalOnly )
+{
+  ATH_MSG_DEBUG("Registering cut with name '" << name << "', description '" << description
+                << "' and original CutID " << parentCutID);
+
+  // Get the CutBookkeeper of the origin Filter Algorithm/Tool
+  xAOD::CutBookkeeper* parentCbk = getCutBookkeeper(parentCutID, 0);
+  if (parentCbk == nullptr) {
+    ATH_MSG_ERROR("Could not find parent CutBookkeeper with CutID " << parentCutID);
+    return 0;
+  }
+
+  // Call the registerFilter method and get the correct CutBookkeeper
+  // from the returned cutID
+  CutIdentifier cutID = registerFilter(name, description, nominalOnly);
+  xAOD::CutBookkeeper* cbk = getCutBookkeeper(cutID, 0);
+  if (cbk == nullptr) {
+    ATH_MSG_ERROR("Could not find CutBookkeeper with CutID " << cutID);
+    return 0;
+  }
+
+  // Add child to parent
+  parentCbk->addChild(cbk);
+
+  return cutID;
+}
+
+
 void
 CutFlowSvc::setFilterDescription( CutIdentifier cutID,
                                   const std::string& descr )
-- 
GitLab