]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWG2/RESONANCES/AliRsnEvent.cxx
Update to the analysis on MC data only.
[u/mrichter/AliRoot.git] / PWG2 / RESONANCES / AliRsnEvent.cxx
index 396ff1906826e6c9a0bb7072da58e36182951b51..485987a21fcc79230fd0a4029a02278976216595 100644 (file)
@@ -1,18 +1,3 @@
-/**************************************************************************
- * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- *                                                                        *
- * Author: The ALICE Off-line Project.                                    *
- * Contributors are mentioned in the code where appropriate.              *
- *                                                                        *
- * Permission to use, copy, modify and distribute this software and its   *
- * documentation strictly for non-commercial purposes is hereby granted   *
- * without fee, provided that the above copyright notice appears in all   *
- * copies and that both the copyright notice and this permission notice   *
- * appear in the supporting documentation. The authors make no claims     *
- * about the suitability of this software for any purpose. It is          *
- * provided "as is" without express or implied warranty.                  *
- **************************************************************************/
-
 //
 // *** Class AliRsnEvent ***
 //
 //          M. Vala (email: martin.vala@cern.ch)
 //
 
-#include <Riostream.h>
+#include <TArrayF.h>
 
 #include "AliLog.h"
+#include "AliVEvent.h"
+#include "AliMCEvent.h"
+#include "AliStack.h"
+#include "AliGenEventHeader.h"
+#include "AliRsnCutPID.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),
+  fLeading(-1)
 {
 //
-// Default constructor
-// (implemented but not recommended for direct use)
+// Default constructor.
 //
 }
 
 //_____________________________________________________________________________
 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),
+  fLeading(event.fLeading)
 {
 //
 // 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));
 }
 
 //_____________________________________________________________________________
-AliRsnEvent& AliRsnEvent::operator= (const AliRsnEvent &event)
+AliRsnEvent& AliRsnEvent::operator= (const AliRsnEvent & event)
 {
 //
 // 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;
+  fLeading         = event.fLeading;
+
   return (*this);
 }
 
@@ -129,385 +67,330 @@ AliRsnEvent::~AliRsnEvent()
 {
 //
 // 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()
+Bool_t AliRsnEvent::SetDaughter(AliRsnDaughter &out, Int_t i, AliRsnDaughter::ERefType type)
 {
 //
-// Initialize TClonesArray data-member.
+// Using the second and third arguments, retrieves the i-th object in the
+// appropriate sample (tracks or V0s) and sets the firs reference object
+// in order to point to that.
+// If a MonteCarlo information is provided, sets the useful informations from there,
+// and in case of a V0, sets the 'label' data member only when the two daughters
+// of the V0 point to the same mother.
+// Returns kFALSE whenever the operation fails (out of range, NULL references).
 //
 
-  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)
-{
-//
-// Stores a new track into the array and returns
-// a reference pointer to it (which is NULL in case of errors).
-//
-
-  Int_t nextIndex = fTracks->GetEntriesFast();
-  TClonesArray &tracks = (*fTracks);
-  AliRsnDaughter *copy = new(tracks[nextIndex]) AliRsnDaughter(track);
-  return copy;
-}
-
-//_____________________________________________________________________________
-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);
-}
+  Int_t label;
 
-//_____________________________________________________________________________
-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.
-//
-
-  Double_t prob;
-  AliRsnPID::EType trackType;
-  AliRsnDaughter *track, *leading = 0x0;
-  TObjArrayIter iter(fTracks);
-  while ((track = (AliRsnDaughter*) iter.Next()))
+  // retrieve reference particle from reference event
+  // if it is found, by defaul track can be used (good)
+  if (type == AliRsnDaughter::kTrack)
   {
-    if (track->Pt() < ptMin) continue;
-    if (realistic)
+    if (i >= fRef->GetNumberOfTracks())
+    {
+      out.SetBad();
+      return kFALSE;
+    }
+    AliVTrack *track = (AliVTrack*)fRef->GetTrack(i);
+    label = TMath::Abs(track->GetLabel());
+    if (!track)
     {
-      AliRsnDaughter::SetPIDMethod(AliRsnDaughter::kRealistic);
+      out.SetBad();
+      return kFALSE;
     }
     else
     {
-      AliRsnDaughter::SetPIDMethod(AliRsnDaughter::kPerfect);
+      out.SetRef(track);
+      out.SetLabel(label);
+      if (fRefMC)
+      {
+        if (label < fRefMC->GetNumberOfTracks()) 
+        {
+          AliMCParticle *part = (AliMCParticle*)fRefMC->GetTrack(label);
+          out.SetRefMC(part);
+        }
+      }
+      out.SetGood();
     }
-    trackType = track->PIDType(prob);
-    if (type != AliRsnPID::kUnknown && trackType != type) continue;
-    ptMin = track->Pt();
-    leading = track;
   }
