ATLAS Offline Software
Loading...
Searching...
No Matches
CaloLocalHadCoeff.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
11#include <algorithm>
12#include <cmath>
13#include <iomanip>
14#include <iostream>
15#include <sstream>
16
17
18
19/* ***************************************************************************
20LocalHadDimension ->
21*************************************************************************** */
22
23
24// return bin number for cluster variable
26{
27 if( x<m_xmin ) {
28 return -1;
29 }
30 if( x>=m_xmax ) {
31 return -100;
32 }
33 int i_bin = -1;
34 if( m_xbins.empty() ) { // flat binning
35 i_bin = (int)((x - m_xmin)/m_dx);
36 }else{ // user binning
37 for(i_bin=0; i_bin<(int)m_xbins.size(); i_bin++){
38 if( x < m_xbins[i_bin] ) break;
39 }
40 }
41 return i_bin;
42}
43
44// return two bins
46{
47 if (x < m_xmin) {
48 xadj=0.;
49 return 0;
50 }
51
52// int i_bin = (int)((x - m_xmin)/m_dx);
53 int i_bin = getBin(x);
54
55 if(i_bin<-10) {
56 i_bin=m_nbins-1;
57 xadj=1.0;
58 } else if(i_bin<0) {
59 i_bin=0;
60 xadj=0.0;
61 }else{
62 xadj = fmod( (x-m_xmin)/m_dx, 1);
63 if(xadj <= 0.5) {
64 if(i_bin > 0 ){
65 --i_bin;
66 xadj += 0.5;
67 } else {
68 xadj=0.;
69 }
70 }else{
71// if(i_bin > 0){
72 xadj -= 0.5;
73// }
74 }
75 }
76 return i_bin;
77}
78
79// return true, if this general bin is neighbour of the bin given by indexes vector
80bool CaloLocalHadCoeff::isNeighbour(const int iBinx, std::vector<int> &v_indx) const {
81 // Sanity check
82 if(iBinx < 0 || iBinx >= (int) m_CoeffSet.size()) return false;
83 if((int)v_indx.size() != getAreaFromBin(iBinx)->getNdim()) {
84 std::cout<<"CaloLocalHadCoeff::LocalHadDimension::getBinAdjusted() -> Error! Wrong indexes vector size in isNeighbour: "<< v_indx.size()<<std::endl;
85 return false;
86 }
87 std::vector<int> xidx;
88 bin2indexes(iBinx, xidx);
89 for(unsigned int i=0; i<xidx.size(); ++i) {
90 if(abs(v_indx[i]-xidx[i]) == 1) return true;
91 }
92 return false;
93}
94
95
96// return true, if bin was filled with data, depending on type of area
97bool CaloLocalHadCoeff::isFilled(const int bin) const
98{
99 if( bin<0 || bin >= (int)m_CoeffSet.size() ) {
100 return false;
101 }
102 switch(getAreaFromBin(bin)->getType()) {
105 return m_CoeffSet[bin][ient] != 0;
106 }
108 return m_CoeffSet[bin][CaloLocalHadDefs::BIN_P0] != 0 ||
109
111
113 }
115 bool bf=false;
116 for(unsigned int i=0; i<m_CoeffSet[bin].size(); ++i) if(m_CoeffSet[bin][i] != 0) bf=true;
117 return bf;
118 }
119 default:{
120 std::cout<<"CaloLocalHadCoeff::isFilled() -> Error! Unknown area typ: "<<getAreaFromBin(bin)->getType()<<" in isFilled !!"<<std::endl;
121 return false;
122 }
123 }
124 // should not come here, but syntax need it:
125 return false;
126}
127
128
129
130/* ***************************************************************************
131LocalHadArea ->
132*************************************************************************** */
133
134// add new dimension to the area
136{
137 m_dims.push_back(dim);
138 // recalculation of length of the area (product of bins numbers of each dimension)
139 m_length = 1;
140 int ndim = (int)m_dims.size();
141 for(int i=0; i<ndim; i++){
142 m_length = m_length*m_dims[i].getNbins();
143 }
144 // calculation of dimension locator coefficient for fast calculation of global bin number
145 m_dims_loc.resize(ndim, 0);
146 for(int i_dim=0; i_dim<ndim; i_dim++){
147 int xloc = 1;
148 for(int j=i_dim+1; j<ndim; j++){
149 xloc = xloc*m_dims[j].getNbins();
150 }
151 m_dims_loc[i_dim] = xloc;
152 }
153}
154
155
156
157/* ***************************************************************************
158CaloLocalHadCoeff
159*************************************************************************** */
160
161// default constructor
163{
164 static_assert(std::is_nothrow_move_constructible<CaloLocalHadCoeff>::value);
165 static_assert(std::is_nothrow_move_constructible<LocalHadArea>::value);
166 static_assert(std::is_nothrow_move_constructible<LocalHadDimension>::value);
167}
168
169
170
171/* ***************************************************************************
172CaloLocalHadCoeff: area's methods
173*************************************************************************** */
174
175// to add new area definition
177{
178 // calculating offset for coefficients of this area using previous areas defined
179 int offset = 0;
180 for(unsigned int i_area=0; i_area<m_AreaSet.size(); i_area++){
181 offset += m_AreaSet[i_area].getLength();
182 }
183 theArea.setOffset(offset);
184 // adding zero coefficients
186 pars.resize(theArea.getNpars(), 0.0);
187 for(int i_size=0; i_size<theArea.getLength(); i_size++){
188 m_CoeffSet.push_back(pars);
189 }
190 // adding area
191 m_AreaSet.push_back(theArea);
192}
193
194// to set new area
195void CaloLocalHadCoeff::setArea(const int n_area, const LocalHadArea & theArea)
196{
197 m_AreaSet[n_area] = theArea;
198}
199
200// return area
202{
203 if(n_area >= 0 && n_area<(int)m_AreaSet.size() ) {
204 return &(m_AreaSet[n_area]);
205 } else {
206 return nullptr;
207 }
208}
209
210// return area for given global bin number
212{
213 int i_area = 0;
214 int narea = m_AreaSet.size();
215 for(i_area=0; i_area<narea; i_area++) {
216 if( iBin < m_AreaSet[i_area].getOffset() ) break;
217 if( iBin >= m_AreaSet[i_area].getOffset()
218 && (i_area == narea-1 || iBin < m_AreaSet[i_area+1].getOffset()) ) break;
219 }
220 return &(m_AreaSet[i_area]);
221}
222
223// return area for given global bin number
225{
226 i_area = 0;
227 int narea = m_AreaSet.size();
228 for(i_area=0; i_area<narea; i_area++) {
229 if( iBin < m_AreaSet[i_area].getOffset() ) break;
230 if( iBin >= m_AreaSet[i_area].getOffset()
231 && (i_area == narea-1 || iBin < m_AreaSet[i_area+1].getOffset()) ) break;
232 }
233 return &(m_AreaSet[i_area]);
234}
235
236
237
238/* ***************************************************************************
239CaloLocalHadCoeff: coefficients methods
240*************************************************************************** */
241
242// set coefficient
243void CaloLocalHadCoeff::setCoeff(const int iBin, const LocalHadCoeff & theCoeff)
244{
245 m_CoeffSet[iBin] = theCoeff;
246}
247
248// return coefficient for given global bin number
250{
251 if ( iBin >= 0 && iBin < (int)m_CoeffSet.size() ) {
252 return (& m_CoeffSet[iBin]);
253 }else{
254 return nullptr;
255 }
256}
257
258// return coefficient for given area number and list of cluster variables
259const CaloLocalHadCoeff::LocalHadCoeff * CaloLocalHadCoeff::getCoeff(const int &n_area, std::vector<float> &vars) const
260{
261 int iBin = getBin(n_area, vars);
262 return getCoeff(iBin);
263}
264
265
266
267/* ***************************************************************************
268CaloLocalHadCoeff: bin's methods
269*************************************************************************** */
270
271// return global bin number for given area and list of cluster variables
272// size of input vector must be equal to the number of dimensions defined for this area
273int CaloLocalHadCoeff::getBin(const int n_area, std::vector<float> &vars) const
274{
275 const LocalHadArea *area = &m_AreaSet[n_area];
276 // loop over dimensions
277 int iBin = area->getOffset();
278 for(int i_dim=0; i_dim<area->getNdim(); i_dim++){
279 int i_bin_dim = area->getDimension(i_dim)->getBin( vars[i_dim] );
280 if(i_bin_dim < 0) return -1;
281 iBin += i_bin_dim*area->getDimLoc(i_dim);
282 }
283 return iBin;
284}
285
286// returns general iBin for given area and vector of bin numbers for each dimension
287// size of input vector must be equal to the number of dimensions defined for this area
288int CaloLocalHadCoeff::getBin(const int n_area, std::vector<int> &v_indexes) const
289{
290 const LocalHadArea *area = &m_AreaSet[n_area];
291 // loop over dimensions
292 int iBin = area->getOffset();
293 for(int i_dim=0; i_dim<area->getNdim(); i_dim++){
294 if(v_indexes[i_dim] < 0) return -1;
295 iBin += v_indexes[i_dim]*area->getDimLoc(i_dim);
296 }
297 return iBin;
298}
299
300// convert general iBin to vector of bins for each dimension
301int CaloLocalHadCoeff::bin2indexes(const int iBin, std::vector<int> &v_dim_indx) const
302{
303 const LocalHadArea *theArea = getAreaFromBin(iBin);
304 v_dim_indx.resize(theArea->getNdim(),0);
305 for(int i_dim=0; i_dim<theArea->getNdim(); i_dim++){
306 int x0 = 0;
307 for(int j=0; j<i_dim; j++){
308 x0 += v_dim_indx[j]*theArea->getDimLoc(j);
309 }
310 v_dim_indx[i_dim] = (iBin-theArea->getOffset()-x0)/theArea->getDimLoc(i_dim);
311 }
312 return 0;
313}
314
315// return and arrays needed for interpolation for a given area (n_area), given list of dimensions (dim) and given phase space point (x)
316// for speed reason, no check on dimensions !!!!!!!!
317bool CaloLocalHadCoeff::getInterpArrays(const int n_area, const std::vector<int> &dim, std::vector<float> &x,
318 std::vector<double> &xadj, std::vector<unsigned int> &gbin) const {
319 // sanity check
320 if(n_area<0 || n_area >= (int)m_AreaSet.size()) return false;
321 const LocalHadArea *area=&(m_AreaSet[n_area]);
322 if(dim.empty()) {
323 std::cout << "CaloLocalHadCoeff::getInterpArrays() -> Error! Empty dimension list" << std::endl;
324 return false;
325 }else if( (int)dim.size() > area->getNdim()) {
326 std::cout << "CaloLocalHadCoeff::getInterpArrays() -> Error! Vector of dimensions to interpolate exceed defined in area." << std::endl;
327 return false;
328 }
329 int ndim = dim.size();
330
331 if((int)x.size()!= area->getNdim()) {
332 std::cout<<"CaloLocalHadCoeff::getInterpArrays() -> Error! Wrong size of phase space point !!!"<<std::endl;
333 return false;
334 }
335
336 xadj.resize(ndim);
337 unsigned int ncorners = (1<<ndim);
338 gbin.resize(ncorners);
339
340 float xa;
341 int ibin, i;
342 unsigned int i_len;
343 std::vector<int> vTmp;
344 std::vector<int> vIdx(area->getNdim());
345 std::vector<std::vector<int> > vpW;
346 for(i=0; i<ndim; i++){
347 ibin = (area->getDimension(dim[i]))->getBinAdjusted(x[dim[i]],xa);
348 //if(xadj<0) printf("%d x:%6.3f xadj:%6.3f ibin:%d ibin+1:%d \n",i, x[i], xadj, ibin, ibin+1);
349 xadj[i] = xa;
350 vTmp.clear();
351 vTmp.push_back(ibin);
352 if(ibin< (area->getDimension(dim[i]))->getNbins()-1) vTmp.push_back(ibin+1);
353 else vTmp.push_back(ibin);
354 vpW.push_back(vTmp);
355 }
356 // fill the vIdx for dimensions we are not interpolating over
357 for(i=0; i<area->getNdim(); ++i){
358 if(std::find(dim.begin(),dim.end(),i) != dim.end()) continue;
359 vIdx[i] = area->getDimension(i)->getBin(x[i]);
360 }
361
362 // now find the global bin for all corners
363 //vTmp.clear();
364 //vTmp.resize(ndim);
365 for(i_len=0; i_len<ncorners; ++i_len){
366 for( i=0; i<ndim; i++){
367 //std::cout<<"Sec. idx: "<<int(i_len/int(pow(2,i)))%int(pow(2,i))<<std::endl;
368 if(i==0) vIdx[dim[i]] = vpW[i][i_len%2];
369 else vIdx[dim[i]] = vpW[i][int(i_len/int(pow(2,i)))%int(pow(2,i))];
370 //if(i==2) std::cout<< vTmp[i] <<" ";
371 //std::cout<< vTmp[i] <<" ";
372 }
373 // std::cout<<std::endl;
374 ibin = getBin(n_area,vIdx);
375 gbin[i_len] = ibin;
376 }
377 return true;
378}
379
double area(double R)
#define x
constexpr int pow(int base, int exp) noexcept
Definition of correction area.
int getDimLoc(int i_dim) const
get dimension locator coefficient
std::vector< LocalHadDimension > m_dims
vector of defined dimensions
int getLength() const
return area length
int m_length
length of area data block (product of m_nbins over all dimensions defined)
int getNdim() const
get number of dimensions
int getNpars() const
return number of parameters
std::vector< int > m_dims_loc
locator index for dimensions
int getOffset() const
return area offset
void addDimension(LocalHadDimension &dim)
to add new dimension
unsigned int getType() const
return area type
void setOffset(int offset)
set area offset
Class defines binning for user dimension.
float m_xmin
minimum value for the first bin
float m_dx
bin size (in the case of equidistant binning)
std::vector< float > m_xbins
bins borders (if dimension has non-equidistant binning), vector of size m_nbins+1
float m_xmax
maximum value for the last bin
int getBin(float &x) const
return bin number
int getBinAdjusted(float &x, float &xadj) const
CaloLocalHadCoeff()
Default constructor.
const LocalHadCoeff * getCoeff(const int &iBin) const
get data for given general bin number
bool isFilled(const int iBin) const
check if general bin is filled
const LocalHadArea * getArea(int n_area) const
return area
void addArea(LocalHadArea &theArea)
add new area
bool isNeighbour(const int iBinx, std::vector< int > &v_indx) const
are this bins is neighbour to this indexes vector (any of their indexes differ per one ?...
void setCoeff(const int iBin, const LocalHadCoeff &theCoeff)
set new data
int bin2indexes(const int iBin, std::vector< int > &v_dim_indx) const
expand general bin into vector of bins for defined dimensions
const LocalHadArea * getAreaFromBin(int iBin) const
return area defined for given general iBin
void setArea(const int n_area, const LocalHadArea &theArea)
replace existing area with another one
int getBin(const int n_area, std::vector< float > &vars) const
calculate general bin from vector of input cluster variables
bool getInterpArrays(const int n_area, const std::vector< int > &dim, std::vector< float > &x, std::vector< double > &xadj, std::vector< unsigned int > &gbin) const
for interpolation, build the vector of relative x, and global bins for interpolated array for area n_...
std::vector< float > LocalHadCoeff
Correction parameters for one general bin.
std::vector< LocalHadArea > m_AreaSet
vector of correction areas
std::vector< LocalHadCoeff > m_CoeffSet
vector of correction coefficients
void getOffset(boost::tokenizer< boost::char_separator< char > >::iterator &token, uint32_t &offset)