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