ATLAS Offline Software
CaloLCCoeffHelper.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 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 //-----------------------------------------------------------------------
19 #include <iostream>
20 #include <sstream>
21 #include <cstring>
22 #include <iomanip>
23 #include <cmath>
24 #include "boost/io/ios_state.hpp"
25 
28 
29 
31 = default;
32 
33 
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  std::cout << "CaloLCCoeffHelper::initDataFromFile() -> Error! Could not parse line '" << cLine << "' at p1." << std::endl;
83  return std::nullopt;
84  }
85 
86  CaloLocalHadCoeff::LocalHadArea theArea(area_title.c_str(), area_type, area_npars);
87 
88  // loop over defined dimensions
89  while(fin.getline(cLine,sizeof(cLine)-1)){
90  if( cLine[0] == '#') continue;
91  sLine = cLine;
92  if(sLine.find("break") != std::string::npos) {
93  break;
94  }
95  auto dim = parse_dim(sLine);
96  if( !dim ) {
97  std::cout << "CaloLCCoeffHelper::initDataFromFile() ->Error! Could not parse line '" << sLine << "' at p2a." << std::endl;
98  return std::nullopt;
99  }
100  theArea.addDimension(*dim);
101  }
102  data->addArea(theArea);
103 
104  // now reading parameters
105  for(int i_len=0; i_len<theArea.getLength(); i_len++){
106  if(!fin.getline(cLine,sizeof(cLine)-1)) {
107  std::cout << "panic " << std::endl;
108  return std::nullopt;
109  }
110  sLine = cLine;
111  ist.clear(); ist.str(sLine);
112  int idummy;
113  if( !(ist >> idummy) ) {
114  std::cout << "CaloLCCoeffHelper::initDataFromFile() -> Warning! Area " << theArea.getTitle() << " doesn't have parameters." << std::endl;
115  break;
116  }
117  if(idummy != theArea.getOffset()+i_len){
118  std::cout << "CaloLCCoeffHelper::initDataFromFile() ->Error! Could not parse line '" << cLine << "' at p3." << std::endl;
119  return std::nullopt;
120  }
121  for(int j=0; j<theArea.getNdim(); j++) {
122  if(!(ist >> idummy)) {
123  std::cout << "CaloLCCoeffHelper::initDataFromFile() -> panic!" << std::endl;
124  return std::nullopt;
125  }
126  }
128  pars.resize(theArea.getNpars(),0.0);
129  for(int j=0; j<theArea.getNpars(); j++) {
130  if( !(ist >> pars[j]) ) {
131  std::cout << "CaloLCCoeffHelper::initDataFromFile() ->Error! Could not parse line '" << cLine << "' at p4." << std::endl;
132  std::cout << " dmArea.m_title" << theArea.getTitle() << std::endl;
133  return std::nullopt;
134  }
135  }
136  data->setCoeff(theArea.getOffset()+i_len, pars);
137  }
138  }
139  fin.close();
140 
141  return data;
142 }
143 
144 
145 
146 /* ****************************************************************************
147 
148 **************************************************************************** */
150 {
151  std::ofstream fout;
152  fout.open(fname);
153  PrintData(data, fout);
154  fout.close();
155 }
156 
157 
158 
159 /* ****************************************************************************
160 
161 **************************************************************************** */
163 {
164  boost::io::ios_base_all_saver ifs (fout);
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::setw(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::setw(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::fixed << std::setprecision(6) << std::setw(12) << (*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()) {
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 
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
make_hlt_rep.pars
pars
Definition: make_hlt_rep.py:90
CaloLocalHadCoeff::LocalHadDimension
Class defines binning for user dimension.
Definition: CaloLocalHadCoeff.h:47
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
CaloLCCoeffHelper::getAreaFromName
static const CaloLocalHadCoeff::LocalHadArea * getAreaFromName(const CaloLocalHadCoeff *m_coeff, const std::string &sname, int &m_indx)
Definition: CaloLCCoeffHelper.cxx:39
WriteBchToCool.comments
comments
Definition: WriteBchToCool.py:297
checkFileSG.line
line
Definition: checkFileSG.py:75
yodamerge_tmp.dim
dim
Definition: yodamerge_tmp.py:239
CaloLocalHadDefs.h
CaloLocalHadDefs::AREA_DMFIT
@ AREA_DMFIT
Definition: CaloLocalHadDefs.h:21
CaloLocalHadCoeff::LocalHadArea::getOffset
int getOffset() const
return area offset
Definition: CaloLocalHadCoeff.h:175
CaloLocalHadDefs::AREA_DMSMPW
@ AREA_DMSMPW
Definition: CaloLocalHadDefs.h:23
CaloLCCoeffHelper::InitDataFromFile
static std::optional< CaloLocalHadCoeff > InitDataFromFile(const char *fname)
Definition: CaloLCCoeffHelper.cxx:56
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
CaloLocalHadCoeff::LocalHadArea::getLength
int getLength() const
return area length
Definition: CaloLocalHadCoeff.h:177
CaloLCCoeffHelper::~CaloLCCoeffHelper
virtual ~CaloLCCoeffHelper()
x
#define x
CaloWeightInterpolator.h
CaloLocalHadCoeff::LocalHadCoeff
std::vector< float > LocalHadCoeff
Correction parameters for one general bin.
Definition: CaloLocalHadCoeff.h:220
CaloLocalHadCoeff::LocalHadArea::addDimension
void addDimension(LocalHadDimension &dim)
to add new dimension
Definition: CaloLocalHadCoeff.cxx:135
lumiFormat.i
int i
Definition: lumiFormat.py:85
dqt_zlumi_alleff_HIST.fout
fout
Definition: dqt_zlumi_alleff_HIST.py:59
fitman.bx
bx
Definition: fitman.py:410
CaloLocalHadCoeff
Hold binned correction data for local hadronic calibration procedure.
Definition: CaloLocalHadCoeff.h:41
CaloLCCoeffHelper::CaloLCCoeffHelper
CaloLCCoeffHelper()
find_tgc_unfilled_channelids.ip
ip
Definition: find_tgc_unfilled_channelids.py:3
CaloLCCoeffHelper.h
CaloLocalHadCoeff::LocalHadArea::getNdim
int getNdim() const
get number of dimensions
Definition: CaloLocalHadCoeff.h:179
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
CaloLocalHadCoeff::LocalHadArea::getNpars
int getNpars() const
return number of parameters
Definition: CaloLocalHadCoeff.h:173
MuonCalib::Legendre::coeff
constexpr double coeff(unsigned int l, unsigned int k)
Calculates the n-th coefficient of the legendre polynomial series.
Definition: LegendrePoly.h:73
python.AthDsoLogger.fname
string fname
Definition: AthDsoLogger.py:67
CaloLocalHadDefs::AREA_STD
@ AREA_STD
Definition: CaloLocalHadDefs.h:20
CaloLocalHadCoeff::LocalHadArea::getTitle
const std::string & getTitle() const
return name
Definition: CaloLocalHadCoeff.h:183
CaloCellTimeCorrFiller.filename
filename
Definition: CaloCellTimeCorrFiller.py:24
CaloLocalHadCoeff::LocalHadArea
Definition of correction area.
Definition: CaloLocalHadCoeff.h:145
compute_lumi.fin
fin
Definition: compute_lumi.py:19
CaloLCCoeffHelper::parse_dim
static std::optional< CaloLocalHadCoeff::LocalHadDimension > parse_dim(const std::string &sLine)
Definition: CaloLCCoeffHelper.cxx:341
area
double area(double R)
Definition: ConvertStaveServices.cxx:42
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15
CaloWeightInterpolator::getWeight
static double getWeight(std::vector< double > &w, std::vector< double > &x)
Definition: CaloWeightInterpolator.cxx:26
CaloLCCoeffHelper::PrintData
static void PrintData(CaloLocalHadCoeff *m_data, std::ostream &fout)
Definition: CaloLCCoeffHelper.cxx:162
CaloLocalHadDefs::AREA_DMLOOKUP
@ AREA_DMLOOKUP
Definition: CaloLocalHadDefs.h:22