LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
DetectorPropertiesStandard.cxx
Go to the documentation of this file.
1 
7 // Framework includes
8 
9 // LArSoft includes
11 #include "larcorealg/CoreUtils/ProviderUtil.h" // lar::IgnorableProviderConfigKeys()
17 
18 #include "cetlib/pow.h"
20 
21 // Art includes
22 #include "fhiclcpp/types/Table.h"
23 
24 // C/C++ libraries
25 #include <sstream> // std::ostringstream
26 
27 namespace {
28  std::string CheckTimeOffsets(std::set<geo::View_t> const& requested_views,
29  geo::WireReadoutGeom const& wireReadoutGeom)
30  {
31  auto const& present_views = wireReadoutGeom.Views();
32 
33  auto view_diff = [&present_views, &requested_views](geo::View_t const view) {
34  return static_cast<int>(present_views.count(view)) -
35  static_cast<int>(requested_views.count(view));
36  };
37 
38  // It is not an error to specify an offset if the view does not
39  // exist. However, if a view does exist, and an offset does not,
40  // then that will end the job.
41  std::ostringstream errors;
42  if (auto diff = view_diff(geo::kU); diff > 0) { errors << "TimeOffsetU missing for view U.\n"; }
43  if (auto diff = view_diff(geo::kV); diff > 0) { errors << "TimeOffsetV missing for view V.\n"; }
44  if (auto diff = view_diff(geo::kZ); diff > 0) { errors << "TimeOffsetZ missing for view Z.\n"; }
45  if (auto diff = view_diff(geo::kY); diff > 0) { errors << "TimeOffsetY missing for view Y.\n"; }
46  if (auto diff = view_diff(geo::kX); diff > 0) { errors << "TimeOffsetX missing for view X.\n"; }
47  return errors.str();
48  }
49 }
50 
51 namespace detinfo {
52 
53  //--------------------------------------------------------------------
55  fhicl::ParameterSet const& pset,
56  geo::GeometryCore const* geo,
57  geo::WireReadoutGeom const* wireReadoutGeom,
58  detinfo::LArProperties const* lp,
59  std::set<std::string> const& ignore_params)
60  : fLP(lp), fGeo(geo), fChannelMap(wireReadoutGeom)
61  {
62  ValidateAndConfigure(pset, ignore_params);
63  }
64 
65  //--------------------------------------------------------------------
67  std::set<std::string> const& ignore_params)
68  {
69  {
70  mf::LogInfo debug("setupProvider<DetectorPropertiesStandard>");
71 
72  debug << "Asked to ignore " << ignore_params.size() << " keys:";
73  for (auto const& key : ignore_params)
74  debug << " '" << key << "'";
75  }
76 
77  std::set<std::string> ignorable_keys = lar::IgnorableProviderConfigKeys();
78  ignorable_keys.insert(ignore_params.begin(), ignore_params.end());
79 
80  // parses and validates the parameter set:
81  fhicl::Table<Configuration_t> const config{p, ignorable_keys};
82 
83  fEfield = config().Efield();
84  fElectronlifetime = config().Electronlifetime();
85  fTemperature = config().Temperature();
86  fElectronsToADC = config().ElectronsToADC();
87  fNumberTimeSamples = config().NumberTimeSamples();
88  fReadOutWindowSize = config().ReadOutWindowSize();
89 
90  std::set<geo::View_t> present_views;
91  if (config().TimeOffsetU(fTimeOffsetU)) present_views.insert(geo::kU);
92  if (config().TimeOffsetV(fTimeOffsetV)) present_views.insert(geo::kV);
93  if (config().TimeOffsetZ(fTimeOffsetZ)) present_views.insert(geo::kZ);
94  if (config().TimeOffsetY(fTimeOffsetY)) present_views.insert(geo::kY);
95  if (config().TimeOffsetX(fTimeOffsetX)) present_views.insert(geo::kX);
96 
97  std::string const errors = CheckTimeOffsets(present_views, *fChannelMap);
98  if (!errors.empty()) {
99  throw cet::exception("DetectorPropertiesStandard") << "Detected configuration errors: \n"
100  << errors;
101  }
102 
103  fSternheimerParameters.a = config().SternheimerA();
104  fSternheimerParameters.k = config().SternheimerK();
105  fSternheimerParameters.x0 = config().SternheimerX0();
106  fSternheimerParameters.x1 = config().SternheimerX1();
107  fSternheimerParameters.cbar = config().SternheimerCbar();
108 
109  fDriftVelFudgeFactor = config().DriftVelFudgeFactor();
110 
111  fUseIcarusMicrobooneDriftModel = config().UseIcarusMicrobooneDriftModel();
112 
113  fIncludeInterPlanePitchInXTickOffsets = config().IncludeInterPlanePitchInXTickOffsets();
114 
115  fSimpleBoundary = config().SimpleBoundary();
116 
117  fModBoxA = config().ModBoxAlpha();
118  fModBoxB = config().ModBoxBeta();
119  }
120 
121  //------------------------------------------------------------------------------------//
122  double DetectorPropertiesStandard::Efield(unsigned int const planegap) const
123  {
124  if (planegap >= fEfield.size())
125  throw cet::exception("DetectorPropertiesStandard")
126  << "requesting Electric field in a plane gap that is not defined\n";
127 
128  return fEfield[planegap];
129  }
130 
131  //------------------------------------------------
132  double DetectorPropertiesStandard::Density(double temperature) const
133  {
134  // Default temperature use internal value.
135  if (temperature == 0.) temperature = Temperature();
136 
137  return -0.00615 * temperature + 1.928;
138  }
139 
140  //----------------------------------------------------------------------------------
141  // Restricted mean energy loss (dE/dx) in units of MeV/cm.
142  //
143  // For unrestricted mean energy loss, set tcut = 0, or tcut large.
144  //
145  // Arguments:
146  //
147  // mom - Momentum of incident particle in GeV/c.
148  // mass - Mass of incident particle in GeV/c^2.
149  // tcut - Maximum kinetic energy of delta rays (MeV).
150  //
151  // Returned value is positive.
152  //
153  // Based on Bethe-Bloch formula as contained in particle data book.
154  // Material parameters (stored in larproperties.fcl) are taken from
155  // pdg web site http://pdg.lbl.gov/AtomicNuclearProperties/
156  //
157  double DetectorPropertiesStandard::Eloss(double mom, double mass, double tcut) const
158  {
159  // Some constants.
160  constexpr double K = 0.307075; // 4 pi N_A r_e^2 m_e c^2 (MeV cm^2/mol).
161  constexpr double me = 0.510998918; // Electron mass (MeV/c^2).
162 
163  // Calculate kinematic quantities.
164  double const bg = mom / mass; // beta*gamma.
165  double const gamma = sqrt(1. + bg * bg); // gamma.
166  double const beta = bg / gamma; // beta (velocity).
167  double const mer = 0.001 * me / mass; // electron mass / mass of incident particle.
168  double const tmax =
169  2. * me * bg * bg / (1. + 2. * gamma * mer + mer * mer); // Maximum delta ray energy (MeV).
170 
171  // Make sure tcut does not exceed tmax.
172  if (tcut == 0. || tcut > tmax) tcut = tmax;
173 
174  // Calculate density effect correction (delta).
175  double const x = std::log10(bg);
176  double delta = 0.;
177  if (x >= fSternheimerParameters.x0) {
178  delta = 2. * std::log(10.) * x - fSternheimerParameters.cbar;
179  if (x < fSternheimerParameters.x1)
180  delta += fSternheimerParameters.a *
182  }
183 
184  // Calculate stopping number.
185  double B =
186  0.5 * std::log(2. * me * bg * bg * tcut / (1.e-12 * cet::square(fLP->ExcitationEnergy()))) -
187  0.5 * beta * beta * (1. + tcut / tmax) - 0.5 * delta;
188 
189  // Don't let the stopping number become negative.
190  if (B < 1.) B = 1.;
191 
192  // Calculate dE/dx.
193  return Density() * K * fLP->AtomicNumber() * B / (fLP->AtomicMass() * beta * beta);
194  }
195 
196  //----------------------------------------------------------------------------------
197  double DetectorPropertiesStandard::ElossVar(double const mom, double const mass) const
198  {
199  // Some constants.
200  constexpr double K = 0.307075; // 4 pi N_A r_e^2 m_e c^2 (MeV cm^2/mol).
201  constexpr double me = 0.510998918; // Electron mass (MeV/c^2).
202 
203  // Calculate kinematic quantities.
204  double const bg = mom / mass; // beta*gamma.
205  double const gamma2 = 1. + bg * bg; // gamma^2.
206  double const beta2 = bg * bg / gamma2; // beta^2.
207  return gamma2 * (1. - 0.5 * beta2) * me * (fLP->AtomicNumber() / fLP->AtomicMass()) * K *
208  Density();
209  }
210 
211  //------------------------------------------------------------------------------------//
212  double DetectorPropertiesStandard::DriftVelocity(double efield, double temperature) const
213  {
214  // Drift Velocity as a function of Electric Field and LAr Temperature from:
215  // W. Walkowiak, NIM A 449 (2000) 288-294
216  //
217  // Option to use MicroBooNE+ICARUS model (as in arXiv:2008.09765) provided as well,
218  // with temperature depenence as prescribed by Mike Mooney based on looking at the
219  // Walkowiak data.
220  //
221  // Efield should have units of kV/cm
222  // Temperature should have units of Kelvin
223 
224  // Default Efield, use internal value.
225  if (efield == 0.) efield = Efield();
226 
227  if (efield > 4.0)
228  mf::LogWarning("DetectorPropertiesStandard")
229  << "DriftVelocity Warning! : E-field value of " << efield
230  << " kV/cm is outside of range covered by drift velocity parameterization. Returned value "
231  "may not be correct";
232 
233  // Default temperature use internal value.
234  if (temperature == 0.) temperature = Temperature();
235 
236  if (temperature < 87.0 || temperature > 94.0)
237  mf::LogWarning("DetectorPropertiesStandard")
238  << "DriftVelocity Warning! : Temperature value of " << temperature
239  << " K is outside of range covered by drift velocity parameterization. Returned value may "
240  "not be correct";
241 
242  double vd;
243 
245  double const tshift = -87.203 + temperature;
246  double const xFit = 0.0938163 - 0.0052563 * tshift - 0.0001470 * tshift * tshift;
247  double const uFit = 5.18406 + 0.01448 * tshift - 0.003497 * tshift * tshift -
248  0.000516 * tshift * tshift * tshift;
249 
250  // Icarus Parameter Set, use as default
251  constexpr double P1 = -0.04640; // K^-1
252  constexpr double P2 = 0.01712; // K^-1
253  constexpr double P3 = 1.88125; // (kV/cm)^-1
254  constexpr double P4 = 0.99408; // kV/cm
255  constexpr double P5 = 0.01172; // (kV/cm)^-P6
256  constexpr double P6 = 4.20214;
257  constexpr double T0 = 105.749; // K
258 
259  // Walkowiak Parameter Set
260  constexpr double P1W = -0.01481; // K^-1
261  constexpr double P2W = -0.0075; // K^-1
262  constexpr double P3W = 0.141; // (kV/cm)^-1
263  constexpr double P4W = 12.4; // kV/cm
264  constexpr double P5W = 1.627; // (kV/cm)^-P6
265  constexpr double P6W = 0.317;
266  constexpr double T0W = 90.371; // K
267 
268  // From Craig Thorne . . . currently not documented
269  // smooth transition from linear at small fields to
270  // icarus fit at most fields to Walkowiak at very high fields
271  if (efield < xFit)
272  vd = efield * uFit;
273  else if (efield < 0.619) {
274  vd = ((P1 * (temperature - T0) + 1) *
275  (P3 * efield * std::log(1 + P4 / efield) + P5 * std::pow(efield, P6)) +
276  P2 * (temperature - T0));
277  }
278  else if (efield < 0.699) {
279  vd = 12.5 * (efield - 0.619) *
280  ((P1W * (temperature - T0W) + 1) *
281  (P3W * efield * std::log(1 + P4W / efield) + P5W * std::pow(efield, P6W)) +
282  P2W * (temperature - T0W)) +
283  12.5 * (0.699 - efield) *
284  ((P1 * (temperature - T0) + 1) *
285  (P3 * efield * std::log(1 + P4 / efield) + P5 * std::pow(efield, P6)) +
286  P2 * (temperature - T0));
287  }
288  else {
289  vd = ((P1W * (temperature - T0W) + 1) *
290  (P3W * efield * std::log(1 + P4W / efield) + P5W * std::pow(efield, P6W)) +
291  P2W * (temperature - T0W));
292  }
293  }
294 
295  // MicroBooNE+ICARUS model (arXiv:2008.09765) with temperature dependence given by
296  // Mike Mooney based on looking at Walkowiak data (NIM A 449 (2000) 288-294)
298  constexpr double P0 = 0.;
299  constexpr double P1 = 5.53416;
300  constexpr double P2 = -6.53093;
301  constexpr double P3 = 3.20752;
302  constexpr double P4 = 0.389696;
303  constexpr double P5 = -0.556184;
304  vd = (1.0 - 0.0184 * (temperature - 89.0)) *
305  (P0 + P1 * cet::pow<1>(efield) + P2 * cet::pow<2>(efield) + P3 * cet::pow<3>(efield) +
306  P4 * cet::pow<4>(efield) + P5 * cet::pow<5>(efield));
307  }
308 
309  vd *= fDriftVelFudgeFactor / 10.;
310 
311  return vd; // in cm/us
312  }
313 
314  //----------------------------------------------------------------------------------
315  // The below function assumes that the user has applied the lifetime
316  // correction and effective pitch between the wires (usually after 3D
317  // reconstruction). Using with mean wire pitch will not give correct results.
318  // parameters:
319  // dQdX in electrons/cm, charge (amplitude or integral obtained) divided by
320  // effective pitch for a given 3D track.
321  // Electric Field in the drift region in KV/cm/
322  // returns dEdX in MeV/cm
324  {
325  return BirksCorrection(dQdx, Efield());
326  }
327  double DetectorPropertiesStandard::BirksCorrection(double dQdx, double E_field) const
328  {
329  // Correction for charge quenching using parameterization from
330  // S.Amoruso et al., NIM A 523 (2004) 275
331 
332  constexpr double A3t = util::kRecombA;
333  double K3t = util::kRecombk; // in KV/cm*(g/cm^2)/MeV
334  double const rho = Density(); // LAr density in g/cm^3
335  constexpr double Wion = 1000. / util::kGeVToElectrons; // 23.6 eV = 1e, Wion in MeV/e
336  K3t /= rho; // KV/MeV
337  double const dEdx = dQdx / (A3t / Wion - K3t / E_field * dQdx); // MeV/cm
338 
339  return dEdx;
340  }
341 
342  //----------------------------------------------------------------------------------
343  // Modified Box model correction
345  {
346  return ModBoxCorrection(dQdx, Efield());
347  }
348  double DetectorPropertiesStandard::ModBoxCorrection(double dQdx, double E_field) const
349  {
350  // Modified Box model correction has better behavior than the Birks
351  // correction at high values of dQ/dx.
352  double const rho = Density(); // LAr density in g/cm^3
353  constexpr double Wion = 1000. / util::kGeVToElectrons; // 23.6 eV = 1e, Wion in MeV/e
354  double const Beta = fModBoxB / (rho * E_field);
355  double const Alpha = fModBoxA;
356  double const dEdx = (exp(Beta * Wion * dQdx) - Alpha) / Beta;
357 
358  return dEdx;
359  }
360 
361  //--------------------------------------------------------------------
362  // x<--> ticks conversion methods
363  //
364  // Ben Jones April 2012,
365  // based on code by Herb Greenlee in SpacePointService
366  //
367 
368  //--------------------------------------------------------------------
369  // Recalculate x<-->ticks conversion parameters from detector constants
370 
372  detinfo::DetectorClocksData const& clock_data) const
373  {
374  double const samplingRate = sampling_rate(clock_data);
375  double const efield = Efield();
376  double const temperature = Temperature();
377  double const driftVelocity = DriftVelocity(efield, temperature);
378  double const x_ticks_coefficient = 0.001 * driftVelocity * samplingRate;
379 
380  double const triggerOffset = trigger_offset(clock_data);
381 
382  std::vector<std::vector<std::vector<double>>> x_ticks_offsets(fGeo->Ncryostats());
383  std::vector<std::vector<double>> drift_direction(fGeo->Ncryostats());
384 
385  for (size_t cstat = 0; cstat < fGeo->Ncryostats(); ++cstat) {
386  auto const& cryostat = fGeo->Cryostat(geo::CryostatID(cstat));
387  x_ticks_offsets[cstat].resize(cryostat.NTPC());
388  drift_direction[cstat].resize(cryostat.NTPC());
389 
390  for (size_t tpc = 0; tpc < cryostat.NTPC(); ++tpc) {
391  const geo::TPCGeo& tpcgeom = cryostat.TPC(tpc);
392  auto const& tpcid = tpcgeom.ID();
393 
394  const double dir = -to_int(tpcgeom.DriftSign());
395  drift_direction[cstat][tpc] = dir;
396 
397  unsigned int nplane = fChannelMap->Nplanes(tpcid);
398  x_ticks_offsets[cstat][tpc].resize(nplane, 0.);
399 
400  // Choose which plane to propagate to. If accounting for the drift time between
401  // planes, start with the first plane, and iteratively add distances between
402  // planes Otherwise propagate straight to the last plane and assume a standard
403  // drift velocity (for wirecell recob::Wires)
404  unsigned int planeToPropagateTo = fIncludeInterPlanePitchInXTickOffsets ? 0 : nplane - 1;
405 
406  // Calculate geometric time offset (only works if xyz.X() <=0 )
407  auto const xyz = fChannelMap->Plane({tpcid, planeToPropagateTo}).GetCenter();
408  for (geo::PlaneGeo const& pgeom : fChannelMap->Iterate<geo::PlaneGeo>(tpcid)) {
409  unsigned int const plane = pgeom.ID().Plane;
410  x_ticks_offsets[cstat][tpc][plane] =
411  -xyz.X() / (dir * x_ticks_coefficient) + triggerOffset;
412 
414  // Get field in gap between planes
415  double efieldgap[3];
416  double driftVelocitygap[3];
417  double x_ticks_coefficient_gap[3];
418  for (int igap = 0; igap < 3; ++igap) {
419  efieldgap[igap] = Efield(igap);
420  driftVelocitygap[igap] = DriftVelocity(efieldgap[igap], temperature);
421  x_ticks_coefficient_gap[igap] = 0.001 * driftVelocitygap[igap] * samplingRate;
422  }
423 
424  if (nplane == 3) {
425  /*
426  | ---------- plane = 2 (collection)
427  | Coeff[2]
428  | ---------- plane = 1 (2nd induction)
429  | Coeff[1]
430  | ---------- plane = 0 (1st induction) x = xyz[0]
431  | Coeff[0]
432  | ---------- x = 0
433  V For plane = 0, t offset is -xyz[0]/Coeff[0]
434  x */
435  for (unsigned int ip = 0; ip < plane; ++ip) {
436  x_ticks_offsets[cstat][tpc][plane] +=
437  fChannelMap->PlanePitch(tpcid, ip, ip + 1) / x_ticks_coefficient_gap[ip + 1];
438  }
439  }
440  else if (nplane == 2) {
441  /*
442  | ---------- plane = 1 (collection)
443  | Coeff[2]
444  | ---------- plane = 0 (2nd induction) x = xyz[0]
445  | ---------- x = 0, Coeff[1]
446  V ---------- first induction plane
447  x Coeff[0]
448  For plane = 0, t offset is pitch/Coeff[1] -
449  (pitch+xyz[0])/Coeff[0] = -xyz[0]/Coeff[0] -
450  pitch*(1/Coeff[0]-1/Coeff[1])
451  */
452  for (unsigned int ip = 0; ip < plane; ++ip) {
453  x_ticks_offsets[cstat][tpc][plane] +=
454  fChannelMap->PlanePitch(tpcid, ip, ip + 1) / x_ticks_coefficient_gap[ip + 2];
455  }
456  x_ticks_offsets[cstat][tpc][plane] -=
457  fChannelMap->PlanePitch(tpcid) *
458  (1 / x_ticks_coefficient - 1 / x_ticks_coefficient_gap[1]);
459  }
460 
461  } // end if fIncludeInterPlanePitchInXTickOffsets
462 
463  // Add view dependent offset
464  // FIXME the offset should be plane-dependent
465  geo::View_t view = pgeom.View();
466  switch (view) {
467  case geo::kU: x_ticks_offsets[cstat][tpc][plane] += fTimeOffsetU; break;
468  case geo::kV: x_ticks_offsets[cstat][tpc][plane] += fTimeOffsetV; break;
469  case geo::kZ: x_ticks_offsets[cstat][tpc][plane] += fTimeOffsetZ; break;
470  case geo::kY: x_ticks_offsets[cstat][tpc][plane] += fTimeOffsetY; break;
471  case geo::kX: x_ticks_offsets[cstat][tpc][plane] += fTimeOffsetX; break;
472  default: throw cet::exception(__FUNCTION__) << "Bad view = " << view << "\n";
473  } // switch
474  }
475  }
476  }
477 
478  return DetectorPropertiesData{
479  *this, x_ticks_coefficient, move(x_ticks_offsets), move(drift_direction)};
480  }
481 } // namespace
Float_t x
Definition: compare.C:6
Encapsulate the construction of a single cyostat .
DetectorPropertiesStandard(fhicl::ParameterSet const &pset, geo::GeometryCore const *geo, geo::WireReadoutGeom const *wireReadoutGeom, detinfo::LArProperties const *lp, std::set< std::string > const &ignore_params={})
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
double Efield(unsigned int planegap=0) const override
kV/cm
Planes which measure V.
Definition: geo_types.h:132
void ValidateAndConfigure(fhicl::ParameterSet const &p, std::set< std::string > const &ignore_params)
Configures the provider, first validating the configuration.
double ElossVar(double mom, double mass) const override
Energy loss fluctuation ( )
Planes which measure X direction.
Definition: geo_types.h:136
Geometry information for a single TPC.
Definition: TPCGeo.h:33
double BirksCorrection(double dQdX) const override
dQ/dX in electrons/cm, returns dE/dX in MeV/cm.
unsigned int fNumberTimeSamples
number of clock ticks per event
double Temperature() const override
In kelvin.
virtual double Density() const
Returns argon density at the temperature from Temperature()
double PlanePitch(TPCID const &tpcid, unsigned int p1=0, unsigned int p2=1) const
Planes which measure Z direction.
Definition: geo_types.h:134
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
Definition: GeometryCore.h:303
DetectorPropertiesData DataFor(detinfo::DetectorClocksData const &clock_data) const override
Planes which measure Y direction.
Definition: geo_types.h:135
virtual double ExcitationEnergy() const =0
Mean excitation energy of the liquid (eV)
Access the description of the physical detector geometry.
Planes which measure U.
Definition: geo_types.h:131
virtual double AtomicMass() const =0
Atomic mass of the liquid (g/mol)
constexpr double kGeVToElectrons
23.6eV per ion pair, 1e9 eV/GeV
std::set< View_t > const & Views() const
Returns a list of possible views in the detector.
DebugStuff debug
Definition: DebugStruct.cxx:4
Interface for a class providing readout channel mapping to geometry.
Geometry information for a single wire plane.The plane is represented in the geometry by a solid whic...
Definition: PlaneGeo.h:67
SternheimerParameters_t fSternheimerParameters
Sternheimer parameters.
constexpr int to_int(Coordinate const coord) noexcept
Enumerate the possible plane projections.
Definition: geo_types.h:124
std::set< std::string > const & IgnorableProviderConfigKeys()
Returns a list of configuration keys that providers should ignore.
Definition: ProviderUtil.h:34
General LArSoft Utilities.
geo::DriftSign DriftSign() const
Returns the expected drift direction based on geometry.
Definition: TPCGeo.h:79
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:373
Description of the physical geometry of one entire detector.
Definition: GeometryCore.h:91
float dEdx(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const TCSlice &slc, TP3D &tp3d)
Definition: PFPUtils.cxx:2671
CryostatGeo const & Cryostat(CryostatID const &cryoid=details::cryostat_zero) const
Returns the specified cryostat.
unsigned int Nplanes(TPCID const &tpcid=details::tpc_zero) const
Returns the total number of planes in the specified TPC.
double ModBoxCorrection(double dQdX) const override
Encapsulate the construction of a single detector plane .
Contains all timing reference information for the detector.
TDirectory * dir
Definition: macro.C:5
unsigned int fReadOutWindowSize
number of clock ticks per readout window
virtual double AtomicNumber() const =0
Atomic number of the liquid.
constexpr double kRecombk
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
range_type< T > Iterate() const
Definition: Iterable.h:121
int trigger_offset(DetectorClocksData const &data)
std::vector< double > fEfield
kV/cm (per inter-plane volume) !
Simple utilities for service providers.
constexpr double kRecombA
A constant.
PlaneGeo const & Plane(TPCID const &tpcid, View_t view) const
Returns the specified wire.
double DriftVelocity(double efield=0., double temperature=0.) const override
cm/us
Float_t e
Definition: plot.C:35
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
ROOT libraries.
TPCID const & ID() const
Returns the identifier of this TPC.
Definition: TPCGeo.h:147
PlaneID const & ID() const
Returns the identifier of this plane.
Definition: PlaneGeo.h:173
Interface to geometry for wire readouts .
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
Encapsulate the construction of a single detector plane .
double Eloss(double mom, double mass, double tcut) const override
Restricted mean energy loss (dE/dx)
The data type to uniquely identify a cryostat.
Definition: geo_types.h:187