All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
12 #include "art/Framework/Core/EDProducer.h"
13 #include "art/Framework/Core/ModuleMacros.h"
14 #include "art/Framework/Principal/Event.h"
15 #include "art/Framework/Services/Registry/ServiceHandle.h"
16 #include "canvas/Persistency/Common/PtrVector.h"
17 #include "messagefacility/MessageLogger/MessageLogger.h"
18 
31 
32 namespace trkf {
33 
34  class FeatureTracker : public art::EDProducer {
35  public:
36  explicit FeatureTracker(fhicl::ParameterSet const& pset);
37 
38  private:
39  void produce(art::Event& evt) override;
40 
42  TVector3 xyz,
43  std::vector<double>& uvw,
44  std::vector<double>& t,
45  int tpc = 0,
46  int cryo = 0);
47 
48  std::map<int, std::vector<double>> ExtractEndPointTimes(
49  std::vector<recob::EndPoint2D> EndPoints);
50 
51  std::vector<recob::SpacePoint> Get3DFeaturePoints(
52  detinfo::DetectorClocksData const& clockData,
53  detinfo::DetectorPropertiesData const& detProp,
54  std::vector<recob::EndPoint2D> const& EndPoints,
55  art::PtrVector<recob::Hit> const& Hits);
56 
57  std::vector<recob::Seed> GetValidLines(detinfo::DetectorPropertiesData const& detProp,
58  std::vector<recob::SpacePoint>& sps,
59  bool ApplyFilter = true);
60 
61  void RemoveDuplicatePaths(std::vector<recob::Seed>& Seeds,
62  std::vector<int>& ConnectionPoint1,
63  std::vector<int>& ConnectionPoint2);
64 
67 
68  std::string fHitModuleLabel;
69  std::string fCalDataModuleLabel;
70 
73 
74  std::map<int, std::vector<double>> fEndPointTimes;
75  art::ServiceHandle<geo::Geometry const> fGeometryHandle;
76  };
77 
78  FeatureTracker::FeatureTracker(const fhicl::ParameterSet& pset)
79  : EDProducer{pset}
80  , fSP(pset.get<fhicl::ParameterSet>("SpacepointPset"))
81  , fCorner(pset.get<fhicl::ParameterSet>("CornerPset"))
82  , fHitModuleLabel{pset.get<std::string>("HitModuleLabel")}
83  , fCalDataModuleLabel{pset.get<std::string>("CornerPset.CalDataModuleLabel")}
84  , fLineIntFraction{pset.get<double>("LineIntFraction")}
85  , fLineIntThreshold{pset.get<double>("LineIntThreshold")}
86  {
87  produces<std::vector<recob::Seed>>();
88  }
89 
90  void
92  {
93 
94  // Extract hits PtrVector from event
95  art::Handle<std::vector<recob::Hit>> hith;
96  evt.getByLabel(fHitModuleLabel, hith);
97 
98  art::PtrVector<recob::Hit> hitvec;
99  for (unsigned int i = 0; i < hith->size(); ++i) {
100  art::Ptr<recob::Hit> prod(hith, i);
101  hitvec.push_back(prod);
102  }
103 
104  //We need to grab out the wires.
105  art::Handle<std::vector<recob::Wire>> wireHandle;
106  evt.getByLabel(fCalDataModuleLabel, wireHandle);
107  std::vector<recob::Wire> const& wireVec(*wireHandle);
108 
109  //First, have it process the wires.
110  fCorner.GrabWires(wireVec, *fGeometryHandle);
111 
112  std::vector<recob::EndPoint2D> EndPoints;
114 
116 
117  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
118  auto const detProp =
119  art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(evt, clockData);
120  std::vector<recob::SpacePoint> sps = Get3DFeaturePoints(clockData, detProp, EndPoints, hitvec);
121  std::vector<recob::Seed> SeedsToStore = GetValidLines(detProp, sps, true);
122 
123  std::unique_ptr<std::vector<recob::Seed>> seeds(new std::vector<recob::Seed>);
124 
125  for (size_t i = 0; i != SeedsToStore.size(); ++i)
126  seeds->push_back(SeedsToStore.at(i));
127 
128  evt.put(std::move(seeds));
129  }
130 
131  //---------------------------------------------------------------------
132 
133  std::map<int, std::vector<double>>
134  FeatureTracker::ExtractEndPointTimes(std::vector<recob::EndPoint2D> EndPoints)
135  {
136  std::map<int, std::vector<double>> EndPointTimesInPlane;
137  for (size_t i = 0; i != EndPoints.size(); ++i) {
138  EndPointTimesInPlane[EndPoints.at(i).View()].push_back(EndPoints.at(i).DriftTime());
139  }
140 
141  for (std::map<int, std::vector<double>>::iterator itEpTime = EndPointTimesInPlane.begin();
142  itEpTime != EndPointTimesInPlane.end();
143  ++itEpTime) {
144  std::sort(itEpTime->second.begin(), itEpTime->second.end());
145  }
146  return EndPointTimesInPlane;
147  }
148 
149  //---------------------------------------------------------------------
150 
151  std::vector<recob::Seed>
153  std::vector<recob::SpacePoint>& spts,
154  bool ApplyFilter)
155  {
156  std::vector<recob::Seed> SeedsToReturn;
157 
158  std::vector<int> ConnectionPoint1;
159  std::vector<int> ConnectionPoint2;
160  std::map<int, std::vector<int>> SeedConnections;
161 
162  for (size_t i = 0; i != spts.size(); ++i) {
163  for (size_t j = 0; j != i; ++j) {
164 
165  TVector3 xyz_i;
166  TVector3 xyz_j;
167 
168  std::vector<double> t_i, t_j;
169 
170  std::vector<double> uvw_i;
171  std::vector<double> uvw_j;
172 
173  for (size_t d = 0; d != 3; ++d) {
174  xyz_i[d] = spts.at(i).XYZ()[d];
175  xyz_j[d] = spts.at(j).XYZ()[d];
176  }
177 
178  GetProjectedEnds(detProp, xyz_i, uvw_i, t_i, 0, 0);
179  GetProjectedEnds(detProp, xyz_j, uvw_j, t_j, 0, 0);
180 
181  bool ThisLineGood = true;
182 
183  for (size_t p = 0; p != uvw_i.size(); ++p) {
184  TH2F const& RawHist = fCorner.GetWireDataHist(p);
185 
186  double lineint = fCorner.line_integral(
187  RawHist, uvw_i.at(p), t_i.at(p), uvw_j.at(p), t_j.at(p), fLineIntThreshold);
188 
189  if (lineint < fLineIntFraction) { ThisLineGood = false; }
190  }
191  if (ThisLineGood) {
192  double Err[3];
193  double Pos[3];
194  double Dir[3];
195 
196  for (size_t d = 0; d != 3; ++d) {
197  Pos[d] = 0.5 * (xyz_i[d] + xyz_j[d]);
198  Dir[d] = 0.5 * (xyz_i[d] - xyz_j[d]);
199  Err[d] = 0;
200  }
201 
202  ConnectionPoint1.push_back(i);
203  ConnectionPoint2.push_back(j);
204 
205  SeedsToReturn.push_back(recob::Seed(Pos, Dir, Err, Err));
206  }
207  }
208  }
209 
210  if (ApplyFilter) {
211  RemoveDuplicatePaths(SeedsToReturn, ConnectionPoint1, ConnectionPoint2);
212  mf::LogInfo("FeatureTracker")
213  << "Seeds after filter " << SeedsToReturn.size() << " seeds" << std::endl;
214  }
215 
216  return SeedsToReturn;
217  }
218 
219  //--------------------------------------------------
220 
221  void
222  FeatureTracker::RemoveDuplicatePaths(std::vector<recob::Seed>& Seeds,
223  std::vector<int>& ConnectionPoint1,
224  std::vector<int>& ConnectionPoint2)
225  {
226 
227  std::map<int, bool> MarkedForRemoval;
228 
229  std::map<int, std::vector<int>> SeedsSharingPoint;
230  for (size_t i = 0; i != Seeds.size(); ++i) {
231  SeedsSharingPoint[ConnectionPoint1[i]].push_back(i);
232  SeedsSharingPoint[ConnectionPoint2[i]].push_back(i);
233  }
234 
235  for (size_t s = 0; s != Seeds.size(); ++s) {
236 
237  int StartPt = ConnectionPoint1.at(s);
238  int EndPt = ConnectionPoint2.at(s);
239  int MidPt = -1;
240 
241  for (size_t SeedsWithThisStart = 0; SeedsWithThisStart != SeedsSharingPoint[StartPt].size();
242  SeedsWithThisStart++) {
243  int i = SeedsSharingPoint[StartPt].at(SeedsWithThisStart);
244  if (ConnectionPoint1.at(i) == StartPt)
245  MidPt = ConnectionPoint2.at(i);
246  else if (ConnectionPoint2.at(i) == StartPt)
247  MidPt = ConnectionPoint1.at(i);
248 
249  for (size_t SeedsWithThisMid = 0; SeedsWithThisMid != SeedsSharingPoint[MidPt].size();
250  SeedsWithThisMid++) {
251  int j = SeedsSharingPoint[MidPt].at(SeedsWithThisMid);
252  if ((ConnectionPoint1.at(j) == EndPt) || (ConnectionPoint2.at(j) == EndPt)) {
253 
254  double Lengthi = Seeds.at(i).GetLength();
255  double Lengthj = Seeds.at(j).GetLength();
256  double Lengths = Seeds.at(s).GetLength();
257 
258  if ((Lengths > Lengthi) && (Lengths > Lengthj)) {
259  MarkedForRemoval[i] = true;
260  MarkedForRemoval[j] = true;
261  }
262 
263  if ((Lengthi > Lengths) && (Lengthi > Lengthj)) {
264  MarkedForRemoval[s] = true;
265  MarkedForRemoval[j] = true;
266  }
267  if ((Lengthj > Lengthi) && (Lengthj > Lengths)) {
268  MarkedForRemoval[s] = true;
269  MarkedForRemoval[i] = true;
270  }
271  }
272  }
273  }
274  }
275  for (std::map<int, bool>::reverse_iterator itrem = MarkedForRemoval.rbegin();
276  itrem != MarkedForRemoval.rend();
277  ++itrem) {
278  if (itrem->second == true) {
279  Seeds.erase(Seeds.begin() + itrem->first);
280  ConnectionPoint1.erase(ConnectionPoint1.begin() + itrem->first);
281  ConnectionPoint2.erase(ConnectionPoint2.begin() + itrem->first);
282  }
283  }
284  }
285 
286  //---------------------------------------------------------------------
287 
288  void
290  TVector3 xyz,
291  std::vector<double>& uvw,
292  std::vector<double>& t,
293  int tpc,
294  int cryo)
295  {
296  art::ServiceHandle<geo::Geometry const> geo;
297 
298  int NPlanes = geo->Cryostat(cryo).TPC(tpc).Nplanes();
299 
300  uvw.resize(NPlanes);
301  t.resize(NPlanes);
302 
303  for (int plane = 0; plane != NPlanes; plane++) {
304  uvw[plane] = geo->NearestWire(xyz, plane, tpc, cryo);
305  t[plane] = detProp.ConvertXToTicks(xyz[0], plane, tpc, cryo);
306  }
307  }
308 
309  //----------------------------------------------------------------------
310 
311  std::vector<recob::SpacePoint>
314  std::vector<recob::EndPoint2D> const& EndPoints,
315  art::PtrVector<recob::Hit> const& Hits)
316  {
317 
318  art::PtrVector<recob::Hit> HitsForEndPoints;
319 
320  // Loop through the hits looking for the ones which match corners
321  for (std::vector<recob::EndPoint2D>::const_iterator itEP = EndPoints.begin();
322  itEP != EndPoints.end();
323  ++itEP) {
324  int EPMatchCount = 0;
325 
326  for (art::PtrVector<recob::Hit>::const_iterator itHit = Hits.begin(); itHit != Hits.end();
327  ++itHit) {
328 
329  if ((itEP->View() == (*itHit)->View()) &&
330  (itEP->WireID().Wire == (*itHit)->WireID().Wire)) {
331  HitsForEndPoints.push_back(*itHit);
332  EPMatchCount++;
333  }
334  }
335  }
336  std::vector<recob::SpacePoint> spts;
337  fSP.makeSpacePoints(clockData, detProp, HitsForEndPoints, spts);
338 
339  for (size_t i = 0; i != spts.size(); ++i) {
340  for (size_t p = 0; p != 3; ++p) {
341  double Closest = 100000;
342  double spt_t = detProp.ConvertXToTicks(spts.at(i).XYZ()[0], p, 0, 0);
343  for (size_t epTime = 0; epTime != fEndPointTimes[p].size(); ++epTime) {
344  if (fabs(fEndPointTimes[p].at(epTime) - spt_t) < Closest) {
345  Closest = fabs(fEndPointTimes[p].at(epTime) - spt_t);
346  }
347  }
348  }
349  }
350  return spts;
351  }
352 
353  DEFINE_ART_MODULE(FeatureTracker)
354 }
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.
Declaration of signal hit object.
pdgs p
Definition: selectors.fcl:22
trkf::SpacePointAlg fSP
void GetProjectedEnds(detinfo::DetectorPropertiesData const &detProp, TVector3 xyz, std::vector< double > &uvw, std::vector< double > &t, int tpc=0, int cryo=0)
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
void GrabWires(std::vector< recob::Wire > const &wireVec, geo::Geometry const &)
void produce(art::Event &evt) override
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
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
std::map< int, std::vector< double > > fEndPointTimes
std::vector< TrajPoint > seeds
Definition: DataStructs.cxx:14
art::PtrVector< recob::Hit > Hits
Contains all timing reference information for the detector.
then echo File list $list not found else cat $list while read file do echo $file sed s
Definition: file_to_url.sh:60
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.
art framework interface to geometry description
auto const detProp
Encapsulate the construction of a single detector plane.
corner::CornerFinderAlg fCorner
FeatureTracker(fhicl::ParameterSet const &pset)