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