ParticleDecayId_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 // 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 //
9 /////////////////////////////////////////////////////////////////////////////////
10 
17 #include "fhiclcpp/types/Atom.h"
18 #include "fhiclcpp/types/Table.h"
20 
28 
30 
31 #include <TVector3.h>
32 #include <memory>
33 
34 namespace nnet {
35 
37  public:
38  struct Config {
39  using Name = fhicl::Name;
41 
43 
45  Name("WireLabel"),
46  Comment("tag of deconvoluted ADC on wires (recob::Wire)")};
47 
49  Name("TrackModuleLabel"),
50  Comment("tag of tracks where decays points are to be found")};
51 
53  Name("RoiThreshold"),
54  Comment("search for decay points where the net output > ROI threshold")};
55 
57  Name("PointThreshold"),
58  Comment("tag decay point if it is detected in at least two planes with net outputs product "
59  "> POINT threshold")};
60 
62  Comment("use all views to find decays if -1, or skip the view with "
63  "provided index and use only the two other views")};
64  };
66  explicit ParticleDecayId(Parameters const& p);
67 
68  ParticleDecayId(ParticleDecayId const&) = delete;
69  ParticleDecayId(ParticleDecayId&&) = delete;
70  ParticleDecayId& operator=(ParticleDecayId const&) = delete;
72 
73  private:
74  void produce(art::Event& e) override;
75 
76  bool DetectDecay(detinfo::DetectorClocksData const& clockData,
77  detinfo::DetectorPropertiesData const& detProp,
78  const std::vector<recob::Wire>& wires,
79  const std::vector<art::Ptr<recob::Hit>>& hits,
80  std::map<size_t, TVector3>& spoints,
81  std::vector<std::pair<TVector3, double>>& result);
82 
84 
87 
89 
90  int fSkipView;
91  };
92  // ------------------------------------------------------
93 
95  : EDProducer{config}
97  , fWireProducerLabel(config().WireLabel())
98  , fTrackModuleLabel(config().TrackModuleLabel())
99  , fRoiThreshold(config().RoiThreshold())
100  , fPointThreshold(config().PointThreshold())
101  , fSkipView(config().SkipView())
102  {
103  produces<std::vector<recob::Vertex>>();
104  produces<art::Assns<recob::Vertex, recob::Track>>();
105  }
106  // ------------------------------------------------------
107 
108  void
110  {
111  std::cout << std::endl << "event " << evt.id().event() << std::endl;
112 
113  auto vtxs = std::make_unique<std::vector<recob::Vertex>>();
114  auto vtx2trk = std::make_unique<art::Assns<recob::Vertex, recob::Track>>();
115 
116  auto wireHandle = evt.getValidHandle<std::vector<recob::Wire>>(fWireProducerLabel);
117  auto trkListHandle = evt.getValidHandle<std::vector<recob::Track>>(fTrackModuleLabel);
118  auto spListHandle = evt.getValidHandle<std::vector<recob::SpacePoint>>(fTrackModuleLabel);
119 
120  art::FindManyP<recob::Hit> hitsFromTracks(trkListHandle, evt, fTrackModuleLabel);
121  art::FindManyP<recob::SpacePoint> spFromTracks(trkListHandle, evt, fTrackModuleLabel);
122  art::FindManyP<recob::Hit> hitsFromSPoints(spListHandle, evt, fTrackModuleLabel);
123 
124  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
125  auto const detProp =
127 
128  std::vector<std::pair<TVector3, double>> decays;
129  for (size_t i = 0; i < hitsFromTracks.size(); ++i) {
130  auto hits = hitsFromTracks.at(i);
131  auto spoints = spFromTracks.at(i);
132  if (hits.empty()) continue;
133 
134  std::map<size_t, TVector3> trkSpacePoints;
135  for (const auto& p : spoints) {
136  auto sp_hits = hitsFromSPoints.at(p.key());
137  for (const auto& h : sp_hits) {
138  trkSpacePoints[h.key()] = TVector3(p->XYZ()[0], p->XYZ()[1], p->XYZ()[2]);
139  }
140  }
141 
142  DetectDecay(clockData, detProp, *wireHandle, hits, trkSpacePoints, decays);
143  }
144 
145  double xyz[3];
146  for (const auto& p3d : decays) {
147 
148  xyz[0] = p3d.first.X();
149  xyz[1] = p3d.first.Y();
150  xyz[2] = p3d.first.Z();
151  std::cout << " detected: [" << xyz[0] << ", " << xyz[1] << ", " << xyz[2]
152  << "] p:" << p3d.second << std::endl;
153 
154  size_t vidx = vtxs->size();
155  vtxs->push_back(recob::Vertex(xyz, vidx));
156 
157  // to do: assn to eg. appropriate track
158  // selected among set of connected tracks
159  //art::Ptr<recob::Track> tptr(trkListHandle, i);
160  //art::Ptr<recob::Vertex> vptr(vid, vidx, evt.productGetter(vid));
161  //vtx2trk->addSingle(vptr, tptr);
162  }
163 
164  evt.put(std::move(vtxs));
165  evt.put(std::move(vtx2trk));
166  }
167  // ------------------------------------------------------
168 
169  bool
171  detinfo::DetectorPropertiesData const& detProp,
172  const std::vector<recob::Wire>& wires,
173  const std::vector<art::Ptr<recob::Hit>>& hits,
174  std::map<size_t, TVector3>& spoints,
175  std::vector<std::pair<TVector3, double>>& result)
176  {
177  const size_t nviews = 3;
178 
179  std::vector<art::Ptr<recob::Hit>> wire_drift[nviews];
180  for (size_t i = 0; i < hits.size(); ++i) // split hits between views
181  {
182  wire_drift[hits[i]->View()].push_back(hits[i]);
183  }
184 
185  std::vector<float> outputs[nviews];
186  for (size_t v = 0; v < nviews;
187  ++v) // calculate nn outputs for each view (hopefully not changing cryo/tpc many times)
188  {
189  outputs[v].resize(wire_drift[v].size(), 0);
190  for (size_t i = 0; i < wire_drift[v].size(); ++i) {
191  int tpc = wire_drift[v][i]->WireID().TPC;
192  int cryo = wire_drift[v][i]->WireID().Cryostat;
193 
194  fPointIdAlg.setWireDriftData(clockData, detProp, wires, v, tpc, cryo);
195 
196  outputs[v][i] = fPointIdAlg.predictIdVector(wire_drift[v][i]->WireID().Wire,
197  wire_drift[v][i]->PeakTime())[0]; // p(decay)
198  }
199  }
200 
201  std::vector<std::pair<size_t, float>> candidates2d[nviews];
202  std::vector<std::pair<TVector3, float>> candidates3d[nviews];
203  for (size_t v = 0; v < nviews; ++v) {
204  size_t idx = 0;
205  while (idx < outputs[v].size()) {
206  if (outputs[v][idx] > fRoiThreshold) {
207  size_t ci = idx;
208  float max = outputs[v][idx];
209  ++idx;
210 
211  while ((idx < outputs[v].size()) && (outputs[v][idx] > fRoiThreshold)) {
212  if (outputs[v][idx] > max) {
213  max = outputs[v][idx];
214  ci = idx;
215  }
216  ++idx;
217  }
218  candidates2d[v].emplace_back(ci, max);
219  candidates3d[v].emplace_back(spoints[wire_drift[v][ci].key()], max);
220  }
221  else
222  ++idx;
223  }
224  }
225 
226  double min_dist =
227  2.0; // [cm], threshold for today to distinguish between two different candidates,
228  // if belo threshold, then use 3D point corresponding to higher cnn output
229 
230  // need coincidence of high cnn out in two views, then look if there is another close candidate
231  // and again select by cnn output value, would like to have few strong candidates
232  bool found = false;
233  for (size_t v = 0; v < nviews - 1; ++v) {
234  for (size_t i = 0; i < candidates3d[v].size(); ++i) {
235  TVector3 c0(candidates3d[v][i].first);
236  float p0 = candidates3d[v][i].second;
237 
238  for (size_t u = v + 1; u < nviews; ++u) {
239  for (size_t j = 0; j < candidates3d[v].size(); ++j) {
240  TVector3 c1(candidates3d[v][j].first);
241  float p1 = candidates3d[v][j].second;
242 
243  if ((c0 - c1).Mag() < min_dist) {
244  TVector3 c(c0);
245  if (p1 > p0) { c = c1; }
246  double p = p0 * p1;
247 
248  if (p > fPointThreshold) {
249  double d, dmin = min_dist;
250  size_t kmin = 0;
251  for (size_t k = 0; k < result.size(); ++k) {
252  d = (result[k].first - c).Mag();
253  if (d < dmin) {
254  dmin = d;
255  kmin = k;
256  }
257  }
258  if (dmin < min_dist) {
259  if (result[kmin].second < p) // replace previously found point
260  {
261  result[kmin].first = c;
262  result[kmin].second = p;
263  found = true;
264  }
265  }
266  else // nothing close in the list, add new point
267  {
268  result.emplace_back(c, p);
269  found = true;
270  }
271  } // if (p > fPointThreshold)
272  } // coincidence: points from views u and v are close
273  } // loop over points in view u
274  } // loop over views u
275  } // loop over points in view v
276  } // loop over views v
277  return found;
278  }
279 
281 
282 }
static QCString result
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.h:20
struct vector vector
ChannelGroupService::Name Name
ParticleDecayId & operator=(ParticleDecayId const &)=delete
uint size() const
Definition: qcstring.h:201
Definition of vertex object for LArSoft.
Definition: Vertex.h:35
void produce(art::Event &e) override
art framework interface to geometry description
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
std::vector< float > predictIdVector(unsigned int wire, float drift) const
calculate multi-class probabilities for [wire, drift] point
Definition: PointIdAlg.cxx:221
fhicl::Atom< art::InputTag > WireLabel
const double e
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
def key(type, name=None)
Definition: graph.py:13
static Config * config
Definition: config.cpp:1054
def move(depos, offset)
Definition: depos.py:107
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
Definition: DataViewImpl.h:441
p
Definition: test.py:223
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: DataViewImpl.h:686
fhicl::Atom< art::InputTag > TrackModuleLabel
static int max(int a, int b)
Declaration of signal hit object.
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)
#define Comment
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)
Provides recob::Track data product.
EventNumber_t event() const
Definition: EventID.h:116
ParticleDecayId(Parameters const &p)
TCEvent evt
Definition: DataStructs.cxx:7
second_as<> second
Type of time stored in seconds, in double precision.
Definition: spacetime.h:85
EventID id() const
Definition: Event.cc:34
QTextStream & endl(QTextStream &s)