]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - RALICE/AliJet.cxx
Moving AliDSCValue, AliDCSSensor And AliDCSSensorArray from CDB to STEER to avoud...
[u/mrichter/AliRoot.git] / RALICE / AliJet.cxx
... / ...
CommitLineData
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 AliJet
20// Creation and investigation of a jet of particle tracks.
21// An AliJet can be constructed by adding AliTracks.
22//
23// To provide maximal flexibility to the user, two modes of track storage
24// are provided by means of the memberfunction SetTrackCopy().
25//
26// a) SetTrackCopy(0) (which is the default).
27// Only the pointers of the 'added' tracks are stored.
28// This mode is typically used by making jet studies based on a fixed list
29// of tracks which stays under user control or is contained for instance
30// in an AliEvent.
31// In this way the AliJet just represents a 'logical structure' for the
32// physics analysis which can be embedded in e.g. an AliEvent or AliVertex.
33//
34// Note :
35// Modifications made to the original tracks also affect the AliTrack objects
36// which are stored in the AliJet.
37//
38// b) SetTrackCopy(1).
39// Of every 'added' track a private copy will be made of which the pointer
40// will be stored.
41// In this way the AliJet represents an entity on its own and modifications
42// made to the original tracks do not affect the AliTrack objects which are
43// stored in the AliJet.
44// This mode will allow 'adding' many different AliTracks into an AliJet by
45// creating only one AliTrack instance in the main programme and using the
46// AliTrack::Reset() and AliTrack parameter setting memberfunctions.
47//
48// See also the documentation provided for the memberfunction SetOwner().
49//
50// Coding example to make 2 jets j1 and j2.
51// ----------------------------------------
52// j1 contains the AliTracks t1 and t2
53// j2 contains 10 different AliTracks via tx
54//
55// AliTrack t1,t2;
56// ...
57// ... // code to fill the AliTrack data
58// ...
59// AliJet j1();
60// j1.AddTrack(t1);
61// j1.AddTrack(t2);
62//
63// AliJet j2();
64// j2.SetTrackCopy(1);
65// AliTrack* tx=new AliTrack();
66// for (Int_t i=0; i<10; i++)
67// {
68// ...
69// ... // code to set momentum etc... of the track tx
70// ...
71// j2.AddTrack(tx);
72// tx->Reset();
73// }
74//
75// j1.Data();
76// j2.Data("sph");
77//
78// Float_t e1=j1.GetEnergy();
79// Float_t pnorm=j1->GetMomentum();
80// Ali3Vector p=j1->Get3Momentum();
81// Float_t m=j1.GetInvmass();
82// Int_t ntk=j1.GetNtracks();
83// AliTrack* tj=j1.GetTrack(1);
84//
85// delete tx;
86//
87// Note : By default all quantities are in GeV, GeV/c or GeV/c**2
88// but the user can indicate the usage of a different scale
89// for the energy-momentum units via the SetEscale() memberfunction.
90// The actual energy-momentum unit scale can be obtained via the
91// GetEscale() memberfunction.
92//
93//--- Author: Nick van Eijndhoven 10-jul-1997 UU-SAP Utrecht
94//- Modified: NvE $Date$ UU-SAP Utrecht
95///////////////////////////////////////////////////////////////////////////
96
97#include "AliJet.h"
98#include "Riostream.h"
99
100ClassImp(AliJet) // Class implementation to enable ROOT I/O
101
102AliJet::AliJet() : TNamed(),Ali4Vector()
103{
104// Default constructor
105// All variables initialised to 0
106// Initial maximum number of tracks is set to the default value
107 Init();
108 Reset();
109 SetNtinit();
110}
111///////////////////////////////////////////////////////////////////////////
112void AliJet::Init()
113{
114// Initialisation of pointers etc...
115 fTracks=0;
116 fNtinit=0;
117 fTrackCopy=0;
118 fRef=0;
119 fSelected=0;
120 fEscale=1;
121}
122///////////////////////////////////////////////////////////////////////////
123AliJet::AliJet(Int_t n) : TNamed(),Ali4Vector()
124{
125// Create a jet to hold initially a maximum of n tracks
126// All variables initialised to 0
127 Init();
128 Reset();
129 if (n > 0)
130 {
131 SetNtinit(n);
132 }
133 else
134 {
135 cout << endl;
136 cout << " *AliJet* Initial max. number of tracks entered : " << n << endl;
137 cout << " This is invalid. Default initial maximum will be used." << endl;
138 cout << endl;
139 SetNtinit();
140 }
141}
142///////////////////////////////////////////////////////////////////////////
143AliJet::~AliJet()
144{
145// Default destructor
146 if (fTracks)
147 {
148 delete fTracks;
149 fTracks=0;
150 }
151 if (fRef)
152 {
153 delete fRef;
154 fRef=0;
155 }
156 if (fSelected)
157 {
158 delete fSelected;
159 fSelected=0;
160 }
161}
162///////////////////////////////////////////////////////////////////////////
163void AliJet::SetOwner(Bool_t own)
164{
165// Set ownership of all added objects.
166// The default parameter is own=kTRUE.
167//
168// Invokation of this memberfunction also sets all the copy modes
169// (e.g. TrackCopy & co.) according to the value of own.
170//
171// This function (with own=kTRUE) is particularly useful when reading data
172// from a tree/file, since Reset() will then actually remove all the
173// added objects from memory irrespective of the copy mode settings
174// during the tree/file creation process. In this way it provides a nice way
175// of preventing possible memory leaks in the reading/analysis process.
176//
177// In addition this memberfunction can also be used as a shortcut to set all
178// copy modes in one go during a tree/file creation process.
179// However, in this case the user has to take care to only set/change the
180// ownership (and copy mode) for empty objects (e.g. newly created objects
181// or after invokation of the Reset() memberfunction) otherwise it will
182// very likely result in inconsistent destructor behaviour.
183
184 Int_t mode=1;
185 if (!own) mode=0;
186 if (fTracks) fTracks->SetOwner(own);
187 fTrackCopy=mode;
188}
189///////////////////////////////////////////////////////////////////////////
190AliJet::AliJet(const AliJet& j) : TNamed(j),Ali4Vector(j)
191{
192// Copy constructor
193 fNtinit=j.fNtinit;
194 fNtmax=j.fNtmax;
195 fQ=j.fQ;
196 fEscale=j.fEscale;
197 fNtrk=j.fNtrk;
198 fTrackCopy=j.fTrackCopy;
199 fUserId=j.fUserId;
200 if (j.fRef) fRef=new AliPositionObj(*(j.fRef));
201
202 fSelected=0;
203
204 fTracks=0;
205 if (fNtrk)
206 {
207 fTracks=new TObjArray(fNtmax);
208 if (fTrackCopy) fTracks->SetOwner();
209 }
210
211 for (Int_t i=1; i<=fNtrk; i++)
212 {
213 AliTrack* tx=j.GetTrack(i);
214 if (fTrackCopy)
215 {
216 fTracks->Add(tx->Clone());
217 }
218 else
219 {
220 fTracks->Add(tx);
221 }
222 }
223}
224///////////////////////////////////////////////////////////////////////////
225void AliJet::SetNtinit(Int_t n)
226{
227// Set the initial maximum number of tracks for this jet
228 fNtinit=n;
229 fNtmax=n;
230
231 if (fTracks)
232 {
233 delete fTracks;
234 fTracks=0;
235 }
236 if (fRef)
237 {
238 delete fRef;
239 fRef=0;
240 }
241}
242///////////////////////////////////////////////////////////////////////////
243void AliJet::Reset()
244{
245// Reset all variables to 0
246// The max. number of tracks is set to the initial value again
247// Note : The scale for the energy/momentum units will not be changed.
248 fNtrk=0;
249 fQ=0;
250 fUserId=0;
251 Double_t a[4]={0,0,0,0};
252 SetVector(a,"sph");
253 if (fNtinit > 0) SetNtinit(fNtinit);
254}
255///////////////////////////////////////////////////////////////////////////
256void AliJet::AddTrack(AliTrack& t)
257{
258// Add a track to the jet.
259// In case the maximum number of tracks has been reached
260// space will be extended to hold an additional amount of tracks as
261// was initially reserved.
262// See SetTrackCopy() to tailor the functionality of the stored structures.
263//
264// Notes :
265// -------
266// In case a private copy is made, this is performed via the Clone() memberfunction.
267// All AliTrack and derived classes have the default TObject::Clone() memberfunction.
268// However, derived classes generally contain an internal data structure which may
269// include pointers to other objects. Therefore it is recommended to provide
270// for all derived classes a specific copy constructor and override the default Clone()
271// memberfunction using this copy constructor.
272// An example for this may be seen from AliTrack.
273//
274// In case NO private copy is made, a check will be performed if this
275// specific track is already present in the jet.
276// If this is the case, no action is performed to prevent multiple
277// additions of the same track.
278
279
280 AddTrack(t,1);
281}
282///////////////////////////////////////////////////////////////////////////
283void AliJet::AddTrack(AliTrack& t,Int_t copy)
284{
285// Internal memberfunction to actually add a track to the jet.
286// In case the maximum number of tracks has been reached
287// space will be extended to hold an additional amount of tracks as
288// was initially reserved.
289//
290// If copy=0 NO copy of the track will be made, irrespective of the setting
291// of the TrackCopy flag.
292// This allows a proper treatment of automatically generated connecting
293// tracks between vertices.
294//
295// In case NO copy of the track is made, a check will be performed if this
296// specific track is already present in the jet.
297// If this is the case, no action is performed to prevent multiple
298// additions of the same track.
299//
300// Note :
301// In case a private copy is made, this is performed via the Clone() memberfunction.
302
303 if (!fTracks)
304 {
305 fTracks=new TObjArray(fNtmax);
306 if (fTrackCopy) fTracks->SetOwner();
307 }
308 else if (!fTrackCopy || !copy) // Check if this track is already present
309 {
310 for (Int_t i=0; i<fNtrk; i++)
311 {
312 AliTrack* tx=(AliTrack*)fTracks->At(i);
313 if (tx == &t) return;
314 }
315 }
316
317 if (fNtrk == fNtmax) // Check if maximum track number is reached
318 {
319 fNtmax+=fNtinit;
320 fTracks->Expand(fNtmax);
321 }
322
323 // Add the track to this jet
324 fNtrk++;
325 if (fTrackCopy && copy)
326 {
327 fTracks->Add(t.Clone());
328 }
329 else
330 {
331 fTracks->Add(&t);
332 }
333
334 fQ+=t.GetCharge();
335
336 Ali4Vector p4=(Ali4Vector)t;
337 Float_t tscale=t.GetEscale();
338 if ((tscale/fEscale > 1.1) || (fEscale/tscale > 1.1)) p4=p4*(tscale/fEscale);
339 (*this)+=p4;
340
341}
342///////////////////////////////////////////////////////////////////////////
343void AliJet::Data(TString f,TString u)
344{
345// Provide jet information within the coordinate frame f
346//
347// The string argument "u" allows to choose between different angular units
348// in case e.g. a spherical frame is selected.
349// u = "rad" : angles provided in radians
350// "deg" : angles provided in degrees
351//
352// The defaults are f="car" and u="rad".
353
354 const char* name=GetName();
355 const char* title=GetTitle();
356
357 cout << " *AliJet::Data*";
358 if (strlen(name)) cout << " Name : " << GetName();
359 if (strlen(title)) cout << " Title : " << GetTitle();
360 cout << endl;
361 cout << " Id : " << fUserId << " Invmass : " << GetInvmass() << " Charge : " << fQ
362 << " Momentum : " << GetMomentum() << " Energy scale : " << fEscale << " GeV" << endl;
363
364 ShowTracks(0);
365
366 Ali4Vector::Data(f,u);
367}
368///////////////////////////////////////////////////////////////////////////
369void AliJet::List(TString f,TString u)
370{
371// Provide jet and primary track information within the coordinate frame f
372//
373// The string argument "u" allows to choose between different angular units
374// in case e.g. a spherical frame is selected.
375// u = "rad" : angles provided in radians
376// "deg" : angles provided in degrees
377//
378// The defaults are f="car" and u="rad".
379
380 Data(f,u); // Information of the current jet
381 if (fRef) { cout << " Ref-point :"; fRef->Data(f,u); }
382
383 // The tracks of this jet
384 AliTrack* t;
385 for (Int_t it=1; it<=fNtrk; it++)
386 {
387 t=GetTrack(it);
388 if (t)
389 {
390 cout << " ---Track no. " << it << endl;
391 cout << " ";
392 t->Data(f,u);
393 }
394 else
395 {
396 cout << " *AliJet::List* Error : No track present." << endl;
397 }
398 }
399}
400///////////////////////////////////////////////////////////////////////////
401void AliJet::ListAll(TString f,TString u)
402{
403// Provide jet and prim.+sec. track information within the coordinate frame f
404//
405// The string argument "u" allows to choose between different angular units
406// in case e.g. a spherical frame is selected.
407// u = "rad" : angles provided in radians
408// "deg" : angles provided in degrees
409//
410// The defaults are f="car" and u="rad".
411
412 Data(f,u); // Information of the current jet
413 if (fRef) { cout << " Ref-point :"; fRef->Data(f,u); }
414
415 // The tracks of this jet
416 AliTrack* t;
417 for (Int_t it=1; it<=fNtrk; it++)
418 {
419 t=GetTrack(it);
420 if (t)
421 {
422 cout << " ---Track no. " << it << endl;
423 cout << " ";
424 t->ListAll(f,u);
425 }
426 else
427 {
428 cout << " *AliJet::List* Error : No track present." << endl;
429 }
430 }
431}
432///////////////////////////////////////////////////////////////////////////
433Int_t AliJet::GetNtracks(Int_t idmode,Int_t chmode,Int_t pcode)
434{
435// Provide the number of user selected tracks in this jet based on the
436// idmode, chmode and pcode selections as specified by the user.
437// For specification of the selection parameters see GetTracks().
438// The default parameters correspond to no selection, which implies
439// that invokation of GetNtracks() just returns the total number of
440// tracks registered in this jet.
441//
442// Note : In case certain selections are specified, this function
443// invokes GetTracks(idmode,chmode,pcode) to determine the
444// number of tracks corresponding to the selections.
445// When the jet contains a large number of tracks, invokation
446// of GetTracks(idmode,chmode,pcode) and subsequently invoking
447// GetEntries() for the resulting TObjArray* might be slightly
448// faster.
449
450 Int_t n=0;
451 if (idmode==0 && chmode==2 && pcode==0)
452 {
453 return fNtrk;
454 }
455 else
456 {
457 TObjArray* arr=GetTracks(idmode,chmode,pcode);
458 n=arr->GetEntries();
459 return n;
460 }
461}
462///////////////////////////////////////////////////////////////////////////
463Double_t AliJet::GetEnergy(Float_t scale)
464{
465// Return the total energy of the jet.
466// By default the energy is returned in the units as it was stored in the jet
467// structure. However, the user can select a different energy unit scale by
468// specification of the scale parameter.
469// The convention is that scale=1 corresponds to GeV, so specification
470// of scale=0.001 will provide the energy in MeV.
471// The error can be obtained by invoking GetResultError() after
472// invokation of GetEnergy().
473 Double_t E=GetScalar();
474 if (E>0)
475 {
476 if (scale>0)
477 {
478 E*=fEscale/scale;
479 fDresult*=fEscale/scale;
480 }
481 return E;
482 }
483 else
484 {
485 return 0;
486 }
487}
488///////////////////////////////////////////////////////////////////////////
489Double_t AliJet::GetMomentum(Float_t scale)
490{
491// Return the value of the total jet 3-momentum
492// By default the momentum is returned in the units as it was stored in the jet
493// structure. However, the user can select a different momentum unit scale by
494// specification of the scale parameter.
495// The convention is that scale=1 corresponds to GeV/c, so specification
496// of scale=0.001 will provide the momentum in MeV/c.
497// The error can be obtained by invoking GetResultError() after
498// invokation of GetMomentum().
499
500 Double_t norm=fV.GetNorm();
501 fDresult=fV.GetResultError();
502 if (scale>0)
503 {
504 norm*=fEscale/scale;
505 fDresult*=fEscale/scale;
506 }
507 return norm;
508}
509///////////////////////////////////////////////////////////////////////////
510Ali3Vector AliJet::Get3Momentum(Float_t scale) const
511{
512// Return the the total jet 3-momentum
513// By default the components of the 3-momentum are returned in the units
514// as they were stored in the jet structure.
515// However, the user can select a different momentum unit scale for the
516// components by specification of the scale parameter.
517// The convention is that scale=1 corresponds to GeV/c, so specification
518// of scale=0.001 will provide the 3-momentum in MeV/c.
519
520 Ali3Vector p=Get3Vector();
521 if (scale>0) p*=fEscale/scale;
522 return p;
523}
524///////////////////////////////////////////////////////////////////////////
525Double_t AliJet::GetInvmass(Float_t scale)
526{
527// Return the invariant mass of the jet.
528// By default the mass is returned in the units as it was stored in the jet
529// structure. However, the user can select a different mass unit scale by
530// specification of the scale parameter.
531// The convention is that scale=1 corresponds to GeV/c**2, so specification
532// of scale=0.001 will provide the invariant mass in MeV/c**2.
533// The error can be obtained by invoking GetResultError() after
534// invokation of GetInvmass().
535
536 Double_t inv=Dot(*this);
537 Double_t dinv=GetResultError();
538 Double_t dm=0;
539 if (inv >= 0)
540 {
541 Double_t m=sqrt(inv);
542 if (m) dm=dinv/(2.*m);
543 if (scale>0)
544 {
545 m*=fEscale/scale;
546 dm*=fEscale/scale;
547 }
548 fDresult=dm;
549 return m;
550 }
551 else
552 {
553 fDresult=dm;
554 return 0;
555 }
556}
557///////////////////////////////////////////////////////////////////////////
558Float_t AliJet::GetCharge() const
559{
560// Return the total charge of the jet
561 return fQ;
562}
563///////////////////////////////////////////////////////////////////////////
564AliTrack* AliJet::GetTrack(Int_t i) const
565{
566// Return the i-th track of this jet
567
568 if (!fTracks) return 0;
569
570 if (i<=0 || i>fNtrk)
571 {
572 cout << " *AliJet*::GetTrack* Invalid argument i : " << i
573 << " Ntrk = " << fNtrk << endl;
574 return 0;
575 }
576 else
577 {
578 return (AliTrack*)fTracks->At(i-1);
579 }
580}
581///////////////////////////////////////////////////////////////////////////
582AliTrack* AliJet::GetIdTrack(Int_t id) const
583{
584// Return the track with user identifier "id" of this jet
585 if (!fTracks) return 0;
586
587 AliTrack* tx=0;
588 for (Int_t i=0; i<fNtrk; i++)
589 {
590 tx=(AliTrack*)fTracks->At(i);
591 if (id == tx->GetId()) return tx;
592 }
593 return 0; // No matching id found
594}
595///////////////////////////////////////////////////////////////////////////
596TObjArray* AliJet::GetTracks(Int_t idmode,Int_t chmode,Int_t pcode)
597{
598// Provide references to user selected tracks based on the idmode, chmode
599// and pcode selections as specified by the user.
600//
601// The following selection combinations are available :
602// ----------------------------------------------------
603// idmode = -1 ==> Select tracks with negative user identifier "id"
604// 0 ==> No selection on user identifier
605// 1 ==> Select tracks with positive user identifier "id"
606//
607// chmode = -1 ==> Select tracks with negative charge
608// 0 ==> Select neutral tracks
609// 1 ==> Select tracks with positive charge
610// 2 ==> No selection on charge
611// 3 ==> Select all charged tracks
612//
613// pcode = 0 ==> No selection on particle code
614// X ==> Select tracks with particle code +X or -X
615// This allows selection of both particles and anti-particles
616// in case of PDG particle codes.
617// Selection of either particles or anti-particles can be
618// obtained in combination with the "chmode" selector.
619//
620// Examples :
621// ----------
622// idmode=-1 chmode=0 pcode=0 : Selection of all neutral tracks with negative id.
623// idmode=0 chmode=2 pcode=211 : Selection of all charged pions (PDG convention).
624// idmode=0 chmode=1 pcode=321 : Selection of all positive kaons (PDG convention).
625//
626// The default values are idmode=0 chmode=2 pcode=0 (i.e. no selections applied).
627//
628// Notes :
629// -------
630// 1) In case the user has labeled simulated tracks with negative id and
631// reconstructed tracks with positive id, this memberfunction provides
632// easy access to either all simulated or reconstructed tracks.
633// 2) Subsequent invokations of this memberfunction with e.g. chmode=-1 and chmode=1
634// provides a convenient way to investigate particle pairs with opposite charge
635// (e.g. for invariant mass analysis).
636// 3) The selected track pointers are returned via a multi-purpose array,
637// which will be overwritten by subsequent selections.
638// In case the selected track list is to be used amongst other selections,
639// the user is advised to store the selected track pointers in a local
640// TObjArray or TRefArray.
641
642 if (fSelected)
643 {
644 fSelected->Clear();
645 }
646 else
647 {
648 fSelected=new TObjArray();
649 }
650
651 if (!fTracks) return fSelected;
652
653 AliTrack* tx=0;
654 Int_t code=0;
655 Int_t id=0;
656 Float_t q=0;
657 for (Int_t i=0; i<fNtrk; i++)
658 {
659 tx=(AliTrack*)fTracks->At(i);
660 if (!tx) continue;
661
662 code=tx->GetParticleCode();
663 if (pcode && abs(pcode)!=abs(code)) continue;
664
665 id=tx->GetId();
666 if (idmode==-1 && id>=0) continue;
667 if (idmode==1 && id<=0) continue;
668
669 q=tx->GetCharge();
670 if (chmode==-1 && q>=0) continue;
671 if (chmode==0 && fabs(q)>1e-10) continue;
672 if (chmode==1 && q<=0) continue;
673 if (chmode==3 && fabs(q)<1e-10) continue;
674
675 fSelected->Add(tx);
676 }
677
678 return fSelected;
679}
680///////////////////////////////////////////////////////////////////////////
681TObjArray* AliJet::GetTracks(TString name)
682{
683// Provide references to all tracks with the specified name.
684//
685// Notes :
686// -------
687// 1) In case the user has labeled reconstructed tracks with the name of
688// the applied reconstruction algorithm, this memberfunction provides
689// easy access to all tracks reconstructed by a certain method.
690// 2) The selected track pointers are returned via a multi-purpose array,
691// which will be overwritten by subsequent selections.
692// In case the selected track list is to be used amongst other selections,
693// the user is advised to store the selected track pointers in a local
694// TObjArray or TRefArray.
695
696 if (fSelected)
697 {
698 fSelected->Clear();
699 }
700 else
701 {
702 fSelected=new TObjArray();
703 }
704
705 if (!fTracks) return fSelected;
706
707 AliTrack* tx=0;
708 TString s;
709 for (Int_t i=0; i<fNtrk; i++)
710 {
711 tx=(AliTrack*)fTracks->At(i);
712 if (!tx) continue;
713
714 s=tx->GetName();
715 if (s == name) fSelected->Add(tx);
716 }
717
718 return fSelected;
719}
720///////////////////////////////////////////////////////////////////////////
721void AliJet::RemoveTracks(TString name)
722{
723// Remove all tracks with the specified name.
724// If name="*" all tracks will be removed.
725//
726// Note :
727// ------
728// In case the user has labeled reconstructed tracks with the name of
729// the applied reconstruction algorithm, this memberfunction provides
730// easy removal of all tracks reconstructed by a certain method.
731
732 if (!fTracks) return;
733
734 AliTrack* tx=0;
735 TString s;
736 TObject* obj=0;
737 for (Int_t i=0; i<fNtrk; i++)
738 {
739 tx=(AliTrack*)fTracks->At(i);
740 if (!tx) continue;
741
742 s=tx->GetName();
743 if (s==name || name=="*")
744 {
745 obj=fTracks->Remove(tx);
746 if (obj && fTracks->IsOwner()) delete tx;
747 }
748 }
749 fTracks->Compress();
750 fNtrk=fTracks->GetEntries();
751}
752///////////////////////////////////////////////////////////////////////////
753void AliJet::RemoveTracks(Int_t idmode,Int_t chmode,Int_t pcode)
754{
755// Remove user selected tracks based on the idmode, chmode and pcode
756// selections as specified by the user.
757// For defintions of these selections see the corresponding GetTracks()
758// memberfunction.
759
760 if (!fTracks) return;
761
762 TObjArray* arr=GetTracks(idmode,chmode,pcode);
763 if (!arr) return;
764
765 Int_t ntk=arr->GetEntries();
766 if (!ntk) return;
767
768 AliTrack* tx=0;
769 TObject* obj=0;
770 for (Int_t i=0; i<ntk; i++)
771 {
772 tx=(AliTrack*)arr->At(i);
773 if (!tx) continue;
774
775 obj=fTracks->Remove(tx);
776 if (obj && fTracks->IsOwner()) delete tx;
777 }
778 fTracks->Compress();
779 fNtrk=fTracks->GetEntries();
780 arr->Clear();
781}
782///////////////////////////////////////////////////////////////////////////
783void AliJet::ShowTracks(Int_t mode)
784{
785// Provide an overview of the available tracks.
786// The argument mode determines the amount of information as follows :
787// mode = 0 ==> Only printout of the number of tracks
788// 1 ==> Provide a listing with 1 line of info for each track
789//
790// The default is mode=1.
791//
792 Int_t ntk=GetNtracks();
793 if (ntk)
794 {
795 if (!mode)
796 {
797 cout << " There are " << ntk << " tracks available." << endl;
798 }
799 else
800 {
801 cout << " The following " << ntk << " tracks are available :" << endl;
802 for (Int_t i=1; i<=ntk; i++)
803 {
804 AliTrack* tx=GetTrack(i);
805 if (tx)
806 {
807 const char* name=tx->GetName();
808 const char* title=tx->GetTitle();
809 cout << " Track : " << i;
810 cout << " Id : " << tx->GetId();
811 cout << " Q : " << tx->GetCharge() << " m : " << tx->GetMass() << " p : " << tx->GetMomentum();
812 if (strlen(name)) cout << " Name : " << name;
813 if (strlen(title)) cout << " Title : " << title;
814 cout << endl;
815 }
816 }
817 }
818 }
819 else
820 {
821 cout << " No tracks are present." << endl;
822 }
823}
824///////////////////////////////////////////////////////////////////////////
825Double_t AliJet::GetPt(Float_t scale)
826{
827// Provide the transverse momentum value w.r.t. z-axis.
828// By default the value is returned in the units as it was stored in the jet
829// structure. However, the user can select a different momentum unit scale by
830// specification of the scale parameter.
831// The convention is that scale=1 corresponds to GeV/c, so specification
832// of scale=0.001 will provide the transverse momentum in MeV/c.
833// The error on the value can be obtained by GetResultError()
834// after invokation of GetPt().
835 Ali3Vector v;
836 v=GetVecTrans();
837 Double_t norm=v.GetNorm();
838 fDresult=v.GetResultError();
839 if (scale>0)
840 {
841 norm*=fEscale/scale;
842 fDresult*=fEscale/scale;
843 }
844
845 return norm;
846}
847///////////////////////////////////////////////////////////////////////////
848Double_t AliJet::GetPl(Float_t scale)
849{
850// Provide the longitudinal momentum value w.r.t. z-axis.
851// By default the value is returned in the units as it was stored in the jet
852// structure. However, the user can select a different momentum unit scale by
853// specification of the scale parameter.
854// The convention is that scale=1 corresponds to GeV/c, so specification
855// of scale=0.001 will provide the longitudinal momentum in MeV/c.
856// Note : the returned value can also be negative.
857// The error on the value can be obtained by GetResultError()
858// after invokation of GetPl().
859
860 Ali3Vector v;
861 v=GetVecLong();
862
863 Double_t pl=v.GetNorm();
864 fDresult=v.GetResultError();
865
866 Double_t a[3];
867 v.GetVector(a,"sph");
868 if (cos(a[1])<0) pl=-pl;
869 if (scale>0)
870 {
871 pl*=fEscale/scale;
872 fDresult*=fEscale/scale;
873 }
874
875 return pl;
876}
877///////////////////////////////////////////////////////////////////////////
878Double_t AliJet::GetEt(Float_t scale)
879{
880// Provide transverse energy value w.r.t. z-axis.
881// By default the value is returned in the units as it was stored in the jet
882// structure. However, the user can select a different energy unit scale by
883// specification of the scale parameter.
884// The convention is that scale=1 corresponds to GeV, so specification
885// of scale=0.001 will provide the transverse energy in MeV.
886// The error on the value can be obtained by GetResultError()
887// after invokation of GetEt().
888
889 Double_t et=GetScaTrans();
890 if (scale>0)
891 {
892 et*=fEscale/scale;
893 fDresult*=fEscale/scale;
894 }
895
896 return et;
897}
898///////////////////////////////////////////////////////////////////////////
899Double_t AliJet::GetEl(Float_t scale)
900{
901// Provide longitudinal energy value w.r.t. z-axis.
902// By default the value is returned in the units as it was stored in the jet
903// structure. However, the user can select a different energy unit scale by
904// specification of the scale parameter.
905// The convention is that scale=1 corresponds to GeV, so specification
906// of scale=0.001 will provide the longitudinal energy in MeV.
907// Note : the returned value can also be negative.
908// The error on the value can be obtained by GetResultError()
909// after invokation of GetEl().
910
911 Double_t el=GetScaLong();
912 if (scale>0)
913 {
914 el*=fEscale/scale;
915 fDresult*=fEscale/scale;
916 }
917
918 return el;
919}
920///////////////////////////////////////////////////////////////////////////
921Double_t AliJet::GetMt(Float_t scale)
922{
923// Provide transverse mass value w.r.t. z-axis.
924// By default the value is returned in the units as it was stored in the jet
925// structure. However, the user can select a different energy unit scale by
926// specification of the scale parameter.
927// The convention is that scale=1 corresponds to GeV, so specification
928// of scale=0.001 will provide the transverse mass in MeV.
929// The error on the value can be obtained by GetResultError()
930// after invokation of GetMt().
931 Double_t pt=GetPt();
932 Double_t dpt=GetResultError();
933 Double_t m=GetInvmass();
934 Double_t dm=GetResultError();
935
936 Double_t mt=sqrt(pt*pt+m*m);
937 Double_t dmt2=0;
938 if (mt) dmt2=(pow((pt*dpt),2)+pow((m*dm),2))/(mt*mt);
939
940 fDresult=sqrt(dmt2);
941 if (scale>0)
942 {
943 mt*=fEscale/scale;
944 fDresult*=fEscale/scale;
945 }
946 return mt;
947}
948///////////////////////////////////////////////////////////////////////////
949Double_t AliJet::GetRapidity()
950{
951// Provide rapidity value w.r.t. z-axis.
952// The error on the value can be obtained by GetResultError()
953// after invokation of GetRapidity().
954// Note : Also GetPseudoRapidity() is available since this class is
955// derived from Ali4Vector.
956 Double_t e=GetEnergy();
957 Double_t de=GetResultError();
958 Double_t pl=GetPl();
959 Double_t dpl=GetResultError();
960 Double_t sum=e+pl;
961 Double_t dif=e-pl;
962
963 Double_t y=9999,dy2=0;
964 if (sum && dif) y=0.5*log(sum/dif);
965
966 if (sum*dif) dy2=(1./(sum*dif))*(pow((pl*de),2)+pow((e*dpl),2));
967
968 fDresult=sqrt(dy2);
969 return y;
970}
971///////////////////////////////////////////////////////////////////////////
972void AliJet::SetTrackCopy(Int_t j)
973{
974// (De)activate the creation of private copies of the added tracks.
975// j=0 ==> No private copies are made; pointers of original tracks are stored.
976// j=1 ==> Private copies of the tracks are made and these pointers are stored.
977//
978// Note : Once the storage contains pointer(s) to AliTrack(s) one cannot
979// change the TrackCopy mode anymore.
980// To change the TrackCopy mode for an existing AliJet containing
981// tracks one first has to invoke Reset().
982 if (!fTracks)
983 {
984 if (j==0 || j==1)
985 {
986 fTrackCopy=j;
987 }
988 else
989 {
990 cout << "*AliJet::SetTrackCopy* Invalid argument : " << j << endl;
991 }
992 }
993 else
994 {
995 cout << "*AliJet::SetTrackCopy* Storage already contained tracks."
996 << " ==> TrackCopy mode not changed." << endl;
997 }
998}
999///////////////////////////////////////////////////////////////////////////
1000Int_t AliJet::GetTrackCopy() const
1001{
1002// Provide value of the TrackCopy mode.
1003// 0 ==> No private copies are made; pointers of original tracks are stored.
1004// 1 ==> Private copies of the tracks are made and these pointers are stored.
1005 return fTrackCopy;
1006}
1007///////////////////////////////////////////////////////////////////////////
1008void AliJet::SetId(Int_t id)
1009{
1010// Set a user defined identifier for this jet.
1011 fUserId=id;
1012}
1013///////////////////////////////////////////////////////////////////////////
1014Int_t AliJet::GetId() const
1015{
1016// Provide the user defined identifier of this jet.
1017 return fUserId;
1018}
1019///////////////////////////////////////////////////////////////////////////
1020void AliJet::SetReferencePoint(AliPosition& p)
1021{
1022// Store the position of the jet reference-point.
1023// The reference-point of a jet provides a means to define a generic
1024// space-time location for the jet as a whole.
1025// This doesn't have to be necessarily the location where all the constituent
1026// tracks originate (e.g. a bundle of parallel tracks doesn't have such
1027// a location). As such the meaning of this reference-point is different from
1028// a normal vertex position and allows to provide complimentary information.
1029// This reference point is the preferable point to start e.g. extrapolations
1030// and investigate coincidences in space and/or time.
1031 if (fRef) delete fRef;
1032 fRef=new AliPositionObj(p);
1033}
1034///////////////////////////////////////////////////////////////////////////
1035AliPosition* AliJet::GetReferencePoint()
1036{
1037// Provide the position of the jet reference-point.
1038// The reference-point of a jet provides a means to define a generic
1039// space-time location for the jet as a whole.
1040// This doesn't have to be necessarily the location where all the constituent
1041// tracks originate (e.g. a bundle of parallel tracks doesn't have such
1042// a location). As such the meaning of this reference-point is different from
1043// a normal vertex position and allows to provide complimentary information.
1044// This reference point is the preferable point to start e.g. extrapolations
1045// and investigate coincidences in space and/or time.
1046 return fRef;
1047}
1048///////////////////////////////////////////////////////////////////////////
1049TObjArray* AliJet::SortTracks(Int_t mode,TObjArray* tracks)
1050{
1051// Order the references to an array of tracks by looping over the input array "tracks"
1052// and checking the value of a certain observable.
1053// The ordered array is returned as a TObjArray.
1054// In case tracks=0 (default), the registered tracks of the current jet are used.
1055// Note that the original track array is not modified.
1056// Via the "mode" argument the user can specify the observable to be checked upon
1057// and specify whether sorting should be performed in decreasing order (mode<0)
1058// or in increasing order (mode>0).
1059//
1060// The convention for the observable selection is the following :
1061// mode : 1 ==> Number of signals associated to the track
1062// 2 ==> Track energy
1063// 3 ==> Track momentum
1064// 4 ==> Mass of the track
1065// 5 ==> Transverse momentum of the track
1066// 6 ==> Longitudinal momentum of the track
1067// 7 ==> Transverse energy of the track
1068// 8 ==> Longitudinal energy of the track
1069// 9 ==> Transverse mass of the track
1070// 10 ==> Track rapidity
1071// 11 ==> Pseudo-rapidity of the track
1072// 12 ==> Charge of the track
1073// 13 ==> Probability of the track hypothesis
1074//
1075// The default is mode=-1.
1076//
1077// Note : This sorting routine uses a common area in memory, which is used
1078// by various other sorting facilities as well.
1079// This means that the resulting sorted TObjArray may be overwritten
1080// when another sorting is invoked.
1081// To retain the sorted list of pointers, the user is advised to copy
1082// the pointers contained in the returned TObjArray into a private
1083// TObjArray instance.
1084
1085 if (fSelected)
1086 {
1087 delete fSelected;
1088 fSelected=0;
1089 }
1090
1091 if (!tracks) tracks=fTracks;
1092
1093 if (!mode || abs(mode)>13 || !tracks) return fSelected;
1094
1095 Int_t ntracks=tracks->GetEntries();
1096 if (!ntracks)
1097 {
1098 return fSelected;
1099 }
1100 else
1101 {
1102 fSelected=new TObjArray(ntracks);
1103 }
1104
1105 Double_t val1,val2; // Values of the observable to be tested upon
1106
1107 Int_t nord=0;
1108 for (Int_t i=0; i<ntracks; i++) // Loop over all tracks of the array
1109 {
1110 AliTrack* tx=(AliTrack*)tracks->At(i);
1111
1112 if (!tx) continue;
1113
1114 if (nord == 0) // store the first track at the first ordered position
1115 {
1116 nord++;
1117 fSelected->AddAt(tx,nord-1);
1118 continue;
1119 }
1120
1121 for (Int_t j=0; j<=nord; j++) // put track in the right ordered position
1122 {
1123 if (j == nord) // track has smallest (mode<0) or largest (mode>0) observable value seen so far
1124 {
1125 nord++;
1126 fSelected->AddAt(tx,j); // add track at the end
1127 break; // go for next track
1128 }
1129
1130 val1=0;
1131 val2=0;
1132
1133 switch (abs(mode))
1134 {
1135 case 1:
1136 val1=tx->GetNsignals();
1137 val2=((AliTrack*)fSelected->At(j))->GetNsignals();
1138 break;
1139 case 2:
1140 val1=tx->GetEnergy(1);
1141 val2=((AliTrack*)fSelected->At(j))->GetEnergy(1);
1142 break;
1143 case 3:
1144 val1=tx->GetMomentum(1);
1145 val2=((AliTrack*)fSelected->At(j))->GetMomentum(1);
1146 break;
1147 case 4:
1148 val1=tx->GetMass(1);
1149 val2=((AliTrack*)fSelected->At(j))->GetMass(1);
1150 break;
1151 case 5:
1152 val1=tx->GetPt(1);
1153 val2=((AliTrack*)fSelected->At(j))->GetPt(1);
1154 break;
1155 case 6:
1156 val1=tx->GetPl(1);
1157 val2=((AliTrack*)fSelected->At(j))->GetPl(1);
1158 break;
1159 case 7:
1160 val1=tx->GetEt(1);
1161 val2=((AliTrack*)fSelected->At(j))->GetEt(1);
1162 break;
1163 case 8:
1164 val1=tx->GetEl(1);
1165 val2=((AliTrack*)fSelected->At(j))->GetEl(1);
1166 break;
1167 case 9:
1168 val1=tx->GetMt(1);
1169 val2=((AliTrack*)fSelected->At(j))->GetMt(1);
1170 break;
1171 case 10:
1172 val1=tx->GetRapidity();
1173 val2=((AliTrack*)fSelected->At(j))->GetRapidity();
1174 break;
1175 case 11:
1176 val1=tx->GetPseudoRapidity();
1177 val2=((AliTrack*)fSelected->At(j))->GetPseudoRapidity();
1178 break;
1179 case 12:
1180 val1=tx->GetCharge();
1181 val2=((AliTrack*)fSelected->At(j))->GetCharge();
1182 break;
1183 case 13:
1184 val1=tx->GetProb();
1185 val2=((AliTrack*)fSelected->At(j))->GetProb();
1186 break;
1187 }
1188
1189 if (mode<0 && val1 <= val2) continue;
1190 if (mode>0 && val1 >= val2) continue;
1191
1192 nord++;
1193 for (Int_t k=nord-1; k>j; k--) // create empty position
1194 {
1195 fSelected->AddAt(fSelected->At(k-1),k);
1196 }
1197 fSelected->AddAt(tx,j); // put track at empty position
1198 break; // go for next track
1199 }
1200 }
1201 return fSelected;
1202}
1203///////////////////////////////////////////////////////////////////////////
1204Double_t AliJet::GetDistance(AliPosition* p,Float_t scale)
1205{
1206// Provide distance of the current jet to the position p.
1207// The error on the result can be obtained as usual by invoking
1208// GetResultError() afterwards.
1209//
1210// By default the distance will be provided in the metric unit scale of
1211// the AliPosition p.
1212// However, the user can select a different metric unit scale by
1213// specification of the scale parameter.
1214// The convention is that scale=1 corresponds to meter, so specification
1215// of scale=0.01 will provide the distance in cm.
1216// As such it is possible to obtain a correctly computed distance even in case
1217// the jet parameters have a different unit scale.
1218// However, it is recommended to work always with one single unit scale.
1219//
1220// Note : In case of incomplete information, a distance value of -1 is
1221// returned.
1222
1223 Double_t dist=-1.;
1224 fDresult=0.;
1225
1226 if (!p) return dist;
1227
1228 // Obtain a defined position on this jet
1229 AliPosition* rx=fRef;
1230
1231 if (!rx) return dist;
1232
1233 Ali3Vector pj=Get3Momentum();
1234
1235 if (pj.GetNorm() <= 0.) return dist;
1236
1237 AliTrack tj;
1238 tj.Set3Momentum(pj);
1239 tj.SetReferencePoint(*rx);
1240 dist=tj.GetDistance(p,scale);
1241 fDresult=tj.GetResultError();
1242 return dist;
1243}
1244///////////////////////////////////////////////////////////////////////////
1245Double_t AliJet::GetDistance(AliTrack* t,Float_t scale)
1246{
1247// Provide distance of the current jet to the track t.
1248// The error on the result can be obtained as usual by invoking
1249// GetResultError() afterwards.
1250//
1251// By default the distance will be provided in the metric unit scale of
1252// the current jet.
1253// However, the user can specify a required metric unit scale by specification
1254// of the scale parameter.
1255// The convention is that scale=1 corresponds to meter, so specification
1256// of scale=0.01 will provide the distance in cm.
1257// As such it is possible to obtain a correctly computed distance even in case
1258// the jet and track parameters have a different unit scale.
1259// However, it is recommended to work always with one single unit scale.
1260//
1261// Note : In case of incomplete information, a distance value of -1 is
1262// returned.
1263
1264 Double_t dist=-1.;
1265 fDresult=0.;
1266
1267 if (!t) return dist;
1268
1269 // Obtain a defined position on this jet
1270 AliPosition* rx=fRef;
1271
1272 if (!rx) return dist;
1273
1274 Ali3Vector pj=Get3Momentum();
1275
1276 if (pj.GetNorm() <= 0.) return dist;
1277
1278 AliTrack tj;
1279 tj.Set3Momentum(pj);
1280 tj.SetReferencePoint(*rx);
1281 dist=tj.GetDistance(t,scale);
1282 fDresult=tj.GetResultError();
1283 return dist;
1284}
1285///////////////////////////////////////////////////////////////////////////
1286Double_t AliJet::GetDistance(AliJet* j,Float_t scale)
1287{
1288// Provide distance of the current jet to the jet j.
1289// The error on the result can be obtained as usual by invoking
1290// GetResultError() afterwards.
1291//
1292// By default the distance will be provided in the metric unit scale of
1293// the current jet.
1294// This implies that the results of j1.GetDistance(j2) and j2.GetDistance(j1)
1295// may be numerically different in case j1 and j2 have different metric units.
1296// However, the user can specify a required metric unit scale by specification
1297// of the scale parameter.
1298// The convention is that scale=1 corresponds to meter, so specification
1299// of scale=0.01 will provide the distance in cm.
1300// As such it is possible to obtain a correctly computed distance even in case
1301// the jet parameters have a different unit scale.
1302// However, it is recommended to work always with one single unit scale.
1303//
1304// Note : In case of incomplete information, a distance value of -1 is
1305// returned.
1306
1307 Double_t dist=-1.;
1308 fDresult=0.;
1309
1310 if (!j) return dist;
1311
1312 // Obtain a defined position on jet j
1313 AliPosition* rx=j->GetReferencePoint();
1314
1315 if (!rx) return dist;
1316
1317 Ali3Vector pj=j->Get3Momentum();
1318
1319 if (pj.GetNorm() <= 0.) return dist;
1320
1321 AliTrack tj;
1322 tj.Set3Momentum(pj);
1323 tj.SetReferencePoint(*rx);
1324 dist=GetDistance(tj,scale);
1325 return dist;
1326}
1327///////////////////////////////////////////////////////////////////////////
1328Int_t AliJet::GetNsignals() const
1329{
1330// Provide the number of signals associated to the jet tracks.
1331// Note : Multiple occurrences of the same signal are only counted once.
1332
1333 if (fNtrk<1) return 0;
1334
1335 TObjArray arr;
1336
1337 Int_t n=0;
1338 AliTrack* tx=0;
1339 Int_t exists=0;
1340 for (Int_t i=1; i<=fNtrk; i++)
1341 {
1342 tx=GetTrack(i);
1343 for (Int_t j=1; j<=tx->GetNsignals(); j++)
1344 {
1345 AliSignal* sx=tx->GetSignal(j);
1346 if (!sx) continue;
1347 exists=0;
1348 for (Int_t k=0; k<arr.GetEntries(); k++)
1349 {
1350 if (sx==(AliSignal*)arr.At(k))
1351 {
1352 exists=1;
1353 break;
1354 }
1355 }
1356 if (!exists) arr.Add(sx);
1357 }
1358 }
1359 n=arr.GetEntries();
1360 return n;
1361}
1362///////////////////////////////////////////////////////////////////////////
1363void AliJet::SetEscale(Float_t scale)
1364{
1365// Indicate the energy/momentum scale as used by the user.
1366// The convention is that scale=1 indicates values in units
1367// of GeV, GeV/c or GeV/c**2.
1368// So, in case one decides to store values in units of MeV, MeV/c or MeV/c**2
1369// the scale indicator should be set to scale=0.001.
1370//
1371// By default scale=1 is set in the constructor.
1372
1373 if (scale>0)
1374 {
1375 fEscale=scale;
1376 }
1377 else
1378 {
1379 cout << " *AliJet::SetEscale* Invalid scale value : " << scale << endl;
1380 }
1381}
1382///////////////////////////////////////////////////////////////////////////
1383Float_t AliJet::GetEscale() const
1384{
1385// Provide the energy/momentum scale as used by the user.
1386// The convention is that scale=1 indicates values in units
1387// of GeV, GeV/c or GeV/c**2.
1388// So, a value of scale=0.001 indicates that energy/momentum values are
1389// stored in units of MeV, MeV/c or MeV/c**2.
1390 return fEscale;
1391}
1392///////////////////////////////////////////////////////////////////////////
1393TObject* AliJet::Clone(const char* name) const
1394{
1395// Make a deep copy of the current object and provide the pointer to the copy.
1396// This memberfunction enables automatic creation of new objects of the
1397// correct type depending on the object type, a feature which may be very useful
1398// for containers when adding objects in case the container owns the objects.
1399// This feature allows e.g. AliVertex to store either AliJet objects or
1400// objects derived from AliJet via the AddJet memberfunction, provided
1401// these derived classes also have a proper Clone memberfunction.
1402
1403 AliJet* jet=new AliJet(*this);
1404 if (name)
1405 {
1406 if (strlen(name)) jet->SetName(name);
1407 }
1408 return jet;
1409}
1410///////////////////////////////////////////////////////////////////////////