From d44082e3075bc828850a6ef22a5fa746a82771a8 Mon Sep 17 00:00:00 2001
From: Charles Burton <burton@utexas.edu>
Date: Tue, 13 Aug 2019 19:26:58 +0000
Subject: [PATCH] Create and fill Monitored::Group with a vector of variables

---
 .../AthenaMonitoring/AthMonitorAlgorithm.h    | 60 ++++++++++++-------
 .../AthenaMonitoring/MonitoredGroup.h         |  6 ++
 .../src/AthMonitorAlgorithm.cxx               | 12 ++++
 .../src/ExampleMonitorAlgorithm.cxx           |  5 ++
 4 files changed, 63 insertions(+), 20 deletions(-)

diff --git a/Control/AthenaMonitoring/AthenaMonitoring/AthMonitorAlgorithm.h b/Control/AthenaMonitoring/AthenaMonitoring/AthMonitorAlgorithm.h
index c78524baa38..59eaf244a55 100644
--- a/Control/AthenaMonitoring/AthenaMonitoring/AthMonitorAlgorithm.h
+++ b/Control/AthenaMonitoring/AthenaMonitoring/AthMonitorAlgorithm.h
@@ -77,37 +77,56 @@ public:
      */
     virtual StatusCode fillHistograms(const EventContext& ctx) const = 0;
 
+    /** @defgroup Group Filling Functions
+     *  A group of functions which fill monitored variables in groups.
+     *  @{
+     */
+    /**
+     * Fills a vector of variables to a group by reference. (BASE FILL)
+     *
+     * At the end of the fillHistograms routine, one should save the monitored variables
+     * to the group. This function wraps the process of getting the desired group by a
+     * call to AthMonitorAlgorithm::getGroup() and a call to Monitored::Group::fill(),
+     * which also disables the auto-fill feature to avoid double-filling. Note, users
+     * should avoid using this specific function name 'fill' in daughter classes.
+     *
+     * @param groupHandle A reference of the GenericMonitoringTool to which add variables
+     * @param variables Vector of monitored variables to be saved
+     */
+    void fill( const ToolHandle<GenericMonitoringTool>& groupHandle,
+               std::vector<std::reference_wrapper<Monitored::IMonitoredVariable>> variables ) const;
 
     /**
-     * Adds variables from an event to a group by name.
-     * 
-     * @param groupName The string name of the GenericMonitoringTool
-     * @param variables Variables desired to be saved.
-     * @return StatusCode
+     * Fills a variadic list of variables to a group by reference. Callse BASE FILL.
+     *
+     * @param groupHandle Reference to the GenericMonitoringTool
+     * @param variables... Variadic list of monitored variables to be saved
      */
     template <typename... T>
