LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
FeatureTracker_module.cc
Go to the documentation of this file.
1 //
2 // Name: FeatureTracker.h
3 //
4 // Purpose: This module takes features found in 2D and uses them
5 // to produce seeds for 3D tracking.
6 //
7 // Ben Jones, MIT
8 //
9 
10 #include "TVector3.h"
11 
18 
31 
32 namespace trkf {
33 
35  public:
36  explicit FeatureTracker(fhicl::ParameterSet const& pset);
37 
38  private:
39  void produce(art::Event& evt) override;
40 
42  geo::Point_t const& xyz,
43  std::vector<double>& uvw,
44  std::vector<double>& t);
45 
46  std::map<int, std::vector<double>> ExtractEndPointTimes(
47  std::vector<recob::EndPoint2D> EndPoints);
48 
49  std::vector<recob::SpacePoint> Get3DFeaturePoints(
50  detinfo::DetectorClocksData const& clockData,
51  detinfo::DetectorPropertiesData const& detProp,
52  std::vector<recob::EndPoint2D> const& EndPoints,
54 
55  std::vector<recob::Seed> GetValidLines(detinfo::DetectorPropertiesData const& detProp,
56  std::vector<recob::SpacePoint>& sps,
57  bool ApplyFilter = true);
58 
59  void RemoveDuplicatePaths(std::vector<recob::Seed>& Seeds,
60  std::vector<int>& ConnectionPoint1,
61  std::vector<int>& ConnectionPoint2);
62 
65 
66  std::string fHitModuleLabel;
67  std::string fCalDataModuleLabel;
68 
71 
72  std::map<int, std::vector<double>> fEndPointTimes;
74  };
75 
77  : EDProducer{pset}
78  , fSP(pset.get<fhicl::ParameterSet>("SpacepointPset"))
79  , fCorner(pset.get<fhicl::ParameterSet>("CornerPset"))
80  , fHitModuleLabel{pset.get<std::string>("HitModuleLabel")}
81  , fCalDataModuleLabel{pset.get<std::string>("CornerPset.CalDataModuleLabel")}
82  , fLineIntFraction{pset.get<double>("LineIntFraction")}
83  , fLineIntThreshold{pset.get<double>("LineIntThreshold")}
84  {
85  produces<std::vector<recob::Seed>>();
86  }
87 
89  {
90 
91  // Extract hits PtrVector from event
93  evt.getByLabel(fHitModuleLabel, hith);
94 
96  for (unsigned int i = 0; i < hith->size(); ++i) {
97  art::Ptr<recob::Hit> prod(hith, i);
98  hitvec.push_back(prod);
99  }
100 
101  //We need to grab out the wires.
103  evt.getByLabel(fCalDataModuleLabel, wireHandle);
104  std::vector<recob::Wire> const& wireVec(*wireHandle);
105 
106  //First, have it process the wires.
107  fCorner.GrabWires(wireVec, *fGeometryHandle);
108 
109  std::vector<recob::EndPoint2D> EndPoints;
111 
113 
114  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
115  auto const detProp =
117  std::vector<recob::SpacePoint> sps = Get3DFeaturePoints(clockData, detProp, EndPoints, hitvec);
118  std::vector<recob::Seed> SeedsToStore = GetValidLines(detProp, sps, true);
119 
120  std::unique_ptr<std::vector<recob::Seed>> seeds(new std::vector<recob::Seed>);
121 
122  for (size_t i = 0; i != SeedsToStore.size(); ++i)
123  seeds->push_back(SeedsToStore.at(i));
124 
125  evt.put(std::move(seeds));
126  }
127 
128  //---------------------------------------------------------------------
129 
130  std::map<int, std::vector<double>> FeatureTracker::ExtractEndPointTimes(
131  std::vector<recob::EndPoint2D> EndPoints)
132  {
133  std::map<int, std::vector<double>> EndPointTimesInPlane;
134  for (size_t i = 0; i != EndPoints.size(); ++i) {
135  EndPointTimesInPlane[EndPoints.at(i).View()].push_back(EndPoints.at(i).DriftTime());
136  }
137 
138  for (std::map<int, std::vector<double>>::iterator itEpTime = EndPointTimesInPlane.begin();
139  itEpTime != EndPointTimesInPlane.end();
140  ++itEpTime) {
141  std::sort(itEpTime->second.begin(), itEpTime->second.end());
142  }
143  return EndPointTimesInPlane;
144  }
145 
146  //---------------------------------------------------------------------
147 
148  std::vector<recob::Seed> FeatureTracker::GetValidLines(
149  detinfo::DetectorPropertiesData const& detProp,
150  std::vector<recob::SpacePoint>& spts,
151  bool ApplyFilter)
152  {
153  std::vector<recob::Seed> SeedsToReturn;
154 
155  std::vector<int> ConnectionPoint1;
156  std::vector<int> ConnectionPoint2;
157  std::map<int, std::vector<int>> SeedConnections;
158 
159  for (size_t i = 0; i != spts.size(); ++i) {
160  for (size_t j = 0; j != i; ++j) {
161 
162  auto const& xyz_i = spts[i].position();
163  auto const& xyz_j = spts[j].position();
164 
165  std::vector<double> t_i, t_j;
166  std::vector<double> uvw_i, uvw_j;
167 
168  GetProjectedEnds(detProp, xyz_i, uvw_i, t_i);
169  GetProjectedEnds(detProp, xyz_j, uvw_j, t_j);
170 
171  bool ThisLineGood = true;
172 
173  for (size_t p = 0; p != uvw_i.size(); ++p) {
174  TH2F const& RawHist = fCorner.GetWireDataHist(p);
175 
176  double lineint = fCorner.line_integral(
177  RawHist, uvw_i.at(p), t_i.at(p), uvw_j.at(p), t_j.at(p), fLineIntThreshold);
178 
179  if (lineint < fLineIntFraction) { ThisLineGood = false; }
180  }
181  if (ThisLineGood) {
182  double Err[3] = {};
183  double Pos[3] = {0.5 * (xyz_i.X() + xyz_j.X()),
184  0.5 * (xyz_i.Y() + xyz_j.Y()),
185  0.5 * (xyz_i.Z() + xyz_j.Z())};
186  double Dir[3] = {0.5 * (xyz_i.X() - xyz_j.X()),
187  0.5 * (xyz_i.Y() - xyz_j.Y()),
188  0.5 * (xyz_i.Z() - xyz_j.Z())};
189 
190  ConnectionPoint1.push_back(i);
191  ConnectionPoint2.push_back(j);
192 
193  SeedsToReturn.push_back(recob::Seed(Pos, Dir, Err, Err));
194  }
195  }
196  }
197 
198  if (ApplyFilter) {
199  RemoveDuplicatePaths(SeedsToReturn, ConnectionPoint1, ConnectionPoint2);
200  mf::LogInfo("FeatureTracker")
201  << "Seeds after filter " << SeedsToReturn.size() << " seeds" << std::endl;
202  }
203 
204  return SeedsToReturn;
205  }
206 
207  //--------------------------------------------------
208 
209  void FeatureTracker::RemoveDuplicatePaths(std::vector<recob::Seed>& Seeds,
210  std::vector<int>& ConnectionPoint1,
211  std::vector<int>& ConnectionPoint2)
212  {
213 
214  std::map<int, bool> MarkedForRemoval;
215 
216  std::map<int, std::vector<int>> SeedsSharingPoint;
217  for (size_t i = 0; i != Seeds.size(); ++i) {
218  SeedsSharingPoint[ConnectionPoint1[i]].push_back(i);
219  SeedsSharingPoint[ConnectionPoint2[i]].push_back(i);
220  }
221 
222  for (size_t s = 0; s != Seeds.size(); ++s) {
223 
224  int StartPt = ConnectionPoint1.at(s);
225  int EndPt = ConnectionPoint2.at(s);
226  int MidPt = -1;
227 
228  for (size_t SeedsWithThisStart = 0; SeedsWithThisStart != SeedsSharingPoint[StartPt].size();
229  SeedsWithThisStart++) {
230  int i = SeedsSharingPoint[StartPt].at(SeedsWithThisStart);
231  if (ConnectionPoint1.at(i) == StartPt)
232  MidPt = ConnectionPoint2.at(i);
233  else if (ConnectionPoint2.at(i) == StartPt)
234  MidPt = ConnectionPoint1.at(i);
235 
236  for (size_t SeedsWithThisMid = 0; SeedsWithThisMid != SeedsSharingPoint[MidPt].size();
237  SeedsWithThisMid++) {
238  int j = SeedsSharingPoint[MidPt].at(SeedsWithThisMid);
239  if ((ConnectionPoint1.at(j) == EndPt) || (ConnectionPoint2.at(j) == EndPt)) {
240 
241  double Lengthi = Seeds.at(i).GetLength();
242  double Lengthj = Seeds.at(j).GetLength();
243  double Lengths = Seeds.at(s).GetLength();
244 
245  if ((Lengths > Lengthi) && (Lengths > Lengthj)) {
246  MarkedForRemoval[i] = true;
247  MarkedForRemoval[j] = true;
248  }
249 
250  if ((Lengthi > Lengths) && (Lengthi > Lengthj)) {
251  MarkedForRemoval[s] = true;
252  MarkedForRemoval[j] = true;
253  }
254  if ((Lengthj > Lengthi) && (Lengthj > Lengths)) {
255  MarkedForRemoval[s] = true;
256  MarkedForRemoval[i] = true;
257  }
258  }
259  }
260  }
261  }
262  for (std::map<int, bool>::reverse_iterator itrem = MarkedForRemoval.rbegin();
263  itrem != MarkedForRemoval.rend();
264  ++itrem) {
265  if (itrem->second == true) {
266  Seeds.erase(Seeds.begin() + itrem->first);
267  ConnectionPoint1.erase(ConnectionPoint1.begin() + itrem->first);
268  ConnectionPoint2.erase(ConnectionPoint2.begin() + itrem->first);
269  }
270  }
271  }
272 
273  //---------------------------------------------------------------------
274 
276  geo::Point_t const& xyz,
277  std::vector<double>& uvw,
278  std::vector<double>& t)
279  {
281 
282  constexpr geo::TPCID tpcID{0, 0};
283  unsigned int NPlanes = geo->TPC(tpcID).Nplanes();
284 
285  uvw.resize(NPlanes);
286  t.resize(NPlanes);
287 
288  for (unsigned int plane = 0; plane != NPlanes; plane++) {
289  uvw[plane] = geo->NearestWireID(xyz, geo::PlaneID{tpcID, plane}).Wire;
290  t[plane] = detProp.ConvertXToTicks(xyz.X(), geo::PlaneID{tpcID, plane});
291  }
292  }
293 
294  //----------------------------------------------------------------------
295 
296  std::vector<recob::SpacePoint> FeatureTracker::Get3DFeaturePoints(
297  detinfo::DetectorClocksData const& clockData,
298  detinfo::DetectorPropertiesData const& detProp,
299  std::vector<recob::EndPoint2D> const& EndPoints,
301  {
302 
303  art::PtrVector<recob::Hit> HitsForEndPoints;
304 
305  // Loop through the hits looking for the ones which match corners
306  for (std::vector<recob::EndPoint2D>::const_iterator itEP = EndPoints.begin();
307  itEP != EndPoints.end();
308  ++itEP) {
309  int EPMatchCount = 0;
310 
311  for (art::PtrVector<recob::Hit>::const_iterator itHit = Hits.begin(); itHit != Hits.end();
312  ++itHit) {
313 
314  if ((itEP->View() == (*itHit)->View()) &&
315  (itEP->WireID().Wire == (*itHit)->WireID().Wire)) {
316  HitsForEndPoints.push_back(*itHit);
317  EPMatchCount++;
318  }
319  }
320  }
321  std::vector<recob::SpacePoint> spts;
322  fSP.makeSpacePoints(clockData, detProp, HitsForEndPoints, spts);
323 
324  for (size_t i = 0; i != spts.size(); ++i) {
325  for (size_t p = 0; p != 3; ++p) {
326  double Closest = 100000;
327  double spt_t = detProp.ConvertXToTicks(spts.at(i).XYZ()[0], p, 0, 0);
328  for (size_t epTime = 0; epTime != fEndPointTimes[p].size(); ++epTime) {
329  if (fabs(fEndPointTimes[p].at(epTime) - spt_t) < Closest) {
330  Closest = fabs(fEndPointTimes[p].at(epTime) - spt_t);
331  }
332  }
333  }
334  }
335  return spts;
336  }
337 
339 }
std::vector< recob::SpacePoint > Get3DFeaturePoints(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, std::vector< recob::EndPoint2D > const &EndPoints, art::PtrVector< recob::Hit > const &Hits)
void RemoveDuplicatePaths(std::vector< recob::Seed > &Seeds, std::vector< int > &ConnectionPoint1, std::vector< int > &ConnectionPoint2)
Encapsulate the construction of a single cyostat.
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
unsigned int Nplanes() const
Number of planes in this tpc.
Definition: TPCGeo.h:137
iterator begin()
Definition: PtrVector.h:217
Declaration of signal hit object.
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.cc:6
The data type to uniquely identify a Plane.
Definition: geo_types.h:463
trkf::SpacePointAlg fSP
intermediate_table::const_iterator const_iterator
TH2F const & GetWireDataHist(unsigned int) const
void get_feature_points(std::vector< recob::EndPoint2D > &, geo::Geometry const &)
std::map< int, std::vector< double > > ExtractEndPointTimes(std::vector< recob::EndPoint2D > EndPoints)
art::ServiceHandle< geo::Geometry const > fGeometryHandle
TPCGeo const & TPC(TPCID const &tpcid=tpc_zero) const
Returns the specified TPC.
Definition: GeometryCore.h:722
PutHandle< PROD > put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: Event.h:77
void GrabWires(std::vector< recob::Wire > const &wireVec, geo::Geometry const &)
typename data_t::const_iterator const_iterator
Definition: PtrVector.h:55
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
void produce(art::Event &evt) override
void push_back(Ptr< U > const &p)
Definition: PtrVector.h:435
algorithm to find feature 2D points
void makeSpacePoints(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const art::PtrVector< recob::Hit > &hits, std::vector< recob::SpacePoint > &spts) const
iterator end()
Definition: PtrVector.h:231
float line_integral(TH2F const &hist, int x1, float y1, int x2, float y2, float threshold) const
double ConvertXToTicks(double X, int p, int t, int c) const
The data type to uniquely identify a TPC.
Definition: geo_types.h:381
std::map< int, std::vector< double > > fEndPointTimes
std::vector< TrajPoint > seeds
Definition: DataStructs.cxx:14
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:180
WireID NearestWireID(Point_t const &point, PlaneID const &planeid) const
Returns the ID of wire closest to position in the specified TPC.
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
Contains all timing reference information for the detector.
void GetProjectedEnds(detinfo::DetectorPropertiesData const &detProp, geo::Point_t const &xyz, std::vector< double > &uvw, std::vector< double > &t)
std::vector< recob::Seed > GetValidLines(detinfo::DetectorPropertiesData const &detProp, std::vector< recob::SpacePoint > &sps, bool ApplyFilter=true)
Declaration of basic channel signal object.
TCEvent evt
Definition: DataStructs.cxx:8
Algorithm for generating space points from hits.
Namespace collecting geometry-related classes utilities.
art framework interface to geometry description
Encapsulate the construction of a single detector plane.
corner::CornerFinderAlg fCorner
FeatureTracker(fhicl::ParameterSet const &pset)