Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DEventProcessor_run_summary.cc
Go to the documentation of this file.
1 // $Id$
2 //
3 // File: DEventProcessor_run_summary.cc
4 // Created: Tue Nov 18 15:44:17 EST 2014
5 // Creator: sdobbs (on Linux ifarm1102 2.6.32-220.7.1.el6.x86_64 x86_64)
6 //
7 
9 #include "DEPICSstore.h"
10 
11 #include <DAQ/DEPICSvalue.h>
12 
13 #include <TDirectory.h>
14 
15 static int VERBOSE = 0;
16 
17 // Routine used to create our DEventProcessor
18 
19 extern "C"
20 {
21  void InitPlugin(JApplication *locApplication)
22  {
23  InitJANAPlugin(locApplication);
24  locApplication->AddProcessor(new DEventProcessor_run_summary()); //register this plugin
25  }
26 } // "C"
27 
28 //------------------
29 // init
30 //------------------
32 {
33  // This is called once at program startup. If you are creating
34  // and filling historgrams in this plugin, you should lock the
35  // ROOT mutex like this:
36  //
37  // japp->RootWriteLock();
38  // ... create historgrams or trees ...
39  // japp->RootUnLock();
40  //
41 
42  current_run_number = -1;
43  conditions_tree = NULL;
44  epics_info = NULL;
45 
46  // deal with command line parameters
47  gPARMS->SetDefaultParameter("SUMMARY:VERBOSE", VERBOSE,
48  "Verbosity level for creating summary values. 0=no messages, 10=all messages");
49  if(VERBOSE)
50  cout << "Run summary verbosity level = " << VERBOSE << endl;
51 
52  return NOERROR;
53 }
54 
55 //------------------
56 // brun
57 //------------------
58 jerror_t DEventProcessor_run_summary::brun(jana::JEventLoop* locEventLoop, int locRunNumber)
59 {
60  // This is called whenever the run number changes
61  // keep track of current run number for use in our end run function
62  current_run_number = locRunNumber;
63 
64  // make tree if it doesn't exist
65  japp->RootWriteLock();
66 
67  //Create a folder in the ROOT output file that will contain all of the output ROOT objects (if any) for this plugin
68  //If another thread has already created the folder, it just changes to it.
69  TDirectory *main_dir = gDirectory;
70  gDirectory->cd("/");
71 
72  TDirectory* plugin_dir = static_cast<TDirectory*>(gDirectory->GetDirectory("conditions")); // TDirectoryFile
73  if(plugin_dir == NULL)
74  plugin_dir = gDirectory->mkdir("conditions");
75  plugin_dir->cd();
76 
77  if(gDirectory->Get("conditions") == NULL) //check to see if already created by another thread
78  conditions_tree = new TTree("conditions","");
79  else //already created by another thread
80  conditions_tree = static_cast<TTree*>(gDirectory->Get("conditions"));
81 
82  main_dir->cd();
83 
84  japp->RootUnLock();
85 
86  // reset EPICS summary info each run
87  if(epics_info)
88  delete epics_info;
89  epics_info = new DEPICSstore;
90 
91  return NOERROR;
92 }
93 
94 //------------------
95 // evnt
96 //------------------
97 jerror_t DEventProcessor_run_summary::evnt(jana::JEventLoop* locEventLoop, uint64_t locEventNumber)
98 {
99  // This is called for every event. Use of common resources like writing
100  // to a file or filling a histogram should be mutex protected. Using
101  // locEventLoop->Get(...) to get reconstructed objects (and thereby activating the
102  // reconstruction algorithm) should be done outside of any mutex lock
103  // since multiple threads may call this method at the same time.
104  //
105  // Here's an example:
106  //
107  // vector<const MyDataClass*> mydataclasses;
108  // locEventLoop->Get(mydataclasses);
109  //
110  // japp->RootWriteLock();
111  // ... fill historgrams or trees ...
112  // japp->RootUnLock();
113 
114  // read in whatever epics values are in this event
115  vector<const DEPICSvalue*> epicsvalues;
116  locEventLoop->Get(epicsvalues);
117 
118  // save their values
119  for(vector<const DEPICSvalue*>::const_iterator val_itr = epicsvalues.begin();
120  val_itr != epicsvalues.end(); val_itr++) {
121  const DEPICSvalue* epics_val = *val_itr;
122  if(VERBOSE)
123  cout << "EPICS: " << epics_val->name << " = " << epics_val->sval << endl;
124 
125  if(epics_info)
126  epics_info->AddValue(epics_val);
127  else
128  jerr << "EPICS store object not loaded!" << endl;
129  }
130 
131  return NOERROR;
132 }
133 
134 //------------------
135 // erun
136 //------------------
138 {
139  // This is called whenever the run number changes, before it is
140  // changed to give you a chance to clean up before processing
141  // events from the next run number.
142 
143  // if we couldn't create the tree earlier, then throw it away
144  if(conditions_tree == NULL)
145  return NOERROR;
146 
147  // Although we are only filling objects local to this plugin, TTree::Fill() periodically writes to file: Global ROOT lock
148  japp->RootWriteLock(); //ACQUIRE ROOT LOCK
149 
150  // make a branch for the run number
151  TBranch *run_branch = conditions_tree->FindBranch("run_number");
152  if(run_branch == NULL)
153  conditions_tree->Branch("run_number", &current_run_number, "run_number/D");
154  else
155  conditions_tree->SetBranchAddress("run_number", &current_run_number);
156 
157  // make branches for each of the values
158  const map<string, DEPICSvalue_data_t> &epics_store = epics_info->GetStore();
159  for(map<string, DEPICSvalue_data_t>::const_iterator epics_val_itr = epics_store.begin();
160  epics_val_itr != epics_store.end(); epics_val_itr++) {
161  string branch_name = epics_val_itr->first;
162  // ROOT branches assume that colons define the different leaves in a branch
163  // so replace them in the name with underscores
164  std::replace( branch_name.begin(), branch_name.end(), ':', '_');
165  // also clean numerical expressions
166  std::replace( branch_name.begin(), branch_name.end(), '-', '_');
167  std::replace( branch_name.begin(), branch_name.end(), '+', '_');
168  std::replace( branch_name.begin(), branch_name.end(), '*', '_');
169  std::replace( branch_name.begin(), branch_name.end(), '/', '_');
170  TBranch *the_branch = conditions_tree->FindBranch(branch_name.c_str());
171  if(the_branch == NULL) {
172  string branch_def = branch_name + "/D";
173  conditions_tree->Branch(branch_name.c_str(), &(epics_val_itr->second.value->fval), branch_def.c_str());
174  } else {
175  conditions_tree->SetBranchAddress(branch_name.c_str(), &(epics_val_itr->second.value->fval));
176  }
177  }
178 
179  // save the values for this run
180  conditions_tree->Fill();
181 
182  japp->RootUnLock(); //RELEASE ROOT LOCK
183 
184  return NOERROR;
185 }
186 
187 //------------------
188 // fini
189 //------------------
191 {
192  // Called before program exit after event processing is finished.
193  //cout << "=================================================" << endl;
194  //cout << "Summary of processed runs:" << endl;
195  //cout << "=================================================" << endl;
196 
197  return NOERROR;
198 }
199 
void AddValue(const DEPICSvalue *new_value)
Definition: DEPICSstore.cc:32
jerror_t erun(void)
Called every time run number changes, provided brun has been called.
string sval
Definition: DEPICSvalue.h:65
jerror_t brun(jana::JEventLoop *locEventLoop, int locRunNumber)
Called every time a new run number is detected.
JApplication * japp
InitPlugin_t InitPlugin
const bool VERBOSE
map< string, DEPICSvalue_data_t > & GetStore()
Definition: DEPICSstore.h:48
string name
Definition: DEPICSvalue.h:64
jerror_t init(void)
Called once at program start.
jerror_t evnt(jana::JEventLoop *locEventLoop, uint64_t locEventNumber)
Called every event.
jerror_t fini(void)
Called after last event of last event source has been processed.
A DEPICSvalue object holds information for a single EPICS value read from the data stream...
Definition: DEPICSvalue.h:37