ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
Calorimeter
CaloUtils
src
CaloLCCoeffHelper.cxx
Go to the documentation of this file.
1
/*
2
Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3
*/
4
5
// //-----------------------------------------------------------------------
6
// File and Version Information:
7
// $Id: CaloHadDMCoeffHelper.cxx,v 1.2 2009-03-06 14:43:23 pospelov Exp $
8
//
9
// Description: see CaloHadDMCoeffHelper.h
10
//
11
// Environment:
12
// Software developed for the ATLAS Detector at CERN LHC
13
//
14
// Author List:
15
// Gennady Pospelov
16
//
17
//-----------------------------------------------------------------------
18
#include "
CaloUtils/CaloLCCoeffHelper.h
"
19
#include <iostream>
20
#include <sstream>
21
#include <cstring>
22
#include <iomanip>
23
#include <cmath>
24
#include <format>
25
26
#include "
CaloConditions/CaloLocalHadDefs.h
"
27
#include "
CaloUtils/CaloWeightInterpolator.h
"
28
29
30
CaloLCCoeffHelper::CaloLCCoeffHelper
()
31
=
default
;
32
33
34
CaloLCCoeffHelper::~CaloLCCoeffHelper
()
35
=
default
;
36
37
38
// get HadDMArea from area name
39
const
CaloLocalHadCoeff::LocalHadArea
*
CaloLCCoeffHelper::getAreaFromName
(
const
CaloLocalHadCoeff
* coeff,
const
std::string& sname,
int
&indx)
40
{
41
for
(
int
i_area=0; i_area<coeff->
getSizeAreaSet
(); i_area++) {
42
if
(sname == coeff->
getArea
(i_area)->
getTitle
()) {
43
indx = i_area;
44
return
coeff->
getArea
(i_area);
45
}
46
}
47
std::cout <<
"CaloLCCoeffHelper::getAreaFromName() -> Error! No such area '"
<< sname <<
"'"
<< std::endl;
48
return
nullptr
;
49
}
50
51
52
53
/* ****************************************************************************
54
To read set of local hadronic coefficients from text file
55
**************************************************************************** */
56
std::optional<CaloLocalHadCoeff>
CaloLCCoeffHelper::InitDataFromFile
(
const
char
*filename)
57
{
58
std::optional<CaloLocalHadCoeff> data=std::make_optional<CaloLocalHadCoeff>();
59
60
char
cLine[1024];
61
62
// Find the full path to filename
63
std::cout <<
"CaloLCCoeffHelper::InitDataFromFile - Reading file '"
<< filename <<
"'."
<< std::endl;
64
65
std::ifstream fin(filename);
66
if
( !fin ) {
67
std::cout <<
"CaloLCCoeffHelper::InitDataFromFile - Can't open file '"
<< filename <<
"'."
<< std::endl;
68
return
std::nullopt;
69
}
70
71
std::string sLine;
72
std::istringstream ist;
73
while
(fin.getline(cLine,
sizeof
(cLine)-1)) {
74
if
( strlen(cLine)==0 || cLine[0] ==
'#'
|| cLine[0] ==
'\n'
)
continue
;
75
76
// parsing area line
77
sLine = cLine;
78
ist.clear(); ist.str(sLine);
79
std::string sdummy, area_title;
80
int
area_indx(0), area_type(0), area_npars(0);
81
if
( !(ist >> sdummy >> area_indx >> area_title >> area_type >> area_npars) ||
82
area_npars < 0 || area_npars > 1000 ) {
83
std::cout <<
"CaloLCCoeffHelper::initDataFromFile() -> Error! Could not parse line '"
<< cLine <<
"' at p1."
<< std::endl;
84
return
std::nullopt;
85
}
86
87
CaloLocalHadCoeff::LocalHadArea
theArea(area_title.c_str(), area_type, area_npars);
88
89
// loop over defined dimensions
90
while
(fin.getline(cLine,
sizeof
(cLine)-1)){
91
if
( cLine[0] ==
'#'
)
continue
;
92
sLine = cLine;
93
if
(sLine.find(
"break"
) != std::string::npos) {
94
break
;
95
}
96
auto
dim =
parse_dim
(sLine);
97
if
( !dim ) {
98
std::cout <<
"CaloLCCoeffHelper::initDataFromFile() ->Error! Could not parse line '"
<< sLine <<
"' at p2a."
<< std::endl;
99
return
std::nullopt;
100
}
101
theArea.
addDimension
(*dim);
102
}
103
data->addArea(theArea);
104
105
// now reading parameters
106
for
(
int
i_len=0; i_len<theArea.
getLength
(); i_len++){
107
if
(!fin.getline(cLine,
sizeof
(cLine)-1)) {
108
std::cout <<
"panic "
<< std::endl;
109
return
std::nullopt;
110
}
111
sLine = cLine;
112
ist.clear(); ist.str(sLine);
113
int
idummy;
114
if
( !(ist >> idummy) ) {
115
std::cout <<
"CaloLCCoeffHelper::initDataFromFile() -> Warning! Area "
<< theArea.
getTitle
() <<
" doesn't have parameters."
<< std::endl;
116
break
;
117
}
118
if
(idummy != theArea.
getOffset
()+i_len){
119
std::cout <<
"CaloLCCoeffHelper::initDataFromFile() ->Error! Could not parse line '"
<< cLine <<
"' at p3."
<< std::endl;
120
return
std::nullopt;
121
}
122
for
(
int
j=0; j<theArea.
getNdim
(); j++) {
123
if
(!(ist >> idummy)) {
124
std::cout <<
"CaloLCCoeffHelper::initDataFromFile() -> panic!"
<< std::endl;
125
return
std::nullopt;
126
}
127
}
128
CaloLocalHadCoeff::LocalHadCoeff
pars;
129
pars.resize(theArea.
getNpars
(),0.0);
130
for
(
int
j=0; j<theArea.
getNpars
(); j++) {
131
if
( !(ist >> pars[j]) ) {
132
std::cout <<
"CaloLCCoeffHelper::initDataFromFile() ->Error! Could not parse line '"
<< cLine <<
"' at p4."
<< std::endl;
133
std::cout <<
" dmArea.m_title"
<< theArea.
getTitle
() << std::endl;
134
return
std::nullopt;
135
}
136
}
137
data->setCoeff(theArea.
getOffset
()+i_len, pars);
138
}
139
}
140
fin.close();
141
142
return
data;
143
}
144
145
146
147
/* ****************************************************************************
148
149
**************************************************************************** */
150
void
CaloLCCoeffHelper::PrintData
(
CaloLocalHadCoeff
*data,
const
char
*fname)
151
{
152
std::ofstream
fout
;
153
fout
.open(fname);
154
PrintData
(data,
fout
);
155
fout
.close();
156
}
157
158
159
160
/* ****************************************************************************
161
162
**************************************************************************** */
163
void
CaloLCCoeffHelper::PrintData
(
CaloLocalHadCoeff
*data, std::ostream &
fout
)
164
{
165
const
char
*comments =
166
{
167
"# Coefficients for local hadronic calibration .\n\n"
168
};
169
fout
<< comments << std::endl;
170
char
line[1024];
171
172
// loop over areas
173
for
(
int
i_area=0; i_area < data->getSizeAreaSet(); i_area++){
174
const
CaloLocalHadCoeff::LocalHadArea
*
area
= data->getArea(i_area);
175
fout
<<
"area "
<< i_area <<
" "
<<
area
->getTitle() <<
" "
<<
area
->getType() <<
" "
<<
area
->getNpars() << std::endl;
176
for
(
int
i_dim=0; i_dim<
area
->getNdim(); i_dim++){
177
const
CaloLocalHadCoeff::LocalHadDimension
*dim =
area
->getDimension(i_dim);
178
snprintf(line,
sizeof
(line),
179
"%-6s %2d %6.3f %12.3f "
,dim->getTitle().c_str(), dim->getNbins(), dim->getXmin(), dim->getXmax() );
180
std::string sline(line);
181
sline +=
"flat"
;
182
fout
<< sline;
183
// if( !dim.m_xbins.size() ) {
184
// sline += "flat";
185
// fout << sline;
186
// }else {
187
// sline += "hand";
188
// fout << sline;
189
// for(unsigned int i=0; i<dim.m_xbins.size(); i++){
190
// fout << " " << dim.m_xbins[i];
191
// }
192
// }
193
fout
<< std::endl;
194
}
195
fout
<<
"break"
<< std::endl;
// i.e. no more dimensions
196
197
// now printing the data
198
for
(
int
i_data=0; i_data<
area
->getLength(); i_data++) {
199
int
indx =
area
->getOffset() + i_data;
200
const
CaloLocalHadCoeff::LocalHadCoeff
*pars = data->getCoeff(indx);
201
if
( !pars ) {
202
std::cout <<
"CaloLCCoeffHelper::PrintData() -> Error! Wrong bin number"
<< std::endl;
203
return
;
204
}
205
fout
<< std::format(
"{:>5} "
, indx);
206
std::vector<int > v_dim_indexes;
207
data->bin2indexes(indx, v_dim_indexes);
208
for
(
unsigned
int
i_dim=0; i_dim<v_dim_indexes.size(); i_dim++){
209
fout
<< std::format(
"{:>4} "
, v_dim_indexes[i_dim]);
210
}
211
fout
<<
" "
;
212
for
(
unsigned
int
i_par=0; i_par<(*pars).size(); i_par++) {
213
fout
<< std::format(
"{:>12.6f} "
, (*pars)[i_par]);
214
}
215
fout
<< std::endl;
216
}
217
218
// end of DM area
219
fout
<< std::endl;
220
}
221
// printing title strin
222
}
223
224
225
226
/* **************************************************************************
227
Interpolate data, area in phase space point x, over dimensions dim (all if 0)
228
for speed reason, no check on dim content !!!!!!!!
229
*************************************************************************** */
230
bool
CaloLCCoeffHelper::Interpolate
(
const
CaloLocalHadCoeff
*data,
const
unsigned
int
n_area,
231
std::vector<float> &
x
,
CaloLocalHadCoeff::LocalHadCoeff
&pars,
232
const
std::vector<int> &dim,
double
xfit)
233
{
234
// Sanity check
235
if
( n_area >= (
unsigned
int
)data->getSizeAreaSet())
return
false
;
236
// We are not extrapolator
237
if
(!data->isFilled(data->getBin(n_area,
x
))) {
238
return
false
;
239
}
240
241
const
CaloLocalHadCoeff::LocalHadArea
*
area
= data->getArea(n_area);
242
unsigned
int
ndim;
243
if
(dim.empty()) {
244
std::cout <<
"CaloLCCoeffHelper::Interpolate() -> Error! Empty vector of dimensions to interpolate trough."
<< std::endl;
245
return
false
;
246
}
else
if
( (
int
)dim.size() >
area
->getNdim()){
247
std::cout <<
"CaloLCCoeffHelper::Interpolate() -> Error! Vector of dimensions to interpolate exceed defined in area."
<< std::endl;
248
return
false
;
249
}
else
ndim=dim.size();
250
unsigned
int
ncorners = (1<<ndim);
251
252
std::vector<double > vXadj(ndim);
253
std::vector<unsigned int > vgbins(ncorners);
254
std::vector<double > vWeights(ncorners);
255
std::vector<int> ebindx;
256
std::vector<int> bx;
257
unsigned
int
nip;
258
259
switch
(
area
->getType()) {
260
case
CaloLocalHadDefs::AREA_STD
:
case
CaloLocalHadDefs::AREA_DMLOOKUP
:
case
CaloLocalHadDefs::AREA_DMSMPW
:
case
CaloLocalHadDefs::AREA_DMFIT
: {
261
nip = data->getCoeff(
area
->getOffset()+1)->size();
262
if
(
area
->getType() ==
CaloLocalHadDefs::AREA_DMFIT
) {
263
nip = 1;
264
}
else
{
265
nip = data->getCoeff(
area
->getOffset()+1)->size();
266
}
267
pars.resize(nip);
268
for
(
unsigned
int
ip=0; ip<nip; ++ip) {
269
bool
isa = data->getInterpArrays(n_area,dim,
x
,vXadj,vgbins);
270
if
(! isa) {
271
std::cout<<
"No arrays for x: "
;
272
for
(
unsigned
int
l=0; l<
x
.size(); ++l) std::cout<<
x
[l]<<
" "
;
273
std::cout<<std::endl;
274
return
false
;
275
}
276
for
(
unsigned
int
i_len=0; i_len<ncorners; ++i_len){
277
// Check for empty bin here TODO !!!!!
278
if
(data->isFilled(vgbins[i_len])) {
279
const
CaloLocalHadCoeff::LocalHadCoeff
* lpars =
280
data->getCoeff(vgbins[i_len]);
281
if
(
area
->getType() ==
CaloLocalHadDefs::AREA_DMFIT
) {
282
// std::cout << "xxx " << xfit << " " << (*pars)[0] << " " << (*pars)[1] << " " << (*pars)[2] << std::endl;
283
vWeights[i_len] = (*lpars)[0] + (*lpars)[1]*pow(xfit,(*lpars)[2]);
284
}
else
{
285
vWeights[i_len] = (*lpars)[ip];
286
}
287
// std::cout<<vWeights[i_len]<<" ";
288
}
else
{
289
// std::cout<<x[0]<<" "<<x[1]<<" : "<<vXadj[0]<<" "<<vXadj[1]<<" | ";
290
// if empty, put inside average over all neighbours in our list
291
vWeights[i_len] = 0.;
292
unsigned
int
icount = 0;
293
data->bin2indexes(vgbins[i_len],ebindx);
294
// for(unsigned int blen=0; blen<ebindx.size(); ++blen) { std::cout<<ebindx[blen]<<" "; }
295
//std::cout<<" | ";
296
for
(
unsigned
int
blen=0; blen<ncorners; ++blen){
297
if
(blen == i_len)
continue
;
298
if
(!data->isFilled(vgbins[blen])){
299
data->bin2indexes(vgbins[i_len],bx);
300
//for(unsigned int l=0; l<bx.size(); ++l) { std::cout<<bx[l]<<" "; }
301
//std::cout<<" nf| ";
302
continue
;
303
}
304
if
(data->isNeighbour(vgbins[blen], ebindx)) {
305
const
CaloLocalHadCoeff::LocalHadCoeff
* lpars =
306
data->getCoeff(vgbins[blen]);
307
if
(
area
->getType() ==
CaloLocalHadDefs::AREA_DMFIT
) {
308
vWeights[i_len] = (*lpars)[0] + (*lpars)[1]*pow(xfit,(*lpars)[2]);
309
}
else
{
310
vWeights[i_len] += (*lpars)[ip];
311
}
312
++icount;
313
}
314
}
315
if
(icount) {
316
//std::cout<<"i";
317
vWeights[i_len] /= icount;
318
}
319
//std::cout<<vWeights[i_len]<<"a ";
320
//std::cout<<std::endl;
321
}
322
}
323
pars[ip] =
CaloWeightInterpolator::getWeight
(vWeights,vXadj);
324
}
325
return
true
;
326
}
327
default
: {
328
std::cout<<
"Not implemented yet for this Area type !!!"
<<std::endl;
329
return
false
;
330
}
331
}
332
// Should not get here, but syntax needs this
333
return
false
;
334
}
335
336
337
338
/* **************************************************************************
339
parsing dimension string of type 'ener 8 3.1 6.3'
340
*************************************************************************** */
341
std::optional<CaloLocalHadCoeff::LocalHadDimension>
CaloLCCoeffHelper::parse_dim
(
const
std::string &sLine)
342
{
343
std::optional<CaloLocalHadCoeff::LocalHadDimension> dim{std::nullopt};
344
std::istringstream ist(sLine.c_str());
345
346
std::string dim_title;
347
std::string stype;
348
int
dim_nbins(0), dim_type(0);
349
float
dim_xmax(0), dim_xmin(0);
350
351
if
( !(ist >> dim_title >> dim_nbins >> dim_xmin >> dim_xmax >> stype) ){
352
std::cout <<
"CaloHadDMCoeffHelper::parse_dim() -> Error! Could not parse line '"
<< sLine <<
"' at p1."
<< std::endl;
353
return
std::nullopt;
354
}
355
356
// Check nbins for reasonableness --- prevents a coverity warning.
357
if
(dim_nbins < 1)
358
dim_nbins = 1;
359
else
if
(dim_nbins > 10000)
360
dim_nbins = 10000;
361
362
if
(stype.find(
"flat"
) != std::string::npos) {
363
// equidistant binning
364
dim.emplace(dim_title.c_str(), dim_type, dim_nbins, dim_xmin, dim_xmax);
365
}
else
if
(stype.find(
"hand"
) != std::string::npos) {
366
// user defined binning
367
std::vector<float> x_bins;
368
float
e;
369
for
(
int
i=0; i<dim_nbins+1; i++) {
370
if
( !(ist >> e) ) {
371
std::cout <<
"CaloHadDMCoeffHelper::parse_dim() -> Error! Could not parse line '"
<< sLine <<
"' at p2."
<< std::endl;
372
return
std::nullopt;
373
}
else
{
374
x_bins.push_back(e);
375
}
376
}
377
dim.emplace(dim_title.c_str(), dim_type, x_bins);
378
}
else
{
379
std::cout <<
"CaloHadDMCoeffHelper::parse_dim() -> Error! Could not parse line '"
<< sLine <<
"' at p3."
<< std::endl;
380
return
std::nullopt;
381
}
382
return
dim;
383
}
384
CaloLCCoeffHelper.h
CaloLocalHadDefs.h
CaloWeightInterpolator.h
area
double area(double R)
Definition
ConvertStaveServices.cxx:42
x
#define x
CaloLCCoeffHelper::~CaloLCCoeffHelper
virtual ~CaloLCCoeffHelper()
CaloLCCoeffHelper::Interpolate
static bool Interpolate(const CaloLocalHadCoeff *m_data, const unsigned int n_area, std::vector< float > &x, CaloLocalHadCoeff::LocalHadCoeff &pars, const std::vector< int > &dim, double xfit=0.)
Definition
CaloLCCoeffHelper.cxx:230
CaloLCCoeffHelper::PrintData
static void PrintData(CaloLocalHadCoeff *m_data, std::ostream &fout)
Definition
CaloLCCoeffHelper.cxx:163
CaloLCCoeffHelper::InitDataFromFile
static std::optional< CaloLocalHadCoeff > InitDataFromFile(const char *fname)
Definition
CaloLCCoeffHelper.cxx:56
CaloLCCoeffHelper::CaloLCCoeffHelper
CaloLCCoeffHelper()
CaloLCCoeffHelper::parse_dim
static std::optional< CaloLocalHadCoeff::LocalHadDimension > parse_dim(const std::string &sLine)
Definition
CaloLCCoeffHelper.cxx:341
CaloLCCoeffHelper::getAreaFromName
static const CaloLocalHadCoeff::LocalHadArea * getAreaFromName(const CaloLocalHadCoeff *m_coeff, const std::string &sname, int &m_indx)
Definition
CaloLCCoeffHelper.cxx:39
CaloLocalHadCoeff::LocalHadArea
Definition of correction area.
Definition
CaloLocalHadCoeff.h:145
CaloLocalHadCoeff::LocalHadArea::getLength
int getLength() const
return area length
Definition
CaloLocalHadCoeff.h:177
CaloLocalHadCoeff::LocalHadArea::getTitle
const std::string & getTitle() const
return name
Definition
CaloLocalHadCoeff.h:183
CaloLocalHadCoeff::LocalHadArea::getNdim
int getNdim() const
get number of dimensions
Definition
CaloLocalHadCoeff.h:179
CaloLocalHadCoeff::LocalHadArea::getNpars
int getNpars() const
return number of parameters
Definition
CaloLocalHadCoeff.h:173
CaloLocalHadCoeff::LocalHadArea::getOffset
int getOffset() const
return area offset
Definition
CaloLocalHadCoeff.h:175
CaloLocalHadCoeff::LocalHadArea::addDimension
void addDimension(LocalHadDimension &dim)
to add new dimension
Definition
CaloLocalHadCoeff.cxx:135
CaloLocalHadCoeff::LocalHadDimension
Class defines binning for user dimension.
Definition
CaloLocalHadCoeff.h:47
CaloLocalHadCoeff
Hold binned correction data for local hadronic calibration procedure.
Definition
CaloLocalHadCoeff.h:41
CaloLocalHadCoeff::getArea
const LocalHadArea * getArea(int n_area) const
return area
Definition
CaloLocalHadCoeff.cxx:201
CaloLocalHadCoeff::LocalHadCoeff
std::vector< float > LocalHadCoeff
Correction parameters for one general bin.
Definition
CaloLocalHadCoeff.h:220
CaloLocalHadCoeff::getSizeAreaSet
int getSizeAreaSet() const
return number of areas defined for this data set
Definition
CaloLocalHadCoeff.h:248
fout
static TFile * fout
Definition
listroot.cxx:40
CaloLocalHadDefs::AREA_DMFIT
@ AREA_DMFIT
Definition
CaloLocalHadDefs.h:21
CaloLocalHadDefs::AREA_DMSMPW
@ AREA_DMSMPW
Definition
CaloLocalHadDefs.h:23
CaloLocalHadDefs::AREA_STD
@ AREA_STD
Definition
CaloLocalHadDefs.h:20
CaloLocalHadDefs::AREA_DMLOOKUP
@ AREA_DMLOOKUP
Definition
CaloLocalHadDefs.h:22
CaloWeightInterpolator::getWeight
static double getWeight(std::vector< double > &w, std::vector< double > &x)
Definition
CaloWeightInterpolator.cxx:26
Generated on
for ATLAS Offline Software by
1.17.0