QwAnalysis
QwParity.cc File Reference

main(...) function for the qwanalysis executable More...

#include <iostream>
#include <fstream>
#include <vector>
#include <new>
#include <boost/shared_ptr.hpp>
#include "Rtypes.h"
#include "TROOT.h"
#include "TFile.h"
#include "QwLog.h"
#include "QwRootFile.h"
#include "QwOptionsParity.h"
#include "QwEventBuffer.h"
#include "QwParityDB.h"
#include "QwHistogramHelper.h"
#include "QwSubsystemArrayParity.h"
#include "QwHelicityPattern.h"
#include "QwEventRing.h"
#include "QwEPICSEvent.h"
#include "QwRegression.h"
#include "QwRegressionSubsystem.h"
#include "QwPromptSummary.h"
#include "QwHelicity.h"
#include "QwFakeHelicity.h"
#include "QwBeamLine.h"
#include "QwMainCerenkovDetector.h"
#include "QwScanner.h"
#include "QwLumi.h"
#include "QwBeamMod.h"
#include "QwIntegratedRaster.h"
+ Include dependency graph for QwParity.cc:

Go to the source code of this file.

Functions

Int_t main (Int_t argc, Char_t *argv[])
 

Detailed Description

main(...) function for the qwanalysis executable

Definition in file QwParity.cc.

Function Documentation

Int_t main ( Int_t  argc,
Char_t *  argv[] 
)

without anything, print usage

First, fill the search paths for the parameter files; this sets a static variable within the QwParameterFile class which will be used by all instances. The "scratch" directory should be first.

Then, we set the command line arguments and the configuration filename, and we define the options that can be used in them (using QwOptions).

Define the command line options

Load command line options for the histogram/tree helper class

Setup screen and file logging

Create the event buffer

Create the database connection

Start loop over all runs

Begin processing for the first run

Set the current event number for parameter file lookup

Create an EPICS event

Load the detectors from file

Create event-based linear regression subsystem

Create the helicity pattern

Create the asymmetry-based linear regression

Create the event ring with the subsystem array

Create the running sum

Start loop over events

Definition at line 51 of file QwParity.cc.