+  else if (type == AliRsnDaughter::kV0)
+  {
+    if (i > fRef->GetNumberOfV0s())
+    {
+      out.SetBad();
+      return kFALSE;
+    }
+    AliESDv0     *esdV = 0x0;
+    AliAODv0     *aodV = 0x0;
+    Int_t         lp, ln;
+    AliVTrack    *tp = 0x0, *tn = 0x0;
+    if (IsESD()) esdV = GetRefESD()->GetV0(i);
+    if (IsAOD()) aodV = GetRefAOD()->GetV0(i);
+    if (!esdV && !aodV)
+    {
+      out.SetBad();
+      return kFALSE;
+    }
+    else
+    {
+      if (esdV) out.SetRef(esdV); else out.SetRef(aodV);
+      // retrieve the V0 daughters, which must be done differently with ESD and AOD v0s
+      if (esdV)
+      {
+        // get the 2 daughters of the V0
+        AliESDEvent *ev = dynamic_cast<AliESDEvent*>(fRef);
+        tp = ev->GetTrack(esdV->GetPindex());
+        tn = ev->GetTrack(esdV->GetNindex());
+      }
+      else if (aodV)
+      {
+        // get the 2 daughters of the V0
+        AliAODEvent *ev = dynamic_cast<AliAODEvent*>(fRef);
+        tp = ev->GetTrack(aodV->GetPosID());
+        tn = ev->GetTrack(aodV->GetNegID());
+      }
 
-  return leading;
+      // now, if we have a MC, use the two track objects
+      // to retrieve the true particle which generated the V0
+      // using their labels; by default they are a false V0 with label -1
+      label = -1;
+      if (tp && tn && fRefMC)
+      {
+        lp = TMath::Abs(tp->GetLabel());
+        ln = TMath::Abs(tn->GetLabel());
+        // if labels are meaningful, retrieve corresponding particles
+        TParticle *pp = fRefMC->Stack()->Particle(lp);
+        TParticle *pn = fRefMC->Stack()->Particle(ln);
+        // if their first mothers are the same, the V0 is true
+        // otherwise no label can be assigned
+        if (pp->GetFirstMother() == pn->GetFirstMother()) label = pp->GetFirstMother();
+      }
+      out.SetLabel(label);
+      out.SetGood();
+    }
+  }
+  
+  // finally, in case we have a MC, searches for the mother, in order to store
+  // its PDG code into the output AliRsnDaughter
+  if (fRefMC)
+  {
+    label = out.GetLabel();
+    AliStack *stack = fRefMC->Stack();
+    if (label >= 0 && label < stack->GetNtrack())
+    {
+      TParticle *part = stack->Particle(label);
+      if (part)
+      {
+        Int_t imum = part->GetFirstMother();
+        if (imum >= 0 && imum <= stack->GetNtrack())
+        {
+          TParticle *mum = stack->Particle(imum);
+          if (mum) out.SetMotherPDG(TMath::Abs(mum->GetPdgCode()));
+        }
+      }
+    }
+  }
+  
+  return kTRUE;
 }
 
 //_____________________________________________________________________________
