JAPAn
Just Another Parity Analyzer
Loading...
Searching...
No Matches
GrandCorrelator.cc
Go to the documentation of this file.
1#include "GrandCorrelator.h"
2
3// System includes
4#include <algorithm>
5#include <fstream>
6#include <utility>
7#include <assert.h>
8#include <math.h>
9
10// ROOT headers
11#include "TFile.h"
12#include "TH2D.h"
13#include "TString.h"
14
15
16// Qweak headers
17#include "QwOptions.h"
18#include "QwHelicityPattern.h"
19#include "VQwDataElement.h"
20#include "QwVQWK_Channel.h"
21#include "QwParameterFile.h"
22#include "QwRootFile.h"
23#include "QwLog.h"
24
25// Static members
27
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{
57 // Close alpha and alias file
60}
61
63{
64 options.AddOptions()("print-correlations",
65 po::value<bool>(&fPrintCorrelations)->default_bool_value(false),
66 "print correlations after determining them");
67}
68
72
74{
76 file.PopValue("slope-file-base", fAlphaOutputFileBase);
77 file.PopValue("slope-file-suff", fAlphaOutputFileSuff);
78 file.PopValue("slope-path", fAlphaOutputPath);
79 file.PopValue("alias-file-base", fAliasOutputFileBase);
80 file.PopValue("alias-file-suff", fAliasOutputFileSuff);
81 file.PopValue("alias-path", fAliasOutputPath);
82 file.PopValue("disable-histos", fDisableHistos);
83 file.PopValue("block", fBlock);
84 if (fBlock >= 4)
85 QwWarning << "GrandCorrelator: expect 0 <= block <= 3 but block = "
86 << fBlock << QwLog::endl;
87}
88
89
91{
93 fGoodEvent = 0;
94 // Event error flag
97 // Dependent variable error codes
98 for (size_t i = 0; i < fDependentVar.size(); ++i) {
99 //fGoodEvent |= fDependentVar.at(i)->GetErrorCode();
100 fDependentValues.at(i) = (fDependentVar[i]->GetValue(fBlock+1));
101 if (fDependentVar.at(i)->GetErrorCode() !=0) (fErrCounts_DV.at(i))++;
102 }
103 // Independent variable error codes
104 for (size_t i = 0; i < fIndependentVar.size(); ++i) {
105 //fGoodEvent |= fIndependentVar.at(i)->GetErrorCode();
106 fIndependentValues.at(i) = (fIndependentVar[i]->GetValue(fBlock+1));
107 if (fIndependentVar.at(i)->GetErrorCode() !=0) (fErrCounts_IV.at(i))++;
108 }
109
110 for(size_t i = 0; i < fAllVar.size(); ++i){
111 fAllGood[i] = (fAllVar[i]->GetErrorCode() == 0);
112 fAllValues[i] = fAllVar[i]->GetValue(fBlock+1);
113 //if(!fAllGood[i]) fErrCounts_IV[i]++;
114 }
115 if(fGoodEvent != 0){
116 return;
117 }
119 //TVectorD P(fIndependentValues.size(), fIndependentValues.data());
120 //TVectorD Y(fDependentValues.size(), fDependentValues.data());
121 //operator+= (std::make_pair(P, Y));
122
123 for(size_t i = 0; i<fAllVar.size(); ++i){
124 for(size_t j = i; j<fAllVar.size(); ++j){
125 if(!fAllGood[i] || !fAllGood[j]) continue;
126
127 double xi = fAllValues[i];
128 double xj = fAllValues[j];
129 double delta_i = xi - mMij(i,j);
130 double delta_j = xj - mMij(j,i);
131
132 mNij(i,j) += 1;
133 mMij(i,j) += delta_i / mNij(i,j);
134 mSij(i,j) += delta_i * (xi-mMij(i,j));
135 if (mNij(i,j)<=1){
136 mCij(i,j) = 0.0;
137 } else {
138 mCij(i,j) += ((mNij(i,j) - 1) / mNij(i,j)) * (delta_i) * (delta_j);
139 }
140
141 if (j>i){
142 mNij(j,i) = mNij(i,j);
143 mMij(j,i) += delta_j / mNij(j,i);
144 mSij(j,i) += delta_j * (xj - mMij(j,i));
145 mCij(j,i) = mCij(i,j);
146 }
147
148
149 }
150 }
151}
152
154{
155 // Clear error counters
156 fErrCounts_EF = 0;
157 std::fill(fErrCounts_DV.begin(), fErrCounts_DV.end(), 0);
158 std::fill(fErrCounts_IV.begin(), fErrCounts_IV.end(), 0);
159
160 // Clear event counts
161 fTotalCount = 0;
163 fGoodEvent = -1;
164
165 // Clear regression
166 this->clear();
167}
168
169void GrandCorrelator::AccumulateRunningSum(VQwDataHandler &value, Int_t count, Int_t ErrorMask)
170{
171 GrandCorrelator* correlator = dynamic_cast<GrandCorrelator*>(&value);
172 if (correlator) {
173 operator+=(*correlator);
174 } else {
175 QwWarning << "GrandCorrelator::AccumulateRunningSum "
176 << "can only accept other GrandCorrelator objects."
177 << QwLog::endl;
178 }
179}
180
182{
183 // Check if any channels are active
184 if (nP == 0 || nY == 0) {
185 return;
186 }
187
188 QwMessage << "GrandCorrelator::CalcCorrelations(): name=" << GetName() << QwLog::endl;
189
190 // Print entry summary
191 QwVerbose << "GrandCorrelator: "
192 << "total entries: " << fTotalCount << ", "
193 << "good entries: " << fGoodEventNumber
194 << QwLog::endl;
195 // and warn if zero
196 if (fTotalCount > 100 && fGoodEventNumber == 0) {
197 QwWarning << "GrandCorrelator: "
198 << "< 1% good events, "
199 << fGoodEventNumber << " of " << fTotalCount
200 << QwLog::endl;
201 }
202
203 // Event error flag
204 if (fErrCounts_EF > 0) {
205 QwVerbose << " Entries failed due to error flag: "
207 }
208 // Dependent variable error codes
209 for (size_t i = 0; i < fDependentVar.size(); ++i) {
210 if (fErrCounts_DV.at(i) > 0) {
211 QwVerbose << " Entries failed due to " << fDependentVar.at(i)->GetElementName()
212 << ": " << fErrCounts_DV.at(i) << QwLog::endl;
213 }
214 }
215 // Independent variable error codes
216 for (size_t i = 0; i < fIndependentVar.size(); ++i) {
217 if (fErrCounts_IV.at(i) > 0) {
218 QwVerbose << " Entries failed due to " << fIndependentVar.at(i)->GetElementName()
219 << ": " << fErrCounts_IV.at(i) << QwLog::endl;
220 }
221 }
222
223 if (! this->failed()) {
224 if (fPrintCorrelations) {
225 this->printSummaryP();
226 this->printSummaryY();
227 }
228
229 this->solve();
230
231 if (kTRUE || fPrintCorrelations) {
232 this->printSummaryAlphas();
235 }
236 }
237
238 // Fill tree
239 if (fTree) fTree->Fill();
240 else QwWarning << "No tree" << QwLog::endl;
241
242 // Write alpha and alias file
245}
246
247/** Load the channel map
248 *
249 * @param mapfile Filename of map file
250 * @return Zero when success
251 */
252Int_t GrandCorrelator::LoadChannelMap(const std::string& mapfile)
253{
254 // Open the file
255 QwParameterFile map(mapfile);
256
257 // Read the sections of dependent variables
258 std::pair<EQwHandleType,std::string> type_name;
259
260 // Add independent variables and sensitivities
261 while (map.ReadNextLine()) {
262 // Throw away comments, whitespace, empty lines
263 map.TrimComment();
264 map.TrimWhitespace();
265 if (map.LineIsEmpty()) continue;
266 // Get first token: label (dv or iv), second token is the name like "asym_blah"
267 string primary_token = map.GetNextToken(" ");
268 string current_token = map.GetNextToken(" ");
269 // Parse current token into independent variable type and name
270 type_name = ParseHandledVariable(current_token);
271
272 if (primary_token == "iv") {
273 fIndependentType.push_back(type_name.first);
274 fIndependentName.push_back(type_name.second);
275 fIndependentFull.push_back(current_token);
276 }
277 else if (primary_token == "dv") {
278 fDependentType.push_back(type_name.first);
279 fDependentName.push_back(type_name.second);
280 fDependentFull.push_back(current_token);
281 }
282 else if (primary_token == "treetype") {
283 QwMessage << "Tree Type read, ignoring." << QwLog::endl;
284 }
285 else {
286 QwError << "LoadChannelMap in GrandCorrelator read invalid primary_token " << primary_token << QwLog::endl;
287 }
288 }
289
290 return 0;
291}
292
294{
296
297 // Return if correlator is not enabled
298
299 /// Fill vector of pointers to the relevant data elements
300 for (size_t dv = 0; dv < fDependentName.size(); dv++) {
301 // Get the dependent variables
302
303 const VQwHardwareChannel* dv_ptr = 0;
304
305 if (fDependentType.at(dv)==kHandleTypeMps){
306 // Quietly ignore the MPS type when we're connecting the asym & diff
307 continue;
308 }else{
309 dv_ptr = this->RequestExternalPointer(fDependentFull.at(dv));
310 if (dv_ptr==NULL){
311 switch (fDependentType.at(dv)) {
312 case kHandleTypeAsym:
313 dv_ptr = asym.RequestExternalPointer(fDependentName.at(dv));
314 break;
315 case kHandleTypeDiff:
316 dv_ptr = diff.RequestExternalPointer(fDependentName.at(dv));
317 break;
318 default:
319 QwWarning << "GrandCorrelator::ConnectChannels(QwSubsystemArrayParity& asym, QwSubsystemArrayParity& diff): "
320 << "Dependent variable, " << fDependentName.at(dv)
321 << ", for asym/diff correlator does not have proper type, type=="
322 << fDependentType.at(dv) << "." << QwLog::endl;
323 break;
324 }
325 }
326
327
328
329 if (dv_ptr == NULL){
330 QwWarning << "QwCombiner::ConnectChannels(QwSubsystemArrayParity& asym, QwSubsystemArrayParity& diff): Dependent variable, "
331 << fDependentName.at(dv)
332 << ", was not found (fullname=="
333 << fDependentFull.at(dv)<< ")." << QwLog::endl;
334 continue;
335 }
336 }
337
338 // pair creation
339 if(dv_ptr != NULL){
340 // fDependentVarType.push_back(fDependentType.at(dv));
341 fDependentVar.push_back(dv_ptr);
342 }
343
344 }
345
346 // Add independent variables
347 for (size_t iv = 0; iv < fIndependentName.size(); iv++) {
348 // Get the independent variables
349 const VQwHardwareChannel* iv_ptr = 0;
350 iv_ptr = this->RequestExternalPointer(fIndependentFull.at(iv));
351 if (iv_ptr==NULL){
352 switch (fIndependentType.at(iv)) {
353 case kHandleTypeAsym:
354 iv_ptr = asym.RequestExternalPointer(fIndependentName.at(iv));
355 break;
356 case kHandleTypeDiff:
357 iv_ptr = diff.RequestExternalPointer(fIndependentName.at(iv));
358 break;
359 default:
360 QwWarning << "Independent variable for correlator has unknown type."
361 << QwLog::endl;
362 break;
363 }
364 }
365
366 if (iv_ptr) {
367 fIndependentVar.push_back(iv_ptr);
368
369 } else {
370 QwWarning << "Independent variable " << fIndependentName.at(iv) << " for correlator could not be found."
371 << QwLog::endl;
372 }
373
374 }
375 fIndependentValues.resize(fIndependentVar.size());
376 fDependentValues.resize(fDependentVar.size());
377
378 nP = fIndependentName.size();
379 nY = fDependentName.size();
380
381 this->setDims(nP, nY);
382 this->init();
383
384 fErrCounts_IV.resize(fIndependentVar.size(),0);
385 fErrCounts_DV.resize(fDependentVar.size(),0);
386
387 // Create vector list for all values
389 fAllVar.insert(fAllVar.end(), fDependentVar.begin(), fDependentVar.end());
391 fAllValues.insert(fAllValues.end(), fDependentValues.begin(), fDependentValues.end());
392 fAllGood.resize(fAllValues.size(), true);
393
394
395 return 0;
396}
397
398
399
401 QwRootFile *treerootfile,
402 const std::string& treeprefix,
403 const std::string& branchprefix)
404{
405 // Check if any channels are active
406 if (nP == 0 || nY == 0) {
407 return;
408 }
409
410 // Check if tree name is specified
411 if (fTreeName == "") {
412 QwWarning << "GrandCorrelator: no tree name specified, use 'tree-name = value'" << QwLog::endl;
413 return;
414 }
415
416 // Create alpha and alias files before trying to create the tree
417 OpenAlphaFile(treeprefix);
418 OpenAliasFile(treeprefix);
419
420 // Construct tree name and create new tree
421 const std::string name = treeprefix + fTreeName;
422 treerootfile->NewTree(name, fTreeComment.c_str());
423 fTree = treerootfile->GetTree(name);
424 // Check to make sure the tree was created successfully
425 if (fTree == NULL) return;
426
427 // Set up branches
428 fTree->Branch(TString(branchprefix + "total_count"), &fTotalCount);
429 fTree->Branch(TString(branchprefix + "good_count"), &fGoodEventNumber);
430
431 fTree->Branch(TString(branchprefix + "n"), &(this->fGoodEventNumber));
432 fTree->Branch(TString(branchprefix + "ErrorFlag"), &(this->fErrorFlag));
433
434 auto bn = [&](const TString& n) {
435 return TString(branchprefix + n);
436 };
437 auto pm = [](TMatrixD& m) {
438 return m.GetMatrixArray();
439 };
440 auto lm = [](TMatrixD& m, const TString& n) {
441 return Form("%s[%d][%d]/D", n.Data(), m.GetNrows(), m.GetNcols());
442 };
443 auto branchm = [&](TTree* tree, TMatrixD& m, const TString& n) {
444 tree->Branch(bn(n),pm(m),lm(m,n));
445 };
446 auto pv = [](TVectorD& v) {
447 return v.GetMatrixArray();
448 };
449 auto lv = [](TVectorD& v, const TString& n) {
450 return Form("%s[%d]/D", n.Data(), v.GetNrows());
451 };
452 auto branchv = [&](TTree* tree, TVectorD& v, const TString& n) {
453 tree->Branch(bn(n),pv(v),lv(v,n));
454 };
455
456 branchm(fTree,this->Axy, "A");
457 branchm(fTree,this->dAxy, "dA");
458
459 branchm(fTree,this->mVPP, "VPP");
460 branchm(fTree,this->mVPY, "VPY");
461 branchm(fTree,this->mVYP, "VYP");
462 branchm(fTree,this->mVYY, "VYY");
463 branchm(fTree,this->mVYYp, "VYYp");
464
465 branchm(fTree,this->mSPP, "SPP");
466 branchm(fTree,this->mSPY, "SPY");
467 branchm(fTree,this->mSYP, "SYP");
468 branchm(fTree,this->mSYY, "SYY");
469 branchm(fTree,this->mSYYp, "SYYp");
470
471 branchm(fTree,this->mRPP, "RPP");
472 branchm(fTree,this->mRPY, "RPY");
473 branchm(fTree,this->mRYP, "RYP");
474 branchm(fTree,this->mRYY, "RYY");
475 branchm(fTree,this->mRYYp, "RYYp");
476
477 branchv(fTree,this->mMP, "MP"); // Parameter mean
478 branchv(fTree,this->mMY, "MY"); // Uncorrected mean
479 branchv(fTree,this->mMYp, "MYp"); // Corrected mean
480
481 branchv(fTree,this->mSP, "dMP"); // Parameter mean error
482 branchv(fTree,this->mSY, "dMY"); // Uncorrected mean error
483 branchv(fTree,this->mSYp, "dMYp"); // Corrected mean error
484
485}
486
487/// \brief Construct the histograms in a folder with a prefix
488void GrandCorrelator::ConstructHistograms(TDirectory *folder, TString &prefix)
489{
490 // Skip if disabled
491 if (fDisableHistos) return;
492
493 // Check if any channels are active
494 if (nP == 0 || nY == 0) {
495 return;
496 }
497
498 // Go to directory
499 TString name(fName);
500 name.ReplaceAll(" ","_");
501 folder->mkdir(name)->cd();
502
503 //..... 1D, iv
504 fH1iv.resize(nP);
505 for (int i = 0; i < nP; i++) {
506 fH1iv[i] = TH1D(
507 Form("P%d",i),
508 Form("iv P%d=%s, pass=%s ;iv=%s (ppm)",i,fIndependentName[i].c_str(),fName.Data(),fIndependentName[i].c_str()),
509 128,0.,0.);
510 fH1iv[i].GetXaxis()->SetNdivisions(4);
511 }
512
513 //..... 2D, iv correlations
514 Double_t x1 = 0;
515 fH2iv.resize(nP);
516 for (int i = 0; i < nP; i++) {
517 fH2iv[i].resize(nP);
518 for (int j = i+1; j < nP; j++) { // not all are used
519 fH2iv[i][j] = TH2D(
520 Form("P%d_P%d",i,j),
521 Form("iv correlation P%d_P%d, pass=%s ;P%d=%s (ppm);P%d=%s (ppm) ",
522 i,j,fName.Data(),i,fIndependentName[i].c_str(),j,fIndependentName[j].c_str()),
523 64,-x1,x1,
524 64,-x1,x1);
525 fH2iv[i][j].GetXaxis()->SetTitleColor(kBlue);
526 fH2iv[i][j].GetYaxis()->SetTitleColor(kBlue);
527 fH2iv[i][j].GetXaxis()->SetNdivisions(4);
528 fH2iv[i][j].GetYaxis()->SetNdivisions(4);
529 }
530 }
531
532 //..... 1D, dv
533 fH1dv.resize(nY);
534 for (int i = 0; i < nY; i++) {
535 fH1dv[i] = TH1D(
536 Form("Y%d",i),
537 Form("dv Y%d=%s, pass=%s ;dv=%s (ppm)",i,fDependentName[i].c_str(),fName.Data(),fDependentName[i].c_str()),
538 128,0.,0.);
539 fH1dv[i].GetXaxis()->SetNdivisions(4);
540 }
541
542 //..... 2D, dv-iv correlations
543 Double_t y1 = 0;
544 fH2dv.resize(nP);
545 for (int i = 0; i < nP; i++) {
546 fH2dv[i].resize(nY);
547 for (int j = 0; j < nY; j++) {
548 fH2dv[i][j] = TH2D(
549 Form("P%d_Y%d",i,j),
550 Form("iv-dv correlation P%d_Y%d, pass=%s ;P%d=%s (ppm);Y%d=%s (ppm) ",
551 i,j,fName.Data(),i,fIndependentName[i].c_str(),j,fDependentName[j].c_str()),
552 64,-x1,x1,
553 64,-y1,y1);
554 fH2dv[i][j].GetXaxis()->SetTitleColor(kBlue);
555 fH2dv[i][j].GetYaxis()->SetTitleColor(kBlue);
556 fH2dv[i][j].GetXaxis()->SetNdivisions(4);
557 fH2dv[i][j].GetYaxis()->SetNdivisions(4);
558 }
559 }
560
561 // store list of names to be archived
562 fHnames.resize(2);
563 fHnames[0] = TH1D("NamesIV",Form("IV name list nIV=%d",nP),nP,0,1);
564 for (int i = 0; i < nP; i++)
565 fHnames[0].Fill(fIndependentName[i].c_str(),1.*i);
566 fHnames[1] = TH1D("NamesDV",Form("DV name list nIV=%d",nY),nY,0,1);
567 for (int i = 0; i < nY; i++)
568 fHnames[1].Fill(fDependentName[i].c_str(),i*1.);
569}
570
571/// \brief Fill the histograms
573{
574 // Skip if disabled
575 if (fDisableHistos) return;
576
577 // Check if any channels are active
578 if (nP == 0 || nY == 0) {
579 return;
580 }
581
582 // Skip if bad event
583 if (fGoodEvent != 0) return;
584
585 // Fill histograms
586 for (size_t i = 0; i < fIndependentValues.size(); i++) {
587 fH1iv[i].Fill(fIndependentValues[i]);
588 for (size_t j = i+1; j < fIndependentValues.size(); j++)
590 }
591 for (size_t j = 0; j < fDependentValues.size(); j++) {
592 fH1dv[j].Fill(fDependentValues[j]);
593 for (size_t i = 0; i < fIndependentValues.size(); i++)
594 fH2dv[i][j].Fill(fIndependentValues[i], fDependentValues[j]);
595 }
596}
597
599{
600 // Ensure in output file
602
603 // Write objects
604 this->Axy.Write("slopes");
605 this->dAxy.Write("sigSlopes");
606
607 this->mRPP.Write("IV_IV_correlation");
608 this->mRPY.Write("IV_DV_correlation");
609 this->mRYY.Write("DV_DV_correlation");
610 this->mRYYp.Write("DV_DV_correlation_prime");
611
612 this->mMP.Write("IV_mean");
613 this->mMY.Write("DV_mean");
614 this->mMYp.Write("DV_mean_prime");
615
616 // number of events
617 TMatrixD Mstat(1,1);
618 Mstat(0,0)=this->getUsedEve();
619 Mstat.Write("MyStat");
620
621 //... IVs
622 TH1D hiv("IVname","names of IVs",nP,-0.5,nP-0.5);
623 for (int i=0;i<nP;i++) hiv.Fill(fIndependentFull[i].c_str(),i);
624 hiv.Write();
625
626 //... DVs
627 TH1D hdv("DVname","names of IVs",nY,-0.5,nY-0.5);
628 for (int i=0;i<nY;i++) hdv.Fill(fDependentFull[i].c_str(),i);
629 hdv.Write();
630
631 // sigmas
632 this->mSP.Write("IV_sigma");
633 this->mSY.Write("DV_sigma");
634 this->mSYp.Write("DV_sigma_prime");
635
636 // raw covariances
637 this->mVPP.Write("IV_IV_rawVariance");
638 this->mVPY.Write("IV_DV_rawVariance");
639 this->mVYY.Write("DV_DV_rawVariance");
640 this->mVYYp.Write("DV_DV_rawVariance_prime");
641 TVectorD mVY2(TMatrixDDiag(this->mVYY));
642 mVY2.Write("DV_rawVariance");
643 TVectorD mVP2(TMatrixDDiag(this->mVPP));
644 mVP2.Write("IV_rawVariance");
645 TVectorD mVY2prime(TMatrixDDiag(this->mVYYp));
646 mVY2prime.Write("DV_rawVariance_prime");
647
648 // normalized covariances
649 this->mSPP.Write("IV_IV_normVariance");
650 this->mSPY.Write("IV_DV_normVariance");
651 this->mSYY.Write("DV_DV_normVariance");
652 this->mSYYp.Write("DV_DV_normVariance_prime");
653 TVectorD sigY2(TMatrixDDiag(this->mSYY));
654 sigY2.Write("DV_normVariance");
655 TVectorD sigX2(TMatrixDDiag(this->mSPP));
656 sigX2.Write("IV_normVariance");
657 TVectorD sigY2prime(TMatrixDDiag(this->mSYYp));
658 sigY2prime.Write("DV_normVariance_prime");
659
660 this->Axy.Write("A_xy");
661 this->Ayx.Write("A_yx");
662}
663
664void GrandCorrelator::OpenAlphaFile(const std::string& prefix)
665{
666 // Create old-style blueR ROOT file
667 std::string name = prefix + fAlphaOutputFileBase + run_label.Data() + fAlphaOutputFileSuff;
668 std::string path = fAlphaOutputPath + "/";
669 std::string file = path + name;
670 fAlphaOutputFile = new TFile(TString(file), "RECREATE", "correlation coefficients");
671 if (! fAlphaOutputFile->IsWritable()) {
672 QwError << "GrandCorrelator could not create output file " << file << QwLog::endl;
673 delete fAlphaOutputFile;
675 }
676}
677
678void GrandCorrelator::OpenAliasFile(const std::string& prefix)
679{
680 // Turn "." into "_" in run_label (no "." allowed in function name, and must
681 // agree with the filename)
682 std::string label(run_label);
683 std::replace(label.begin(), label.end(), '.', '_');
684 // Create old-style regalias script
685 std::string name = prefix + fAliasOutputFileBase + label + fAliasOutputFileSuff;
686 std::string path = fAliasOutputPath + "/";
687 std::string file = path + name + ".C"; // add extension outside of file suffix
688 fAliasOutputFile.open(file, std::ofstream::out);
689 if (fAliasOutputFile.good()) {
690 fAliasOutputFile << Form("void %s(int i = 0) {", name.c_str()) << std::endl;
691 } else {
692 QwWarning << "GrandCorrelator: Could not write to alias output file " << QwLog::endl;
693 }
694}
695
697{
698 // Close slopes output file
699 if (fAlphaOutputFile) {
700 fAlphaOutputFile->Write();
701 fAlphaOutputFile->Close();
702 }
703}
704
706{
707 // Close alias output file
708 if (fAliasOutputFile.good()) {
709 fAliasOutputFile << "}" << std::endl << std::endl;
710 fAliasOutputFile.close();
711 } else {
712 QwWarning << "GrandCorrelator: Unable to close alias output file." << QwLog::endl;
713 }
714}
715
717{
718 // Ensure output file is open
719 if (fAliasOutputFile.bad()) {
720 QwWarning << "GrandCorrelator: Could not write to alias output file " << QwLog::endl;
721 return;
722 }
723
724 fAliasOutputFile << " if (i == " << fCycleCounter << ") {" << std::endl;
725 fAliasOutputFile << Form(" TTree* tree = (TTree*) gDirectory->Get(\"mul\");") << std::endl;
726 for (int i = 0; i < nY; i++) {
727 fAliasOutputFile << Form(" tree->SetAlias(\"reg_%s\",",fDependentFull[i].c_str()) << std::endl;
728 fAliasOutputFile << Form(" \"%s",fDependentFull[i].c_str());
729 for (int j = 0; j < nP; j++) {
730 fAliasOutputFile << Form("%+.4e*%s", -this->Axy(j,i), fIndependentFull[j].c_str());
731 }
732 fAliasOutputFile << "\");" << std::endl;
733 }
734 fAliasOutputFile << " }" << std::endl;
735
736 // Increment call counter
738}
739
740
741
742
748
749//=================================================
750//=================================================
752: VQwDataHandler(source),
753 fBlock(source.fBlock),
758 fAlphaOutputFile(nullptr),
759 fTree(nullptr),
763 nP(source.nP),nY(source.nY),
765 fErrorFlag(-1),
767{
769
770 QwWarning << "GrandCorrelator copy constructor required but untested" << QwLog::endl;
771
772 // Clear all data
774}
775
776//=================================================
777//=================================================
779{
780 mMP.ResizeTo(nP);
781 mMY.ResizeTo(nY);
782 mMYp.ResizeTo(nY);
783
784 mVPP.ResizeTo(nP,nP);
785 mVPY.ResizeTo(nP,nY);
786 mVYP.ResizeTo(nY,nP);
787 mVYY.ResizeTo(nY,nY);
788 mVYYp.ResizeTo(nY,nY);
789 mVP.ResizeTo(nP);
790 mVY.ResizeTo(nY);
791 mVYp.ResizeTo(nY);
792
793 mSPP.ResizeTo(mVPP);
794 mSPY.ResizeTo(mVPY);
795 mSYP.ResizeTo(mVYP);
796 mSYY.ResizeTo(mVYY);
797 mSYYp.ResizeTo(mVYYp);
798
799 Axy.ResizeTo(nP,nY);
800 Ayx.ResizeTo(nY,nP);
801 dAxy.ResizeTo(Axy);
802 dAyx.ResizeTo(Ayx);
803
804 mSP.ResizeTo(nP);
805 mSY.ResizeTo(nY);
806 mSYp.ResizeTo(nY);
807
808 mRPP.ResizeTo(mVPP);
809 mRPY.ResizeTo(mVPY);
810 mRYP.ResizeTo(mVYP);
811 mRYY.ResizeTo(mVYY);
812 mRYYp.ResizeTo(mVYYp);
813
814 mNij.ResizeTo(nP+nY,nP+nY);
815 mSij.ResizeTo(nP+nY,nP+nY);
816 mMij.ResizeTo(nP+nY,nP+nY);
817 mCij.ResizeTo(nP+nY,nP+nY);
818 mVij.ResizeTo(nP+nY,nP+nY);
819 mRij.ResizeTo(nP+nY,nP+nY);
820 sigma_ij.ResizeTo(nP+nY,nP+nY);
821 sigma_ji.ResizeTo(nP+nY,nP+nY);
822 mVFULL.ResizeTo(nP+nY,nP+nY);
823 mRFULL.ResizeTo(nP+nY,nP+nY);
824 mSFULL.ResizeTo(nP+nY,nP+nY);
825 mVFULL_clean.ResizeTo(nP+nY,nP+nY);
826 mSFULL_clean.ResizeTo(nP+nY,nP+nY);
827
829}
830
831//=================================================
832//=================================================
834{
835 mMP.Zero();
836 mMY.Zero();
837 mMYp.Zero();
838
839 mVPP.Zero();
840 mVPY.Zero();
841 mVYP.Zero();
842 mVYY.Zero();
843 mVYYp.Zero();
844 mVP.Zero();
845 mVY.Zero();
846 mVYp.Zero();
847
848 mSPP.Zero();
849 mSPY.Zero();
850 mSYP.Zero();
851 mSYY.Zero();
852 mSYYp.Zero();
853
854 Axy.Zero();
855 Ayx.Zero();
856 dAxy.Zero();
857 dAyx.Zero();
858
859 mSP.Zero();
860 mSY.Zero();
861 mSYp.Zero();
862
863 mRPP.Zero();
864 mRPY.Zero();
865 mRYP.Zero();
866 mRYY.Zero();
867 mRYYp.Zero();
868
869 mNij.Zero();
870 mSij.Zero();
871 mMij.Zero();
872 mCij.Zero();
873 mVij.Zero();
874 mRij.Zero();
875 sigma_ij.Zero();
876 sigma_ji.Zero();
877 mVFULL.Zero();
878 mRFULL.Zero();
879 mSFULL.Zero();
880 mVFULL_clean.Zero();
881 mSFULL_clean.Zero();
882
883 fErrorFlag = -1;
885}
886
887//=================================================
888//=================================================
890{
891 QwMessage << "LinReg dims: nP=" << nP << " nY=" << nY << QwLog::endl;
892
893 QwMessage << "MP:"; mMP.Print();
894 QwMessage << "MY:"; mMY.Print();
895 QwMessage << "VPP:"; mVPP.Print();
896 QwMessage << "VPY:"; mVPY.Print();
897 QwMessage << "VYY:"; mVYY.Print();
898 QwMessage << "VYYprime:"; mVYYp.Print();
899}
900
901//==========================================================
902//==========================================================
903GrandCorrelator& GrandCorrelator::operator+=(const std::pair<TVectorD,TVectorD>& rhs)
904{
905 // Get independent and dependent components
906 const TVectorD& P = rhs.first;
907 const TVectorD& Y = rhs.second;
908
909 // Update number of events
911
912 if (fGoodEventNumber <= 1) {
913 // First event, set covariances to zero and means to first value
914 mVPP.Zero();
915 mVPY.Zero();
916 mVYY.Zero();
917 mMP = P;
918 mMY = Y;
919 } else {
920 // Deviations from mean
921 TVectorD delta_y(Y - mMY);
922 TVectorD delta_p(P - mMP);
923
924 // Update covariances
925 Double_t alpha = (fGoodEventNumber - 1.0) / fGoodEventNumber;
926 mVPP.Rank1Update(delta_p, alpha);
927 mVPY.Rank1Update(delta_p, delta_y, alpha);
928 mVYY.Rank1Update(delta_y, alpha);
929
930 // Update means
931 Double_t beta = 1.0 / fGoodEventNumber;
932 mMP += delta_p * beta;
933 mMY += delta_y * beta;
934 }
935
936 return *this;
937}
938
939//==========================================================
940//==========================================================
942{
943 // If set X = A + B, then
944 // Cov[X] = Cov[A] + Cov[B]
945 // + (E[x_A] - E[x_B]) * (E[y_A] - E[y_B]) * n_A * n_B / n_X
946 // Ref: E. Schubert, M. Gertz (9 July 2018).
947 // "Numerically stable parallel computation of (co-)variance".
948 // SSDBM '18 Proceedings of the 30th International Conference
949 // on Scientific and Statistical Database Management.
950 // https://doi.org/10.1145/3221269.3223036
951
952
954 return *this;
955
956 // Deviations from mean
957 TVectorD delta_y(mMY - rhs.mMY);
958 TVectorD delta_p(mMP - rhs.mMP);
959
960 // Update covariances
961 Double_t alpha = fGoodEventNumber * rhs.fGoodEventNumber
963 mVYY += rhs.mVYY;
964 mVYY.Rank1Update(delta_y, alpha);
965 mVPY += rhs.mVPY;
966 mVPY.Rank1Update(delta_p, delta_y, alpha);
967 mVPP += rhs.mVPP;
968 mVPP.Rank1Update(delta_p, alpha);
969
970 // Update means
971 Double_t beta = rhs.fGoodEventNumber / (fGoodEventNumber + rhs.fGoodEventNumber);
972 mMY += delta_y * beta;
973 mMP += delta_p * beta;
974
976
977 return *this;
978}
979
980//==========================================================
981//==========================================================
982Int_t GrandCorrelator::getMeanP(const int i, Double_t &mean) const
983{
984 mean=-1e50;
985 if(i<0 || i >= nP ) return -1;
986 if( fGoodEventNumber<1) return -3;
987 mean = mMP(i); return 0;
988}
989
990
991//==========================================================
992//==========================================================
993Int_t GrandCorrelator::getMeanY(const int i, Double_t &mean) const
994{
995 mean=-1e50;
996 if(i<0 || i >= nY ) return -1;
997 if( fGoodEventNumber<1) return -3;
998 mean = mMY(i); return 0;
999}
1000
1001
1002//==========================================================
1003//==========================================================
1004Int_t GrandCorrelator::getMeanYprime(const int i, Double_t &mean) const
1005{
1006 mean=-1e50;
1007 if(i<0 || i >= nY ) return -1;
1008 if( fGoodEventNumber<1) return -3;
1009 mean = mMYp(i); return 0;
1010}
1011
1012
1013//==========================================================
1014//==========================================================
1015Int_t GrandCorrelator::getSigmaP(const int i, Double_t &sigma) const
1016{
1017 sigma=-1e50;
1018 if(i<0 || i >= nP ) return -1;
1019 if( fGoodEventNumber<2) return -3;
1020 sigma=sqrt(mVPP(i,i)/(fGoodEventNumber-1.));
1021 return 0;
1022}
1023
1024
1025//==========================================================
1026//==========================================================
1027Int_t GrandCorrelator::getSigmaY(const int i, Double_t &sigma) const
1028{
1029 sigma=-1e50;
1030 if(i<0 || i >= nY ) return -1;
1031 if( fGoodEventNumber<2) return -3;
1032 sigma=sqrt(mVYY(i,i)/(fGoodEventNumber-1.));
1033 return 0;
1034}
1035
1036//==========================================================
1037//==========================================================
1038Int_t GrandCorrelator::getSigmaYprime(const int i, Double_t &sigma) const
1039{
1040 sigma=-1e50;
1041 if(i<0 || i >= nY ) return -1;
1042 if( fGoodEventNumber<2) return -3;
1043 sigma=sqrt(mVYYp(i,i)/(fGoodEventNumber-1.));
1044 return 0;
1045}
1046
1047//==========================================================
1048//==========================================================
1049Int_t GrandCorrelator::getCovarianceP( int i, int j, Double_t &covar) const
1050{
1051 covar=-1e50;
1052 if( i>j) { int k=i; i=j; j=k; }//swap i & j
1053 //... now we need only upper right triangle
1054 if(i<0 || i >= nP ) return -11;
1055 if( fGoodEventNumber<2) return -14;
1056 covar=mVPP(i,j)/(fGoodEventNumber-1.);
1057 return 0;
1058}
1059
1060//==========================================================
1061//==========================================================
1062Int_t GrandCorrelator::getCovariancePY( int ip, int iy, Double_t &covar) const
1063{
1064 covar=-1e50;
1065 //... now we need only upper right triangle
1066 if(ip<0 || ip >= nP ) return -11;
1067 if(iy<0 || iy >= nY ) return -12;
1068 if( fGoodEventNumber<2) return -14;
1069 covar=mVPY(ip,iy)/(fGoodEventNumber-1.);
1070 return 0;
1071}
1072
1073//==========================================================
1074//==========================================================
1075Int_t GrandCorrelator::getCovarianceY( int i, int j, Double_t &covar) const
1076{
1077 covar=-1e50;
1078 if( i>j) { int k=i; i=j; j=k; }//swap i & j
1079 //... now we need only upper right triangle
1080 if(i<0 || i >= nY ) return -11;
1081 if( fGoodEventNumber<2) return -14;
1082 covar=mVYY(i,j)/(fGoodEventNumber-1.);
1083 return 0;
1084}
1085
1086//==========================================================
1087//==========================================================
1089{
1090 QwMessage << Form("\nLinRegBevPeb::printSummaryP seen good eve=%lld",fGoodEventNumber)<<QwLog::endl;
1091
1092 size_t dim=nP;
1093 if(fGoodEventNumber>2) { // print full matrix
1094 QwMessage << Form("\nname: ");
1095 for (size_t i = 1; i <dim; i++) {
1096 QwMessage << Form("P%d%11s",(int)i," ");
1097 }
1098 QwMessage << Form("\n mean sig(distrib) nSig(mean) correlation-matrix ....\n");
1099 for (size_t i = 0; i <dim; i++) {
1100 double meanI,sigI;
1101 if (getMeanP(i,meanI) < 0) QwWarning << "LRB::getMeanP failed" << QwLog::endl;
1102 if (getSigmaP(i,sigI) < 0) QwWarning << "LRB::getSigmaP failed" << QwLog::endl;
1103 double nSig=-1;
1104 double err=sigI/sqrt(fGoodEventNumber);
1105 if(sigI>0.) nSig=meanI/err;
1106
1107 QwMessage << Form("P%d: %+12.4g %12.3g %.1f ",(int)i,meanI,sigI,nSig);
1108 for (size_t j = 1; j <dim; j++) {
1109 if( j<=i) { QwMessage << Form(" %12s","._._._."); continue;}
1110 double sigJ,cov;
1111 if (getSigmaP(j,sigJ) < 0) QwWarning << "LRB::getSigmaP failed" << QwLog::endl;
1112 if (getCovarianceP(i,j,cov) < 0) QwWarning << "LRB::getCovarianceP failed" << QwLog::endl;
1113 double corel=cov / sigI / sigJ;
1114
1115 QwMessage << Form(" %12.3g",corel);
1116 }
1117 QwMessage << Form("\n");
1118 }
1119 }
1120}
1121
1122//==========================================================
1123//==========================================================
1125{
1126 QwMessage << Form("\nLinRegBevPeb::printSummaryY seen good eve=%lld (CSV-format)",fGoodEventNumber)<<QwLog::endl;
1127 QwMessage << Form(" j, mean, sig(mean), nSig(mean), sig(distribution) \n");
1128
1129 for (int i = 0; i <nY; i++) {
1130 double meanI,sigI;
1131 if (getMeanY(i,meanI) < 0) QwWarning << "LRB::getMeanY failed" << QwLog::endl;
1132 if (getSigmaY(i,sigI) < 0) QwWarning << "LRB::getSigmaY failed" << QwLog::endl;
1133 double err = sigI / sqrt(fGoodEventNumber);
1134 double nSigErr = meanI / err;
1135 QwMessage << Form("Y%02d, %+11.4g, %12.4g, %8.1f, %12.4g "" ",i,meanI,err,nSigErr,sigI)<<QwLog::endl;
1136
1137 }
1138}
1139
1140
1141
1142//==========================================================
1143//==========================================================
1145{
1146 QwMessage << Form("\nLinRegBevPeb::printSummaryAlphas seen good eve=%lld",fGoodEventNumber)<<QwLog::endl;
1147 QwMessage << Form("\n j slope sigma mean/sigma\n");
1148 for (int iy = 0; iy <nY; iy++) {
1149 QwMessage << Form("dv=Y%d: ",iy)<<QwLog::endl;
1150 for (int j = 0; j < nP; j++) {
1151 double val=Axy(j,iy);
1152 double err=dAxy(j,iy);
1153 double nSig=val/err;
1154 char x=' ';
1155 if(fabs(nSig)>3.) x='*';
1156 QwMessage << Form(" slope_%d = %11.3g +/-%11.3g (nSig=%.2f) %c\n",j,val, err,nSig,x);
1157 }
1158 }
1159}
1160
1161
1162//==========================================================
1163//==========================================================
1165{
1166 QwMessage << Form("\nLinRegBevPeb::printSummaryYP seen good eve=%lld",fGoodEventNumber)<<QwLog::endl;
1167
1168 if(fGoodEventNumber<2) { QwMessage<<" too few events, skip"<<QwLog::endl; return;}
1169 QwMessage << Form("\n name: ");
1170 for (int i = 0; i <nP; i++) {
1171 QwMessage << Form(" %10sP%d "," ",i);
1172 }
1173 QwMessage << Form("\n j meanY sigY correlation with Ps ....\n");
1174 for (int iy = 0; iy <nY; iy++) {
1175 double meanI,sigI;
1176 if (getMeanY(iy,meanI) < 0) QwWarning << "LRB::getMeanY failed" << QwLog::endl;
1177 if (getSigmaY(iy,sigI) < 0) QwWarning << "LRB::getSigmaY failed" << QwLog::endl;
1178
1179 QwMessage << Form(" %3d %6sY%d: %+12.4g %12.4g ",iy," ",iy,meanI,sigI);
1180 for (int ip = 0; ip <nP; ip++) {
1181 double sigJ,cov;
1182 if (getSigmaP(ip,sigJ) < 0) QwWarning << "LRB::getSigmaP failed" << QwLog::endl;
1183 if (getCovariancePY(ip,iy,cov) < 0) QwWarning << "LRB::getCovariancePY failed" << QwLog::endl;
1184 double corel = cov / sigI / sigJ;
1185 QwMessage << Form(" %12.3g",corel);
1186 }
1187 QwMessage << Form("\n");
1188 }
1189}
1190
1191
1192//==========================================================
1193//==========================================================
1195{
1196 QwMessage << "Uncorrected Y values:" << QwLog::endl;
1197 QwMessage << " mean sig" << QwLog::endl;
1198 for (int i = 0; i < nY; i++){
1199 QwMessage << "Y" << i << ": " << mMY(i) << " +- " << mSY(i) << QwLog::endl;
1200 }
1202}
1203
1204
1205//==========================================================
1206//==========================================================
1208{
1209 QwMessage << "Corrected Y values:" << QwLog::endl;
1210 QwMessage << " mean sig" << QwLog::endl;
1211 for (int i = 0; i < nY; i++){
1212 QwMessage << "Y" << i << ": " << mMYp(i) << " +- " << mSYp(i) << QwLog::endl;
1213 }
1215}
1216
1217//==========================================================
1218//==========================================================
1220{
1221//==========================================================
1222//Solve step 1
1223for(size_t i = 0; i < fAllVar.size(); ++i){
1224 for(size_t j = i; j < fAllVar.size(); ++j){
1225 if(mNij(i,j) >= 2){
1226 mVij(i,j) = mCij(i,j) / (mNij(i,j) - 1.);
1227 sigma_ij(i,j) = sqrt((mSij(i,j)) / (mNij(i,j) - 1.));
1228 sigma_ji(j,i) = sqrt((mSij(j,i)) / (mNij(j,i) - 1.));
1229
1230 if(sigma_ij(i,j) > 0.0 && sigma_ji(j,i) > 0.0){
1231 mRij(i,j) = mVij(i,j) / (sigma_ij(i,j) * sigma_ji(j,i));
1232 } else {
1233 mRij(i,j) = 0.0;
1234 }
1235
1236 if(j > i){
1237 mVij(j,i) = mVij(i,j);
1238 sigma_ij(j,i) = sqrt((mSij(j,i)) / (mNij(j,i) - 1.));
1239 sigma_ji(i,j) = sqrt((mSij(i,j)) / (mNij(i,j) - 1.));
1240
1241 if(sigma_ij(j,i) > 0.0 && sigma_ji(i,j) > 0.0){
1242 mRij(j,i) = mVij(j,i) / (sigma_ij(j,i) * sigma_ji(i,j));
1243 } else {
1244 mRij(i,j) = 0.0;
1245 }
1246 }
1247 }
1248 else {
1249 mVij(i,j) = 0;
1250 sigma_ij(i,j) = 0;
1251 sigma_ji(j,i) = 0;
1252 mRij(i,j) = 0;
1253 }
1254
1255 //Bottom half matrix
1256
1257 mVij(j,i) = mVij(i,j);
1258
1259 // Correlation
1260 if (sigma_ij(i,j) > 0.0 && sigma_ji(j,i) > 0.0) {
1261 mRij(i,j) = mVij(i,j) / (sigma_ij(i,j) * sigma_ji(j,i));
1262 mRij(j,i) = mRij(i,j); // mirror
1263 } else {
1264 mRij(i,j) = 0.0;
1265 mRij(j,i) = 0.0;
1266 }
1267 }
1268}
1269
1270
1271//==========================================================
1272//Solve step 2
1273 mVFULL = mCij;
1274 mVPY = mVFULL.GetSub(0,nP-1,nP,nP+nY-1);
1275 mVPP = mVFULL.GetSub(0,nP-1,0,nP-1);
1276 mVYY = mVFULL.GetSub(nP,nP+nY-1,nP,nP+nY-1);
1277
1278 mRFULL = mRij;
1279 mRPY = mRFULL.GetSub(0,nP-1,nP,nP+nY-1);
1280 mRPP = mRFULL.GetSub(0,nP-1,0,nP-1);
1281 mRYY = mRFULL.GetSub(nP,nP+nY-1,nP,nP+nY-1);
1282
1283 mSFULL = mVij;
1284 mSPY = mSFULL.GetSub(0,nP-1,nP,nP+nY-1);
1285 mSPP = mSFULL.GetSub(0,nP-1,0,nP-1);
1286 mSYY = mSFULL.GetSub(nP,nP+nY-1,nP,nP+nY-1);
1287
1288
1289 // off-diagonal raw covariance
1290 mVYP.Transpose(mVPY);
1291
1292 // diagonal variances
1293 TMatrixD sigmaP = sigma_ij.GetSub(0,nP-1,0,nP-1);
1294 TMatrixD sigmaY = sigma_ij.GetSub(nP,nP+nY-1,nP,nP+nY-1);
1295
1296 mVP = TMatrixDDiag(sigmaP);
1297 mVY = TMatrixDDiag(sigmaY);
1298
1299 // "Clean" matrices
1300 for(size_t i = 0; i < fAllVar.size(); ++i){
1301 for(size_t j = i; j < fAllVar.size(); ++j){
1302 if(i < 5 && j < 5){
1303 }
1304 mVFULL_clean(i,j) = mRij(i,j) * sigma_ij(i,j) * sigma_ji(j,i) * (fGoodEventNumber - 1);
1305 mVFULL_clean(j,i) = mVFULL_clean(i,j);
1306 mSFULL_clean(i,j) = mRij(i,j) * sigma_ij(i,j) * sigma_ji(j,i);
1307 mSFULL_clean(j,i) = mSFULL_clean(i,j);
1308 }
1309}
1310 TMatrixD mVPY_clean = mVFULL_clean.GetSub(0,nP-1,nP,nP+nY-1);
1311 TMatrixD mVPP_clean = mVFULL_clean.GetSub(0,nP-1,0,nP-1);
1312 TMatrixD mVYY_clean = mVFULL_clean.GetSub(nP,nP+nY-1,nP,nP+nY-1);
1313 TMatrixD mVYP_clean(TMatrixD::kTransposed, mVPY_clean);
1314
1315
1316 TMatrixD mSPY_clean = mSFULL_clean.GetSub(0,nP-1,nP,nP+nY-1);
1317 TMatrixD mSPP_clean = mSFULL_clean.GetSub(0,nP-1,0,nP-1);
1318 TMatrixD mSYY_clean = mSFULL_clean.GetSub(nP,nP+nY-1,nP,nP+nY-1);
1319
1320
1321 TMatrixD mSYP_clean(TMatrixD::kTransposed, mSPY_clean);
1322
1323 TVectorD mSP_clean = TMatrixDDiag(mSPP_clean);
1324 mSP_clean.Sqrt();
1325
1326 TVectorD mSY_clean = TMatrixDDiag(mSYY_clean);
1327 mSY_clean.Sqrt();
1328
1329 // Check for goodness and then get rid of bad columns
1330
1331 // Warn if correlation matrix determinant close to zero (heuristic)
1332 if (mRPP.Determinant() < std::pow(10,-(2*nP))) {
1333 QwWarning << "LRB: correlation matrix nearly singular, "
1334 << "determinant = " << mRPP.Determinant()
1335 << " (set includes highly correlated variable pairs)"
1336 << QwLog::endl;
1337 if (fGoodEventNumber > 10*nP) {
1338 QwMessage << fGoodEventNumber << " events" << QwLog::endl;
1339 QwMessage << "Covariance matrix: " << QwLog::endl; mVPP_clean.Print();
1340 QwMessage << "Correlation matrix: " << QwLog::endl; mRPP.Print();
1341 }
1342 QwWarning << "LRB: solving failed (this happens when only few events)."
1343 << QwLog::endl;
1344 return;
1345 }
1346
1347 //==========================================================
1348 //Solve Step 3
1349 // slopes
1350 TMatrixD invRPP(TMatrixD::kInverted, mRPP);
1351 Axy = TMatrixD(invRPP, TMatrixD::kMult, mRPY);
1352
1353 Axy.NormByColumn(mSP_clean); // divide
1354
1355 Axy.NormByRow(mSY_clean, ""); // mult
1356
1357 Ayx.Transpose(Axy);
1358
1359 // new means
1360 mMYp = mMY - Ayx * mMP;
1361
1362 // new raw covariance
1363 mVYYp = mVYY_clean + Ayx * mVPP_clean * Axy - (Ayx * mVPY_clean + mVYP_clean * Axy);
1364
1365 // new variances
1366 mVYp = TMatrixDDiag(mVYYp);
1367 for (int i = 0; i < mVYp.GetNrows(); i++) {
1368 if (mVYp(i) < 0 && fabs(mVYp(i)) < 1e-12) {
1369 mVYp(i) = 0;
1370 }
1371 }
1372
1373 mVYp.Sqrt();
1374
1375 // new normalized covariance
1376 mSYYp = mSYY_clean + Ayx * mSPP_clean * Axy - (Ayx * mSPY_clean + mSYP_clean * Axy);
1377 // uncertainties on the new means
1378 mSYp = TMatrixDDiag(mSYYp);
1379 mSYp.Sqrt();
1380
1381 // new correlation matrix
1382 mRYYp = mVYYp;
1383 mRYYp.NormByColumn(mVYp);
1384
1385 mRYYp.NormByRow(mVYp);
1386
1387
1388 // slope uncertainties
1389 double norm = 1. / (fGoodEventNumber - nP - 1);
1390 dAxy.Zero();
1391 dAxy.Rank1Update(TMatrixDDiag(invRPP), TMatrixDDiag(mRYYp), norm); // diag mRYYp = row of ones
1392 dAxy.Sqrt();
1393
1394 dAxy.NormByColumn(mSP_clean); // divide
1395
1396 dAxy.NormByRow(mSYp, ""); // mult
1397
1398 dAyx.Transpose(dAxy);
1399
1400
1401 fErrorFlag = 0;
1402}
An options class which parses command line, config file and environment.
Decoding and management for VQWK ADC channels (6x32-bit datawords)
ROOT file and tree management wrapper classes.
Definition of the pure virtual base class of all data elements.
Parameter file parsing and management.
A logfile class, based on an identical class in the Hermes analyzer.
#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
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:859
void NewTree(const std::string &name, const std::string &desc)
Create a new tree with name and description.
Definition QwRootFile.h:953
TTree * GetTree(const std::string &name)
Get the tree with name.
Definition QwRootFile.h:987
Abstract base for concrete hardware channels implementing dual-operator pattern.
std::ofstream fAliasOutputFile
std::string fAliasOutputFileSuff
TVectorD mMP
mean values
TMatrixD Axy
slopes
void printSummaryAlphas() const
void printSummaryMeansWithUncCorrected() const
Int_t getSigmaP(const int i, Double_t &sigma) const
Get mean value of a variable, returns error code.
Int_t fErrorFlag
is information valid
TMatrixD mVPY
unnormalized covariances
TVectorD mVP
variances
std::vector< const VQwHardwareChannel * > fAllVar
TMatrixD mSPY
normalized covariances
GrandCorrelator & operator+=(const std::pair< TVectorD, TVectorD > &rhs)
std::string fAliasOutputFileBase
Int_t getMeanY(const int i, Double_t &mean) const
void ClearEventData() override
std::vector< double > fAllValues
void printSummaryMeansWithUnc() const
TVectorD mSP
sigmas
Int_t getMeanYprime(const int i, Double_t &mean) const
std::string fAlphaOutputFileSuff
void ProcessOptions(QwOptions &options)
void printSummaryY() const
void printSummaryP() const
void OpenAlphaFile(const std::string &prefix)
std::vector< int > fErrCounts_DV
void FillHistograms() override
Fill the histograms.
GrandCorrelator(const TString &name)
Constructor with name.
static void DefineOptions(QwOptions &options)
std::vector< TH1D > fH1iv
std::string fAlphaOutputPath
void ProcessData() override
std::vector< TH1D > fHnames
void OpenAliasFile(const std::string &prefix)
void printSummaryYP() const
Int_t getSigmaYprime(const int i, Double_t &sigma) const
Long64_t fGoodEventNumber
accumulated so far
std::vector< std::string > fIndependentFull
void ConstructHistograms(TDirectory *folder, TString &prefix) override
Construct the histograms in a folder with a prefix.
Int_t getCovarianceY(int i, int j, Double_t &covar) const
Int_t ConnectChannels(QwSubsystemArrayParity &asym, QwSubsystemArrayParity &diff) override
Connect to Channels (asymmetry/difference only)
std::vector< std::vector< TH2D > > fH2dv
std::string fAliasOutputPath
unsigned int fGoodEvent
TMatrixD mNij
new matrices and vectors
std::vector< EQwHandleType > fIndependentType
Int_t getCovariancePY(int ip, int iy, Double_t &covar) const
void ConstructTreeBranches(QwRootFile *treerootfile, const std::string &treeprefix="", const std::string &branchprefix="") override
Construct the tree branches.
std::vector< std::vector< TH2D > > fH2iv
std::vector< std::string > fIndependentName
~GrandCorrelator() override
Int_t getMeanP(const int i, Double_t &mean) const
Get mean value of a variable, returns error code.
std::vector< Double_t > fIndependentValues
std::vector< int > fErrCounts_IV
std::vector< const VQwHardwareChannel * > fIndependentVar
void ParseConfigFile(QwParameterFile &file) override
double getUsedEve() const
void setDims(int a, int b)
Int_t getSigmaY(const int i, Double_t &sigma) const
std::vector< bool > fAllGood
std::string fAlphaOutputFileBase
static bool fPrintCorrelations
Int_t getCovarianceP(int i, int j, Double_t &covar) const
Get mean value of a variable, returns error code.
std::vector< TH1D > fH1dv
TMatrixD mRPY
correlations
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