#include <Riostream.h>
#include "AliLog.h"
+#include "AliVEvent.h"
+#include "AliESDEvent.h"
+#include "AliAODEvent.h"
+#include "AliMCEvent.h"
+#include "AliStack.h"
-#include "AliRsnDaughter.h"
#include "AliRsnEvent.h"
-#include "AliRsnMCInfo.h"
ClassImp(AliRsnEvent)
//_____________________________________________________________________________
-AliRsnEvent::AliRsnEvent() :
- TNamed("rsnEvent", ""),
- fPVx(0.0),
- fPVy(0.0),
- fPVz(0.0),
- fTracks(0x0),
- fNoPID(0x0),
- fPerfectPID(0x0),
- fRealisticPID(0x0)
+AliRsnEvent::AliRsnEvent(AliVEvent *ref, AliMCEvent *refMC) :
+ fRef(ref),
+ fRefMC(refMC)
{
//
// Default constructor
-// (implemented but not recommended for direct use)
//
}
//_____________________________________________________________________________
AliRsnEvent::AliRsnEvent(const AliRsnEvent &event) :
- TNamed(event),
- fPVx(event.fPVx),
- fPVy(event.fPVy),
- fPVz(event.fPVz),
- fTracks(0x0),
- fNoPID(0x0),
- fPerfectPID(0x0),
- fRealisticPID(0x0)
+ TObject(event),
+ fRef(event.fRef),
+ fRefMC(event.fRefMC)
+
{
//
// Copy constructor.
-// Copies all the tracks from the argument's collection
-// to this' one, and then recreates the PID index arrays,
-// trusting on the PID informations in the copied tracks.
//
-
- // during track copy, counts how many faults happen
- Int_t errors = Fill(event.fTracks);
- if (errors) AliWarning(Form("%d errors occurred in copy", errors));
-
- // fill PID index arrays
- // FillPIDArrays();
-
- if (event.fNoPID) fNoPID = new AliRsnPIDIndex(* (event.fNoPID));
- if (event.fPerfectPID) fPerfectPID = new AliRsnPIDIndex(* (event.fPerfectPID));
- if (event.fRealisticPID) fRealisticPID = new AliRsnPIDIndex(* (event.fRealisticPID));
}
//_____________________________________________________________________________
//
// Works in the same way as the copy constructor.
//
- // copy name and title
- SetName(event.GetName());
- SetTitle(event.GetTitle());
-
- // copy primary vertex and initialize track counter to 0
- fPVx = event.fPVx;
- fPVy = event.fPVy;
- fPVz = event.fPVz;
-
- // add tracks from array of argument
- Int_t errors = Fill(event.fTracks);
- if (errors) AliWarning(Form("%d errors occurred in copy", errors));
-
- // fill PID arrays
- // FillPIDArrays();
- if (event.fNoPID)
- {
- if (!fNoPID) fNoPID = new AliRsnPIDIndex(* (event.fNoPID));
- else (*fNoPID) = * (event.fNoPID);
- }
- if (event.fPerfectPID)
- {
- if (!fPerfectPID) fPerfectPID = new AliRsnPIDIndex(* (event.fPerfectPID));
- else (*fPerfectPID) = * (event.fPerfectPID);
- }
- if (event.fRealisticPID)
- {
- if (!fRealisticPID) fRealisticPID = new AliRsnPIDIndex(* (event.fRealisticPID));
- else (*fRealisticPID) = * (event.fRealisticPID);
- }
- // return this object
+ (TObject)(*this) = (TObject)event;
+ fRef = event.fRef;
+ fRefMC = event.fRefMC;
+
return (*this);
}
{
//
// Destructor.
-// Deletes the TClonesArray, after clearing its content.
-// Other memory-allocating arrays are cleared by their
-// destructor, which is automatically called from here.
-//
-
- Clear();
- if (fTracks) delete fTracks;
-}
-
-//_____________________________________________________________________________
-void AliRsnEvent::Init()
-{
-//
-// Initialize TClonesArray data-member.
-//
-
- fTracks = new TClonesArray("AliRsnDaughter", 1);
- //fTracks->BypassStreamer (kFALSE);
-}
-
-//_____________________________________________________________________________
-void AliRsnEvent::Clear(Option_t* /*option*/)
-{
-//
-// Empties the collections (does not delete the objects).
-// The track collection is emptied only at the end.
-// Since some objects could be uninitialized, some
-// "if" statement are used.
//
-
- if (fTracks) fTracks->Delete();
- delete fNoPID;
- fNoPID = 0x0;
- delete fPerfectPID;
- fPerfectPID = 0x0;
- delete fRealisticPID;
- fRealisticPID = 0x0;
}
//_____________________________________________________________________________
-AliRsnDaughter* AliRsnEvent::AddTrack(AliRsnDaughter track)
+void AliRsnEvent::SetDaughter(AliRsnDaughter &out, Int_t i)
{
//
-// Stores a new track into the array and returns
-// a reference pointer to it (which is NULL in case of errors).
+// Return a track stored here in format of AliRsnDaughter.
+// and finds in the reference event the informations to set
+// the proprietary data members of AliRsnDaughter
//
- Int_t nextIndex = fTracks->GetEntriesFast();
- TClonesArray &tracks = (*fTracks);
- AliRsnDaughter *copy = new(tracks[nextIndex]) AliRsnDaughter(track);
- return copy;
-}
+ // retrieve reference particle from reference event
+ AliVParticle *ref = (AliVParticle*)fRef->GetTrack(i);
-//_____________________________________________________________________________
-AliRsnDaughter* AliRsnEvent::GetTrack(Int_t index)
-{
-//
-// Returns one track in the collection
-// given the absolute index in the global TClonesArray
-//
- return (AliRsnDaughter*) fTracks->UncheckedAt(index);
-}
+ if (!ref) return;
-//_____________________________________________________________________________
-AliRsnDaughter* AliRsnEvent::GetLeadingParticle
-(Double_t ptMin, AliRsnPID::EType type, Bool_t realistic)
-{
-//
-// Returns the particle in this event with largest transverse momentum,
-// provided that this momentum is larger than the first argument
-// and that the PID type correspond to the second argument.
-// If one specifies "AliRsnPID::kUnknown" as second arguments, the PID check is not done.
-//
+ // if MC info is present, retrieve from it
+ TParticle *refMC = 0;
+ if (fRefMC) {
+ Int_t label = TMath::Abs(ref->GetLabel());
+ refMC = fRefMC->Stack()->Particle(label);
+ }
- Double_t prob;
- AliRsnPID::EType trackType;
- AliRsnDaughter *track, *leading = 0x0;
- TObjArrayIter iter(fTracks);
- while ((track = (AliRsnDaughter*) iter.Next()))
- {
- if (track->Pt() < ptMin) continue;
- if (realistic)
- {
- AliRsnDaughter::SetPIDMethod(AliRsnDaughter::kRealistic);
- }
- else
- {
- AliRsnDaughter::SetPIDMethod(AliRsnDaughter::kPerfect);
- }
- trackType = track->PIDType(prob);
- if (type != AliRsnPID::kUnknown && trackType != type) continue;
- ptMin = track->Pt();
- leading = track;
+ // create output object
+ out.SetRef(ref);
+ out.SetGood();
+ out.SetParticle(refMC);
+ if (fRefMC)
+ out.FindMotherPDG(fRefMC->Stack());
+
+ // retrieve primary vertex and set impact parameters
+ Double_t dx = out.Xv(), dy = out.Yv(), dz = out.Zv();
+ const AliVVertex *v = fRef->GetPrimaryVertex();
+ if (v) {
+ dx -= v->GetX();
+ dy -= v->GetY();
+ dz -= v->GetZ();
+ }
+ out.SetDr(TMath::Sqrt(dx*dx + dy*dy));
+ out.SetDz(dz);
+
+ // dynamic reference to true nature of referenced event
+ // to get kink index
+ AliESDEvent *esd = dynamic_cast<AliESDEvent*>(fRef);
+ AliAODEvent *aod = dynamic_cast<AliAODEvent*>(fRef);
+
+ if (esd) {
+ AliESDtrack *esdTrack = esd->GetTrack(i);
+ out.FindKinkIndex(esdTrack);
+ } else if (aod) {
+ out.FindKinkIndex(aod);
}
- return leading;
+ out.SetGood();
}
//_____________________________________________________________________________
-Int_t AliRsnEvent::GetLastFastTrack
-(Double_t ptMin, AliRsnPID::EType type, Bool_t realistic)
+AliRsnDaughter AliRsnEvent::GetDaughter(Int_t i)
{
//
-// Loops on the list of tracks (eventually skipping the ones which do not match
-// the given PID type with the specified PID method) and returns the index of the last
-// one whose transverse momentum is still larger than a specified value.
-// When no tracks are found this way, the value "-1" is returned.
+// Return an AliRsnDaughter taken from this event,
+// with all additional data members well set.
//
- if (realistic)
- {
- AliRsnDaughter::SetPIDMethod(AliRsnDaughter::kRealistic);
- }
- else
- {
- AliRsnDaughter::SetPIDMethod(AliRsnDaughter::kPerfect);
- }
+ AliRsnDaughter out;
+ SetDaughter(out, i);
- Double_t prob;
- Int_t i, nTracks = fTracks->GetEntries(), lastIndex = -1;
- for (i = 0; i < nTracks; i++)
- {
- AliRsnDaughter *d = (AliRsnDaughter*) fTracks->At(i);
- AliRsnPID::EType trackType = d->PIDType(prob);
- if (type != AliRsnPID::kUnknown && trackType != type) continue;
- if (d->Pt() >= ptMin) lastIndex = i;
- }
-
- return lastIndex;
+ return out;
}
//_____________________________________________________________________________
-TArrayI* AliRsnEvent::GetCharged(Char_t sign)
+Int_t AliRsnEvent::GetMultiplicity()
{
//
-// Returns an array with the indexes of all tracks with a given charge
-// (arg can be '+' or '-'), irrespective of its PID.
-// When the argument is wrong, a NULL pointer is returned.
+// Returns event multiplicity
//
- if (fNoPID) return fNoPID->GetTracksArray(sign, AliRsnPID::kUnknown);
- return 0x0;
+ AliDebug(AliLog::kDebug+2,"<-");
+ if (!fRef) return 0;
+ AliDebug(AliLog::kDebug+2,"->");
+ return fRef->GetNumberOfTracks();
}
//_____________________________________________________________________________
-TArrayI * AliRsnEvent::GetTracksArray
-(AliRsnDaughter::EPIDMethod pidtype, Char_t sign, AliRsnPID::EType type)
+Double_t AliRsnEvent::GetVz()
{
//
-// Returns an array of indexes of all tracks in this event
-// which match the charge sign and PID type in the arguments,
-// according to one of the allowed PID methods (perfect or realistic).
-// It retrieves this array from the AliRsnPIDIndex data members.
-// If the arguments are wrong a NULL pointer is returned.
+// Return Z coord of primary vertex
//
-
- switch (pidtype)
- {
- case AliRsnDaughter::kRealistic:
- if (fRealisticPID)
- {
- return fRealisticPID->GetTracksArray(sign, type);
- }
- break;
- case AliRsnDaughter::kPerfect:
- if (fPerfectPID)
- {
- return fPerfectPID->GetTracksArray(sign, type);
- }
- break;
- case AliRsnDaughter::kNoPID:
- if (fNoPID)
- {
- return fNoPID->GetTracksArray(sign, AliRsnPID::kUnknown);
- }
- break;
- default:
- AliError("Handled PID methods here are only fNoPID,kPerfect and kRealistic. Nothing done.");
- return 0x0;
- }
- return 0x0;
+ AliDebug(AliLog::kDebug+2,"<-");
+ return fRef->GetPrimaryVertex()->GetZ();
+ AliDebug(AliLog::kDebug+2,"->");
}
//_____________________________________________________________________________
-void AliRsnEvent::FillPIDArrays(Int_t arraySizeInit)
+AliRsnDaughter AliRsnEvent::GetLeadingParticle
+(Double_t ptMin, AliPID::EParticleType type)
{
//
-// Initializes and fills the AliRsnPIDIndex objects containing
-// arrays of indexes for each possible charge and PID type.
-// This method is the unique way to do this, for safety reasons.
+// Searches the collection of all particles with given PID type and charge,
+// and returns the one with largest momentum, provided that it is greater than 1st argument.
+// If one specifies AliRsnPID::kUnknown as type or AliRsnDaughter::kNoPID as method,
+// the check is done over all particles irrespectively of their PID.
+// If the sign argument is '+' or '-', the check is done over the particles of that charge,
+// otherwise it is done irrespectively of the charge.
//
- if (fNoPID) delete fNoPID;
- if (fPerfectPID) delete fPerfectPID;
- if (fRealisticPID) delete fRealisticPID;
- fNoPID = new AliRsnPIDIndex(arraySizeInit);
- fPerfectPID = new AliRsnPIDIndex(arraySizeInit);
- fRealisticPID = new AliRsnPIDIndex(arraySizeInit);
-
- // set the default type to Realistic
- AliRsnDaughter::SetPIDMethod(AliRsnDaughter::kRealistic);
-
- // loop on tracks and create references
- Double_t prob;
- Int_t i, icharge, type;
- Short_t charge;
- AliRsnMCInfo *mcinfo = 0;
- AliRsnDaughter *track = 0;
- TObjArrayIter iter(fTracks);
- while ((track = (AliRsnDaughter*) iter.Next()))
- {
- charge = track->Charge();
- type = (Int_t) track->PIDType(prob);
- i = fTracks->IndexOf(track);
- mcinfo = track->GetMCInfo();
- if (charge > 0) icharge = 0;
- else if (charge < 0) icharge = 1;
- else
- {
- AliError("Found particle with ZERO charge!!!");
- continue;
- }
- // add to charged array
- fNoPID->AddIndex(i, icharge, (Int_t) AliRsnPID::kUnknown);
- // add to realistic PID array
- fRealisticPID->AddIndex(i, icharge, (Int_t) type);
- // add to perfect PID array (needs MCInfo present)
- if (mcinfo)
- {
- fPerfectPID->AddIndex(i, icharge, (Int_t) AliRsnPID::InternalType(mcinfo->PDG()));
+ Int_t i, nTracks = fRef->GetNumberOfTracks();
+ AliRsnDaughter output;
+
+ for (i = 0; i < nTracks; i++) {
+ AliRsnDaughter track = GetDaughter(i);
+ if (!AcceptTrackPID(&track, type)) continue;
+ if (track.Pt() < ptMin) continue;
+ if (!output.IsOK() || track.Pt() > output.Pt()) {
+ output = track;
+ output.SetGood();
}
}
- // adjusts the size of arrays
- if (fNoPID) fNoPID->SetCorrectIndexSize();
- if (fPerfectPID) fPerfectPID->SetCorrectIndexSize();
- if (fRealisticPID) fRealisticPID->SetCorrectIndexSize();
+ return output;
}
-//_____________________________________________________________________________
-void AliRsnEvent::Print(Option_t *option) const
+//_________________________________________________________________________________________________
+Double_t AliRsnEvent::GetAverageMomentum(Int_t &count, AliPID::EParticleType type)
{
//
-// Lists the details of the event, and the ones of each
-// contained track.
-// The options are passed to AliRsnDaughter::Print().
-// Look at that method to understand option values.
+// Loops on the list of tracks and computes average total momentum.
//
- cout << "...Multiplicity : " << fTracks->GetEntries() << endl;
- cout << "...Primary vertex : " << fPVx << ' ' << fPVy << ' ' << fPVz << endl;
+ Int_t i, nTracks = fRef->GetNumberOfTracks();
+ Double_t pmean = 0.0;
- TObjArrayIter iter(fTracks);
- AliRsnDaughter *d = 0;
- while ((d = (AliRsnDaughter*) iter.Next()))
- {
- cout << "....Track #" << fTracks->IndexOf(d) << endl;
- d->Print(option);
+ for (i = 0, count = 0; i < nTracks; i++) {
+ AliRsnDaughter track = GetDaughter(i);
+ if (!AcceptTrackPID(&track, type)) continue;
+ pmean += track.P();
+ count++;
}
-}
-//_____________________________________________________________________________
-void AliRsnEvent::MakeComputations()
-{
-//
-// Computes all required overall variables:
-// - multiplicity
-// - mean phi of tracks
-//
+ if (count > 0) pmean /= (Double_t)count;
+ else pmean = 0.0;
- if (!fTracks) {
- fMult = 0;
- fPhiMean = 0.0;
- }
- else {
- fMult = fTracks->GetEntries();
- fPhiMean = 0.0;
-
- AliRsnDaughter *d = 0;
- TObjArrayIter next(fTracks);
- while ( (d = (AliRsnDaughter*)next()) ) {
- fPhiMean += d->Phi();
- }
- fPhiMean /= (Double_t)fMult;
- }
+ return pmean;
}
//_____________________________________________________________________________
-void AliRsnEvent::CorrectByPrimaryVertex()
+Bool_t AliRsnEvent::GetAngleDistr
+(Double_t &angleMean, Double_t &angleRMS, AliRsnDaughter leading)
{
//
-// Corrects the X,Y,Z position of DCA vertex of all tracks
-// by the amount of stored primary vertex
+// Takes the leading particle and computes the mean and RMS
+// of the distribution of directions of all other tracks
+// with respect to the direction of leading particle.
//
- TObjArrayIter iter(fTracks);
- AliRsnDaughter *d = 0;
- while ((d = (AliRsnDaughter*) iter.Next())) {
- d->ShiftZero(fPVx, fPVy, fPVz);
- }
-}
+ if (!leading.IsOK()) return kFALSE;
-/*
-//_____________________________________________________________________________
-Int_t AliRsnEvent::GetMultiplicity() const
-{
-//
-// Get number of all tracks
-//
+ Int_t i, count, nTracks = fRef->GetNumberOfTracks();
+ Double_t angle, angle2Mean = 0.0;
- if (!fTracks) return 0;
- return fTracks->GetEntries();
-}
-*/
+ angleMean = angle2Mean = 0.0;
-//_____________________________________________________________________________
-Int_t AliRsnEvent::GetNCharged(Char_t sign)
-{
-//
-// Get number of charged tracks
-//
+ for (i = 0, count = 0; i < nTracks; i++) {
+ AliRsnDaughter trk = GetDaughter(i);
+ if (trk.GetID() == leading.GetID()) continue;
- Int_t icharge;
- icharge = ChargeIndex(sign);
- if (icharge < 0) return 0;
- TArrayI *charged = GetCharged(sign);
- if (!charged) return 0;
- return charged->GetSize();
-}
+ angle = leading.AngleTo(trk);
-//_____________________________________________________________________________
-Int_t AliRsnEvent::Fill(TObjArray *array)
-{
-//
-// Fills the data-member TClonesArray of tracks with
-// the ones stored in the array passed as argument.
-// If this data-member is already present, it is cleared.
-// Returns the number of tracks which raised problems
-// while attempting to add them. Zero is the best.
-//
-
- // clear the array if it is already instantiated,
- // create if otherwise
- if (fTracks) fTracks->Delete();
- else Init();
-
- // copy argument entries into data-member
- Int_t errors = 0;
- AliRsnDaughter *track = 0;
- TObjArrayIter iter(array);
- while ((track = (AliRsnDaughter*) iter.Next()))
- {
- AliRsnDaughter *ref = AddTrack(*track);
- if (!ref)
- {
- AliWarning(Form("Problem occurred when copying track #%d from passed array", array->IndexOf(track)));
- errors++;
- }
+ angleMean += angle;
+ angle2Mean += angle * angle;
+ count++;
}
- return errors;
+ if (!count) return kFALSE;
+
+ angleMean /= (Double_t)count;
+ angle2Mean /= (Double_t)count;
+ angleRMS = TMath::Sqrt(angle2Mean - angleMean*angleMean);
+
+ return kTRUE;
}
//_____________________________________________________________________________
-Int_t AliRsnEvent::ChargeIndex(Char_t sign) const
+Bool_t AliRsnEvent::AcceptTrackPID
+(AliRsnDaughter *d, AliPID::EParticleType type)
+{
//
-// Returns the array index corresponding to charge
-// 0 for positive, 1 for negative
+// [PRIVATE]
+// Checks if the track PID (according to method in use) corresponds
+// to the required identification species.
+// If the second argument is "kUnknown", answer of this method is always YES.
//
-{
- if (sign == '+') return 0;
- else if (sign == '-') return 1;
- else
- {
- AliError(Form("Character '%c' not recognized as charge sign", sign));
- return -1;
- }
+
+ if (type == AliPID::kUnknown) return kTRUE;
+
+ return (d->AssignedPID() == type);
}