All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
V0Finder.cc
Go to the documentation of this file.
1 #include "V0Finder.h"
2 #include "marlin/Global.h"
3 #include "EVENT/LCCollection.h"
4 #include "EVENT/Track.h"
5 #include "IMPL/LCCollectionVec.h"
6 #include "IMPL/ReconstructedParticleImpl.h"
7 #include "IMPL/VertexImpl.h"
8 #include "UTIL/Operators.h"
9 #include <math.h>
10 
11 #include <DD4hep/Detector.h>
12 #include <DD4hep/DD4hepUnits.h>
13 #include <DDRec/Vector3D.h>
14 
15 
16 #include "HelixClass.h"
17 
18 using namespace lcio ;
19 using namespace marlin ;
20 
21 
23 
24 
25 V0Finder::V0Finder() : Processor("V0Finder") {
26 
27  _description = "V0 Finder Processor " ;
28 
29  registerInputCollection(LCIO::TRACK,
30  "TrackCollection",
31  "Name of input collection of reconstructed particles",
33  std::string("LDCTracks"));
34 
35  registerOutputCollection(LCIO::RECONSTRUCTEDPARTICLE,
36  "RecoParticleCollection",
37  "Name of output collection of reconstructed particles",
39  std::string("V0RecoParticles"));
40 
41  registerOutputCollection(LCIO::VERTEX,
42  "VertexCollection",
43  "Name of output collection of neutral vertices",
45  std::string("V0Vertices"));
46 
47 // std::vector<float> rVertCut;
48 // rVertCut.push_back(14.);
49 // rVertCut.push_back(60.);
50 // rVertCut.push_back(320.);
51 // rVertCut.push_back(1600.);
52 
53  registerProcessorParameter("CutOnRadius",
54  "Cuts on V0 radius",
55  _rVertCut,
56  float(5.0));
57 
58 // std::vector<float> dVertCut;
59 // dVertCut.push_back(0.2);
60 // dVertCut.push_back(1.0);
61 // dVertCut.push_back(1.5);
62 
63 
64  registerProcessorParameter("CutOnTrkDistance",
65  "Cut on two track distance",
66  _dVertCut,
67  float(1.5));
68 
69  registerProcessorParameter("MinimumTrackHitRatio",
70  "Minimum ratio of inner track hit radius to reconstructed vertex radius",
72  float(0.7));
73 
74  registerProcessorParameter("MassRangeGamma",
75  "Maximal deviation in mass for photon candidate",
77  float(0.01));
78 
79  registerProcessorParameter("MassRangeK0S",
80  "Maximal deviation in mass for K0S candidate",
82  float(0.01));
83 
84  registerProcessorParameter("MassRangeL0",
85  "Maximal deviation in mass for Lamda0 candidate",
87  float(0.008));
88 
89  registerProcessorParameter("RxyCutGamma",
90  "Minimum radius in xy plane for photon candidate",
92  float(10.0));
93 
94  registerProcessorParameter("RxyCutK0S",
95  "Minimum radius in xy plane for K0S candidate",
96  _rxyCutK0S,
97  float(30.0));
98 
99  registerProcessorParameter("RxyCutLambda",
100  "Minimum radius in xy plane for Lambda0 candidate",
102  float(50.0));
103 
104 
105 
106 }
107 
109 
110  MASSProton = 0.93827203;
111  MASSPion = 0.13957018;
112  MASSLambda0 = 1.115683;
113  MASSK0S = 0.497648;
114  MASSGamma = 0;
115 
116  dd4hep::Detector& theDet = dd4hep::Detector::getInstance();
117  double bfieldV[3] ;
118  theDet.field().magneticField( { 0., 0., 0. } , bfieldV ) ;
119  _bField = bfieldV[2]/dd4hep::tesla ;
120 
121  _nRun = -1;
122  _nEvt = 0;
123 
124 }
125 
126 
127 void V0Finder::processRunHeader( LCRunHeader* ) {
128 
129  _nRun++ ;
130  _nEvt = 0;
131 
132 }
133 
134 void V0Finder::processEvent( LCEvent * evt ) {
135 
136 
137  try {
138 
139  LCCollection * col = evt->getCollection( _trackColName.c_str() );
140 
141  int nelem = col->getNumberOfElements();
142 
143  TrackPairVec trkPairs;
144  trkPairs.clear();
145 
146  std::map<Track*,int> trackUsed;
147 
148  for (int i=0;i<nelem;++i) {
149  Track * trk = dynamic_cast<Track*>(col->getElementAt(i));
150  trackUsed[trk] = 0;
151  }
152 
153  for (int i=0;i<nelem-1;++i) {
154  Track * firstTrack = dynamic_cast<Track*>(col->getElementAt(i));
155  float d01 = firstTrack->getD0();
156  float z01 = firstTrack->getZ0();
157  float phi1 = firstTrack->getPhi();
158  float tanLambda1 = firstTrack->getTanLambda();
159  float omega1 = firstTrack->getOmega();
160  HelixClass firstHelix;
161  firstHelix.Initialize_Canonical(phi1,d01,z01,omega1,tanLambda1,_bField);
162  float charge1 = firstHelix.getCharge();
163 
164  float r1 = firstTrack->getRadiusOfInnermostHit();
165 
166  for (int j=i+1;j<nelem;++j) {
167  Track * secondTrack = dynamic_cast<Track*>(col->getElementAt(j));
168  float r2 = secondTrack->getRadiusOfInnermostHit();
169 
170  float d02 = secondTrack->getD0();
171  float z02 = secondTrack->getZ0();
172  float phi2 = secondTrack->getPhi();
173  float tanLambda2 = secondTrack->getTanLambda();
174  float omega2 = secondTrack->getOmega();
175  HelixClass secondHelix;
176  secondHelix.Initialize_Canonical(phi2,d02,z02,omega2,tanLambda2,_bField);
177  float charge2 = secondHelix.getCharge();
178  float prodCharge = charge1*charge2;
179  if (prodCharge<0) { // two tracks with opposite charges
180 
181  float px1 = firstHelix.getMomentum()[0];
182  float py1 = firstHelix.getMomentum()[1];
183  float pz1 = firstHelix.getMomentum()[2];
184  float pp1 = sqrt(px1*px1+py1*py1+pz1*pz1);
185 
186  float px2 = secondHelix.getMomentum()[0];
187  float py2 = secondHelix.getMomentum()[1];
188  float pz2 = secondHelix.getMomentum()[2];
189  float pp2 = sqrt(px2*px2+py2*py2+pz2*pz2);
190 
191  float distV0;
192  float momentum[3];
193  float vertex[3];
194 
195  if (pp1>pp2) {
196  distV0 = firstHelix.getDistanceToHelix(&secondHelix, vertex, momentum);
197  }
198  else {
199  distV0 = secondHelix.getDistanceToHelix(&firstHelix, vertex, momentum);
200  }
201 
202  float radV0 = sqrt(vertex[0]*vertex[0]+vertex[1]*vertex[1]);
203 
204 
205  // check to ensure there are no hits on tracks at radii significantly smaller than reconstructed vertex
206  // TO DO: should be done more precisely using helices
207  if(r1/radV0<_minTrackHitRatio)continue;
208  if(r2/radV0<_minTrackHitRatio)continue;
209 
210 
211  // if (distV0 < _dVertCut && radV0 > _rVertCut ) { // cut on vertex radius and track misdistance
212  if (radV0 > _rVertCut ) {
213 
214  streamlog_out( DEBUG4 ) << " ***************** found vertex for tracks : " << dd4hep::rec::Vector3D( (const float*) vertex )
215  << " t1 " << lcshort( firstTrack ) << "\n"
216  << " t2 " << lcshort( secondTrack )
217  << " distV0 " << distV0
218  << std::endl ;
219 
220  if( distV0 < _dVertCut ) { // cut on vertex radius and track misdistance
221 
222 
223  streamlog_out( DEBUG ) << " ***** testing various hypotheses " << std::endl ;
224 
225  // Testing K0 hypothesis
226  float energy1 = sqrt(pp1*pp1+MASSPion*MASSPion);
227  float energy2 = sqrt(pp2*pp2+MASSPion*MASSPion);
228  float energyV0 = energy1 + energy2;
229  float massK0 = sqrt(energyV0*energyV0-momentum[0]*momentum[0]-momentum[1]*momentum[1]-momentum[2]*momentum[2]);
230 
231  // Testing L0 hypothesis
232  if (charge1<0) {
233  energy1 = sqrt(pp1*pp1+MASSPion*MASSPion);
234  energy2 = sqrt(pp2*pp2+MASSProton*MASSProton);
235  }
236  else {
237  energy1 = sqrt(pp1*pp1+MASSProton*MASSProton);
238  energy2 = sqrt(pp2*pp2+MASSPion*MASSPion);
239  }
240  energyV0 = energy1 + energy2;
241  float massL0 = sqrt(energyV0*energyV0-momentum[0]*momentum[0]-momentum[1]*momentum[1]-momentum[2]*momentum[2]);
242 
243  // Testing L0bar hypothesis
244  if (charge1>0) {
245  energy1 = sqrt(pp1*pp1+MASSPion*MASSPion);
246  energy2 = sqrt(pp2*pp2+MASSProton*MASSProton);
247  }
248  else {
249  energy1 = sqrt(pp1*pp1+MASSProton*MASSProton);
250  energy2 = sqrt(pp2*pp2+MASSPion*MASSPion);
251  }
252  energyV0 = energy1 + energy2;
253  float massL0bar = sqrt(energyV0*energyV0-momentum[0]*momentum[0]-momentum[1]*momentum[1]-momentum[2]*momentum[2]);
254 
255 
256 
257  // Testing photon hypothesis
258  energyV0 = pp1 + pp2;
259  float massGamma = sqrt(energyV0*energyV0-momentum[0]*momentum[0]-momentum[1]*momentum[1]-momentum[2]*momentum[2]);
260 
261  float deltaK0 = fabs(massK0 - MASSK0S);
262  float deltaL0 = fabs(massL0 - MASSLambda0);
263  float deltaGm = fabs(massGamma - MASSGamma);
264  float deltaL0bar = fabs(massL0bar - MASSLambda0);
265  if(radV0<_rxyCutGamma )deltaGm = 100000.;
266  if(radV0<_rxyCutK0S )deltaK0 = 100000.;
267  if(radV0<_rxyCutLambda)deltaL0 = 100000.;
268  if(radV0<_rxyCutLambda)deltaL0bar = 100000.;
269 
270  int code = 22;
271  bool massCondition = false;
272 
273  if (deltaGm<deltaL0&&deltaGm<deltaK0&&deltaGm<deltaL0bar) {
274  code = 22;
275  massCondition = deltaGm < _deltaMassGamma;
276  }
277  else if (deltaK0<deltaL0 && deltaK0<deltaL0bar) {
278  code = 310;
279  massCondition = deltaK0 < _deltaMassK0S;
280  }
281  else{
282  if (deltaL0<deltaL0bar ) {
283  code = 3122;
284  massCondition = deltaL0 < _deltaMassL0;
285  }else{
286  code = -3122;
287  massCondition = deltaL0bar < _deltaMassL0;
288  }
289  }
290 
291  streamlog_out( DEBUG ) << " ***** mass condition : " << massCondition
292  << " code : " << code << std::endl ;
293 
294  if (massCondition) {
295  bool ok = true;
296  if(r1/radV0<_minTrackHitRatio|| r2/radV0<_minTrackHitRatio){
297  r1 = this->Rmin(firstTrack);
298  r2 = this->Rmin(secondTrack);
299  if(r1/radV0<_minTrackHitRatio || r2/radV0<_minTrackHitRatio)ok = false;
300  //std::cout << " V0X: " << ok << " r = " << radV0 << " r1 = " << r1 << " r2 = " << r2 << std::endl;
301  }
302  if(!ok)continue;
303  TrackPair * trkPair = new TrackPair();
304  trkPair->setFirstTrack( firstTrack );
305  trkPair->setSecondTrack( secondTrack );
306  trkPair->setDistance( distV0 );
307  trkPair->setVertex( vertex );
308  trkPair->setMomentum( momentum );
309  trkPair->setCode( code );
310  trkPairs.push_back( trkPair );
311 
312  }
313  else {
314 // std::cout << "Rejected vertex : V = ("
315 // << vertex[0] << ","
316 // << vertex[1] << ","
317 // << vertex[2] << ")" << std::endl;
318  }
319 
320 // std::cout << "Code = " << code << std::endl;
321 // std::cout << "Vertex = " << vertex[0] << " " << vertex[1] << " " << vertex[2] << std::endl;
322 // std::cout << "Momentum = " << momentum[0] << " " << momentum[1] << " " << momentum[2] << std::endl;
323 
324 
325  }
326  }
327  }
328  }
329 
330  }//DEBUG ------
331 
332 // std::cout << std::endl;
333 
334  // Sorting of all vertices in ascending order of the track misdistance
335 
336  int nTrkPairs = int(trkPairs.size());
337 
338  if (nTrkPairs>0) { // V0s are present in event
339 
340  // std::cout << "Number of track pairs = " << nTrkPairs << std::endl;
341 
342  Sorting( trkPairs );
343 
344  // Declaration of the output collections
345  LCCollectionVec * colRecoPart = new LCCollectionVec(LCIO::RECONSTRUCTEDPARTICLE);
346  LCCollectionVec * colVertex = new LCCollectionVec(LCIO::VERTEX);
347 
348  for (int iTrkP=0;iTrkP<nTrkPairs;++iTrkP) {
349  TrackPair * pair = trkPairs[iTrkP];
350  Track * firstTrack = pair->getFirstTrack();
351  Track * secondTrack = pair->getSecondTrack();
352  if (trackUsed[firstTrack]==0&&trackUsed[secondTrack]==0) {
353 
354  ReconstructedParticleImpl * part = new ReconstructedParticleImpl();
355  VertexImpl * vtx = new VertexImpl();
356 
357  float vertex[3];
358  float momentum[3];
359  int code = pair->getCode();
360  for (int iC=0;iC<3;++iC) {
361  vertex[iC] = pair->getVertex()[iC];
362  momentum[iC] = pair->getMomentum()[iC];
363  }
364 
365  float distance = pair->getDistance();
366  vtx->setPosition( vertex );
367  vtx->addParameter( distance );
368 
369  part->setMomentum( momentum );
370  part->setType( code );
371 
372 // std::cout << "Code = " << code << " Distance = " << distance << std::endl;
373 // std::cout << "Vertex = ("
374 // << vertex[0] << ","
375 // << vertex[1] << ","
376 // << vertex[2] << ")" << std::endl;
377 
378 // std::cout << "Momentum = ("
379 // << momentum[0] << ","
380 // << momentum[1] << ","
381 // << momentum[2] << ")" << std::endl;
382 // std::cout << firstTrack << " " << secondTrack << std::endl;
383 
384 
385  float mass = 0;
386  if ( code == 22)
387  mass = 0;
388  else if ( code == 310 )
389  mass = MASSK0S;
390  else
391  mass = MASSLambda0;
392 
393  part->setMass( mass );
394  vtx->setAssociatedParticle( part );
395  part->setStartVertex( vtx );
396  part->addTrack( firstTrack );
397  part->addTrack( secondTrack );
398 
399  colRecoPart->addElement( part );
400  colVertex->addElement( vtx );
401 
402  trackUsed[firstTrack] = 1;
403  trackUsed[secondTrack] = 1;
404  }
405  }
406 
407  evt->addCollection( colRecoPart,_recoPartColName.c_str() );
408  evt->addCollection( colVertex, _vertexColName.c_str() );
409 
410  }
411 
412  // Clean up memory
413  for (int iTrkP=0;iTrkP<nTrkPairs;++iTrkP) {
414  TrackPair * trkPair = trkPairs[iTrkP];
415  delete trkPair;
416  }
417  trkPairs.clear();
418 
419  // getchar();
420 
421  }
422  catch(DataNotAvailableException &e) {}
423 
424 
425 
426  _nEvt++;
427 
428 }
429 
430 
431 void V0Finder::check( LCEvent * ) { }
432 
433 void V0Finder::end(){ }
434 
435 void V0Finder::Sorting( TrackPairVec & trkPairVec ) {
436 
437  int sizeOfVector = int(trkPairVec.size());
438  TrackPair *one,*two,*Temp;
439 
440  for (int i = 0 ; i < sizeOfVector-1; i++)
441  for (int j = 0; j < sizeOfVector-i-1; j++)
442  {
443  one = trkPairVec[j];
444  two = trkPairVec[j+1];
445  if( one->getDistance() > two->getDistance() )
446  {
447  Temp = trkPairVec[j];
448  trkPairVec[j] = trkPairVec[j+1];
449  trkPairVec[j+1] = Temp;
450  }
451  }
452 
453 }
454 
455 float V0Finder::Rmin( Track* track ) {
456 
457  // find track extrema
458 
459  float rmin = 1000000.;
460  TrackerHitVec hitvec = track->getTrackerHits();
461  int nhits = (int)hitvec.size();
462  float zmax =-99999.;
463  float zmin =99999.;
464  for(int ih =0;ih<nhits;++ih){
465  float z = (float)hitvec[ih]->getPosition()[2];
466  if(z<zmin)zmin=z;
467  if(z>zmax)zmax=z;
468  }
469  float tanLambda = track->getTanLambda();
470  // std::cout << " V0 Check : " << tanLambda << " z = " << zmin << " - " << zmax << std::endl;
471  float zzz = zmin;
472  if(tanLambda<0)zzz=zmax;
473 
474  float zstart = 0;
475  if(fabs(zmin)<fabs(zmax))zstart = zmin;
476  if(fabs(zmax)<fabs(zmin))zstart = zmax;
477  //std::cout << " V0 Check " << zstart << " - " << zzz << std::endl;
478  for(int ih =0;ih<nhits;++ih){
479  float z = (float)hitvec[ih]->getPosition()[2];
480  if(fabs(z-zstart)<250){
481  float x = (float)hitvec[ih]->getPosition()[0];
482  float y = (float)hitvec[ih]->getPosition()[1];
483  float r2 = x*x+y*y;
484  float r = sqrt(r2);
485  if(r<rmin)rmin = r;
486  }
487 
488  }
489 
490  return rmin;
491 
492 }
float Rmin(Track *track)
Definition: V0Finder.cc:455
int _nEvt
Definition: V0Finder.h:84
virtual void processEvent(LCEvent *evt)
Definition: V0Finder.cc:134
void Sorting(TrackPairVec &trkPairVec)
Definition: V0Finder.cc:435
CLHEP::Hep3Vector Vector3D
int _nRun
Definition: V0Finder.h:83
std::string _recoPartColName
Definition: V0Finder.h:88
float MASSLambda0
Definition: V0Finder.h:97
float _bField
Definition: V0Finder.h:93
float _rxyCutGamma
Definition: V0Finder.h:105
float _rxyCutK0S
Definition: V0Finder.h:106
float MASSProton
Definition: V0Finder.h:95
V0Finder()
Definition: V0Finder.cc:25
float _rxyCutLambda
Definition: V0Finder.h:107
virtual void processRunHeader(LCRunHeader *run)
Definition: V0Finder.cc:127
V0Finder aV0Finder
Definition: V0Finder.cc:22
float _deltaMassGamma
Definition: V0Finder.h:103
float _dVertCut
Definition: V0Finder.h:91
virtual void init()
Definition: V0Finder.cc:108
float MASSGamma
Definition: V0Finder.h:99
static const float e
std::string _trackColName
Definition: V0Finder.h:86
virtual void check(LCEvent *evt)
Definition: V0Finder.cc:431
float _deltaMassL0
Definition: V0Finder.h:102
float _rVertCut
Definition: V0Finder.h:90
std::string _vertexColName
Definition: V0Finder.h:87
std::vector< LCCollection * > LCCollectionVec
Definition: SiStripClus.h:55
virtual void end()
Definition: V0Finder.cc:433
float MASSK0S
Definition: V0Finder.h:98
float _minTrackHitRatio
Definition: V0Finder.h:109
float _deltaMassK0S
Definition: V0Finder.h:101
float MASSPion
Definition: V0Finder.h:96