References QwHelicityPattern::AccumulateRunningBurstSum(), QwSubsystemArrayParity::AccumulateRunningSum(), QwRegression::AccumulateRunningSum(), QwOptions::AddConfigFile(), QwOptions::AddOptions(), QwDatabase::AllowsWriteAccess(), QwParameterFile::AppendToSearchPath(), QwSubsystemArrayParity::ApplySingleEventCuts(), QwSubsystemArray::AtEndOfEventLoop(), QwHelicityPattern::CalculateAsymmetry(), QwHelicityPattern::CalculateBurstAverage(), QwRegression::CalculateRunningAverage(), QwSubsystemArrayParity::CalculateRunningAverage(), QwHelicityPattern::CalculateRunningAverage(), QwHelicityPattern::CalculateRunningBurstAverage(), QwHelicityPattern::ClearBurstSum(), QwSubsystemArray::ClearEventData(), QwHelicityPattern::ClearEventData(), QwHelicityPattern::ClearRunningSum(), QwEventBuffer::CloseStream(), QwRootFile::ConstructHistograms(), QwRootFile::ConstructTreeBranches(), default_bool_value, DefineOptionsParity(), QwLog::endl(), QwRegression::FillDB(), QwHelicityPattern::FillDB(), QwSubsystemArrayParity::FillDB_MPS(), QwEventBuffer::FillEPICSData(), QwHelicityPattern::FillErrDB(), QwRootFile::FillHistograms(), QwParityDB::FillParameterFiles(), QwEventBuffer::FillSubsystemConfigurationData(), QwEventBuffer::FillSubsystemData(), QwRootFile::FillTree(), QwRootFile::FillTreeBranches(), QwHelicityPattern::GetBurstAsymmetry(), QwHelicityPattern::GetBurstDifference(), QwHelicityPattern::GetBurstYield(), getenv_safe_string(), QwEventBuffer::GetEventNumber(), QwEventBuffer::GetNextEvent(), QwEventBuffer::GetRunLabel(), QwEventBuffer::GetRunNumber(), QwEventBuffer::GetSegmentNumber(), QwOptions::GetValue(), gQwHists, gQwLog, gQwOptions, QwSubsystemArrayParity::IncrementErrorCounters(), QwHelicityPattern::IsBurstSumEnabled(), QwHelicityPattern::IsCompletePattern(), QwHelicityPattern::IsEndOfBurst(), QwEventBuffer::IsEPICSEvent(), QwHelicityPattern::IsGoodAsymmetry(), QwEventBuffer::IsPhysicsEvent(), QwEventRing::IsReady(), QwEventBuffer::IsROCConfigurationEvent(), QwHelicityPattern::IsRunningSumEnabled(), QwRegression::kRegTypeAsym, QwRegression::LinearRegression(), QwOptions::ListConfigFiles(), QwSubsystemArray::ListPublishedValues(), QwHelicityPattern::LoadEventData(), QwEventBuffer::OpenNextStream(), QwEventRing::pop(), QwSubsystemArrayParity::PrintErrorCounters(), QwSubsystemArray::PrintParamFileList(), QwEventBuffer::PrintRunTimes(), QwRegression::PrintValue(), QwSubsystemArrayParity::PrintValue(), QwSubsystemArray::ProcessEvent(), QwHistogramHelper::ProcessOptions(), QwEPICSEvent::ProcessOptions(), QwHelicityPattern::ProcessOptions(), QwEventBuffer::ProcessOptions(), QwLog::ProcessOptions(), QwSubsystemArray::ProcessOptions(), QwEventRing::push(), QwMessage, QwEventBuffer::ReOpenStream(), MQwCodaControlEvent::ReportRunSummary(), QwOptions::SetCommandLine(), QwParameterFile::SetCurrentRunNumber(), QwParityDB::SetupOneRun(), QwSubsystemArray::ShareHistograms(), QwHelicityPattern::UpdateBlinder(), QwOptions::Usage(), QwRootFile::Write(), QwRootFile::WriteParamFileList(), and QwHelicityPattern::WritePromptSummary().