-Int_t AliRsnEvent::GetLastFastTrack
-(Double_t ptMin, AliRsnPID::EType type, Bool_t realistic)
+Bool_t AliRsnEvent::SetDaughterMC(AliRsnDaughter &out, 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.
+// Using the second argument, retrieves the i-th object in the
+// appropriate sample and sets the firs reference object
+// in order to point to that.
+// If a MonteCarlo information is provided, sets the useful informations from there,
+// and in case of a V0, sets the 'label' data member only when the two daughters
+// of the V0 point to the same mother.
+// Returns kFALSE whenever the operation fails (out of range, NULL references).
 //
 
-  if (realistic)
+  if (!fRefMC)
+  {
+    out.SetBad();
+    return kFALSE;
+  }
+
+  if (i >= fRefMC->GetNumberOfTracks())
+  {
+    out.SetBad();
+    return kFALSE;
+  }
+  
+  AliMCParticle *track = (AliMCParticle*)fRef->GetTrack(i);
+  if (!track)
   {
-    AliRsnDaughter::SetPIDMethod(AliRsnDaughter::kRealistic);
+    out.SetBad();
+    return kFALSE;
   }
   else
   {
-    AliRsnDaughter::SetPIDMethod(AliRsnDaughter::kPerfect);
+    out.SetRef(track);
+    out.SetRefMC(track);
+    out.SetLabel(i);
+    out.SetGood();
   }
-
-  Double_t prob;
-  Int_t i, nTracks = fTracks->GetEntries(), lastIndex = -1;
-  for (i = 0; i < nTracks; i++)
+  
+  AliStack  *stack = fRefMC->Stack();
+  TParticle *part  = track->Particle();
+  if (part)
   {
-    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;
+    Int_t imum = part->GetFirstMother();
+    if (imum >= 0 && imum <= stack->GetNtrack())
+    {
+      TParticle *mum = stack->Particle(imum);
+      if (mum) out.SetMotherPDG(TMath::Abs(mum->GetPdgCode()));
+    }
   }
-
-  return lastIndex;
+  
+  return kTRUE;
 }
 
 //_____________________________________________________________________________
-TArrayI* AliRsnEvent::GetCharged(Char_t sign)
+AliRsnDaughter AliRsnEvent::GetDaughter(Int_t i, AliRsnDaughter::ERefType type)
 {
 //
-// 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.
+// Return an AliRsnDaughter taken from this event,
+// with all additional data members well set.
 //
-  if (fNoPID) return fNoPID->GetTracksArray(sign, AliRsnPID::kUnknown);
-  return 0x0;
+
+  AliRsnDaughter out;
+  SetDaughter(out, i, type);
+
+  return out;
 }
 
 //_____________________________________________________________________________
-TArrayI * AliRsnEvent::GetTracksArray
-(AliRsnDaughter::EPIDMethod pidtype, Char_t sign, AliRsnPID::EType type)
+AliRsnDaughter AliRsnEvent::GetDaughterMC(Int_t i)
 {
 //
-// 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 an AliRsnDaughter taken from this event,
+// with all additional data members well set.
 //
 
-  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;
+  AliRsnDaughter out;
+  SetDaughterMC(out, i);
+
+  return out;
 }
 
 //_____________________________________________________________________________
-void AliRsnEvent::FillPIDArrays(Int_t arraySizeInit)
+Int_t AliRsnEvent::GetMultiplicity()
 {
 //
-// 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.
+// Returns event multiplicity
 //
-
-  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()));
-    }
-  }
-
-  // adjusts the size of arrays
-  if (fNoPID) fNoPID->SetCorrectIndexSize();
-  if (fPerfectPID) fPerfectPID->SetCorrectIndexSize();
-  if (fRealisticPID) fRealisticPID->SetCorrectIndexSize();
+  AliDebug(AliLog::kDebug+2,"<-");
+  if (!fRef) return 0;
+  AliDebug(AliLog::kDebug+2,"->");
+  return fRef->GetNumberOfTracks();
 }
 
 //_____________________________________________________________________________
-void AliRsnEvent::Print(Option_t *option) const
+Double_t AliRsnEvent::GetVz()
 {
 //
-// 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.
+// Return Z coord of primary vertex
 //
 
-  cout << "...Multiplicity     : " << fTracks->GetEntries() << endl;
-  cout << "...Primary vertex   : " << fPVx << ' ' << fPVy << ' ' << fPVz << endl;
-
-  TObjArrayIter iter(fTracks);
-  AliRsnDaughter *d = 0;
-  while ((d = (AliRsnDaughter*) iter.Next()))
-  {
-    cout << "....Track #" << fTracks->IndexOf(d) << endl;
-    d->Print(option);
-  }
+  AliDebug(AliLog::kDebug+2,"<-");
+  return fRef->GetPrimaryVertex()->GetZ();
+  AliDebug(AliLog::kDebug+2,"->");
 }
 
 //_____________________________________________________________________________
