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 "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 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 59 of file QwParity.cc.

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