LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
DetectorPropertiesServiceArgoNeuT_service.cc
Go to the documentation of this file.
1 //
3 // \file DetectorPropertiesServiceArgoNeuT_service.cc
4 //
6 // Framework includes
7 
8 // LArSoft includes
18 
19 // Art includes
23 
24 namespace util{
25 
26  //--------------------------------------------------------------------
29  : fNumberTimeSamples(pset.get< unsigned int >("NumberTimeSamples"))
30  {
31  fLP = dynamic_cast<util::LArPropertiesServiceArgoNeuT const*>
32  (lar::providerFrom<detinfo::LArPropertiesService>());
33  if (!fLP) {
34  // this legacy service works only coupled to the corresponding
35  // LArProperties legacy service:
37  << "DetectorPropertiesServiceArgoNeuT service requires"
38  " LArPropertiesServiceArgoNeuT";
39  }
40 
41  this->reconfigure(pset);
42 
43  // Register for callbacks.
44 
47  }
48 
49  //------------------------------------------------------------
51  {
52  return lar::providerFrom<detinfo::DetectorClocksService>()->TPCTDC2Tick(tdc);
53  }
54 
55  //--------------------------------------------------------------
57  {
58  return lar::providerFrom<detinfo::DetectorClocksService>()->TPCTick2TDC(ticks);
59  }
60 
61  //--------------------------------------------------------------------
63  {
64  //fSamplingRate = p.get< double >("SamplingRate" );
65  double d;
66  int i;
67  bool b;
68  if(p.get_if_present<double>("SamplingRate",d))
69  throw cet::exception(__FUNCTION__) << "SamplingRate is a deprecated fcl parameter for DetectorPropertiesServiceArgoNeuT!";
70  if(p.get_if_present<int>("TriggerOffset",i))
71  throw cet::exception(__FUNCTION__) << "TriggerOffset is a deprecated fcl parameter for DetectorPropertiesServiceArgoNeuT!";
72  if(p.get_if_present<bool>("InheritTriggerOffset",b))
73  throw cet::exception(__FUNCTION__) << "InheritTriggerOffset is a deprecated fcl parameter for DetectorPropertiesServiceArgoNeuT!";
74 
75  fElectronsToADC = p.get< double >("ElectronsToADC" );
76  fNumberTimeSamples = p.get< unsigned int >("NumberTimeSamples");
77  fReadOutWindowSize = p.get< unsigned int >("ReadOutWindowSize");
78  fTimeOffsetU = p.get< double >("TimeOffsetU" );
79  fTimeOffsetV = p.get< double >("TimeOffsetV" );
80  fTimeOffsetZ = p.get< double >("TimeOffsetZ" );
81  fInheritNumberTimeSamples = p.get<bool >("InheritNumberTimeSamples", false);
82 
83  fSimpleBoundary = p.get<bool >("SimpleBoundaryProcess", true);
84 
85  fXTicksParamsLoaded = false;
86 
87  fTPCClock = lar::providerFrom<detinfo::DetectorClocksService>()->TPCClock();
88 
89  // Save the parameter set.
90  fPS = p;
91 
92  return;
93  }
94 
95  //-------------------------------------------------------------
97  {
98  // Make sure TPC Clock is updated with DetectorClocksService (though in principle it shouldn't change)
99  fTPCClock = lar::providerFrom<detinfo::DetectorClocksService>()->TPCClock();
100  }
101 
102 //---------------------------------------------------------------------------------
104 {
105  bool fToughErrorTreatment= art::ServiceHandle<util::DatabaseUtil>()->ToughErrorTreatment();
106  bool fShouldConnect = art::ServiceHandle<util::DatabaseUtil>()->ShouldConnect();
107  //Have not read from DB, should read and requested tough treatment
108  if(!fAlreadyReadFromDB && fToughErrorTreatment && fShouldConnect )
109  throw cet::exception("DetectorPropertiesServiceArgoNeuT") << " Extracting values from DetectorPropertiesServiceArgoNeuT before they "
110  << " have been read in from database. \n "
111  << "Set ToughErrorTreatment or ShouldConnect "
112  << " to false in databaseutil.fcl if you want "
113  << " to avoid this. \n";
114  //Have not read from DB, should read and requested soft treatment
115  else if(!fAlreadyReadFromDB && !fToughErrorTreatment && fShouldConnect )
116  mf::LogWarning("DetectorPropertiesServiceArgoNeuT") << "!!! Extracting values from DetectorPropertiesServiceArgoNeuT before they "
117  << " have been read in from the database. \n "
118  << " You may not be using the correct values of "
119  << " T0!"
120  << " You should not be initializing"
121  << " Database originating values in BeginJob()s or constructors."
122  << " You have been warned !!! \n ";
123 
124  //In other cases, either already read from DB, or should not connect so it doesn't matter
125 }
126 
127 //------------------------------------------------------------------------------------//
129 {
130  return fTPCClock.Ticks(lar::providerFrom<detinfo::DetectorClocksService>()->TriggerOffsetTPC() * -1.);
131 }
132 
133 
134  //--------------------------------------------------------------------
135  // x<--> ticks conversion methods
136  //
137  // Ben Jones April 2012,
138  // based on code by Herb Greenlee in SpacePointService
139  //
140 
141 
142 
143 
144  //--------------------------------------------------------------------
145  // Take an X coordinate, and convert to a number of ticks, the
146  // charge deposit occured at t=0
147 
148  double DetectorPropertiesServiceArgoNeuT::ConvertXToTicks(double X, int p, int t, int c) const
149  {
151  return (X / (fXTicksCoefficient * fDriftDirection.at(c).at(t)) + fXTicksOffsets.at(c).at(t).at(p) );
152  }
153 
154 
155 
156  //-------------------------------------------------------------------
157  // Take a cooridnate in ticks, and convert to an x position
158  // assuming event deposit occured at t=0
159 
160  double DetectorPropertiesServiceArgoNeuT::ConvertTicksToX(double ticks, int p, int t, int c) const
161  {
163  return (ticks - fXTicksOffsets.at(c).at(t).at(p)) * fXTicksCoefficient * fDriftDirection.at(c).at(t);
164  }
165 
166 
167  //--------------------------------------------------------------------
168  // Recalculte x<-->ticks conversion parameters from detector constants
169 
171  {
173 
174  double samplingRate = SamplingRate();
175  double efield = Efield();
176  double temperature = fLP->Temperature();
177  double driftVelocity = DriftVelocity(efield, temperature);
178 
179  fXTicksCoefficient = 0.001 * driftVelocity * samplingRate;
180 
181  double triggerOffset = TriggerOffset();
182 
183  fXTicksOffsets.clear();
184  fXTicksOffsets.resize(geo->Ncryostats());
185 
186  fDriftDirection.clear();
187  fDriftDirection.resize(geo->Ncryostats());
188 
189  for(size_t cstat = 0; cstat < geo->Ncryostats(); ++cstat){
190  fXTicksOffsets[cstat].resize(geo->Cryostat(cstat).NTPC());
191  fDriftDirection[cstat].resize(geo->Cryostat(cstat).NTPC());
192 
193  for(size_t tpc = 0; tpc < geo->Cryostat(cstat).NTPC(); ++tpc) {
194  const geo::TPCGeo& tpcgeom = geo->Cryostat(cstat).TPC(tpc);
195 
196  const double dir((tpcgeom.DriftDirection() == geo::kNegX) ? +1.0 :-1.0);
197  fDriftDirection[cstat][tpc] = dir;
198 
199  int nplane = tpcgeom.Nplanes();
200  fXTicksOffsets[cstat][tpc].resize(nplane, 0.);
201  for(int plane = 0; plane < nplane; ++plane) {
202  const geo::PlaneGeo& pgeom = tpcgeom.Plane(plane);
203 
204 
205  // Get field in gap between planes
206  double efieldgap[3];
207  double driftVelocitygap[3];
208  double fXTicksCoefficientgap[3];
209  for (int igap = 0; igap<3; ++igap){
210  efieldgap[igap] = Efield(igap);
211  driftVelocitygap[igap] = DriftVelocity(efieldgap[igap], temperature);
212  fXTicksCoefficientgap[igap] = 0.001 * driftVelocitygap[igap] * samplingRate;
213  }
214 
215  // Calculate geometric time offset.
216  // only works if xyz[0]<=0
217  const double* xyz = tpcgeom.PlaneLocation(0);
218 
219  fXTicksOffsets[cstat][tpc][plane] = -xyz[0]/(dir * fXTicksCoefficient) + triggerOffset;
220 
221  if (nplane==3){
222  /*
223  | ---------- plane = 2 (collection)
224  | Coeff[2]
225  | ---------- plane = 1 (2nd induction)
226  | Coeff[1]
227  | ---------- plane = 0 (1st induction) x = xyz[0]
228  | Coeff[0]
229  | ---------- x = 0
230  V For plane = 0, t offset is -xyz[0]/Coeff[0]
231  x */
232  for (int ip = 0; ip < plane; ++ip){
233  fXTicksOffsets[cstat][tpc][plane] += tpcgeom.PlanePitch(ip,ip+1)/fXTicksCoefficientgap[ip+1];
234  }
235  }
236  else if (nplane==2){
237  /*
238  | ---------- plane = 1 (collection)
239  | Coeff[2]
240  | ---------- plane = 0 (2nd induction) x = xyz[0]
241  | ---------- x = 0, Coeff[1]
242  V ---------- first induction plane
243  x Coeff[0]
244 For plane = 0, t offset is pitch/Coeff[1] - (pitch+xyz[0])/Coeff[0]
245  = -xyz[0]/Coeff[0] - pitch*(1/Coeff[0]-1/Coeff[1])
246  */
247  for (int ip = 0; ip < plane; ++ip){
248  fXTicksOffsets[cstat][tpc][plane] += tpcgeom.PlanePitch(ip,ip+1)/fXTicksCoefficientgap[ip+2];
249  }
250  fXTicksOffsets[cstat][tpc][plane] -= tpcgeom.PlanePitch()*(1/fXTicksCoefficient-1/fXTicksCoefficientgap[1]);
251  }
252 
253  // Add view dependent offset
254  geo::View_t view = pgeom.View();
255  if(view == geo::kU)
256  fXTicksOffsets[cstat][tpc][plane] += fTimeOffsetU;
257  else if(view == geo::kV)
258  fXTicksOffsets[cstat][tpc][plane] += fTimeOffsetV;
259  else if(view == geo::kZ)
260  fXTicksOffsets[cstat][tpc][plane] += fTimeOffsetZ;
261  else
262  throw cet::exception("DetectorPropertiesServiceArgoNeuT") << "Bad view = "
263  << view << "\n" ;
264  }
265  }
266  }
267 
268  fXTicksParamsLoaded=true;
269  }
270 
271  //--------------------------------------------------------------------
272  // Get scale factor for x<-->ticks
273 
275  {
277  return fXTicksCoefficient * fDriftDirection.at(c).at(t);
278  }
279 
280  //--------------------------------------------------------------------
281  // Get scale factor for x<-->ticks
282 
284  {
286  return fXTicksCoefficient;
287  }
288 
289  //--------------------------------------------------------------------
290  // Get offset for x<-->ticks
291 
292  double DetectorPropertiesServiceArgoNeuT::GetXTicksOffset(int p, int t, int c) const
293  {
295  return fXTicksOffsets.at(c).at(t).at(p);
296  }
297 
298  //--------------------------------------------------------------------
299  // Callback called after input file is opened.
300 
301  void DetectorPropertiesServiceArgoNeuT::postOpenFile(const std::string& filename)
302  {
303  // Use this method to figure out whether to inherit configuration
304  // parameters from previous jobs.
305  //
306  // There is no way currently to correlate parameter sets saved in
307  // sqlite RootFileDB with process history (from MetaData tree).
308  // Therefore, we use the approach of scanning every historical
309  // parameter set in RootFileDB, and finding all parameter sets
310  // that appear to be DetectorPropertiesServiceArgoNeuT configurations. If all
311  // historical parameter sets are in agreement about the value of
312  // an inherited parameter, then we accept the historical value,
313  // print a message, and override the configuration parameter. In
314  // cases where the historical configurations are not in agreement
315  // about the value of an inherited parameter, we ignore any
316  // historical parameter values that are the same as the current
317  // configured value of the parameter (that is, we resolve the
318  // conflict in favor of parameters values that are different than
319  // the current configuration). If two or more historical values
320  // differ from the current configuration, throw an exception.
321  // Note that it is possible to give precendence to the current
322  // configuration by disabling inheritance for that configuration
323  // parameter.
324 
325  // Don't do anything if no parameters are supposed to be inherited.
326 
328  return;
329 
330  // The only way to access art service metadata from the input file
331  // is to open it as a separate TFile object. Do that now.
332 
333  if(filename.size() != 0) {
334 
335  TFile* file = TFile::Open(filename.c_str(), "READ");
336  if(file != 0 && !file->IsZombie() && file->IsOpen()) {
337 
338  // Open the sqlite datatabase.
339 
340  art::SQLite3Wrapper sqliteDB(file, "RootFileDB");
341 
342  // Loop over all stored ParameterSets.
343 
344  unsigned int iNumberTimeSamples = 0; // Combined value of NumberTimeSamples.
345  unsigned int nNumberTimeSamples = 0; // Number of NumberTimeSamples parameters seen.
346 
347  sqlite3_stmt * stmt = 0;
348  sqlite3_prepare_v2(sqliteDB, "SELECT PSetBlob from ParameterSets;", -1, &stmt, NULL);
349  while (sqlite3_step(stmt) == SQLITE_ROW) {
351  fhicl::make_ParameterSet(reinterpret_cast<char const *>(sqlite3_column_text(stmt, 0)), ps);
352  // Is this a DetectorPropertiesServiceArgoNeuT parameter set?
353 
354  bool psok = isDetectorPropertiesServiceArgoNeuT(ps);
355  if(psok) {
356 
357  // Check NumberTimeSamples
358 
360  unsigned int newNumberTimeSamples = ps.get<unsigned int>("NumberTimeSamples");
361 
362  // Ignore parameter values that match the current configuration.
363 
364  if(newNumberTimeSamples != fPS.get<unsigned int>("NumberTimeSamples")) {
365  if(nNumberTimeSamples == 0)
366  iNumberTimeSamples = newNumberTimeSamples;
367  else if(newNumberTimeSamples != iNumberTimeSamples) {
368  throw cet::exception("DetectorPropertiesServiceArgoNeuT")
369  << "Historical values of NumberTimeSamples do not agree: "
370  << iNumberTimeSamples << " " << newNumberTimeSamples << "\n" ;
371  }
372  ++nNumberTimeSamples;
373  }
374  }
375  }
376  }
377 
378  // Done looping over parameter sets.
379  // Now decide which parameters we will actually override.
380 
382  nNumberTimeSamples != 0 &&
383  iNumberTimeSamples != fNumberTimeSamples) {
384  mf::LogInfo("DetectorPropertiesServiceArgoNeuT")
385  << "Overriding configuration parameter NumberTimeSamples using historical value.\n"
386  << " Configured value: " << fNumberTimeSamples << "\n"
387  << " Historical (used) value: " << iNumberTimeSamples << "\n";
388  fNumberTimeSamples = iNumberTimeSamples;
389  }
390  }
391 
392  // Close file.
393  if(file != 0) {
394  if(file->IsOpen())
395  file->Close();
396  delete file;
397  }
398  }
399  }
400 
401  //--------------------------------------------------------------------
402  // Determine whether a parameter set is a DetectorPropertiesServiceArgoNeuT configuration.
403 
405  {
406  // This method uses heuristics to determine whether the parameter
407  // set passed as argument is a DetectorPropertiesServiceArgoNeuT configuration
408  // parameter set.
409 
410  std::string s;
411  double d;
412  int i;
413  unsigned int u;
414 
415  bool result = !ps.get_if_present("module_label", s);
416  result = result && ps.get_if_present("TriggerOffset", i);
417  result = result && ps.get_if_present("SamplingRate", d);
418  result = result && ps.get_if_present("NumberTimeSamples", u);
419  result = result && ps.get_if_present("ReadOutWindowSize", u);
420 
421  return result;
422  }
423 
424 } // namespace
425 
426 namespace util{
427 
429 
430 } // namespace util
Float_t s
Definition: plot.C:23
Namespace for general, non-LArSoft-specific utilities.
Definition: PIDAAlg.h:17
double PlanePitch(unsigned int p1=0, unsigned int p2=1) const
Returns the center of the TPC volume in world coordinates [cm].
Definition: TPCGeo.cxx:418
Encapsulate the construction of a single cyostat.
double fTimeOffsetU
time offsets to convert spacepoint
#define DEFINE_ART_SERVICE_INTERFACE_IMPL(svc, iface)
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
Planes which measure V.
Definition: geo_types.h:77
virtual double ConvertTDCToTicks(double tdc) const override
unsigned int Nplanes() const
Number of planes in this tpc.
Definition: TPCGeo.h:145
double fTimeOffsetV
coordinates to hit times on each
double fElectronsToADC
conversion factor for # of ionization electrons to 1 ADC count
Geometry information for a single TPC.
Definition: TPCGeo.h:37
Planes which measure Z direction.
Definition: geo_types.h:79
void make_ParameterSet(intermediate_table const &tbl, ParameterSet &ps)
int Ticks() const
Current clock tick (that is, the number of tick Time() falls in).
Definition: ElecClock.h:235
DetectorPropertiesServiceArgoNeuT(fhicl::ParameterSet const &pset, art::ActivityRegistry &reg)
Drift towards negative X values.
Definition: geo_types.h:109
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
virtual double ConvertTicksToX(double ticks, int p, int t, int c) const override
Planes which measure U.
Definition: geo_types.h:76
virtual double ConvertXToTicks(double X, int p, int t, int c) const override
View_t View() const
Which coordinate does this plane measure.
Definition: PlaneGeo.h:171
bool fInheritNumberTimeSamples
Flag saying whether to inherit NumberTimeSamples.
Properties related to liquid argon environment in the detector.
T get(std::string const &key) const
Definition: ParameterSet.h:231
virtual double DriftVelocity(double efield=0., double temperature=0.) const override
Geometry information for a single wire plane.The plane is represented in the geometry by a solid whic...
Definition: PlaneGeo.h:78
virtual double Efield(unsigned int planegap=0) const override
< kV/cm
Float_t d
Definition: plot.C:237
unsigned int NTPC() const
Number of TPCs in this cryostat.
Definition: CryostatGeo.h:155
CryostatGeo const & Cryostat(geo::CryostatID const &cryoid) const
Returns the specified cryostat.
unsigned int fReadOutWindowSize
number of clock ticks per readout window
bool get_if_present(std::string const &key, T &value) const
Definition: ParameterSet.h:208
std::vector< std::vector< double > > fDriftDirection
DriftDirection_t DriftDirection() const
Returns an enumerator value describing the drift direction.
Definition: TPCGeo.h:127
fhicl::ParameterSet fPS
Original parameter set.
virtual double SamplingRate() const override
Returns the period of the TPC readout electronics clock.
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
bool fAlreadyReadFromDB
tests whether the values have alread been picked up from the Database
virtual double GetXTicksOffset(int p, int t, int c) const override
Encapsulate the construction of a single detector plane.
TDirectory * dir
Definition: macro.C:5
const TPCGeo & TPC(unsigned int itpc) const
Return the itpc&#39;th TPC in the cryostat.
unsigned int fNumberTimeSamples
number of clock ticks per event
GlobalSignal< detail::SignalResponseType::FIFO, void(Event const &)> sPreProcessEvent
std::vector< std::vector< std::vector< double > > > fXTicksOffsets
GlobalSignal< detail::SignalResponseType::LIFO, void(std::string const &)> sPostOpenFile
util::LArPropertiesServiceArgoNeuT const * fLP
Pointer to the specific LArPropertiesServiceArgoNeuT service (provider)
static bool isDetectorPropertiesServiceArgoNeuT(const fhicl::ParameterSet &ps)
TFile * file
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
detinfo::ElecClock fTPCClock
TPC electronics clock.
PlaneGeo const & Plane(geo::View_t view) const
Return the plane in the tpc with View_t view.
Definition: TPCGeo.cxx:298
virtual double ConvertTicksToTDC(double ticks) const override
virtual void reconfigure(fhicl::ParameterSet const &pset) override
Float_t X
Definition: plot.C:39
Namespace collecting geometry-related classes utilities.
const double * PlaneLocation(unsigned int p) const
Returns the coordinates of the center of the specified plane [cm].
Definition: TPCGeo.cxx:412
art framework interface to geometry description
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
Encapsulate the construction of a single detector plane.