-void AliRsnEvent::MakeComputations()
+Int_t AliRsnEvent::SelectLeadingParticle
+(Double_t ptMin, AliRsnCutPID *cutPID)
 {
 //
-// Computes all required overall variables:
-// - multiplicity
-// - mean phi of tracks
+// 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 (!fTracks) 
-  {
-    fMult = 0; 
-    fPhiMean = 1000.0;
-  }
-  else 
-  {
-    fMult = fTracks->GetEntries();
-    if (fMult < 1) {
-      fPhiMean = 1000.0;
-    }
-    else
+  Int_t i, nTracks = fRef->GetNumberOfTracks();
+  fLeading = -1;
+  AliRsnDaughter leading;
+  leading.SetBad();
+
+  for (i = 0; i < nTracks; i++) {
+    AliRsnDaughter track = GetDaughter(i);
+    if (cutPID) if (!cutPID->IsSelected(&track)) continue;
+    if (track.P().Perp() < ptMin) continue;
+    if (!leading.IsOK() || track.P().Perp() > leading.P().Perp())
     {
-      fPhiMean = 0.0;
-      AliRsnDaughter *d = 0;
-      TObjArrayIter next(fTracks);
-      while ( (d = (AliRsnDaughter*)next()) ) fPhiMean += d->Phi();
-      fPhiMean /= (Double_t)fMult;
+      fLeading = i;
+      leading = track;
     }
   }
+
+  return fLeading;
 }
 
-//_____________________________________________________________________________
-void AliRsnEvent::CorrectByPrimaryVertex()
+//_________________________________________________________________________________________________
+Double_t AliRsnEvent::GetAverageMomentum(Int_t &count, AliRsnCutPID *cutPID)
 {
 //
-// Corrects the X,Y,Z position of DCA vertex of all tracks
-// by the amount of stored primary vertex
+// Loops on the list of tracks and computes average total momentum.
 //
 
-    TObjArrayIter iter(fTracks);
-    AliRsnDaughter *d = 0;
-    while ((d = (AliRsnDaughter*) iter.Next())) {
-        d->ShiftZero(fPVx, fPVy, fPVz);
-    }
-}
+  Int_t i, nTracks = fRef->GetNumberOfTracks();
+  Double_t pmean = 0.0;
 
-/*
-//_____________________________________________________________________________
-Int_t AliRsnEvent::GetMultiplicity() const
-{
-//
-// Get number of all tracks
-//
+  for (i = 0, count = 0; i < nTracks; i++) {
+    AliRsnDaughter track = GetDaughter(i);
+    if (cutPID) if (!cutPID->IsSelected(&track)) continue;
+    pmean += track.P().Mag();
+    count++;
+  }
 
-  if (!fTracks) return 0;
-  return fTracks->GetEntries();
+  if (count > 0) pmean /= (Double_t)count;
+  else pmean = 0.0;
+
+  return pmean;
 }
-*/
 
 //_____________________________________________________________________________
-Int_t AliRsnEvent::GetNCharged(Char_t sign)
+Bool_t AliRsnEvent::GetAngleDistr
+(Double_t &angleMean, Double_t &angleRMS, AliRsnDaughter leading)
 {
 //
-// Get number of charged tracks
+// 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.
 //
 
-  Int_t icharge;
-  icharge = ChargeIndex(sign);
-  if (icharge < 0) return 0;
-  TArrayI *charged = GetCharged(sign);
-  if (!charged) return 0;
-  return charged->GetSize();
-}
+  if (!leading.IsOK()) return kFALSE;
 
-//_____________________________________________________________________________
-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.
-//
+  Int_t i, count, nTracks = fRef->GetNumberOfTracks();
+  Double_t angle, angle2Mean = 0.0;
 
-  // clear the array if it is already instantiated,
-  // create if otherwise
-  if (fTracks) fTracks->Delete();
-  else Init();
+  angleMean = angle2Mean = 0.0;
 
-  // 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++;
-    }
-  }
+  for (i = 0, count = 0; i < nTracks; i++) {
+    AliRsnDaughter trk = GetDaughter(i);
+    if (trk.GetID() == leading.GetID()) continue;
 
-  return errors;
-}
+    angle = leading.P().Angle(trk.P().Vect());
 
-//_____________________________________________________________________________
-Int_t AliRsnEvent::ChargeIndex(Char_t sign) const
-//
-// Returns the array index corresponding to charge
-// 0 for positive, 1 for negative
-//
-{
-  if (sign == '+') return 0;
-  else if (sign == '-') return 1;
-  else
-  {
-    AliError(Form("Character '%c' not recognized as charge sign", sign));
-    return -1;
+    angleMean += angle;
+    angle2Mean += angle * angle;
+    count++;
   }
+
+  if (!count) return kFALSE;
+
+  angleMean /= (Double_t)count;
+  angle2Mean /= (Double_t)count;
+  angleRMS = TMath::Sqrt(angle2Mean - angleMean * angleMean);
+
+  return kTRUE;
 }