LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
ParticleDecayId_module.cc
Go to the documentation of this file.
1 // Class: ParticleDecayId
3 // Module Type: producer
4 // File: ParticleDecayId_module.cc
5 // Authors: dorota.stefan@cern.ch pplonski86@gmail.com robert.sulej@cern.ch
6 //
7 // THIS IS STIIL DEVELOPMENT NOW - CODE MAKING VERTICES MAY STILL CHANGE STRATEGY
8 //
10 
20 
31 #include "fhiclcpp/types/Atom.h"
32 #include "fhiclcpp/types/Comment.h"
33 #include "fhiclcpp/types/Name.h"
34 #include "fhiclcpp/types/Table.h"
36 
37 #include <TVector3.h>
38 
39 #include <iostream>
40 #include <map>
41 #include <memory>
42 #include <utility>
43 #include <vector>
44 
45 namespace nnet {
46 
48  public:
49  struct Config {
50  using Name = fhicl::Name;
52 
54 
56  Name("WireLabel"),
57  Comment("tag of deconvoluted ADC on wires (recob::Wire)")};
58 
60  Name("TrackModuleLabel"),
61  Comment("tag of tracks where decays points are to be found")};
62 
64  Name("RoiThreshold"),
65  Comment("search for decay points where the net output > ROI threshold")};
66 
68  Name("PointThreshold"),
69  Comment("tag decay point if it is detected in at least two planes with net outputs product "
70  "> POINT threshold")};
71 
73  Comment("use all views to find decays if -1, or skip the view with "
74  "provided index and use only the two other views")};
75  };
77  explicit ParticleDecayId(Parameters const& p);
78 
79  ParticleDecayId(ParticleDecayId const&) = delete;
80  ParticleDecayId(ParticleDecayId&&) = delete;
81  ParticleDecayId& operator=(ParticleDecayId const&) = delete;
83 
84  private:
85  void produce(art::Event& e) override;
86 
87  bool DetectDecay(detinfo::DetectorClocksData const& clockData,
88  detinfo::DetectorPropertiesData const& detProp,
89  const std::vector<recob::Wire>& wires,
91  std::map<size_t, TVector3>& spoints,
92  std::vector<std::pair<TVector3, double>>& result);
93 
95 
98 
100 
102  };
103  // ------------------------------------------------------
104 
106  : EDProducer{config}
107  , fPointIdAlg(config().PointIdAlg())
108  , fWireProducerLabel(config().WireLabel())
109  , fTrackModuleLabel(config().TrackModuleLabel())
110  , fRoiThreshold(config().RoiThreshold())
111  , fPointThreshold(config().PointThreshold())
112  , fSkipView(config().SkipView())
113  {
114  produces<std::vector<recob::Vertex>>();
115  produces<art::Assns<recob::Vertex, recob::Track>>();
116  }
117  // ------------------------------------------------------
118 
120  {
121  std::cout << std::endl << "event " << evt.id().event() << std::endl;
122 
123  auto vtxs = std::make_unique<std::vector<recob::Vertex>>();
124  auto vtx2trk = std::make_unique<art::Assns<recob::Vertex, recob::Track>>();
125 
126  auto wireHandle = evt.getValidHandle<std::vector<recob::Wire>>(fWireProducerLabel);
127  auto trkListHandle = evt.getValidHandle<std::vector<recob::Track>>(fTrackModuleLabel);
128  auto spListHandle = evt.getValidHandle<std::vector<recob::SpacePoint>>(fTrackModuleLabel);
129 
130  art::FindManyP<recob::Hit> hitsFromTracks(trkListHandle, evt, fTrackModuleLabel);
131  art::FindManyP<recob::SpacePoint> spFromTracks(trkListHandle, evt, fTrackModuleLabel);
132  art::FindManyP<recob::Hit> hitsFromSPoints(spListHandle, evt, fTrackModuleLabel);
133 
134  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
135  auto const detProp =
137 
138  std::vector<std::pair<TVector3, double>> decays;
139  for (size_t i = 0; i < hitsFromTracks.size(); ++i) {
140  auto hits = hitsFromTracks.at(i);
141  auto spoints = spFromTracks.at(i);
142  if (hits.empty()) continue;
143 
144  std::map<size_t, TVector3> trkSpacePoints;
145  for (const auto& p : spoints) {
146  auto sp_hits = hitsFromSPoints.at(p.key());
147  for (const auto& h : sp_hits) {
148  trkSpacePoints[h.key()] = TVector3(p->XYZ()[0], p->XYZ()[1], p->XYZ()[2]);
149  }
150  }
151 
152  DetectDecay(clockData, detProp, *wireHandle, hits, trkSpacePoints, decays);
153  }
154 
155  double xyz[3];
156  for (const auto& p3d : decays) {
157 
158  xyz[0] = p3d.first.X();
159  xyz[1] = p3d.first.Y();
160  xyz[2] = p3d.first.Z();
161  std::cout << " detected: [" << xyz[0] << ", " << xyz[1] << ", " << xyz[2]
162  << "] p:" << p3d.second << std::endl;
163 
164  size_t vidx = vtxs->size();
165  vtxs->push_back(recob::Vertex(xyz, vidx));
166 
167  // to do: assn to eg. appropriate track
168  // selected among set of connected tracks
169  //art::Ptr<recob::Track> tptr(trkListHandle, i);
170  //art::Ptr<recob::Vertex> vptr(vid, vidx, evt.productGetter(vid));
171  //vtx2trk->addSingle(vptr, tptr);
172  }
173 
174  evt.put(std::move(vtxs));
175  evt.put(std::move(vtx2trk));
176  }
177  // ------------------------------------------------------
178 
180  detinfo::DetectorPropertiesData const& detProp,
181  const std::vector<recob::Wire>& wires,
183  std::map<size_t, TVector3>& spoints,
184  std::vector<std::pair<TVector3, double>>& result)
185  {
186  const size_t nviews = 3;
187 
188  std::vector<art::Ptr<recob::Hit>> wire_drift[nviews];
189  for (size_t i = 0; i < hits.size(); ++i) // split hits between views
190  {
191  wire_drift[hits[i]->View()].push_back(hits[i]);
192  }
193 
194  std::vector<float> outputs[nviews];
195  for (size_t v = 0; v < nviews;
196  ++v) // calculate nn outputs for each view (hopefully not changing cryo/tpc many times)
197  {
198  outputs[v].resize(wire_drift[v].size(), 0);
199  for (size_t i = 0; i < wire_drift[v].size(); ++i) {
200  int tpc = wire_drift[v][i]->WireID().TPC;
201  int cryo = wire_drift[v][i]->WireID().Cryostat;
202 
203  fPointIdAlg.setWireDriftData(clockData, detProp, wires, v, tpc, cryo);
204 
205  outputs[v][i] = fPointIdAlg.predictIdVector(wire_drift[v][i]->WireID().Wire,
206  wire_drift[v][i]->PeakTime())[0]; // p(decay)
207  }
208  }
209 
210  std::vector<std::pair<size_t, float>> candidates2d[nviews];
211  std::vector<std::pair<TVector3, float>> candidates3d[nviews];
212  for (size_t v = 0; v < nviews; ++v) {
213  size_t idx = 0;
214  while (idx < outputs[v].size()) {
215  if (outputs[v][idx] > fRoiThreshold) {
216  size_t ci = idx;
217  float max = outputs[v][idx];
218  ++idx;
219 
220  while ((idx < outputs[v].size()) && (outputs[v][idx] > fRoiThreshold)) {
221  if (outputs[v][idx] > max) {
222  max = outputs[v][idx];
223  ci = idx;
224  }
225  ++idx;
226  }
227  candidates2d[v].emplace_back(ci, max);
228  candidates3d[v].emplace_back(spoints[wire_drift[v][ci].key()], max);
229  }
230  else
231  ++idx;
232  }
233  }
234 
235  double min_dist =
236  2.0; // [cm], threshold for today to distinguish between two different candidates,
237  // if belo threshold, then use 3D point corresponding to higher cnn output
238 
239  // need coincidence of high cnn out in two views, then look if there is another close candidate
240  // and again select by cnn output value, would like to have few strong candidates
241  bool found = false;
242  for (size_t v = 0; v < nviews - 1; ++v) {
243  for (size_t i = 0; i < candidates3d[v].size(); ++i) {
244  TVector3 c0(candidates3d[v][i].first);
245  float p0 = candidates3d[v][i].second;
246 
247  for (size_t u = v + 1; u < nviews; ++u) {
248  for (size_t j = 0; j < candidates3d[v].size(); ++j) {
249  TVector3 c1(candidates3d[v][j].first);
250  float p1 = candidates3d[v][j].second;
251 
252  if ((c0 - c1).Mag() < min_dist) {
253  TVector3 c(c0);
254  if (p1 > p0) { c = c1; }
255  double p = p0 * p1;
256 
257  if (p > fPointThreshold) {
258  double d, dmin = min_dist;
259  size_t kmin = 0;
260  for (size_t k = 0; k < result.size(); ++k) {
261  d = (result[k].first - c).Mag();
262  if (d < dmin) {
263  dmin = d;
264  kmin = k;
265  }
266  }
267  if (dmin < min_dist) {
268  if (result[kmin].second < p) // replace previously found point
269  {
270  result[kmin].first = c;
271  result[kmin].second = p;
272  found = true;
273  }
274  }
275  else // nothing close in the list, add new point
276  {
277  result.emplace_back(c, p);
278  found = true;
279  }
280  } // if (p > fPointThreshold)
281  } // coincidence: points from views u and v are close
282  } // loop over points in view u
283  } // loop over views u
284  } // loop over points in view v
285  } // loop over views v
286  return found;
287  }
288 
290 
291 }
Declaration of signal hit object.
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.cc:6
ParticleDecayId & operator=(ParticleDecayId const &)=delete
Definition of vertex object for LArSoft.
Definition: Vertex.h:35
void produce(art::Event &e) override
PutHandle< PROD > put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: Event.h:77
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:101
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:289
std::vector< float > predictIdVector(unsigned int wire, float drift) const
calculate multi-class probabilities for [wire, drift] point
Definition: PointIdAlg.cxx:239
fhicl::Atom< art::InputTag > WireLabel
void hits()
Definition: readHits.C:15
TCanvas * c1
Definition: plotHisto.C:7
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
Definition: EmTrack.h:40
Float_t d
Definition: plot.C:235
Provides recob::Track data product.
fhicl::Atom< art::InputTag > TrackModuleLabel
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
bool setWireDriftData(const detinfo::DetectorClocksData &clock_data, const detinfo::DetectorPropertiesData &det_prop, const std::vector< recob::Wire > &wires, unsigned int plane, unsigned int tpc, unsigned int cryo)
Utility object to perform functions of association.
Contains all timing reference information for the detector.
bool DetectDecay(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const std::vector< recob::Wire > &wires, const std::vector< art::Ptr< recob::Hit >> &hits, std::map< size_t, TVector3 > &spoints, std::vector< std::pair< TVector3, double >> &result)
EventNumber_t event() const
Definition: EventID.h:116
Declaration of basic channel signal object.
ParticleDecayId(Parameters const &p)
TCEvent evt
Definition: DataStructs.cxx:8
Float_t e
Definition: plot.C:35
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:82
EventID id() const
Definition: Event.cc:23