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