LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
PrimaryVertexFinder_module.cc
Go to the documentation of this file.
1 //
3 // PrimaryVertexFinder class
4 //
6 
7 // Framework includes
13 #include "art_root_io/TFileService.h"
17 #include "fhiclcpp/ParameterSet.h"
19 
20 #include <algorithm>
21 #include <iomanip>
22 #include <math.h>
23 #include <string>
24 #include <vector>
25 
26 #include "TH1F.h"
27 #include "TH2F.h"
28 #include "TVector3.h"
29 
37 
39 namespace vertex {
40 
42 
43  public:
44  explicit PrimaryVertexFinder(fhicl::ParameterSet const& pset);
45  void beginJob();
46 
47  void produce(art::Event& evt);
48 
49  private:
50  std::string fTrackModuleLabel;
51  double fVertexWindow;
53  bool IsInVertexCollection(int a, std::vector<std::vector<int>> vertex_collection);
54  int IndexInVertexCollection(int a, int b, std::vector<std::vector<int>> vertex_collection);
55  bool IsInNewVertex(int a, std::vector<int> newvertex);
56  double gammavalue(TVector3 startpoint1,
57  TVector3 startpoint2,
58  TVector3 dircos1,
59  TVector3 dircos2);
60  double alphavalue(double gamma,
61  TVector3 startpoint1,
62  TVector3 startpoint2,
63  TVector3 dircos1,
64  TVector3 dircos2);
65  double MinDist(double alpha,
66  double gamma,
67  TVector3 startpoint1,
68  TVector3 startpoint2,
69  TVector3 dircos1,
70  TVector3 dircos2);
71  TVector3 PointOnExtendedTrack(double alphagamma, TVector3 startpoint, TVector3 dircos);
72  TH2F* fNoTracks;
78  };
79 
80 }
81 
82 //------------------------------------------------------------------------------
83 bool sort_pred2(const std::pair<art::Ptr<recob::Track>, double>& left,
84  const std::pair<art::Ptr<recob::Track>, double>& right)
85 {
86  return left.second < right.second;
87 }
88 
89 namespace vertex {
90 
91  //-----------------------------------------------------------------------------
93  {
94  fTrackModuleLabel = pset.get<std::string>("TrackModuleLabel");
95  fVertexWindow = pset.get<double>("VertexWindow");
96 
97  produces<std::vector<recob::Vertex>>();
98  produces<art::Assns<recob::Vertex, recob::Hit>>();
99  produces<art::Assns<recob::Vertex, recob::Track>>();
100  produces<art::Assns<recob::Vertex, recob::Shower>>();
101  }
102 
103  //-------------------------------------------------------------------------
105  {
106  // get access to the TFile service
108 
109  // fNoVertices= tfs->make<TH2F>("fNoVertices", ";Event No; No of vertices", 100,0, 100, 30, 0, 30);
110  fNoTracks = tfs->make<TH2F>("fNoTracks", ";Event No; No of Tracks", 10, 0, 10, 10, 0, 10);
111  fLength_1stTrack = tfs->make<TH1F>("fLength_Track1", "Muon Track Length", 100, 0, 100);
112  fLength_2ndTrack = tfs->make<TH1F>("fLength_Track2", "2nd Track Length", 100, 0, 100);
113  fLength_3rdTrack = tfs->make<TH1F>("fLength_Track3", "3rd Track Length", 100, 0, 100);
114  fLength_4thTrack = tfs->make<TH1F>("fLength_Track4", "4th Track Length", 100, 0, 100);
115  fLength_5thTrack = tfs->make<TH1F>("fLength_Track5", "5th Track Length", 100, 0, 100);
116  }
117 
118  // //-----------------------------------------------------------------------------
120  {
121 
122  mf::LogInfo("PrimaryVertexFinder")
123  << "------------------------------------------------------------------------------";
124 
125  // std::cout << "run : " << evt.Header().Run() << std::endl;
126  // std::cout << "subrun : " << evt.Header().Subrun() << std::endl;
127  //std::cout << "event : " << evt.Header().Event() << std::endl;
128 
129  mf::LogInfo("PrimaryVertexFinder") << "event : " << evt.id().event();
130 
132 
133  //mf::LogInfo("PrimaryVertexFinder") << "I am in Primary vertex finder " << std::endl;
134 
135  art::Handle<std::vector<recob::Track>> trackListHandle;
136  evt.getByLabel(fTrackModuleLabel, trackListHandle);
137 
138  //Point to a collection of vertices to output.
139  std::unique_ptr<std::vector<recob::Vertex>> vcol(new std::vector<recob::Vertex>);
140  std::unique_ptr<art::Assns<recob::Vertex, recob::Hit>> vhassn(
142  std::unique_ptr<art::Assns<recob::Vertex, recob::Track>> vtassn(
144  std::unique_ptr<art::Assns<recob::Vertex, recob::Shower>> vsassn(
146 
147  std::vector<recob::Track> const& trkIn = *trackListHandle;
148 
149  mf::LogInfo("PrimaryVertexFinder") << "number of tracks in this event = " << trkIn.size();
150  fNoTracks->Fill(evt.id().event(), trkIn.size());
151 
152  std::vector<recob::SpacePoint> startpoints_vec; // first space point of each track
153 
154  std::vector<TVector3> startvec;
155  TVector3 startXYZ;
156 
157  std::vector<TVector3> endvec;
158  TVector3 endXYZ;
159 
160  std::vector<TVector3> dircosvec;
161  TVector3 dircosXYZ;
162 
163  std::vector<std::pair<art::Ptr<recob::Track>, double>> trackpair;
164 
165  art::FindMany<recob::SpacePoint> TrackSpacePoints(trackListHandle, evt, fTrackModuleLabel);
166 
167  for (unsigned int i = 0; i < trkIn.size(); ++i) {
168  recob::Track::Point_t start, end;
169  std::tie(start, end) = trkIn[i].Extent();
170  startXYZ.SetXYZ(start.X(), start.Y(), start.Z());
171  endXYZ.SetXYZ(end.X(), end.Y(), end.Z());
172 
173  double length = (endXYZ - startXYZ).Mag(); // (endvec[i]-startvec[i]).Mag();
174  //mf::LogInfo("PrimaryVertexFinder") << "Track length calculated = " << length << std::endl;
175  trackpair.push_back(std::pair<art::Ptr<recob::Track>, double>({trackListHandle, i}, length));
176  }
177 
178  for (size_t i = 0; i < trackpair.size(); ++i) {
179  mf::LogInfo("PrimaryVertexFinder") << "track id is = " << (trackpair[i].first)->ID()
180  << " track length = " << (trackpair[i].second);
181  }
182 
183  std::sort(trackpair.rbegin(), trackpair.rend(), sort_pred2);
184 
185  mf::LogInfo("PrimaryVertexFinder") << "AFTER SORTING ";
186  for (size_t i = 0; i < trackpair.size(); ++i) {
187  mf::LogInfo("PrimaryVertexFinder") << "track id is = " << (trackpair[i].first)->ID()
188  << " track length = " << (trackpair[i].second);
189  }
190 
191  if (trackpair.size() > 0) fLength_1stTrack->Fill(trackpair[0].second);
192 
193  if (trackpair.size() > 1) fLength_2ndTrack->Fill(trackpair[1].second);
194 
195  if (trackpair.size() > 2) fLength_3rdTrack->Fill(trackpair[2].second);
196 
197  if (trackpair.size() > 3) fLength_4thTrack->Fill(trackpair[3].second);
198 
199  if (trackpair.size() > 4) fLength_5thTrack->Fill(trackpair[4].second);
200 
201  for (size_t j = 0; j < trackpair.size(); ++j) { //loop over tracks
202  art::Ptr<recob::Track> const& track = trackpair[j].first;
203 
204  // the index of this track in the query is the same as its position in
205  // the data product:
206  std::vector<recob::SpacePoint const*> const& spacepoints = TrackSpacePoints.at(track.key());
207 
208  startXYZ = trackpair[j].first->Vertex<TVector3>();
209  endXYZ = trackpair[j].first->End<TVector3>();
210  dircosXYZ = trackpair[j].first->VertexDirection<TVector3>();
211 
212  startvec.push_back(startXYZ);
213  endvec.push_back(endXYZ);
214  dircosvec.push_back(dircosXYZ);
215 
216  mf::LogInfo("PrimaryVertexFinder") << "PrimaryVertexFinder got " << spacepoints.size()
217  << " 3D spacepoint(s) from Track3Dreco.cxx";
218 
219  // save the first SpacePoint of each Track... from now the SpacePoint ID represents the Track ID!!
220  startpoints_vec.emplace_back(spacepoints[0]->XYZ(),
221  spacepoints[0]->ErrXYZ(),
222  spacepoints[0]->Chisq(),
223  startpoints_vec.size());
224 
225  } // loop over tracks
226 
227  for (size_t i = 0; i < startvec.size(); ++i) { //trackpair.size()
228  mf::LogInfo("PrimaryVertexFinder") << "Tvector3 start point SORTED = ";
229  startvec[i].Print();
230  }
231  for (size_t i = 0; i < dircosvec.size(); ++i) { //trackpair.size()
232  mf::LogInfo("PrimaryVertexFinder") << "Tvector3 dir cos SORTED = ";
233  dircosvec[i].Print();
234  }
235 
236  std::vector<std::vector<int>> vertex_collection_int;
237  std::vector<std::vector<TVector3>> vertexcand_vec;
238 
239  for (unsigned int i = 0; i < trackpair.size(); ++i) {
240  for (unsigned int j = i + 1; j < trackpair.size(); ++j) {
241  mf::LogInfo("PrimaryVertexFinder")
242  << "distance between " << i << " and " << j << " = "
243  << StartPointSeperation(startpoints_vec[i], startpoints_vec[j]);
244  double GAMMA = gammavalue(startvec[i], startvec[j], dircosvec[i], dircosvec[j]);
245  double ALPHA = alphavalue(GAMMA, startvec[i], startvec[j], dircosvec[i], dircosvec[j]);
246  double MINDIST =
247  MinDist(ALPHA, GAMMA, startvec[i], startvec[j], dircosvec[i], dircosvec[j]);
248  mf::LogInfo("PrimaryVertexFinder")
249  << "alpha = " << ALPHA << " gamma = " << GAMMA << " MINIMUM DISTANCE = " << MINDIST;
250 
251  TVector3 TRACK1POINT = PointOnExtendedTrack(ALPHA, startvec[i], dircosvec[i]);
252  TVector3 TRACK2POINT = PointOnExtendedTrack(GAMMA, startvec[j], dircosvec[j]);
253 
254  mf::LogInfo("PrimaryVertexFinder") << "POINTS ON THE TRACKS ARE:: ";
255  TRACK1POINT.Print();
256  TRACK2POINT.Print();
257 
258  //if(StartPointSeperation(startpoints_vec[i], startpoints_vec[j])<fVertexWindow){ ///// correct this
259  //if(MINDIST<2 && trackpair[i].second >30 && trackpair[j].second >30){
260  if (MINDIST < fVertexWindow && ((TRACK1POINT - startvec[i]).Mag()) < fVertexWindow) {
261 
262  if ((!IsInVertexCollection(i, vertex_collection_int)) &&
263  (!IsInVertexCollection(j, vertex_collection_int))) {
264  std::vector<int> newvertex_int;
265  std::vector<TVector3> vertexcand;
266  newvertex_int.push_back(i);
267  newvertex_int.push_back(j);
268  vertex_collection_int.push_back(newvertex_int);
269  //newvertex.clear();
270  vertexcand.push_back(TRACK1POINT);
271  vertexcand.push_back(TRACK2POINT);
272  vertexcand_vec.push_back(vertexcand);
273  }
274  else {
275  int index = IndexInVertexCollection(i, j, vertex_collection_int);
276  //mf::LogInfo("PrimaryVertexFinder") << "index where a new vertex will be added = " << index << std::endl;
277  if (!IsInNewVertex(i, vertex_collection_int[index])) {
278  vertex_collection_int[index].push_back(i);
279  vertexcand_vec[index].push_back(TRACK1POINT); //need to fix for delta rays
280  }
281  if (!IsInNewVertex(j, vertex_collection_int[index])) {
282  vertex_collection_int[index].push_back(j);
283  vertexcand_vec[index].push_back(TRACK2POINT); //need to fix for delta rays
284  }
285  }
286  } // end else
287  }
288  }
289 
290  //now add the unmatched track IDs to the collection
291  for (size_t i = 0; i < trackpair.size(); ++i) {
292  if (!IsInVertexCollection(i, vertex_collection_int)) {
293  //if(trackpair[i].second>30){
294  std::vector<int> temp;
295  std::vector<TVector3> temp1;
296  temp.push_back(i);
297  temp1.push_back(startvec[i]);
298  vertex_collection_int.push_back(temp);
299  vertexcand_vec.push_back(temp1);
300  //}
301  }
302  }
303 
304  // indices (in their data products) of tracks and showers connected to the vertex
305  std::vector<size_t> vTrackIndices, vShowerIndices;
306 
307  // find the hits of all the tracks
308  art::FindManyP<recob::Hit> TrackHits(trackListHandle, evt, fTrackModuleLabel);
309 
310  // find the hits of all the showers
311  // art::FindManyP<recob::Hit> ShowerHits(showerListHandle, evt, fShowerModuleLabel);
313  art::FindManyP<recob::Hit> ShowerHits(
315 
316  for (size_t i = 0; i < vertex_collection_int.size(); ++i) {
317  double x = 0.;
318  double y = 0.;
319  double z = 0.;
320  int elemsize = 0.;
321  for (std::vector<int>::iterator itr = vertex_collection_int[i].begin();
322  itr < vertex_collection_int[i].end();
323  ++itr) {
324  mf::LogInfo("PrimaryVertexFinder")
325  << "vector elements at index " << i << " are " << *itr
326  << "\ntrack original ID = " << (trackpair[*itr].first)->ID();
327  // save the index in the data product of this track
328  vTrackIndices.push_back(trackpair[*itr].first.key());
329  }
330  mf::LogInfo("PrimaryVertexFinder") << "------------";
331 
332  for (std::vector<TVector3>::iterator itr = vertexcand_vec[i].begin();
333  itr < vertexcand_vec[i].end();
334  ++itr) {
335  //calculate sum of x, y and z of a vertex
336  x += (*itr).X();
337  y += (*itr).Y();
338  z += (*itr).Z();
339  elemsize = vertexcand_vec[i].size();
340  }
341 
342  double avgx = x / elemsize;
343  double avgy = y / elemsize;
344  double avgz = z / elemsize;
345 
346  Double_t vtxcoord[3];
347  vtxcoord[0] = avgx;
348  vtxcoord[1] = avgy;
349  vtxcoord[2] = avgz;
350 
351  recob::Vertex the3Dvertex(vtxcoord, vcol->size());
352  vcol->push_back(the3Dvertex);
353 
354  if (!vTrackIndices.empty()) {
355  // associate the tracks and their hits with the vertex
357  evt, *vtassn, vcol->size() - 1, vTrackIndices.begin(), vTrackIndices.end());
358  for (size_t tIndex : vTrackIndices) {
359  std::vector<art::Ptr<recob::Hit>> const& hits = TrackHits.at(tIndex);
360  util::CreateAssn(evt, *vcol, hits, *vhassn);
361  }
362  vTrackIndices.clear();
363  } // if tracks
364 
365  if (!vShowerIndices.empty()) {
366  // associate the showers and their hits with the vertex
368  evt, *vsassn, vcol->size() - 1, vShowerIndices.begin(), vShowerIndices.end());
369  for (size_t sIndex : vShowerIndices) {
370  std::vector<art::Ptr<recob::Hit>> const& hits = ShowerHits.at(sIndex);
371  util::CreateAssn(evt, *vcol, hits, *vhassn);
372  }
373  vShowerIndices.clear();
374  } // if showers
375 
376  } // end loop over vertex_collection_ind
377 
378  MF_LOG_VERBATIM("Summary") << std::setfill('-') << std::setw(175) << "-" << std::setfill(' ');
379  MF_LOG_VERBATIM("Summary") << "PrimaryVertexFinder Summary:";
380  for (size_t i = 0; i < vcol->size(); ++i)
381  MF_LOG_VERBATIM("Summary") << vcol->at(i);
382 
383  evt.put(std::move(vcol));
384  evt.put(std::move(vtassn));
385  evt.put(std::move(vhassn));
386  evt.put(std::move(vsassn));
387 
388  } // end of produce
389 } // end of vertex namespace
390 
391 // //-----------------------------------------------------------------------------
393  recob::SpacePoint sp2)
394 {
395  double x = (sp2.XYZ()[0]) - (sp1.XYZ()[0]);
396  double y = (sp2.XYZ()[1]) - (sp1.XYZ()[1]);
397  double z = (sp2.XYZ()[2]) - (sp1.XYZ()[2]);
398  double distance = std::sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2));
399  return distance;
400 }
401 // //---------------------------------------------------------------------------------
403  int a,
404  std::vector<std::vector<int>> vertex_collection)
405 {
406  int flag = 0;
407 
408  for (unsigned int i = 0; i < vertex_collection.size(); i++) {
409  for (std::vector<int>::iterator itr = vertex_collection[i].begin();
410  itr < vertex_collection[i].end();
411  ++itr) {
412  if (a == *itr) {
413  flag = 1;
414  break;
415  }
416  }
417  }
418  if (flag == 1) return true;
419  return false;
420 }
421 // //------------------------------------------------------------------------------
423  int a,
424  int b,
425  std::vector<std::vector<int>> vertex_collection)
426 {
427  int index = -1;
428  for (unsigned int i = 0; i < vertex_collection.size(); i++) {
429  for (std::vector<int>::iterator itr = vertex_collection[i].begin();
430  itr < vertex_collection[i].end();
431  ++itr) {
432  if (a == *itr || b == *itr) index = i;
433  }
434  }
435  return index;
436 }
437 // //------------------------------------------------------------------------------
438 bool vertex::PrimaryVertexFinder::IsInNewVertex(int a, std::vector<int> newvertex)
439 {
440  int flag = 0;
441  for (unsigned int i = 0; i < newvertex.size(); i++) {
442  if (a == newvertex[i]) {
443  flag = 1;
444  break;
445  }
446  }
447 
448  if (flag == 1) return true;
449  return false;
450 }
451 // //------------------------------------------------------------------------------
452 double vertex::PrimaryVertexFinder::gammavalue(TVector3 startpoint1,
453  TVector3 startpoint2,
454  TVector3 dircos1,
455  TVector3 dircos2)
456 {
457  double gamma = ((startpoint1 * dircos2) - (startpoint2 * dircos2) +
458  ((dircos1 * dircos2) * (startpoint2 * dircos1)) -
459  ((dircos1 * dircos2) * (startpoint1 * dircos1))) /
460  (1 - ((dircos1 * dircos2) * (dircos1 * dircos2)));
461 
462  return gamma;
463 }
464 // //------------------------------------------------------------------------------
466  TVector3 startpoint1,
467  TVector3 startpoint2,
468  TVector3 dircos1,
469  TVector3 dircos2)
470 {
471  double alpha = (gamma * (dircos1 * dircos2)) + (startpoint2 * dircos1) - (startpoint1 * dircos1);
472 
473  return alpha;
474 }
475 // //------------------------------------------------------------------------------
477  double gamma,
478  TVector3 startpoint1,
479  TVector3 startpoint2,
480  TVector3 dircos1,
481  TVector3 dircos2)
482 {
483  TVector3 mindis_vector = startpoint1 - startpoint2 + alpha * dircos1 - gamma * dircos2;
484  double mindis = mindis_vector.Mag();
485  return mindis;
486 }
487 // //------------------------------------------------------------------------------
489  TVector3 startpoint,
490  TVector3 dircos)
491 {
492  TVector3 PointOnExtendedTrack = startpoint + (alphagamma * dircos);
493  return PointOnExtendedTrack;
494 }
495 // //------------------------------------------------------------------------------
496 
497 namespace vertex {
498 
500 
501 } // end of vertex namespace
Float_t x
Definition: compare.C:6
intermediate_table::iterator iterator
PrimaryVertexFinder(fhicl::ParameterSet const &pset)
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:102
TVector3 PointOnExtendedTrack(double alphagamma, TVector3 startpoint, TVector3 dircos)
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
Declaration of signal hit object.
Float_t y
Definition: compare.C:6
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.cc:6
Double_t z
Definition: plot.C:276
Definition of vertex object for LArSoft.
Definition: Vertex.h:35
bool IsInNewVertex(int a, std::vector< int > newvertex)
PutHandle< PROD > put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: Event.h:77
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:289
void hits()
Definition: readHits.C:15
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
key_type key() const noexcept
Definition: Ptr.h:166
Provides recob::Track data product.
const Double32_t * XYZ() const
Definition: SpacePoint.h:78
double MinDist(double alpha, double gamma, TVector3 startpoint1, TVector3 startpoint2, TVector3 dircos1, TVector3 dircos2)
bool CreateAssn(art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t index=UINT_MAX)
Creates a single one-to-one association.
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:94
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
Utility object to perform functions of association.
double StartPointSeperation(recob::SpacePoint sp1, recob::SpacePoint sp2)
bool sort_pred2(const std::pair< art::Ptr< recob::Track >, double > &left, const std::pair< art::Ptr< recob::Track >, double > &right)
#define MF_LOG_VERBATIM(category)
tracking::Point_t Point_t
Definition: Track.h:52
EventNumber_t event() const
Definition: EventID.h:116
double gammavalue(TVector3 startpoint1, TVector3 startpoint2, TVector3 dircos1, TVector3 dircos2)
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
double alphavalue(double gamma, TVector3 startpoint1, TVector3 startpoint2, TVector3 dircos1, TVector3 dircos2)
TCEvent evt
Definition: DataStructs.cxx:8
bool IsInVertexCollection(int a, std::vector< std::vector< int >> vertex_collection)
Float_t track
Definition: plot.C:35
int IndexInVertexCollection(int a, int b, std::vector< std::vector< int >> vertex_collection)
EventID id() const
Definition: Event.cc:23
art framework interface to geometry description
vertex reconstruction