Belle II Software  release-08-01-10
CDCDedxCosineEdge.h
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 #pragma once
10 #include <TObject.h>
11 #include <vector>
12 #include <cmath>
13 #include <framework/logging/Logger.h>
14 #include <iostream>
15 
16 namespace Belle2 {
27  class CDCDedxCosineEdge: public TObject {
28  public:
29 
34 
38  explicit CDCDedxCosineEdge(const std::vector<std::vector<double>>& largecosth): m_largeCos(largecosth) {};
39 
44 
49  int getSize(const int side) const
50  {
51  if (side < 0) {
52  return m_largeCos[0].size();
53  } else if (side > 0) {
54  return m_largeCos[1].size();
55  } else {
56  B2ERROR("CDCDedxCosineEdge:choose >0 for forward and <0 for backward side");
57  return 0;
58  }
59  };
60 
61 
66  double getMean(int side, unsigned int ibin) const
67  {
68 
69  std::vector<double> temp;
70  if (side < 0) {
71  temp = m_largeCos[0];
72  } else if (side > 0) {
73  temp = m_largeCos[1];
74  } else {
75  B2ERROR("CDCDedxCosineEdge:choose > 0 for forward and <0 for backward side");
76  return 1.0;
77  }
78 
79  if (ibin >= temp.size()) { //index starts from zero
80  B2WARNING("CDCDedxADCNonLinearity:returning (1.0) uncorrected ADC as bin: " << ibin << " is not in range");
81  return 1.0;
82  }
83  return temp[ibin];
84  };
85 
89  double getMean(double costh)const
90  {
91 
92  double coslow = 0.0, coshigh = 0.0;
93  std::vector<double> temp;
94 
95  if (costh < 0) {
96  temp = m_largeCos[0];
97  coslow = -0.870; coshigh = -0.850; //this is hardcoded and fixed
98  } else if (costh > 0) {
99  temp = m_largeCos[1];
100  coslow = 0.950; coshigh = 0.960; //this is hardcoded and fixed
101  } else {
102  B2ERROR("CDCDedxCosineEdge:choose > 0 for forward and <0 for backward side");
103  return 1.0;
104  }
105 
106  //don't do anything for other cosine range
107  if (costh < coslow || costh > coshigh) {
108  B2WARNING("CDCDedxCosineEdge:outside range (" << costh << ")choose in between " << coslow << " and " << coshigh);
109  return 1.0;
110  }
111 
112  if (costh <= -0.866 || costh >= 0.9575) return 1.0;
113 
114  // gains are stored at the center of the bins
115  // find the bin center immediately preceding this value of costh
116  double binsize = (coshigh - coslow) / temp.size();
117  int bin = std::floor((costh - 0.5 * binsize - coslow) / binsize);
118 
119  // extrapolate backward for lowest half-bin and center positive half-bin
120  // extrapolate forward for highest half-bin and center negative half-bin
121  int thisbin = bin, nextbin = bin + 1;
122  int nbin = int(temp.size());
123  if (bin < 0 || (temp[nextbin] - temp[thisbin] < -0.6 && bin < nbin - 1)) {
124  thisbin = bin + 1; nextbin = bin + 2;
125  } else {
126  if (bin >= nbin - 1 || (temp[nextbin] - temp[thisbin] > 0.6 && bin < nbin - 1)) {
127  thisbin = bin - 1; nextbin = bin;
128  }
129  }
130 
131  double frac = ((costh - 0.5 * binsize - coslow) / binsize) - thisbin;
132 
133  if (thisbin < 0 || (unsigned)nextbin >= temp.size()) {
134  B2WARNING("CDCDedxCosineEdge:no constants for costh: " << costh << " as it is not in range");
135  return 1.0;
136  }
137 
138  return ((temp[nextbin] - temp[thisbin]) * frac + temp[thisbin]);
139  }
140 
145  double getCosEdgePar(int side, unsigned int ibin) const
146  {
147 
148  std::vector<double> temp;
149  double coslow = 0.0, coshigh = 0.0;
150  if (side < 0) {
151  temp = m_largeCos[0];
152  coslow = -0.870; coshigh = -0.850;
153  } else if (side > 0) {
154  temp = m_largeCos[1];
155  coslow = 0.950; coshigh = 0.960;
156  } else {
157  B2ERROR("CDCDedxCosineEdge:choose > 0 for forward and <0 for backward side");
158  return -99.0;
159  }
160 
161  if (ibin >= temp.size()) {
162  B2ERROR("CDCDedxCosineEdge:Problem with bin index: choose 0 and " << temp.size() - 1); //
163  return -99.0;
164  }
165 
166  if (temp.size() == 0)return -99.0;
167  double bw = abs(coshigh - coslow) / temp.size();
168  double bc = coslow + (0.5 + ibin) * bw; //bin centre
169  std::cout << "Par # " << ibin << ", costh bin centre = " << bc << ", const =" << temp[ibin] << std::endl;
170  return temp[ibin];
171  };
172 
173 
177  void printCosEdgePars(int side)
178  {
179  std::vector<double> temp;
180  double coslow = 0.0, coshigh = 0.0;
181  if (side < 0) {
182  temp = m_largeCos[0];
183  coslow = -0.870; coshigh = -0.850;
184  } else if (side > 0) {
185  temp = m_largeCos[1];
186  coslow = 0.950; coshigh = 0.960;
187  } else {
188  B2ERROR("CDCDedxCosineEdge:choose > 0 for forward and <0 for backward side");
189  return;
190  }
191 
192  if (temp.size() == 0)return;
193  double bw = abs(coshigh - coslow) / temp.size();
194  B2INFO("Printing parameters (0=backward and 1=forward): " << side << ", nPars = " << temp.size());
195  for (unsigned int ibin = 0; ibin < temp.size(); ibin++) {
196  double bc = coslow + (0.5 + ibin) * bw; //bin centre
197  std::cout << "Par # " << ibin << ", costh bin centre = " << bc << ", const = " << temp[ibin] << std::endl;
198  }
199  temp.clear();
200  };
201 
202 
208  void setCosthEdgePar(int side, unsigned int ibin, double value)
209  {
210  int iside = -99.0;
211  if (side < 0) {
212  iside = 0;
213  } else if (side > 0) {
214  iside = 1;
215  } else {
216  B2ERROR("CDCDedxCosineEdge:choose >0 for forward and <0 for backward side");
217  return;
218  }
219 
220  if (ibin >= m_largeCos[iside].size()) {
221  B2ERROR("CDCDedxCosineEdge:Problem with bin index: choose 0 and " << m_largeCos[iside].size() - 1); //
222  return;
223  }
224 
225  m_largeCos[iside][ibin] = value;
226  std::cout << "Par # " << ibin << ", const = " << m_largeCos[iside][ibin] << std::endl;
227  };
228 
229 
230  private:
231  std::vector<std::vector<double>> m_largeCos;
233  };
235 } // end namespace Belle2
dE/dx special large cosine calibration to fix bending shoulder at large costh
CDCDedxCosineEdge()
Default constructor.
ClassDef(CDCDedxCosineEdge, 1)
ClassDef.
double getCosEdgePar(int side, unsigned int ibin) const
return specific large cosine constants on give side
void setCosthEdgePar(int side, unsigned int ibin, double value)
set specific hadron parameter
double getMean(int side, unsigned int ibin) const
return calibration constant for given side and bin #
double getMean(double costh) const
return calibration constant for cosine value
void printCosEdgePars(int side)
print large cosine constants array on requested side
CDCDedxCosineEdge(const std::vector< std::vector< double >> &largecosth)
Constructor.
std::vector< std::vector< double > > m_largeCos
ADC vs corrected ADC mapping.
int getSize(const int side) const
Get the number of bins of requested side.
Abstract base class for different kinds of events.