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  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,
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 
70 
73 
74  std::map<int, std::vector<double>> fEndPointTimes;
76  };
77 
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
96  evt.getByLabel(fHitModuleLabel, hith);
97 
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.
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 =
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  {
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>
313  detinfo::DetectorPropertiesData const& detProp,
314  std::vector<recob::EndPoint2D> const& EndPoints,
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 
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.
std::string string
Definition: nybbler.cc:12
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
unsigned int Nplanes() const
Number of planes in this tpc.
Definition: TPCGeo.h:165
iterator begin()
Definition: PtrVector.h:217
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.h:20
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)
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 framework interface to geometry description
art::ServiceHandle< geo::Geometry const > fGeometryHandle
void GrabWires(std::vector< recob::Wire > const &wireVec, geo::Geometry const &)
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
Definition: DataViewImpl.h:633
typename data_t::const_iterator const_iterator
Definition: PtrVector.h:55
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
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
def move(depos, offset)
Definition: depos.py:107
geo::WireID::WireID_t NearestWire(geo::Point_t const &point, geo::PlaneID const &planeid) const
Returns the index of wire closest to position in the specified TPC.
iterator end()
Definition: PtrVector.h:231
float line_integral(TH2F const &hist, int x1, float y1, int x2, float y2, float threshold) const
p
Definition: test.py:223
double ConvertXToTicks(double X, int p, int t, int c) const
CryostatGeo const & Cryostat(geo::CryostatID const &cryoid) const
Returns the specified cryostat.
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: DataViewImpl.h:686
std::map< int, std::vector< double > > fEndPointTimes
std::vector< TrajPoint > seeds
Definition: DataStructs.cxx:13
Declaration of signal hit object.
Contains all timing reference information for the detector.
const TPCGeo & TPC(unsigned int itpc) const
Return the itpc&#39;th TPC in the cryostat.
Definition: CryostatGeo.cxx:93
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:7
Algorithm for generating space points from hits.
LArSoft geometry interface.
Definition: ChannelGeo.h:16
static QCString * s
Definition: config.cpp:1042
QTextStream & endl(QTextStream &s)
Encapsulate the construction of a single detector plane.
corner::CornerFinderAlg fCorner
FeatureTracker(fhicl::ParameterSet const &pset)