JAPAn
Just Another Parity Analyzer
Loading...
Searching...
No Matches
QwCorrelator.cc
Go to the documentation of this file.
1/*!
2 * \file QwCorrelator.cc
3 * \brief Implementation of correlator data handler using LinRegBlue algorithms
4 * \author Michael Vallee
5 * \date 2018-08-01
6 */
7
8#include "QwCorrelator.h"
9
10// System includes
11#include <utility>
12
13// ROOT headers
14#include "TFile.h"
15#include "TH2D.h"
16
17// Qweak headers
18#include "QwOptions.h"
19#include "QwHelicityPattern.h"
20#include "VQwDataElement.h"
21#include "QwVQWK_Channel.h"
22#include "QwParameterFile.h"
23#include "QwRootFile.h"
24
25// Static members
27
28QwCorrelator::QwCorrelator(const TString& name)
29: VQwDataHandler(name),
30 fBlock(-1),
31 fDisableHistos(true),
32 fAlphaOutputFileBase("blueR"),
33 fAlphaOutputFileSuff("new.slope.root"),
36 fTree(0),
37 fAliasOutputFileBase("regalias_"),
40 fNameNoSpaces(name),
41 nP(0),nY(0),
43{
44 fNameNoSpaces.ReplaceAll(" ","_");
45 // Set default tree name and descriptions (in VQwDataHandler)
46 fTreeName = "lrb";
47 fTreeComment = "Correlations";
48 // Parsing separator
49 ParseSeparator = "_";
50
51 // Clear all data
53}
54
56: VQwDataHandler(source),
57 fBlock(source.fBlock),
63 fTree(0),
67 nP(source.nP),nY(source.nY),
69{
70 QwWarning << "QwCorrelator copy constructor required but untested" << QwLog::endl;
71
72 // Clear all data
74}
75
77{
78 // Close alpha and alias file
81}
82
84{
85 options.AddOptions()("print-correlations",
86 po::value<bool>(&fPrintCorrelations)->default_bool_value(false),
87 "print correlations after determining them");
88}
89
93
95{
97 file.PopValue("slope-file-base", fAlphaOutputFileBase);
98 file.PopValue("slope-file-suff", fAlphaOutputFileSuff);
99 file.PopValue("slope-path", fAlphaOutputPath);
100 file.PopValue("alias-file-base", fAliasOutputFileBase);
101 file.PopValue("alias-file-suff", fAliasOutputFileSuff);
102 file.PopValue("alias-path", fAliasOutputPath);
103 file.PopValue("disable-histos", fDisableHistos);
104 file.PopValue("block", fBlock);
105 if (fBlock >= 4)
106 QwWarning << "QwCorrelator: expect 0 <= block <= 3 but block = "
107 << fBlock << QwLog::endl;
108}
109
111{
112 // Add to total count
113 fTotalCount++;
114
115 // Start as good event
116 fGoodEvent = 0;
117
118 // Event error flag
120 if ( GetEventcutErrorFlag() != 0) fErrCounts_EF++;
121 // Dependent variable error codes
122 for (size_t i = 0; i < fDependentVar.size(); ++i) {
123 fGoodEvent |= fDependentVar.at(i)->GetErrorCode();
124 fDependentValues.at(i) = (fDependentVar[i]->GetValue(fBlock+1));
125 if (fDependentVar.at(i)->GetErrorCode() !=0) (fErrCounts_DV.at(i))++;
126 }
127 // Independent variable error codes
128 for (size_t i = 0; i < fIndependentVar.size(); ++i) {
129 fGoodEvent |= fIndependentVar.at(i)->GetErrorCode();
130 fIndependentValues.at(i) = (fIndependentVar[i]->GetValue(fBlock+1));
131 if (fIndependentVar.at(i)->GetErrorCode() !=0) (fErrCounts_IV.at(i))++;
132 }
133
134 // If good, process event
135 if (fGoodEvent == 0) {
136 fGoodCount++;
137
138 TVectorD P(fIndependentValues.size(), fIndependentValues.data());
139 TVectorD Y(fDependentValues.size(), fDependentValues.data());
140 linReg += std::make_pair(P, Y);
141 }
142}
143
145{
146 // Clear error counters
147 fErrCounts_EF = 0;
148 std::fill(fErrCounts_DV.begin(), fErrCounts_DV.end(), 0);
149 std::fill(fErrCounts_IV.begin(), fErrCounts_IV.end(), 0);
150
151 // Clear event counts
152 fTotalCount = 0;
153 fGoodCount = 0;
154 fGoodEvent = -1;
155
156 // Clear regression
157 linReg.clear();
158}
159
160void QwCorrelator::AccumulateRunningSum(VQwDataHandler &value, Int_t count, Int_t ErrorMask)
161{
162 QwCorrelator* correlator = dynamic_cast<QwCorrelator*>(&value);
163 if (correlator) {
164 linReg += correlator->linReg;
165 } else {
166 QwWarning << "QwCorrelator::AccumulateRunningSum "
167 << "can only accept other QwCorrelator objects."
168 << QwLog::endl;
169 }
170}
171
173{
174 // Check if any channels are active
175 if (nP == 0 || nY == 0) {
176 return;
177 }
178
179 QwMessage << "QwCorrelator::CalcCorrelations(): name=" << GetName() << QwLog::endl;
180
181 // Print entry summary
182 QwVerbose << "QwCorrelator: "
183 << "total entries: " << fTotalCount << ", "
184 << "good entries: " << fGoodCount
185 << QwLog::endl;
186 // and warn if zero
187 if (fTotalCount > 100 && fGoodCount == 0) {
188 QwWarning << "QwCorrelator: "
189 << "< 1% good events, "
190 << fGoodCount << " of " << fTotalCount
191 << QwLog::endl;
192 }
193
194 // Event error flag
195 if (fErrCounts_EF > 0) {
196 QwVerbose << " Entries failed due to error flag: "
198 }
199 // Dependent variable error codes
200 for (size_t i = 0; i < fDependentVar.size(); ++i) {
201 if (fErrCounts_DV.at(i) > 0) {
202 QwVerbose << " Entries failed due to " << fDependentVar.at(i)->GetElementName()
203 << ": " << fErrCounts_DV.at(i) << QwLog::endl;
204 }
205 }
206 // Independent variable error codes
207 for (size_t i = 0; i < fIndependentVar.size(); ++i) {
208 if (fErrCounts_IV.at(i) > 0) {
209 QwVerbose << " Entries failed due to " << fIndependentVar.at(i)->GetElementName()
210 << ": " << fErrCounts_IV.at(i) << QwLog::endl;
211 }
212 }
213
214 if (! linReg.failed()) {
215
216 if (fPrintCorrelations) {
217 linReg.printSummaryP();
218 linReg.printSummaryY();
219 }
220
221 linReg.solve();
222
223 if (fPrintCorrelations) {
224 linReg.printSummaryAlphas();
225 linReg.printSummaryMeansWithUnc();
226 linReg.printSummaryMeansWithUncCorrected();
227 }
228 }
229
230 // Fill tree
231 if (fTree) fTree->Fill();
232 else QwWarning << "No tree" << QwLog::endl;
233
234 // Write alpha and alias file
237}
238
239
240/** Load the channel map
241 *
242 * @param mapfile Filename of map file
243 * @return Zero when success
244 */
245Int_t QwCorrelator::LoadChannelMap(const std::string& mapfile)
246{
247 // Open the file
248 QwParameterFile map(mapfile);
249
250 // Read the sections of dependent variables
251 std::pair<EQwHandleType,std::string> type_name;
252
253 // Add independent variables and sensitivities
254 while (map.ReadNextLine()) {
255 // Throw away comments, whitespace, empty lines
256 map.TrimComment();
257 map.TrimWhitespace();
258 if (map.LineIsEmpty()) continue;
259 // Get first token: label (dv or iv), second token is the name like "asym_blah"
260 string primary_token = map.GetNextToken(" ");
261 string current_token = map.GetNextToken(" ");
262 // Parse current token into independent variable type and name
263 type_name = ParseHandledVariable(current_token);
264
265 if (primary_token == "iv") {
266 fIndependentType.push_back(type_name.first);
267 fIndependentName.push_back(type_name.second);
268 fIndependentFull.push_back(current_token);
269 }
270 else if (primary_token == "dv") {
271 fDependentType.push_back(type_name.first);
272 fDependentName.push_back(type_name.second);
273 fDependentFull.push_back(current_token);
274 }
275 else if (primary_token == "treetype") {
276 QwMessage << "Tree Type read, ignoring." << QwLog::endl;
277 }
278 else {
279 QwError << "LoadChannelMap in QwCorrelator read invalid primary_token " << primary_token << QwLog::endl;
280 }
281 }
282
283 return 0;
284}
285
286
288{
290
291 // Return if correlator is not enabled
292
293 /// Fill vector of pointers to the relevant data elements
294 for (size_t dv = 0; dv < fDependentName.size(); dv++) {
295 // Get the dependent variables
296
297 const VQwHardwareChannel* dv_ptr = 0;
298
299 if (fDependentType.at(dv)==kHandleTypeMps){
300 // Quietly ignore the MPS type when we're connecting the asym & diff
301 continue;
302 }else{
303 dv_ptr = this->RequestExternalPointer(fDependentFull.at(dv));
304 if (dv_ptr==NULL){
305 switch (fDependentType.at(dv)) {
306 case kHandleTypeAsym:
307 dv_ptr = asym.RequestExternalPointer(fDependentName.at(dv));
308 break;
309 case kHandleTypeDiff:
310 dv_ptr = diff.RequestExternalPointer(fDependentName.at(dv));
311 break;
312 default:
313 QwWarning << "QwCorrelator::ConnectChannels(QwSubsystemArrayParity& asym, QwSubsystemArrayParity& diff): "
314 << "Dependent variable, " << fDependentName.at(dv)
315 << ", for asym/diff correlator does not have proper type, type=="
316 << fDependentType.at(dv) << "." << QwLog::endl;
317 break;
318 }
319 }
320 if (dv_ptr == NULL){
321 QwWarning << "QwCombiner::ConnectChannels(QwSubsystemArrayParity& asym, QwSubsystemArrayParity& diff): Dependent variable, "
322 << fDependentName.at(dv)
323 << ", was not found (fullname=="
324 << fDependentFull.at(dv)<< ")." << QwLog::endl;
325 continue;
326 }
327 }
328
329 // pair creation
330 if(dv_ptr != NULL){
331 // fDependentVarType.push_back(fDependentType.at(dv));
332 fDependentVar.push_back(dv_ptr);
333 }
334
335 }
336
337 // Add independent variables
338 for (size_t iv = 0; iv < fIndependentName.size(); iv++) {
339 // Get the independent variables
340 const VQwHardwareChannel* iv_ptr = 0;
341 iv_ptr = this->RequestExternalPointer(fIndependentFull.at(iv));
342 if (iv_ptr==NULL){
343 switch (fIndependentType.at(iv)) {
344 case kHandleTypeAsym:
345 iv_ptr = asym.RequestExternalPointer(fIndependentName.at(iv));
346 break;
347 case kHandleTypeDiff:
348 iv_ptr = diff.RequestExternalPointer(fIndependentName.at(iv));
349 break;
350 default:
351 QwWarning << "Independent variable for correlator has unknown type."
352 << QwLog::endl;
353 break;
354 }
355 }
356 if (iv_ptr) {
357 fIndependentVar.push_back(iv_ptr);
358 } else {
359 QwWarning << "Independent variable " << fIndependentName.at(iv) << " for correlator could not be found."
360 << QwLog::endl;
361 }
362
363 }
364 fIndependentValues.resize(fIndependentVar.size());
365 fDependentValues.resize(fDependentVar.size());
366
367 nP = fIndependentName.size();
368 nY = fDependentName.size();
369
370 linReg.setDims(nP, nY);
371 linReg.init();
372
373 fErrCounts_IV.resize(fIndependentVar.size(),0);
374 fErrCounts_DV.resize(fDependentVar.size(),0);
375
376 return 0;
377}
378
379
381 QwRootFile *treerootfile,
382 const std::string& treeprefix,
383 const std::string& branchprefix)
384{
385 // Check if any channels are active
386 if (nP == 0 || nY == 0) {
387 return;
388 }
389
390 // Check if tree name is specified
391 if (fTreeName == "") {
392 QwWarning << "QwCorrelator: no tree name specified, use 'tree-name = value'" << QwLog::endl;
393 return;
394 }
395
396 // Create alpha and alias files before trying to create the tree
397 OpenAlphaFile(treeprefix);
398 OpenAliasFile(treeprefix);
399
400 // Construct tree name and create new tree
401 const std::string name = treeprefix + fTreeName;
402 treerootfile->NewTree(name, fTreeComment.c_str());
403 fTree = treerootfile->GetTree(name);
404 // Check to make sure the tree was created successfully
405 if (fTree == NULL) return;
406
407 // Set up branches
408 fTree->Branch(TString(branchprefix + "total_count"), &fTotalCount);
409 fTree->Branch(TString(branchprefix + "good_count"), &fGoodCount);
410
411 fTree->Branch(TString(branchprefix + "n"), &(linReg.fGoodEventNumber));
412 fTree->Branch(TString(branchprefix + "ErrorFlag"), &(linReg.fErrorFlag));
413
414 auto bn = [&](const TString& n) {
415 return TString(branchprefix + n);
416 };
417 auto pm = [](TMatrixD& m) {
418 return m.GetMatrixArray();
419 };
420 auto lm = [](TMatrixD& m, const TString& n) {
421 return Form("%s[%d][%d]/D", n.Data(), m.GetNrows(), m.GetNcols());
422 };
423 auto branchm = [&](TTree* tree, TMatrixD& m, const TString& n) {
424 tree->Branch(bn(n),pm(m),lm(m,n));
425 };
426 auto pv = [](TVectorD& v) {
427 return v.GetMatrixArray();
428 };
429 auto lv = [](TVectorD& v, const TString& n) {
430 return Form("%s[%d]/D", n.Data(), v.GetNrows());
431 };
432 auto branchv = [&](TTree* tree, TVectorD& v, const TString& n) {
433 tree->Branch(bn(n),pv(v),lv(v,n));
434 };
435
436 branchm(fTree,linReg.Axy, "A");
437 branchm(fTree,linReg.dAxy, "dA");
438
439 branchm(fTree,linReg.mVPP, "VPP");
440 branchm(fTree,linReg.mVPY, "VPY");
441 branchm(fTree,linReg.mVYP, "VYP");
442 branchm(fTree,linReg.mVYY, "VYY");
443 branchm(fTree,linReg.mVYYp, "VYYp");
444
445 branchm(fTree,linReg.mSPP, "SPP");
446 branchm(fTree,linReg.mSPY, "SPY");
447 branchm(fTree,linReg.mSYP, "SYP");
448 branchm(fTree,linReg.mSYY, "SYY");
449 branchm(fTree,linReg.mSYYp, "SYYp");
450
451 branchm(fTree,linReg.mRPP, "RPP");
452 branchm(fTree,linReg.mRPY, "RPY");
453 branchm(fTree,linReg.mRYP, "RYP");
454 branchm(fTree,linReg.mRYY, "RYY");
455 branchm(fTree,linReg.mRYYp, "RYYp");
456
457 branchv(fTree,linReg.mMP, "MP"); // Parameter mean
458 branchv(fTree,linReg.mMY, "MY"); // Uncorrected mean
459 branchv(fTree,linReg.mMYp, "MYp"); // Corrected mean
460
461 branchv(fTree,linReg.mSP, "dMP"); // Parameter mean error
462 branchv(fTree,linReg.mSY, "dMY"); // Uncorrected mean error
463 branchv(fTree,linReg.mSYp, "dMYp"); // Corrected mean error
464
465}
466
467/// \brief Construct the histograms in a folder with a prefix
468void QwCorrelator::ConstructHistograms(TDirectory *folder, TString &prefix)
469{
470 // Skip if disabled
471 if (fDisableHistos) return;
472
473 // Check if any channels are active
474 if (nP == 0 || nY == 0) {
475 return;
476 }
477
478 // Go to directory
479 TString name(fName);
480 name.ReplaceAll(" ","_");
481 folder->mkdir(name)->cd();
482
483 //..... 1D, iv
484 fH1iv.resize(nP);
485 for (int i = 0; i < nP; i++) {
486 fH1iv[i] = TH1D(
487 Form("P%d",i),
488 Form("iv P%d=%s, pass=%s ;iv=%s (ppm)",i,fIndependentName[i].c_str(),fName.Data(),fIndependentName[i].c_str()),
489 128,0.,0.);
490 fH1iv[i].GetXaxis()->SetNdivisions(4);
491 }
492
493 //..... 2D, iv correlations
494 Double_t x1 = 0;
495 fH2iv.resize(nP);
496 for (int i = 0; i < nP; i++) {
497 fH2iv[i].resize(nP);
498 for (int j = i+1; j < nP; j++) { // not all are used
499 fH2iv[i][j] = TH2D(
500 Form("P%d_P%d",i,j),
501 Form("iv correlation P%d_P%d, pass=%s ;P%d=%s (ppm);P%d=%s (ppm) ",
502 i,j,fName.Data(),i,fIndependentName[i].c_str(),j,fIndependentName[j].c_str()),
503 64,-x1,x1,
504 64,-x1,x1);
505 fH2iv[i][j].GetXaxis()->SetTitleColor(kBlue);
506 fH2iv[i][j].GetYaxis()->SetTitleColor(kBlue);
507 fH2iv[i][j].GetXaxis()->SetNdivisions(4);
508 fH2iv[i][j].GetYaxis()->SetNdivisions(4);
509 }
510 }
511
512 //..... 1D, dv
513 fH1dv.resize(nY);
514 for (int i = 0; i < nY; i++) {
515 fH1dv[i] = TH1D(
516 Form("Y%d",i),
517 Form("dv Y%d=%s, pass=%s ;dv=%s (ppm)",i,fDependentName[i].c_str(),fName.Data(),fDependentName[i].c_str()),
518 128,0.,0.);
519 fH1dv[i].GetXaxis()->SetNdivisions(4);
520 }
521
522 //..... 2D, dv-iv correlations
523 Double_t y1 = 0;
524 fH2dv.resize(nP);
525 for (int i = 0; i < nP; i++) {
526 fH2dv[i].resize(nY);
527 for (int j = 0; j < nY; j++) {
528 fH2dv[i][j] = TH2D(
529 Form("P%d_Y%d",i,j),
530 Form("iv-dv correlation P%d_Y%d, pass=%s ;P%d=%s (ppm);Y%d=%s (ppm) ",
531 i,j,fName.Data(),i,fIndependentName[i].c_str(),j,fDependentName[j].c_str()),
532 64,-x1,x1,
533 64,-y1,y1);
534 fH2dv[i][j].GetXaxis()->SetTitleColor(kBlue);
535 fH2dv[i][j].GetYaxis()->SetTitleColor(kBlue);
536 fH2dv[i][j].GetXaxis()->SetNdivisions(4);
537 fH2dv[i][j].GetYaxis()->SetNdivisions(4);
538 }
539 }
540
541 // store list of names to be archived
542 fHnames.resize(2);
543 fHnames[0] = TH1D("NamesIV",Form("IV name list nIV=%d",nP),nP,0,1);
544 for (int i = 0; i < nP; i++)
545 fHnames[0].Fill(fIndependentName[i].c_str(),1.*i);
546 fHnames[1] = TH1D("NamesDV",Form("DV name list nIV=%d",nY),nY,0,1);
547 for (int i = 0; i < nY; i++)
548 fHnames[1].Fill(fDependentName[i].c_str(),i*1.);
549}
550
551/// \brief Fill the histograms
553{
554 // Skip if disabled
555 if (fDisableHistos) return;
556
557 // Check if any channels are active
558 if (nP == 0 || nY == 0) {
559 return;
560 }
561
562 // Skip if bad event
563 if (fGoodEvent != 0) return;
564
565 // Fill histograms
566 for (size_t i = 0; i < fIndependentValues.size(); i++) {
567 fH1iv[i].Fill(fIndependentValues[i]);
568 for (size_t j = i+1; j < fIndependentValues.size(); j++)
570 }
571 for (size_t j = 0; j < fDependentValues.size(); j++) {
572 fH1dv[j].Fill(fDependentValues[j]);
573 for (size_t i = 0; i < fIndependentValues.size(); i++)
574 fH2dv[i][j].Fill(fIndependentValues[i], fDependentValues[j]);
575 }
576}
577
579{
580 // Ensure in output file
582
583 // Write objects
584 linReg.Axy.Write("slopes");
585 linReg.dAxy.Write("sigSlopes");
586
587 linReg.mRPP.Write("IV_IV_correlation");
588 linReg.mRPY.Write("IV_DV_correlation");
589 linReg.mRYY.Write("DV_DV_correlation");
590 linReg.mRYYp.Write("DV_DV_correlation_prime");
591
592 linReg.mMP.Write("IV_mean");
593 linReg.mMY.Write("DV_mean");
594 linReg.mMYp.Write("DV_mean_prime");
595
596 // number of events
597 TMatrixD Mstat(1,1);
598 Mstat(0,0)=linReg.getUsedEve();
599 Mstat.Write("MyStat");
600
601 //... IVs
602 TH1D hiv("IVname","names of IVs",nP,-0.5,nP-0.5);
603 for (int i=0;i<nP;i++) hiv.Fill(fIndependentFull[i].c_str(),i);
604 hiv.Write();
605
606 //... DVs
607 TH1D hdv("DVname","names of IVs",nY,-0.5,nY-0.5);
608 for (int i=0;i<nY;i++) hdv.Fill(fDependentFull[i].c_str(),i);
609 hdv.Write();
610
611 // sigmas
612 linReg.mSP.Write("IV_sigma");
613 linReg.mSY.Write("DV_sigma");
614 linReg.mSYp.Write("DV_sigma_prime");
615
616 // raw covariances
617 linReg.mVPP.Write("IV_IV_rawVariance");
618 linReg.mVPY.Write("IV_DV_rawVariance");
619 linReg.mVYY.Write("DV_DV_rawVariance");
620 linReg.mVYYp.Write("DV_DV_rawVariance_prime");
621 TVectorD mVY2(TMatrixDDiag(linReg.mVYY));
622 mVY2.Write("DV_rawVariance");
623 TVectorD mVP2(TMatrixDDiag(linReg.mVPP));
624 mVP2.Write("IV_rawVariance");
625 TVectorD mVY2prime(TMatrixDDiag(linReg.mVYYp));
626 mVY2prime.Write("DV_rawVariance_prime");
627
628 // normalized covariances
629 linReg.mSPP.Write("IV_IV_normVariance");
630 linReg.mSPY.Write("IV_DV_normVariance");
631 linReg.mSYY.Write("DV_DV_normVariance");
632 linReg.mSYYp.Write("DV_DV_normVariance_prime");
633 TVectorD sigY2(TMatrixDDiag(linReg.mSYY));
634 sigY2.Write("DV_normVariance");
635 TVectorD sigX2(TMatrixDDiag(linReg.mSPP));
636 sigX2.Write("IV_normVariance");
637 TVectorD sigY2prime(TMatrixDDiag(linReg.mSYYp));
638 sigY2prime.Write("DV_normVariance_prime");
639
640 linReg.Axy.Write("A_xy");
641 linReg.Ayx.Write("A_yx");
642}
643
644void QwCorrelator::OpenAlphaFile(const std::string& prefix)
645{
646 // Create old-style blueR ROOT file
647 std::string name = prefix + fAlphaOutputFileBase + run_label.Data() + fAlphaOutputFileSuff;
648 std::string path = fAlphaOutputPath + "/";
649 std::string file = path + name;
650 fAlphaOutputFile = new TFile(TString(file), "RECREATE", "correlation coefficients");
651 if (! fAlphaOutputFile->IsWritable()) {
652 QwError << "QwCorrelator could not create output file " << file << QwLog::endl;
653 delete fAlphaOutputFile;
655 }
656}
657
658void QwCorrelator::OpenAliasFile(const std::string& prefix)
659{
660 // Turn "." into "_" in run_label (no "." allowed in function name, and must
661 // agree with the filename)
662 std::string label(run_label);
663 std::replace(label.begin(), label.end(), '.', '_');
664 // Create old-style regalias script
665 std::string name = prefix + fAliasOutputFileBase + label + fAliasOutputFileSuff;
666 std::string path = fAliasOutputPath + "/";
667 std::string file = path + name + ".C"; // add extension outside of file suffix
668 fAliasOutputFile.open(file, std::ofstream::out);
669 if (fAliasOutputFile.good()) {
670 fAliasOutputFile << Form("void %s(int i = 0) {", name.c_str()) << std::endl;
671 } else {
672 QwWarning << "QwCorrelator: Could not write to alias output file " << QwLog::endl;
673 }
674}
675
677{
678 // Close slopes output file
679 if (fAlphaOutputFile) {
680 // Switch to this file's directory before writing to avoid
681 // trying to write objects from other (possibly closed) files
682 fAlphaOutputFile->cd();
683 fAlphaOutputFile->Write();
684 fAlphaOutputFile->Close();
685 }
686}
687
689{
690 // Close alias output file
691 if (fAliasOutputFile.good()) {
692 fAliasOutputFile << "}" << std::endl << std::endl;
693 fAliasOutputFile.close();
694 } else {
695 QwWarning << "QwCorrelator: Unable to close alias output file." << QwLog::endl;
696 }
697}
698
700{
701 // Ensure output file is open
702 if (fAliasOutputFile.bad()) {
703 QwWarning << "QwCorrelator: Could not write to alias output file " << QwLog::endl;
704 return;
705 }
706
707 fAliasOutputFile << " if (i == " << fCycleCounter << ") {" << std::endl;
708 fAliasOutputFile << Form(" TTree* tree = (TTree*) gDirectory->Get(\"mul\");") << std::endl;
709 for (int i = 0; i < nY; i++) {
710 fAliasOutputFile << Form(" tree->SetAlias(\"reg_%s\",",fDependentFull[i].c_str()) << std::endl;
711 fAliasOutputFile << Form(" \"%s",fDependentFull[i].c_str());
712 for (int j = 0; j < nP; j++) {
713 fAliasOutputFile << Form("%+.4e*%s", -linReg.Axy(j,i), fIndependentFull[j].c_str());
714 }
715 fAliasOutputFile << "\");" << std::endl;
716 }
717 fAliasOutputFile << " }" << std::endl;
718
719 // Increment call counter
721}
An options class which parses command line, config file and environment.
#define QwVerbose
Predefined log drain for verbose messages.
Definition QwLog.h:54
#define QwError
Predefined log drain for errors.
Definition QwLog.h:39
#define QwWarning
Predefined log drain for warnings.
Definition QwLog.h:44
#define QwMessage
Predefined log drain for regular messages.
Definition QwLog.h:49
ROOT file and tree management wrapper classes.
Parameter file parsing and management.
Definition of the pure virtual base class of all data elements.
Decoding and management for VQWK ADC channels (6x32-bit datawords)
Correlator data handler using LinRegBlue algorithms.
Helicity pattern analysis and management.
const VQwHardwareChannel * RequestExternalPointer(const TString &name) const
const VQwHardwareChannel * RequestExternalPointer(const TString &name) const
Retrieve a direct pointer to an external variable Searches for the named variable in external subsyst...
static std::ostream & endl(std::ostream &)
End of the line.
Definition QwLog.cc:297
Command-line and configuration file options processor.
Definition QwOptions.h:141
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:170
Configuration file parser with flexible tokenization and search capabilities.
Bool_t PopValue(const std::string keyname, T &retvalue)
void TrimWhitespace(TString::EStripType head_tail=TString::kBoth)
void TrimComment(const char commentchar)
std::string GetNextToken(const std::string &separatorchars)
Get next token as a string.
A wrapper class for a ROOT file or memory mapped file.
Definition QwRootFile.h:833
void NewTree(const std::string &name, const std::string &desc)
Create a new tree with name and description.
Definition QwRootFile.h:918
TTree * GetTree(const std::string &name)
Get the tree with name.
Definition QwRootFile.h:949
Abstract base for concrete hardware channels implementing dual-operator pattern.
std::vector< std::string > fIndependentName
void OpenAliasFile(const std::string &prefix)
unsigned int fGoodEvent
void WriteAlphaFile()
std::string fAlphaOutputPath
void CloseAliasFile()
void ClearEventData() override
std::string fAliasOutputFileBase
void OpenAlphaFile(const std::string &prefix)
void ProcessData() override
QwCorrelator(const TString &name)
Constructor with name.
std::vector< std::vector< TH2D > > fH2iv
void CalcCorrelations()
~QwCorrelator() override
std::vector< Double_t > fIndependentValues
std::string fAlphaOutputFileBase
std::vector< EQwHandleType > fIndependentType
std::string fAliasOutputPath
std::ofstream fAliasOutputFile
Int_t ConnectChannels(QwSubsystemArrayParity &asym, QwSubsystemArrayParity &diff) override
Connect to Channels (asymmetry/difference only)
TString fNameNoSpaces
TFile * fAlphaOutputFile
void ConstructTreeBranches(QwRootFile *treerootfile, const std::string &treeprefix="", const std::string &branchprefix="") override
Construct the tree branches.
void ParseConfigFile(QwParameterFile &file) override
void CloseAlphaFile()
Int_t fCycleCounter
static bool fPrintCorrelations
void WriteAliasFile()
LinRegBevPeb linReg
void ConstructHistograms(TDirectory *folder, TString &prefix) override
Construct the histograms in a folder with a prefix.
std::vector< std::string > fIndependentFull
std::vector< const VQwHardwareChannel * > fIndependentVar
std::string fAlphaOutputFileSuff
std::vector< TH1D > fHnames
std::vector< TH1D > fH1dv
std::string fAliasOutputFileSuff
std::vector< std::vector< TH2D > > fH2dv
std::vector< TH1D > fH1iv
void ProcessOptions(QwOptions &options)
std::vector< int > fErrCounts_DV
void FillHistograms() override
Fill the histograms.
bool fDisableHistos
std::vector< int > fErrCounts_IV
static void DefineOptions(QwOptions &options)
Subsystem array container specialized for parity analysis with asymmetry calculations.
const UInt_t * GetEventcutErrorFlagPointer() const
std::vector< std::string > fDependentFull
void AccumulateRunningSum()
void SetEventcutErrorFlagPointer(const UInt_t *errorflagptr)
TString GetName()
std::vector< Double_t > fDependentValues
virtual void ParseConfigFile(QwParameterFile &file)
std::vector< const VQwHardwareChannel * > fDependentVar
UInt_t GetEventcutErrorFlag() const
VQwDataHandler(const TString &name)
std::string ParseSeparator
std::string fTreeComment
std::string fTreeName
std::pair< EQwHandleType, std::string > ParseHandledVariable(const std::string &variable)
std::vector< EQwHandleType > fDependentType
std::vector< std::string > fDependentName