ProjectionMatchingAlg.h
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////////////////////////
2 // Class: ProjectionMatchingAlg
3 // Author: D.Stefan (Dorota.Stefan@ncbj.gov.pl) and R.Sulej (Robert.Sulej@cern.ch), May 2015
4 //
5 // Projection Matching Algorithm
6 // see RecoAlg/PMAlg/PmaTrack3D.h for more details.
7 //
8 // Build 3D segments and whole tracks by matching an object 2D projections to hits, simultaneously
9 // in multiple wire planes. Based on the algorithm first presented in "Precise 3D track reco..."
10 // AHEP (2013) 260820, with all the tricks that we developed later and with the work for the full-event
11 // topology optimization that is still under construction now (2015).
12 //
13 // The algorithm class provides functionality to build a track from selected hits. These
14 // can be detailed tracks or just simple segments (if the number of nodes to add is set to 0).
15 // The parameters of optimization algorithm, fixed nodes and 3D reference points can be configured here.
16 // Please, check the track making module to find a way of selecting appropriate clusteres:
17 // PMAlgTrackMaker_module.cc
18 //
19 ////////////////////////////////////////////////////////////////////////////////////////////////////
20 
21 #ifndef ProjectionMatchingAlg_h
22 #define ProjectionMatchingAlg_h
23 
24 // Framework includes
25 #include "fhiclcpp/fwd.h"
26 #include "fhiclcpp/types/Atom.h"
27 
28 // LArSoft includes
34 namespace detinfo {
35  class DetectorPropertiesData;
36 }
37 namespace geo {
38  class GeometryCore;
39  class TPCGeo;
40 }
41 namespace lariov {
42  class ChannelStatusProvider;
43 }
44 
45 // ROOT & C++
46 #include <memory>
47 class TH1F;
48 
49 namespace pma {
50  class ProjectionMatchingAlg;
51 }
52 
54 public:
55  struct Config {
56  using Name = fhicl::Name;
58 
59  fhicl::Atom<double> OptimizationEps{
60  Name("OptimizationEps"),
61  Comment("relative change of the obj.fn which stops optimization after adding a node")};
62 
63  fhicl::Atom<double> FineTuningEps{
64  Name("FineTuningEps"),
65  Comment("relative change of the obj.fn which stops fine-tuning of optimized track")};
66 
67  fhicl::Atom<double> TrkValidationDist2D{
68  Name("TrkValidationDist2D"),
69  Comment("max. distance [cm] used in the track validation in the third plane")};
70 
71  fhicl::Atom<double> HitTestingDist2D{
72  Name("HitTestingDist2D"),
73  Comment("max. distance [cm] used in testing compatibility of hits with the track")};
74 
75  fhicl::Atom<double> MinTwoViewFraction{
76  Name("MinTwoViewFraction"),
77  Comment("min. fraction of track length covered with hits from many 2D views intertwinted "
78  "with each other")};
79 
80  fhicl::Atom<double> NodeMargin3D{
81  Name("NodeMargin3D"),
82  Comment("margin in [cm] around TPC for allowed track node positions")};
83 
84  fhicl::Atom<double> HitWeightU{Name("HitWeightU"), Comment("weights used for hits in U plane")};
85 
86  fhicl::Atom<double> HitWeightV{Name("HitWeightV"), Comment("weights used for hits in V plane")};
87 
88  fhicl::Atom<double> HitWeightZ{Name("HitWeightZ"), Comment("weights used for hits in Z plane")};
89  };
90 
92 
94  : ProjectionMatchingAlg(fhicl::Table<Config>(pset, {})())
95  {}
96 
97  /// Calculate the fraction of the track that is close to non-empty pixel
98  /// (above thr value) in the ADC image of the testView (a view that was not
99  /// used to build the track).
100  double validate_on_adc(const detinfo::DetectorPropertiesData& detProp,
101  const lariov::ChannelStatusProvider& channelStatus,
102  const pma::Track3D& trk,
103  const img::DataProviderAlg& adcImage,
104  float thr) const;
105 
106  /// Calculate the fraction of the track that is closer than
107  /// fTrkValidationDist2D to any hit from hits in the testView (a view that was
108  /// not used to build the track). Creates also histograms of values in pixels
109  /// for the passing and rejected points on the track, so the threshold value
110  /// for the ADC-based calibration can be estimated.
111  double validate_on_adc_test(const detinfo::DetectorPropertiesData& detProp,
112  const lariov::ChannelStatusProvider& channelStatus,
113  const pma::Track3D& trk,
114  const img::DataProviderAlg& adcImage,
115  const std::vector<art::Ptr<recob::Hit>>& hits,
116  TH1F* histoPassing,
117  TH1F* histoRejected) const;
118 
119  /// Calculate the fraction of the track that is closer than
120  /// fTrkValidationDist2D to any hit from hits in their plane (a plane that was
121  /// not used to build the track). Hits should be preselected, so all belong to
122  /// the same plane.
123  double validate(const detinfo::DetectorPropertiesData& detProp,
124  const lariov::ChannelStatusProvider& channelStatus,
125  const pma::Track3D& trk,
126  const std::vector<art::Ptr<recob::Hit>>& hits) const;
127 
128  /// Calculate the fraction of the 3D segment that is closer than
129  /// fTrkValidationDist2D to any hit from hits in the testPlane of TPC/Cryo.
130  /// Hits from the testPlane are preselected by this function among all
131  /// provided (so a bit slower than fn above).
132  double validate(const detinfo::DetectorPropertiesData& detProp,
133  const lariov::ChannelStatusProvider& channelStatus,
134  const TVector3& p0,
135  const TVector3& p1,
136  const std::vector<art::Ptr<recob::Hit>>& hits,
137  unsigned int testView,
138  unsigned int tpc,
139  unsigned int cryo) const;
140 
141  /// Calculate the fraction of trajectory seen by two 2D projections at least; even a
142  /// prfect track starts/stops with the hit from one 2D view, then hits from other views
143  /// come, which results with the fraction value high, but always < 1.0; wrong cluster
144  /// matchings or incomplete tracks give significantly lower values.
145  double twoViewFraction(pma::Track3D& trk) const;
146 
147  /// Count the number of hits that are closer than eps * fHitTestingDist2D to the track 2D projection.
148  unsigned int
150  const pma::Track3D& trk,
151  const std::vector<art::Ptr<recob::Hit>>& hits,
152  double eps = 1.0) const
153  {
154  return trk.TestHits(detProp, hits, eps * fHitTestingDist2D);
155  }
156 
157  /// Test if hits at the track endpoinds do not stick out of TPC which they belong to.
158  /// Here one can implement some configurable margin if needed for real data imeprfections.
159  bool
160  isContained(const pma::Track3D& trk, float margin = 0.0F) const
161  {
162  return (trk.FirstElement()->SameTPC(trk.front()->Point3D(), margin) &&
163  trk.LastElement()->SameTPC(trk.back()->Point3D(), margin));
164  }
165 
166  /// Build a track from two sets of hits from single TPC, hits should origin
167  /// from at least two
168  /// wire planes; number of segments used to create the track depends on the
169  /// number of hits.
170  pma::Track3D* buildTrack(const detinfo::DetectorPropertiesData& detProp,
171  const std::vector<art::Ptr<recob::Hit>>& hits_1,
172  const std::vector<art::Ptr<recob::Hit>>& hits_2 = {}) const;
173 
174  /// Build a track from sets of hits, multiple TPCs are OK (like taken from
175  /// PFParticles),
176  /// as far as hits origin from at least two wire planes.
177  pma::Track3D* buildMultiTPCTrack(const detinfo::DetectorPropertiesData& clockData,
178  const std::vector<art::Ptr<recob::Hit>>& hits) const;
179 
180  /// Build a shower segment from sets of hits and attached to the provided
181  /// vertex.
182  pma::Track3D* buildShowerSeg(const detinfo::DetectorPropertiesData& detProp,
183  const std::vector<art::Ptr<recob::Hit>>& hits,
184  const pma::Vector3D& vtx) const;
185 
186  /// Build a straight segment from two sets of hits (they should origin from
187  /// two wire planes); method is intendet for short tracks or shower initial
188  /// parts, where only a few hits per plane are available and there is no
189  /// chance to see a curvature or any other features.
190  pma::Track3D* buildSegment(const detinfo::DetectorPropertiesData& clockData,
191  const std::vector<art::Ptr<recob::Hit>>& hits_1,
192  const std::vector<art::Ptr<recob::Hit>>& hits_2 = {}) const;
193 
194  /// Build a straight segment from two sets of hits (they should origin from
195  /// two wire planes), starting from a given point (like vertex known from
196  /// another algorithm); method is intendet for short tracks or shower initial
197  /// parts, where only a few hits per plane are available and there is no
198  /// chance to see a curvature or any other features.
199  pma::Track3D* buildSegment(const detinfo::DetectorPropertiesData& clockData,
200  const std::vector<art::Ptr<recob::Hit>>& hits_1,
201  const std::vector<art::Ptr<recob::Hit>>& hits_2,
202  const TVector3& point) const;
203 
204  /// Build a straight segment from set of hits (they should origin from two
205  /// wire planes at least), starting from a given point.
206  pma::Track3D* buildSegment(const detinfo::DetectorPropertiesData& detProp,
207  const std::vector<art::Ptr<recob::Hit>>& hits,
208  const TVector3& point) const;
209 
210  /// Get rid of small groups of hits around cascades; used to calculate cascade
211  /// starting direction using the compact core cluster.
212  void FilterOutSmallParts(const detinfo::DetectorPropertiesData& detProp,
213  double r2d,
214  const std::vector<art::Ptr<recob::Hit>>& hits_in,
216  const TVector2& vtx2d) const;
217 
218  void RemoveNotEnabledHits(pma::Track3D& trk) const;
219 
220  /// Add more hits to an existing track, reoptimize, optionally add more nodes.
221  pma::Track3D* extendTrack(const detinfo::DetectorPropertiesData& clockData,
222  const pma::Track3D& trk,
223  const std::vector<art::Ptr<recob::Hit>>& hits,
224  bool add_nodes) const;
225 
226  /// Add 3D reference points to clean endpoints of a track (both need to be in
227  /// the same TPC).
228  void guideEndpoints(const detinfo::DetectorPropertiesData& clockData,
229  pma::Track3D& trk,
230  const std::map<unsigned int, std::vector<art::Ptr<recob::Hit>>>& hits) const;
231 
232  /// Add 3D reference points to clean endpoint of a track.
233  void guideEndpoints(const detinfo::DetectorPropertiesData& clockData,
234  pma::Track3D& trk,
235  pma::Track3D::ETrackEnd endpoint,
236  const std::map<unsigned int, std::vector<art::Ptr<recob::Hit>>>& hits) const;
237 
238  std::vector<pma::Hit3D*> trimTrackToVolume(pma::Track3D& trk, TVector3 p0, TVector3 p1) const;
239 
240  /// Flip tracks to get second as a continuation of first; returns false if not
241  /// possible (tracks in reversed order).
242  bool alignTracks(pma::Track3D& first, pma::Track3D& second) const;
243 
244  /// Add src to dst as it was its continuation; nodes of src are added to dst
245  /// after its own nodes, hits of src are added to hits of dst, then dst is
246  /// reoptimized.
247  void mergeTracks(const detinfo::DetectorPropertiesData& detProp,
248  pma::Track3D& dst,
249  pma::Track3D& src,
250  bool reopt) const;
251 
252  /// Try to correct track direction of the stopping particle:
253  /// dir: kForward - particle stop is at the end of the track;
254  /// kBackward - particle stop is at the beginning of the track;
255  /// dQ/dx difference has to be above thr to actually flip the track;
256  /// compares dQ/dx of n hits at each end of the track (default is based on the track length).
257  void
260  double thr = 0.0,
261  unsigned int n = 0) const
262  {
263  trk.AutoFlip(dir, thr, n);
264  };
265 
266  /// Intendet to calculate dQ/dx in the initial part of EM cascade; collection
267  /// view is used by default, but it works also with other projections.
268  double selectInitialHits(pma::Track3D& trk,
269  unsigned int view = geo::kZ,
270  unsigned int* nused = 0) const;
271 
272 private:
273  // Helpers for guideEndpoints
274  bool chkEndpointHits_(const detinfo::DetectorPropertiesData& detProp,
275  int wire,
276  int wdir,
277  double drift_x,
278  int view,
279  unsigned int tpc,
280  unsigned int cryo,
281  const pma::Track3D& trk,
282  const std::vector<art::Ptr<recob::Hit>>& hits) const;
283  bool addEndpointRef_(const detinfo::DetectorPropertiesData& detProp,
284  pma::Track3D& trk,
285  const std::map<unsigned int, std::vector<art::Ptr<recob::Hit>>>& hits,
286  std::pair<int, int> const* wires,
287  double const* xPos,
288  unsigned int tpc,
289  unsigned int cryo) const;
290 
291  // Helpers for FilterOutSmallParts
292  bool GetCloseHits_(const detinfo::DetectorPropertiesData& detProp,
293  double r2d,
294  const std::vector<art::Ptr<recob::Hit>>& hits_in,
295  std::vector<size_t>& used,
296  std::vector<art::Ptr<recob::Hit>>& hits_out) const;
297 
298  bool Has_(const std::vector<size_t>& v, size_t idx) const;
299 
300  // Make segment shorter depending on mse
301  void ShortenSeg_(const detinfo::DetectorPropertiesData& detProp,
302  pma::Track3D& trk,
303  const geo::TPCGeo& tpcgeom) const;
304 
305  // Control length of the track and number of hits which are still enabled
306  bool TestTrk_(pma::Track3D& trk, const geo::TPCGeo& tpcgeom) const;
307 
308  // Calculate good number of segments depending on the number of hits.
309  static size_t getSegCount_(size_t trk_size);
310 
311  // Parameters used in the algorithm
312 
313  double const fOptimizationEps; // relative change in the obj.function that
314  // ends optimization, then next nodes are added
315  // or track building is finished
316 
317  double const fFineTuningEps; // relative change in the obj.function that ends
318  // final tuning
319 
320  double const fTrkValidationDist2D; // max. distance [cm] used in the track
321  // validation in the "third" plane
322  double const fHitTestingDist2D; // max. distance [cm] used in testing comp. of
323  // hits with the track
324 
325  double const fMinTwoViewFraction; // min. length fraction covered with multiple 2D
326  // view hits intertwinted with each other
327 
328  // Geometry and detector properties
330 };
331 
332 #endif
void AutoFlip(pma::Track3D::EDirection dir, double thr=0.0, unsigned int n=0)
Definition: PmaTrack3D.cxx:672
Implementation of the Projection Matching Algorithm.
ProjectionMatchingAlg(const fhicl::ParameterSet &pset)
G4double thr[100]
Definition: G4S2Light.cc:59
geo::GeometryCore const * fGeom
pma::Hit3D const * front() const
Definition: PmaTrack3D.h:98
unsigned int TestHits(detinfo::DetectorPropertiesData const &detProp, const std::vector< art::Ptr< recob::Hit >> &hits, double dist=0.4) const
Count close 2D hits.
Definition: PmaTrack3D.cxx:858
Geometry information for a single TPC.
Definition: TPCGeo.h:38
struct vector vector
ChannelGroupService::Name Name
TVector3 const & Point3D() const
Definition: PmaHit3D.h:55
Planes which measure Z direction.
Definition: geo_types.h:132
string dir
recob::tracking::Vector_t Vector3D
Definition: Utilities.h:31
art framework interface to geometry description
pma::Node3D * FirstElement() const
Definition: PmaTrack3D.h:340
unsigned int testHits(detinfo::DetectorPropertiesData const &detProp, const pma::Track3D &trk, const std::vector< art::Ptr< recob::Hit >> &hits, double eps=1.0) const
Count the number of hits that are closer than eps * fHitTestingDist2D to the track 2D projection...
pma::Node3D * LastElement() const
Definition: PmaTrack3D.h:345
bool isContained(const pma::Track3D &trk, float margin=0.0F) const
static Config * config
Definition: config.cpp:1054
void autoFlip(pma::Track3D &trk, pma::Track3D::EDirection dir=Track3D::kForward, double thr=0.0, unsigned int n=0) const
std::void_t< T > n
Class providing information about the quality of channels.
bool SameTPC(const TVector3 &p3d, float margin=0.0F) const
Check if p3d is in the same TPC as the node.
Definition: PmaNode3D.cxx:102
General LArSoft Utilities.
Description of geometry of one entire detector.
def validate(nxgraph, desc)
Definition: graph.py:45
Filters for channels, events, etc.
Implementation of the Projection Matching Algorithm.
Declaration of signal hit object.
#define Comment
pma::Hit3D const * back() const
Definition: PmaTrack3D.h:103
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:85
LArSoft geometry interface.
Definition: ChannelGeo.h:16