-    void fill( const std::string& groupName, T&&... variables ) const {
-        fill(getGroup(groupName),std::forward<T>(variables)...);
+    void fill( const ToolHandle<GenericMonitoringTool>& groupHandle, T&&... variables ) const {
+        fill(groupHandle,{std::forward<T>(variables)...});
     }
 
+    /**
+     * Fills a vector of variables to a group by name. Calls BASE FILL.
+     *
+     * @param groupHandle Reference to the GenericMonitoringTool
+     * @param variables Vector of monitored variables to be saved
+     */
+    void fill( const std::string& groupName,
+               std::vector<std::reference_wrapper<Monitored::IMonitoredVariable>> variables ) const;
 
     /**
-     * Adds variables from an event to a group by the group's object reference.
-     * 
-     * At the end of the fillHistograms routine, one should save the monitored variables 
-     * to the group. This function wraps the process of getting the desired group by a 
-     * call to AthMonitorAlgorithm::getGroup() and a call to Monitored::Group::fill(), 
-     * which also disables the auto-fill feature to avoid double-filling. Note, users 
-     * should avoid using this specific function name in daughter classes.
-     * 
-     * @param groupHandle A reference of the GenericMonitoringTool to which add variables.
-     * @param variables Variables desired to be saved
-     * @return StatusCode
+     * Fills a variadic list of variables to a group by name. Calls BASE FILL.
+     *
+     * @param groupName The string name of the GenericMonitoringTool
+     * @param variables... Variadic list of monitored variables to be saved
      */
     template <typename... T>
-    void fill( const ToolHandle<GenericMonitoringTool>& groupHandle, T&&... variables ) const {
-        Monitored::Group(groupHandle,std::forward<T>(variables)...).fill();
+    void fill( const std::string& groupName, T&&... variables ) const {
+        fill(getGroup(groupName),{std::forward<T>(variables)...});
     }
+    /** @} */ // end of fill group
 
 
     /**
@@ -323,6 +342,7 @@ protected:
     SG::ReadHandleKey<xAOD::EventInfo> m_EventInfoKey {this,"EventInfoKey","EventInfo"}; ///< Key for retrieving EventInfo from StoreGate
 
 private:
+    typedef std::vector<std::reference_wrapper<Monitored::IMonitoredVariable>> MonVarVec_t;
     std::string m_name;
 };
 
diff --git a/Control/AthenaMonitoring/AthenaMonitoring/MonitoredGroup.h b/Control/AthenaMonitoring/AthenaMonitoring/MonitoredGroup.h
index 05a29823a2d..3535ba5582c 100644
--- a/Control/AthenaMonitoring/AthenaMonitoring/MonitoredGroup.h
+++ b/Control/AthenaMonitoring/AthenaMonitoring/MonitoredGroup.h
@@ -46,6 +46,12 @@ namespace Monitored {
         m_monitoredGroup{monitoredGroup...},
         m_histogramsFillers(!m_tool.empty() ? m_tool->getHistogramsFillers(m_monitoredGroup) : std::vector<std::shared_ptr<Monitored::HistogramFiller>>()) { }
 
+    Group(const ToolHandle<GenericMonitoringTool>& tool, std::vector<std::reference_wrapper<IMonitoredVariable>> monitoredGroup)
+      : m_tool(tool),
+        m_autoFill(true),
+        m_monitoredGroup(monitoredGroup),
+        m_histogramsFillers(!m_tool.empty() ? m_tool->getHistogramsFillers(m_monitoredGroup) : std::vector<std::shared_ptr<Monitored::HistogramFiller>>()) { }
+
     virtual ~Group() {
       if (m_autoFill) {
         fill();
diff --git a/Control/AthenaMonitoring/src/AthMonitorAlgorithm.cxx b/Control/AthenaMonitoring/src/AthMonitorAlgorithm.cxx
index 89edbecc7dc..073a8a1f958 100644
--- a/Control/AthenaMonitoring/src/AthMonitorAlgorithm.cxx
+++ b/Control/AthenaMonitoring/src/AthMonitorAlgorithm.cxx
@@ -86,6 +86,18 @@ StatusCode AthMonitorAlgorithm::execute( const EventContext& ctx ) const {
 }
 
 
+void AthMonitorAlgorithm::fill( const ToolHandle<GenericMonitoringTool>& groupHandle,
+                                MonVarVec_t variables ) const {
+    Monitored::Group(groupHandle,variables).fill();
+}
+
+
+void AthMonitorAlgorithm::fill( const std::string& groupName,
+                                MonVarVec_t variables ) const {
+    fill(getGroup(groupName),variables);
+}
+
+
 SG::ReadHandle<xAOD::EventInfo> AthMonitorAlgorithm::GetEventInfo( const EventContext& ctx ) const {
     return SG::ReadHandle<xAOD::EventInfo>(m_EventInfoKey, ctx);
 }
diff --git a/Control/AthenaMonitoring/src/ExampleMonitorAlgorithm.cxx b/Control/AthenaMonitoring/src/ExampleMonitorAlgorithm.cxx
index 6fd4bcab827..2c6906c43fa 100644
--- a/Control/AthenaMonitoring/src/ExampleMonitorAlgorithm.cxx
+++ b/Control/AthenaMonitoring/src/ExampleMonitorAlgorithm.cxx
@@ -54,6 +54,11 @@ StatusCode ExampleMonitorAlgorithm::fillHistograms( const EventContext& ctx ) co
     // Alternative fill method. Get the group yourself, and pass it to the fill function.
     auto tool = getGroup("ExampleMonitor");
     fill(tool,run);
+
+    // Fill with a vector; useful in some circumstances.
+    std::vector<std::reference_wrapper<Monitored::IMonitoredVariable>> varVec = {lumiPerBCID,pT};
+    fill("ExampleMonitor",varVec);
+    fill(tool,varVec);
     
     return StatusCode::SUCCESS;
 }
-- 
GitLab