Minor correction needed on HP
[u/mrichter/AliRoot.git] / RALICE / AliVertex.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 // $Id$
17
18 ///////////////////////////////////////////////////////////////////////////
19 // Class AliVertex
20 // Creation and investigation of an AliVertex.
21 // An AliVertex can be constructed by adding AliTracks and/or AliJets.
22 //
23 // Note : Also (secondary) vertices can be added to a vertex.
24 //
25 // To provide maximal flexibility to the user, two modes of vertex storage
26 // are provided by means of the memberfunction SetVertexCopy().
27 // The same holds for the storage of jets via SetJetCopy().
28 //
29 // a) SetVertexCopy(0) (which is the default).
30 //    Only the pointers of the 'added' vertices are stored.
31 //    This mode is typically used by making vertex studies based on a fixed list
32 //    of vertices which stays under user control or is contained for instance
33 //    in an AliEvent.  
34 //    In this way the AliVertex just represents a 'logical structure' for the
35 //    physics analysis which can be embedded in e.g. an AliEvent or AliVertex.
36 //    Modifications made to the original vertices also affect the AliVertex objects
37 //    which are stored. 
38 // b) SetVertexCopy(1).
39 //    Of every 'added' vertex a private copy will be made of which the pointer
40 //    will be stored.
41 //    In this way the AliVertex represents an entity on its own and modifications
42 //    made to the original vertices do not affect the AliVertex objects which are
43 //    stored. 
44 //    This mode will allow 'adding' many different AliVertex objects by
45 //    creating only one AliVertex instance in the main programme and using the
46 //    AliVertex::Reset() and AliVertex::AddTrack and parameter setting memberfunctions.
47 //
48 // Coding example to make 3 vertices v1, v2 and v3.
49 // ------------------------------------------------
50 // v1 contains the tracks 1,2,3 and 4
51 // v2 contains many different tracks
52 // v3 contains the jets 1 and 2
53 //
54 //        AliTrack t1,t2,t3,t4;
55 //         ...
56 //         ... // code to fill the track data
57 //         ...
58 //
59 //        AliJet j1,j2;
60 //         ...
61 //         ... // code to fill the jet data
62 //         ...
63 //
64 //        AliVertex v1;
65 //        v1.SetVertexCopy(1);
66 //
67 //        v1.AddTrack(t1);
68 //        v1.AddTrack(t2);
69 //        v1.AddTrack(t3);
70 //        v1.AddTrack(t4);
71 //
72 //        Float_t r1[3]={2.4,0.1,-8.5};
73 //        v1.SetPosition(r1,"car");
74 //
75 //        AliVertex v2;
76 //        v2.SetTrackCopy(1);
77 //
78 //        AliTrack* tx=new AliTrack();
79 //        for (Int_t i=0; i<10; i++)
80 //        {
81 //         ...
82 //         ... // code to fill the track data
83 //         ...
84 //         v2.AddTrack(tx);
85 //         tx->Reset(); 
86 //        }
87 //
88 //        Float_t r2[3]={1.6,-3.2,5.7};
89 //        v2.SetPosition(r2,"car");
90 //
91 //        AliVertex v3;
92 //
93 //        v3.AddJet(j1);
94 //        v3.AddJet(j2);
95 //
96 //        Float_t r3[3]={6.2,4.8,1.3};
97 //        v3.SetPosition(r3,"car");
98 //
99 //        v1.Info("sph");
100 //        v2.ListAll();
101 //        v3.List("cyl");
102 //
103 //        Float_t e1=v1.GetEnergy();
104 //        Ali3Vector p1=v1.Get3Momentum();
105 //        Float_t loc[3];
106 //        v1.GetPosition(loc,"sph");
107 //        AliPosition r=v2.GetPosition();
108 //        r.Info(); 
109 //        Int_t nt=v2.GetNtracks();
110 //        AliTrack* tv=v2.GetTrack(1); // Access track number 1 of Vertex v2
111 //
112 // Specify the vertices v2 and v3 as secondary vertices of v1
113 //
114 //        v1.AddVertex(v2);
115 //        v1.AddVertex(v3);
116 //
117 //        v1.List();
118 //
119 //        Int_t nv=v1.GetNvtx();
120 //        AliVertex* vx=v1.GetVertex(1); // Access 1st secondary vertex of v1
121 //        Float_t e=vx->GetEnergy();
122 //
123 //        Float_t M=v1.GetInvmass(); 
124 //
125 // Reconstruct Vertex v1 from scratch
126 //
127 //        v1.Reset();
128 //        v1.SetNvmax(25); // Increase initial no. of sec. vertices
129 //        v1.AddTrack(t3);
130 //        v1.AddTrack(t4);
131 //        v1.AddJet(j2);
132 //        Float_t pos[3]={7,9,4};
133 //        v1.SetPosition(pos,"car");
134 //
135 // Note : All quantities are in GeV, GeV/c or GeV/c**2
136 //
137 //--- Author: Nick van Eijndhoven 04-apr-1998 UU-SAP Utrecht
138 //- Modified: NvE $Date$ UU-SAP Utrecht
139 ///////////////////////////////////////////////////////////////////////////
140
141 #include "AliVertex.h"
142  
143 ClassImp(AliVertex) // Class implementation to enable ROOT I/O
144  
145 AliVertex::AliVertex()
146 {
147 // Default constructor.
148 // All variables initialised to 0.
149 // Initial maximum number of tracks is set to the default value.
150 // Initial maximum number of sec. vertices is set to the default value.
151  fNvmax=0;
152  fVertices=0;
153  fConnects=0;
154  fVertexCopy=0;
155  fNjmax=0;
156  fJets=0;
157  fJetCopy=0;
158  Reset();
159  SetNtinit();
160  SetNvmax();
161  SetNjmax();
162 }
163 ///////////////////////////////////////////////////////////////////////////
164 AliVertex::AliVertex(Int_t n)
165 {
166 // Create a vertex to hold initially a maximum of n tracks
167 // All variables initialised to 0
168  fNvmax=0;
169  fVertices=0;
170  fConnects=0;
171  fVertexCopy=0;
172  fNjmax=0;
173  fJets=0;
174  fJetCopy=0;
175  Reset();
176  if (n > 0)
177  {
178   SetNtinit(n);
179  }
180  else
181  {
182   cout << endl;
183   cout << " *AliVertex* Initial max. number of tracks entered : " << n << endl;
184   cout << " This is invalid. Default initial maximum will be used." << endl;
185   cout << endl;
186   SetNtinit();
187  }
188  SetNvmax();
189  SetNjmax();
190 }
191 ///////////////////////////////////////////////////////////////////////////
192 AliVertex::~AliVertex()
193 {
194 // Default destructor
195  if (fVertices)
196  {
197   if (fVertexCopy) fVertices->Delete();
198   delete fVertices;
199   fVertices=0;
200  }
201  if (fConnects)
202  {
203   fConnects->Delete();
204   delete fConnects;
205   fConnects=0;
206  }
207  if (fJets)
208  {
209   if (fJetCopy) fJets->Delete();
210   delete fJets;
211   fJets=0;
212  }
213 }
214 ///////////////////////////////////////////////////////////////////////////
215 void AliVertex::SetNvmax(Int_t n)
216 {
217 // Set the initial maximum number of (secondary) vertices
218  if (n > 0)
219  {
220   fNvmax=n;
221  }
222  else
223  {
224   fNvmax=1;
225  }
226  if (fVertices)
227  {
228   if (fVertexCopy) fVertices->Delete();
229   delete fVertices;
230   fVertices=0;
231  }
232 }
233 ///////////////////////////////////////////////////////////////////////////
234 void AliVertex::SetNjmax(Int_t n)
235 {
236 // Set the initial maximum number of jets
237  if (n > 0)
238  {
239   fNjmax=n;
240  }
241  else
242  {
243   fNjmax=1;
244  }
245  if (fJets)
246  {
247   if (fJetCopy) fJets->Delete();
248   delete fJets;
249   fJets=0;
250  }
251 }
252 ///////////////////////////////////////////////////////////////////////////
253 void AliVertex::Reset()
254 {
255 // Reset all variables to 0 and reset all stored vertex and jet lists.
256 // The max. number of tracks is set to the initial value again
257 // The max. number of vertices is set to the default value again
258 // The max. number of jets is set to the default value again
259
260  AliJet::Reset();
261
262  Double_t a[3]={0,0,0};
263  SetPosition(a,"sph");
264  SetPositionErrors(a,"car");
265
266  fNvtx=0;
267  if (fNvmax>0) SetNvmax(fNvmax);
268  if (fConnects)
269  {
270   fConnects->Delete();
271   delete fConnects;
272   fConnects=0;
273  }
274
275  fNjets=0;
276  if (fNjmax>0) SetNjmax(fNjmax);
277 }
278 ///////////////////////////////////////////////////////////////////////////
279 void AliVertex::ResetVertices()
280 {
281 // Reset the stored vertex list and delete all connecting tracks which
282 // were generated automatically via connect=1 in AddVertex().
283 // The max. number of vertices is set to the default value again.
284 // All physics quantities are updated according to the remaining structure
285 // of connected tracks.
286  AliTrack* t;
287  if (fConnects)
288  {
289   for (Int_t i=0; i<=fConnects->GetLast(); i++)
290   {
291    t=(AliTrack*)fConnects->At(i);
292    AliTrack* test=(AliTrack*)fTracks->Remove(t);
293    if (test) fNtrk--;
294   }
295   fTracks->Compress();
296  }
297
298  fQ=0;
299  Double_t a[4]={0,0,0,0};
300  Ali4Vector::SetVector(a,"sph");
301  for (Int_t i=0; i<fNtrk; i++)
302  {
303   t=GetTrack(i);
304   (*this)+=(Ali4Vector&)(*t);
305   fQ+=t->GetCharge();
306  }
307
308  fNvtx=0;
309  if (fNvmax>0) SetNvmax(fNvmax);
310  if (fConnects)
311  {
312   fConnects->Delete();
313   delete fConnects;
314   fConnects=0;
315  }
316 }
317 ///////////////////////////////////////////////////////////////////////////
318 void AliVertex::AddJet(AliJet& j,Int_t tracks)
319 {
320 // Add a jet (and its tracks) to the vertex
321 // In case the maximum number of jets has been reached,
322 // the array space will be extended automatically
323 //
324 // Note : By default the tracks of the jet are added to the current (primary)
325 //        vertex.
326 //        The automatic addition of the tracks of the jet can be suppressed
327 //        by specifying tracks=0. In this case only the AliJet object will
328 //        be stored according to the mode specified by SetJetCopy().
329 //        The latter will enable jet studies based on a fixed list of tracks
330 //        as contained e.g. in an AliVertex or AliEvent. 
331  if (!fJets) fJets=new TObjArray(fNjmax);
332  if (fNjets == fNjmax) // Check if maximum jet number is reached
333  {
334   fNjmax++;
335   fJets->Expand(fNjmax);
336  }
337
338  // Add the jet to the list 
339  fNjets++;
340  if (fJetCopy)
341  {
342   AliJet* jx=new AliJet(j);
343   fJets->Add(jx);
344  }
345  else
346  {
347   fJets->Add(&j);
348  }
349
350  // Add the tracks of the jet to this vertex
351  if (tracks)
352  {
353   AliTrack* tj;
354   for (Int_t i=1; i<=j.GetNtracks(); i++)
355   {
356    tj=j.GetTrack(i);
357    AddTrack(tj);
358   }
359  }
360 }
361 ///////////////////////////////////////////////////////////////////////////
362 void AliVertex::AddVertex(AliVertex& v,Int_t connect)
363 {
364 // Add a (secondary) vertex to the current vertex.
365 // In case the maximum number of (secondary) vertices has been reached,
366 // the array space will be extended automatically
367 //
368 // Note : By default the 4-momentum and charge of the current (primary) vertex
369 //        are updated by automatically creating the track connecting
370 //        both vertices. The track parameters are taken from the
371 //        4-momentum and charge of the secondary vertex.
372 //        The automatic creation of the connecting track and updating
373 //        of the (primary) vertex 4-momentum and charge can be suppressed
374 //        by specifying connect=0. In this case, however, the user
375 //        has to introduce the connecting track lateron by hand
376 //        explicitly in order to match the kinematics and charge.
377 //
378  if (!fVertices) fVertices=new TObjArray(fNvmax);
379  if (fNvtx == fNvmax) // Check if maximum vertex number is reached
380  {
381   fNvmax++;
382   fVertices->Expand(fNvmax);
383  }
384
385  // Add the linked (secondary) vertex to the list 
386  fNvtx++;
387  if (fVertexCopy)
388  {
389   AliVertex* vx=new AliVertex(v);
390   fVertices->Add(vx);
391  }
392  else
393  {
394   fVertices->Add(&v);
395  }
396
397  // Create connecting track and update 4-momentum and charge for current vertex
398  if (connect)
399  {
400   AliPosition r1=GetPosition();
401   AliPosition r2=v.GetPosition();
402   Float_t q=v.GetCharge();
403   Ali3Vector p=v.Get3Momentum();
404   Double_t v2=v.GetInvariant();
405   Double_t dv2=v.Ali4Vector::GetResultError();
406
407   AliTrack* t=new AliTrack;
408   t->SetBeginPoint(r1);
409   t->SetEndPoint(r2);
410   t->SetCharge(q);
411   t->Set3Momentum(p);
412   t->SetInvariant(v2,dv2);
413
414   AddTrack(t);
415
416   if (!fConnects) fConnects=new TObjArray(fNvmax);
417   fConnects->Add(t);
418  }
419 }
420 ///////////////////////////////////////////////////////////////////////////
421 void AliVertex::Info(TString f)
422 {
423 // Provide vertex information within the coordinate frame f
424  cout << " *AliVertex::Info* Invmass : " << GetInvmass()
425       << " Charge : " << GetCharge() << " Momentum : " << GetMomentum()
426       << " Ntracks : " << GetNtracks() << " Nvertices : " << fNvtx 
427       << " Njets : " << fNjets << endl;
428  cout << " ";
429  Ali4Vector::Info(f);
430  cout << "  Position";
431  AliPosition::Info(f); 
432
433 ///////////////////////////////////////////////////////////////////////////
434 void AliVertex::List(TString f)
435 {
436 // Provide primary track and sec. vertex information within the coordinate frame f
437
438  Info(f); // Information of the current vertex
439
440  // The tracks of this vertex
441  AliTrack* t; 
442  for (Int_t it=1; it<=GetNtracks(); it++)
443  {
444   t=GetTrack(it);
445   if (t)
446   {
447    cout << "  ---Track no. " << it << endl;
448    cout << " ";
449    t->Info(f); 
450   }
451   else
452   {
453    cout << " *AliVertex::List* Error : No track present." << endl; 
454   }
455  }
456
457  // The secondary vertices of this vertex
458  AliVertex* v; 
459  for (Int_t iv=1; iv<=GetNvertices(); iv++)
460  {
461   v=GetVertex(iv);
462   if (v)
463   {
464    cout << "  ---Level 1 sec. vertex no. " << iv << endl;
465    cout << " ";
466    v->Info(f); 
467   }
468   else
469   {
470    cout << " *AliVertex::List* Error : No sec. vertex present." << endl; 
471   }
472  }
473
474 ///////////////////////////////////////////////////////////////////////////
475 void AliVertex::ListAll(TString f)
476 {
477 // Provide complete (sec) vertex and (decay) track info within the coordinate frame f
478
479  Info(f); // Information of the current vertex
480
481  // The tracks of this vertex
482  AliTrack* t; 
483  for (Int_t it=1; it<=GetNtracks(); it++)
484  {
485   t=GetTrack(it);
486   if (t)
487   {
488    cout << "  ---Track no. " << it << endl;
489    cout << " ";
490    t->ListAll(f); 
491   }
492   else
493   {
494    cout << " *AliVertex::ListAll* Error : No track present." << endl; 
495   }
496  }
497
498  AliVertex* v=this;
499  Dump(v,1,f); // Information of all sec. vertices
500 }
501 //////////////////////////////////////////////////////////////////////////
502 void AliVertex::Dump(AliVertex* v,Int_t n,TString f)
503 {
504 // Recursively provide the info of all secondary vertices of this vertex
505  AliVertex* vs; 
506  for (Int_t iv=1; iv<=v->GetNvertices(); iv++)
507  {
508   vs=v->GetVertex(iv);
509   if (vs)
510   {
511    cout << "  ---Level " << n << " sec. vertex no. " << iv << endl;
512    cout << " ";
513    vs->Info(f); 
514
515    // The tracks of this vertex
516    AliTrack* t; 
517    for (Int_t it=1; it<=vs->GetNtracks(); it++)
518    {
519     t=vs->GetTrack(it);
520     if (t)
521     {
522      cout << "  ---Track no. " << it << endl;
523      cout << " ";
524      t->ListAll(f); 
525     }
526     else
527     {
528      cout << " *AliVertex::Dump* Error : No track present." << endl; 
529     }
530    }
531
532    // Go for next sec. vertex level of this sec. vertex recursively
533    Dump(vs,n+1,f);
534   }
535   else
536   {
537    cout << " *AliVertex::Dump* Error : No sec. vertex present." << endl; 
538   }
539  }
540
541 //////////////////////////////////////////////////////////////////////////
542 Int_t AliVertex::GetNvertices()
543 {
544 // Return the current number of (secondary) vertices
545  return fNvtx;
546 }
547 ///////////////////////////////////////////////////////////////////////////
548 AliVertex* AliVertex::GetVertex(Int_t i)
549 {
550 // Return the i-th (secondary) vertex of the current vertex
551  if (!fVertices)
552  {
553   cout << " *AliVertex*::GetVertex* No (secondary) vertices present." << endl;
554   return 0;
555  }
556  else
557  {
558   if (i<=0 || i>fNvtx)
559   {
560    cout << " *AliVertex*::GetVertex* Invalid argument i : " << i
561         << " Nvtx = " << fNvtx << endl;
562    return 0;
563   }
564   else
565   {
566    return (AliVertex*)fVertices->At(i-1);
567   }
568  }
569 }
570 ///////////////////////////////////////////////////////////////////////////
571 void AliVertex::SetVertexCopy(Int_t j)
572 {
573 // (De)activate the creation of private copies of the added vertices.
574 // j=0 ==> No private copies are made; pointers of original vertices are stored.
575 // j=1 ==> Private copies of the vertices are made and these pointers are stored.
576 //
577 // Note : Once the storage contains pointer(s) to AliVertex objects one cannot
578 //        change the VertexCopy mode anymore.
579 //        To change the VertexCopy mode for an existing AliVertex containing
580 //        vertices one first has to invoke Reset().
581  if (!fVertices)
582  {
583   if (j==0 || j==1)
584   {
585    fVertexCopy=j;
586   }
587   else
588   {
589    cout << "*AliVertex::SetVertexCopy* Invalid argument : " << j << endl;
590   }
591  }
592  else
593  {
594   cout << "*AliVertex::SetVertexCopy* Storage already contained vertices."
595        << "  ==> VertexCopy mode not changed." << endl; 
596  }
597 }
598 ///////////////////////////////////////////////////////////////////////////
599 Int_t AliVertex::GetVertexCopy()
600 {
601 // Provide value of the VertexCopy mode.
602 // 0 ==> No private copies are made; pointers of original vertices are stored.
603 // 1 ==> Private copies of the vertices are made and these pointers are stored.
604  return fVertexCopy;
605 }
606 ///////////////////////////////////////////////////////////////////////////
607 Int_t AliVertex::GetNjets()
608 {
609 // Return the current number of jets
610  return fNjets;
611 }
612 ///////////////////////////////////////////////////////////////////////////
613 AliJet* AliVertex::GetJet(Int_t i)
614 {
615 // Return the i-th jet of the current vertex
616  if (!fJets)
617  {
618   cout << " *AliVertex*::GetJet* No jets present." << endl;
619   return 0;
620  }
621  else
622  {
623   if (i<=0 || i>fNjets)
624   {
625    cout << " *AliVertex*::GetJet* Invalid argument i : " << i
626         << " Njets = " << fNjets << endl;
627    return 0;
628   }
629   else
630   {
631    return (AliJet*)fJets->At(i-1);
632   }
633  }
634 }
635 ///////////////////////////////////////////////////////////////////////////
636 void AliVertex::SetJetCopy(Int_t j)
637 {
638 // (De)activate the creation of private copies of the added jets.
639 // j=0 ==> No private copies are made; pointers of original jets are stored.
640 // j=1 ==> Private copies of the jets are made and these pointers are stored.
641 //
642 // Note : Once the storage contains pointer(s) to AliJet objects one cannot
643 //        change the JetCopy mode anymore.
644 //        To change the JetCopy mode for an existing AliVertex containing
645 //        jets one first has to invoke Reset().
646  if (!fJets)
647  {
648   if (j==0 || j==1)
649   {
650    fJetCopy=j;
651   }
652   else
653   {
654    cout << "*AliVertex::SetJetCopy* Invalid argument : " << j << endl;
655   }
656  }
657  else
658  {
659   cout << "*AliVertex::SetJetCopy* Storage already contained jets."
660        << "  ==> JetCopy mode not changed." << endl; 
661  }
662 }
663 ///////////////////////////////////////////////////////////////////////////
664 Int_t AliVertex::GetJetCopy()
665 {
666 // Provide value of the JetCopy mode.
667 // 0 ==> No private copies are made; pointers of original jets are stored.
668 // 1 ==> Private copies of the jets are made and these pointers are stored.
669  return fJetCopy;
670 }
671 ///////////////////////////////////////////////////////////////////////////