From 8669a94e63201799472273cf3da1afa028c91f47 Mon Sep 17 00:00:00 2001
From: "Stephen A. Wood" <saw@jlab.org>
Date: Mon, 9 Feb 2015 16:49:37 -0500
Subject: [PATCH] Add "Global variables" to reports.   Variable found in a
 report template is first tested to see if it is a   Hall C style parameter
 (in gHcParms).  If not, then tested to see if it   is a global variable (in
 gHaVars).

---
 examples/report.template |  1 +
 src/THcAnalyzer.cxx      |  2 +-
 src/THcFormula.cxx       | 76 ++++++++++++++++++++++++++++++++++++++--
 src/THcFormula.h         |  9 ++++-
 4 files changed, 84 insertions(+), 4 deletions(-)

diff --git a/examples/report.template b/examples/report.template
index df78bb4..bb41e4f 100644
--- a/examples/report.template
+++ b/examples/report.template
@@ -69,4 +69,5 @@ last event  = {gen_event_id_number:%7d}
 Later, such things as hardware scalers will be added to the set of variables
 that can be used in expressions.
 
+Last momenutm: {H.tr.p[0]}
 
diff --git a/src/THcAnalyzer.cxx b/src/THcAnalyzer.cxx
index 6d3f0c9..117df87 100644
--- a/src/THcAnalyzer.cxx
+++ b/src/THcAnalyzer.cxx
@@ -110,7 +110,7 @@ void THcAnalyzer::PrintReport(const char* templatefile, const char* ofile)
 	if(format.empty()) format = "%s";
 	replacement=Form(format.c_str(),textstring);
       } else {
-	THcFormula* formula = new THcFormula("temp",expression.c_str(),gHcParms, gHaCuts);
+	THcFormula* formula = new THcFormula("temp",expression.c_str(),gHcParms,gHaVars,gHaCuts);
 	Double_t value=formula->Eval();
 	// If the value is close to integer and no format is defined
 	// use "%.0f" to print out integer
diff --git a/src/THcFormula.cxx b/src/THcFormula.cxx
index 0b12372..7740c06 100644
--- a/src/THcFormula.cxx
+++ b/src/THcFormula.cxx
@@ -12,6 +12,7 @@
 //////////////////////////////////////////////////////////////////////////
 
 #include "THcFormula.h"
+#include "THcParmList.h"
 #include "THaVarList.h"
 #include "THaCutList.h"
 #include "THaCut.h"
@@ -24,13 +25,15 @@ static const Double_t kBig = 1e38; // Error value
 
 //_____________________________________________________________________________
 THcFormula::THcFormula(const char* name, const char* expression, 
-		       const THaVarList* vlst, const THaCutList* clst ) :
+		       const THcParmList* plst, const THaVarList* vlst,
+		       const THaCutList* clst ) :
   THaFormula()
 {
 
   // We have to duplicate the TFormula constructor code here because of
   // the calls DefinedVariable.  Our version will only get called if
-  // to Compile(). Compile() only works if fVarList is set. 
+  // to Compile(). Compile() only works if fParmList is set. 
+  fParmList = plst;
   fVarList = vlst;
   fCutList = clst;
 
@@ -55,6 +58,23 @@ THcFormula::THcFormula(const char* name, const char* expression,
   Compile();   // This calls our own Compile()
 }
 
+//_____________________________________________________________________________
+THcFormula& THcFormula::operator=( const THcFormula& rhs )
+{
+  if( this != &rhs ) {
+    TFormula::operator=(rhs);
+    fNcodes = rhs.fNcodes;
+    fParmList = rhs.fParmList;
+    fVarList = rhs.fVarList;
+    fCutList = rhs.fCutList;
+    fError = rhs.fError;
+    fRegister = rhs.fRegister;
+    delete [] fVarDef;
+    fVarDef = new FVarDef_t[ kMAXCODES ];
+    memcpy( fVarDef, rhs.fVarDef, kMAXCODES*sizeof(FVarDef_t));
+  }
+  return *this;
+}
 
 //_____________________________________________________________________________
 THcFormula::~THcFormula()
@@ -140,6 +160,58 @@ Double_t THcFormula::DefinedValue( Int_t i )
   }
 }  
 
+
+//_____________________________________________________________________________
+Int_t THcFormula::DefinedGlobalVariable( const TString& name )
+{
+  // Check if 'name' is a known global variable. If so, enter it in the
+  // local list of variables used in this formula.
+
+  // No list of variables or too many variables in this formula?
+  if( (!fVarList && !fParmList) || fNcodes >= kMAXCODES )
+    return -2;
+
+
+  // Parse name for array syntax
+  THaArrayString var(name);
+  if( var.IsError() )
+    return -1;
+
+  // First check if this name is a Parameter
+  const THaVar* obj = fParmList->Find( var.GetName() );
+  if ( !obj) {  // If not, find a global variable with this name
+    obj = fVarList->Find( var.GetName() );
+    if( !obj )
+      return -1;
+  }
+
+  // Error if array requested but the corresponding variable is not an array
+  if( var.IsArray() && !obj->IsArray() )
+    return -2;
+
+  // Subscript(s) within bounds?
+  Int_t index = 0;
+  if( var.IsArray() 
+      && (index = obj->Index( var )) <0 ) return -2;
+		    
+  // Check if this variable already used in this formula
+  FVarDef_t* def = fVarDef;
+  for( Int_t i=0; i<fNcodes; i++, def++ ) {
+    if( obj == def->code && index == def->index )
+      return i;
+  }
+  // If this is a new variable, add it to the list
+  def->type = kVariable;
+  def->code = obj;
+  def->index = index;
+
+  // No parameters ever for a THaFormula
+  fNpar = 0;
+
+  return fNcodes++;
+}
+
+
 //_____________________________________________________________________________
 
 ClassImp(THcFormula)
diff --git a/src/THcFormula.h b/src/THcFormula.h
index 13e854c..0294ee6 100644
--- a/src/THcFormula.h
+++ b/src/THcFormula.h
@@ -7,23 +7,30 @@
 // 
 //////////////////////////////////////////////////////////////////////////
 
+#include "THcGlobals.h"
 #include "THaFormula.h"
 
+class THaParmList;
+
 class THcFormula : public THaFormula {
 
 public:
 
   THcFormula( const char* name, const char* formula, 
-	      const THaVarList*, const THaCutList* clst);
+	      const THcParmList*, const THaVarList*,
+	      const THaCutList* clst);
+  THcFormula& operator=( const THcFormula& rhs );
   virtual ~THcFormula();
 
   virtual Double_t DefinedValue( Int_t i);
   virtual Int_t    DefinedCut( const TString& variable);
+  virtual Int_t    DefinedGlobalVariable( const TString& variable);
 
 protected:
 
   enum {kCutScaler = kString+1};
   enum {kCutNCalled = kCutScaler+1};
+  const THcParmList* fParmList; // Pointer to list of parameters
   ClassDef(THcFormula,0) // Formula with cut scalers
 };
 
-- 
GitLab