JAPAn
Just Another Parity Analyzer
Loading...
Searching...
No Matches
QwPromptSummary.cc
Go to the documentation of this file.
1
2/*!
3 * \file QwPromptSummary.cc
4 * \brief Implementation for prompt summary data management
5 * \author jhlee@jlab.org
6 * \date 2011-12-16
7 */
8
9#include "QwPromptSummary.h"
10
11// System headers
12#include <iostream>
13#include <fstream>
14
15// ROOT headers
16#include "TMath.h"
17
18//
19//
20//
21// PromptSummaryElement
22//
23//
24//
25//
26
28{
29 fElementName = "";
30
31 fYield = 0.0;
32 fYieldError = 0.0;
33 fYieldWidth = 0.0;
34 fYieldUnit = "";
35
36 fAsymDiff = 0.0;
37 fAsymDiffError = 0.0;
38 fAsymDiffWidth = 0.0;
39 fAsymDiffUnit = "";
40
41};
42
43
45{
46 fElementName = name;
47
48 fYield = 0.0;
49 fYieldError = 0.0;
50 fYieldWidth = 0.0;
51 fYieldUnit = "";
52
53 fAsymDiff = 0.0;
54 fAsymDiffError = 0.0;
55 fAsymDiffWidth = 0.0;
56 fAsymDiffUnit = "";
57
58};
59
63
64
65void
67 Double_t yield,
68 Double_t yield_err,
69 Double_t yield_width,
70 TString yield_unit,
71 Double_t asym_diff,
72 Double_t asym_diff_err,
73 Double_t asym_diff_width,
74 TString asym_diff_unit
75 )
76{
77 fYield = yield;
78 fYieldError = yield_err;
79 fYieldWidth = yield_width;
80 fYieldUnit = yield_unit;
81
82 fAsymDiff = asym_diff;
83 fAsymDiffError = asym_diff_err;
84 fAsymDiffWidth = asym_diff_width;
85 fAsymDiffUnit = asym_diff_unit;
86
87 return;
88};
89
90
91TString
93{
94 // return Form("%14s | %12.2lf +/- %8.2lf | %+12.2lf +/- %8.2lf | %+12.2lf +/- %8.2lf\n", fElementName.Data(), fYield, fYieldError, fAsymDiff, fAsymDiffError, fAsymDiffWidth, fAsymDiffWidthError);
95 TString test;
96 return test;
97};
98
99TString
101{
102
103TString out = "";
104
105Bool_t dd= fElementName.Contains("_dd");
106Bool_t da= fElementName.Contains("_da");
107
108
109if (type.Contains("yield")&& !(dd||da)){
110 out = Form("%20s | Mean: %8.3f +/- %8.3f \t Width: %8.3f\n", fElementName.Data(), fYield, fYieldError, fYieldWidth);
111}
112if (type.Contains("asy")&& !(dd||da)){
113 out = Form("%20s | Mean: %8.3f +/- %8.3f \t Width: %8.3f\n", fElementName.Data(), fAsymDiff, fAsymDiffError, fAsymDiffWidth);
114}
115if (type.Contains("double")&& (dd||da)) {
116 out = Form("%20s | Mean: %8.3f +/- %8.3f \t Width: %8.3f\n", fElementName.Data(), fAsymDiff, fAsymDiffError, fAsymDiffWidth);
117}
118
119
120return out;
121
122};
123
124
125void
126PromptSummaryElement::Set(TString type, const Double_t a, const Double_t a_err, const Double_t a_width)
127{
128 Double_t unit= 1;
129
130 Bool_t bcm= fElementName.Contains("bcm");
131 Bool_t bpm= fElementName.Contains("bpm");
132 Bool_t sam= fElementName.Contains("sam");
133 Bool_t md= fElementName.Contains("md");
134
135 if (type.Contains("yield")){
136 if (bcm) {
137 this->SetYieldUnit("uA");
138 unit=Qw::uA;
139 }
140 else if (bpm) {
141 this->SetYieldUnit("mm");
142 unit=Qw::mm;
143 }
144 else if (sam||md) {
145 this->SetYieldUnit("mV/uA");
146 unit=Qw::mV_uA;
147 }
148 else {
149 this->SetYieldUnit("---");
150 }
151 this->SetYield(a/unit);
152 this->SetYieldError(a_err/unit);
153 this->SetYieldWidth(a_width/unit);
154
155 }
156 else if(type.Contains("asymmetry")) {
157 if (bpm) {
158 this->SetDifferenceUnit("um");
159 unit=Qw::um;
160 this->SetDifference(a/unit);
161 this->SetDifferenceError(a_err/unit);
162 this->SetDifferenceWidth(a_width/unit);
163 }
164 else {
165 this->SetAsymmetryUnit("ppm");
166 unit=Qw::ppm;
167 this->SetAsymmetry(a/unit);
168 this->SetAsymmetryError(a_err/unit);
169 this->SetAsymmetryWidth(a_width/unit);
170 }
171 }
172 else if(type.Contains("difference")) {
173 }
174 else {
175 }
176 return;
177};
178
180{
181 fRunNumber = 0;
182 fRunletNumber = 0;
183
184 fLocalDebug = kTRUE;
185
186 this->SetupElementList();
187
188};
189
190
191QwPromptSummary::QwPromptSummary(Int_t run_number, Int_t runlet_number)
192{
193 fRunNumber = run_number;
194 fRunletNumber = runlet_number;
195
196 fLocalDebug = kFALSE;
197
198 this->SetupElementList();
199
200};
201
202
203QwPromptSummary::QwPromptSummary(Int_t run_number, Int_t runlet_number, const std::string& parameter_file)
204{
205 fRunNumber = run_number;
206 fRunletNumber = runlet_number;
207
208 fLocalDebug = kFALSE;
209
210 this->LoadElementsFromParameterFile(parameter_file);
211
212};
213
214
216{
217
218 for (auto i=fElementList.begin() ; i!=fElementList.end();i++){
219 delete i->second;
220 }
221 fElementList.clear();
222
223};
224
225
226
227void
229{
230 // Try to load from default parameter file first
231 std::string default_param_file = "prompt_summary.map";
232
233 try {
234 QwParameterFile paramfile(default_param_file);
236 if (fElementList.size() > 0) {
237 QwMessage << "QwPromptSummary: Loaded " << fElementList.size() << " elements from " << default_param_file << QwLog::endl;
238 return; // Successfully loaded from file
239 }
240 } catch (const std::exception& e) {
241 if (fLocalDebug) {
242 QwMessage << "QwPromptSummary: Could not load from " << default_param_file
243 << ", using default elements: " << e.what() << QwLog::endl;
244 }
245 }
246};
247
248
249void
250QwPromptSummary::LoadElementsFromParameterFile(const std::string& parameter_file)
251{
252 try {
253 QwParameterFile paramfile(parameter_file);
255 } catch (const std::exception& e) {
256 QwError << "QwPromptSummary::LoadElementsFromParameterFile: Unable to open parameter file: "
257 << parameter_file << " - " << e.what() << QwLog::endl;
258 QwMessage << "Falling back to default (empty) element list." << QwLog::endl;
259 }
260};
261
262
263void
265{
266 QwMessage << "QwPromptSummary::LoadElementsFromParameterFile: Loading prompt summary elements" << QwLog::endl;
267
268 // Read preamble
269 std::unique_ptr<QwParameterFile> preamble = parameterfile.ReadSectionPreamble();
270 if (preamble) {
271 QwVerbose << "PromptSummary preamble:" << QwLog::endl;
272 QwVerbose << *preamble << QwLog::endl;
273 }
274
275 // Read sections
276 std::unique_ptr<QwParameterFile> section;
277 std::string section_name;
278 while ((section = parameterfile.ReadNextSection(section_name))) {
279 QwVerbose << "Processing section: " << section_name << QwLog::endl;
280
281 // Check if this is a prompt summary elements section
282 if (section_name == "prompt_summary_elements" || section_name == "elements") {
283 // Process individual elements in this section
284 while (section->ReadNextLine()) {
285 section->TrimWhitespace();
286 section->TrimComment();
287 if (section->LineIsEmpty()) continue;
288
289 std::string line = section->GetLine();
290
291 // Parse element definitions
292 // Format 1: Simple element name
293 // Format 2: element_name = type (where type could be single, difference, etc.)
294
295 std::string element_name, element_type;
296 if (section->HasVariablePair("=", element_name, element_type)) {
297 // Format: element_name = type
298 // Trim whitespace manually since TrimWhitespace is protected
299 element_name.erase(0, element_name.find_first_not_of(" \t\r\n"));
300 element_name.erase(element_name.find_last_not_of(" \t\r\n") + 1);
301 element_type.erase(0, element_type.find_first_not_of(" \t\r\n"));
302 element_type.erase(element_type.find_last_not_of(" \t\r\n") + 1);
303
304 if (fLocalDebug) {
305 QwMessage << "Adding element: " << element_name << " (type: " << element_type << ")" << QwLog::endl;
306 }
307 } else {
308 // Format: simple element name
309 element_name = line;
310 element_type = "single"; // default type
311
312 if (fLocalDebug) {
313 QwMessage << "Adding element: " << element_name << " (default type)" << QwLog::endl;
314 }
315 }
316
317 // Create and add the element
318 if (!element_name.empty()) {
319 this->AddElement(new PromptSummaryElement(TString(element_name.c_str())));
320 }
321 }
322 }
323 }
324
325 QwMessage << "QwPromptSummary: Loaded " << fElementList.size() << " elements from parameter file" << QwLog::endl;
326};
327
328
329void
331{
332 TString name = in->GetName(); name.ToLower();
333 fElementList[name] = in;
334 if(fLocalDebug) {
335 printf("AddElement %s at pos %lu\n", in->GetName().Data(), fElementList.size()-1);
336 }
337 if (fElementList.size() == 1) {
338 QwMessage << "First element: " << in->GetName() << " will be reference" << QwLog::endl;
340 }
341};
342
343
346{
347 name.ToLower();
348 if (fElementList.find(name) != fElementList.end()) {
349 PromptSummaryElement* an_element = fElementList[name];
350 if(fLocalDebug) {
351 std::cout << "System " << an_element->GetName()
352 << " QwPromptSummary::GetElementByName address at " << an_element << std::endl;
353 }
354 return an_element;
355 } else {
356 QwDebug << "System " << name
357 << " QwPromptSummary::GetElementByName not found" << std::endl;
358 }
359 return NULL;
360};
361
362
363TString
365{
366 TString out = "";
367 // TString filename = "";
368
369 // filename = Form("summary_%d_%d.txt", fRunNumber, fRunletNumber);
370
371 out = "======= BEGIN ======= \n";
372 out += Form(" RUN = %5d RUNLET %2d \n\n\n\n\n\n", fRunNumber, fRunletNumber);
373 return out;
374};
375
376
377
378TString
380{
381 TString out = "";
382
383 out = "==================================================\n";
384 return out;
385};
386
387
388TString
389QwPromptSummary::PrintCSVHeader(Int_t nEvents, TString start_time, TString end_time)
390{
391 TString out = "";
392
393 Double_t goodEvents = 0.0;
394 TString referenceElementName = "N/A";
395
396 // Use the first element in the list to determine good events
397 if (fReferenceElement) {
398 goodEvents = fReferenceElement->GetNumGoodEvents() * fPatternSize;
399 referenceElementName = fReferenceElement->GetName();
400 } else {
401 QwError << "Warning: No reference element found in QwPromptSummary. Setting goodEvents=0." << QwLog::endl;
402 }
403
404 out += Form("Run: %d \n",fRunNumber);
405 out += "Start Time: "+start_time+"\nEnd Time: "+end_time+"\n";
406 out += Form("Number of events processed: %i\n",nEvents);
407 out += Form("Number of events in good multiplicity patterns: %3.0f\n", goodEvents);
408 out += Form("Percentage of good events: %3.1f %%\n", goodEvents/nEvents*100);
409 out += Form("Good events reference: %s (first element from parameter file)\n", referenceElementName.Data());
410 out += "=========================================================================\n";
411 out += "Yield Units: bcm(uA), cavq(uA), bpm(mm), sam(mV/uA)\n";
412 out += "Asymmetry/Difference Units: bcm(ppm), cavq(ppm), bpm(um), sam(ppm)\n";
413
414 out += "=========================================================================\n";
415
416
417
418 return out;
419};
420
421
422
423void
425 Double_t yield,
426 Double_t yield_err,
427 Double_t yield_width,
428 TString yield_unit,
429 Double_t asym_diff,
430 Double_t asym_diff_err,
431 Double_t asym_diff_width,
432 TString asym_diff_unit
433 )
434{
435
436 PromptSummaryElement* an_element = NULL;
437 an_element = this->GetElementByName(name);
438 if(an_element) {
439 an_element->FillData(yield, yield_err, yield_width, yield_unit, asym_diff, asym_diff_err, asym_diff_width, asym_diff_unit);
440 }
441 else {
442 if(fLocalDebug) {
443 std::cout
444 << "QwPromptSummary::FillDataInElement : No Element with the name "
445 << name
446 << std::endl;
447 }
448 }
449 return;
450};
451
452
453void
455 Double_t yield,
456 Double_t yield_error,
457 Double_t yield_width,
458 TString yield_unit
459 )
460{
461 PromptSummaryElement* an_element = NULL;
462 an_element = this->GetElementByName(name);
463 if(an_element) {
464 an_element->SetYield(yield);
465 an_element->SetYieldError(yield_error);
466 an_element->SetYieldWidth(yield_width);
467 }
468 else {
469 if(fLocalDebug) {
470 std::cout
471 << "QwPromptSummary::FillYieldToElement : No Element with the name "
472 << name
473 << std::endl;
474 }
475 }
476 return;
477};
478
479void
481 Double_t asym_diff,
482 Double_t asym_diff_err,
483 Double_t asym_diff_width,
484 TString asym_diff_unit
485 )
486{
487 PromptSummaryElement* an_element = NULL;
488 an_element = this->GetElementByName(name);
489 if(an_element) {
490 an_element->SetAsymmetry(asym_diff);
491 an_element->SetAsymmetryError(asym_diff_err);
492 an_element->SetAsymmetryWidth(asym_diff_width);
493 }
494 else {
495 if(fLocalDebug) {
496 std::cout
497 << "QwPromptSummary::FillYieldToElement : No Element with the name "
498 << name
499 << std::endl;
500 }
501 }
502
503 return;
504};
505
506void
507QwPromptSummary::FillDoubleDifference(TString type, TString name1, TString name2)
508{
509 PromptSummaryElement* an_element = NULL;
510
511
512 PromptSummaryElement* one_element = NULL;
513 PromptSummaryElement* two_element = NULL;
514
515 one_element = this->GetElementByName(name1);
516 two_element = this->GetElementByName(name2);
517
518 if(one_element && two_element ) {
519
520 an_element = this->GetElementByName(name1+"-"+name2);
521
522 if(an_element) {
523
524
525 Double_t diff = 0.0;
526 Double_t error_diff = 0.0;
527 Double_t width_diff = 0.0;
528
529 Double_t a = 0.0;
530 Double_t b = 0.0;
531 Double_t a_err = 0.0;
532 Double_t b_err = 0.0;
533 Double_t a_wit = 0.0;
534 Double_t b_wit = 0.0;
535
536
537 if(type.Contains("yield")) {
538 a = one_element -> GetYield();
539 b = two_element -> GetYield();
540 a_err = one_element -> GetYieldError();
541 b_err = two_element -> GetYieldError();
542 a_wit = one_element -> GetYieldWidth();
543 b_wit = two_element -> GetYieldWidth();
544
545 diff = a - b;
546 error_diff = TMath::Sqrt(a_err*a_err + b_err*b_err);
547 width_diff = a_wit - b_wit;
548
549 an_element -> SetYield(diff);
550 an_element -> SetYieldError(error_diff);
551 an_element -> SetYieldWidth(width_diff);
552
553 } else {
554 a = one_element -> GetAsymmetry();
555 b = two_element -> GetAsymmetry();
556 a_err = one_element -> GetAsymmetryError();
557 b_err = two_element -> GetAsymmetryError();
558 a_wit = one_element -> GetAsymmetryWidth();
559 b_wit = two_element -> GetAsymmetryWidth();
560
561 diff = a - b;
562 error_diff = TMath::Sqrt(a_err*a_err + b_err*b_err);
563 width_diff = a_wit - b_wit;
564
565 an_element -> SetAsymmetry(diff);
566 an_element -> SetAsymmetryError(error_diff);
567 an_element -> SetAsymmetryWidth(width_diff);
568
569
570 }
571
572 }
573 else {
574 if(fLocalDebug) {
575 std::cout
576 << "QwPromptSummary::FillYieldToElement : No Element with the name "
577 << name1 + "-" + name2
578 << std::endl;
579 }
580 }
581
582 }
583 else {
584 if(fLocalDebug) {
585 std::cout
586 << "QwPromptSummary::FillDoubleDifference: No Elements with the name "
587 << name1 << " and " << name2
588 << std::endl;
589 }
590 }
591}
592
593void
594QwPromptSummary::PrintCSV(Int_t nEvents, TString start_time, TString end_time)
595{
596 printf("-----------------------\n");
597 TString filename = gQwOptions.GetValue<std::string>("rootfiles");
598 filename+=Form("/summary_%d.txt", fRunNumber);
599 TString header= this->PrintCSVHeader(nEvents, start_time, end_time);
600 std::ofstream output;
601 output.open(filename.Data());
602 output<< header.Data();
603
604 TString secheader= "=========================================================================\n";
605 secheader+=Form("%40s \n","Yields");
606 secheader+="=========================================================================\n" ;
607 output << secheader.Data() ;
608
609 for (auto i=fElementList.begin(); i!=fElementList.end(); i++ )
610 {
611 output << i->second->GetCSVSummary("yield") ;
612 }
613
614
615 secheader= "=========================================================================\n";
616 secheader+=Form("%50s\n","Asymmetries/Differences");
617 secheader+="=========================================================================\n";
618 output << secheader.Data();
619
620 for ( auto j=fElementList.begin(); j!=fElementList.end(); j++ )
621 {
622 output << j->second->GetCSVSummary("asymmetry");
623 }
624
625
626
627 secheader= "=========================================================================\n";
628 secheader+=Form("%55s\n", "Combined Differences/Averages");
629 secheader+="=========================================================================\n";
630 output << secheader.Data();
631
632 for ( auto j=fElementList.begin(); j!=fElementList.end(); j++ )
633 {
634 output << j->second->GetCSVSummary("double");
635 }
636
637 output<< "=========================================================================\n";
638 output<< Form("%45s\n"," End of Summary");
639 output<< "=========================================================================\n";
640 output.close();
641
642 return;
643};
644
645void
647{
648 return;
649};
650
#define gQwOptions
Definition QwOptions.h:31
#define QwVerbose
Predefined log drain for verbose messages.
Definition QwLog.h:54
#define QwError
Predefined log drain for errors.
Definition QwLog.h:39
#define QwMessage
Predefined log drain for regular messages.
Definition QwLog.h:49
#define QwDebug
Predefined log drain for debugging output.
Definition QwLog.h:59
Prompt summary data management.
static const double ppm
Definition QwUnits.h:140
static const double uA
Beam current: base unit is microamp.
Definition QwUnits.h:123
static const double um
Definition QwUnits.h:66
static const double mV_uA
Signal volts per microamp.
Definition QwUnits.h:129
static const double mm
Length units: base unit is mm.
Definition QwUnits.h:65
static std::ostream & endl(std::ostream &)
End of the line.
Definition QwLog.cc:297
Configuration file parser with flexible tokenization and search capabilities.
std::unique_ptr< QwParameterFile > ReadSectionPreamble()
Rewinds to the start and read until it finds next section header.
std::unique_ptr< QwParameterFile > ReadNextSection(std::string &secname, const bool keep_header=false)
void SetYield(const Double_t in)
void SetDifference(const Double_t in)
~PromptSummaryElement() override
void SetYieldWidth(const Double_t in)
void SetAsymmetryWidth(const Double_t in)
TString GetCSVSummary(TString type)
void SetYieldError(const Double_t in)
void SetAsymmetry(const Double_t in)
void SetDifferenceUnit(const TString in)
void Set(TString type, const Double_t a, const Double_t a_err, const Double_t a_width)
void SetAsymmetryUnit(const TString in)
void SetDifferenceError(const Double_t in)
void SetAsymmetryError(const Double_t in)
void FillData(Double_t yield, Double_t yield_err, Double_t yield_width, TString yield_unit, Double_t asym_diff, Double_t asym_diff_err, Double_t asym_diff_width, TString asym_diff_unit)
void SetDifferenceWidth(const Double_t in)
void SetYieldUnit(const TString in)
void FillDataInElement(TString name, Double_t yield, Double_t yield_err, Double_t yield_width, TString yield_unit, Double_t asym_diff, Double_t asym_diff_err, Double_t asym_diff_width, TString asym_diff_unit)
virtual ~QwPromptSummary()
TString PrintTextSummaryTailer()
PromptSummaryElement * fReferenceElement
void AddElement(PromptSummaryElement *in)
TString PrintTextSummaryHeader()
void FillDoubleDifference(TString type, TString name1, TString name2)
void LoadElementsFromParameterFile(const std::string &parameter_file)
PromptSummaryElement * GetElementByName(TString name)
TString PrintCSVHeader(Int_t nEvents, TString start_time, TString end_time)
void FillYieldToElement(TString name, Double_t yield, Double_t yield_error, Double_t yield_width, TString yield_unit)
void FillAsymDiffToElement(TString name, Double_t asym_diff, Double_t asym_diff_err, Double_t asym_diff_width, TString asym_diff_unit)
void PrintCSV(Int_t nEvents, TString start_time, TString end_time)
std::map< TString, PromptSummaryElement * > fElementList