LArSoft  v09_93_00
Liquid Argon Software toolkit - https://larsoft.org/
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
SpacePointSolver_module.cc
Go to the documentation of this file.
1 // Christopher Backhouse - bckhouse@fnal.gov
2 
3 // Test file at Caltech: /nfs/raid11/dunesam/prodgenie_nu_dune10kt_1x2x6_mcc7.0/prodgenie_nu_dune10kt_1x2x6_63_20160811T171439_merged.root
4 
5 // C/C++ standard libraries
6 #include <iostream>
7 #include <string>
8 
9 // framework libraries
18 #include "cetlib/pow.h"
19 #include "fhiclcpp/ParameterSet.h"
20 
21 // LArSoft libraries
23 #include "larcoreobj/SimpleTypesAndConstants/RawTypes.h" // raw::ChannelID_t
27 
28 #include "larevt/CalibrationDBI/Interface/ChannelStatusProvider.h"
29 #include "larevt/CalibrationDBI/Interface/ChannelStatusService.h"
30 
32 
35 
36 namespace reco3d {
37 
42 
43  bool operator<(const InductionWireWithXPos& w) const { return xpos < w.xpos; }
44 
46  double xpos;
47  };
48 
50  public:
51  explicit SpacePointSolver(const fhicl::ParameterSet& pset);
52 
53  private:
54  void produce(art::Event& evt) override;
55  void beginJob() override;
56 
57  void AddNeighbours(const std::vector<SpaceCharge*>& spaceCharges) const;
58 
59  typedef std::map<const WireHit*, const recob::Hit*> HitMap_t;
60 
61  void BuildSystem(const std::vector<HitTriplet>& triplets,
62  std::vector<CollectionWireHit*>& cwires,
63  std::vector<InductionWireHit*>& iwires,
64  std::vector<SpaceCharge*>& orphanSCs,
65  bool incNei,
66  HitMap_t& hitmap) const;
67 
68  void Minimize(const std::vector<CollectionWireHit*>& cwires,
69  const std::vector<SpaceCharge*>& orphanSCs,
70  double alpha,
71  int maxiterations);
72 
74  bool AddSpacePoint(const SpaceCharge& sc,
75  int id,
77 
78  void FillSystemToSpacePoints(const std::vector<CollectionWireHit*>& cwires,
79  const std::vector<SpaceCharge*>& orphanSCs,
81 
82  void FillSystemToSpacePointsAndAssns(const std::vector<art::Ptr<recob::Hit>>& hitlist,
83  const std::vector<CollectionWireHit*>& cwires,
84  const std::vector<SpaceCharge*>& orphanSCs,
85  const HitMap_t& hitmap,
88 
89  std::string fHitLabel;
90 
91  bool fFit;
92  bool fAllowBadInductionHit, fAllowBadCollectionHit;
93 
94  double fAlpha;
95 
96  double fDistThresh;
98 
101 
102  double fXHitOffset;
103 
105  std::unique_ptr<reco3d::IHitReader> fHitReader;
106 
107  unsigned int fMinNHits;
108  unsigned int fMaxNTriplets;
109  };
110 
112 
113  // ---------------------------------------------------------------------------
114  SpacePointSolver::SpacePointSolver(const fhicl::ParameterSet& pset)
115  : EDProducer{pset}
116  , fHitLabel(pset.get<std::string>("HitLabel"))
117  , fFit(pset.get<bool>("Fit"))
118  , fAllowBadInductionHit(pset.get<bool>("AllowBadInductionHit"))
119  , fAllowBadCollectionHit(pset.get<bool>("AllowBadCollectionHit"))
120  , fAlpha(pset.get<double>("Alpha"))
121  , fDistThresh(pset.get<double>("WireIntersectThreshold"))
122  , fDistThreshDrift(pset.get<double>("WireIntersectThresholdDriftDir"))
123  , fMaxIterationsNoReg(pset.get<int>("MaxIterationsNoReg"))
124  , fMaxIterationsReg(pset.get<int>("MaxIterationsReg"))
125  , fXHitOffset(pset.get<double>("XHitOffset"))
126  , fMinNHits(pset.get<unsigned int>("MinNHits"))
127  , fMaxNTriplets(pset.get<unsigned int>("MaxNTriplets"))
128  {
129  recob::ChargedSpacePointCollectionCreator::produces(producesCollector(), "pre");
130  if (fFit) {
132  produces<art::Assns<recob::SpacePoint, recob::Hit>>();
133  recob::ChargedSpacePointCollectionCreator::produces(producesCollector(), "noreg");
134  }
135 
136  fHitReader = art::make_tool<reco3d::IHitReader>(pset.get<fhicl::ParameterSet>("HitReaderTool"));
137  }
138 
139  // ---------------------------------------------------------------------------
141  {
142  geom = art::ServiceHandle<geo::Geometry const>()->provider();
143  }
144 
145  // ---------------------------------------------------------------------------
146  void SpacePointSolver::AddNeighbours(const std::vector<SpaceCharge*>& spaceCharges) const
147  {
148  static const double kCritDist = 5;
149 
150  // Could use a QuadTree or VPTree etc, but seems like overkill
151  class IntCoord {
152  public:
153  IntCoord(const SpaceCharge& sc)
154  : fX(sc.fX / kCritDist), fY(sc.fY / kCritDist), fZ(sc.fZ / kCritDist)
155  {}
156 
157  bool operator<(const IntCoord& i) const
158  {
159  return std::make_tuple(fX, fY, fZ) < std::make_tuple(i.fX, i.fY, i.fZ);
160  }
161 
162  std::vector<IntCoord> Neighbours() const
163  {
164  std::vector<IntCoord> ret;
165  for (int dx = -1; dx <= +1; ++dx) {
166  for (int dy = -1; dy <= +1; ++dy) {
167  for (int dz = -1; dz <= +1; ++dz) {
168  ret.push_back(IntCoord(fX + dx, fY + dy, fZ + dz));
169  }
170  }
171  }
172  return ret;
173  }
174 
175  protected:
176  IntCoord(int x, int y, int z) : fX(x), fY(y), fZ(z) {}
177 
178  int fX, fY, fZ;
179  };
180 
181  std::map<IntCoord, std::vector<SpaceCharge*>> scMap;
182  for (SpaceCharge* sc : spaceCharges) {
183  scMap[IntCoord(*sc)].push_back(sc);
184  }
185 
186  std::cout << "Neighbour search..." << std::endl;
187 
188  // Now that we know all the space charges, can go through and assign neighbours
189 
190  int Ntests = 0;
191  int Nnei = 0;
192  for (SpaceCharge* sc1 : spaceCharges) {
193  IntCoord ic(*sc1);
194  for (IntCoord icn : ic.Neighbours()) {
195  for (SpaceCharge* sc2 : scMap[icn]) {
196 
197  ++Ntests;
198 
199  if (sc1 == sc2) continue;
200  double dist2 =
201  cet::sum_of_squares(sc1->fX - sc2->fX, sc1->fY - sc2->fY, sc1->fZ - sc2->fZ);
202 
203  if (dist2 > cet::square(kCritDist)) continue;
204 
205  if (dist2 == 0) {
206  std::cout << "ZERO DISTANCE SOMEHOW?" << std::endl;
207  std::cout << sc1->fCWire << " " << sc1->fWire1 << " " << sc1->fWire2 << std::endl;
208  std::cout << sc2->fCWire << " " << sc2->fWire1 << " " << sc2->fWire2 << std::endl;
209  std::cout << dist2 << " " << sc1->fX << " " << sc2->fX << " " << sc1->fY << " "
210  << sc2->fY << " " << sc1->fZ << " " << sc2->fZ << std::endl;
211  continue;
212  dist2 = cet::square(kCritDist);
213  }
214 
215  ++Nnei;
216 
217  // This is a pretty random guess
218  const double coupling = exp(-sqrt(dist2) / 2);
219  sc1->fNeighbours.emplace_back(sc2, coupling);
220 
221  if (std::isnan(1 / sqrt(dist2)) || std::isinf(1 / sqrt(dist2))) {
222  std::cout << dist2 << " " << sc1->fX << " " << sc2->fX << " " << sc1->fY << " "
223  << sc2->fY << " " << sc1->fZ << " " << sc2->fZ << std::endl;
224  abort();
225  }
226  } // end for sc2
227  } // end for icn
228 
229  // The neighbours lists use the most memory, so be careful to trim
230  sc1->fNeighbours.shrink_to_fit();
231  } // end for sc1
232 
233  for (SpaceCharge* sc : spaceCharges) {
234  for (Neighbour& nei : sc->fNeighbours) {
235  sc->fNeiPotential += nei.fCoupling * nei.fSC->fPred;
236  }
237  }
238 
239  std::cout << Ntests << " tests to find " << Nnei << " neighbours" << std::endl;
240  }
241 
242  // ---------------------------------------------------------------------------
243  void SpacePointSolver::BuildSystem(const std::vector<HitTriplet>& triplets,
244  std::vector<CollectionWireHit*>& cwires,
245  std::vector<InductionWireHit*>& iwires,
246  std::vector<SpaceCharge*>& orphanSCs,
247  bool incNei,
248  HitMap_t& hitmap) const
249  {
250  std::set<const recob::Hit*> ihits;
251  std::set<const recob::Hit*> chits;
252  for (const HitTriplet& trip : triplets) {
253  if (trip.x) chits.insert(trip.x);
254  if (trip.u) ihits.insert(trip.u);
255  if (trip.v) ihits.insert(trip.v);
256  }
257 
258  std::map<const recob::Hit*, InductionWireHit*> inductionMap;
259  for (const recob::Hit* hit : ihits) {
260  InductionWireHit* iwire = new InductionWireHit(hit->Channel(), hit->Integral());
261  inductionMap[hit] = iwire;
262  iwires.emplace_back(iwire);
263  hitmap[iwire] = hit;
264  }
265 
266  std::map<const recob::Hit*, std::vector<SpaceCharge*>> collectionMap;
267  std::map<const recob::Hit*, std::vector<SpaceCharge*>> collectionMapBad;
268 
269  std::set<InductionWireHit*> satisfiedInduction;
270 
271  for (const HitTriplet& trip : triplets) {
272  // Don't have a cwire object yet, set it later
273  SpaceCharge* sc = new SpaceCharge(
274  trip.pt.x, trip.pt.y, trip.pt.z, 0, inductionMap[trip.u], inductionMap[trip.v]);
275 
276  if (trip.u && trip.v) {
277  collectionMap[trip.x].push_back(sc);
278  if (trip.x) {
279  satisfiedInduction.insert(inductionMap[trip.u]);
280  satisfiedInduction.insert(inductionMap[trip.v]);
281  }
282  }
283  else {
284  collectionMapBad[trip.x].push_back(sc);
285  }
286  }
287 
288  std::vector<SpaceCharge*> spaceCharges;
289 
290  for (const recob::Hit* hit : chits) {
291  // Find the space charges associated with this hit
292  std::vector<SpaceCharge*>& scs = collectionMap[hit];
293  if (scs.empty()) {
294  // If there are no full triplets try the triplets with one bad channel
295  scs = collectionMapBad[hit];
296  }
297  else {
298  // If there were good triplets, delete the bad hit ones
299  for (SpaceCharge* sc : collectionMapBad[hit])
300  delete sc;
301  }
302  // Still no space points, don't bother making a wire
303  if (scs.empty()) continue;
304 
305  CollectionWireHit* cwire = new CollectionWireHit(hit->Channel(), hit->Integral(), scs);
306  hitmap[cwire] = hit;
307  cwires.push_back(cwire);
308  spaceCharges.insert(spaceCharges.end(), scs.begin(), scs.end());
309  for (SpaceCharge* sc : scs)
310  sc->fCWire = cwire;
311  } // end for hit
312 
313  // Space charges whose collection wire is bad, which we have no other way of
314  // addressing.
315  for (SpaceCharge* sc : collectionMap[0]) {
316  // Only count orphans where an induction wire has no other explanation
317  if (satisfiedInduction.count(sc->fWire1) == 0 || satisfiedInduction.count(sc->fWire2) == 0) {
318  orphanSCs.push_back(sc);
319  }
320  else {
321  delete sc;
322  }
323  }
324  spaceCharges.insert(spaceCharges.end(), orphanSCs.begin(), orphanSCs.end());
325 
326  std::cout << cwires.size() << " collection wire objects" << std::endl;
327  std::cout << spaceCharges.size() << " potential space points" << std::endl;
328 
329  if (incNei) AddNeighbours(spaceCharges);
330  }
331 
332  // ---------------------------------------------------------------------------
334  int id,
336  {
337  static const double err[6] = {
338  0,
339  };
340 
341  const float charge = sc.fPred;
342  if (charge == 0) return false;
343 
344  const double xyz[3] = {sc.fX, sc.fY, sc.fZ};
345  points.add({xyz, err, 0.0, id}, charge);
346 
347  return true;
348  }
349 
350  // ---------------------------------------------------------------------------
352  const std::vector<CollectionWireHit*>& cwires,
353  const std::vector<SpaceCharge*>& orphanSCs,
355  {
356  int iPoint = 0;
357  for (const CollectionWireHit* cwire : cwires) {
358  for (const SpaceCharge* sc : cwire->fCrossings) {
359  AddSpacePoint(*sc, iPoint++, points);
360  } // for sc
361  } // for cwire
362 
363  for (const SpaceCharge* sc : orphanSCs)
364  AddSpacePoint(*sc, iPoint++, points);
365  }
366 
367  // ---------------------------------------------------------------------------
369  const std::vector<art::Ptr<recob::Hit>>& hitlist,
370  const std::vector<CollectionWireHit*>& cwires,
371  const std::vector<SpaceCharge*>& orphanSCs,
372  const HitMap_t& hitmap,
375  {
376  std::map<const recob::Hit*, art::Ptr<recob::Hit>> ptrmap;
377  for (art::Ptr<recob::Hit> hit : hitlist)
378  ptrmap[hit.get()] = hit;
379 
380  std::vector<const SpaceCharge*> scs;
381  for (const SpaceCharge* sc : orphanSCs)
382  scs.push_back(sc);
383  for (const CollectionWireHit* cwire : cwires)
384  for (const SpaceCharge* sc : cwire->fCrossings)
385  scs.push_back(sc);
386 
387  int iPoint = 0;
388 
389  for (const SpaceCharge* sc : scs) {
390  if (!AddSpacePoint(*sc, iPoint++, points)) continue;
391  const auto& spsPtr = points.lastSpacePointPtr();
392 
393  if (sc->fCWire) { assn.addSingle(spsPtr, ptrmap[hitmap.at(sc->fCWire)]); }
394  if (sc->fWire1) { assn.addSingle(spsPtr, ptrmap[hitmap.at(sc->fWire1)]); }
395  if (sc->fWire2) { assn.addSingle(spsPtr, ptrmap[hitmap.at(sc->fWire2)]); }
396  }
397  }
398 
399  // ---------------------------------------------------------------------------
400  void SpacePointSolver::Minimize(const std::vector<CollectionWireHit*>& cwires,
401  const std::vector<SpaceCharge*>& orphanSCs,
402  double alpha,
403  int maxiterations)
404  {
405  double prevMetric = Metric(cwires, alpha);
406  std::cout << "Begin: " << prevMetric << std::endl;
407  for (int i = 0; i < maxiterations; ++i) {
408  Iterate(cwires, orphanSCs, alpha);
409  const double metric = Metric(cwires, alpha);
410  std::cout << i << " " << metric << std::endl;
411  if (metric > prevMetric) {
412  std::cout << "Warning: metric increased" << std::endl;
413  return;
414  }
415  if (fabs(metric - prevMetric) < 1e-3 * fabs(prevMetric)) return;
416  prevMetric = metric;
417  }
418  }
419 
420  // ---------------------------------------------------------------------------
422  {
424  std::vector<art::Ptr<recob::Hit>> hitlist;
425  if (evt.getByLabel(fHitLabel, hits)) art::fill_ptr_vector(hitlist, hits);
426 
427  auto spcol_pre = recob::ChargedSpacePointCollectionCreator::forPtrs(evt, "pre");
428  auto spcol_noreg = recob::ChargedSpacePointCollectionCreator::forPtrs(evt, "noreg");
430  auto assns = std::make_unique<art::Assns<recob::SpacePoint, recob::Hit>>();
431 
432  auto putemptycols = [&]() {
433  spcol_pre.put();
434  if (fFit) {
435  spcol.put();
436  evt.put(std::move(assns));
437  spcol_noreg.put();
438  }
439  };
440 
441  // Skip very small events
442  if (hits->size() < fMinNHits) {
443  putemptycols();
444  return;
445  }
446 
448 
449  std::vector<art::Ptr<recob::Hit>> xhits, uhits, vhits;
450  bool is2view = fHitReader->readHits(hitlist, xhits, uhits, vhits);
451 
452  std::vector<raw::ChannelID_t> xbadchans, ubadchans, vbadchans;
453  if (fAllowBadInductionHit || fAllowBadCollectionHit) {
454  for (raw::ChannelID_t cid :
455  art::ServiceHandle<lariov::ChannelStatusService const>()->GetProvider().BadChannels()) {
456  if (geom->SignalType(cid) == geo::kCollection) {
457  if (fAllowBadCollectionHit && geom->View(cid) == geo::kZ) { xbadchans.push_back(cid); }
458  }
459  else {
460  if (fAllowBadInductionHit) {
461  if (geom->View(cid) == geo::kU) ubadchans.push_back(cid);
462  if (geom->View(cid) == geo::kV) vbadchans.push_back(cid);
463  }
464  }
465  }
466  }
467  std::cout << xbadchans.size() << " X, " << ubadchans.size() << " U, " << vbadchans.size()
468  << " V bad channels" << std::endl;
469 
470  std::vector<CollectionWireHit*> cwires;
471  // So we can find them all to free the memory
472  std::vector<InductionWireHit*> iwires;
473  // Nodes with a bad collection wire that we otherwise can't address
474  std::vector<SpaceCharge*> orphanSCs;
475 
476  auto const detProp =
478 
479  HitMap_t hitmap;
480  if (is2view) {
481  std::cout << "Finding 2-view coincidences..." << std::endl;
482  TripletFinder tf(detProp,
483  xhits,
484  uhits,
485  {},
486  xbadchans,
487  ubadchans,
488  {},
489  fDistThresh,
490  fDistThreshDrift,
491  fXHitOffset);
492  auto triplets = tf.TripletsTwoView();
493  if (fMaxNTriplets > 0 && triplets.size() > fMaxNTriplets) {
494  std::cout << "Huge Triplet Size, bailing out" << std::endl;
495  putemptycols();
496  return;
497  }
498  BuildSystem(triplets, cwires, iwires, orphanSCs, fAlpha != 0, hitmap);
499  }
500  else {
501  std::cout << "Finding XUV coincidences..." << std::endl;
502  TripletFinder tf(detProp,
503  xhits,
504  uhits,
505  vhits,
506  xbadchans,
507  ubadchans,
508  vbadchans,
509  fDistThresh,
510  fDistThreshDrift,
511  fXHitOffset);
512  auto triplets = tf.Triplets();
513  if (fMaxNTriplets > 0 && triplets.size() > fMaxNTriplets) {
514  std::cout << "Huge Triplet Size, bailing out" << std::endl;
515  putemptycols();
516  return;
517  }
518  BuildSystem(triplets, cwires, iwires, orphanSCs, fAlpha != 0, hitmap);
519  }
520 
521  FillSystemToSpacePoints(cwires, orphanSCs, spcol_pre);
522  spcol_pre.put();
523 
524  if (fFit) {
525  std::cout << "Iterating with no regularization..." << std::endl;
526  Minimize(cwires, orphanSCs, 0, fMaxIterationsNoReg);
527 
528  FillSystemToSpacePoints(cwires, orphanSCs, spcol_noreg);
529  spcol_noreg.put();
530 
531  std::cout << "Now with regularization..." << std::endl;
532  Minimize(cwires, orphanSCs, fAlpha, fMaxIterationsReg);
533 
534  FillSystemToSpacePointsAndAssns(hitlist, cwires, orphanSCs, hitmap, spcol, *assns);
535  spcol.put();
536  evt.put(std::move(assns));
537  } // end if fFit
538 
539  for (InductionWireHit* i : iwires)
540  delete i;
541  for (CollectionWireHit* c : cwires)
542  delete c;
543  for (SpaceCharge* s : orphanSCs)
544  delete s;
545  }
546 
547 } // end namespace reco3d
Float_t x
Definition: compare.C:6
const geo::GeometryCore * geom
Planes which measure V.
Definition: geo_types.h:136
art::Ptr< recob::SpacePoint > lastSpacePointPtr() const
Returns an art pointer to the last inserted space point (no check!).
Float_t y
Definition: compare.C:6
void Minimize(const std::vector< CollectionWireHit * > &cwires, const std::vector< SpaceCharge * > &orphanSCs, double alpha, int maxiterations)
static void produces(art::ProducesCollector &producesCollector, std::string const &instanceName={})
Declares the data products being produced.
Double_t z
Definition: plot.C:276
double fCoupling
Definition: Solver.h:34
This provides an art tool interface definition for reading hits into the SpacePointSolver universe...
std::unique_ptr< reco3d::IHitReader > fHitReader
Expt specific tool for reading hits.
void AddNeighbours(const std::vector< SpaceCharge * > &spaceCharges) const
Planes which measure Z direction.
Definition: geo_types.h:138
InductionWireWithXPos(InductionWireHit *w, double x)
Definition: tf_graph.h:25
PutHandle< PROD > put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: Event.h:77
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:289
void produce(art::Event &evt) override
Planes which measure U.
Definition: geo_types.h:135
double fZ
Definition: Solver.h:51
void hits()
Definition: readHits.C:15
std::map< const WireHit *, const recob::Hit * > HitMap_t
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
void beginJob()
Definition: Breakpoints.cc:14
void Iterate(CollectionWireHit *cwire, double alpha)
Definition: Solver.cxx:260
InductionWireHit * fWire2
Definition: Solver.h:53
double fY
Definition: Solver.h:51
parameter set interface
bool AddSpacePoint(const SpaceCharge &sc, int id, recob::ChargedSpacePointCollectionCreator &points) const
return whether the point was inserted (only happens when it has charge)
InductionWireHit * fWire1
Definition: Solver.h:53
void FillSystemToSpacePointsAndAssns(const std::vector< art::Ptr< recob::Hit >> &hitlist, const std::vector< CollectionWireHit * > &cwires, const std::vector< SpaceCharge * > &orphanSCs, const HitMap_t &hitmap, recob::ChargedSpacePointCollectionCreator &points, art::Assns< recob::SpacePoint, recob::Hit > &assn) const
double fX
Definition: Solver.h:51
double Metric(double q, double p)
Definition: Solver.cxx:70
bool operator<(const InductionWireWithXPos &w) const
Description of geometry of one entire detector.
Definition: GeometryCore.h:119
Detector simulation of raw signals on wires.
static ChargedSpacePointCollectionCreator forPtrs(art::Event &event, std::string const &instanceName={})
Static function binding a new object to a specific art event.
void BuildSystem(const std::vector< HitTriplet > &triplets, std::vector< CollectionWireHit * > &cwires, std::vector< InductionWireHit * > &iwires, std::vector< SpaceCharge * > &orphanSCs, bool incNei, HitMap_t &hitmap) const
SigType_t SignalType(PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC plane.
Creates a collection of space points with associated charge.
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
CollectionWireHit * fCWire
Definition: Solver.h:52
Float_t sc
Definition: plot.C:23
void addSingle(Ptr< left_t > const &left, Ptr< right_t > const &right, data_t const &data)
Definition: Assns.h:549
View_t View(PlaneID const &pid) const
Returns the view (wire orientation) on the channels of specified TPC plane.
std::vector< HitTriplet > Triplets()
void FillSystemToSpacePoints(const std::vector< CollectionWireHit * > &cwires, const std::vector< SpaceCharge * > &orphanSCs, recob::ChargedSpacePointCollectionCreator &pts) const
Helpers to create space points with associated charge.
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:46
TCEvent evt
Definition: DataStructs.cxx:8
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:28
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:306
Float_t e
Definition: plot.C:35
double fPred
Definition: Solver.h:57
Float_t w
Definition: plot.C:20
void add(recob::SpacePoint const &spacePoint, recob::PointCharge const &charge)
Inserts the specified space point and associated data into the collection.
art framework interface to geometry description
Signal from collection planes.
Definition: geo_types.h:152
SpaceCharge * fSC
Definition: Solver.h:33