QwAnalysis
QwMoller.cc
Go to the documentation of this file.
1 /*------------------------------------------------------------------------*//*!
2 
3  \defgroup QwMoller QwMoller
4 
5 *//*-------------------------------------------------------------------------*/
6 
7 /*------------------------------------------------------------------------*//*!
8 
9  \file QwMoller.cc
10 
11  \ingroup QwMoller
12 
13  \brief Moller data analysis
14 
15 *//*-------------------------------------------------------------------------*/
16 
17 // C and C++ headers
18 #include <iostream>
19 #include <math.h>
20 #include <sstream>
21 
22 // Boost math library for random number generation
23 #include <boost/random.hpp>
24 
25 // ROOT headers
26 #include <TROOT.h>
27 #include <TFile.h>
28 #include <TTree.h>
29 
30 
31 // Qweak headers
32 #include "QwLog.h"
33 #include "QwOptionsParity.h"
34 #include "QwEventBuffer.h"
35 #include "QwHelicity.h"
36 #include "QwHelicityPattern.h"
37 #include "QwHistogramHelper.h"
38 #include "QwSubsystemArrayParity.h"
39 
40 // Moller headers
41 #include "QwMollerDetector.h"
42 
43 //global variables
44 static const int scal_num = 96;
46 
47 // Activate components
48 static bool bTree = true;
49 static bool bHisto = true;
50 static bool bHelicity = true;
51 
52 void setOptions();
53 
54 int main(int argc, char* argv[])
55 {
56 
57  std::cout << std::endl << " -= Moller Run Analyzer Started =-" << std::endl;
58  //QwParameterFile::AppendToSearchPath(".");
59  gQwOptions.SetConfigFile("moller.flags");
60 
61  /// Set the expected options, command line arguments and the configuration filename
62  setOptions();
63  gQwOptions.SetCommandLine(argc, argv);
64 
66  gQwOptions.Parse();
67 
68  std::cout << "bcm_offsets: " << gQwOptions.GetValue<float>("bcm1_offset") << ' ' << gQwOptions.GetValue<float>("bcm2_offset") << ' ' << \
69  gQwOptions.GetValue<float>("bcm3_offset") << std::endl;
70 
71  std::cout << "bcm_gains: " << gQwOptions.GetValue<float>("bcm1_gain") << ' ' << gQwOptions.GetValue<float>("bcm2_gain") << ' ' <<
72  gQwOptions.GetValue<float>("bcm3_gain") << std::endl;
73 
74  std::cout << "norm_bcm: " << gQwOptions.GetValue<float>("norm_bcm") << std::endl;
75 
76  /// Message logging facilities
77  gQwLog.InitLogFile("Moller.log", QwLog::kTruncate);
80 
81  /// Fill the search paths for the parameter files; this sets a static
82  /// variable within the QwParameterFile class which will be used by
83  /// all instances. The "scratch" directory should be first.
85  QwParameterFile::AppendToSearchPath(getenv_safe_string("QWANALYSIS") + "/Parity/prminput");
86 
87  // Load histogram definitions
88  gQwHists.LoadHistParamsFromFile("moller_hists.in");
89 
90 
91 
92  // Detector array
94  detectors.ProcessOptions(gQwOptions);
95  detectors.UpdateEventTypeMask();
96 
97  /// Create the running sum
98  QwSubsystemArrayParity runningsum(detectors);
99 
100  // Helicity pattern
101  QwHelicityPattern helicitypattern(detectors);
102 
103  // Event buffer
104  QwEventBuffer eventbuffer;
105 
106  std::string fileName;
107 
108  /// System setup complete,
109  /// Here's where we would loop over all specified runs
110  //UInt_t runnumber_min = (UInt_t) gQwOptions.GetIntValuePairFirst("run");
111  //UInt_t runnumber_max = (UInt_t) gQwOptions.GetIntValuePairLast("run");
112  //std::cout << "RUN: " << runnumber_min << " to " << runnumber_max << std::endl;
113  for (UInt_t run = 15; run <= 15; run++) {
114 
115  // Data file (input)
116  if (gQwOptions.HasValue("input_file")){
117  fileName = gQwOptions.GetValue<std::string>("input_file");
118  } else { // if (eventbuffer.OpenDataFile(TString("moller-moller_") + Form("%ld.log.0",run),"R")) {
119  fileName = TString("moller-moller_") + Form("%u.log.0",run);
120  // } else {
121  // QwError << "No Input File Specified!" << std::endl;
122  // return 1;
123  }
124 
125  // Open Data file
126  if (eventbuffer.OpenDataFile(fileName,"R") != CODA_OK) {
127  QwError << "Could not open file!" << QwLog::endl;
128  return 1;
129  }
130 
131  // ROOT file output (histograms)
132  TString rootfilename = getenv_safe("QW_ROOTFILES")
133  + TString("/Moller_") + Form("%u.root",run);
134  TFile rootfile(rootfilename, "RECREATE", "QWeak ROOT file");
135 
136  if (bHisto) {
137  rootfile.cd();
138  detectors.ConstructHistograms(rootfile.mkdir("moller_histo"));
139  if (bHelicity) {
140  rootfile.cd();
141  helicitypattern.ConstructHistograms(rootfile.mkdir("hel_histo"));
142  }
143  }
144 
145  // ROOT file output (expert tree)
146  if (bTree) {
147  rootfile.cd();
148  detectors.ConstructTree(rootfile.mkdir("expert"));
149  }
150 
151 
152  // ROOT file output (trees)
153  TTree *mpstree;
154  TTree *heltree;
155  std::vector <Double_t> mpsvector;
156  std::vector <Double_t> helvector;
157 
158  if (bTree) {
159  // MPS events
160  rootfile.cd();
161  mpstree = new TTree("MPS_Tree","MPS event data tree");
162  mpsvector.reserve(6000);
163  TString dummystr="";
164  detectors.ConstructBranchAndVector(mpstree, dummystr, mpsvector);
165 
166  rootfile.cd();
167  if (bHelicity) {
168  // Helicity events (per multiplet)
169  rootfile.cd();
170  heltree = new TTree("HEL_Tree","Helicity event data tree");
171  helvector.reserve(6000);
172  TString dummystr="";
173  helicitypattern.ConstructBranchAndVector(heltree, dummystr, helvector);
174  }
175  }
176 
177 
178 
179  while (eventbuffer.GetEvent() == CODA_OK) {
180 
181  /// First, do processing of non-physics events...
182  if (eventbuffer.IsROCConfigurationEvent()) {
183  std::cout << "it is ROC CONFIG event\n";
184  // Send ROC configuration event data to the subsystem objects.
185  // eventbuffer.FillSubsystemConfigurationData(detectors);
186  }
187 
188  if (!eventbuffer.IsPhysicsEvent()) continue;
189 
190  /// Add event into the subsystem
191  eventbuffer.FillSubsystemData(detectors);
192 
193  detectors.ProcessEvent();
194  detectors.IncrementErrorCounters();
195 
196  /// Helicity pattern
197  helicitypattern.LoadEventData(detectors);
198 
199  /// Accumulate the running sum to calculate the event based running average
200  runningsum.AccumulateRunningSum(detectors);
201 
202  /// Print the helicity information
203  //if (bHelicity && false) {
204  // - actual helicity
205  //std::cout << (helicity->GetHelicityReported() == 0 ? "-" : helicity->GetHelicityReported() == 1 ? "+" : "?");
206  // - delayed helicity
207  //std::cout << (helicity->GetHelicityActual() == 0 ? "(-) " : helicity->GetHelicityActual() == 1 ? "(+) " : "(?) ");
208  //if (helicity->GetPhaseNumber() == kMultiplet) {
209  // std::cout << std::uppercase << std::hex << helicity->GetRandomSeedActual() << ", \t";
210  // std::cout << helicity->GetRandomSeedDelayed() << std::dec << std::endl;
211  //}
212  //}
213 
214  /// Fill the histograms
215  if (bHisto) detectors.FillHistograms();
216 
217  /// Fill the expert tree
218  if (bTree) detectors.FillTree();
219 
220  /// Fill the tree
221  if (bTree) {
222  detectors.FillTreeVector(mpsvector);
223  mpstree->Fill();
224  }
225 
226  /// TODO We need another check here to test for pattern validity. Right
227  /// now the first 24 cycles are also added to the histograms.
228  if (bHelicity && helicitypattern.IsCompletePattern()) {
229  helicitypattern.CalculateAsymmetry();
230  if (bHisto) helicitypattern.FillHistograms();
231  // helicitypattern.ClearEventData();
232  }
233 
234 
235  /// Periodically print event number
236  if (eventbuffer.GetEventNumber() % 5000 == 0){
237  QwMessage << "Number of events processed so far: " << eventbuffer.GetEventNumber() << QwLog::endl;
238  }
239 
240  } /// end of loop over events
241 
242  std::cout << "Last event processed: " << eventbuffer.GetEventNumber() << std::endl;
243  /// Close ROOT file
244  rootfile.Write(0,TObject::kOverwrite);
245 
246  // Close data file and print run summary
247  eventbuffer.CloseDataFile();
248  eventbuffer.ReportRunSummary();
249 
250  } // end of loop over runs
251 
252  if (helicitypattern.IsEndOfBurst()) {
253  helicitypattern.AccumulateRunningBurstSum();
254  helicitypattern.CalculateBurstAverage();
255  helicitypattern.ClearBurstSum();
256  }
257 
258  if (helicitypattern.IsRunningSumEnabled()) {
259  helicitypattern.CalculateRunningAverage();
260  helicitypattern.PrintRunningAverage();
261  if (helicitypattern.IsBurstSumEnabled()) {
262  helicitypattern.CalculateRunningBurstAverage();
263  helicitypattern.PrintRunningBurstAverage();
264  }
265  }
266 
267  // This will calculate running averages over single helicity events
268  runningsum.CalculateRunningAverage();
269  QwMessage << " Running average of events" << QwLog::endl;
270  QwMessage << " =========================" << QwLog::endl;
271  runningsum.PrintValue();
272 
273 
274  std::cout << std::endl << " -= Moller Run Analyzer Ended =-" << std::endl << std::endl;
275  return 0;
276 }
277 
278 void setOptions(){
279  gQwOptions.AddOptions()("EXPERIMENT", po::value<std::string>(), "Name of the experiment");
280  gQwOptions.AddOptions()("input_file,f", po::value<std::string>(), "Input file to be used");
281  gQwOptions.AddOptions()("input_directory,d", po::value<std::string>(), "Directory to be searched for input files, default is current");
282  gQwOptions.AddOptions()("output_directory,o", po::value<std::string>(), "Directory where output files are saved");
283  gQwOptions.AddOptions()("pol_factor", po::value<float>(), "This needs to be explained to me");
284  gQwOptions.AddOptions()("bcm1_offset", po::value<float>(), " ");
285  gQwOptions.AddOptions()("bcm2_offset", po::value<float>(), " ");
286  gQwOptions.AddOptions()("bcm3_offset", po::value<float>(), " ");
287  gQwOptions.AddOptions()("bcm1_gain", po::value<float>(), " ");
288  gQwOptions.AddOptions()("bcm2_gain", po::value<float>(), " ");
289  gQwOptions.AddOptions()("bcm3_gain", po::value<float>(), " ");
290  gQwOptions.AddOptions()("norm_bcm", po::value<float>(), " ");
291  gQwOptions.AddOptions()("bcm1_index", po::value<int>(), " ");
292  gQwOptions.AddOptions()("bcm2_index", po::value<int>(), " ");
293  gQwOptions.AddOptions()("bcm3_index", po::value<int>(), " ");
294  gQwOptions.AddOptions()("clock_index", po::value<float>(), " ");
295  gQwOptions.AddOptions()("bcur_limit", po::value<float>(), " ");
296  gQwOptions.AddOptions()("timebin", po::value<float>(), " ");
297  gQwOptions.AddOptions()("bcur_units", po::value<std::string>(), " ");
298  gQwOptions.AddOptions()("helicity_pattern", po::value<int>()->default_value(4), "Length of the helicity window, should be 4, 8, or 16");
299 }
#define QwMessage
Predefined log drain for regular messages.
Definition: QwLog.h:50
void InitLogFile(const std::string name, const std::ios_base::openmode mode=kAppend)
Initialize the log file with name &#39;name&#39;.
Definition: QwLog.cc:157
void FillHistograms()
Fill the histograms for this subsystem.
void PrintValue() const
Print value of all channels.
static void AppendToSearchPath(const TString &searchdir)
Add a directory to the search path.
void ConstructHistograms()
Construct the histograms for this subsystem.
float gscaler_old[scal_num]
Definition: QwMoller.cc:45
void SetScreenThreshold(int thr)
Set the screen log level.
Definition: QwLog.cc:178
static const int scal_num
Definition: QwMoller.cc:44
void DefineOptionsParity(QwOptions &options)
float gscaler_change[scal_num]
Definition: QwMoller.cc:45
bool HasValue(const std::string &key)
Has this key been defined.
Definition: QwOptions.h:233
static bool bHelicity
Definition: QwMoller.cc:50
void AccumulateRunningSum(const QwSubsystemArrayParity &value)
Update the running sums for devices accumulated for the global error non-zero events/patterns.
void ConstructBranchAndVector(TTree *tree, TString &prefix, std::vector< Double_t > &values)
void ConstructBranchAndVector(TTree *tree, TString &prefix, std::vector< Double_t > &values)
Construct a branch and vector for this subsystem with a prefix.
float gscaler_new[scal_num]
Definition: QwMoller.cc:45
QwOptions gQwOptions
Definition: QwOptions.cc:27
void CalculateRunningAverage()
Calculate the average for all good events.
Bool_t IsBurstSumEnabled()
Status of burst sum calculation flag.
Bool_t IsCompletePattern() const
void ProcessOptions(QwOptions &options)
Process configuration options (default behavior)
Int_t OpenDataFile(UInt_t current_run, Short_t seg)
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()
static const std::ios_base::openmode kTruncate
Log file open modes.
Definition: QwLog.h:103
T GetValue(const std::string &key)
Get a templated value.
Definition: QwOptions.h:240
void SetFileThreshold(int thr)
Set the file log level.
Definition: QwLog.cc:185
Virtual base class for the parity subsystems.
void PrintRunningAverage() const
void ConstructTree()
Construct the tree for this subsystem.
const char * getenv_safe(const char *name)
Definition: QwOptions.h:28
void SetConfigFile(const std::string &configfile)
Set a configuration file.
Definition: QwOptions.h:192
A logfile class, based on an identical class in the Hermes analyzer.
static bool bHisto
Definition: QwMoller.cc:49
void setOptions()
Definition: QwMoller.cc:278
void Parse(bool force=false)
Parse all sources of options.
Definition: QwOptions.h:222
Load the options for the parity subsystems.
QwHistogramHelper gQwHists
Globally defined instance of the QwHistogramHelper class.
Bool_t FillSubsystemData(QwSubsystemArray &subsystems)
Bool_t IsRunningSumEnabled()
Status of running sum calculation flag.
void FillTree()
Fill the tree for this subsystem.
static std::ostream & endl(std::ostream &)
End of the line.
Definition: QwLog.cc:299
Int_t CloseDataFile()
void ProcessEvent()
Process the decoded data in this event.
const std::string getenv_safe_string(const char *name)
Definition: QwOptions.h:37
void LoadEventData(QwSubsystemArrayParity &event)
static bool bTree
Definition: QwMoller.cc:48
float gscalar[scal_num]
Definition: QwMoller.cc:45
void PrintRunningBurstAverage() const
Bool_t IsPhysicsEvent()
void IncrementErrorCounters()
Update the data elements&#39; error counters based on their internal error flags.
int main(int argc, char **argv)
Definition: QwRoot.cc:20
void LoadHistParamsFromFile(const std::string &filename)
QwLog gQwLog
Definition: QwLog.cc:22
UInt_t UpdateEventTypeMask()
Update the event type mask from the subsystems.
Bool_t IsROCConfigurationEvent()
#define QwError
Predefined log drain for errors.
Definition: QwLog.h:40
void SetCommandLine(int argc, char *argv[], bool default_config_file=true)
Set the command line arguments.
Definition: QwOptions.cc:112
void FillTreeVector(std::vector< Double_t > &values) const
Fill the vector for this subsystem.