JAPAn
Just Another Parity Analyzer
Loading...
Searching...
No Matches
QwParity.cc File Reference

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

#include <iostream>
#include <fstream>
#include <vector>
#include <new>
#include "Rtypes.h"
#include "TROOT.h"
#include "TFile.h"
#include "QwLog.h"
#include "QwRootFile.h"
#include "QwOptionsParity.h"
#include "QwEventBuffer.h"
#include "QwHistogramHelper.h"
#include "QwSubsystemArrayParity.h"
#include "QwHelicityPattern.h"
#include "QwEventRing.h"
#include "QwEPICSEvent.h"
#include "QwCombiner.h"
#include "QwCombinerSubsystem.h"
#include "QwPromptSummary.h"
#include "QwCorrelator.h"
#include "LRBCorrector.h"
#include "QwExtractor.h"
#include "QwDataHandlerArray.h"
#include "QwHelicity.h"
#include "QwFakeHelicity.h"
#include "QwBeamLine.h"
#include "QwBeamMod.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 qwparity executable

Definition in file QwParity.cc.

Function Documentation

◆ main()

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

Enable implicit multi-threading in e.g. TTree::Fill

Define the command line options

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

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.

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 correction subsystem

Create the helicity pattern

Create the event ring with the subsystem array

Create the data handler arrays

Create the burst sum

Create the running sum

Start loop over events

Definition at line 58 of file QwParity.cc.

