13 #include "cetlib_except/exception.h"
14 #include "messagefacility/MessageLogger/MessageLogger.h"
23 fVUVTimingParams(VUVTimingParams)
24 , fVISTimingParams(VISTimingParams)
25 , fdoReflectedLight(doReflectedLight)
26 , fGeoPropTimeOnly(GeoPropTimeOnly)
27 , fISTPC{*(lar::providerFrom<geo::Geometry>())}
32 mf::LogInfo(
"PropagationTimeModel") <<
"Photon propagation time model initalized." << std::endl;
44 mf::LogInfo(
"PropagationTimeModel") <<
"Using VUV timing parameterization";
49 fparameters[3] =
fVUVTimingParams.get<std::vector<std::vector<double>>>(
"Width");
51 fparameters[5] =
fVUVTimingParams.get<std::vector<std::vector<double>>>(
"Slope");
52 fparameters[6] =
fVUVTimingParams.get<std::vector<std::vector<double>>>(
"Expo_over_Landau_norm");
64 const size_t num_params = (fmax_d -
fmin_d) / fstep_size;
65 const size_t num_angles = std::round(90/fangle_bin_timing_vuv);
75 for (
size_t angle_bin=0; angle_bin < num_angles; ++angle_bin) {
76 for (
size_t index=0; index < num_params; ++index) {
83 mf::LogInfo(
"PropagationTimeModel") <<
"Using VIS (reflected) timing parameterization";
96 mf::LogInfo(
"PropagationTimeModel") <<
"Using geometric VUV time propagation";
107 fActiveVolumes[0].CenterY(),
108 fActiveVolumes[0].CenterZ()};
122 else if (opDet.
isBar()) {
142 const size_t OpChannel,
149 double distance = std::hypot(x0.X() - opDetCenter.X(), x0.Y() - opDetCenter.Y(), x0.Z() - opDetCenter.Z());
152 else cosine =
std::abs(x0.X() - opDetCenter.X()) / distance;
156 getVUVTimes(arrival_time_dist, distance, angle_bin);
166 double distance = std::hypot(x0.X() - opDetCenter.X(), x0.Y() - opDetCenter.Y(), x0.Z() - opDetCenter.Z());
170 throw cet::exception(
"PropagationTimeModel")
171 <<
"Propagation time model not found.";
183 for (
size_t i = 0; i < arrivalTimes.size(); ++i) {
184 arrivalTimes[i] = t_prop_correction;
191 for (
size_t i = 0; i < arrivalTimes.size(); ++i) {
204 for (
size_t i = 0; i < arrivalTimes.size(); ++i) {
205 arrivalTimes[i] = t_prop_correction;
218 const double signal_t_range = 5000.;
229 std::array<double, 3> pars_landau;
240 double pars_far[4] = {t_direct_min, pars_landau[0], pars_landau[1], pars_landau[2]};
242 VUVTiming = TF1(
"VUVTiming",
model_far, 0, signal_t_range, 4);
243 VUVTiming.SetParameters(pars_far);
247 VUVTiming = TF1(
"VUVTiming",
model_close, 0, signal_t_range, 7);
253 pars_expo[0] *= pars_landau[2];
254 pars_expo[0] = std::log(pars_expo[0]);
256 TF1 fint = TF1(
"fint",
finter_d, pars_landau[0], 4 * t_direct_mean, 5);
257 double parsInt[5] = {
258 pars_landau[0], pars_landau[1], pars_landau[2], pars_expo[0], pars_expo[1]};
259 fint.SetParameters(parsInt);
260 double t_int = fint.GetMinimumX();
261 double minVal = fint.Eval(t_int);
263 if (minVal > 0.015) {
264 mf::LogWarning(
"PropagationTimeModel")
265 <<
"WARNING: Parametrization of VUV light discontinuous for distance = "
266 << distance_in_cm << std::endl;
267 mf::LogWarning(
"PropagationTimeModel")
268 <<
"WARNING: This shouldn't be happening " << std::endl;
270 double parsfinal[7] = {t_int,
277 VUVTiming.SetParameters(parsfinal);
283 if (distance_in_cm < 50) fsampling = 10000;
284 else if (distance_in_cm < 100) fsampling = 5000;
285 else fsampling = 1000;
286 VUVTiming.SetNpx(fsampling);
290 const size_t nq_max = 1;
291 double xq_max[nq_max];
292 double yq_max[nq_max];
294 VUVTiming.GetQuantiles(nq_max, yq_max, xq_max);
295 double max = yq_max[0];
297 double min = t_direct_min;
311 const TVector3 &ScintPoint,
312 const TVector3 &OpDetPoint)
325 TVector3 bounce_point(plane_depth,ScintPoint[1],ScintPoint[2]);
328 double VUVdist = (bounce_point - ScintPoint).Mag();
329 double Visdist = (OpDetPoint - bounce_point).Mag();
332 int angle_bin_vuv = 0;
336 for (
size_t i = 0; i < arrivalTimes.size(); ++i) {
355 vuv_time =
fVUV_min[angle_bin_vuv][index];
358 double fastest_time = vis_time + vuv_time;
361 double cosine_theta =
std::abs(OpDetPoint[0] - bounce_point[0]) / Visdist;
368 double distance_cathode_plane =
std::abs(plane_depth - ScintPoint[0]);
378 for (
size_t i = 0; i <
fcut_off_pars[theta_bin].size(); i++){
386 std::vector<double> interp_vals_tau(
ftau_pars[theta_bin].
size(), 0.0);
387 for (
size_t i = 0; i <
ftau_pars[theta_bin].size(); i++){
394 for (
size_t i = 0; i < arrivalTimes.size(); ++i) {
395 double arrival_time_smeared;
397 if (arrivalTimes[i] >= cutoff) {
continue; }
406 arrival_time_smeared = arrivalTimes[i];
413 arrival_time_smeared =
414 arrivalTimes[i] + (arrivalTimes[i] - fastest_time) * (std::pow(x, -tau) - 1);
417 }
while (arrival_time_smeared > cutoff);
419 arrivalTimes[i] = arrival_time_smeared;
427 double negate = double(x < 0);
429 x -= double(x > 1.0) * (x - 1.0);
430 double ret = -0.0187293;
432 ret = ret + 0.0742610;
434 ret = ret - 0.2121144;
436 ret = ret + 1.5707288;
437 ret = ret * std::sqrt(1.0 - x);
438 ret = ret - 2. * negate * ret;
439 return negate * 3.14159265358979 + ret;
449 const std::vector<double>& yData,
455 size_t size = xData.size();
456 if (x >= xData[size - 2]) {
460 while (x > xData[i + 1])
464 double xL = xData[i];
465 double xR = xData[i + 1];
466 double yL = yData[i];
467 double yR = yData[i + 1];
469 if (x < xL)
return yL;
470 if (x > xR)
return yL;
472 const double dydx = (yR - yL) / (xR - xL);
473 return yL + dydx * (x - xL);
479 const std::vector<double>& xData,
480 const std::vector<double>& yData1,
481 const std::vector<double>& yData2,
482 const std::vector<double>& yData3,
486 size_t size = xData.size();
488 if (x >= xData[size - 2]) {
492 while (x > xData[i + 1])
495 double xL = xData[i];
496 double xR = xData[i + 1];
497 double yL1 = yData1[i];
498 double yR1 = yData1[i + 1];
499 double yL2 = yData2[i];
500 double yR2 = yData2[i + 1];
501 double yL3 = yData3[i];
502 double yR3 = yData3[i + 1];
518 const double m = (x - xL) / (xR - xL);
519 inter[0] = m * (yR1 - yL1) + yL1;
520 inter[1] = m * (yR2 - yL2) + yL2;
521 inter[2] = m * (yR3 - yL3) + yL3;
528 double y1 = par[2] * TMath::Landau(x[0], par[0], par[1]);
529 double y2 = TMath::Exp(par[3] + x[0] * par[4]);
531 return TMath::Abs(y1 - y2);
546 double y1 = par[3] * TMath::Landau(x[0], par[1], par[2]);
547 double y2 = TMath::Exp(par[4] + x[0] * par[5]);
548 if (x[0] <= par[6] || x[0] > par[0]) y1 = 0.;
549 if (x[0] < par[0]) y2 = 0.;
563 double y = par[3] * TMath::Landau(x[0], par[1], par[2]);
564 if (x[0] <= par[0]) y = 0.;
double fangle_bin_timing_vuv
Specializations of geo_vectors_utils.h for ROOT old vector types.
OpDetGeo const & OpDetGeoFromOpDet(unsigned int OpDet) const
Returns the geo::OpDetGeo object for the given detector number.
static std::vector< geo::BoxBoundedGeo > extractActiveLArVolume(geo::GeometryCore const &geom)
Utilities related to art service access.
void propagationTime(std::vector< double > &arrival_time_dist, geo::Point_t const &x0, const size_t OpChannel, bool Reflected=false)
Encapsulate the construction of a single cyostat.
process_name opflash particleana ie x
void getVUVTimes(std::vector< double > &arrivalTimes, const double distance_in_cm, const size_t angle_bin)
bool isBar() const
Returns whether the detector shape is a bar (TGeoBBox).
Point GetCathodeCenter() const
double fangle_bin_timing_vis
std::size_t size(FixedBins< T, C > const &) noexcept
void GetCenter(double *xyz, double localz=0.0) const
PropagationTimeModel(fhicl::ParameterSet VUVTimingParams, fhicl::ParameterSet VISTimingParams, CLHEP::HepRandomEngine &ScintTimeEngine, bool doReflectedLight=false, bool GeoPropTimeOnly=false)
static double model_close(const double *x, const double *par)
void getVISTimes(std::vector< double > &arrivalTimes, const TVector3 &ScintPoint, const TVector3 &OpDetPoint)
static double finter_d(const double *x, const double *par)
tuple m
now if test mode generate materials, CRT shell, world, gdml header else just generate CRT shell for u...
std::vector< geo::Point_t > fOpDetCenter
const bool fdoReflectedLight
bool isSphere() const
Returns whether the detector shape is a hemisphere (TGeoSphere).
void interpolate3(std::array< double, 3 > &inter, const std::vector< double > &xData, const std::vector< double > &yData1, const std::vector< double > &yData2, const std::vector< double > &yData3, double x, bool extrapolate)
double interpolate(const std::vector< double > &xData, const std::vector< double > &yData, double x, bool extrapolate, size_t i=0) const
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Access the description of detector geometry.
std::vector< std::vector< std::vector< double > > > ftau_pars
auto counter(T begin, T end)
Returns an object to iterate values from begin to end in a range-for loop.
process_name opflash particleana ie ie y
std::vector< double > fradial_distances_refl
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
static double model_far(const double *x, const double *par)
const bool fGeoPropTimeOnly
std::vector< geo::BoxBoundedGeo > fActiveVolumes
double finflexion_point_distance
double fast_acos(double x) const
Test of util::counter and support utilities.
std::vector< int > fOpDetOrientation
Description of geometry of one entire detector.
std::vector< std::vector< double > > fVUV_max
unsigned int NOpDets() const
Number of OpDets in the whole detector.
Encapsulate the geometry of an optical detector.
void getVUVTimesGeo(std::vector< double > &arrivalTimes, const double distance_in_cm)
std::vector< std::vector< double > > fparameters[7]
const fhicl::ParameterSet fVUVTimingParams
TVector3 toTVector3(Vector const &v)
Converts a vector into a TVector3.
std::vector< std::vector< std::vector< double > > > fcut_off_pars
std::vector< std::vector< TF1 > > fVUV_timing
std::vector< std::vector< double > > fVUV_min
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
std::vector< double > fdistances_refl
CLHEP::RandFlat fUniformGen
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
void generateParam(const size_t index, const size_t angle_bin)
const fhicl::ParameterSet fVISTimingParams
art framework interface to geometry description
createEngine fScintTimeEngine(art::ServiceHandle< rndm::NuRandomService >() ->createEngine(*this,"HepJamesRandom","scinttime", p,"SeedScintTime"))