LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
PropagationTimeModel.cxx
Go to the documentation of this file.
1 #include "PropagationTimeModel.h"
3 
4 // LArSoft libraries
11 
12 // support libraries
13 #include "cetlib_except/exception.h"
14 #include "fhiclcpp/ParameterSet.h"
16 
17 #include "TMath.h"
18 
19 #include <iostream>
20 
21 namespace {
22  //......................................................................
23  double finter_d(const double* x, const double* par)
24  {
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);
28  }
29 
30  //......................................................................
31  double model_close(const double* x, const double* par)
32  {
33  // par0 = joining point
34  // par1 = Landau MPV
35  // par2 = Landau width
36  // par3 = normalization
37  // par4 = Expo cte
38  // par5 = Expo tau
39  // par6 = t_min
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.;
44  return (y1 + y2);
45  }
46 
47  //......................................................................
48  double model_far(const double* x, const double* par)
49  {
50  // par1 = Landau MPV
51  // par2 = Landau width
52  // par3 = normalization
53  // par0 = t_min
54  if (x[0] <= par[0]) return 0.;
55  return par[3] * TMath::Landau(x[0], par[1], par[2]);
56  }
57 }
58 
59 namespace phot {
60 
62  const fhicl::ParameterSet& VISTimingParams,
63  CLHEP::HepRandomEngine& scintTimeEngine,
64  const bool doReflectedLight,
65  const bool GeoPropTimeOnly)
66  : fGeoPropTimeOnly(GeoPropTimeOnly)
67  , fUniformGen(scintTimeEngine)
68  , fGeom(*(lar::providerFrom<geo::Geometry>()))
69  , fplane_depth(std::abs(fGeom.TPC().GetCathodeCenter().X()))
70  , fOpDetCenter(opDetCenters())
71  , fOpDetOrientation(opDetOrientations())
72  {
73  mf::LogInfo("PropagationTimeModel")
74  << "Initializing Photon propagation time model." << std::endl;
75  if (!fGeoPropTimeOnly) {
76  // Direct / VUV
77  mf::LogInfo("PropagationTimeModel") << "Using VUV timing parameterization";
78  fstep_size = VUVTimingParams.get<double>("step_size");
79  fmin_d = VUVTimingParams.get<double>("min_d");
80  fvuv_vgroup_mean = VUVTimingParams.get<double>("vuv_vgroup_mean");
81  fvuv_vgroup_max = VUVTimingParams.get<double>("vuv_vgroup_max");
82  finflexion_point_distance = VUVTimingParams.get<double>("inflexion_point_distance");
83  fangle_bin_timing_vuv = VUVTimingParams.get<double>("angle_bin_timing_vuv");
84  generateVUVParams(VUVTimingParams, scintTimeEngine);
85 
86  // Reflected / Visible
87  if (doReflectedLight) {
88  mf::LogInfo("PropagationTimeModel") << "Using VIS (reflected) timing parameterization";
89  fdistances_refl = VISTimingParams.get<std::vector<double>>("Distances_refl");
90  fradial_distances_refl = VISTimingParams.get<std::vector<double>>("Distances_radial_refl");
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");
94  fvis_vmean = VISTimingParams.get<double>("vis_vmean");
95  fangle_bin_timing_vis = VISTimingParams.get<double>("angle_bin_timing_vis");
96  }
97  }
98 
99  if (fGeoPropTimeOnly) {
100  mf::LogInfo("PropagationTimeModel") << "Using geometric VUV time propagation";
101  fvuv_vgroup_mean = VUVTimingParams.get<double>("vuv_vgroup_mean");
102  }
103 
104  mf::LogInfo("PropagationTimeModel") << "Photon propagation time model initalized." << std::endl;
105  }
106 
107  //......................................................................
108  // Propagation time calculation function
109  void PropagationTimeModel::propagationTime(std::vector<double>& arrivalTimes,
110  const geo::Point_t& x0,
111  const size_t OpChannel,
112  const bool Reflected)
113  {
114  if (!fGeoPropTimeOnly) {
115  // Get VUV photons transport time distribution from the parametrization
116  geo::Point_t const& opDetCenter = fOpDetCenter[OpChannel];
117  if (!Reflected) {
118  double distance =
119  std::hypot(x0.X() - opDetCenter.X(), x0.Y() - opDetCenter.Y(), x0.Z() - opDetCenter.Z());
120  double cosine;
121  if (fOpDetOrientation[OpChannel] == 1)
122  cosine = std::abs(x0.Y() - opDetCenter.Y()) / distance;
123  else
124  cosine = std::abs(x0.X() - opDetCenter.X()) / distance;
125 
126  double theta = fast_acos(cosine) * 180. / CLHEP::pi;
127  int angle_bin = theta / fangle_bin_timing_vuv;
128  getVUVTimes(arrivalTimes, distance, angle_bin); // in ns
129  }
130  else {
131  getVISTimes(arrivalTimes, x0, opDetCenter); // in ns
132  }
133  }
134  else if (fGeoPropTimeOnly && !Reflected) {
135  // Get VUV photons arrival time geometrically
136  geo::Point_t const& opDetCenter = fOpDetCenter[OpChannel];
137  double distance =
138  std::hypot(x0.X() - opDetCenter.X(), x0.Y() - opDetCenter.Y(), x0.Z() - opDetCenter.Z());
139  getVUVTimesGeo(arrivalTimes, distance); // in ns
140  }
141  else {
142  throw cet::exception("PropagationTimeModel") << "Propagation time model not found.";
143  }
144  }
145 
146  //......................................................................
147  // VUV propagation times calculation function
148  void PropagationTimeModel::getVUVTimes(std::vector<double>& arrivalTimes,
149  const double distance,
150  const size_t angle_bin)
151  {
152  if (distance < fmin_d) {
153  // times are fixed shift i.e. direct path only
154  double t_prop_correction = distance / fvuv_vgroup_mean;
155  for (size_t i = 0; i < arrivalTimes.size(); ++i) {
156  arrivalTimes[i] = t_prop_correction;
157  }
158  }
159  else {
160  // determine nearest parameterisation in discretisation
161  int index = std::round((distance - fmin_d) / fstep_size);
162  // randomly sample parameterisation for each photon
163  for (size_t i = 0; i < arrivalTimes.size(); ++i) {
164  arrivalTimes[i] = fVUVTimingGen[angle_bin][index].fire() *
165  (fVUV_max[angle_bin][index] - fVUV_min[angle_bin][index]) +
166  fVUV_min[angle_bin][index];
167  }
168  }
169  }
170 
171  //......................................................................
172  // VUV arrival times calculation function
173  // - pure geometric approximation for use in Xenon doped scenarios
174  void PropagationTimeModel::getVUVTimesGeo(std::vector<double>& arrivalTimes,
175  const double distance) const
176  {
177  // times are fixed shift i.e. direct path only
178  double t_prop_correction = distance / fvuv_vgroup_mean;
179  for (size_t i = 0; i < arrivalTimes.size(); ++i) {
180  arrivalTimes[i] = t_prop_correction;
181  }
182  }
183 
184  //......................................................................
185  // VUV propagation times parameterization generation function
187  CLHEP::HepRandomEngine& scintTimeEngine)
188  {
189  mf::LogInfo("PropagationTimeModel") << "Generating VUV parameters";
190  double max_d = VUVTimingParams.get<double>("max_d");
191  const size_t num_params =
192  (max_d - fmin_d) / fstep_size; // for d < fmin_d, no parameterisaton, a
193  // delta function is used instead
194  const size_t num_angles = std::round(90. / fangle_bin_timing_vuv);
195 
196  // initialise vectors to contain range parameterisations
197  double dummy[1] = {1.};
198  fVUVTimingGen = std::vector(num_angles, std::vector(num_params, CLHEP::RandGeneral(dummy, 1)));
199  fVUV_max = std::vector(num_angles, std::vector(num_params, 0.0));
200  fVUV_min = std::vector(num_angles, std::vector(num_params, 0.0));
201 
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");
210 
211  // time range
212  const double signal_t_range = 5000.;
213 
214  for (size_t index = 0; index < num_params; ++index) {
215  double distance_in_cm = (index * fstep_size) + fmin_d;
216 
217  // direct path transport time
218  double t_direct_mean = distance_in_cm / fvuv_vgroup_mean;
219  double t_direct_min = distance_in_cm / fvuv_vgroup_max;
220 
221  // number of sampling points, for shorter distances, peak is
222  // sharper so more sensitive sampling required
223  int sampling;
224  if (distance_in_cm < 2. * fmin_d)
225  sampling = 10000;
226  else if (distance_in_cm < 4. * fmin_d)
227  sampling = 5000;
228  else
229  sampling = 1000;
230 
231  for (size_t angle_bin = 0; angle_bin < num_angles; ++angle_bin) {
232  // Defining the model function(s) describing the photon
233  // transportation timing vs distance.
234  // Getting the landau parameters from the time parametrization
235  std::array<double, 3> pars_landau;
236  interpolate3(pars_landau,
237  parameters[0][0],
238  parameters[2][angle_bin],
239  parameters[3][angle_bin],
240  parameters[1][angle_bin],
241  distance_in_cm,
242  true);
243  TF1 VUVTiming;
244  // Deciding which time model to use (depends on the distance)
245  // defining useful times for the VUV arrival time shapes
246  if (distance_in_cm >= finflexion_point_distance) {
247  // Set model: Landau
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);
251  }
252  else {
253  // Set model: Landau + Exponential
254  double pars_expo[2];
255  // Getting the exponential parameters from the time parametrization
256  pars_expo[1] =
257  interpolate(parameters[4][0], parameters[5][angle_bin], distance_in_cm, true);
258  pars_expo[0] =
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]);
262  // this is to find the intersection point between the two functions:
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);
269  // the functions must intersect - output warning if they don't
270  if (minVal > 0.015) {
271  mf::LogWarning("PropagationTimeModel")
272  << "WARNING: Parametrization of VUV light discontinuous for "
273  "distance = "
274  << distance_in_cm << "\n"
275  << "This shouldn't be happening " << std::endl;
276  }
277  double parsfinal[7] = {t_int,
278  pars_landau[0],
279  pars_landau[1],
280  pars_landau[2],
281  pars_expo[0],
282  pars_expo[1],
283  t_direct_min};
284  VUVTiming = TF1("VUVTiming", model_close, 0., signal_t_range, 7);
285  VUVTiming.SetParameters(parsfinal);
286  }
287 
288  // store min/max, necessary to transform to the domain of the
289  // original distribution
290  // const size_t nq_max = 1;
291  double xq_max[1] = {0.975}; // include 97.5% of tail
292  double yq_max[1];
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);
298  fVUV_max[angle_bin][index] = max;
299  fVUV_min[angle_bin][index] = min;
300 
301  // create the distributions that represent the parametrised timing,
302  // and use those to create a RNG that samples said distributions
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);
307  fVUVTimingGen[angle_bin][index] =
308  CLHEP::RandGeneral(scintTimeEngine, vuv_timings.data(), vuv_timings.size());
309  } // index < num_params
310  } // angle_bin < num_angles
311  }
312 
313  //......................................................................
314  // VIS arrival times calculation functions
315  void PropagationTimeModel::getVISTimes(std::vector<double>& arrivalTimes,
316  const geo::Point_t& scintPoint,
317  const geo::Point_t& opDetPoint)
318  {
319  // ***************************************************************************
320  // Calculation of earliest arrival times and corresponding unsmeared
321  // distribution
322  // ***************************************************************************
323 
324  // set plane_depth for correct TPC:
325  double plane_depth;
326  if (scintPoint.X() < 0.)
327  plane_depth = -fplane_depth;
328  else
329  plane_depth = fplane_depth;
330 
331  // calculate point of reflection for shortest path
332  geo::Point_t bounce_point(plane_depth, scintPoint.Y(), scintPoint.Z());
333 
334  // calculate distance travelled by VUV light and by vis light
335  double VUVdist = std::sqrt((bounce_point - scintPoint).Mag2());
336  double Visdist = std::sqrt((opDetPoint - bounce_point).Mag2());
337 
338  // calculate times taken by VUV part of path
339  int angle_bin_vuv = 0; // on-axis by definition
340  getVUVTimes(arrivalTimes, VUVdist, angle_bin_vuv);
341 
342  // sum parts to get total transport times times
343  for (size_t i = 0; i < arrivalTimes.size(); ++i) {
344  arrivalTimes[i] += Visdist / fvis_vmean;
345  }
346 
347  // ***************************************************************************
348  // Smearing of arrival time distribution
349  // ***************************************************************************
350  // calculate fastest time possible
351  // vis part
352  double vis_time = Visdist / fvis_vmean;
353  // vuv part
354  double vuv_time;
355  if (VUVdist < fmin_d) { vuv_time = VUVdist / fvuv_vgroup_max; }
356  else {
357  // find index of required parameterisation
358  const size_t index = std::round((VUVdist - fmin_d) / fstep_size);
359  // find shortest time
360  vuv_time = fVUV_min[angle_bin_vuv][index];
361  }
362  double fastest_time = vis_time + vuv_time;
363 
364  // calculate angle theta between bound_point and optical detector
365  double cosine_theta = std::abs(opDetPoint.X() - bounce_point.X()) / Visdist;
366  double theta = fast_acos(cosine_theta) * 180. / CLHEP::pi;
367 
368  // determine smearing parameters using interpolation of generated points:
369  // 1). tau = exponential smearing factor, varies with distance and angle
370  // 2). cutoff = largest smeared time allowed, preventing excessively large
371  // times caused by exponential distance to cathode
372  double distance_cathode_plane = std::abs(plane_depth - scintPoint.X());
373  // angular bin
374  size_t theta_bin = theta / fangle_bin_timing_vis;
375  // radial distance from centre of TPC (y,z plane)
376  double r =
377  std::hypot(scintPoint.Y() - fcathode_centre.Y(), scintPoint.Z() - fcathode_centre.Z());
378 
379  // cut-off and tau
380  // cut-off
381  // interpolate in d_c for each r bin
382  std::vector<double> interp_vals(fcut_off_pars[theta_bin].size(), 0.0);
383  for (size_t i = 0; i < fcut_off_pars[theta_bin].size(); i++) {
384  interp_vals[i] =
385  interpolate(fdistances_refl, fcut_off_pars[theta_bin][i], distance_cathode_plane, true);
386  }
387  // interpolate in r
388  double cutoff = interpolate(fradial_distances_refl, interp_vals, r, true);
389 
390  // tau
391  // interpolate in x for each r bin
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++) {
394  interp_vals_tau[i] =
395  interpolate(fdistances_refl, ftau_pars[theta_bin][i], distance_cathode_plane, true);
396  }
397  // interpolate in r
398  double tau = interpolate(fradial_distances_refl, interp_vals_tau, r, true);
399 
400  // apply smearing:
401  for (size_t i = 0; i < arrivalTimes.size(); ++i) {
402  double arrival_time_smeared;
403  // if time is already greater than cutoff, do not apply smearing
404  if (arrivalTimes[i] >= cutoff) { continue; }
405  // otherwise smear
406  else {
407  unsigned int counter = 0;
408  // loop until time generated is within cutoff limit
409  // most are within single attempt, very few take more than two
410  do {
411  // don't attempt smearings too many times
412  if (counter >= 10) {
413  arrival_time_smeared = arrivalTimes[i]; // don't smear
414  break;
415  }
416  else {
417  // generate random number in appropriate range
418  double x = fUniformGen.fire(0.5, 1.0);
419  // apply the exponential smearing
420  arrival_time_smeared =
421  arrivalTimes[i] + (arrivalTimes[i] - fastest_time) * (std::pow(x, -tau) - 1);
422  }
423  counter++;
424  } while (arrival_time_smeared > cutoff);
425  }
426  arrivalTimes[i] = arrival_time_smeared;
427  }
428  }
429 
431  {
432  larg4::ISTPC is_tpc = larg4::ISTPC{fGeom};
433  std::vector<geo::BoxBoundedGeo> activeVolumes = is_tpc.extractActiveLArVolume(fGeom);
434  geo::Point_t cathode_centre = {
435  fGeom.TPC().GetCathodeCenter().X(), activeVolumes[0].CenterY(), activeVolumes[0].CenterZ()};
436  return cathode_centre;
437  }
438 
439  std::vector<geo::Point_t> PropagationTimeModel::opDetCenters() const
440  {
441  std::vector<geo::Point_t> opDetCenter;
442  for (size_t const i : util::counter(fGeom.NOpDets())) {
443  geo::OpDetGeo const& opDet = fGeom.OpDetGeoFromOpDet(i);
444  opDetCenter.push_back(opDet.GetCenter());
445  }
446  return opDetCenter;
447  }
448 
450  {
451  std::vector<int> opDetOrientation;
452  for (size_t const i : util::counter(fGeom.NOpDets())) {
453  geo::OpDetGeo const& opDet = fGeom.OpDetGeoFromOpDet(i);
454  if (opDet.isSphere()) { // dome PMTs
455  opDetOrientation.push_back(0);
456  }
457  else if (opDet.isBar()) {
458  // determine orientation to get correction OpDet dimensions
459  if (opDet.Width() > opDet.Height()) { // laterals, Y dimension smallest
460  opDetOrientation.push_back(1);
461  }
462  else { // anode/cathode (default), X dimension smallest
463  opDetOrientation.push_back(0);
464  }
465  }
466  else {
467  opDetOrientation.push_back(0);
468  }
469  }
470  return opDetOrientation;
471  }
472 
473 } // namespace phot
Float_t x
Definition: compare.C:6
TRandom r
Definition: spectrum.C:23
Point_t GetCathodeCenter() const
Returns the expected drift direction based on geometry.
Definition: TPCGeo.cxx:139
std::vector< geo::Point_t > opDetCenters() const
const std::vector< geo::Point_t > fOpDetCenter
static std::vector< geo::BoxBoundedGeo > extractActiveLArVolume(geo::GeometryCore const &geom)
Definition: ISTPC.cxx:46
Utilities related to art service access.
const std::vector< int > fOpDetOrientation
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]
Definition: compare.C:5
geo::GeometryCore const & fGeom
T::provider_type const * providerFrom()
Returns a constant pointer to the provider of specified service.
Definition: ServiceUtil.h:75
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
bool isBar() const
Returns whether the detector shape is a bar (TGeoBBox).
Definition: OpDetGeo.h:167
Point_t const & GetCenter() const
Definition: OpDetGeo.h:71
void generateVUVParams(const fhicl::ParameterSet &VUVTimingParams, CLHEP::HepRandomEngine &scintTimeEngine)
constexpr auto abs(T v)
Returns the absolute value of the argument.
STL namespace.
std::vector< std::vector< CLHEP::RandGeneral > > fVUVTimingGen
Float_t y2[n_points_geant4]
Definition: compare.C:26
bool isSphere() const
Returns whether the detector shape is a hemisphere (TGeoSphere).
Definition: OpDetGeo.h:170
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:101
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:289
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.
Definition: counter.h:292
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
Definition: ParameterSet.h:314
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
unsigned int NOpDets() const
Number of OpDets in the whole detector.
std::vector< double > fdistances_refl
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.
Definition: geo_vectors.h:180
General LArSoft Utilities.
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)
std::vector< int > opDetOrientations() const
double Width() const
Definition: OpDetGeo.h:78
TPCGeo const & TPC(TPCID const &tpcid=details::tpc_zero) const
Returns the specified TPC.
Definition: GeometryCore.h:448
double interpolate(const std::vector< double > &xData, const std::vector< double > &yData, const double x, const bool extrapolate, size_t i)
Float_t X
Definition: plot.C:37
ROOT libraries.
double Height() const
Definition: OpDetGeo.h:79
art framework interface to geometry description
hh[ixs]
Definition: PlotSingle.C:6
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
std::vector< std::vector< double > > fVUV_max
OpDetGeo const & OpDetGeoFromOpDet(unsigned int OpDet) const
Returns the geo::OpDetGeo object for the given detector number.