59{
60 /// Enable implicit multi-threading in e.g. TTree::Fill
61 ROOT::EnableImplicitMT();
62
63 /// Define the command line options
65
66 /// Define additional command line arguments and the configuration filename,
67 /// and we define the options that can be used in them (using QwOptions).
68 gQwOptions.AddOptions()("single-output-file", po::value<bool>()->default_bool_value(false), "Write a single output file");
69 gQwOptions.AddOptions()("print-errorcounters", po::value<bool>()->default_bool_value(true), "Print summary of error counters");
70 gQwOptions.AddOptions()("write-promptsummary", po::value<bool>()->default_bool_value(false), "Write PromptSummary");
71 gQwOptions.AddOptions()("callgrind-instr-start-event-loop", po::value<bool>()->default_bool_value(false), "Start callgrind instrumentation with main event loop (with --instr-atstart=no)");
72 gQwOptions.AddOptions()("callgrind-instr-stop-event-loop", po::value<bool>()->default_bool_value(false), "Stop callgrind instrumentation with main event loop (with --instr-atstart=no)");
73
74 /// Without anything, print usage
75 if (argc == 1) {
76 gQwOptions.Usage();
77 exit(0);
78 }
79
80 /// First, fill the search paths for the parameter files; this sets a
81 /// static variable within the QwParameterFile class which will be used by
82 /// all instances.
83 /// The "scratch" directory should be first.
85 QwParameterFile::AppendToSearchPath(getenv_safe_string("QWANALYSIS") + "/Parity/prminput");
86 QwParameterFile::AppendToSearchPath(getenv_safe_string("QWANALYSIS") + "/Analysis/prminput");
87
88 gQwOptions.SetCommandLine(argc, argv);
89 gQwOptions.AddConfigFile("qweak_mysql.conf");
90
91 gQwOptions.ListConfigFiles();
92
93 /// Load command line options for the histogram/tree helper class
94 gQwHists.ProcessOptions(gQwOptions);
95 /// Setup screen and file logging
96 gQwLog.ProcessOptions(&gQwOptions);
97
98
99 /// Create the event buffer
100 QwEventBuffer eventbuffer;
101 eventbuffer.ProcessOptions(gQwOptions);
102
103 /// Create the database connection
104 #ifdef __USE_DATABASE__
105 QwParityDB database(gQwOptions);
106 #endif //__USE_DATABASE__
107
108 // QwPromptSummary promptsummary;
109
110 /// Start loop over all runs
111 Int_t run_number = 0;
112 while (eventbuffer.OpenNextStream() == CODA_OK) {
113
114 /// Begin processing for the first run
115
116 run_number = eventbuffer.GetRunNumber();
117 TString run_label = eventbuffer.GetRunLabel();
118
119 /// Set the current event number for parameter file lookup
121 // Parse the options again, in case there are run-ranged config files
122 gQwOptions.Parse(kTRUE);
123 eventbuffer.ProcessOptions(gQwOptions);
124
125 // if (gQwOptions.GetValue<bool>("write-promptsummary")) {
126 QwPromptSummary promptsummary(run_number, eventbuffer.GetSegmentNumber());
127 // }
128 /// Create an EPICS event
129 QwEPICSEvent epicsevent;
130 epicsevent.ProcessOptions(gQwOptions);
131 epicsevent.LoadChannelMap("EpicsTable.map");
132
133
134 /// Load the detectors from file
136 detectors.ProcessOptions(gQwOptions);
137 detectors.ListPublishedValues();
138
139 /// Create event-based correction subsystem
140 // TString name = "EvtCorrector";
141 // QwCombinerSubsystem corrector_sub(gQwOptions, detectors, name);
142 // detectors.push_back(corrector_sub.GetSharedPointerToStaticObject());
143
144 /// Create the helicity pattern
145 // Instead of having run_label in the constructor of helicitypattern, it might
146 // make since to have it be an option for use globally
147 QwHelicityPattern helicitypattern(detectors,run_label);
148 helicitypattern.ProcessOptions(gQwOptions);
149
150 /// Create the event ring with the subsystem array
151 QwEventRing eventring(gQwOptions,detectors);
152 // Make a copy of the detectors object to hold the
153 // events which pass through the ring.
154 QwSubsystemArrayParity ringoutput(detectors);
155
156 /// Create the data handler arrays
157 QwDataHandlerArray datahandlerarray_evt(gQwOptions,ringoutput,run_label);
158 QwDataHandlerArray datahandlerarray_mul(gQwOptions,helicitypattern,run_label);
159 QwDataHandlerArray datahandlerarray_burst(gQwOptions,helicitypattern,run_label);
160
161 /// Create the burst sum
162 QwHelicityPattern patternsum_per_burst(helicitypattern);
163 patternsum_per_burst.DisablePairs();
164
165 /// Create the running sum
166 QwSubsystemArrayParity eventsum(detectors);
167 QwHelicityPattern patternsum(helicitypattern);
168 patternsum.DisablePairs();
169 QwHelicityPattern burstsum(helicitypattern);
170 burstsum.DisablePairs();
171
172 // Initialize the database connection.
173 #ifdef __USE_DATABASE__
174 database.SetupOneRun(eventbuffer);
175 #endif // __USE_DATABASE__
176
177 // Open the ROOT file (close when scope ends)
178 QwRootFile *treerootfile = NULL;
179 QwRootFile *burstrootfile = NULL;
180 QwRootFile *historootfile = NULL;
181
182
183 if (gQwOptions.GetValue<bool>("single-output-file")) {
184
185 treerootfile = new QwRootFile(run_label);
186 burstrootfile = historootfile = treerootfile;
187 // Construct a tree which contains map file names which are used to analyze data
188 treerootfile->WriteParamFileList("mapfiles", detectors);
189
190 } else {
191
192 treerootfile = new QwRootFile(run_label + ".trees");
193 burstrootfile = new QwRootFile(run_label + ".bursts");
194 historootfile = new QwRootFile(run_label + ".histos");
195
196 // Construct a tree which contains map file names which are used to analyze data
197 detectors.PrintParamFileList();
198 treerootfile->WriteParamFileList("mapfiles", detectors);
199 burstrootfile->WriteParamFileList("mapfiles", detectors);
200 historootfile->WriteParamFileList("mapfiles", detectors);
201 }
202 #ifdef __USE_DATABASE__
203 if (database.AllowsWriteAccess()) {
204 database.FillParameterFiles(detectors);
205 }
206 #endif // __USE_DATABASE__
207 // Construct histograms
208 historootfile->ConstructHistograms("evt_histo", ringoutput);
209 historootfile->ConstructHistograms("mul_histo", helicitypattern);
210 burstrootfile->ConstructHistograms("burst_histo", patternsum_per_burst);
211 detectors.ShareHistograms(ringoutput);
212
213 // Construct tree branches
214 treerootfile->ConstructTreeBranches("evt", "MPS event data tree", ringoutput);
215 treerootfile->ConstructTreeBranches("mul", "Helicity event data tree", helicitypattern);
216 burstrootfile->ConstructTreeBranches("pr", "Pair tree", helicitypattern.GetPairYield(),"yield_");
217 burstrootfile->ConstructTreeBranches("pr", "Pair tree", helicitypattern.GetPairAsymmetry(),"asym_");
218 treerootfile->ConstructTreeBranches("slow", "EPICS and slow control tree", epicsevent);
219 burstrootfile->ConstructTreeBranches("burst", "Burst level data tree", patternsum_per_burst, "|stat");
220
221 // Construct RNTuple fields if enabled
222#ifdef HAS_RNTUPLE_SUPPORT
223 treerootfile->ConstructNTupleFields("evt", "MPS event data RNTuple", ringoutput);
224 treerootfile->ConstructNTupleFields("mul", "Helicity event data RNTuple", helicitypattern);
225 burstrootfile->ConstructNTupleFields("pr_yield", "Pair yield RNTuple", helicitypattern.GetPairYield(),"yield_");
226 burstrootfile->ConstructNTupleFields("pr_asym", "Pair asymmetry RNTuple", helicitypattern.GetPairAsymmetry(),"asym_");
227 treerootfile->ConstructNTupleFields("slow", "EPICS and slow control RNTuple", epicsevent);
228 burstrootfile->ConstructNTupleFields("burst", "Burst level data RNTuple", patternsum_per_burst, "|stat");
229#endif
230
231 historootfile->ConstructHistograms("evt_histo", datahandlerarray_evt);
232 historootfile->ConstructHistograms("mul_histo", datahandlerarray_mul);
233 burstrootfile->ConstructHistograms("burst_histo", datahandlerarray_burst);
234
235 datahandlerarray_evt.ConstructTreeBranches(treerootfile, "evt_");
236 datahandlerarray_mul.ConstructTreeBranches(treerootfile);
237 datahandlerarray_burst.ConstructTreeBranches(burstrootfile, "burst_", "|stat");
238
239 // Construct RNTuple fields for data handlers if enabled
240#ifdef HAS_RNTUPLE_SUPPORT
241 datahandlerarray_evt.ConstructNTupleFields(treerootfile, "evt_");
242 datahandlerarray_mul.ConstructNTupleFields(treerootfile);
243 datahandlerarray_burst.ConstructNTupleFields(burstrootfile, "burst_", "|stat");
244#endif
245
246 treerootfile->ConstructTreeBranches("evts", "Running sum tree", eventsum, "|stat");
247 treerootfile->ConstructTreeBranches("muls", "Running sum tree", patternsum, "|stat");
248 burstrootfile->ConstructTreeBranches("bursts", "Burst running sum tree", burstsum, "|stat");
249
250 // Construct RNTuple fields for additional data if enabled
251#ifdef HAS_RNTUPLE_SUPPORT
252 treerootfile->ConstructNTupleFields("evts", "Running sum RNTuple", eventsum, "|stat");
253 treerootfile->ConstructNTupleFields("muls", "Running sum RNTuple", patternsum, "|stat");
254 burstrootfile->ConstructNTupleFields("bursts", "Burst running sum RNTuple", burstsum, "|stat");
255#endif
256
257 // Summarize the ROOT file structure
258 //treerootfile->PrintTrees();
259 //treerootfile->PrintDirs();
260
261
262 // Clear the single-event running sum at the beginning of the runlet
263 eventsum.ClearEventData();
264 patternsum.ClearEventData();
265 burstsum.ClearEventData();
266 // Clear the running sum of the burst values at the beginning of the runlet
267 helicitypattern.ClearEventData();
268 patternsum_per_burst.ClearEventData();
269
270
271
272 // Load the blinder seed from a random number generator for online mode
273 if (eventbuffer.IsOnline() ){
274 helicitypattern.UpdateBlinder();//this routine will call update blinder mechanism using a random number
275 }else{
276 // Load the blinder seed from the database for this runlet.
277#ifdef __USE_DATABASE__
278 helicitypattern.UpdateBlinder(&database);
279#endif // __USE_DATABASE__
280 }
281
282
283 // Find the first EPICS event and try to initialize
284 // the blinder, but only for disk files, not online.
285 if (! eventbuffer.IsOnline() ){
286 QwMessage << "Finding first EPICS event" << QwLog::endl;
287 while (eventbuffer.GetNextEvent() == CODA_OK) {
288 if (eventbuffer.IsEPICSEvent()) {
289 eventbuffer.FillEPICSData(epicsevent);
290 if (epicsevent.HasDataLoaded()) {
291 helicitypattern.UpdateBlinder(epicsevent);
292 // and break out of this event loop
293 break;
294 }
295 }
296 }
297 epicsevent.ResetCounters();
298 // Rewind stream
299 QwMessage << "Rewinding stream" << QwLog::endl;
300 eventbuffer.ReOpenStream();
301 }
302
303 // Start event loop instrumentation
304#ifdef CALLGRIND_START_INSTRUMENTATION
305 if (gQwOptions.GetValue<bool>("callgrind-instr-start-event-loop")) {
306 QwMessage << "Starting callgrind instrumentation" << QwLog::endl;
307 CALLGRIND_START_INSTRUMENTATION;
308 }
309#endif
310
311 /// Start loop over events
312 while (eventbuffer.GetNextEvent() == CODA_OK) {
313
314 // First, do processing of non-physics events...
315 if (eventbuffer.IsROCConfigurationEvent()) {
316 // Send ROC configuration event data to the subsystem objects.
317 eventbuffer.FillSubsystemConfigurationData(detectors);
318 }
319
320 // Secondly, process EPICS events, but not for online running,
321 // because the EPICS events get messed up by our 32-bit to 64-bit
322 // double ET system.
323 if (! eventbuffer.IsOnline() && eventbuffer.IsEPICSEvent()) {
324 eventbuffer.FillEPICSData(epicsevent);
325 if (epicsevent.HasDataLoaded()){
326 epicsevent.CalculateRunningValues();
327 helicitypattern.UpdateBlinder(epicsevent);
328
329 treerootfile->FillTreeBranches(epicsevent);
330 treerootfile->FillTree("slow");
331
332 // Fill RNTuple if enabled
333#ifdef HAS_RNTUPLE_SUPPORT
334 treerootfile->FillNTupleFields(epicsevent);
335 treerootfile->FillNTuple("slow");
336#endif
337 }
338 }
339
340
341 // Now, if this is not a physics event, go back and get a new event.
342 if (! eventbuffer.IsPhysicsEvent()) continue;
343
344
345 // Fill the subsystem objects with their respective data for this event.
346 eventbuffer.FillSubsystemData(detectors);
347
348 // Process the subsystem data
349 detectors.ProcessEvent();
350
351
352 // The event pass the event cut constraints
353 if (detectors.ApplySingleEventCuts()) {
354
355 // Add event to the ring
356 eventring.push(detectors);
357
358 // Check to see ring is ready
359 if (eventring.IsReady()) {
360 ringoutput = eventring.pop();
361 ringoutput.IncrementErrorCounters();
362
363
364 // Accumulate the running sum to calculate the event based running average
365 eventsum.AccumulateRunningSum(ringoutput);
366
367 // Fill the histograms
368 historootfile->FillHistograms(ringoutput);
369
370 // Fill mps tree branches
371 treerootfile->FillTreeBranches(ringoutput);
372 treerootfile->FillTree("evt");
373
374 // Fill RNTuple if enabled
375#ifdef HAS_RNTUPLE_SUPPORT
376 treerootfile->FillNTupleFields(ringoutput);
377 treerootfile->FillNTuple("evt");
378#endif
379
380 // Process data handlers
381 datahandlerarray_evt.ProcessDataHandlerEntry();
382
383 // Fill data handler histograms
384 historootfile->FillHistograms(datahandlerarray_evt);
385
386 // Fill data handler tree branches
387 datahandlerarray_evt.FillTreeBranches(treerootfile);
388
389 // Fill data handler RNTuple fields if enabled
390#ifdef HAS_RNTUPLE_SUPPORT
391 datahandlerarray_evt.FillNTupleFields(treerootfile);
392#endif
393
394 // Load the event into the helicity pattern
395 helicitypattern.LoadEventData(ringoutput);
396
397 if (helicitypattern.PairAsymmetryIsGood()) {
398 patternsum.AccumulatePairRunningSum(helicitypattern);
399
400 // Fill pair tree branches
401 burstrootfile->FillTreeBranches(helicitypattern.GetPairYield());
402 burstrootfile->FillTreeBranches(helicitypattern.GetPairAsymmetry());
403 burstrootfile->FillTreeBranches(helicitypattern.GetPairDifference());
404 burstrootfile->FillTree("pr");
405
406 // Fill pair RNTuples if enabled
407#ifdef HAS_RNTUPLE_SUPPORT
408 burstrootfile->FillNTupleFields("pr_yield", helicitypattern.GetPairYield());
409 burstrootfile->FillNTupleFields("pr_asym", helicitypattern.GetPairAsymmetry());
410 burstrootfile->FillNTuple("pr_yield");
411 burstrootfile->FillNTuple("pr_asym");
412#endif
413
414 // Clear the data
415 helicitypattern.ClearPairData();
416 }
417
418 // Check to see if we can calculate helicity pattern asymmetry, do so, and report if it worked
419 if (helicitypattern.IsGoodAsymmetry()) {
420 patternsum.AccumulateRunningSum(helicitypattern);
421
422 // Fill histograms
423 historootfile->FillHistograms(helicitypattern);
424
425 // Fill helicity tree branches
426 treerootfile->FillTreeBranches(helicitypattern);
427 treerootfile->FillTree("mul");
428
429 // Fill helicity RNTuple if enabled
430#ifdef HAS_RNTUPLE_SUPPORT
431 treerootfile->FillNTupleFields(helicitypattern);
432 treerootfile->FillNTuple("mul");
433#endif
434
435 // Process data handlers
436 datahandlerarray_mul.ProcessDataHandlerEntry();
437 datahandlerarray_burst.ProcessDataHandlerEntry();
438
439 // Fill data handler histograms
440 historootfile->FillHistograms(datahandlerarray_mul);
441
442 // Fill data handler tree branches
443 datahandlerarray_mul.FillTreeBranches(treerootfile);
444
445 // Fill data handler RNTuple fields if enabled
446#ifdef HAS_RNTUPLE_SUPPORT
447 datahandlerarray_mul.FillNTupleFields(treerootfile);
448#endif
449
450 // Fill the pattern into the sum for this burst
451 patternsum_per_burst.AccumulateRunningSum(helicitypattern);
452
453 // Accumulate data handler arrays
454 //datahandlerarray_burst.AccumulateRunningSum(datahandlerarray_mul);
455
456 // Burst mode
457 if (patternsum_per_burst.IsEndOfBurst()) {
458
459 // Calculate average over this burst
460 patternsum_per_burst.CalculateRunningAverage();
461
462 // Fill the burst into the sum over all bursts
463 burstsum.AccumulateRunningSum(patternsum_per_burst);
464
465 if (gQwOptions.GetValue<bool>("print-burstsum")) {
466 QwMessage << " Running average of this burst" << QwLog::endl;
467 QwMessage << " =============================" << QwLog::endl;
468 patternsum_per_burst.PrintValue();
469 }
470
471 // Fill histograms
472 burstrootfile->FillHistograms(patternsum_per_burst);
473
474 // Fill burst tree branches
475 burstrootfile->FillTreeBranches(patternsum_per_burst);
476 burstrootfile->FillTree("burst");
477
478 // Fill burst RNTuple if enabled
479#ifdef HAS_RNTUPLE_SUPPORT
480 burstrootfile->FillNTupleFields(patternsum_per_burst);
481 burstrootfile->FillNTuple("burst");
482#endif
483
484 // Finish data handler for burst
485 datahandlerarray_burst.FinishDataHandler();
486
487 // Fill data handler histograms
488 burstrootfile->FillHistograms(datahandlerarray_burst);
489
490 // Fill data handler tree branches
491 datahandlerarray_burst.FillTreeBranches(burstrootfile);
492
493 // Fill data handler RNTuple fields if enabled
494#ifdef HAS_RNTUPLE_SUPPORT
495 datahandlerarray_burst.FillNTupleFields(burstrootfile);
496#endif
497
498 helicitypattern.IncrementBurstCounter();
499 datahandlerarray_mul.UpdateBurstCounter(helicitypattern.GetBurstCounter());
500 datahandlerarray_burst.UpdateBurstCounter(helicitypattern.GetBurstCounter());
501 // Clear the data
502 patternsum_per_burst.ClearEventData();
503 datahandlerarray_burst.ClearEventData();
504 }
505
506 // Clear the data
507 helicitypattern.ClearEventData();
508
509 } // helicitypattern.IsGoodAsymmetry()
510
511 } // eventring.IsReady()
512
513 } // detectors.ApplySingleEventCuts()
514
515 } // end of loop over events
516
517 // Unwind event ring
518 QwMessage << "Unwinding event ring" << QwLog::endl;
519 eventring.Unwind();
520
521 // Stop event loop instrumentation
522#ifdef CALLGRIND_START_INSTRUMENTATION
523 if (gQwOptions.GetValue<bool>("callgrind-instr-stop-event-loop")) {
524 CALLGRIND_STOP_INSTRUMENTATION;
525 QwMessage << "Stapped callgrind instrumentation" << QwLog::endl;
526 }
527#endif
528
529 // TODO Drain event run
530
531 // Finalize burst
532 if (patternsum_per_burst.HasBurstData()){
533 // Calculate average over this burst
534 patternsum_per_burst.CalculateRunningAverage();
535
536 // Fill the burst into the sum over all bursts
537 burstsum.AccumulateRunningSum(patternsum_per_burst);
538
539 if (gQwOptions.GetValue<bool>("print-burstsum")) {
540 QwMessage << " Running average of this burst" << QwLog::endl;
541 QwMessage << " =============================" << QwLog::endl;
542 patternsum_per_burst.PrintValue();
543 }
544
545 // Fill histograms
546 burstrootfile->FillHistograms(patternsum_per_burst);
547
548 // Fill burst tree branches
549 burstrootfile->FillTreeBranches(patternsum_per_burst);
550 burstrootfile->FillTree("burst");
551
552 // Fill burst RNTuple if enabled
553#ifdef HAS_RNTUPLE_SUPPORT
554 burstrootfile->FillNTupleFields(patternsum_per_burst);
555 burstrootfile->FillNTuple("burst");
556#endif
557
558 // Finish data handler for burst
559 datahandlerarray_burst.FinishDataHandler();
560
561 // Fill data handler histograms
562 burstrootfile->FillHistograms(datahandlerarray_burst);
563
564 // Fill data handler tree branches
565 datahandlerarray_burst.FillTreeBranches(burstrootfile);
566
567 // Fill data handler RNTuple fields if enabled
568#ifdef HAS_RNTUPLE_SUPPORT
569 datahandlerarray_burst.FillNTupleFields(burstrootfile);
570#endif
571 patternsum_per_burst.PrintIndexMapFile(run_number);
572 }
573
574 // Perform actions at the end of the event loop on the
575 // detectors object, which ought to have handles for the
576 // MPS based histograms.
577 ringoutput.AtEndOfEventLoop();
578
579 QwMessage << "Number of events processed at end of run: "
580 << eventbuffer.GetPhysicsEventNumber() << QwLog::endl;
581
582 // Finish data handlers
583 datahandlerarray_evt.FinishDataHandler();
584 datahandlerarray_mul.FinishDataHandler();
585
586 // Calculate running averages
587 eventsum.CalculateRunningAverage();
588 patternsum.CalculateRunningAverage();
589 burstsum.CalculateRunningAverage();
590
591 // This will calculate running averages over single helicity events
592 if (gQwOptions.GetValue<bool>("print-runningsum")) {
593 QwMessage << " Running average of events" << QwLog::endl;
594 QwMessage << " =========================" << QwLog::endl;
595 eventsum.PrintValue();
596 }
597 treerootfile->FillTreeBranches(eventsum);
598 treerootfile->FillTree("evts");
599
600 // Fill running sum RNTuple if enabled
601#ifdef HAS_RNTUPLE_SUPPORT
602 treerootfile->FillNTupleFields(eventsum);
603 treerootfile->FillNTuple("evts");
604#endif
605
606 if (gQwOptions.GetValue<bool>("print-patternsum")) {
607 QwMessage << " Running average of patterns" << QwLog::endl;
608 QwMessage << " =========================" << QwLog::endl;
609 patternsum.PrintValue();
610 }
611 treerootfile->FillTreeBranches(patternsum);
612 treerootfile->FillTree("muls");
613
614 // Fill pattern sum RNTuple if enabled
615#ifdef HAS_RNTUPLE_SUPPORT
616 treerootfile->FillNTupleFields(patternsum);
617 treerootfile->FillNTuple("muls");
618#endif
619
620 if (gQwOptions.GetValue<bool>("print-burstsum")) {
621 QwMessage << " Running average of bursts" << QwLog::endl;
622 QwMessage << " =========================" << QwLog::endl;
623 burstsum.PrintValue();
624 }
625 burstrootfile->FillTreeBranches(burstsum);
626 burstrootfile->FillTree("bursts");
627
628 // Fill burst sum RNTuple if enabled
629#ifdef HAS_RNTUPLE_SUPPORT
630 burstrootfile->FillNTupleFields(burstsum);
631 burstrootfile->FillNTuple("bursts");
632#endif
633
634 // Construct objects
635 burstrootfile->ConstructObjects("objects", helicitypattern);
636
637 /* Write to the root file, being sure to delete the old cycles *
638 * which were written by Autosave. *
639 * Doing this will remove the multiple copies of the ntuples *
640 * from the root file. *
641 * *
642 * Then, we need to delete the histograms here. *
643 * If we wait until the subsystem destructors, we get a *
644 * segfault; but in addition to that we should delete them *
645 * here, in case we run over multiple runs at a time. */
646 if (treerootfile == historootfile) {
647 // Use different write methods based on output format
648#ifdef HAS_RNTUPLE_SUPPORT
649 if (gQwOptions.GetValue<bool>("enable-rntuples") && gQwOptions.GetValue<bool>("disable-trees")) {
650 // RNTuple-only mode: use Close() for proper RNTuple finalization
651 treerootfile->Close();
652 } else {
653#endif
654 // TTree mode or mixed mode: use Write() for explicit tree writing
655 treerootfile->Write(0, TObject::kOverwrite);
656 treerootfile->Close();
657#ifdef HAS_RNTUPLE_SUPPORT
658 }
659#endif
660 delete treerootfile; treerootfile = 0; burstrootfile = 0; historootfile = 0;
661 } else {
662 // Use different write methods based on output format
663#ifdef HAS_RNTUPLE_SUPPORT
664 if (gQwOptions.GetValue<bool>("enable-rntuples") && gQwOptions.GetValue<bool>("disable-trees")) {
665 // RNTuple-only mode: use Close() for proper RNTuple finalization
666 treerootfile->Close();
667 burstrootfile->Close();
668 historootfile->Close();
669 } else {
670#endif
671 // TTree mode or mixed mode: use Write() for explicit tree writing
672 treerootfile->Write(0, TObject::kOverwrite);
673 burstrootfile->Write(0, TObject::kOverwrite);
674 historootfile->Write(0, TObject::kOverwrite);
675 treerootfile->Close();
676 burstrootfile->Close();
677 historootfile->Close();
678#ifdef HAS_RNTUPLE_SUPPORT
679 }
680#endif
681 delete treerootfile; treerootfile = 0;
682 delete burstrootfile; burstrootfile = 0;
683 delete historootfile; historootfile = 0;
684 }
685
686 // Print the event cut error summary for each subsystem
687 if (gQwOptions.GetValue<bool>("print-errorcounters")) {
688 QwMessage << " ------------ error counters ------------------ " << QwLog::endl;
689 ringoutput.PrintErrorCounters();
690 }
691
692 if (gQwOptions.GetValue<bool>("write-promptsummary")) {
693 // runningsum.WritePromptSummary(&promptsummary, "yield");
694 // runningsum.WritePromptSummary(&promptsummary, "asymmetry");
695 // runningsum.WritePromptSummary(&promptsummary, "difference");
696 datahandlerarray_mul.WritePromptSummary(&promptsummary, "asymmetry");
697 patternsum.WritePromptSummary(&promptsummary);
698 promptsummary.PrintCSV(eventbuffer.GetPhysicsEventNumber(),eventbuffer.GetStartSQLTime(), eventbuffer.GetEndSQLTime());
699 }
700 // Read from the database
701 #ifdef __USE_DATABASE__
702 database.SetupOneRun(eventbuffer);
703
704 // Each subsystem has its own Connect() and Disconnect() functions.
705 if (database.AllowsWriteAccess()) {
706 patternsum.FillDB(&database);
707 patternsum.FillErrDB(&database);
708 epicsevent.FillDB(&database);
709 ringoutput.FillDB_MPS(&database, "optics");
710 }
711 #endif // __USE_DATABASE__
712
713 //epicsevent.WriteEPICSStringValues();
714
715 // Close event buffer stream
716 eventbuffer.CloseStream();
717
718
719
720 // Report run summary
721 eventbuffer.ReportRunSummary();
722 eventbuffer.PrintRunTimes();
723 } // end of loop over runs
724
725 QwMessage << "I have done everything I can do..." << QwLog::endl;
726
727 return 0;
728}
QwHistogramHelper gQwHists
Globally defined instance of the QwHistogramHelper class.
const std::string getenv_safe_string(const char *name)
Definition QwOptions.h:43
#define gQwOptions
Definition QwOptions.h:31
QwLog gQwLog
Definition QwLog.cc:20
#define QwMessage
Predefined log drain for regular messages.
Definition QwLog.h:49
void DefineOptionsParity(QwOptions &options)
EPICS slow controls data management.
Bool_t HasDataLoaded() const
void ProcessOptions(QwOptions &options)
Process the configuration options.
Int_t LoadChannelMap(TString mapfile)
void CalculateRunningValues()
void FillDB(QwParityDB *db)
void ResetCounters()
Event buffer management for reading and processing CODA data.
TString GetRunLabel() const
Returns a string like <run#> or <run#>.<file#>
TString GetEndSQLTime()
void ReportRunSummary()
Bool_t IsOnline()
Int_t CloseStream()
Closes a currently open event stream.
Bool_t IsEPICSEvent()
Int_t OpenNextStream()
Opens the event stream (file or ET) based on the internal flags.
void ProcessOptions(QwOptions &options)
Sets internal flags based on the QwOptions.
Bool_t FillSubsystemData(QwSubsystemArray &subsystems)
Int_t GetSegmentNumber() const
Return CODA file segment number.
TString GetStartSQLTime()
Int_t GetRunNumber() const
Return CODA file run number.
Bool_t IsROCConfigurationEvent()
Int_t GetPhysicsEventNumber()
Bool_t IsPhysicsEvent()
Bool_t FillEPICSData(QwEPICSEvent &epics)
Bool_t FillSubsystemConfigurationData(QwSubsystemArray &subsystems)
static std::ostream & endl(std::ostream &)
End of the line.
Definition QwLog.cc:297
static void AppendToSearchPath(const TString &searchdir)
Add a directory to the search path.
static void SetCurrentRunNumber(const UInt_t runnumber)
Set the current run number for looking up the appropriate parameter file.
A wrapper class for a ROOT file or memory mapped file.
Definition QwRootFile.h:833
Int_t FillTree(const std::string &name)
Fill the tree with name.
Definition QwRootFile.h:955
Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
void Close()
void ConstructTreeBranches(const std::string &name, const std::string &desc, T &object, const std::string &prefix="")
Construct the tree branches of a generic object.
void FillHistograms(T &object)
Fill histograms of the subsystem array.
Definition QwRootFile.h:901
void FillTreeBranches(const std::string &name, const T &object)
Fill the tree branches of a generic object by tree name.
Int_t WriteParamFileList(const TString &name, T &object)
void ConstructHistograms(const std::string &name, T &object)
Construct the histograms of a generic object.
void ConstructObjects(const std::string &name, T &object)
Construct the histograms of a generic object.
Virtual base class for the parity handlers.
Ring buffer of subsystem snapshots for burp/stability handling.
Definition QwEventRing.h:28
Manages yields/differences/asymmetries for helicity patterns.
Subsystem array container specialized for parity analysis with asymmetry calculations.

