Belle II Software  release-08-03-00
eclAutocovarianceCalibrationC3Algorithm.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 /* Own header. */
10 #include <ecl/calibration/eclAutocovarianceCalibrationC3Algorithm.h>
11 
12 /* ECL headers. */
13 #include <ecl/dataobjects/ECLElementNumbers.h>
14 #include <ecl/dbobjects/ECLAutoCovariance.h>
15 
16 /* ROOT headers. */
17 #include <TFile.h>
18 #include <TGraph.h>
19 #include <TH2I.h>
20 #include"TMatrixDSym.h"
21 #include"TDecompChol.h"
22 
23 using namespace Belle2;
24 using namespace ECL;
25 
28  CalibrationAlgorithm("eclAutocovarianceCalibrationC3Collector")
29 {
31  "Computes the covariance matrix for each crystal"
32  );
33 }
34 
36 {
37 
38 
40  gROOT->SetBatch();
41 
43  std::vector<double> cryIDs;
44  std::vector<double> noiseMatrix00Vector;
45  std::vector<double> autoCov00Vector;
46  std::vector<double> totalCountsVector;
47  std::vector<double> invertAttempts;
48 
51  auto CovarianceMatrixInfoVsCrysID = getObjectPtr<TH2F>("CovarianceMatrixInfoVsCrysID");
52 
53  ECLAutoCovariance* Autocovariances = new ECLAutoCovariance();
54 
55  for (int ID = 0; ID < ECLElementNumbers::c_NCrystals; ID++) {
56 
57  m_u2 = 1.0; //Reseting
58 
59  double totalCounts = CovarianceMatrixInfoVsCrysID->GetBinContent(CovarianceMatrixInfoVsCrysID->GetBin(ID + 1,
60  m_numberofADCPoints + 1));
61 
62  if (totalCounts < m_TotalCountsThreshold) {
63  B2INFO("eclAutocovarianceCalibrationC3Algorithm: warning total entries for cell ID " << ID + 1 << " is only: " << totalCounts <<
64  " Requirement is m_TotalCountsThreshold: " << m_TotalCountsThreshold);
66  return c_NotEnoughData;
67  }
68 
69  TMatrixDSym NoiseMatrix;
70  NoiseMatrix.ResizeTo(m_numberofADCPoints, m_numberofADCPoints);
71  for (int i = 0; i < m_numberofADCPoints; i++) {
72  for (int j = 0; j < m_numberofADCPoints; j++) {
73  int index = abs(i - j);
74  NoiseMatrix(i, j) = double(CovarianceMatrixInfoVsCrysID->GetBinContent(CovarianceMatrixInfoVsCrysID->GetBin(ID + 1,
75  index + 1))) / (totalCounts - 1) / (double(m_numberofADCPoints - index));
76  }
77  }
78 
79  TMatrixDSym NoiseMatrixReduced(m_numberofADCPoints);
80  for (int i = 0; i < m_numberofADCPoints; i++) {
81  for (int j = 0; j < m_numberofADCPoints; j++) {
82  NoiseMatrixReduced(i, j) = (NoiseMatrix(0, abs(i - j)));
83  }
84  }
85 
86  bool invert_successful = 0;
87  int invert_attempt = 0;
88  double tempAutoCov[m_numberofADCPoints];
89  for (int i = 0; i < m_numberofADCPoints; i++) tempAutoCov[i] = NoiseMatrixReduced(0, i);
90  std::vector<double> buf(m_numberofADCPoints);
91  while (invert_successful == 0) {
92 
93  Autocovariances->setAutoCovariance(ID + 1, tempAutoCov);
94  Autocovariances->getAutoCovariance(ID + 1, buf.data());
95 
96  TMatrixDSym NoiseMatrix_check(m_numberofADCPoints);
97  for (int i = 0; i < m_numberofADCPoints; i++) {
98  for (int j = 0; j < m_numberofADCPoints; j++) {
99  NoiseMatrix_check(i, j) = buf[abs(i - j)];
100  }
101  }
102 
103  TDecompChol dc(NoiseMatrix_check);
104  invert_successful = dc.Invert(NoiseMatrix_check);
105  if (invert_successful == 0) {
106 
107  if (invert_attempt > 4) {
108  B2INFO("eclAutocovarianceCalibrationC3Algorithm iD " << ID << " invert_attempt limit reached " << invert_attempt);
109  B2INFO("eclAutocovarianceCalibrationC3Algorithm setting m_u2 to zero");
110  m_u2 = 0.0;
111  }
112  if (invert_attempt > 100) {
113  B2INFO("eclAutocovarianceCalibrationC3Algorithm unable to invert!");
114  return c_NotEnoughData;
115  }
116 
117  B2INFO("eclAutocovarianceCalibrationC3Algorithm iD " << ID << " invert_attempt " << invert_attempt);
118 
119  for (int i = 0; i < m_numberofADCPoints; i++) B2INFO("old[" << i << "] = " << tempAutoCov[i]);
120  for (int i = 1; i < m_numberofADCPoints; i++) tempAutoCov[i] *= (m_u2 / (1. + exp((i - m_u0) / m_u1)));
121  for (int i = 0; i < m_numberofADCPoints; i++) B2INFO("new[" << i << "] = " << tempAutoCov[i]);
122 
123  } else {
124  noiseMatrix00Vector.push_back(NoiseMatrix_check(0, 0));
125  }
126  invert_attempt++;
127  }
128 
129  cryIDs.push_back(ID + 1);
130  autoCov00Vector.push_back(tempAutoCov[0]);
131  totalCountsVector.push_back(totalCounts);
132  invertAttempts.push_back(invert_attempt);
133 
134  }
135 
137  saveCalibration(Autocovariances, "ECLAutoCovariance");
138 
140  auto gautoCov00Vector = new TGraph(cryIDs.size(), cryIDs.data(), autoCov00Vector.data());
141  gautoCov00Vector->SetName("gautoCov00Vector");
142  gautoCov00Vector->SetMarkerStyle(20);
143  auto gnoiseMatrix00Vector = new TGraph(cryIDs.size(), cryIDs.data(), noiseMatrix00Vector.data());
144  gnoiseMatrix00Vector->SetName("gnoiseMatrix00Vector");
145  gnoiseMatrix00Vector->SetMarkerStyle(20);
146  auto gtotalCountsVector = new TGraph(cryIDs.size(), cryIDs.data(), totalCountsVector.data());
147  gtotalCountsVector->SetName("gtotalCountsVector");
148  gtotalCountsVector->SetMarkerStyle(20);
149  auto ginvertAttempts = new TGraph(cryIDs.size(), cryIDs.data(), invertAttempts.data());
150  ginvertAttempts->SetName("ginvertAttempts");
151  ginvertAttempts->SetMarkerStyle(20);
152 
154  TString fName = m_outputName;
155  TDirectory::TContext context;
156  TFile* histfile = new TFile(fName, "recreate");
157  histfile->cd();
158  gautoCov00Vector->Write();
159  gnoiseMatrix00Vector->Write();
160  gtotalCountsVector->Write();
161  ginvertAttempts->Write();
162  histfile->Close();
163  delete histfile;
164 
165  return c_OK;
166 }
167 
Base class for calibration algorithms.
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
void setDescription(const std::string &description)
Set algorithm description (in constructor)
EResult
The result of calibration.
@ c_OK
Finished successfuly =0 in Python.
@ c_NotEnoughData
Needs more data =2 in Python.
Covariance matrices for offline ECL waveform fit.
void getAutoCovariance(const int cellID, double acov[31]) const
Get auto covariance for a channel.
void setAutoCovariance(const int cellID, const double acov[31])
Set auto covariance for a channel.
int m_TotalCountsThreshold
min number of counts needed to compute calibration
virtual EResult calibrate() override
..Run algorithm on events
const int c_NCrystals
Number of crystals.
Abstract base class for different kinds of events.