Skip to content
Snippets Groups Projects
THcAnalyzer.cxx 5.22 KiB
Newer Older
  • Learn to ignore specific revisions
  • /** \class THcAnalyzer
        \ingroup Base
    
    \brief Hall C analyzer class.
    
    Adds the following to the Hall A analyzer base class.
    
    1.  PrintReport method to make text reports from template files
    
    2.  Retrieve run number and startind and ending event from parameter DB
    
    #include "THcAnalyzer.h"
    
    #include "THaRunBase.h"
    
    #include "THaBenchmark.h"
    #include "TList.h"
    
    #include "THcParmList.h"
    #include "THcFormula.h"
    #include "THcGlobals.h"
    #include "TMath.h"
    
    
    #include <fstream>
    #include <algorithm>
    #include <iomanip>
    #include <cstring>
    
    
    using namespace std;
    
    
    // Pointer to single instance of this object
    //THcAnalyzer* THcAnalyzer::fgAnalyzer = 0;
    
    
    // do we need to "close" scalers/EPICS analysis if we reach the event limit?
    
    //_____________________________________________________________________________
    
    THcAnalyzer::THcAnalyzer() : THaAnalyzer()
    
    {
    
    }
    
    //_____________________________________________________________________________
    THcAnalyzer::~THcAnalyzer()
    {
    
    //_____________________________________________________________________________
    void THcAnalyzer::PrintReport(const char* templatefile, const char* ofile)
    {
    
      /// Generate "reports" such as end of run scaler/efficiency sheets
      /// Reads a template file, copying that file to the output, replacing
      /// variables and expressions inside of braces ({}) with evaluated values.
      /// Similar but not identical to ENGINE/CTP report templates.
    
      ifstream ifile;
      ifile.open(templatefile);
    
      if(!ifile.is_open()) {
        cout << "Error opening template file " << templatefile << endl;
        return;
      }
    
      ofstream ostr(ofile);
    
      if(!ostr.is_open()) {
          cout << "Error opening report output file " << ofile << endl;
    
      LoadInfo();			// Load some run information into gHcParms
    
    
      // In principle, we should allow braces to be escaped.  But for
      // now we won't.  Existing template files don't seem to output
      // any braces
      for(string line; getline(ifile, line);) {
        //    cout << line << endl;
        string::size_type start;
        while((start = line.find('{',0)) != string::npos) {
          //      cout << start << endl;
          string::size_type end = line.find('}',start);
          if(end==string::npos) break; // No more expressions on the line
          string expression=line.substr(start+1,end-start-1);
          string::size_type formatpos = expression.find(':',0);
          string format;
          if(formatpos != string::npos) {
    	format=expression.substr(formatpos+1);
    	expression=expression.substr(0,formatpos);
    	//	cout << "|" << expression << "|" << format << "|" << endl;
          }
          // Should we first check if the expression can be simply a variable
          // or index into variable?
          // For now, first check if it is a string.
          // If not, then evaluate as an expression.
          string replacement;
          if(const char *textstring=gHcParms->GetString(expression)) {
    	//	cout << expression << " is a string with value " << textstring << endl;
    	if(format.empty()) format = "%s";
    	replacement=Form(format.c_str(),textstring);
          } else {
    
    	THcFormula* formula = new THcFormula("temp",expression.c_str(),gHcParms,gHaVars,gHaCuts);
    
    	Double_t value=formula->Eval();
    
    	delete formula; formula = 0;
    
    	// If the value is close to integer and no format is defined
    	// use "%.0f" to print out integer
    	if(format.empty()) {
    	  if(TMath::Abs(value-TMath::Nint(value)) < 0.0000001) {
    	    format = "%.0f";
    	  } else {
    	    format = "%f";
    	  }
    	}
    
    	if(format[format.length()-1] == 'd') {
    	  replacement=Form(format.c_str(),TMath::Nint(value));
    	} else {
    	  replacement=Form(format.c_str(),value);
    	}
    
          }
          //      cout << "Replacement:" << replacement << endl;
          line.replace(start,end-start+1,replacement);
        }
        ostr << line << endl;
      }
      ostr.close();
      ifile.close();
    
      return;
    }
    
    
    //_____________________________________________________________________________
    void THcAnalyzer::LoadInfo()
    {
    
      /// Create several THcParms variables in gHcParms containing
    
      /// run information such as
    
      // run number, first event analyzed, number of events, etc.
    
      ///    `gen_run_number` - Current run
      ///    `gen_run_starting_event` - Id of first event analyzed
      ///    `gen_event_id_number` - Id of last event analyzed
    
      Int_t* runnum;
      Int_t* firstevent;
      Int_t* lastevent;
    
      THaVar* varptr;
      varptr = gHcParms->Find("gen_run_number");
      if(varptr) {
        runnum = (Int_t*) varptr->GetValuePointer(); // Assume correct type
      } else {
        runnum = new Int_t[1];
        gHcParms->Define("gen_run_number","Run Number", *runnum);
      }
      *runnum = fRun->GetNumber();
    
      varptr = gHcParms->Find("gen_run_starting_event");
      if(varptr) {
        firstevent = (Int_t*) varptr->GetValuePointer(); // Assume correct type
      } else {
        firstevent = new Int_t[1];
        gHcParms->Define("gen_run_starting_event","First event analyzed", *firstevent);
      }
      // May not agree with engine event definintions
      *firstevent = fRun->GetFirstEvent();
    
      varptr = gHcParms->Find("gen_event_id_number");
      if(varptr) {
        lastevent = (Int_t*)varptr->GetValuePointer(); // Assume correct type
      } else {
        lastevent = new Int_t[1];
        gHcParms->Define("gen_event_id_number","Last event analyzed", *lastevent);
      }
      // Not accurate
      *lastevent = fRun->GetFirstEvent()+fRun->GetNumAnalyzed();