52 {
53  /// without anything, print usage
54  if(argc == 1){
55  gQwOptions.Usage();
56  exit(0);
57  }
58 
59  /// First, fill the search paths for the parameter files; this sets a
60  /// static variable within the QwParameterFile class which will be used by
61  /// all instances.
62  /// The "scratch" directory should be first.
64  QwParameterFile::AppendToSearchPath(getenv_safe_string("QWANALYSIS") + "/Parity/prminput");
65  QwParameterFile::AppendToSearchPath(getenv_safe_string("QWANALYSIS") + "/Analysis/prminput");
66 
67  /// Then, we set the command line arguments and the configuration filename,
68  /// and we define the options that can be used in them (using QwOptions).
69  gQwOptions.AddOptions()("single-output-file", po::value<bool>()->default_bool_value(false), "Write a single output file");
70  gQwOptions.AddOptions()("print-errorcounters", po::value<bool>()->default_bool_value(true), "Print summary of error counters");
71  gQwOptions.AddOptions()("write-promptsummary", po::value<bool>()->default_bool_value(false), "Write PromptSummary");
72 
73  gQwOptions.SetCommandLine(argc, argv);
74  gQwOptions.AddConfigFile("qweak_mysql.conf");
75 
77 
78  /// Define the command line options
80  /// Load command line options for the histogram/tree helper class
82  /// Setup screen and file logging
84 
85 
86  /// Create the event buffer
87  QwEventBuffer eventbuffer;
88  eventbuffer.ProcessOptions(gQwOptions);
89 
90  /// Create the database connection
91  QwParityDB database(gQwOptions);
92 
93 
94  // QwPromptSummary promptsummary;
95 
96  /// Start loop over all runs
97  while (eventbuffer.OpenNextStream() == CODA_OK) {
98 
99  /// Begin processing for the first run
100 
101  Int_t run_number = eventbuffer.GetRunNumber();
102 
103  /// Set the current event number for parameter file lookup
105 
106  // if (gQwOptions.GetValue<bool>("write-promptsummary")) {
107  QwPromptSummary promptsummary(run_number, eventbuffer.GetSegmentNumber());
108  // }
109  /// Create an EPICS event
110  QwEPICSEvent epicsevent;
111  epicsevent.ProcessOptions(gQwOptions);
112  epicsevent.LoadChannelMap("EpicsTable.map");
113 
114  /// Load the detectors from file
116  detectors.ProcessOptions(gQwOptions);
117  detectors.ListPublishedValues();
118 
119  /// Create event-based linear regression subsystem
120  // TString name = "MpsRegression";
121  // QwRegressionSubsystem regress_sub(gQwOptions, detectors, name);
122  // detectors.push_back(regress_sub.GetSharedPointerToStaticObject());
123 
124  /// Create the helicity pattern
125  QwHelicityPattern helicitypattern(detectors);
126  helicitypattern.ProcessOptions(gQwOptions);
127 
128  /// Create the asymmetry-based linear regression
129  QwRegression regression(gQwOptions,helicitypattern);
130  QwRegression running_regression(regression);
131 
132  /// Create the event ring with the subsystem array
133  QwEventRing eventring(gQwOptions,detectors);
134  // Make a copy of the detectors object to hold the
135  // events which pass through the ring.
136  QwSubsystemArrayParity ringoutput(detectors);
137 
138  /// Create the running sum
139  QwSubsystemArrayParity runningsum(detectors);
140 
141 
142  // Initialize the database connection.
143  database.SetupOneRun(eventbuffer);
144 
145  // Open the ROOT file (close when scope ends)
146  QwRootFile *treerootfile = NULL;
147  QwRootFile *burstrootfile = NULL;
148  QwRootFile *historootfile = NULL;
149 
150  TString run_label = eventbuffer.GetRunLabel();
151 
152 
153  if (gQwOptions.GetValue<bool>("single-output-file")) {
154 
155  treerootfile = new QwRootFile(run_label);
156  burstrootfile = historootfile = treerootfile;
157  // Construct a tree which contains map file names which are used to analyze data
158  treerootfile->WriteParamFileList("mapfiles", detectors);
159 
160  } else {
161 
162  treerootfile = new QwRootFile(run_label + ".trees");
163  burstrootfile = new QwRootFile(run_label + ".bursts");
164  historootfile = new QwRootFile(run_label + ".histos");
165 
166  // Construct a tree which contains map file names which are used to analyze data
167  detectors.PrintParamFileList();
168  treerootfile->WriteParamFileList("mapfiles", detectors);
169  burstrootfile->WriteParamFileList("mapfiles", detectors);
170  historootfile->WriteParamFileList("mapfiles", detectors);
171  }
172 
173  if (database.AllowsWriteAccess()) {
174  database.FillParameterFiles(detectors);
175  }
176 
177  // Construct histograms
178  historootfile->ConstructHistograms("mps_histo", ringoutput);
179  historootfile->ConstructHistograms("hel_histo", helicitypattern);
180  detectors.ShareHistograms(ringoutput);
181 
182  // Construct tree branches
183  treerootfile->ConstructTreeBranches("Mps_Tree", "MPS event data tree", ringoutput);
184  treerootfile->ConstructTreeBranches("Hel_Tree", "Helicity event data tree", helicitypattern);
185  treerootfile->ConstructTreeBranches("Hel_Tree_Reg", "Helicity event data tree (regressed)", regression);
186  treerootfile->ConstructTreeBranches("Slow_Tree", "EPICS and slow control tree", epicsevent);
187  burstrootfile->ConstructTreeBranches("Burst_Tree", "Burst level data tree", helicitypattern.GetBurstYield(),"yield_");
188  burstrootfile->ConstructTreeBranches("Burst_Tree", "Burst level data tree", helicitypattern.GetBurstAsymmetry(),"asym_");
189  burstrootfile->ConstructTreeBranches("Burst_Tree", "Burst level data tree", helicitypattern.GetBurstDifference(),"diff_");
190 
191  // Summarize the ROOT file structure
192  //treerootfile->PrintTrees();
193  //treerootfile->PrintDirs();
194 
195 
196  // Clear the single-event running sum at the beginning of the runlet
197  runningsum.ClearEventData();
198  helicitypattern.ClearRunningSum();
199  // Clear the running sum of the burst values at the beginning of the runlet
200  helicitypattern.ClearBurstSum();
201 
202 
203  // Load the blinder seed from the database for this runlet.
204  helicitypattern.UpdateBlinder(&database);
205 
206  // Find the first EPICS event and try to initialize
207  // the blinder.
208  QwMessage << "Finding first EPICS event" << QwLog::endl;
209  while (eventbuffer.GetNextEvent() == CODA_OK) {
210  if (eventbuffer.IsEPICSEvent()) {
211  eventbuffer.FillEPICSData(epicsevent);
212  if (epicsevent.HasDataLoaded()) {
213  helicitypattern.UpdateBlinder(epicsevent);
214  // and break out of this event loop
215  break;
216  }
217  }
218  }
219  epicsevent.ResetCounters();
220  // Rewind stream
221  QwMessage << "Rewinding stream" << QwLog::endl;
222  eventbuffer.ReOpenStream();
223 
224  /// Start loop over events
225  while (eventbuffer.GetNextEvent() == CODA_OK) {
226 
227  // First, do processing of non-physics events...
228  if (eventbuffer.IsROCConfigurationEvent()) {
229  // Send ROC configuration event data to the subsystem objects.
230  eventbuffer.FillSubsystemConfigurationData(detectors);
231  }
232 
233  // Secondly, process EPICS events
234  if (eventbuffer.IsEPICSEvent()) {
235  eventbuffer.FillEPICSData(epicsevent);
236  if (epicsevent.HasDataLoaded()){
237  epicsevent.CalculateRunningValues();
238  helicitypattern.UpdateBlinder(epicsevent);
239 
240  treerootfile->FillTreeBranches(epicsevent);
241  treerootfile->FillTree("Slow_Tree");
242  }
243  }
244 
245 
246  // Now, if this is not a physics event, go back and get a new event.
247  if (! eventbuffer.IsPhysicsEvent()) continue;
248 
249 
250 
251  // Fill the subsystem objects with their respective data for this event.
252  eventbuffer.FillSubsystemData(detectors);
253 
254  // Process the subsystem data
255  detectors.ProcessEvent();
256 
257 
258 
259  // The event pass the event cut constraints
260  if (detectors.ApplySingleEventCuts()) {
261 
262  // // TEST
263  // regress_sub.LinearRegression();
264 
265  // Add event to the ring
266  eventring.push(detectors);
267 
268  // Check to see ring is ready
269  if (eventring.IsReady()) {
270  ringoutput = eventring.pop();
271  ringoutput.IncrementErrorCounters();
272 
273 
274  // Accumulate the running sum to calculate the event based running average
275  runningsum.AccumulateRunningSum(ringoutput);
276 
277  // Fill the histograms
278  historootfile->FillHistograms(ringoutput);
279 
280  // Fill mps tree branches
281  treerootfile->FillTreeBranches(ringoutput);
282  treerootfile->FillTree("Mps_Tree");
283 
284  // Load the event into the helicity pattern
285  helicitypattern.LoadEventData(ringoutput);
286 
287  // Calculate helicity pattern asymmetry
288  if (helicitypattern.IsCompletePattern()) {
289 
290  // Update the blinder if conditions have changed
291  helicitypattern.UpdateBlinder(ringoutput);
292 
293  // Calculate the asymmetry
294  helicitypattern.CalculateAsymmetry();
295  if (helicitypattern.IsGoodAsymmetry()) {
296 
297  // Fill histograms
298  historootfile->FillHistograms(helicitypattern);
299 
300  // Fill helicity tree branches
301  treerootfile->FillTreeBranches(helicitypattern);
302  treerootfile->FillTree("Hel_Tree");
303 
304  // Burst mode
305  if (helicitypattern.IsEndOfBurst()) {
306  helicitypattern.AccumulateRunningBurstSum();
307  helicitypattern.CalculateBurstAverage();
308 
309  // Fill burst tree branches
310  burstrootfile->FillTreeBranches(helicitypattern.GetBurstYield());
311  burstrootfile->FillTreeBranches(helicitypattern.GetBurstAsymmetry());
312  burstrootfile->FillTreeBranches(helicitypattern.GetBurstDifference());
313  burstrootfile->FillTree("Burst_Tree");
314 
315  // Clear the data
316  helicitypattern.ClearBurstSum();
317  }
318 
319  // Linear regression on asymmetries
320  regression.LinearRegression(QwRegression::kRegTypeAsym);
321  running_regression.AccumulateRunningSum(regression);
322 
323  // Fill regressed tree branches
324  treerootfile->FillTreeBranches(regression);
325  treerootfile->FillTree("Hel_Tree_Reg");
326 
327  // Clear the data
328  helicitypattern.ClearEventData();
329 
330  } // helicitypattern.IsGoodAsymmetry()
331 
332  } // helicitypattern.IsCompletePattern()
333 
334  } // eventring.IsReady()
335 
336  } // detectors.ApplySingleEventCuts()
337 
338  } // end of loop over events
339 
340  // Perform actions at the end of the event loop on the
341  // detectors object, which ought to have handles for the
342  // MPS based histograms.
343  ringoutput.AtEndOfEventLoop();
344 
345  QwMessage << "Number of events processed at end of run: "
346  << eventbuffer.GetEventNumber() << QwLog::endl;
347 
348 
349  // Calculate running averages over helicity patterns
350  if (helicitypattern.IsRunningSumEnabled()) {
351  helicitypattern.CalculateRunningAverage();
352  if (helicitypattern.IsBurstSumEnabled()) {
353  helicitypattern.CalculateRunningBurstAverage();
354  }
355  }
356 
357  running_regression.CalculateRunningAverage();
358  running_regression.PrintValue();
359 
360  // This will calculate running averages over single helicity events
361  runningsum.CalculateRunningAverage();
362  if (gQwOptions.GetValue<bool>("print-runningsum")) {
363  QwMessage << " Running average of events" << QwLog::endl;
364  QwMessage << " =========================" << QwLog::endl;
365  runningsum.PrintValue();
366  }
367 
368 
369  /* Write to the root file, being sure to delete the old cycles *
370  * which were written by Autosave. *
371  * Doing this will remove the multiple copies of the ntuples *
372  * from the root file. *
373  * *
374  * Then, we need to delete the histograms here. *
375  * If we wait until the subsystem destructors, we get a *
376  * segfault; but in addition to that we should delete them *
377  * here, in case we run over multiple runs at a time. */
378  if (treerootfile == historootfile) {
379  treerootfile->Write(0,TObject::kOverwrite);
380  delete treerootfile; treerootfile = 0; burstrootfile = 0; historootfile = 0;
381  } else {
382  treerootfile->Write(0,TObject::kOverwrite);
383  burstrootfile->Write(0,TObject::kOverwrite);
384  historootfile->Write(0,TObject::kOverwrite);
385  delete treerootfile; treerootfile = 0;
386  delete burstrootfile; burstrootfile = 0;
387  delete historootfile; historootfile = 0;
388  }
389 
390  // Print the event cut error summary for each subsystem
391  if (gQwOptions.GetValue<bool>("print-errorcounters")) {
392  QwMessage << " ------------ error counters ------------------ " << QwLog::endl;
393  ringoutput.PrintErrorCounters();
394  }
395 
396  if (gQwOptions.GetValue<bool>("write-promptsummary")) {
397  // runningsum.WritePromptSummary(&promptsummary, "yield");
398  // runningsum.WritePromptSummary(&promptsummary, "asymmetry");
399  // runningsum.WritePromptSummary(&promptsummary, "difference");
400  helicitypattern.WritePromptSummary(&promptsummary);
401  promptsummary.PrintCSV();
402  }
403  // Read from the database
404  database.SetupOneRun(eventbuffer);
405 
406  // Each subsystem has its own Connect() and Disconnect() functions.
407  if (database.AllowsWriteAccess()) {
408  helicitypattern.FillDB(&database);
409  helicitypattern.FillErrDB(&database);
410  epicsevent.FillDB(&database);
411  running_regression.FillDB(&database,"asymmetry");
412  ringoutput.FillDB_MPS(&database, "optics");
413  }
414 
415 
416  //epicsevent.WriteEPICSStringValues();
417 
418  // Close event buffer stream
419  eventbuffer.CloseStream();
420 
421 
422 
423  // Report run summary
424  eventbuffer.ReportRunSummary();
425  eventbuffer.PrintRunTimes();
426  } // end of loop over runs
427 
428  QwMessage << "I have done everything I can do..." << QwLog::endl;
429 
430  return 0;
431 }
void ProcessOptions(QwOptions &options)
Process the configuration options.
Definition: QwEPICSEvent.cc:83
#define QwMessage
Predefined log drain for regular messages.
Definition: QwLog.h:50
static void AppendToSearchPath(const TString &searchdir)
Add a directory to the search path.
Bool_t FillSubsystemConfigurationData(QwSubsystemArray &subsystems)
#define default_bool_value(b)
Definition: QwOptions.h:51
Int_t GetSegmentNumber() const
Return CODA file segment number.
Definition: QwEventBuffer.h:82
Int_t ReOpenStream()
Int_t WriteParamFileList(const TString &name, T &object)
Definition: QwRootFile.h:736
void ConstructHistograms(const std::string &name, T &object)
Construct the histograms of a generic object.
Definition: QwRootFile.h:706
void DefineOptionsParity(QwOptions &options)
void ProcessOptions(QwOptions &options)
Sets internal flags based on the QwOptions.
Int_t OpenNextStream()
Opens the event stream (file or ET) based on the internal flags.
static void SetCurrentRunNumber(const UInt_t runnumber)
Set the current run number for looking up the appropriate parameter file.
Int_t CloseStream()
Closes a currently open event stream.
QwOptions gQwOptions
Definition: QwOptions.cc:27
void ProcessOptions(QwOptions *options)
Process class options for QwOptions.
Definition: QwLog.cc:108
Int_t FillTree(const std::string &name)
Fill the tree with name.
Definition: QwRootFile.h:359
po::options_description_easy_init AddOptions(const std::string &blockname="Specialized options")
Add an option to a named block or create new block.
Definition: QwOptions.h:164
Int_t GetEventNumber()
Int_t GetNextEvent()
void ProcessOptions(QwOptions &options)
Process the configuration options.
T GetValue(const std::string &key)
Get a templated value.
Definition: QwOptions.h:240
void Usage()
Print usage information.
Definition: QwOptions.cc:288
void ListConfigFiles()
List the configuration files.
Definition: QwOptions.h:214
Virtual base class for the parity subsystems.
A wrapper class for a ROOT file or memory mapped file.
Definition: QwRootFile.h:281
Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Definition: QwRootFile.h:437
void AddConfigFile(const std::string &configfile)
Add a configuration file.
Definition: QwOptions.h:199
void ConstructTreeBranches(const std::string &name, const std::string &desc, T &object, const std::string &prefix="")
Construct the tree branches of a generic object.
Definition: QwRootFile.h:600
Int_t GetRunNumber() const
Return CODA file run number.
Definition: QwEventBuffer.h:80
Bool_t IsEPICSEvent()
QwHistogramHelper gQwHists
Globally defined instance of the QwHistogramHelper class.
Bool_t FillSubsystemData(QwSubsystemArray &subsystems)
void PrintRunTimes()
static std::ostream & endl(std::ostream &)
End of the line.
Definition: QwLog.cc:299
void FillTreeBranches(const std::string &name, const T &object)
Fill the tree branches of a generic object by tree name.
Definition: QwRootFile.h:658
const std::string getenv_safe_string(const char *name)
Definition: QwOptions.h:37
void FillHistograms(T &object)
Fill histograms of the subsystem array.
Definition: QwRootFile.h:329
TString GetRunLabel() const
Returns a string like &lt;run#&gt; or &lt;run#&gt;.&lt;file#&gt;
Bool_t FillEPICSData(QwEPICSEvent &epics)
Bool_t IsPhysicsEvent()
QwLog gQwLog
Definition: QwLog.cc:22
Bool_t IsROCConfigurationEvent()
void SetCommandLine(int argc, char *argv[], bool default_config_file=true)
Set the command line arguments.
Definition: QwOptions.cc:112