LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
PhotonLibrary.cxx
Go to the documentation of this file.
1 #include "art_root_io/TFileDirectory.h"
3 
4 #include "cetlib_except/exception.h"
7 
8 #include "RooDouble.h"
9 #include "RooInt.h"
10 #include "RtypesCore.h"
11 #include "TBranch.h"
12 #include "TF1.h"
13 #include "TFile.h"
14 #include "TKey.h"
15 #include "TNamed.h"
16 #include "TString.h"
17 #include "TTree.h"
18 #include "TVector.h"
19 
20 #include <cassert>
21 
22 namespace {
23 
24  template <typename RooT, typename T>
25  struct RooReader {
26  TDirectory& srcDir;
27  std::vector<std::string>& missingKeys;
28 
29  std::optional<T> operator()(std::string const& key)
30  {
31  RooT const* value = srcDir.Get<RooT>(key.c_str());
32  if (value) return std::make_optional<T>(*value);
33  missingKeys.push_back(key);
34  return std::nullopt;
35  }
36  }; // RooReader
37 
38 } // local namespace
39 
40 namespace phot {
41 
42  std::string const PhotonLibrary::OpChannelBranchName = "OpChannel";
43 
44  //------------------------------------------------------------
45  PhotonLibrary::PhotonLibrary(art::TFileDirectory* pDir /* = nullptr */) : fDir(pDir) {}
46 
47  //------------------------------------------------------------
48 
50  bool storeReflected,
51  bool storeReflT0,
52  size_t storeTiming) const
53  {
54  mf::LogInfo("PhotonLibrary") << "Writing photon library to file";
55 
56  if (!fDir) {
57  throw cet::exception("PhotonLibrary")
58  << "StoreLibraryToFile(): no ROOT file provided, can't store anything.\n";
59  }
60 
61  TTree* tt = fDir->make<TTree>("PhotonLibraryData", "PhotonLibraryData");
62 
63  Int_t Voxel = 0;
64  Int_t OpChannel = 0;
65  Float_t Visibility = 0;
66  Float_t ReflVisibility = 0;
67  Float_t ReflTfirst = 0;
68  Float_t* timing_par = nullptr;
69 
70  tt->Branch("Voxel", &Voxel, "Voxel/I");
71  tt->Branch(OpChannelBranchName.c_str(), &OpChannel, (OpChannelBranchName + "/I").c_str());
72  tt->Branch("Visibility", &Visibility, "Visibility/F");
73 
74  if (storeTiming != 0) {
75  if (!hasTiming()) {
76  // if this happens, you need to call CreateEmptyLibrary() with storeReflected set true
77  throw cet::exception("PhotonLibrary")
78  << "StoreLibraryToFile() requested to store the time propagation distribution "
79  "parameters, which was not simulated.";
80  }
81  tt->Branch("timing_par", timing_par, Form("timing_par[%i]/F", size_t2int(storeTiming)));
83  throw cet::exception(" Photon Library ")
84  << "Time propagation lookup table is different size than Direct table \n"
85  << "this should not be happening. ";
86  }
87 
88  if (storeReflected) {
89  if (!hasReflected()) {
90  // if this happens, you need to call CreateEmptyLibrary() with storeReflected set true
91  throw cet::exception("PhotonLibrary")
92  << "StoreLibraryToFile() requested to store reflected light, which was not simulated.";
93  }
94  tt->Branch("ReflVisibility", &ReflVisibility, "ReflVisibility/F");
96  throw cet::exception(" Photon Library ")
97  << "Reflected light lookup table is different size than Direct table \n"
98  << "this should not be happening. ";
99  }
100  if (storeReflT0) {
101  if (!hasReflectedT0()) {
102  // if this happens, you need to call CreateEmptyLibrary() with storeReflectedT0 set true
103  throw cet::exception("PhotonLibrary") << "StoreLibraryToFile() requested to store "
104  "reflected light timing, which was not simulated.";
105  }
106  tt->Branch("ReflTfirst", &ReflTfirst, "ReflTfirst/F");
107  }
108  for (size_t ivox = 0; ivox != fNVoxels; ++ivox) {
109  for (size_t ichan = 0; ichan != fNOpChannels; ++ichan) {
110  Visibility = uncheckedAccess(ivox, ichan);
111  if (storeReflected) ReflVisibility = uncheckedAccessRefl(ivox, ichan);
112  if (storeReflT0) ReflTfirst = uncheckedAccessReflT(ivox, ichan);
113  if (storeTiming != 0) {
114  for (size_t i = 0; i < storeTiming; i++)
115  timing_par[i] = uncheckedAccessTimingPar(ivox, ichan, i);
116  }
117  if (Visibility > 0 || ReflVisibility > 0) {
118  Voxel = ivox;
119  OpChannel = ichan;
120  // visibility(ies) is(are) already set
121  tt->Fill();
122  }
123  }
124  }
125 
126  StoreMetadata();
127  }
128 
129  //------------------------------------------------------------
130 
132  size_t NOpChannels,
133  bool storeReflected /* = false */,
134  bool storeReflT0 /* = false */,
135  size_t storeTiming /* = false */
136  )
137  {
143 
144  fNVoxels = NVoxels;
146 
148  fHasReflected = storeReflected;
149  if (storeReflected) fReflLookupTable.resize(LibrarySize());
150  fHasReflectedT0 = storeReflT0;
151  if (storeReflT0) fReflTLookupTable.resize(LibrarySize());
152  fHasTiming = storeTiming;
153  if (storeTiming != 0) {
156  }
157  }
158 
159  //------------------------------------------------------------
160 
161  void PhotonLibrary::LoadLibraryFromFile(std::string LibraryFile,
162  size_t NVoxels,
163  bool getReflected,
164  bool getReflT0,
165  size_t getTiming,
166  int fTimingMaxRange)
167  {
173 
174  mf::LogInfo("PhotonLibrary") << "Reading photon library from input file: "
175  << LibraryFile.c_str() << std::endl;
176 
177  TFile* f = nullptr;
178  TTree* tt = nullptr;
179  TDirectory* pSrcDir = nullptr;
180 
181  try {
182  f = TFile::Open(LibraryFile.c_str());
183  tt = (TTree*)f->Get("PhotonLibraryData");
184  if (tt) { pSrcDir = f; }
185  else { // Library not in the top directory
186  TKey* key = f->FindKeyAny("PhotonLibraryData");
187  if (key) {
188  tt = (TTree*)key->ReadObj();
189  pSrcDir = key->GetMotherDir();
190  }
191  else {
192  mf::LogError("PhotonLibrary") << "PhotonLibraryData not found in file" << LibraryFile;
193  }
194  }
195  }
196  catch (...) {
197  throw cet::exception("PhotonLibrary")
198  << "Error in ttree load, reading photon library: " << LibraryFile << "\n";
199  }
200 
201  Int_t Voxel;
202  Int_t OpChannel;
203  Float_t Visibility;
204  Float_t ReflVisibility;
205  Float_t ReflTfirst;
206  std::vector<Float_t> timing_par;
207 
208  tt->SetBranchAddress("Voxel", &Voxel);
209  tt->SetBranchAddress("OpChannel", &OpChannel);
210  tt->SetBranchAddress("Visibility", &Visibility);
211 
212  fHasTiming = getTiming;
213 
214  fHasReflected = getReflected;
215  if (getReflected) tt->SetBranchAddress("ReflVisibility", &ReflVisibility);
216  fHasReflectedT0 = getReflT0;
217  if (getReflT0) tt->SetBranchAddress("ReflTfirst", &ReflTfirst);
218 
219  fNVoxels = NVoxels;
220  fNOpChannels = PhotonLibrary::ExtractNOpChannels(tt); // EXPENSIVE!!!
221 
222  // with STL vectors, where `resize()` directly controls the allocation of
223  // memory, reserving the space is redundant; not so with `util::LazyVector`,
224  // where `resize()` never increases the memory; `data_init()` allocates
225  // all the storage we need at once, effectively suppressing the laziness
226  // of the vector (by design, that was only relevant in `CreateEmptyLibrary()`)
229 
230  if (fHasTiming != 0) {
231  timing_par.resize(getTiming);
232  tt->SetBranchAddress("timing_par", timing_par.data());
234  // should be pSrcDir->Get()? kept as is for backward compatibility
235  TNamed* n = (TNamed*)f->Get("fTimingParFormula");
236  if (!n)
237  mf::LogError("PhotonLibrary")
238  << "Error reading the photon propagation formula. Please check the photon library."
239  << std::endl;
240  fTimingParFormula = n->GetTitle();
243  mf::LogInfo("PhotonLibrary")
244  << "Time parametrization is activated. Using the formula: " << fTimingParFormula << " with "
245  << fTimingParNParameters << " parameters." << std::endl;
246  }
247  if (fHasReflected) {
250  }
251  if (fHasReflectedT0) {
254  }
255 
256  size_t NEntries = tt->GetEntries();
257 
258  for (size_t i = 0; i != NEntries; ++i) {
259 
260  tt->GetEntry(i);
261 
262  // Set the visibility at this optical channel
263  uncheckedAccess(Voxel, OpChannel) = Visibility;
264 
265  if (fHasReflected) uncheckedAccessRefl(Voxel, OpChannel) = ReflVisibility;
266  if (fHasReflectedT0) uncheckedAccessReflT(Voxel, OpChannel) = ReflTfirst;
267  if (fHasTiming != 0) {
268  // TODO: use TF1::Copy
269  TF1 timingfunction(Form("timing_%i_%i", Voxel, OpChannel),
270  fTimingParFormula.c_str(),
271  timing_par[0],
272  fTimingMaxRange);
273  timingfunction.SetParameter(
274  0,
275  0.0); //first parameter is now in the range. Let's do this to keep compatible with old libraries.
276  for (size_t k = 1; k < fTimingParNParameters; k++) {
277  timingfunction.SetParameter(k, timing_par[k]);
278  }
279 
280  uncheckedAccessTimingTF1(Voxel, OpChannel) = timingfunction;
281  }
282  } // for entries
283 
284  LoadMetadata(*pSrcDir);
285  {
286  mf::LogInfo log("PhotonLibrary");
287  log << "Photon lookup table size : " << NVoxels << " voxels, " << fNOpChannels
288  << " channels";
289  if (hasVoxelDef())
290  log << "; " << GetVoxelDef();
291  else
292  log << " (no voxel geometry included)";
293  }
294 
295  try {
296  f->Close();
297  }
298  catch (...) {
299  mf::LogError("PhotonLibrary") << "Error in closing file : " << LibraryFile;
300  }
301  }
302 
303  //----------------------------------------------------
304 
305  float PhotonLibrary::GetCount(size_t Voxel, size_t OpChannel) const
306  {
307  if ((Voxel >= fNVoxels) || (OpChannel >= fNOpChannels))
308  return 0;
309  else
310  return uncheckedAccess(Voxel, OpChannel);
311  }
312  //----------------------------------------------------
313 
314  float PhotonLibrary::GetTimingPar(size_t Voxel, size_t OpChannel, size_t parnum) const
315  {
316  if ((Voxel >= fNVoxels) || (OpChannel >= fNOpChannels))
317  return 0;
318  else
319  return uncheckedAccessTimingPar(Voxel, OpChannel, parnum);
320  } //----------------------------------------------------
321 
322  float PhotonLibrary::GetReflCount(size_t Voxel, size_t OpChannel) const
323  {
324  if ((Voxel >= fNVoxels) || (OpChannel >= fNOpChannels))
325  return 0;
326  else
327  return uncheckedAccessRefl(Voxel, OpChannel);
328  }
329  //----------------------------------------------------
330 
331  float PhotonLibrary::GetReflT0(size_t Voxel, size_t OpChannel) const
332  {
333  if ((Voxel >= fNVoxels) || (OpChannel >= fNOpChannels))
334  return 0;
335  else
336  return uncheckedAccessReflT(Voxel, OpChannel);
337  }
338 
339  //----------------------------------------------------
340 
341  void PhotonLibrary::SetCount(size_t Voxel, size_t OpChannel, float Count)
342  {
343  if ((Voxel >= fNVoxels) || (OpChannel >= fNOpChannels))
344  mf::LogError("PhotonLibrary")
345  << "Error - attempting to set count in voxel " << Voxel << " which is out of range";
346  else
347  uncheckedAccess(Voxel, OpChannel) = Count;
348  }
349  //----------------------------------------------------
350 
351  void PhotonLibrary::SetTimingPar(size_t Voxel, size_t OpChannel, float Count, size_t parnum)
352  {
353  if ((Voxel >= fNVoxels) || (OpChannel >= fNOpChannels))
354  mf::LogError("PhotonLibrary") << "Error - attempting to set timing t0 count in voxel "
355  << Voxel << " which is out of range";
356  else
357  uncheckedAccessTimingPar(Voxel, OpChannel, parnum) = Count;
358  }
359  //----------------------------------------------------
360 
361  void PhotonLibrary::SetTimingTF1(size_t Voxel, size_t OpChannel, TF1 func)
362  {
363  if ((Voxel >= fNVoxels) || (OpChannel >= fNOpChannels))
364  mf::LogError("PhotonLibrary") << "Error - attempting to set a propagation function in voxel "
365  << Voxel << " which is out of range";
366  else
367  uncheckedAccessTimingTF1(Voxel, OpChannel) = func;
368  }
369  //----------------------------------------------------
370 
371  void PhotonLibrary::SetReflCount(size_t Voxel, size_t OpChannel, float Count)
372  {
373  if ((Voxel >= fNVoxels) || (OpChannel >= fNOpChannels))
374  mf::LogError("PhotonLibrary")
375  << "Error - attempting to set count in voxel " << Voxel << " which is out of range";
376  else
377  uncheckedAccessRefl(Voxel, OpChannel) = Count;
378  }
379  //----------------------------------------------------
380 
381  void PhotonLibrary::SetReflT0(size_t Voxel, size_t OpChannel, float Count)
382  {
383  if ((Voxel >= fNVoxels) || (OpChannel >= fNOpChannels))
384  mf::LogError("PhotonLibrary")
385  << "Error - attempting to set count in voxel " << Voxel << " which is out of range";
386  else
387  uncheckedAccessReflT(Voxel, OpChannel) = Count;
388  }
389 
390  //----------------------------------------------------
391 
392  float const* PhotonLibrary::GetCounts(size_t Voxel) const
393  {
394  if (Voxel >= fNVoxels)
395  return nullptr;
396  else
397  return fLookupTable.data_address(uncheckedIndex(Voxel, 0));
398  }
399 
400  //----------------------------------------------------
401 
402  const std::vector<float>* PhotonLibrary::GetTimingPars(size_t Voxel) const
403  {
404  if (Voxel >= fNVoxels)
405  return nullptr;
406  else
408  }
409 
410  //----------------------------------------------------
411 
412  TF1* PhotonLibrary::GetTimingTF1s(size_t Voxel) const
413  {
414  if (Voxel >= fNVoxels) return nullptr;
415  /*
416  * Sorry, Universe, but we can't undergo ROOT's bad design hell.
417  * TF1::GetRandom() is non-const member, because it uses some internal
418  * integral information which can be produced on the spot instead than
419  * always be present. That's called caching, it's Good, but it must not
420  * interfere with constantness of the interface (in fact, this is one of
421  * the few acceptable uses of `mutable` members).
422  * Because of this, this method can't return a constant `TF1`, therefore
423  * it can't be constant, therefore the underlying access returning a
424  * constant object is not acceptable.
425  * So I do the Bad thing.
426  * Plus I opened JIRA ROOT-9549
427  * (https://sft.its.cern.ch/jira/browse/ROOT-9549).
428  * After that is solved, this method should become:
429  *
430  * TF1 const* PhotonLibrary::GetTimingTF1s(size_t Voxel) const
431  *
432  * and the users should update their code accordingly.
433  */
434  else
435  return const_cast<TF1*>(fTimingParTF1LookupTable.data_address(uncheckedIndex(Voxel, 0)));
436  }
437 
438  //----------------------------------------------------
439 
440  float const* PhotonLibrary::GetReflCounts(size_t Voxel) const
441  {
442  if (Voxel >= fNVoxels)
443  return nullptr;
444  else
445  return fReflLookupTable.data_address(uncheckedIndex(Voxel, 0));
446  }
447 
448  //----------------------------------------------------
449 
450  float const* PhotonLibrary::GetReflT0s(size_t Voxel) const
451  {
452  if (Voxel >= fNVoxels)
453  return nullptr;
454  else
456  }
457 
458  //------------------------------------------------------------
459  void PhotonLibrary::LoadMetadata(TDirectory& srcDir)
460  {
461 
462  constexpr std::size_t NExpectedKeys = 9U;
463 
464  std::vector<std::string> missingKeys;
465 
466  RooReader<RooInt, Int_t> readInt{srcDir, missingKeys};
467  RooReader<RooDouble, Double_t> readDouble{srcDir, missingKeys};
468 
469  // FIXME: Not sure initializing to 0 is appropriate.
470  double xMin{};
471  double xMax{};
472  int xN{};
473  double yMin{};
474  double yMax{};
475  int yN{};
476  double zMin{};
477  double zMax{};
478  int zN{};
479  if (auto metaValue = readDouble("MinX")) xMin = *metaValue;
480  if (auto metaValue = readDouble("MaxX")) xMax = *metaValue;
481  if (auto metaValue = readInt("NDivX")) xN = *metaValue;
482  if (auto metaValue = readDouble("MinY")) yMin = *metaValue;
483  if (auto metaValue = readDouble("MaxY")) yMax = *metaValue;
484  if (auto metaValue = readInt("NDivY")) yN = *metaValue;
485  if (auto metaValue = readDouble("MinZ")) zMin = *metaValue;
486  if (auto metaValue = readDouble("MaxZ")) zMax = *metaValue;
487  if (auto metaValue = readInt("NDivZ")) zN = *metaValue;
488 
489  if (!missingKeys.empty()) {
490  if (missingKeys.size() != NExpectedKeys) {
491  mf::LogError log("PhotonLibrary");
492  log << "Photon library at '" << srcDir.GetPath() << "' is missing " << missingKeys.size()
493  << " metadata elements:";
494  for (auto const& key : missingKeys)
495  log << " '" << key << "'";
496  }
497  else {
498  mf::LogTrace("PhotonLibrary") << "No voxel metadata found in '" << srcDir.GetPath() << "'";
499  }
500  return;
501  } // if missing keys
502 
503  fVoxelDef.emplace(xMin, xMax, xN, yMin, yMax, yN, zMin, zMax, zN);
504 
505  } // PhotonLibrary::LoadMetadata()
506 
507  //------------------------------------------------------------
509  {
510 
511  assert(fDir);
512 
513  // NVoxels
514  fDir->makeAndRegister<RooInt>("NVoxels", "Total number of voxels in the library", fNVoxels);
515 
516  // NChannels
517  fDir->makeAndRegister<RooInt>(
518  "NChannels", "Total number of optical detector channels in the library", fNOpChannels);
519 
520  if (!hasVoxelDef()) return;
521  sim::PhotonVoxelDef const& voxelDef = GetVoxelDef();
522 
523  // lower point
524  geo::Point_t const& lower = voxelDef.GetRegionLowerCorner();
525  fDir->makeAndRegister<RooDouble>(
526  "MinX", "Lower x coordinate covered by the library (world coordinates, cm)", lower.X());
527  fDir->makeAndRegister<RooDouble>(
528  "MinY", "Lower y coordinate covered by the library (world coordinates, cm)", lower.Y());
529  fDir->makeAndRegister<RooDouble>(
530  "MinZ", "Lower z coordinate covered by the library (world coordinates, cm)", lower.Z());
531 
532  // upper point
533  geo::Point_t const& upper = voxelDef.GetRegionUpperCorner();
534  fDir->makeAndRegister<RooDouble>(
535  "MaxX", "Upper x coordinate covered by the library (world coordinates, cm)", upper.X());
536  fDir->makeAndRegister<RooDouble>(
537  "MaxY", "Upper y coordinate covered by the library (world coordinates, cm)", upper.Y());
538  fDir->makeAndRegister<RooDouble>(
539  "MaxZ", "Upper z coordinate covered by the library (world coordinates, cm)", upper.Z());
540 
541  // steps
542  geo::Vector_t const& stepSizes = voxelDef.GetVoxelSize();
543  fDir->makeAndRegister<RooDouble>("StepX", "Size on x direction of a voxel (cm)", stepSizes.X());
544  fDir->makeAndRegister<RooDouble>("StepY", "Size on y direction of a voxel (cm)", stepSizes.Y());
545  fDir->makeAndRegister<RooDouble>("StepZ", "Size on z direction of a voxel (cm)", stepSizes.Z());
546 
547  // divisions
548  auto const& steps = voxelDef.GetSteps();
549  fDir->makeAndRegister<RooInt>("NDivX", "Steps on the x direction", steps[0]);
550  fDir->makeAndRegister<RooInt>("NDivY", "Steps on the y direction", steps[1]);
551  fDir->makeAndRegister<RooInt>("NDivZ", "Steps on the z direction", steps[2]);
552 
553  } // PhotonLibrary::StoreMetadata()
554 
555  //----------------------------------------------------
556 
558  {
559  TBranch* channelBranch = tree->GetBranch(OpChannelBranchName.c_str());
560  if (!channelBranch) {
562  << "Tree '" << tree->GetName() << "' has no branch 'OpChannel'";
563  }
564 
565  // fix a new local address for the branch
566  char* oldAddress = channelBranch->GetAddress();
567  Int_t channel;
568  channelBranch->SetAddress(&channel);
569  Int_t maxChannel = -1;
570 
571  // read all the channel values and pick the largest one
572  Long64_t iEntry = 0;
573  while (channelBranch->GetEntry(iEntry++)) {
574  if (channel > maxChannel) maxChannel = channel;
575  } // while
576 
577  MF_LOG_DEBUG("PhotonLibrary") << "Detected highest channel to be " << maxChannel << " from "
578  << iEntry << " tree entries";
579 
580  // restore the old branch address
581  channelBranch->SetAddress(oldAddress);
582 
583  return size_t(maxChannel + 1);
584 
585  } // PhotonLibrary::ExtractNOpChannels()
586 
587  //----------------------------------------------------
588 
589 }
virtual float GetReflT0(size_t Voxel, size_t OpChannel) const override
const_pointer data_address(size_type pos) const
Returns a constant pointer to the specified element.
Definition: LazyVector.h:549
static int size_t2int(size_t val)
Converts size_t into integer.
std::optional< sim::PhotonVoxelDef > fVoxelDef
Voxel definition loaded from library metadata.
size_t fHasTiming
Whether the current library deals with time propagation distribution.
void LoadLibraryFromFile(std::string LibraryFile, size_t NVoxels, bool storeReflected=false, bool storeReflT0=false, size_t storeTiming=0, int maxrange=200)
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
Definition: geo_vectors.h:160
util::LazyVector< float > fReflLookupTable
virtual float const * GetCounts(size_t Voxel) const override
Returns a pointer to NOpChannels() visibility values, one per channel.
bool fHasReflectedT0
Whether the current library deals with reflected light timing.
void CreateEmptyLibrary(size_t NVoxels, size_t NChannels, bool storeReflected=false, bool storeReflT0=false, size_t storeTiming=0)
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
virtual float const * GetReflT0s(size_t Voxel) const override
sim::PhotonVoxelDef const & GetVoxelDef() const
Definition: PhotonLibrary.h:89
Vector GetVoxelSize() const
Returns a vector describing the span of a single voxel in x, y an z [cm].
Definition: PhotonVoxels.h:208
bool hasVoxelDef() const
Returns whether voxel metadata is available.
Definition: PhotonLibrary.h:85
virtual int NOpChannels() const override
Representation of a region of space diced into voxels.
Definition: PhotonVoxels.h:58
virtual float GetReflCount(size_t Voxel, size_t OpChannel) const override
void data_init(size_type startIndex, size_type endIndex)
Allocates the specified range and stores default values for it.
Definition: LazyVector.h:609
void clear()
Removes all stored data and sets the nominal size to 0.
Definition: LazyVector.h:587
static std::string const OpChannelBranchName
Name of the optical channel number in the input tree.
float uncheckedAccess(size_t Voxel, size_t OpChannel) const
Unchecked access to a visibility datum.
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
void StoreLibraryToFile(std::string LibraryFile, bool storeReflected=false, bool storeReflT0=false, size_t storeTiming=0) const
float uncheckedAccessReflT(size_t Voxel, size_t OpChannel) const
Unchecked access to a reflected T0 visibility datum.
void SetCount(size_t Voxel, size_t OpChannel, float Count)
void SetTimingTF1(size_t Voxel, size_t OpChannel, TF1 func)
std::string fTimingParFormula
size_t uncheckedIndex(size_t Voxel, size_t OpChannel) const
Returns the index of visibility of specified voxel and cell.
TFile f
Definition: plotHisto.C:6
util::LazyVector< float > fLookupTable
virtual bool hasReflectedT0() const override
Returns whether the current library deals with reflected light timing.
Definition: PhotonLibrary.h:62
static size_t ExtractNOpChannels(TTree *tree)
Returns the number of optical channels in the specified tree.
Definition: type_traits.h:61
size_type size() const noexcept
Returns the size of the vector.
Definition: LazyVector.h:149
void SetReflT0(size_t Voxel, size_t OpChannel, float reflT0)
bool fHasReflected
Whether the current library deals with reflected light counts.
TF1 & uncheckedAccessTimingTF1(size_t Voxel, size_t OpChannel)
Unchecked access to a parameter of the time distribution.
decltype(auto) GetRegionUpperCorner() const
Returns the volume vertex (type Point) with the highest coordinates.
void StoreMetadata() const
Writes the current metadata (if any) into the ROOT output file.
TF1 * GetTimingTF1s(size_t Voxel) const
const std::vector< float > * GetTimingPars(size_t Voxel) const
util::LazyVector< TF1 > fTimingParTF1LookupTable
virtual float GetCount(size_t Voxel, size_t OpChannel) const override
double value
Definition: spectrum.C:18
void SetTimingPar(size_t Voxel, size_t OpChannel, float Count, size_t parnum)
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:180
General LArSoft Utilities.
float uncheckedAccessRefl(size_t Voxel, size_t OpChannel) const
Unchecked access to a reflected visibility datum.
size_t LibrarySize() const
Returns the number of elements in the library.
virtual bool hasReflected() const override
Returns whether the current library deals with reflected light count.
Definition: PhotonLibrary.h:59
#define MF_LOG_DEBUG(id)
float GetTimingPar(size_t Voxel, size_t OpChannel, size_t parnum) const
std::array< unsigned int, 3U > GetSteps() const
Returns the number of voxels along each of the three dimensions.
Char_t n[5]
MaybeLogger_< ELseverityLevel::ELsev_success, true > LogTrace
void resize(size_type newSize)
Changes the nominal size of the container.
Definition: LazyVector.h:567
util::LazyVector< std::vector< float > > fTimingParLookupTable
util::LazyVector< float > fReflTLookupTable
art::TFileDirectory * fDir
ROOT directory where to write data.
virtual float const * GetReflCounts(size_t Voxel) const override
virtual int NVoxels() const override
void SetReflCount(size_t Voxel, size_t OpChannel, float Count)
bool hasTiming() const
Returns whether the current library deals with time propagation distributions.
Definition: PhotonLibrary.h:56
void LoadMetadata(TDirectory &srcDir)
Reads the metadata from specified ROOT directory and sets it as current.
decltype(auto) GetRegionLowerCorner() const
Returns the volume vertex (type Point) with the lowest coordinates.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
float uncheckedAccessTimingPar(size_t Voxel, size_t OpChannel, size_t parnum) const
Unchecked access to a parameter the time distribution.