All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DetectorPropertiesStandard.h
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // \file DetectorPropertiesStandard.h
3 //
4 // \brief service to contain information about detector electronics, etc
5 //
6 // \author brebel@fnal.gov
7 //
8 // Separation of service from Detector info class:
9 // jpaley@fnal.gov
10 ////////////////////////////////////////////////////////////////////////
11 #ifndef DETINFO_DETECTORPROPERTIESSTD_H
12 #define DETINFO_DETECTORPROPERTIESSTD_H
13 
14 // LArSoft libraries
22 
23 // framework libraries
24 #include "fhiclcpp/ParameterSet.h"
25 #include "fhiclcpp/fwd.h"
26 #include "fhiclcpp/types/Atom.h"
27 #include "fhiclcpp/types/OptionalAtom.h"
28 #include "fhiclcpp/types/Sequence.h"
29 
30 // C/C++ standard libraries
31 #include <set>
32 
33 /// General LArSoft Utilities
34 namespace detinfo {
35 
37  public:
38  /// List of service providers we depend on
40 
41  /// Structure for configuration parameters
42  struct Configuration_t {
43  using Name = fhicl::Name;
44  using Comment = fhicl::Comment;
45 
46  fhicl::Sequence<double> Efield{
47  Name("Efield"),
48  Comment("electric field in front of each wire plane (the last one is "
49  "the big one!) [kV/cm]")};
50 
51  fhicl::Atom<double> Electronlifetime{Name("Electronlifetime"),
52  Comment("electron lifetime in liquid argon [us]")};
53  fhicl::Atom<double> Temperature{Name("Temperature"), Comment("argon temperature [K]")};
54  fhicl::Atom<double> ElectronsToADC{
55  Name("ElectronsToADC"),
56  Comment("conversion factor: (ADC counts)/(ionization electrons)")};
57  fhicl::Atom<unsigned int> NumberTimeSamples{
58  Name("NumberTimeSamples"),
59  Comment("number of TPC readout TDC clock ticks per event")};
60  fhicl::Atom<unsigned int> ReadOutWindowSize{
61  Name("ReadOutWindowSize"),
62  Comment("number of TPC readout TDC clock ticks per readout window")};
63 
64  // The following are not really "optional": the ones for the views which
65  // are present are mandatory.
66  fhicl::OptionalAtom<double> TimeOffsetU{
67  Name("TimeOffsetU"),
68  Comment("tick offset subtracted to to convert spacepoint coordinates "
69  "to hit times on view U")};
70  fhicl::OptionalAtom<double> TimeOffsetV{
71  Name("TimeOffsetV"),
72  Comment("tick offset subtracted to to convert spacepoint coordinates "
73  "to hit times on view V")};
74  fhicl::OptionalAtom<double> TimeOffsetZ{
75  Name("TimeOffsetZ"),
76  Comment("tick offset subtracted to to convert spacepoint coordinates "
77  "to hit times on view Z")};
78  fhicl::OptionalAtom<double> TimeOffsetY{
79  Name("TimeOffsetY"),
80  Comment("tick offset subtracted to to convert spacepoint coordinates "
81  "to hit times on view Y")};
82  fhicl::OptionalAtom<double> TimeOffsetX{
83  Name("TimeOffsetX"),
84  Comment("tick offset subtracted to to convert spacepoint coordinates "
85  "to hit times on view X")};
86 
87  fhicl::Atom<double> SternheimerA{
88  Name("SternheimerA"),
89  Comment("parameter a of Sternheimer correction delta = 2log(10) x - "
90  "cbar + { a (x1-x)^k } theta(x1-x), x = log10(p/m)")};
91  fhicl::Atom<double> SternheimerK{
92  Name("SternheimerK"),
93  Comment("parameter k of Sternheimer correction delta = 2log(10) x - "
94  "cbar + { a (x_1-x)^k } theta(x1-x), x = log10(p/m)")};
95  fhicl::Atom<double> SternheimerX0{
96  Name("SternheimerX0"),
97  Comment("minimum x = log10(p/m) for the application of Sternheimer "
98  "correction")};
99  fhicl::Atom<double> SternheimerX1{
100  Name("SternheimerX1"),
101  Comment("parameter x_1 of Sternheimer correction delta = 2log(10) x - "
102  "cbar + { a (x_1-x)^k } theta(x1-x), x = log10(p/m)")};
103  fhicl::Atom<double> SternheimerCbar{
104  Name("SternheimerCbar"),
105  Comment("parameter cbar of Sternheimer correction delta = 2log(10) x - "
106  "cbar + { a (x_1-x)^k } theta(x1-x), x = log10(p/m)")};
107  fhicl::Atom<double> DriftVelFudgeFactor{
108  Name("DriftVelFudgeFactor"),
109  Comment("Allows a scaling factor to fudge the drift velocity "
110  "calculation (as suggested by DriftVel Stancari")};
111 
112  fhicl::Atom<bool> UseIcarusMicrobooneDriftModel{
113  Name("UseIcarusMicrobooneDriftModel"),
114  Comment("Allows user to decide to use the ICARUS+MicroBooNE drift "
115  "model for velocity calculation as in arXiv:2008.09765"),
116  false};
117 
119  Name("IncludeInterPlanePitchInXTickOffsets"),
120  Comment("Historically, ConvertTicksToX has allowed for the drift time "
121  "between the wire planes. This is appropriate for "
122  "recob::RawDigits, and recob::Wires from the 1D unfolding, "
123  "but is not appropriate for recob::Wires from WireCell. "
124  "The default value is 'true', retaining the 'classic' behaviour"),
125  true};
126 
127  fhicl::Atom<bool> SimpleBoundary{Name("SimpleBoundaryProcess"), Comment("")};
128 
129  fhicl::Atom<double> ModBoxAlpha {
130  Name("ModBoxAlpha"),
131  Comment("alpha parameter in the Modified Box recombination model."),
133  };
134 
135  fhicl::Atom<double> ModBoxBeta {
136  Name("ModBoxBeta"),
137  Comment("beta parameter in the Modified Box recombination model."),
139  };
140 
141  }; // Configuration_t
142 
143  DetectorPropertiesStandard(fhicl::ParameterSet const& pset,
144  const geo::GeometryCore* geo,
145  const detinfo::LArProperties* lp,
146  std::set<std::string> const& ignore_params = {});
147 
149  virtual ~DetectorPropertiesStandard() = default;
150 
151  void
152  SetNumberTimeSamples(unsigned int nsamp)
153  {
154  fNumberTimeSamples = nsamp;
155  }
156 
157  // Accessors.
158 
159  double Efield(unsigned int planegap = 0) const override; ///< kV/cm
160 
161  double DriftVelocity(double efield = 0.,
162  double temperature = 0.) const override; ///< cm/us
163 
164  /// dQ/dX in electrons/cm, returns dE/dX in MeV/cm.
165  double BirksCorrection(double dQdX) const override;
166  double BirksCorrection(double dQdX, double EField) const override;
167  double ModBoxCorrection(double dQdX) const override;
168  double ModBoxCorrection(double dQdX, double EField) const override;
169 
170  double
171  ElectronLifetime() const override
172  {
173  return fElectronlifetime; //< microseconds
174  }
175 
176  /**
177  * @brief Returns argon density at a given temperature
178  * @param temperature the temperature in kelvin
179  * @return argon density in g/cm^3
180  *
181  * Density is nearly a linear function of temperature.
182  * See the NIST tables for details
183  * Slope is between -6.2 and -6.1, intercept is 1928 kg/m^3.
184  * This parameterization will be good to better than 0.5%.
185  */
186  double Density(double temperature = 0.) const override; ///< g/cm^3
187 
188  /// In kelvin.
189  double
190  Temperature() const override
191  {
192  return fTemperature;
193  }
194 
195  /**
196  * @brief Restricted mean energy loss (dE/dx)
197  * @param mom momentum of incident particle [GeV/c]
198  * @param mass mass of incident particle [GeV/c^2]
199  * @param tcut maximum kinetic energy of delta rays [MeV]; 0 for unlimited
200  * @return the restricted mean energy loss (dE/dx) in units of MeV/cm
201  *
202  * Returned value is always positive.
203  * For unrestricted mean energy loss, set tcut = 0 (special case),
204  * or tcut large.
205  *
206  * Based on Bethe-Bloch formula as contained in particle data book.
207  * Material parameters are from the configuration.
208  */
209  double Eloss(double mom, double mass, double tcut) const override;
210 
211  /**
212  * @brief Energy loss fluctuation (@f$ \sigma_{E}^2 / x @f$)
213  * @param mom momentum of incident particle in [GeV/c]
214  * @param mass mass of incident particle [GeV/c^2]
215  * @return energy loss fluctuation in MeV^2/cm
216  *
217  * Based on Bichsel formula referred to but not given in PDG.
218  */
219  double ElossVar(double mom, double mass) const override;
220 
221  double
222  ElectronsToADC() const override
223  {
224  return fElectronsToADC;
225  }
226  unsigned int
227  NumberTimeSamples() const override
228  {
229  return fNumberTimeSamples;
230  }
231  unsigned int
232  ReadOutWindowSize() const override
233  {
234  return fReadOutWindowSize;
235  }
236  double
237  TimeOffsetU() const override
238  {
239  return fTimeOffsetU;
240  };
241  double
242  TimeOffsetV() const override
243  {
244  return fTimeOffsetV;
245  };
246  double
247  TimeOffsetZ() const override
248  {
249  return fTimeOffsetZ;
250  };
251  double
252  TimeOffsetY() const override
253  {
254  return fTimeOffsetY;
255  };
256 
257  bool
258  SimpleBoundary() const override
259  {
260  return fSimpleBoundary;
261  }
262 
263  DetectorPropertiesData DataFor(detinfo::DetectorClocksData const& clock_data) const override;
264 
265  private:
266  /**
267  * @brief Configures the provider, first validating the configuration
268  * @param p configuration parameter set
269  * @param ignore_params parameters to be ignored (optional)
270  *
271  * This method will validate the parameter set (except for the parameters
272  * it's explicitly told to ignore) and extract the useful information out
273  * of it.
274  */
275  void ValidateAndConfigure(fhicl::ParameterSet const& p,
276  std::set<std::string> const& ignore_params);
277 
278  std::string CheckTimeOffsets(std::set<geo::View_t> const& requested_views) const;
279 
280  /// Parameters for Sternheimer density effect corrections
282  double a; ///< parameter a
283  double k; ///< parameter k
284  double x0; ///< parameter x0
285  double x1; ///< parameter x1
286  double cbar; ///< parameter Cbar
287  };
288 
289  // service providers we depend on;
290  // in principle could be replaced by a single providerpack_type.
293 
294  std::vector<double> fEfield; ///< kV/cm (per inter-plane volume) !
295  double fElectronlifetime; ///< microseconds
296  double fTemperature; ///< kelvin
297  double fElectronsToADC; ///< conversion factor for # of ionization electrons
298  ///< to 1 ADC count
299  unsigned int fNumberTimeSamples; ///< number of clock ticks per event
300  unsigned int fReadOutWindowSize; ///< number of clock ticks per readout window
301  double fTimeOffsetU; ///< time offset to convert spacepoint coordinates to
302  ///< hit times on view U
303  double fTimeOffsetV; ///< time offset to convert spacepoint coordinates to
304  ///< hit times on view V
305  double fTimeOffsetZ; ///< time offset to convert spacepoint coordinates to
306  ///< hit times on view Z
307  double fTimeOffsetY; ///< time offset to convert spacepoint coordinates to
308  ///< hit times on view Y
309  double fTimeOffsetX; ///< time offset to convert spacepoint coordinates to
310  ///< hit times on view X
311  double fDriftVelFudgeFactor; ///< Scaling factor to allow "fudging" of drift
312  ///< velocity
313 
314  bool fUseIcarusMicrobooneDriftModel; ///< if true, use alternative ICARUS-MicroBooNE drift
315  ///< model instead of Walkowiak-based one
316 
317  /// Historically, ConvertTicksToX has allowed for the drift time between
318  /// the wire planes. This is appropriate for recob::RawDigits, and
319  /// recob::Wires from the 1D unfolding, but is not appropriate for
320  /// recob::Wires from WireCell.
322 
323  SternheimerParameters_t fSternheimerParameters; ///< Sternheimer parameters
324 
325  std::vector<std::vector<double>> fDriftDirection;
326 
328 
329  double fModBoxA;
330  double fModBoxB;
331 
332  }; // class DetectorPropertiesStandard
333 } // namespace detinfo
334 
335 #endif // DETINFO_DETECTOR_PROPERTIES_H
DetectorPropertiesStandard(fhicl::ParameterSet const &pset, const geo::GeometryCore *geo, const detinfo::LArProperties *lp, std::set< std::string > const &ignore_params={})
double ModBoxCorrection(double dQdX) const override
DetectorPropertiesData DataFor(detinfo::DetectorClocksData const &clock_data) const override
virtual ~DetectorPropertiesStandard()=default
unsigned int NumberTimeSamples() const override
double Temperature() const override
In kelvin.
double Eloss(double mom, double mass, double tcut) const override
Restricted mean energy loss (dE/dx)
void ValidateAndConfigure(fhicl::ParameterSet const &p, std::set< std::string > const &ignore_params)
Configures the provider, first validating the configuration.
pdgs p
Definition: selectors.fcl:22
unsigned int fNumberTimeSamples
number of clock ticks per event
std::vector< std::vector< double > > fDriftDirection
virtual double Density() const
Returns argon density at the temperature from Temperature()
pure virtual base interface for detector clocks
Access the description of detector geometry.
constexpr double kModBoxB
Modified Box Beta in g/(MeV cm)*kV/cm.
double ElossVar(double mom, double mass) const override
Energy loss fluctuation ( )
SternheimerParameters_t fSternheimerParameters
Sternheimer parameters.
double ElectronLifetime() const override
Returns the attenuation constant for ionization electrons.
BEGIN_PROLOG vertical distance to the surface Name
std::string CheckTimeOffsets(std::set< geo::View_t > const &requested_views) const
Description of geometry of one entire detector.
Parameters for Sternheimer density effect corrections.
double DriftVelocity(double efield=0., double temperature=0.) const override
cm/us
Contains all timing reference information for the detector.
unsigned int fReadOutWindowSize
number of clock ticks per readout window
Container for a list of pointers to providers.
Definition: ProviderPack.h:114
float mass
Definition: dedx.py:47
double BirksCorrection(double dQdX) const override
dQ/dX in electrons/cm, returns dE/dX in MeV/cm.
std::vector< double > fEfield
kV/cm (per inter-plane volume) !
Data structure containing constant pointers to classes.
constexpr double kModBoxA
Modified Box Alpha.
Collection of Physical constants used in LArSoft.
double Efield(unsigned int planegap=0) const override
kV/cm
unsigned int ReadOutWindowSize() const override