References QwHelicityPattern::AccumulatePairRunningSum(), QwHelicityPattern::AccumulateRunningSum(), QwSubsystemArrayParity::AccumulateRunningSum(), QwParameterFile::AppendToSearchPath(), QwSubsystemArrayParity::ApplySingleEventCuts(), QwSubsystemArray::AtEndOfEventLoop(), QwHelicityPattern::CalculateRunningAverage(), QwSubsystemArrayParity::CalculateRunningAverage(), QwEPICSEvent::CalculateRunningValues(), QwDataHandlerArray::ClearEventData(), QwHelicityPattern::ClearEventData(), QwSubsystemArray::ClearEventData(), QwHelicityPattern::ClearPairData(), QwRootFile::Close(), QwEventBuffer::CloseStream(), QwRootFile::ConstructHistograms(), QwDataHandlerArray::ConstructNTupleFields(), QwRootFile::ConstructObjects(), QwDataHandlerArray::ConstructTreeBranches(), QwRootFile::ConstructTreeBranches(), DefineOptionsParity(), QwHelicityPattern::DisablePairs(), QwLog::endl(), QwEPICSEvent::FillDB(), QwSubsystemArrayParity::FillDB_MPS(), QwEventBuffer::FillEPICSData(), QwRootFile::FillHistograms(), QwDataHandlerArray::FillNTupleFields(), QwEventBuffer::FillSubsystemConfigurationData(), QwEventBuffer::FillSubsystemData(), QwRootFile::FillTree(), QwDataHandlerArray::FillTreeBranches(), QwRootFile::FillTreeBranches(), QwDataHandlerArray::FinishDataHandler(), QwHelicityPattern::GetBurstCounter(), QwEventBuffer::GetEndSQLTime(), getenv_safe_string(), QwEventBuffer::GetNextEvent(), QwHelicityPattern::GetPairAsymmetry(), QwHelicityPattern::GetPairDifference(), QwHelicityPattern::GetPairYield(), QwEventBuffer::GetPhysicsEventNumber(), QwEventBuffer::GetRunLabel(), QwEventBuffer::GetRunNumber(), QwEventBuffer::GetSegmentNumber(), QwEventBuffer::GetStartSQLTime(), gQwHists, gQwLog, gQwOptions, QwHelicityPattern::HasBurstData(), QwEPICSEvent::HasDataLoaded(), QwHelicityPattern::IncrementBurstCounter(), QwSubsystemArrayParity::IncrementErrorCounters(), QwHelicityPattern::IsEndOfBurst(), QwEventBuffer::IsEPICSEvent(), QwHelicityPattern::IsGoodAsymmetry(), QwEventBuffer::IsOnline(), QwEventBuffer::IsPhysicsEvent(), QwEventRing::IsReady(), QwEventBuffer::IsROCConfigurationEvent(), MQwPublishable< U, T >::ListPublishedValues(), QwEPICSEvent::LoadChannelMap(), QwHelicityPattern::LoadEventData(), QwEventBuffer::OpenNextStream(), QwHelicityPattern::PairAsymmetryIsGood(), QwEventRing::pop(), QwPromptSummary::PrintCSV(), QwSubsystemArrayParity::PrintErrorCounters(), QwHelicityPattern::PrintIndexMapFile(), QwSubsystemArray::PrintParamFileList(), QwEventBuffer::PrintRunTimes(), QwHelicityPattern::PrintValue(), QwSubsystemArrayParity::PrintValue(), QwDataHandlerArray::ProcessDataHandlerEntry(), QwSubsystemArray::ProcessEvent(), QwEPICSEvent::ProcessOptions(), QwEventBuffer::ProcessOptions(), QwHelicityPattern::ProcessOptions(), QwSubsystemArray::ProcessOptions(), QwEventRing::push(), QwMessage, QwEventBuffer::ReOpenStream(), QwEventBuffer::ReportRunSummary(), QwEPICSEvent::ResetCounters(), QwParameterFile::SetCurrentRunNumber(), QwSubsystemArray::ShareHistograms(), QwEventRing::Unwind(), QwHelicityPattern::UpdateBlinder(), QwDataHandlerArray::UpdateBurstCounter(), QwRootFile::Write(), QwRootFile::WriteParamFileList(), QwDataHandlerArray::WritePromptSummary(), and QwHelicityPattern::WritePromptSummary().

+ Here is the call graph for this function: