+void AliJet::SetReferencePoint(AliPosition& p)
+{
+// Store the position of the jet reference-point.
+// The reference-point of a jet provides a means to define a generic
+// space-time location for the jet as a whole.
+// This doesn't have to be necessarily the location where all the constituent
+// tracks originate (e.g. a bundle of parallel tracks doesn't have such
+// a location). As such the meaning of this reference-point is different from
+// a normal vertex position and allows to provide complimentary information.
+// This reference point is the preferable point to start e.g. extrapolations
+// and investigate coincidences in space and/or time.
+ if (fRef) delete fRef;
+ fRef=new AliPositionObj(p);
+}
+///////////////////////////////////////////////////////////////////////////
+AliPosition* AliJet::GetReferencePoint()
+{
+// Provide the position of the jet reference-point.
+// The reference-point of a jet provides a means to define a generic
+// space-time location for the jet as a whole.
+// This doesn't have to be necessarily the location where all the constituent
+// tracks originate (e.g. a bundle of parallel tracks doesn't have such
+// a location). As such the meaning of this reference-point is different from
+// a normal vertex position and allows to provide complimentary information.
+// This reference point is the preferable point to start e.g. extrapolations
+// and investigate coincidences in space and/or time.
+ return fRef;
+}
+///////////////////////////////////////////////////////////////////////////
+TObjArray* AliJet::SortTracks(Int_t mode,TObjArray* tracks)
+{
+// Order the references to an array of tracks by looping over the input array "tracks"
+// and checking the value of a certain observable.
+// The ordered array is returned as a TObjArray.
+// In case tracks=0 (default), the registered tracks of the current jet are used.
+// Note that the original track array is not modified.
+// Via the "mode" argument the user can specify the observable to be checked upon
+// and specify whether sorting should be performed in decreasing order (mode<0)
+// or in increasing order (mode>0).
+//
+// The convention for the observable selection is the following :
+// mode : 1 ==> Number of signals associated to the track
+// 2 ==> Track energy
+// 3 ==> Track momentum
+// 4 ==> Mass of the track
+// 5 ==> Transverse momentum of the track
+// 6 ==> Longitudinal momentum of the track
+// 7 ==> Transverse energy of the track
+// 8 ==> Longitudinal energy of the track
+// 9 ==> Transverse mass of the track
+// 10 ==> Track rapidity
+// 11 ==> Pseudo-rapidity of the track
+// 12 ==> Charge of the track
+// 13 ==> Probability of the track hypothesis
+//
+// The default is mode=-1.
+//
+// Note : This sorting routine uses a common area in memory, which is used
+// by various other sorting facilities as well.
+// This means that the resulting sorted TObjArray may be overwritten
+// when another sorting is invoked.
+// To retain the sorted list of pointers, the user is advised to copy
+// the pointers contained in the returned TObjArray into a private
+// TObjArray instance.
+
+ if (fSelected)
+ {
+ delete fSelected;
+ fSelected=0;
+ }
+
+ if (!tracks) tracks=fTracks;
+
+ if (!mode || abs(mode)>13 || !tracks) return fSelected;
+
+ Int_t ntracks=tracks->GetEntries();
+ if (!ntracks)
+ {
+ return fSelected;
+ }
+ else
+ {
+ fSelected=new TObjArray(ntracks);
+ }
+
+ Double_t val1,val2; // Values of the observable to be tested upon
+
+ Int_t nord=0;
+ for (Int_t i=0; i<ntracks; i++) // Loop over all tracks of the array
+ {
+ AliTrack* tx=(AliTrack*)tracks->At(i);
+
+ if (!tx) continue;
+
+ if (nord == 0) // store the first track at the first ordered position
+ {
+ nord++;
+ fSelected->AddAt(tx,nord-1);
+ continue;
+ }
+
+ for (Int_t j=0; j<=nord; j++) // put track in the right ordered position
+ {
+ if (j == nord) // track has smallest (mode<0) or largest (mode>0) observable value seen so far
+ {
+ nord++;
+ fSelected->AddAt(tx,j); // add track at the end
+ break; // go for next track
+ }
+
+ val1=0;
+ val2=0;
+
+ switch (abs(mode))
+ {
+ case 1:
+ val1=tx->GetNsignals();
+ val2=((AliTrack*)fSelected->At(j))->GetNsignals();
+ break;
+ case 2:
+ val1=tx->GetEnergy(1);
+ val2=((AliTrack*)fSelected->At(j))->GetEnergy(1);
+ break;
+ case 3:
+ val1=tx->GetMomentum(1);
+ val2=((AliTrack*)fSelected->At(j))->GetMomentum(1);
+ break;
+ case 4:
+ val1=tx->GetMass(1);
+ val2=((AliTrack*)fSelected->At(j))->GetMass(1);
+ break;
+ case 5:
+ val1=tx->GetPt(1);
+ val2=((AliTrack*)fSelected->At(j))->GetPt(1);
+ break;
+ case 6:
+ val1=tx->GetPl(1);
+ val2=((AliTrack*)fSelected->At(j))->GetPl(1);
+ break;
+ case 7:
+ val1=tx->GetEt(1);
+ val2=((AliTrack*)fSelected->At(j))->GetEt(1);
+ break;
+ case 8:
+ val1=tx->GetEl(1);
+ val2=((AliTrack*)fSelected->At(j))->GetEl(1);
+ break;
+ case 9:
+ val1=tx->GetMt(1);
+ val2=((AliTrack*)fSelected->At(j))->GetMt(1);
+ break;
+ case 10:
+ val1=tx->GetRapidity();
+ val2=((AliTrack*)fSelected->At(j))->GetRapidity();
+ break;
+ case 11:
+ val1=tx->GetPseudoRapidity();
+ val2=((AliTrack*)fSelected->At(j))->GetPseudoRapidity();
+ break;
+ case 12:
+ val1=tx->GetCharge();
+ val2=((AliTrack*)fSelected->At(j))->GetCharge();
+ break;
+ case 13:
+ val1=tx->GetProb();
+ val2=((AliTrack*)fSelected->At(j))->GetProb();
+ break;
+ }
+
+ if (mode<0 && val1 <= val2) continue;
+ if (mode>0 && val1 >= val2) continue;
+
+ nord++;
+ for (Int_t k=nord-1; k>j; k--) // create empty position
+ {
+ fSelected->AddAt(fSelected->At(k-1),k);
+ }
+ fSelected->AddAt(tx,j); // put track at empty position
+ break; // go for next track
+ }
+ }
+ return fSelected;
+}
+///////////////////////////////////////////////////////////////////////////
+Double_t AliJet::GetDistance(AliPosition* p,Float_t scale)
+{
+// Provide distance of the current jet to the position p.
+// The error on the result can be obtained as usual by invoking
+// GetResultError() afterwards.
+//
+// By default the distance will be provided in the metric unit scale of
+// the AliPosition p.
+// However, the user can select a different metric unit scale by
+// specification of the scale parameter.
+// The convention is that scale=1 corresponds to meter, so specification
+// of scale=0.01 will provide the distance in cm.
+// As such it is possible to obtain a correctly computed distance even in case
+// the jet parameters have a different unit scale.
+// However, it is recommended to work always with one single unit scale.
+//
+// Note : In case of incomplete information, a distance value of -1 is
+// returned.
+
+ Double_t dist=-1.;
+ fDresult=0.;
+
+ if (!p) return dist;
+
+ // Obtain a defined position on this jet
+ AliPosition* rx=fRef;
+
+ if (!rx) return dist;
+
+ Ali3Vector pj=Get3Momentum();
+
+ if (pj.GetNorm() <= 0.) return dist;
+
+ AliTrack tj;
+ tj.Set3Momentum(pj);
+ tj.SetReferencePoint(*rx);
+ dist=tj.GetDistance(p,scale);
+ fDresult=tj.GetResultError();
+ return dist;
+}
+///////////////////////////////////////////////////////////////////////////
+Double_t AliJet::GetDistance(AliTrack* t,Float_t scale)
+{
+// Provide distance of the current jet to the track t.
+// The error on the result can be obtained as usual by invoking
+// GetResultError() afterwards.
+//
+// By default the distance will be provided in the metric unit scale of
+// the current jet.
+// However, the user can specify a required metric unit scale by specification
+// of the scale parameter.
+// The convention is that scale=1 corresponds to meter, so specification
+// of scale=0.01 will provide the distance in cm.
+// As such it is possible to obtain a correctly computed distance even in case
+// the jet and track parameters have a different unit scale.
+// However, it is recommended to work always with one single unit scale.
+//
+// Note : In case of incomplete information, a distance value of -1 is
+// returned.
+
+ Double_t dist=-1.;
+ fDresult=0.;
+
+ if (!t) return dist;
+
+ // Obtain a defined position on this jet
+ AliPosition* rx=fRef;
+
+ if (!rx) return dist;
+
+ Ali3Vector pj=Get3Momentum();
+
+ if (pj.GetNorm() <= 0.) return dist;
+
+ AliTrack tj;
+ tj.Set3Momentum(pj);
+ tj.SetReferencePoint(*rx);
+ dist=tj.GetDistance(t,scale);
+ fDresult=tj.GetResultError();
+ return dist;
+}
+///////////////////////////////////////////////////////////////////////////
+Double_t AliJet::GetDistance(AliJet* j,Float_t scale)
+{
+// Provide distance of the current jet to the jet j.
+// The error on the result can be obtained as usual by invoking
+// GetResultError() afterwards.
+//
+// By default the distance will be provided in the metric unit scale of
+// the current jet.
+// This implies that the results of j1.GetDistance(j2) and j2.GetDistance(j1)
+// may be numerically different in case j1 and j2 have different metric units.
+// However, the user can specify a required metric unit scale by specification
+// of the scale parameter.
+// The convention is that scale=1 corresponds to meter, so specification
+// of scale=0.01 will provide the distance in cm.
+// As such it is possible to obtain a correctly computed distance even in case
+// the jet parameters have a different unit scale.
+// However, it is recommended to work always with one single unit scale.
+//
+// Note : In case of incomplete information, a distance value of -1 is
+// returned.
+
+ Double_t dist=-1.;
+ fDresult=0.;
+
+ if (!j) return dist;
+
+ // Obtain a defined position on jet j
+ AliPosition* rx=j->GetReferencePoint();
+
+ if (!rx) return dist;
+
+ Ali3Vector pj=j->Get3Momentum();
+
+ if (pj.GetNorm() <= 0.) return dist;
+
+ AliTrack tj;
+ tj.Set3Momentum(pj);
+ tj.SetReferencePoint(*rx);
+ dist=GetDistance(tj,scale);
+ return dist;
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t AliJet::GetNsignals() const
+{
+// Provide the number of signals associated to the jet tracks.
+// Note : Multiple occurrences of the same signal are only counted once.
+
+ if (fNtrk<1) return 0;
+
+ TObjArray arr;
+
+ Int_t n=0;
+ AliTrack* tx=0;
+ Int_t exists=0;
+ for (Int_t i=1; i<=fNtrk; i++)
+ {
+ tx=GetTrack(i);
+ for (Int_t j=1; j<=tx->GetNsignals(); j++)
+ {
+ AliSignal* sx=tx->GetSignal(j);
+ if (!sx) continue;
+ exists=0;
+ for (Int_t k=0; k<arr.GetEntries(); k++)
+ {
+ if (sx==(AliSignal*)arr.At(k))
+ {
+ exists=1;
+ break;
+ }
+ }
+ if (!exists) arr.Add(sx);
+ }
+ }
+ n=arr.GetEntries();
+ return n;
+}
+///////////////////////////////////////////////////////////////////////////
+void AliJet::SetEscale(Float_t scale)
+{
+// Indicate the energy/momentum scale as used by the user.
+// The convention is that scale=1 indicates values in units
+// of GeV, GeV/c or GeV/c**2.
+// So, in case one decides to store values in units of MeV, MeV/c or MeV/c**2
+// the scale indicator should be set to scale=0.001.
+//
+// By default scale=1 is set in the constructor.
+
+ if (scale>0)
+ {
+ fEscale=scale;
+ }
+ else
+ {
+ cout << " *AliJet::SetEscale* Invalid scale value : " << scale << endl;
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+Float_t AliJet::GetEscale() const
+{
+// Provide the energy/momentum scale as used by the user.
+// The convention is that scale=1 indicates values in units
+// of GeV, GeV/c or GeV/c**2.
+// So, a value of scale=0.001 indicates that energy/momentum values are
+// stored in units of MeV, MeV/c or MeV/c**2.
+ return fEscale;
+}
+///////////////////////////////////////////////////////////////////////////
+TObject* AliJet::Clone(const char* name) const
+{
+// Make a deep copy of the current object and provide the pointer to the copy.
+// This memberfunction enables automatic creation of new objects of the
+// correct type depending on the object type, a feature which may be very useful
+// for containers when adding objects in case the container owns the objects.
+// This feature allows e.g. AliVertex to store either AliJet objects or
+// objects derived from AliJet via the AddJet memberfunction, provided
+// these derived classes also have a proper Clone memberfunction.
+
+ AliJet* jet=new AliJet(*this);
+ if (name)
+ {
+ if (strlen(name)) jet->SetName(name);
+ }
+ return jet;
+}
+///////////////////////////////////////////////////////////////////////////