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}
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
Decoding and management for VQWK ADC channels (6x32-bit datawords)
ROOT file and tree management wrapper classes.
An options class which parses command line, config file and environment.
Definition of the pure virtual base class of all data elements.
Parameter file parsing and management.
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:849
void NewTree(const std::string &name, const std::string &desc)
Create a new tree with name and description.
Definition QwRootFile.h:934
TTree * GetTree(const std::string &name)
Get the tree with name.
Definition QwRootFile.h:968
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