ATLAS Offline Software
EfieldInterpolator.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3  */
4 
5 // PixelDigitization includes
6 #include "EfieldInterpolator.h"
7 
8 #include "TROOT.h"
9 #include "TH1.h"
10 #include "TF1.h"
11 #include "TVectorD.h"
12 #include <TFile.h>
13 #include "TTreeReader.h"
14 #include "TTreeReaderValue.h"
15 #include "TTreeReaderArray.h"
16 #include <TMath.h>
17 #include <TGraph.h>
18 #include <TPRegexp.h>
19 #include <TSystemDirectory.h>
20 #include <TSystemFile.h>
21 #include <TGraph2D.h>
22 #include <algorithm>
23 #include <TString.h>
24 #include <fstream>
25 
26 // Constructor with parameters:
27 EfieldInterpolator::EfieldInterpolator(const std::string& type, const std::string& name, const IInterface* parent) :
29  m_efieldOrigin(interspline) {}
30 
32 
34  ATH_MSG_DEBUG("Initializing " << name() << "...");
35  return StatusCode::SUCCESS;
36 }
37 
39  ATH_MSG_DEBUG("Finalizing " << name() << "...");
40  return StatusCode::SUCCESS;
41 }
42 
43 TVectorD CastStdVec(const std::vector<double>& vin) {
44  TVectorD tmp(vin.size());
45  //for(uint i = 0; i<vin.size(); i++ ){
46  uint index = 0;
47 
48  for (auto i : vin) {
49  tmp[index] = i;
50  index++;
51  }
52  return tmp;
53 }
54 
55 //Returns index at of std::vectorv where val is contained
56 int isContainedAt(const std::vector<double> & v, double val) {
57  for (uint i = 0; i < v.size(); i++) {
58  //Equality for decimals
59  if (v[i] - 0.00001 < val && val < v[i] + 0.00001) return i;
60  }
61  return -1;
62 }
63 
64 // Initialize indicating layer due to different geometry
65 // One instance interpolates only for fixed geometry (=pixel depth)
67  ATH_MSG_INFO("Create interpolator for layer " << layer);
68  if (layer > 0) {
69  //it's b layer
70  m_sensorDepth = 250;
71  } else {
72  //IBL
73  m_sensorDepth = 200;
74  }
75  ATH_MSG_INFO("EfieldInterpolator: Default ctor");
76 }
77 
78 StatusCode EfieldInterpolator::loadTCADlist(const std::string& TCADfileListToLoad) {
80  ATH_MSG_INFO("Load from list " << TCADfileListToLoad);
81  if (!initializeFromFile(TCADfileListToLoad)) {
82  ATH_MSG_WARNING("ERROR: Initialize failed looking for file " << TCADfileListToLoad);
83  //Check if given path links to directory:
84  if (!initializeFromDirectory(TCADfileListToLoad)) {
85  ;
86  return StatusCode::FAILURE;
87  }
88  }
89  ATH_MSG_INFO("Finished loading TCAD list");
90  return StatusCode::SUCCESS;
91 }
92 
93 bool EfieldInterpolator::initializeFromDirectory(const std::string& fpath) {
94  //similar to function loadTCADfiles()
95  //instead of reading file list, list files from directory fpath and create file listing information
96 
97  //retrieve fluence and bias voltage from file name (including path, directory names fluence value)
98  //skip files which do not dollow naming declaration
99 
100  //Create textfile for tmp storage
101  std::ofstream efieldscalib;
102  efieldscalib.open("listOfEfields.txt");
103  TPRegexp rvo("\\b-[0-9](\\w+)V\\b");
104  TPRegexp rfl("\\bfl([\\w.]+)e[0-9]{1,2}");
105  TString ext = ".dat";
106  TString sflu, svol, fullpath;
107  TSystemDirectory dir((TString)fpath, (TString)fpath);
108  TList* files = dir.GetListOfFiles();
109  if (files) {
110  TSystemFile* file;
111  TString fname;
112  TIter next(files);
113  while ((file = (TSystemFile*) next())) {
114  fname = file->GetName();
115  if (fname.BeginsWith("fl") && file->IsDirectory()) {
116  TString deeppath = fpath;
117  deeppath += fname;
118  deeppath += "/reference/";
119  TSystemDirectory deepdir(deeppath, deeppath);
120  TList* deepfiles = deepdir.GetListOfFiles();
121  if (deepfiles) {
122  TSystemFile* deepfile;
123  TString deepfname;
124  TIter deepnext(deepfiles);
125  while ((deepfile = (TSystemFile*) deepnext())) {
126  deepfname = deepfile->GetName();
127  if (!deepfile->IsDirectory() && deepfname.EndsWith(ext)) {
128  svol = deepfname(rvo);
129  svol.ReplaceAll("-", "");
130  svol.ReplaceAll("V", "");
131  sflu = deeppath(rfl);
132  sflu.ReplaceAll("fl", "");
133  fullpath = deeppath;
134  fullpath += deepfname;
135  if (!deepfname.Contains("pruned")) {
136  if (!sflu.IsFloat()) {
137  ATH_MSG_INFO("EfieldInterpolator load from directory - could not resolve fluence from " << fullpath);
138  continue;
139  }
140  if (!svol.IsFloat()) {
141  ATH_MSG_INFO("EfieldInterpolator load from directory - could not resolve voltage from " << fullpath);
142  continue;
143  }
144  } else {
145  ATH_MSG_INFO("Skip pruned files: " << fullpath);
146  continue;
147  }
148  efieldscalib << fullpath << " " << sflu << " " << svol << std::endl;
149  }
150  }
151  }
152  }
153  }
154  }
155  efieldscalib.close();
156  bool success = initializeFromFile("listOfEfields.txt");
157  if (success) ATH_MSG_INFO("Initialized from directory");
158  return success;
159 }
160 
161 // Load maps into TTree for faster processing
162 bool EfieldInterpolator::initializeFromFile(const std::string& finpath) {
163  TString fpath = finpath;
164 
165  m_initialized = false;
166  TString fTCAD = "";
167  if (fpath.EndsWith(".txt")) {
168  //File list path, fluence and bias voltage of TCAD simulation as plain text
169  fTCAD = loadTCADfiles(fpath.Data());
170  ATH_MSG_INFO("Loaded file " << fpath << " - all maps accumulated in " << fTCAD);
172  ATH_MSG_INFO("created interpolation tree ");
173  m_initialized = true;
174  ATH_MSG_INFO("Loaded from .txt file");
175  } else {
176  if (fpath.EndsWith("toTTree.root")) {
177  //File list TCAD efield maps as leaves
179  m_initialized = true;
180  } else {
181  if (fpath.EndsWith(".root")) {
182  //File list is already transformed to tree
183  m_fInter = fpath;
184  m_initialized = true;
185  }
186  }
187  }
188  ATH_MSG_INFO("Interpolation has been initialized from file " << m_fInter << " - successful " << m_initialized);
189  return m_initialized;
190 }
191 
192 // Check if requested values out of range of given TCAD samples
193 void EfieldInterpolator::reliabilityCheck(double aimFluence, const std::vector<double>& fluences, double aimVoltage,
194  const std::vector<double>& voltages) {
195  bool tooLowVolt = true;
196  bool tooHighVolt = true;
197 
198  for (const auto iv : voltages) {
199  if (aimVoltage < iv) tooHighVolt = false;
200  if (aimVoltage > iv) tooLowVolt = false;
201  }
202  bool tooLowFlu = true;
203  bool tooHighFlu = true;
204  for (double fluence : fluences) {
205  if (aimFluence < fluence) tooHighFlu = false;
206  if (aimFluence > fluence) tooLowFlu = false;
207  }
208  if (tooLowFlu) ATH_MSG_WARNING(
209  "WARNING: The fluence value you specified (" << aimFluence << ") is too low to be reliably interpolated!");
210  if (tooLowVolt) ATH_MSG_WARNING(
211  "WARNING: The voltage value you specified (" << aimVoltage << ") is too low to be reliably interpolated!");
212  if (tooHighFlu) ATH_MSG_WARNING(
213  "WARNING: The fluence value you specified (" << aimFluence << ") is too high to be reliably interpolated!");
214  if (tooHighVolt) ATH_MSG_WARNING("WARNING: The voltage value you specified (" << aimVoltage << ") is too high to be reliably interpolated!");
215 
216  // Results from Closure Test
217  // TCAD files save 20 for 20e14 neq/cm2
218  if (12.2 < aimFluence || aimFluence < 1.) ATH_MSG_WARNING(" WARNING: The fluence value you specified (" << aimFluence << ") is outside the range within it could be reliably interpolated!"); //Based on closure test June 2018 - max fluences available: ... 10 12 15 20
219  if (1010. < aimVoltage || aimVoltage < 79.) ATH_MSG_WARNING(" WARNING: The voltage value you specified (" << aimVoltage << ") is outside the range within it could be reliably interpolated!"); }
220 
221 void EfieldInterpolator::scaleIntegralTo(TH1* hin, double aimInt, int first, int last) {
222  hin->Scale(aimInt / (float) hin->Integral(first, last));
223 }
224 
226  if (x1 == 0.) return 0.;
227 
228  return((x1 - x2) / x1);
229 }
230 
231 //Use as definition for distance in Fluence/Voltage space
232 double EfieldInterpolator::relativeDistance(double x1, double y1, double x2, double y2) {
234 }
235 
236 double EfieldInterpolator::extrapolateLinear(double x1, double y1, double x2, double y2, double xaim) {
237  // follow linear extrapolation: y=mx+b
238  double delx = x2 - x1;
239 
240  if (delx == 0) return 0.; // slope not defined
241 
242  double dely = y2 - y1;
243  double b = y1 - (dely / delx) * x1;
244  return(xaim * (dely / delx) + b);
245 }
246 
247 // Return E field which is directly read from TCAD simulation
248 // and fill edges values
249 TH1D* EfieldInterpolator::loadEfieldFromDat(const std::string& fname, bool fillEdges) {
250  TH1D* hefieldz = new TH1D("hefieldz", "hefieldz", m_sensorDepth + 1, -0.5, m_sensorDepth + 0.5);
251 
252  std::ifstream in;
253  in.open(fname);
254  TString z, e;
255  int nlines = 0;
256  ATH_MSG_INFO("Load E field from " << fname);
257  while (1) {
258  in >> z >> e;
259  if (!in.good()) break;
260  if (nlines < 3) printf("e=%s=%f, z=%s=%f \n", e.Data(), e.Atof(), z.Data(), z.Atof());
261  nlines++;
262  hefieldz->Fill(z.Atof(), e.Atof());
263  }
264  in.close();
265  if (fillEdges) EfieldInterpolator::fillEdgeValues(hefieldz);
266  return hefieldz;
267 }
268 
269 // original TCAD simulations given as txt (.dat) files (zVal efieldVal)
270 const std::string EfieldInterpolator::loadTCADfiles(const std::string& targetList) {
271  bool isIBL = true;
272  TString tl = targetList;
273  TString fName = targetList;
274 
275  fName.ReplaceAll(".txt", "_toTTree.root");
276  fName = fName.Remove(0, fName.Last('/') + 1); //Remove prepending path and store in run directory
277  TFile* bufferTCADtree = new TFile(fName.Data(), "RECREATE");
278 
279  if (tl.Length() < 1) {
280  tl = "list_TCAD_efield_maps.txt";
281  ATH_MSG_WARNING("No List to load! Set default: " << tl.Data());
282  }
283  std::ifstream in;
284  TTree* tcadtree = new TTree("tcad", "All TCAD E field simulations stored as individual events in tree");
285  double voltage = -1.;
286  double fluence = -1.;
287  std::vector<double> efield;
288  std::vector<Int_t> pixeldepth;
289  tcadtree->Branch("voltage", &voltage, "voltage/D");
290  tcadtree->Branch("fluence", &fluence, "fluence/D");
291  tcadtree->Branch("efield", &efield);
292  tcadtree->Branch("pixeldepth", &pixeldepth);
293  //Get vetcor of {filename, fluence, bias voltage}
294  std::vector<std::vector<TString> > infile = list_files(tl);
295  TString z, e;
296  TString tmp = "";
297  for (uint ifile = 0; ifile < infile.size(); ifile++) {
298  tmp = infile.at(ifile).at(0);
299  in.open(infile.at(ifile).at(0));
300  // Number format eg 10e14 also 1.2e13
301  //fluence = (infile.at(ifile).at(1).ReplaceAll("e14","")).Atof();
302  fluence = (infile.at(ifile).at(1)).Atof();
303  fluence = fluence * 1e-14; //choose fluence e14 as default unit
304  voltage = infile.at(ifile).at(2).Atof();
305  Int_t nlines = 0;
306  efield.clear();
307  pixeldepth.clear();
308  while (1) {
309  in >> z >> e;
310  if (!in.good()) {
311  ATH_MSG_DEBUG("Break for file No. " << ifile << ": " << infile.at(ifile).at(0) << " . After " << nlines << " steps");
312  break;
313  }
314  ATH_MSG_DEBUG("Reading input line: fluence=" << (infile.at(ifile).at(1)).Data() << fluence << " voltage=" << voltage << " e=" << e.Atof() << "=" << e.Data() << ", z=" << (int) z.Atof() << "=" << z.Data() << " in file = " << ifile);
315  nlines++;
316  efield.push_back(e.Atof());
317  pixeldepth.push_back((int) z.Atof());
318  if (z.Atof() > 200) isIBL = false; // Pixel depth to huge to be IBL
319  }
320  bufferTCADtree->cd();
321  tcadtree->Fill();
322  in.close();
323  }
324  if (!isIBL) {
325  ATH_MSG_INFO("Pixel depth read from file too big for IBL. Set to B layer, depth = 250um\n");
326  m_sensorDepth = 250;
327  }
328  bufferTCADtree->cd();
329  tcadtree->Write();
330  bufferTCADtree->Close();
331  return fName.Data();
332 }
333 
334 std::vector<std::vector<TString> > EfieldInterpolator::list_files(const TString& fileList_TCADsamples) {
335  std::vector<std::vector<TString> > filelist;
336  TString tmpname = "";
337  TString tmpfluence = "";
338  TString tmpvolt = "";
339  std::vector<TString> vstr;
340  std::ifstream in;
341  ATH_MSG_DEBUG("Try to open: " << fileList_TCADsamples.Data());
342  in.open(fileList_TCADsamples);
343  while (1) {
344  in >> tmpname >> tmpfluence >> tmpvolt;
345  if (!in.good()) break;
346  if (tmpname.BeginsWith('#')) continue;
347  if (tmpname.EndsWith(".dat")) {
348  vstr.push_back(tmpname);
349  vstr.push_back(tmpfluence);
350  vstr.push_back(tmpvolt);
351  filelist.push_back(vstr);
352  ATH_MSG_DEBUG("Found and load:" << tmpfluence.Atof() << " neq/cm2 " << tmpvolt.Atof() << "V - " << tmpname.Data());
353  vstr.clear();
354  } else {
355  ATH_MSG_WARNING("Wrong extension: " << tmpname.Data() << " -- check input ");
356  }
357  }
358  in.close();
359  return filelist;
360 }
361 
362 // Return path to file containing tree
363 // Final tree is restructured providing e field value as function of fluence, voltage and pixeldepth
364 const std::string EfieldInterpolator::createInterpolationFromTCADtree(const std::string& fTCAD) {
365  TString tmpfinter = fTCAD;
366 
367  tmpfinter.ReplaceAll("toTTree", "toInterpolationTTree");
368  TFile* faim = new TFile(tmpfinter, "Recreate");
369  TFile* ftreeTCAD = new TFile(fTCAD.c_str());
370  TTreeReader myReader("tcad", ftreeTCAD);
371  TTreeReaderValue<double> involtage(myReader, "voltage");
372  TTreeReaderValue<double> influence(myReader, "fluence");
373  TTreeReaderValue<std::vector<double> > inefield(myReader, "efield");
374  TTreeReaderValue<std::vector<int> > inpixeldepth(myReader, "pixeldepth");
375  // Get Data from TCAD tree
376  // Loop tree once to initialize values
377  // Finding which values for fluence and bias voltage exist
378  // do not hardcode values to maintain compatibility with new simulations available
379  std::vector<double> allFluences; // serves as x-axis
380  std::vector<double> allVoltages; // serves as y-axis
381  std::vector<double> allEfield;
382  int ne = 0;
383  double tmpflu, tmpvol;
384  while (myReader.Next()) {
385  tmpflu = *influence;
386  tmpvol = *involtage;
387  //Check if (double) value of fluence and bias voltage is already saved: if not save
388  if (std::find_if(allFluences.begin(), allFluences.end(), [&tmpflu](const double& b) {
389  return(std::abs(tmpflu - b) < 1E-6);
390  }) == allFluences.end()) allFluences.push_back(tmpflu);
391  if (std::find_if(allVoltages.begin(), allVoltages.end(), [&tmpvol](const double& b) {
392  return(std::abs(tmpvol - b) < 1E-6);
393  }) == allVoltages.end()) allVoltages.push_back(tmpvol);
394  ne++;
395  }
396  //put into ascending order
397  std::sort(allFluences.begin(), allFluences.end());
398  std::sort(allVoltages.begin(), allVoltages.end());
399  for (double & allFluence : allFluences) ATH_MSG_DEBUG("fluences recorded: " << allFluence);
400  for (double & allVoltage : allVoltages) ATH_MSG_DEBUG("voltages recorded: " << allVoltage);
401  std::vector<double> tmpef;
402  myReader.Restart(); //available from ROOT 6.10.
403  //Exclude TCAD efield values close to sensor edge
404  int leftEdge = 3; //unify maps - different startting points from z=1 to z=2 and z=3. Simulation not reliable at edges,
405  // skip first and last
406  int rightEdge = m_sensorDepth - 2;
407  std::vector<int> tmpz;
408  int nz = rightEdge - leftEdge;
409  // Temporary saving to avoid nesting tree loops
410  // ie read all z values at once -> add to each branch-param dimension for z
411  std::vector<double> zpixeldepth(nz, -1);
412  std::vector<std::vector<double> > zfluence(nz, std::vector<double>(ne, -1));
413  std::vector<std::vector<double> > zvoltage(nz, std::vector<double>(ne, -1));
414  std::vector<std::vector<double> > zefield(nz, std::vector<double>(ne, -1));
415  std::vector<std::vector<std::vector<double> > > zefieldmap(nz, std::vector<std::vector<double> >(allFluences.size(), std::vector<double>(allVoltages.size(), -1)));
416  int iev = 0;
417  ATH_MSG_INFO("Access TTreeReader second time\n");
418 
419  while (myReader.Next()) {
420  tmpz = *inpixeldepth; //Pixeldepth of current TCAD map
421  ATH_MSG_DEBUG("Number of available z values = " << tmpz.size());
422  if (tmpz.at(0) > leftEdge) ATH_MSG_WARNING("Map starting from high pixeldepth = " << tmpz.at(0) << ". Might trouble readout.");
423  for (int iz = leftEdge; iz < rightEdge; iz++) {
424  int index = 0;
425  //Safety check:
426  //files starting from z=1, z=2 or z=3
427  //determine correct index to match sensor depth
428  ATH_MSG_DEBUG("Access tmpz \n");
429  ATH_MSG_DEBUG("Adapt index shift \n");
430  while ((tmpz.at(index) != iz) && (index < nz)) {
431  ATH_MSG_DEBUG("Adapt possible index shift for missing edge values: pixeldepth tree = " << nz << " current index = " << index);
432  index++;
433  }
434  if (iz % 2 == 0) ATH_MSG_DEBUG("Index " << index << " - iev " << iev << " - iz " << iz);
435  tmpflu = *influence;
436  tmpvol = *involtage;
437  tmpef = *inefield;
438  zfluence.at(iz - leftEdge).at(iev) = tmpflu; // assign value to certain pixeldepth(z)
439  zvoltage.at(iz - leftEdge).at(iev) = tmpvol;
440  zefield.at(iz - leftEdge).at(iev) = tmpef.at(index);
441  ((zefieldmap.at(iz - leftEdge)).at(isContainedAt(allFluences, tmpflu))).at(isContainedAt(allVoltages, tmpvol)) = tmpef.at(index);
442  ATH_MSG_DEBUG("Event #" << iev << "-z=" << iz << ": fluence =" << tmpflu << " voltage=" << tmpvol << ", E=" << tmpef.at(index));
443  }
444  iev++;
445  }
446  ATH_MSG_DEBUG("# Start filling interpolation tree \n");
447  //Filling the interpolation tree
448  faim->cd();
449  TTree* tz_tmp = new TTree("tz", "All TCAD E field simulations stored splitted by pixel depth");
450  double pixeldepth = -1.;
451  std::vector<double> fluence;
452  std::vector<double> voltage;
453  std::vector<double> xfluence;
454  std::vector<double> yvoltage;
455  std::vector<double> efield;
456  std::vector<std::vector<double> > efieldfluvol;
457 
458  tz_tmp->Branch("pixeldepth", &pixeldepth);
459  tz_tmp->Branch("voltage", &voltage);
460  tz_tmp->Branch("fluence", &fluence);
461  tz_tmp->Branch("yvoltage", &yvoltage);
462  tz_tmp->Branch("xfluence", &xfluence);
463  tz_tmp->Branch("efield", &efield);
464  tz_tmp->Branch("efieldfluvol", &efieldfluvol);
465  for (int iz = leftEdge; iz < rightEdge; iz++) {
466  pixeldepth = iz;
467  fluence = zfluence.at(iz - leftEdge);
468  voltage = zvoltage.at(iz - leftEdge);
469  efield = zefield.at(iz - leftEdge);
470  efieldfluvol = zefieldmap.at(iz - leftEdge);
471  xfluence = allFluences;
472  yvoltage = allVoltages;
473  ATH_MSG_DEBUG("Fill tree for z =" << iz << " pd=" << pixeldepth);
474  faim->cd();
475  tz_tmp->Fill();
476  }
477 
478  //Save new Interpolation tree
479  faim->cd();
480  tz_tmp->Write();
481  faim->Close();
482  m_fInter = tmpfinter.Data();
483  return m_fInter;
484 }
485 
486 // Retrieve fluence values corresponding to a fixed voltage or viceversa if regular order == false
487 int EfieldInterpolator::fillXYvectors(std::vector<double> vLoop, int ifix, const std::vector<std::vector<double> > & v2vsv1, std::vector<double>& xx, std::vector<double>& yy, bool regularOrder) {
488  yy.clear();
489  xx.clear();
490  int nfills = 0;
491  if (regularOrder) {
492  for (uint ie = 0; ie < v2vsv1.size(); ie++) {
493  double ef = v2vsv1.at(ie).at(ifix); // different fluences for voltage ifix
494  if (ef > 0) {
495  yy.push_back(ef);
496  xx.push_back(vLoop.at(ie));
497  nfills++;
498  } else {
499  ATH_MSG_DEBUG("E field value not available for Phi=" << vLoop.at(ie) << " index Vol= " << ifix);
500  //Values not ordered in a regular fluence-bias voltage grid
501  }
502  }
503  } else {
504  for (uint ie = 0; ie < v2vsv1.at(0).size(); ie++) {
505  double ef = v2vsv1.at(ifix).at(ie);
506  if (ef > 0) {
507  yy.push_back(ef);
508  xx.push_back(vLoop.at(ie));
509  nfills++;
510  } else {
511  ATH_MSG_DEBUG("E field value not available for Phi=" << vLoop.at(ifix) << " U=" << vLoop.at(ie));
512  //Values not ordered in a regular fluence-bias voltage grid
513  }
514  }
515  }
516 
517  return nfills;
518 }
519 
520 //Final computation of efield according to method specified
521 double EfieldInterpolator::estimateEfieldLinear(double aimVoltage) {
522  return aimVoltage / (float) m_efieldProfile->GetNbinsX() * 10000; //10^4 for unit conversion
523 }
524 
525 //Interpolate following inverse distance weighted Interpolation
526 double EfieldInterpolator::estimateEfieldInvDistance(const std::vector<double> & vvol, const std::vector<double> & vflu, const std::vector<std::vector<double> > & vfluvvol, double aimFlu, double aimVol, double measure) {
527  ATH_MSG_WARNING("Use interpolation method _Inverse distance weighted_ - guarantees positive E field but no reliable interpolation");
528  double weight = 0.;
529  double meanEf = 0.;
530  double distance = 1.;
531  double efEntry = 0.;
532  //Loop available efield values for fluence/voltage - take weighted mean
533  for (uint ivol = 0; ivol < vvol.size(); ivol++) {
534  for (uint iflu = 0; iflu < vflu.size(); iflu++) {
535  efEntry = vfluvvol.at(iflu).at(ivol);
536  if (efEntry > 0.) { //Otherwise (-1), TCAD not available
537  distance = relativeDistance(aimVol, aimFlu, vvol.at(ivol), vflu.at(iflu));
538  if (distance < 0.00001) return efEntry;//fluence and voltage almost correpsond to available TCAD simulation
539 
540  meanEf += efEntry * TMath::Power((1. / distance), measure);
541  weight += TMath::Power((1. / distance), measure);
542  }
543  }
544  }
545  return(meanEf / weight);
546 }
547 
548 // Interpolate using cubic splines
549 // E efield values given as function of fluence and bias voltage (vvol, vflu)
550 // interpolate to value for aimFluence and aimVoltage
551 double EfieldInterpolator::estimateEfield(std::vector<double> vvol, const std::vector<double>& vflu, const std::vector<std::vector<double> >& vfluvvol, double aimFlu, double aimVol, const std::string& prepend, bool debug) {
552  ATH_MSG_DEBUG("Estimating efield");
553  std::vector<double> evol; // e field values for fixed voltages inter- or extrapolated to fluence of interest
554  std::vector<double> vvolWoEp; // fixed voltages values for which no extrapolation is used to obatin E field in
555  // between fluences
556  std::vector<double> evolWoEp;
557  //Loop the voltages
558  for (uint ifix = 0; ifix < vvol.size(); ifix++) {
559  std::vector<double> vx;// = new std::vector<double> ;
560  std::vector<double> vy;// = new std::vector<double>;
561  double efflu = -1.;
562  int availableTCADpoints = fillXYvectors(vflu, ifix, vfluvvol, vx, vy);
563  ATH_MSG_DEBUG("Number of available TCAD points for voltage " << vvol.at(ifix) << ": " << availableTCADpoints);
564  TString name = "FluenceEfield_";
565  name += ifix;
566  name += "FixVol";
567  name += TString::Format("%.0f", vvol.at(ifix));
568  name += "-aimFlu";
569  name += TString::Format("%.1f", aimFlu);
570  name += "-aimVol";
571  name += TString::Format("%.0f", aimVol);
572 
573  TGraph* tmpgr = new TGraph(CastStdVec(vx), CastStdVec(vy));
574  tmpgr->SetTitle(name.Data());
575  if (isInterpolation(vx, aimFlu)) {
576  name += "_ip";
577  } else {
578  name += "_ep";
579  }
580  if (m_useSpline) {
581  efflu = tmpgr->Eval(aimFlu, nullptr, "S");
582  } else {
583  efflu = tmpgr->Eval(aimFlu); //linear extrapolation
584  }
585  if (debug) {
586  TString aimFile = m_fInter;
587  aimFile.ReplaceAll(".root", "_debug.root");
588  aimFile.ReplaceAll(".root", prepend);
589  aimFile += name;
590  aimFile += ".root";
591  tmpgr->SaveAs(aimFile);
592  }
593  if (isInterpolation(vx, aimFlu)) {
594  // try without extrapolation: skip extrapolated values
595  vvolWoEp.push_back(vvol.at(ifix));
596  evolWoEp.push_back(efflu);
597  }
598 
599  delete tmpgr;
600  evol.push_back(efflu); //includes extrapolated values
601  }//end loop voltages
602 
603  //Check for debugging distribution of available E field values in fluence and
604  if (debug) {
605  saveTGraph(vvol, vflu, vfluvvol, aimFlu, aimVol, prepend);
606  }
607  // if possible to reach voltage of interest without any extrapolation in previous step, prefer this
608  if (isInterpolation(vvolWoEp, aimVol) && vvolWoEp.size() > 1) {
609  vvol = vvolWoEp;
610  evol = evolWoEp;
611  } else {
612  ATH_MSG_WARNING("E field created on extrapolation. Please check if reasonable!");
613  }
614 
615  TString name = "VoltageEfield";
616  name += "-aimFlu";
617  name += TString::Format("%.1f", aimFlu);
618  name += "-aimVol";
619  name += TString::Format("%.0f", aimVol);
620  double aimEf = -1;
621  TGraph* tmpgr = new TGraph(CastStdVec(vvol), CastStdVec(evol));
622  tmpgr->SetTitle(name.Data());
623  if (isInterpolation(vvol, aimVol)) {
624  name += "_ip";
625  } else {
626  name += "_ep";
627  }
628  if (m_useSpline) {
629  aimEf = tmpgr->Eval(aimVol, nullptr, "S");
630  } else {
631  aimEf = tmpgr->Eval(aimVol); //linear extrapolation
632  }
633  if (debug) {
634  TString aimFile = m_fInter;
635  aimFile.ReplaceAll(".root", "_debug.root");
636  aimFile.ReplaceAll(".root", prepend);
637  aimFile += name;
638  aimFile += ".root";
639  tmpgr->SaveAs(aimFile);
640  }
641  delete tmpgr;
642  return aimEf;
643 }
644 
645 //Save all E field values as function of fluence and bias voltage for debugging
646 void EfieldInterpolator::saveTGraph(std::vector<double> vvol, std::vector<double> vflu, std::vector<std::vector<double> > vfluvvol, double aimFlu, double aimVol, const std::string& prepend, bool skipNegative) {
647  TString name = "VoltageEfield";
648 
649  name += "-aimFlu";
650  name += TString::Format("%.1f", aimFlu);
651  name += "-aimVol";
652  name += TString::Format("%.0f", aimVol);
653  TGraph2D* tmpgr = new TGraph2D();
654  tmpgr->GetYaxis()->SetTitle("voltage");
655  tmpgr->GetXaxis()->SetTitle("fluence");
656  tmpgr->SetTitle(name.Data());
657  ATH_MSG_DEBUG("E field values: " << vfluvvol.size() << " x " << vfluvvol.at(0).size() << ", flu(x)" << vflu.size() << ", vol(y)" << vvol.size());
658  int npoint = 0;
659  for (uint ix = 0; ix < vfluvvol.size(); ix++) {
660  for (uint iy = 0; iy < vfluvvol.at(ix).size(); iy++) {
661  printf("Set point %i, %f,%f,%f\n", npoint, vflu.at(ix), vvol.at(iy), vfluvvol.at(ix).at(iy));
662  if (vfluvvol.at(ix).at(iy) < 0) {
663  if (!skipNegative) tmpgr->SetPoint(npoint, vflu.at(ix), vvol.at(iy), -1);
664  } else {
665  tmpgr->SetPoint(npoint, vflu.at(ix), vvol.at(iy), vfluvvol.at(ix).at(iy));
666  }
667  npoint++;
668  }
669  }
670  TString aimFile = m_fInter;
671  aimFile.ReplaceAll(".root", "_debugAvailableEfieldVals.root");
672  aimFile.ReplaceAll(".root", prepend);
673  aimFile += name;
674  aimFile += ".root";
675  tmpgr->SaveAs(aimFile);
676 }
677 
678 TH1D* EfieldInterpolator::createEfieldProfile(double aimFluence, double aimVoltage) {
679  if (!m_initialized) {
680  ATH_MSG_WARNING("ERROR: EfieldInterpolator not properly intialized from " << m_fInter);
681  return nullptr;
682  }
683  if (aimFluence > 1e12) aimFluence = aimFluence / 1e14; //adapt units - TCAD files save 20 for 20e14 neq/cm2
684  TString title = "hefieldz";
685  TString info = "#Phi=";
686  info += TString::Format("%.2f", aimFluence);
687  info += "-U=";
688  info += TString::Format("%.0f", aimVoltage);
689  info += ";Pixeldepth z [#mum]";
690  info += ";E [V/cm]";
692  double pixeldepth;
693  std::vector<double> xfluence;
694  std::vector<double> yvoltage;
695  std::vector<std::vector<double> > efieldfluvol;
696  TFile* ftreeInterpolation = TFile::Open(m_fInter.c_str());
697  TTreeReader myReader("tz", ftreeInterpolation);
698  TTreeReaderValue<std::vector<double> > involtage(myReader, "yvoltage");
699  TTreeReaderValue<std::vector<double> > influence(myReader, "xfluence");
700  TTreeReaderValue<std::vector<std::vector<double> > > inefield(myReader, "efieldfluvol");
701  TTreeReaderValue<double> inpixeldepth(myReader, "pixeldepth");
702  int ientry = 0;
703  while (myReader.Next()) {
704  ATH_MSG_DEBUG("TTree entry: " << ientry);
705  pixeldepth = *inpixeldepth;
706  xfluence = *influence;
707  yvoltage = *involtage;
708  efieldfluvol = *inefield;
709  // Check if interpolation is reliable based on given TCAD samples
710  if (ientry < 2) {
711  reliabilityCheck(aimFluence, xfluence, aimVoltage, yvoltage);
712  }
713  double aimEf = 0.;
714  switch (m_efieldOrigin) {
715  case interspline: aimEf = estimateEfield(yvoltage, xfluence, efieldfluvol, aimFluence, aimVoltage);
716  break;
717 
718  case interinvdist: aimEf = estimateEfieldInvDistance(yvoltage, xfluence, efieldfluvol, aimFluence, aimVoltage);
719  break;
720 
721  case linearField: m_useSpline = false;
722  aimEf = estimateEfield(yvoltage, xfluence, efieldfluvol, aimFluence, aimVoltage);
723  break;
724 
725  case TCAD: aimEf = estimateEfieldLinear(aimVoltage);
726  if (aimEf < 0.) ATH_MSG_ERROR("TCAD E field negative at" << pixeldepth << " !");
727  break;
728  }
729 
730  if (aimEf < 0.) {
731  if (m_useSpline) {
732  TString debugName = "negativeSplineZ";
733  debugName += TString::Format("%.0f", pixeldepth);
734  aimEf = estimateEfield(yvoltage, xfluence, efieldfluvol, aimFluence, aimVoltage, debugName.Data(), true);
735  ATH_MSG_INFO("InterpolatorMessage: linearly interpolated e=" << aimEf << ", z=" << pixeldepth << " Phi=," << aimFluence << " U=" << aimVoltage);
736  m_useSpline = false;
737  m_efieldOrigin = linearField; // not as good as interpolation
738  } else {
739  TString debugName = "negativeLinearZ";
740  debugName += TString::Format("%.0f", pixeldepth);
741  aimEf = estimateEfield(yvoltage, xfluence, efieldfluvol, aimFluence, aimVoltage, debugName.Data(), true);
742  ATH_MSG_ERROR("InterpolatorMessage: spline and linear interpolation failed => InvDistWeighhted e=" << aimEf << ", z=" << pixeldepth << " Phi=," << aimFluence << " U=" << aimVoltage);
743  m_efieldOrigin = interinvdist; // not as good as interpolation (linear or spline) but guaranteed to be positive
744  }
745 
746  myReader.Restart();
747  }
748  m_efieldProfile->SetBinContent(m_efieldProfile->FindBin(pixeldepth), aimEf);
749  ientry++;
750  }
751  ftreeInterpolation->Close();
752  //Check edge values
753  ATH_MSG_DEBUG("Fill edges");
755  scaleIntegralTo(m_efieldProfile, aimVoltage * 10000, 2, m_sensorDepth); //exclude first and last bin
756  TString newtitle = m_efieldProfile->GetTitle();
757  switch (m_efieldOrigin) {
758  case interspline: newtitle += " spline";
759  break;
760 
761  case interinvdist: newtitle += " inverse distance";
762  break;
763 
764  case linearField: newtitle += " linear";
765  break;
766 
767  case TCAD: newtitle += " TCAD";
768  break;
769  }
770 
771  m_efieldProfile->SetTitle(newtitle.Data());
772  ATH_MSG_DEBUG("Created Efield");
773  m_efieldProfile->SetLineWidth(3);
774  m_efieldProfile->SetLineStyle(2);
775  m_efieldProfile->SetLineColor(4);
776  m_efieldProfile->SetStats(0);
777  return m_efieldProfile;
778 }
779 
780 //First few and last few bins of TCAD maps not filled due to edge effect - fill with extrapolation
782  int nBins = hin->GetNbinsX();
783 
784  //Check first and last bins if filled
785  // if not extrapolate linearly from two neighbouring values
786  // empty (or zero) e field values cause unphysical behaviour in ATHENA/Allpix
787  for (int i = 5; i > 0; i--) {
788  //first bins
789  float curval = hin->GetBinContent(i);
790  float binii = hin->GetBinContent(i + 1);
791  float biniii = hin->GetBinContent(i + 2);
792  float bini = hin->GetBinContent(i);
793  if ((bini < 0.01 && binii > 0.01 && biniii > 0.01) || ((biniii - binii) / (float) binii * (binii - bini) / (float) binii < -0.2)) {//either neighbour filled and bin negative, or edge detected, i.e. slope changes sign and relatively larger than middle entry
794  bini = extrapolateLinear(i + 1, binii, i + 2, biniii, i);
795  if (bini > 0) {
796  hin->SetBinContent(i, bini);
797  } else {
798  ATH_MSG_WARNING("Could not correct bin " << i << " for zero or edge ");
799  if (curval <= 0.) hin->SetBinContent(i, 1.); //avoid negative Efield
800  }
801  } else {
802  ATH_MSG_INFO("No need to fill edge bin: " << i);
803  }
804  //Last bins = right hand edge
805  curval = hin->GetBinContent(nBins + 1 - i);
806  binii = hin->GetBinContent(nBins + 1 - i - 1);
807  biniii = hin->GetBinContent(nBins + 1 - i - 2);
808  bini = hin->GetBinContent(nBins + 1 - i);
809  if ((bini < 0.01 && binii > 0.01 && biniii > 0.01) || ((biniii - binii) / (float) binii * (binii - bini) / (float) binii < -0.2)) {//left neighbour filled and bin below negative or slope changes sign and magnitude
810  bini = extrapolateLinear(nBins + 1 - i - 2, hin->GetBinContent(nBins + 1 - i - 2), nBins + 1 - i - 1, hin->GetBinContent(nBins + 1 - i - 1), nBins + 1 - i);
811  if (bini > 0.) {
812  hin->SetBinContent(nBins + 1 - i, bini);
813  } else {
814  ATH_MSG_WARNING("Could not correct bin" << nBins + 1 - i << " for zero or edge ");
815  if (curval <= 0.) hin->SetBinContent(nBins + 1 - i, 1.); //avoid negative Efield
816  }
817  } else {
818  ATH_MSG_INFO("No need to fill edge bin: " << (nBins - i));
819  }
820  }
821 }
822 
823 // Main function to be called to create E field of interest
824 
825 TH1D* EfieldInterpolator::getEfield(double aimFluence, double aimVoltage) {
826  if (m_initialized) {
827  m_efieldProfile = createEfieldProfile(aimFluence, aimVoltage);
828  } else {
829  ATH_MSG_WARNING("EfieldInterpolator not initialized! Not able to produce E field.");
830  }
831  return m_efieldProfile;
832 }
grepfile.info
info
Definition: grepfile.py:38
TestSUSYToolsAlg.ifile
ifile
Definition: TestSUSYToolsAlg.py:92
EfieldInterpolator::scaleIntegralTo
static void scaleIntegralTo(TH1 *hin, double aimInt, int first=1, int last=-1)
Definition: EfieldInterpolator.cxx:221
TCAD
@ TCAD
Definition: EfieldInterpolator.h:29
EfieldInterpolator.h
Instances of this class create a map (TH1D) describing the electric field profile along the pixeldept...
plotBeamSpotCompare.x1
x1
Definition: plotBeamSpotCompare.py:216
EfieldInterpolator::finalize
virtual StatusCode finalize() override
Definition: EfieldInterpolator.cxx:38
run.infile
string infile
Definition: run.py:13
EfieldInterpolator::list_files
std::vector< std::vector< TString > > list_files(const TString &fileList_TCADsamples)
Definition: EfieldInterpolator.cxx:334
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
EfieldInterpolator::m_efieldOrigin
interpolationMethod m_efieldOrigin
Definition: EfieldInterpolator.h:81
interinvdist
@ interinvdist
Definition: EfieldInterpolator.h:31
PlotCalibFromCool.yy
yy
Definition: PlotCalibFromCool.py:714
EfieldInterpolator::EfieldInterpolator
EfieldInterpolator(const std::string &type, const std::string &name, const IInterface *parent)
Definition: EfieldInterpolator.cxx:27
EfieldInterpolator::loadTCADfiles
const std::string loadTCADfiles(const std::string &targetList="")
Definition: EfieldInterpolator.cxx:270
rootconvert.fName
string fName
Definition: rootconvert.py:5
EfieldInterpolator::estimateEfieldInvDistance
double estimateEfieldInvDistance(const std::vector< double > &vvol, const std::vector< double > &vflu, const std::vector< std::vector< double > > &vfluvvol, double aimFlu, double aimVol, double measure=1.)
Definition: EfieldInterpolator.cxx:526
index
Definition: index.py:1
EfieldInterpolator::fillXYvectors
int fillXYvectors(std::vector< double > vLoop, int ifix, const std::vector< std::vector< double > > &v2vsv1, std::vector< double > &xx, std::vector< double > &yy, bool regularOrder=true)
Definition: EfieldInterpolator.cxx:487
EfieldInterpolator::initializeFromDirectory
bool initializeFromDirectory(const std::string &fpath)
Definition: EfieldInterpolator.cxx:93
StateLessPT_NewConfig.Format
Format
Definition: StateLessPT_NewConfig.py:146
plotBeamSpotCompare.x2
x2
Definition: plotBeamSpotCompare.py:218
EfieldInterpolator::isInterpolation
bool isInterpolation(const std::vector< double > &vval, double aimval)
Definition: EfieldInterpolator.h:89
TH1D
Definition: rootspy.cxx:342
EfieldInterpolator::~EfieldInterpolator
virtual ~EfieldInterpolator()
EfieldInterpolator::m_sensorDepth
Gaudi::Property< int > m_sensorDepth
Definition: EfieldInterpolator.h:77
EfieldInterpolator::m_fInter
std::string m_fInter
Definition: EfieldInterpolator.h:83
EfieldInterpolator::m_efieldProfile
TH1D * m_efieldProfile
Definition: EfieldInterpolator.h:82
makeTRTBarrelCans.y1
tuple y1
Definition: makeTRTBarrelCans.py:15
EfieldInterpolator::saveTGraph
void saveTGraph(std::vector< double > vvol, std::vector< double > vflu, std::vector< std::vector< double > > vfluvvol, double aimFlu, double aimVol, const std::string &prepend, bool skipNegative=true)
Definition: EfieldInterpolator.cxx:646
PlotCalibFromCool.ie
ie
Definition: PlotCalibFromCool.py:420
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:200
TH1D::GetBinContent
double GetBinContent(int) const
Definition: rootspy.cxx:347
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
uint
unsigned int uint
Definition: LArOFPhaseFill.cxx:20
EfieldInterpolator::createInterpolationFromTCADtree
const std::string createInterpolationFromTCADtree(const std::string &fTCAD)
Definition: EfieldInterpolator.cxx:364
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
linearField
@ linearField
Definition: EfieldInterpolator.h:32
fillPileUpNoiseLumi.next
next
Definition: fillPileUpNoiseLumi.py:52
lumiFormat.i
int i
Definition: lumiFormat.py:92
z
#define z
EfieldInterpolator::estimateEfieldLinear
double estimateEfieldLinear(double aimVoltage)
Definition: EfieldInterpolator.cxx:521
EfieldInterpolator::setLayer
void setLayer(int layer)
Definition: EfieldInterpolator.cxx:66
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
makeTRTBarrelCans.y2
tuple y2
Definition: makeTRTBarrelCans.py:18
covarianceTool.title
title
Definition: covarianceTool.py:542
generateReferenceFile.files
files
Definition: generateReferenceFile.py:12
file
TFile * file
Definition: tile_monitor.h:29
test_pyathena.parent
parent
Definition: test_pyathena.py:15
EfieldInterpolator::estimateEfield
double estimateEfield(std::vector< double > vvol, const std::vector< double > &vflu, const std::vector< std::vector< double > > &vfluvvol, double aimFlu, double aimVol, const std::string &prepend="", bool debug=false)
Definition: EfieldInterpolator.cxx:551
MakeFileForMJB.ext
string ext
Definition: Moriond2016/MakeFileForMJB.py:41
DeMoUpdate.tmp
string tmp
Definition: DeMoUpdate.py:1167
CastStdVec
TVectorD CastStdVec(const std::vector< double > &vin)
Definition: EfieldInterpolator.cxx:43
interspline
@ interspline
Definition: EfieldInterpolator.h:30
beamspotman.dir
string dir
Definition: beamspotman.py:623
EfieldInterpolator::extrapolateLinear
static double extrapolateLinear(double x1, double y1, double x2, double y2, double xaim)
Definition: EfieldInterpolator.cxx:236
EfieldInterpolator::m_useSpline
Gaudi::Property< bool > m_useSpline
Definition: EfieldInterpolator.h:72
isIBL
bool isIBL(uint32_t robId)
Definition: PixelRodDecoder.cxx:44
dumpTgcDigiJitter.nBins
list nBins
Definition: dumpTgcDigiJitter.py:29
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
EfieldInterpolator::relativeDistance
static double relativeDistance(double x1, double x2)
Definition: EfieldInterpolator.cxx:225
debug
const bool debug
Definition: MakeUncertaintyPlots.cxx:53
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
EfieldInterpolator::createEfieldProfile
TH1D * createEfieldProfile(double aimFluence, double aimVoltage)
Definition: EfieldInterpolator.cxx:678
TH1D::SetBinContent
void SetBinContent(int, double)
Definition: rootspy.cxx:348
EfieldInterpolator::reliabilityCheck
void reliabilityCheck(double aimFluence, const std::vector< double > &fluences, double aimVoltage, const std::vector< double > &voltages)
Definition: EfieldInterpolator.cxx:193
python.AthDsoLogger.fname
string fname
Definition: AthDsoLogger.py:67
python.PyAthena.v
v
Definition: PyAthena.py:157
DeMoScan.index
string index
Definition: DeMoScan.py:362
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
EfieldInterpolator::initialize
virtual StatusCode initialize() override
Definition: EfieldInterpolator.cxx:33
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
python.envutil.filelist
filelist
print ("Checking files %s..." % fullfile)
Definition: envutil.py:152
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
TH1
Definition: rootspy.cxx:268
DeMoScan.first
bool first
Definition: DeMoScan.py:534
EfieldInterpolator::loadEfieldFromDat
TH1D * loadEfieldFromDat(const std::string &fname, bool fillEdges=true)
Definition: EfieldInterpolator.cxx:249
dqt_zlumi_alleff_HIST.tl
tl
Definition: dqt_zlumi_alleff_HIST.py:73
EfieldInterpolator::getEfield
TH1D * getEfield(double aimFluence, double aimVoltage)
Definition: EfieldInterpolator.cxx:825
EfieldInterpolator::m_initialized
Gaudi::Property< bool > m_initialized
Definition: EfieldInterpolator.h:67
PlotCalibFromCool.delx
delx
Definition: PlotCalibFromCool.py:865
AthAlgTool
Definition: AthAlgTool.h:26
isContainedAt
int isContainedAt(const std::vector< double > &v, double val)
Definition: EfieldInterpolator.cxx:56
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
readCCLHist.float
float
Definition: readCCLHist.py:83
EfieldInterpolator::fillEdgeValues
void fillEdgeValues(TH1D *hin)
Definition: EfieldInterpolator.cxx:781
LheEventFiller_Common.ef
ef
Definition: SFGen_i/share/common/LheEventFiller_Common.py:7
beamspotman.fullpath
string fullpath
Definition: beamspotman.py:1039
EfieldInterpolator::initializeFromFile
bool initializeFromFile(const std::string &finpath)
Definition: EfieldInterpolator.cxx:162
EfieldInterpolator::loadTCADlist
StatusCode loadTCADlist(const std::string &TCADfileListToLoad)
Definition: EfieldInterpolator.cxx:78