1 #include "art_root_io/TFileDirectory.h"
2 #include "canvas/Utilities/Exception.h"
4 #include "cetlib_except/exception.h"
6 #include "messagefacility/MessageLogger/MessageLogger.h"
10 #include "RtypesCore.h"
24 template <
typename RooT,
typename T>
27 std::vector<std::string>& missingKeys;
30 operator()(std::string
const& key)
32 RooT
const*
value = srcDir.Get<RooT>(key.c_str());
33 if (value)
return std::make_optional<T>(*value);
34 missingKeys.push_back(key);
54 size_t storeTiming)
const
56 mf::LogInfo(
"PhotonLibrary") <<
"Writing photon library to file";
59 throw cet::exception(
"PhotonLibrary")
60 <<
"StoreLibraryToFile(): no ROOT file provided, can't store anything.\n";
63 TTree* tt =
fDir->make<TTree>(
"PhotonLibraryData",
"PhotonLibraryData");
67 Float_t Visibility = 0;
68 Float_t ReflVisibility = 0;
69 Float_t ReflTfirst = 0;
70 Float_t* timing_par =
nullptr;
72 tt->Branch(
"Voxel", &Voxel,
"Voxel/I");
74 tt->Branch(
"Visibility", &Visibility,
"Visibility/F");
76 if (storeTiming != 0) {
79 throw cet::exception(
"PhotonLibrary")
80 <<
"StoreLibraryToFile() requested to store the time propagation distribution "
81 "parameters, which was not simulated.";
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. ";
93 throw cet::exception(
"PhotonLibrary")
94 <<
"StoreLibraryToFile() requested to store reflected light, which was not simulated.";
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. ";
105 throw cet::exception(
"PhotonLibrary") <<
"StoreLibraryToFile() requested to store "
106 "reflected light timing, which was not simulated.";
108 tt->Branch(
"ReflTfirst", &ReflTfirst,
"ReflTfirst/F");
110 for (
size_t ivox = 0; ivox !=
fNVoxels; ++ivox) {
111 for (
size_t ichan = 0; ichan !=
fNOpChannels; ++ichan) {
115 if (storeTiming != 0) {
116 for (
size_t i = 0; i < storeTiming; i++)
119 if (Visibility > 0 || ReflVisibility > 0) {
136 bool storeReflected ,
156 if (storeTiming != 0) {
178 mf::LogInfo(
"PhotonLibrary") <<
"Reading photon library from input file: "
179 << LibraryFile.c_str() << std::endl;
183 TDirectory* pSrcDir =
nullptr;
186 f = TFile::Open(LibraryFile.c_str());
187 tt = (TTree*)f->Get(
"PhotonLibraryData");
188 if (tt) { pSrcDir = f; }
190 TKey* key = f->FindKeyAny(
"PhotonLibraryData");
192 tt = (TTree*)key->ReadObj();
193 pSrcDir = key->GetMotherDir();
196 mf::LogError(
"PhotonLibrary") <<
"PhotonLibraryData not found in file" << LibraryFile;
201 throw cet::exception(
"PhotonLibrary")
202 <<
"Error in ttree load, reading photon library: " << LibraryFile <<
"\n";
208 Float_t ReflVisibility;
210 std::vector<Float_t> timing_par;
212 tt->SetBranchAddress(
"Voxel", &Voxel);
213 tt->SetBranchAddress(
"OpChannel", &OpChannel);
214 tt->SetBranchAddress(
"Visibility", &Visibility);
219 if (getReflected) tt->SetBranchAddress(
"ReflVisibility", &ReflVisibility);
221 if (getReflT0) tt->SetBranchAddress(
"ReflTfirst", &ReflTfirst);
235 timing_par.resize(getTiming);
236 tt->SetBranchAddress(
"timing_par", timing_par.data());
239 TNamed*
n = (TNamed*)f->Get(
"fTimingParFormula");
241 mf::LogError(
"PhotonLibrary")
242 <<
"Error reading the photon propagation formula. Please check the photon library."
247 mf::LogInfo(
"PhotonLibrary")
248 <<
"Time parametrization is activated. Using the formula: " <<
fTimingParFormula <<
" with "
260 size_t NEntries = tt->GetEntries();
262 for (
size_t i = 0; i != NEntries; ++i) {
273 TF1 timingfunction(Form(
"timing_%i_%i", Voxel, OpChannel),
277 timingfunction.SetParameter(
281 timingfunction.SetParameter(
k, timing_par[
k]);
290 mf::LogInfo log(
"PhotonLibrary");
291 log <<
"Photon lookup table size : " << NVoxels <<
" voxels, " <<
fNOpChannels
296 log <<
" (no voxel geometry included)";
303 mf::LogError(
"PhotonLibrary") <<
"Error in closing file : " << LibraryFile;
353 mf::LogError(
"PhotonLibrary")
354 <<
"Error - attempting to set count in voxel " << Voxel <<
" which is out of range";
364 mf::LogError(
"PhotonLibrary") <<
"Error - attempting to set timing t0 count in voxel "
365 << Voxel <<
" which is out of range";
375 mf::LogError(
"PhotonLibrary") <<
"Error - attempting to set a propagation function in voxel "
376 << Voxel <<
" which is out of range";
386 mf::LogError(
"PhotonLibrary")
387 <<
"Error - attempting to set count in voxel " << Voxel <<
" which is out of range";
397 mf::LogError(
"PhotonLibrary")
398 <<
"Error - attempting to set count in voxel " << Voxel <<
" which is out of range";
416 const std::vector<float>*
430 if (Voxel >=
fNVoxels)
return nullptr;
481 constexpr std::size_t NExpectedKeys = 9U;
483 std::vector<std::string> missingKeys;
485 RooReader<RooInt, Int_t> readInt{srcDir, missingKeys};
486 RooReader<RooDouble, Double_t> readDouble{srcDir, missingKeys};
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;
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 <<
"'";
516 mf::LogTrace(
"PhotonLibrary") <<
"No voxel metadata found in '" << srcDir.GetPath() <<
"'";
521 fVoxelDef.emplace(xMin, xMax, xN, yMin, yMax, yN, zMin, zMax, zN);
533 fDir->makeAndRegister<RooInt>(
"NVoxels",
"Total number of voxels in the library",
fNVoxels);
536 fDir->makeAndRegister<RooInt>(
537 "NChannels",
"Total number of optical detector channels in the library",
fNOpChannels);
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());
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());
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());
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]);
580 if (!channelBranch) {
581 throw art::Exception(art::errors::NotFound)
582 <<
"Tree '" << tree->GetName() <<
"' has no branch 'OpChannel'";
586 char* oldAddress = channelBranch->GetAddress();
588 channelBranch->SetAddress(&channel);
589 Int_t maxChannel = -1;
593 while (channelBranch->GetEntry(iEntry++)) {
594 if (channel > maxChannel) maxChannel = channel;
597 MF_LOG_DEBUG(
"PhotonLibrary") <<
"Detected highest channel to be " << maxChannel <<
" from "
598 << iEntry <<
" tree entries";
601 channelBranch->SetAddress(oldAddress);
603 return size_t(maxChannel + 1);
const_pointer data_address(size_type pos) const
Returns a constant pointer to the specified element.
size_t fTimingParNParameters
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
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)
util::LazyVector< float > fReflLookupTable
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.
void data_init(size_type startIndex, size_type endIndex)
Allocates the specified range and stores default values for it.
void clear()
Removes all stored data and sets the nominal size to 0.
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)
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
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.
TF1 * GetTimingTF1s(size_t Voxel) const
const std::vector< float > * GetTimingPars(size_t Voxel) const
virtual float GetCount(size_t Voxel, size_t OpChannel) const override
util::LazyVector< TF1 > fTimingParTF1LookupTable
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.
virtual int NOpChannels() const override
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
void resize(size_type newSize)
Changes the nominal size of the container.
util::LazyVector< std::vector< float > > fTimingParLookupTable
util::LazyVector< float > fReflTLookupTable
art::TFileDirectory * fDir
ROOT directory where to write data.
virtual int NVoxels() const override
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.
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.