LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
MagDriftAna_module.cc
Go to the documentation of this file.
1 //
3 // MagDriftAna class
4 //
5 // dmckee@phys.ksu.edu
6 //
8 
9 // C++ std library includes
10 #include <algorithm>
11 #include <string>
12 
13 // Framework includes
19 #include "art_root_io/TFileService.h"
21 #include "fhiclcpp/ParameterSet.h"
23 
24 // Root Includes
25 #include "TH2.h"
26 #include "TLine.h"
27 
28 // LArSoft includes
38 
40 namespace hit {
41 
43  class MagDriftAna : public art::EDAnalyzer {
44  public:
45  explicit MagDriftAna(fhicl::ParameterSet const& pset);
46 
47  private:
48  void analyze(const art::Event& evt) override;
49  void endJob() override;
50 
51  // intilize the histograms
52  //
53  // Can't be done in Begin job because I want to use LArProperties
54  // which used the database, so I test and run on each
55  // event. Wasteful and silly, but at least it *works*.
56  void ensureHists(art::Event const& evt, detinfo::DetectorClocksData const& clockData);
57 
59  std::string fLArG4ModuleLabel;
60 
61  // Flag for initialization done, because we set up histograms the
62  // first time through beginRun() so that we can use the
63  // database...
64  bool initDone{false};
65 
66  // Drift properties
67  double fDirCosY{0.};
68  double fDirCosZ{0.};
69 
70  TH1D* fChargeXpos{nullptr}; // << position of the MC Truth charge deposition
71  TH1D* fChargeYpos{nullptr};
72  TH1D* fChargeZpos{nullptr};
73  TH1D* fHitZpos{nullptr}; // << Z position of the recorded hit (from the
74  // z-sensitive wire)
75 
76  TH1D* fDriftDeltaZ{nullptr}; // << Difference in MC charge Z and recorded hit Z
77  TH1D* fDeltaZoverX{nullptr}; // << Delta Z as a function of drift distance
78  TH2D* fDeltaZvsX{nullptr};
79 
80  // Same as above, but only for long drift distances (greater than
81  // 4/5 of the detector)
82  TH1D* fDriftDeltaZAway{nullptr}; // << Difference in MC charge Z and recorded hit Z
83  TH1D* fDeltaZoverXAway{nullptr}; // << Delta Z as a function of drift distance
84 
85  }; // class MagdriftAna
86 
87  //-------------------------------------------------
89  : EDAnalyzer(pset)
90  , fFFTHitFinderModuleLabel{pset.get<std::string>("HitsModuleLabel")}
91  , fLArG4ModuleLabel{pset.get<std::string>("LArGeantModuleLabel")}
92  {}
93 
94  //-------------------------------------------------
96  {
97  if (initDone) return; // Bail if we've already done this.
98  initDone = true; // Insure that we bail later on
99 
101 
102  // Find magnetic field related corrections
103  auto const detProp =
105 
106  // art::ServiceHandle<mag::MagneticField const> MagField;
108  auto const* MagField = MagFieldHandle->provider();
109  double Efield = detProp.Efield();
110  double Temperature = detProp.Temperature();
111  double DriftVelocity = detProp.DriftVelocity(Efield, Temperature) / 1000.;
112 
113  // MagneticField::FieldAtPoint() returns (0, 0, 0) if there is no
114  // field at the requested point, so these direction cosines are
115  // 0 if there is no field
116  fDirCosY = -DriftVelocity * MagField->FieldAtPoint().z() / Efield;
117  fDirCosZ = +DriftVelocity * MagField->FieldAtPoint().y() / Efield;
118  MF_LOG_VERBATIM("MagDriftAna") << "Drift ratios: "
119  << "dY/dX = " << fDirCosY << ", "
120  << "dZ/dX = " << fDirCosZ;
121 
122  // geometry data.
124  // assumes all TPCs are the same
125  auto const& tpc_0 = geom->TPC();
126  double width = 2 * tpc_0.HalfWidth();
127  double halfHeight = tpc_0.HalfHeight();
128  double length = tpc_0.Length();
129 
130  double zScale = std::max(fDirCosZ / 2.0, 4e-4);
131 
132  // Assumes microboone dimensions. Ideally we'd fix this later...
133  fChargeXpos =
134  tfs->make<TH1D>("hChargeXpos", "MC X charge depositions; X (cm); Events", 101, 0.0, width);
135  fChargeYpos = tfs->make<TH1D>(
136  "hChargeYpos", "MC Y charge depositions; Y (cm); Events", 101, -halfHeight, halfHeight);
137  fChargeZpos =
138  tfs->make<TH1D>("hChargeZpos", "MC Z charge depositions; Z (cm); Events", 101, 0.0, length);
139  fHitZpos = tfs->make<TH1D>("hHitZpos", "Z charge collection; Z (cm); Events", 101, 0.0, length);
140 
141  fDriftDeltaZ = tfs->make<TH1D>("hDriftDeltaZ",
142  "Z drift of charge; delta Z (cm); Events",
143  101,
144  -5 * zScale * width,
145  5 * zScale * width);
146  fDeltaZoverX = tfs->make<TH1D>(
147  "hDeltaZoverX", "Z drift of charge; delta Z/X; Events", 51, -10 * zScale, 10 * zScale);
148  fDeltaZvsX = tfs->make<TH2D>("hDeltaZvsX",
149  "delta Z vs X; X (cm); delta Z (cm), Events",
150  51,
151  0.0,
152  width,
153  51,
154  -20 * zScale,
155  20 * zScale);
156 
157  // Some stats only when the Xdrift is large (more than 3/4)
158  fDriftDeltaZAway = tfs->make<TH1D>("hDriftDeltaZAway",
159  "Z drift of charge (long drift); delta Z (cm); Events",
160  101,
161  -5 * zScale * width,
162  5 * zScale * width);
163  fDeltaZoverXAway = tfs->make<TH1D>("hDeltaZoverXAway",
164  "Z drift of charge (long drift); delta Z/X; Events",
165  51,
166  -10 * zScale,
167  10 * zScale);
168  }
169 
170  //-------------------------------------------------
172  {
173  // Add a line on the deltaZ/X graph to denote the calculated value
174  // of the drift ration
175  TLine* l = new TLine(fDirCosZ, 0, fDirCosZ, 1.05 * fDeltaZoverX->GetMaximum());
176  l->SetLineColor(kRed);
177  l->SetLineStyle(kDotted);
178  fDeltaZoverX->GetListOfFunctions()->Add(l);
179 
180  // I know this looks like a memory leak, but each historgram needs
181  // it's own copy of the line to prevent double freeing by the
182  // framework...
183  l = new TLine(fDirCosZ, 0, fDirCosZ, 1.05 * fDeltaZoverX->GetMaximum());
184 
185  l->SetLineColor(kRed);
186  l->SetLineStyle(kDotted);
187  fDeltaZoverXAway->GetListOfFunctions()->Add(l);
188  }
189 
190  //-------------------------------------------------
192  {
193  if (evt.isRealData()) {
194  throw cet::exception("MagDriftAna: ") << "Not for use on Data yet...\n";
195  }
196 
197  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
198 
199  ensureHists(evt, clockData);
200 
202  evt.getByLabel(fFFTHitFinderModuleLabel, hitHandle);
203 
205 
206  // We're going to want to compare the reconstructed Z with the
207  // simulted Z. For that purpose we use the simultion backtracking.
208 
210 
211  std::vector<art::Ptr<recob::Hit>> hits;
212  art::fill_ptr_vector(hits, hitHandle);
213 
214  geo::WireID hitWireID;
215 
216  //++++++++++
217  // Loop over the hits (data) and fill histos
218  //++++++++++
219  for (auto itr : hits) {
220 
221  hitWireID = itr->WireID();
222  // By assumption the drift occurs only in the z-direction, so
223  // we can get all the info we need from the z-measug plane.
224  if (hitWireID.Plane != (geom->Nplanes() - 1)) continue;
225 
226  // Charge collected at the wire
227  //
228  // Exactly once for each recob::Hit
229  auto const w0pos = geom->Plane(hitWireID).Wire(0).GetCenter();
230  double HitZpos = w0pos.Z() + hitWireID.Wire * geom->TPC(hitWireID).WirePitch();
231  double Charge = itr->Integral();
232  fHitZpos->Fill(HitZpos, Charge);
233 
234  // Charge deposition in the detector
235  std::vector<double> xyz = bt_serv->HitToXYZ(clockData, itr);
236  fChargeXpos->Fill(xyz[0], Charge);
237  fChargeYpos->Fill(xyz[1], Charge);
238  double ChargeZpos = xyz[2];
239  fChargeZpos->Fill(ChargeZpos, Charge);
240 
241  // Delta-Z
242  //
243  // Compares the collected z position from the wire to the
244  // simulated z position
245  double DeltaZ = HitZpos - ChargeZpos;
246  fDriftDeltaZ->Fill(DeltaZ, Charge);
247  // Delta Z correlation with X
248  fDeltaZoverX->Fill(DeltaZ / xyz[0], Charge);
249  fDeltaZvsX->Fill(xyz[0], DeltaZ, Charge);
250  // The X related histograms know the dimensions of the
251  // detector, so we use them to set the "away" limit
252  if (xyz[0] > (fChargeYpos->GetXaxis()->GetXmax() * 0.80)) {
253  fDriftDeltaZAway->Fill(DeltaZ, Charge);
254  fDeltaZoverXAway->Fill(DeltaZ / xyz[0], Charge);
255  }
256 
257  } // loop on Hits
258 
259  return;
260  } // end analyze method
261 
263 
264 } // end of hit namespace
Point_t const & GetCenter() const
Returns the world coordinate of the center of the wire [cm].
Definition: WireGeo.h:221
void analyze(const art::Event &evt) override
WireGeo const & Wire(unsigned int iwire) const
Definition: PlaneGeo.cxx:465
Declaration of signal hit object.
std::string fLArG4ModuleLabel
std::string fFFTHitFinderModuleLabel
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:563
bool isRealData() const
Definition: Event.cc:53
std::vector< double > HitToXYZ(detinfo::DetectorClocksData const &clockData, const recob::Hit &hit) const
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.cc:6
TPCGeo const & TPC(TPCID const &tpcid=tpc_zero) const
Returns the specified TPC.
Definition: GeometryCore.h:722
Base class for creation of raw signals on wires.
PlaneGeo const & Plane(PlaneID const &planeid) const
Returns the specified wire.
void hits()
Definition: readHits.C:15
virtual const mag::MagneticField * provider() const =0
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
T get(std::string const &key) const
Definition: ParameterSet.h:314
void endJob() override
double WirePitch(unsigned plane=0) const
Returns the center of the TPC volume in world coordinates [cm].
Definition: TPCGeo.cxx:368
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:481
MagDriftAna(fhicl::ParameterSet const &pset)
Detector simulation of raw signals on wires.
Encapsulate the geometry of a wire.
void ensureHists(art::Event const &evt, detinfo::DetectorClocksData const &clockData)
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
Encapsulate the construction of a single detector plane.
Contains all timing reference information for the detector.
#define MF_LOG_VERBATIM(category)
constexpr WireID()=default
Default constructor: an invalid TPC ID.
unsigned int Nplanes(TPCID const &tpcid=tpc_zero) const
Returns the total number of planes in the specified TPC.
Definition: GeometryCore.h:977
TCEvent evt
Definition: DataStructs.cxx:8
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:306
Float_t e
Definition: plot.C:35
art framework interface to geometry description
double HalfWidth() const
Width is associated with x coordinate [cm].
Definition: TPCGeo.h:96
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
Encapsulate the construction of a single detector plane.