13 #include "cetlib_except/exception.h" 23 double finter_d(
const double*
x,
const double* par)
25 double y1 = par[2] * TMath::Landau(x[0], par[0], par[1]);
26 double y2 = TMath::Exp(par[3] + x[0] * par[4]);
27 return TMath::Abs(y1 - y2);
31 double model_close(
const double*
x,
const double* par)
40 double y1 = par[3] * TMath::Landau(x[0], par[1], par[2]);
41 double y2 = TMath::Exp(par[4] + x[0] * par[5]);
42 if (x[0] <= par[6] || x[0] > par[0]) y1 = 0.;
43 if (x[0] < par[0]) y2 = 0.;
48 double model_far(
const double* x,
const double* par)
54 if (x[0] <= par[0])
return 0.;
55 return par[3] * TMath::Landau(x[0], par[1], par[2]);
63 CLHEP::HepRandomEngine& scintTimeEngine,
64 const bool doReflectedLight,
65 const bool GeoPropTimeOnly)
66 : fGeoPropTimeOnly(GeoPropTimeOnly)
67 , fUniformGen(scintTimeEngine)
69 , fplane_depth(
std::
abs(fGeom.TPC().GetCathodeCenter().
X()))
70 , fOpDetCenter(opDetCenters())
71 , fOpDetOrientation(opDetOrientations())
74 <<
"Initializing Photon propagation time model." << std::endl;
77 mf::LogInfo(
"PropagationTimeModel") <<
"Using VUV timing parameterization";
79 fmin_d = VUVTimingParams.
get<
double>(
"min_d");
87 if (doReflectedLight) {
88 mf::LogInfo(
"PropagationTimeModel") <<
"Using VIS (reflected) timing parameterization";
92 VISTimingParams.
get<std::vector<std::vector<std::vector<double>>>>(
"Cut_off");
93 ftau_pars = VISTimingParams.
get<std::vector<std::vector<std::vector<double>>>>(
"Tau");
100 mf::LogInfo(
"PropagationTimeModel") <<
"Using geometric VUV time propagation";
104 mf::LogInfo(
"PropagationTimeModel") <<
"Photon propagation time model initalized." << std::endl;
111 const size_t OpChannel,
112 const bool Reflected)
119 std::hypot(x0.X() - opDetCenter.X(), x0.Y() - opDetCenter.Y(), x0.Z() - opDetCenter.Z());
122 cosine =
std::abs(x0.Y() - opDetCenter.Y()) / distance;
124 cosine =
std::abs(x0.X() - opDetCenter.X()) / distance;
138 std::hypot(x0.X() - opDetCenter.X(), x0.Y() - opDetCenter.Y(), x0.Z() - opDetCenter.Z());
142 throw cet::exception(
"PropagationTimeModel") <<
"Propagation time model not found.";
149 const double distance,
150 const size_t angle_bin)
155 for (
size_t i = 0; i < arrivalTimes.size(); ++i) {
156 arrivalTimes[i] = t_prop_correction;
163 for (
size_t i = 0; i < arrivalTimes.size(); ++i) {
175 const double distance)
const 179 for (
size_t i = 0; i < arrivalTimes.size(); ++i) {
180 arrivalTimes[i] = t_prop_correction;
187 CLHEP::HepRandomEngine& scintTimeEngine)
189 mf::LogInfo(
"PropagationTimeModel") <<
"Generating VUV parameters";
190 double max_d = VUVTimingParams.
get<
double>(
"max_d");
191 const size_t num_params =
197 double dummy[1] = {1.};
202 std::vector<std::vector<double>> parameters[7];
203 parameters[0] =
std::vector(1, VUVTimingParams.
get<std::vector<double>>(
"Distances_landau"));
204 parameters[1] = VUVTimingParams.
get<std::vector<std::vector<double>>>(
"Norm_over_entries");
205 parameters[2] = VUVTimingParams.
get<std::vector<std::vector<double>>>(
"Mpv");
206 parameters[3] = VUVTimingParams.
get<std::vector<std::vector<double>>>(
"Width");
207 parameters[4] =
std::vector(1, VUVTimingParams.
get<std::vector<double>>(
"Distances_exp"));
208 parameters[5] = VUVTimingParams.
get<std::vector<std::vector<double>>>(
"Slope");
209 parameters[6] = VUVTimingParams.
get<std::vector<std::vector<double>>>(
"Expo_over_Landau_norm");
212 const double signal_t_range = 5000.;
214 for (
size_t index = 0; index < num_params; ++index) {
224 if (distance_in_cm < 2. *
fmin_d)
226 else if (distance_in_cm < 4. *
fmin_d)
231 for (
size_t angle_bin = 0; angle_bin < num_angles; ++angle_bin) {
235 std::array<double, 3> pars_landau;
238 parameters[2][angle_bin],
239 parameters[3][angle_bin],
240 parameters[1][angle_bin],
248 double pars_far[4] = {t_direct_min, pars_landau[0], pars_landau[1], pars_landau[2]};
249 VUVTiming = TF1(
"VUVTiming", model_far, 0., signal_t_range, 4);
250 VUVTiming.SetParameters(pars_far);
257 interpolate(parameters[4][0], parameters[5][angle_bin], distance_in_cm,
true);
259 interpolate(parameters[4][0], parameters[6][angle_bin], distance_in_cm,
true);
260 pars_expo[0] *= pars_landau[2];
261 pars_expo[0] = std::log(pars_expo[0]);
263 TF1 fint = TF1(
"fint", finter_d, pars_landau[0], 4. * t_direct_mean, 5);
264 double parsInt[5] = {
265 pars_landau[0], pars_landau[1], pars_landau[2], pars_expo[0], pars_expo[1]};
266 fint.SetParameters(parsInt);
267 double t_int = fint.GetMinimumX();
268 double minVal = fint.Eval(t_int);
270 if (minVal > 0.015) {
272 <<
"WARNING: Parametrization of VUV light discontinuous for " 274 << distance_in_cm <<
"\n" 275 <<
"This shouldn't be happening " << std::endl;
277 double parsfinal[7] = {t_int,
284 VUVTiming = TF1(
"VUVTiming", model_close, 0., signal_t_range, 7);
285 VUVTiming.SetParameters(parsfinal);
291 double xq_max[1] = {0.975};
293 VUVTiming.SetNpx(sampling);
294 VUVTiming.GetQuantiles(1, yq_max, xq_max);
295 double max = yq_max[0];
296 double min = t_direct_min;
297 VUVTiming.SetRange(min, max);
303 auto hh = (TH1D*)VUVTiming.GetHistogram();
304 std::vector<double> vuv_timings(sampling, 0.);
305 for (
int i = 0; i < sampling; ++i)
306 vuv_timings[i] =
hh->GetBinContent(i + 1);
308 CLHEP::RandGeneral(scintTimeEngine, vuv_timings.data(), vuv_timings.size());
326 if (scintPoint.X() < 0.)
332 geo::Point_t bounce_point(plane_depth, scintPoint.Y(), scintPoint.Z());
335 double VUVdist = std::sqrt((bounce_point - scintPoint).Mag2());
336 double Visdist = std::sqrt((opDetPoint - bounce_point).Mag2());
339 int angle_bin_vuv = 0;
343 for (
size_t i = 0; i < arrivalTimes.size(); ++i) {
360 vuv_time =
fVUV_min[angle_bin_vuv][index];
362 double fastest_time = vis_time + vuv_time;
365 double cosine_theta =
std::abs(opDetPoint.X() - bounce_point.X()) / Visdist;
372 double distance_cathode_plane =
std::abs(plane_depth - scintPoint.X());
383 for (
size_t i = 0; i <
fcut_off_pars[theta_bin].size(); i++) {
392 std::vector<double> interp_vals_tau(
ftau_pars[theta_bin].
size(), 0.0);
393 for (
size_t i = 0; i <
ftau_pars[theta_bin].size(); i++) {
401 for (
size_t i = 0; i < arrivalTimes.size(); ++i) {
402 double arrival_time_smeared;
404 if (arrivalTimes[i] >= cutoff) {
continue; }
413 arrival_time_smeared = arrivalTimes[i];
420 arrival_time_smeared =
421 arrivalTimes[i] + (arrivalTimes[i] - fastest_time) * (std::pow(x, -tau) - 1);
424 }
while (arrival_time_smeared > cutoff);
426 arrivalTimes[i] = arrival_time_smeared;
436 return cathode_centre;
441 std::vector<geo::Point_t> opDetCenter;
444 opDetCenter.push_back(opDet.
GetCenter());
451 std::vector<int> opDetOrientation;
455 opDetOrientation.push_back(0);
457 else if (opDet.
isBar()) {
460 opDetOrientation.push_back(1);
463 opDetOrientation.push_back(0);
467 opDetOrientation.push_back(0);
470 return opDetOrientation;
Point_t GetCathodeCenter() const
Returns the expected drift direction based on geometry.
std::vector< geo::Point_t > opDetCenters() const
const std::vector< geo::Point_t > fOpDetCenter
static std::vector< geo::BoxBoundedGeo > extractActiveLArVolume(geo::GeometryCore const &geom)
Utilities related to art service access.
const std::vector< int > fOpDetOrientation
CLHEP::RandFlat fUniformGen
Encapsulate the construction of a single cyostat .
std::vector< std::vector< std::vector< double > > > fcut_off_pars
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, const double x, const bool extrapolate)
Float_t y1[n_points_granero]
geo::GeometryCore const & fGeom
T::provider_type const * providerFrom()
Returns a constant pointer to the provider of specified service.
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
bool isBar() const
Returns whether the detector shape is a bar (TGeoBBox).
Point_t const & GetCenter() const
void generateVUVParams(const fhicl::ParameterSet &VUVTimingParams, CLHEP::HepRandomEngine &scintTimeEngine)
constexpr auto abs(T v)
Returns the absolute value of the argument.
std::vector< std::vector< CLHEP::RandGeneral > > fVUVTimingGen
Float_t y2[n_points_geant4]
bool isSphere() const
Returns whether the detector shape is a hemisphere (TGeoSphere).
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Access the description of the physical detector geometry.
auto counter(T begin, T end)
Returns an object to iterate values from begin to end in a range-for loop.
const geo::Point_t fcathode_centre
std::vector< std::vector< double > > fVUV_min
double fast_acos(double xin)
T get(std::string const &key) const
const double fplane_depth
void propagationTime(std::vector< double > &arrivalTimes, const geo::Point_t &x0, const size_t OpChannel, const bool Reflected=false)
void getVUVTimesGeo(std::vector< double > &arrivalTimes, const double distance_in_cm) const
std::vector< double > fradial_distances_refl
std::vector< std::vector< std::vector< double > > > ftau_pars
Test of util::counter and support utilities.
void getVUVTimes(std::vector< double > &arrivalTimes, const double distance_in_cm, const size_t angle_bin)
geo::Point_t cathodeCentre() const
double fangle_bin_timing_vuv
unsigned int NOpDets() const
Number of OpDets in the whole detector.
std::vector< double > fdistances_refl
double fangle_bin_timing_vis
PropagationTimeModel(const fhicl::ParameterSet &VUVTimingParams, const fhicl::ParameterSet &VISTimingParams, CLHEP::HepRandomEngine &scintTimeEngine, const bool doReflectedLight=false, const bool GeoPropTimeOnly=false)
Encapsulate the geometry of an optical detector.
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
General LArSoft Utilities.
double finflexion_point_distance
LArSoft-specific namespace.
void getVISTimes(std::vector< double > &arrivalTimes, const geo::Point_t &scintPoint, const geo::Point_t &opDetPoint)
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
constexpr T pi()
Returns the constant pi (up to 35 decimal digits of precision)
const bool fGeoPropTimeOnly
std::vector< int > opDetOrientations() const
TPCGeo const & TPC(TPCID const &tpcid=details::tpc_zero) const
Returns the specified TPC.
double interpolate(const std::vector< double > &xData, const std::vector< double > &yData, const double x, const bool extrapolate, size_t i)
art framework interface to geometry description
cet::coded_exception< error, detail::translate > exception
std::vector< std::vector< double > > fVUV_max
OpDetGeo const & OpDetGeoFromOpDet(unsigned int OpDet) const
Returns the geo::OpDetGeo object for the given detector number.