37 #include "art_root_io/TFileService.h" 39 #include "cetlib/search_path.h" 126 if (pset.
has_key(
"ReflectOverZeroX")) {
129 <<
"`PhotonVisbilityService` configuration specifies both `Mapping` and " 130 "`ReflectOverZeroX`." 131 " Please remove the latter (and use `PhotonMappingXMirrorTransformations` tool).";
135 <<
"Please update the configuration of `PhotonVisbilityService` service" 136 " replacing `ReflectOverZeroX` with tool configuration:" 137 "\n Mapping: { tool_type: \"PhotonMappingXMirrorTransformations\" }";
141 mapDefaultSet.
put(
"tool_type",
143 "PhotonMappingIdentityTransformations");
144 fMapping = art::make_tool<phot::IPhotonMappingTransformations>(
147 mf::LogInfo(
"PhotonVisibilityService") <<
"PhotonVisbilityService initializing" << std::endl;
158 std::string LibraryFileWithPath;
159 cet::search_path sp(
"FW_SEARCH_PATH");
163 <<
"Unable to find photon library in " << sp.to_string() <<
"\n";
169 <<
"PhotonVisibilityService Loading photon library from file " << LibraryFileWithPath
171 <<
" optical detectors." << std::endl;
200 <<
"Photon library reports the geometry:\n" 201 << lib->
GetVoxelDef() <<
"while PhotonVisbilityService is configured with:\n" 210 size_t NOpDets = geom->
NOpDets();
214 <<
" Vis service running library build job. Please ensure " 215 <<
" job contains LightSource, LArG4, SimPhotonCounter";
218 art::TFileDirectory* pDir =
nullptr;
226 <<
"PhotonVisibilityService: " 227 "service `TFileService` is required when building a photon library.\n";
248 std::cout <<
"This is would be building a Hybrid Library. Not defined. " << std::endl;
250 mf::LogInfo(
"PhotonVisibilityService") <<
" Vis service " 251 <<
" Storing Library entries to file..." << std::endl;
266 fHybrid = p.
get<
bool>(
"HybridLibrary",
false);
290 if (!fParPropTime) { fParPropTime_npar = 0; }
292 if (!fUseNhitsModel) {
294 if (fUseCryoBoundary) {
296 fXmin = CryoBounds.MinX();
297 fXmax = CryoBounds.MaxX();
298 fYmin = CryoBounds.MinY();
299 fYmax = CryoBounds.MaxY();
300 fZmin = CryoBounds.MinZ();
301 fZmax = CryoBounds.MaxZ();
323 for (
geo::TPCGeo const& TPC : cryo.IterateTPCs()) {
324 tpcVolume.ExtendToInclude(TPC.ActiveBoundingBox());
329 if (fUseAutomaticVoxels) {
331 std::string logString =
"Automatic voxelisation x-dimension\n";
332 float voxelSizeGoal = 10.0;
342 logString +=
"Automatic voxelisation y-dimension\n";
352 logString +=
"Automatic voxelisation z-dimension\n";
362 mf::LogInfo(
"PhotonVisibilityService") << logString;
368 if (fSaveTPCVoxels !=
"" || fSaveOtherVoxels !=
"") {
371 std::vector<unsigned int> tpcVoxels, otherVoxels;
372 tpcVoxels.reserve(totalVoxels);
373 otherVoxels.reserve(totalVoxels);
374 for (
unsigned int voxelID = 0; voxelID < totalVoxels; ++voxelID) {
377 if (tpcVolume.ContainsPosition(voxelCenter)) { tpcVoxels.push_back(voxelID); }
379 otherVoxels.push_back(voxelID);
382 std::string logString =
"Voxels within TPC: " +
std::to_string(tpcVoxels.size());
383 if (fSaveTPCVoxels !=
"") logString +=
" saved to file\n\t" +
fSaveTPCVoxels;
384 logString +=
"\nVoxels outside TPC: " +
std::to_string(otherVoxels.size());
385 if (fSaveOtherVoxels !=
"") logString +=
" saved to file\n\t" +
fSaveOtherVoxels;
386 mf::LogInfo(
"PhotonVisibilityService") << logString << std::endl;
388 if (fSaveTPCVoxels !=
"") {
389 std::ofstream outputFile = std::ofstream(fSaveTPCVoxels);
390 for (
auto voxel : tpcVoxels)
391 outputFile << voxel <<
"\n";
393 if (fSaveOtherVoxels !=
"") {
394 std::ofstream outputFile = std::ofstream(fSaveOtherVoxels);
395 for (
auto voxel : otherVoxels)
396 outputFile << voxel <<
"\n";
401 if (fIncludePropTime) {
404 std::cout <<
"Loading the VUV time parametrization" << std::endl;
407 fMpv = p.
get<std::vector<std::vector<double>>>(
"Mpv");
408 fWidth = p.
get<std::vector<std::vector<double>>>(
"Width");
410 fSlope = p.
get<std::vector<std::vector<double>>>(
"Slope");
420 if (fStoreReflected) {
423 std::cout <<
"Loading the VIS time paramterisation" << std::endl;
426 fCut_off = p.
get<std::vector<std::vector<std::vector<double>>>>(
"Cut_off");
427 fTau = p.
get<std::vector<std::vector<std::vector<double>>>>(
"Tau");
433 if (fUseNhitsModel) {
434 std::cout <<
"Loading semi-analytic mode models" << std::endl;
450 if (fStoreReflected) {
456 p.
get<std::vector<std::vector<std::vector<double>>>>(
"VIS_correction_flat");
462 p.
get<std::vector<std::vector<std::vector<double>>>>(
"VIS_correction_dome");
496 static std::vector<float> ret;
497 ret.resize(
fMapping->libraryMappingSize(p));
498 for (std::size_t libIndex = 0; libIndex < ret.size(); ++libIndex) {
507 return fMapping->applyOpDetMapping(p, data);
532 bool wantReflected )
const 538 if (!neis)
return 0.0;
543 if (
n.id < 0)
continue;
552 bool wantReflected )
const 560 unsigned int OpChannel,
561 bool wantReflected)
const 575 <<
" PVS notes production of " << N <<
" photons at Vox " << VoxID << std::endl;
605 <<
" PVS logging " << VoxID <<
" " << OpChannel << std::endl;
612 bool wantReflected)
const 635 bool wantReflected)
const 655 return fMapping->applyOpDetMapping(p, data);
677 <<
" PVS logging " << VoxID <<
" " << OpChannel << std::endl;
697 return fMapping->applyOpDetMapping(p, params);
704 return fMapping->applyOpDetMapping(p, functions);
742 <<
" PVS logging " << VoxID <<
" " << OpChannel << std::endl;
755 <<
" PVS logging " << VoxID <<
" " << OpChannel << std::endl;
776 return fMapping->opDetMappingSize();
783 double& tf1_sampling_factor)
const 802 double& t0_break_point)
const 819 double& vuv_vgroup_mean,
820 double& vuv_vgroup_max,
821 double& inflexion_point_distance,
822 double& angle_bin_timing_vuv)
const 842 std::vector<double>& distances,
843 std::vector<double>& radial_distances,
847 double& angle_bin_timing_vis)
const 860 double& delta_angulo_vuv,
869 std::vector<double>& border_corr_angulo_flat,
870 std::vector<std::vector<double>>& border_corr_flat)
const 878 std::vector<double>& border_corr_angulo_dome,
879 std::vector<std::vector<double>>& border_corr_dome)
const 893 std::vector<double>& vis_distances_x_flat,
894 std::vector<double>& vis_distances_r_flat,
903 std::vector<double>& vis_distances_x_dome,
904 std::vector<double>& vis_distances_r_dome,
920 return fMapping->detectorToLibrary(p);
931 std::string* logString)
const 935 float bestResult = 1000;
936 for (
int jog = -10; jog <= 10; ++jog) {
938 tpcMin, tpcMax, cryoMin, cryoMax, nVoxels, voxelMin, voxelMax, voxelSizeGoal, jog);
939 if (result < bestResult) {
967 std::string* logString)
const 970 float tpcSize = tpcMax - tpcMin;
971 int tpcVoxelNumber = ceil(tpcSize / voxelSizeGoal) + jog;
972 float voxelSize = tpcSize / tpcVoxelNumber;
973 float cryoSize = cryoMax - cryoMin;
977 while (voxelMin > cryoMin)
978 voxelMin -= voxelSize;
980 while (voxelMax < cryoMax)
981 voxelMax += voxelSize;
982 float cryoVoxelNumberGuess = cryoSize / voxelSize;
983 nVoxels = round((voxelMax - voxelMin) / voxelSize);
986 *logString +=
"\tTPC size " +
std::to_string(tpcSize) +
"cm requires " +
989 *logString +=
"\tCryostat boundaries " +
std::to_string(cryoMin) +
" to " +
992 *logString +=
"\tCryostat voxel range " +
std::to_string(voxelMin) +
" to " +
997 float voxelDelta = fabs(nVoxels - cryoVoxelNumberGuess);
Definitions of voxel data structures.
std::vector< std::vector< std::vector< double > > > fTau
MappedParams_t doGetTimingPar(geo::Point_t const &p) const
void LoadTimingsForVISPar(std::vector< double > &distances, std::vector< double > &radial_distances, std::vector< std::vector< std::vector< double >>> &cut_off, std::vector< std::vector< std::vector< double >>> &tau, double &vis_vmean, double &angle_bin_timing_vis) const
details::range_type< T > Iterate() const
Initializes the specified ID with the ID of the first cryostat.
phot::IPhotonLibrary::Counts_t GetLibraryReflT0Entries(int VoxID) const
OpDetGeo const & OpDetGeoFromOpDet(unsigned int OpDet) const
Returns the geo::OpDetGeo object for the given detector number.
virtual float GetReflT0(size_t Voxel, size_t OpChannel) const =0
double CosThetaFromNormal(geo::Point_t const &point) const
Get cos(angle) to normal of this detector - used for solid angle calcs.
MappedCounts_t doGetAllVisibilities(geo::Point_t const &p, bool wantReflected=false) const
phot::IPhotonLibrary::Counts_t GetLibraryEntries(int VoxID, bool wantReflected=false) const
~PhotonVisibilityService()
std::unique_ptr< phot::IPhotonMappingTransformations > fMapping
Mapping of detector space into library space.
void RetrieveLightProd(int &VoxID, double &N) const
void SetDirectLightPropFunctions(TF1 const *functions[8], double &d_break, double &d_max, double &tf1_sampling_factor) const
void LoadLibraryFromFile(std::string LibraryFile, size_t NVoxels, bool storeReflected=false, bool storeReflT0=false, size_t storeTiming=0, int maxrange=200)
std::vector< std::vector< double > > fborder_corr_flat
std::vector< double > fvis_distances_r_flat
void LoadTimingsForVUVPar(std::vector< std::vector< double >>(&v)[7], double &step_size, double &max_d, double &min_d, double &vuv_vgroup_mean, double &vuv_vgroup_max, double &inflexion_point_distance, double &angle_bin_timing_vuv) const
std::vector< double > fvis_distances_x_dome
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
void SetLibraryTimingParEntry(int VoxID, int OpChannel, float value, size_t parnum)
sim::PhotonVoxelDef const & GetVoxelDef() const
bool hasVoxelDef() const
Returns whether voxel metadata is available.
std::string fSaveOtherVoxels
std::vector< std::vector< double > > fWidth
std::vector< double > fvis_distances_r_dome
sim::PhotonVoxelDef fVoxelDef
virtual float GetReflCount(size_t Voxel, size_t OpChannel) const =0
phot::IPhotonMappingTransformations::LibraryIndex_t LibraryIndex_t
Type of optical library index.
double fangle_bin_timing_vis
Representation of a region of space diced into voxels.
Geometry information for a single TPC.
double fTF1_sampling_factor
std::vector< double > fDistances_exp
float GetLibraryTimingParEntry(int VoxID, OpDetID_t libOpChannel, size_t npar) const
geo::BoxBoundedGeo const & ActiveBoundingBox() const
Returns the box of the active volume of this TPC.
std::vector< double > fDistances_refl
bool HasLibraryEntries(int VoxID, bool wantReflected=false) const
void LoadVisParsFlat(std::vector< double > &vis_distances_x_flat, std::vector< double > &vis_distances_r_flat, std::vector< std::vector< std::vector< double >>> &vispars_flat) const
float doGetVisibilityOfOpLib(geo::Point_t const &p, LibraryIndex_t libIndex, bool wantReflected=false) const
bool doHasVisibility(geo::Point_t const &p, bool wantReflected=false) const
std::string fVISBorderCorrectionType
std::vector< double > fvis_distances_x_flat
void StoreLibraryToFile(std::string LibraryFile, bool storeReflected=false, bool storeReflT0=false, size_t storeTiming=0) const
std::vector< std::vector< std::vector< double > > > fCut_off
Geometry information for a single cryostat.
float GetLibraryEntry(int VoxID, OpDetID_t libOpChannel, bool wantReflected=false) const
void LoadGHDome(std::vector< std::vector< double >> &GHvuvpars_dome, std::vector< double > &border_corr_angulo_dome, std::vector< std::vector< double >> &border_corr_dome) const
geo::BoxBoundedGeo const & BoundingBox() const
Returns the bounding box of this cryostat.
CryostatGeo const & Cryostat(CryostatID const &cryoid=cryostat_zero) const
Returns the specified cryostat.
int VoxelAt(geo::Point_t const &p) const
void SetCount(size_t Voxel, size_t OpChannel, float Count)
std::vector< double > fDistances_landau
int fParPropTime_MaxRange
void findVoxelSuggestion(float tpcMin, float tpcMax, float cryoMin, float cryoMax, int &nVoxels, float &voxelMin, float &voxelMax, float voxelSizeGoal, std::string *logString=nullptr) const
void SetTimingTF1(size_t Voxel, size_t OpChannel, TF1 func)
void LoadVUVSemiAnalyticProperties(bool &isFlatPDCorr, bool &isDomePDCorr, double &delta_angulo_vuv, double &radius) const
double GetQuenchingFactor(double dQdx) const
float GetLibraryReflT0Entry(int VoxID, OpDetID_t libOpChannel) const
void SetReflectedCOLightPropFunctions(TF1 const *functions[5], double &t0_max, double &t0_break_point) const
std::string fParPropTime_formula
void StoreLightProd(int VoxID, double N)
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
void SetVoxelDef(sim::PhotonVoxelDef const &voxelDef)
PhotonVisibilityService(fhicl::ParameterSet const &pset)
void LoadGHFlat(std::vector< std::vector< double >> &GHvuvpars_flat, std::vector< double > &border_corr_angulo_flat, std::vector< std::vector< double >> &border_corr_flat) const
MappedFunctions_t doGetTimingTF1(geo::Point_t const &p) const
geo::Point_t LibLocation(geo::Point_t const &p) const
void SetReflT0(size_t Voxel, size_t OpChannel, float reflT0)
void LoadVisParsDome(std::vector< double > &vis_distances_x_dome, std::vector< double > &vis_distances_r_dome, std::vector< std::vector< std::vector< double >>> &vispars_dome) const
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
std::vector< double > fDistances_radial_refl
void SetLibraryReflT0Entry(int VoxID, int OpChannel, float value)
virtual Counts_t GetReflCounts(size_t Voxel) const =0
T get(std::string const &key) const
virtual float GetCount(size_t Voxel, size_t OpChannel) const =0
virtual Counts_t GetCounts(size_t Voxel) const =0
Returns a pointer to NOpChannels() visibility values, one per channel.
std::string fSaveTPCVoxels
void reconfigure(fhicl::ParameterSet const &p)
TF1 * GetTimingTF1s(size_t Voxel) const
const std::vector< float > * GetTimingPars(size_t Voxel) const
std::vector< std::vector< double > > fGHvuvpars_flat
phot::IPhotonMappingTransformations::OpDetID_t OpDetID_t
Type of (global) optical detector ID.
std::vector< float > const * Params_t
bool has_key(std::string const &key) const
float testVoxelSuggestion(float tpcMin, float tpcMax, float cryoMin, float cryoMax, int &nVoxels, float &voxelMin, float &voxelMax, float voxelSizeGoal, int jog, std::string *logString=nullptr) const
unsigned int NOpDets() const
Number of OpDets in the whole detector.
virtual bool isVoxelValid(size_t Voxel) const
double fangle_bin_timing_vuv
bool fApplyVISBorderCorrection
std::vector< std::vector< double > > fGHvuvpars_dome
Encapsulate the geometry of an optical detector.
void SetTimingPar(size_t Voxel, size_t OpChannel, float Count, size_t parnum)
std::vector< std::vector< double > > fExpo_over_Landau_norm
const sim::PhotonVoxelDef & GetVoxelDef() const
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
double DistanceToPoint(geo::Point_t const &point) const
Returns the distance of the specified point from detector center [cm].
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
void LoadVisSemiAnalyticProperties(double &delta_angulo_vis, double &radius) const
General LArSoft Utilities.
std::vector< std::vector< double > > fMpv
std::optional< std::array< NeiInfo, 8U > > GetNeighboringVoxelIDs(Point const &v) const
Returns IDs of the eight neighboring voxels around v.
virtual T0s_t GetReflT0s(size_t Voxel) const =0
void SetLibraryEntry(int VoxID, OpDetID_t libOpChannel, float N, bool wantReflected=false)
A base class aware of world box coordinatesAn object describing a simple shape can inherit from this ...
A container for photon visibility mapping data.
const TPCGeo & TPC(unsigned int itpc) const
Return the itpc'th TPC in the cryostat.
IPhotonLibrary * fTheLibrary
double finflexion_point_distance
Point GetCenter() const
Returns the center of the voxel (type Point).
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
std::vector< std::vector< double > > fborder_corr_dome
float GetTimingPar(size_t Voxel, size_t OpChannel, size_t parnum) const
float doGetVisibility(geo::Point_t const &p, unsigned int OpChannel, bool wantReflected=false) const
std::vector< double > fborder_corr_angulo_flat
void ExtendToInclude(Coord_t x, Coord_t y, Coord_t z)
Extends the current box to also include the specified point.
unsigned int GetNVoxels() const
Returns the total number of voxels in the volume.
void SetLibraryTimingTF1Entry(int VoxID, int OpChannel, TF1 const &func)
std::vector< std::vector< std::vector< double > > > fvispars_dome
std::vector< std::vector< double > > fNorm_over_entries
const float * Counts_t
Type for visibility count per optical channel.
geo::BoxBoundedGeo const & Boundaries() const
Returns boundaries of the cryostat (in centimetres).
static double DistanceToOpDetImpl(geo::Point_t const &p, unsigned int OpDet)
MappedT0s_t doGetReflT0s(geo::Point_t const &p) const
static double SolidAngleFactorImpl(geo::Point_t const &p, unsigned int OpDet)
size_t NOpChannels() const
void SetReflCount(size_t Voxel, size_t OpChannel, float Count)
std::vector< std::vector< double > > fSlope
phot::IPhotonLibrary::Functions_t GetLibraryTimingTF1Entries(int VoxID) const
std::vector< double > fborder_corr_angulo_dome
phot::IPhotonLibrary::Params_t GetLibraryTimingParEntries(int VoxID) const
std::vector< std::vector< std::vector< double > > > fvispars_flat
void put(std::string const &key)
art framework interface to geometry description
cet::coded_exception< error, detail::translate > exception
PhotonVoxel GetPhotonVoxel(int ID) const