Belle II Software development
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
11#include <framework/logging/Logger.h>
12
13#include <TObject.h>
14
15#include <cmath>
16#include <vector>
17
18
19namespace Belle2 {
30 class CDCDedxCosineEdge: public TObject {
31 public:
32
37
42 explicit CDCDedxCosineEdge(const std::vector<std::vector<double>>& largecosth): m_largeCos(largecosth) {};
43
48
54 int getSize(const int side) const
55 {
56 if (side < 0) {
57 if (m_largeCos.empty()) return 0;
58 return m_largeCos[0].size();
59 } else {
60 if (m_largeCos.size() < 2) return 0;
61 return m_largeCos[1].size();
62 }
63 };
64
65
72 double getMean(int side, unsigned int ibin) const
73 {
74 if (m_largeCos.size() < 2) {
75 B2ERROR("CDCDedxCosineEdge: vector-of-vectors too short, returning 1");
76 return 1.0;
77 }
78
79 const std::vector<double>& temp = side < 0 ? m_largeCos[0] : m_largeCos[1];
80 if (ibin < temp.size()) return temp[ibin];
81
82 B2WARNING("CDCDedxCosineEdge: invalid bin number, returning 1");
83 return 1.0;
84 };
85
91 double getMean(double costh)const
92 {
93 if (m_largeCos.size() < 2) {
94 B2ERROR("CDCDedxCosineEdge: vector-of-vectors too short, returning 1");
95 return 1.0;
96 }
97
98 const std::vector<double>& temp = costh < 0 ? m_largeCos[0] : m_largeCos[1];
99 if (temp.size() < 2) {
100 B2ERROR("CDCDedxCosineEdge: vector too short, returning 1");
101 return 1.0;
102 }
103
104 double coslow = 0.0, coshigh = 0.0;
105 if (costh < 0) {
106 coslow = -0.870; coshigh = -0.850; //this is hardcoded and fixed
107 } else {
108 coslow = 0.950; coshigh = 0.960; //this is hardcoded and fixed
109 }
110
111 //don't do anything for other cosine range
112 if (costh < coslow or costh > coshigh) {
113 return 1.0;
114 }
115
116 if (costh <= -0.866 or costh >= 0.9575) return 1.0;
117
118 // gains are stored at the center of the bins
119 // find the bin center immediately preceding this value of costh
120 int nbins = int(temp.size());
121 double binsize = (coshigh - coslow) / nbins;
122 int bin = std::floor((costh - 0.5 * binsize - coslow) / binsize);
123 if (bin < 0) bin = 0;
124 else if (bin > nbins - 2) bin = nbins - 2;
125
126 // extrapolate backward for lowest half-bin and center positive half-bin
127 // extrapolate forward for highest half-bin and center negative half-bin
128 // MS: not clear why this is needed
129 if (temp[bin + 1] - temp[bin] < -0.6) bin++;
130 else if (temp[bin + 1] - temp[bin] > 0.6) bin--;
131
132 if (bin < 0 or bin + 1 >= nbins) {
133 B2WARNING("CDCDedxCosineEdge:no constants for costh: " << costh << " as it is not in range");
134 return 1.0;
135 }
136
137 double frac = ((costh - 0.5 * binsize - coslow) / binsize) - bin;
138 return ((temp[bin + 1] - temp[bin]) * frac + temp[bin]);
139 }
140
146 double getCosEdgePar(int side, unsigned int ibin) const
147 {
148
149 std::vector<double> temp;
150 double coslow = 0.0, coshigh = 0.0;
151 if (side < 0) {
152 if (m_largeCos.size() > 0) temp = m_largeCos[0];
153 coslow = -0.870; coshigh = -0.850;
154 } else if (side > 0) {
155 if (m_largeCos.size() > 1) temp = m_largeCos[1];
156 coslow = 0.950; coshigh = 0.960;
157 } else {
158 B2ERROR("CDCDedxCosineEdge:choose > 0 for forward and <0 for backward side");
159 return -99.0;
160 }
161
162 if (ibin >= temp.size()) {
163 B2ERROR("CDCDedxCosineEdge:Problem with bin index: choose 0 and " << temp.size() - 1); //
164 return -99.0;
165 }
166
167 if (temp.size() == 0) return -99.0;
168 double bw = std::abs(coshigh - coslow) / temp.size();
169 double bc = coslow + (0.5 + ibin) * bw; //bin centre
170 std::cout << "Par # " << ibin << ", costh bin centre = " << bc << ", const =" << temp[ibin] << std::endl;
171 return temp[ibin];
172 };
173
174
179 void printCosEdgePars(int side)
180 {
181 std::vector<double> temp;
182 double coslow = 0.0, coshigh = 0.0;
183 if (side < 0) {
184 if (m_largeCos.size() > 0) temp = m_largeCos[0];
185 coslow = -0.870; coshigh = -0.850;
186 } else if (side > 0) {
187 if (m_largeCos.size() > 1) temp = m_largeCos[1];
188 coslow = 0.950; coshigh = 0.960;
189 } else {
190 B2ERROR("CDCDedxCosineEdge:choose > 0 for forward and <0 for backward side");
191 return;
192 }
193
194 if (temp.size() == 0) return;
195 double bw = std::abs(coshigh - coslow) / temp.size();
196 B2INFO("Printing parameters (0=backward and 1=forward): " << side << ", nPars = " << temp.size());
197 for (unsigned int ibin = 0; ibin < temp.size(); ibin++) {
198 double bc = coslow + (0.5 + ibin) * bw; //bin centre
199 std::cout << "Par # " << ibin << ", costh bin centre = " << bc << ", const = " << temp[ibin] << std::endl;
200 }
201 };
202
203
210 void setCosthEdgePar(int side, unsigned int ibin, double value)
211 {
212 if (m_largeCos.size() < 2) {
213 B2ERROR("CDCDedxCosineEdge: vector-of-vectors too short, value not set");
214 return;
215 }
216
217 int iside = side < 0 ? 0 : 1;
218 if (ibin >= m_largeCos[iside].size()) {
219 B2ERROR("CDCDedxCosineEdge: invalid bin number, value not set");
220 return;
221 }
222
223 m_largeCos[iside][ibin] = value;
224 B2DEBUG(20, "Par # " << ibin << ", const = " << m_largeCos[iside][ibin]);
225 };
226
227
228 private:
229 std::vector<std::vector<double>> m_largeCos;
231 };
233} // 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.
std::vector< std::vector< double > > m_largeCos
large cosine calibration constants
CDCDedxCosineEdge(const std::vector< std::vector< double > > &largecosth)
Constructor.
int getSize(const int side) const
Get the number of bins of requested side.
Abstract base class for different kinds of events.