]> 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 5645bc0ae7abcd0f8bb42b69462616c58fa18231..485987a21fcc79230fd0a4029a02278976216595 100644 (file)
-/**************************************************************************
- * 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
-//                     -------------------
-//           Simple collection of reconstructed tracks
-//           selected from an ESD event
-//           to be used for analysis.
-//           .........................................
-// 
-// author: A. Pulvirenti             (email: alberto.pulvirenti@ct.infn.it)
-//-------------------------------------------------------------------------
-
-#include <Riostream.h>
-
-#include <TString.h>
-#include <TObjArray.h>
-#include <TClonesArray.h>
-
-#include "AliRsnDaughter.h"
+//
+// *** Class AliRsnEvent ***
+//
+// A container for a collection of AliRsnDaughter objects from an event.
+// Contains also the primary vertex, useful for some cuts.
+// In order to retrieve easily the tracks which have been identified
+// as a specific type and charge, there is an array of indexes which
+// allows to avoid to loop on all tracks and have only the neede ones.
+//
+// authors: A. Pulvirenti (email: alberto.pulvirenti@ct.infn.it)
+//          M. Vala (email: martin.vala@cern.ch)
+//
+
+#include <TArrayF.h>
+
+#include "AliLog.h"
+#include "AliVEvent.h"
+#include "AliMCEvent.h"
+#include "AliStack.h"
+#include "AliGenEventHeader.h"
+#include "AliRsnCutPID.h"
+
 #include "AliRsnEvent.h"
 
 ClassImp(AliRsnEvent)
 
-//--------------------------------------------------------------------------------------------------------
-AliRsnEvent::AliRsnEvent() :
- fPVx(0.0),
- fPVy(0.0),
- fPVz(0.0),
- fMultiplicity(-1),
- fPosNoPID(0x0),
- fNegNoPID(0x0)
+//_____________________________________________________________________________
+AliRsnEvent::AliRsnEvent(AliVEvent *ref, AliMCEvent *refMC) :
+  fRef(ref),
+  fRefMC(refMC),
+  fLeading(-1)
 {
 //
-// Default constructor
+// Default constructor.
 //
-       Int_t i;
-       for (i = 0; i < AliPID::kSPECIES; i++) {
-               fPos[i] = NULL;
-               fNeg[i] = NULL;
-       }
 }
-//--------------------------------------------------------------------------------------------------------
+
+//_____________________________________________________________________________
 AliRsnEvent::AliRsnEvent(const AliRsnEvent &event) :
- TObject((TObject)event),
- fPVx(event.fPVx),
- fPVy(event.fPVy),
- fPVz(event.fPVz),
- fMultiplicity(event.fMultiplicity),
- fPosNoPID(0x0),
- fNegNoPID(0x0)
+  TObject(event),
+  fRef(event.fRef),
+  fRefMC(event.fRefMC),
+  fLeading(event.fLeading)
 {
 //
 // Copy constructor.
-// Creates new instances of all collections to store a copy of all objects.
 //
-       // clone tracks collections
-       Int_t i;
-       for (i = 0; i < AliPID::kSPECIES; i++) {
-               fPos[i] = 0;
-               fNeg[i] = 0;
-               if (event.fPos[i]) fPos[i] = (TClonesArray*)event.fPos[i]->Clone();
-               if (event.fNeg[i]) fNeg[i] = (TClonesArray*)event.fNeg[i]->Clone();
-       }
-       fPosNoPID = (TClonesArray*)event.fPosNoPID->Clone();
-       fNegNoPID = (TClonesArray*)event.fNegNoPID->Clone();
 }
-//--------------------------------------------------------------------------------------------------------
-AliRsnEvent& AliRsnEvent::operator=(const AliRsnEvent &event)
+
+//_____________________________________________________________________________
+AliRsnEvent& AliRsnEvent::operator= (const AliRsnEvent & event)
 {
 //
-// Assignment operator.
-// Creates new instances of all collections to store a copy of all objects.
+// Works in the same way as the copy constructor.
 //
-       fPVx = event.fPVx;
-       fPVy = event.fPVy;
-       fPVz = event.fPVz;
-       fMultiplicity = event.fMultiplicity;
-
-       // clone tracks collections
-       Int_t i;
-       for (i = 0; i < AliPID::kSPECIES; i++) {
-               fPos[i] = 0;
-               fNeg[i] = 0;
-               if (event.fPos[i]) fPos[i] = (TClonesArray*)event.fPos[i]->Clone();
-               if (event.fNeg[i]) fNeg[i] = (TClonesArray*)event.fNeg[i]->Clone();
-       }
-       fPosNoPID = (TClonesArray*)event.fPosNoPID->Clone();
-       fNegNoPID = (TClonesArray*)event.fNegNoPID->Clone();
-       
-       return (*this);
+
+  (TObject)(*this) = (TObject)event;
+  fRef             = event.fRef;
+  fRefMC           = event.fRefMC;
+  fLeading         = event.fLeading;
+
+  return (*this);
 }
-//--------------------------------------------------------------------------------------------------------
-void AliRsnEvent::AddTrack(AliRsnDaughter track)
+
+//_____________________________________________________________________________
+AliRsnEvent::~AliRsnEvent()
 {
 //
-// Stores a track into the correct array
+// Destructor.
 //
-       // if sign is zero, track is not stored
-       Char_t sign = track.GetSign();
-       if (!sign) return;
-       
-       // if PDG code is assigned, track is stored in the corresponding collection
-       // otherwise, it is stored in the array of unidentified particles with that sign
-       Int_t index, iarray, pdg = track.GetPDG();
-       if (pdg != 0) {
-               iarray = PDG2Enum(pdg);
-               if (iarray < AliPID::kElectron || iarray > AliPID::kProton) return;
-               TClonesArray &array = (sign > 0) ? *fPos[iarray] : *fNeg[iarray];
-               index = array.GetEntries();
-               new(array[index]) AliRsnDaughter(track);
-       }
-       else {
-               TClonesArray &array = (sign > 0) ? *fPosNoPID : *fNegNoPID;
-               index = array.GetEntries();
-               new(array[index]) AliRsnDaughter(track);
-       }
 }
-//--------------------------------------------------------------------------------------------------------
-void AliRsnEvent::Clear(Option_t *option)
+
+//_____________________________________________________________________________
+Bool_t AliRsnEvent::SetDaughter(AliRsnDaughter &out, Int_t i, AliRsnDaughter::ERefType type)
 {
 //
-// Clears list of tracks and references.
-// If the string "DELETE" is specified, the collection classes
-// are also cleared from heap.
+// 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).
 //
-       // evaluate option
-       TString opt(option);
-       Bool_t deleteCollections = opt.Contains("DELETE", TString::kIgnoreCase);
-       
-       Int_t i;
-       for (i = 0; i < AliPID::kSPECIES; i++) {
-               if (fPos[i]) fPos[i]->Delete();
-               if (fNeg[i]) fNeg[i]->Delete();
-               if (deleteCollections) {
-                       delete fPos[i];
-                       delete fNeg[i];
-                       fPos[i] = 0;
-                       fNeg[i] = 0;
-               }
-       }
-       if (fPosNoPID) fPosNoPID->Delete();
-       if (fNegNoPID) fNegNoPID->Delete();
-       if (deleteCollections) {
-               delete fPosNoPID;
-               delete fNegNoPID;
-               fPosNoPID = 0;
-               fNegNoPID = 0;
-       }
+
+  Int_t label;
+
+  // retrieve reference particle from reference event
+  // if it is found, by defaul track can be used (good)
+  if (type == AliRsnDaughter::kTrack)
+  {
+    if (i >= fRef->GetNumberOfTracks())
+    {
+      out.SetBad();
+      return kFALSE;
+    }
+    AliVTrack *track = (AliVTrack*)fRef->GetTrack(i);
+    label = TMath::Abs(track->GetLabel());
+    if (!track)
+    {
+      out.SetBad();
+      return kFALSE;
+    }
+    else
+    {
+      out.SetRef(track);
+      out.SetLabel(label);
+      if (fRefMC)
+      {
+        if (label < fRefMC->GetNumberOfTracks()) 
+        {
+          AliMCParticle *part = (AliMCParticle*)fRefMC->GetTrack(label);
+          out.SetRefMC(part);
+        }
+      }
+      out.SetGood();
+    }
+  }
+  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());
+      }
+
+      // 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;
 }
-//--------------------------------------------------------------------------------------------------------
-void AliRsnEvent::ComputeMultiplicity()
+
+//_____________________________________________________________________________
+Bool_t AliRsnEvent::SetDaughterMC(AliRsnDaughter &out, Int_t i)
 {
 //
-// Computes multiplicity.
+// 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).
 //
-       fMultiplicity = 0;
-       Int_t i;
-       for (i = 0; i < AliPID::kSPECIES; i++) {
-               fMultiplicity += (Int_t)fPos[i]->GetEntries();
-               fMultiplicity += (Int_t)fNeg[i]->GetEntries();
-       }
-       if (fPosNoPID) fMultiplicity += fPosNoPID->GetEntries();
-       if (fNegNoPID) fMultiplicity += fNegNoPID->GetEntries();
+
+  if (!fRefMC)
+  {
+    out.SetBad();
+    return kFALSE;
+  }
+
+  if (i >= fRefMC->GetNumberOfTracks())
+  {
+    out.SetBad();
+    return kFALSE;
+  }
+  
+  AliMCParticle *track = (AliMCParticle*)fRef->GetTrack(i);
+  if (!track)
+  {
+    out.SetBad();
+    return kFALSE;
+  }
+  else
+  {
+    out.SetRef(track);
+    out.SetRefMC(track);
+    out.SetLabel(i);
+    out.SetGood();
+  }
+  
+  AliStack  *stack = fRefMC->Stack();
+  TParticle *part  = track->Particle();
+  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;
 }
-//--------------------------------------------------------------------------------------------------------
-TClonesArray* AliRsnEvent::GetTracks(Char_t sign, AliPID::EParticleType type)
+
+//_____________________________________________________________________________
+AliRsnDaughter AliRsnEvent::GetDaughter(Int_t i, AliRsnDaughter::ERefType type)
 {
 //
-// Returns the particle collection specified in argument
+// Return an AliRsnDaughter taken from this event,
+// with all additional data members well set.
 //
-       Int_t itype = (Int_t)type;
-       if (itype >= 0 && itype < AliPID::kSPECIES) {
-               if (sign == '+') return fPos[type]; else return fNeg[type];
-       }
-       else if (type == AliPID::kUnknown) {
-               if (sign == '+') return fPosNoPID; else return fNegNoPID;
-       }
-       else {
-               return NULL;
-       }
+
+  AliRsnDaughter out;
+  SetDaughter(out, i, type);
+
+  return out;
 }
-//--------------------------------------------------------------------------------------------------------
-void AliRsnEvent::Init()
+
+//_____________________________________________________________________________
+AliRsnDaughter AliRsnEvent::GetDaughterMC(Int_t i)
 {
 //
-// Action 1: define default values for some data members (including pointers).
-// Action 2: if 'ntracks' > 0 allocates memory to store tracks.
+// Return an AliRsnDaughter taken from this event,
+// with all additional data members well set.
 //
-       Int_t i;
-       for (i = 0; i < AliPID::kSPECIES; i++) {
-               fPos[i] = new TClonesArray("AliRsnDaughter", 0);
-               fNeg[i] = new TClonesArray("AliRsnDaughter", 0);
-               fPos[i]->BypassStreamer(kFALSE);
-               fNeg[i]->BypassStreamer(kFALSE);
-       }
-       fPosNoPID = new TClonesArray("AliRsnDaughter", 0);
-       fNegNoPID = new TClonesArray("AliRsnDaughter", 0);
-       fPosNoPID->BypassStreamer(kFALSE);
-       fNegNoPID->BypassStreamer(kFALSE);
+
+  AliRsnDaughter out;
+  SetDaughterMC(out, i);
+
+  return out;
 }
-//--------------------------------------------------------------------------------------------------------
-Int_t AliRsnEvent::PDG2Enum(Int_t pdgcode)
+
+//_____________________________________________________________________________
+Int_t AliRsnEvent::GetMultiplicity()
 {
 //
-// Converts a PDG code into the correct slot in the EParticleType enumeration in AliPID
+// Returns event multiplicity
 //
-       Int_t i;
-       for (i = 0; i < AliPID::kSPECIES; i++) {
-               if (AliPID::ParticleCode((AliPID::EParticleType)i) == TMath::Abs(pdgcode)) {
-                       return i;
-               }
-       }
-       
-       return -1;
+  AliDebug(AliLog::kDebug+2,"<-");
+  if (!fRef) return 0;
+  AliDebug(AliLog::kDebug+2,"->");
+  return fRef->GetNumberOfTracks();
 }
-//--------------------------------------------------------------------------------------------------------
-void AliRsnEvent::PrintTracks()
+
+//_____________________________________________________________________________
+Double_t AliRsnEvent::GetVz()
 {
 //
-// Print data for particles stored in this event
+// Return Z coord of primary vertex
 //
-       cout << endl;
-       
-       AliRsnDaughter *track = 0;
-       
-       Int_t type;
-       for (type = 0; type < AliPID::kSPECIES; type++) {
-               TObjArrayIter iterPos(fPos[type]);
-               cout << "Positive " << AliPID::ParticleName(type) << "s" << endl;
-               if (!fPos[type]) cout << "NOT INITIALIZED" << endl;
-               while ( (track = (AliRsnDaughter*)iterPos.Next()) ) {
-                       cout << "Index, Sign, PDG = ";
-                       cout << track->GetIndex() << " ";
-                       cout << (Int_t)track->GetSign() << " ";
-                       cout << track->GetPDG() << endl;
-               }
-               TObjArrayIter iterNeg(fNeg[type]);
-               cout << "Negative " << AliPID::ParticleName(type) << "s" << endl;
-               if (!fNeg[type]) cout << "NOT INITIALIZED" << endl;
-               while ( (track = (AliRsnDaughter*)iterNeg.Next()) ) {
-                       cout << "Index, Sign, PDG = ";
-                       cout << track->GetIndex() << " ";
-                       cout << (Int_t)track->GetSign() << " ";
-                       cout << track->GetPDG() << endl;
-               }
-       }
+
+  AliDebug(AliLog::kDebug+2,"<-");
+  return fRef->GetPrimaryVertex()->GetZ();
+  AliDebug(AliLog::kDebug+2,"->");
+}
+
+//_____________________________________________________________________________
+Int_t AliRsnEvent::SelectLeadingParticle
+(Double_t ptMin, AliRsnCutPID *cutPID)
+{
+//
+// 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.
+//
+
+  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())
+    {
+      fLeading = i;
+      leading = track;
+    }
+  }
+
+  return fLeading;
+}
+
+//_________________________________________________________________________________________________
+Double_t AliRsnEvent::GetAverageMomentum(Int_t &count, AliRsnCutPID *cutPID)
+{
+//
+// Loops on the list of tracks and computes average total momentum.
+//
+
+  Int_t i, nTracks = fRef->GetNumberOfTracks();
+  Double_t pmean = 0.0;
+
+  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 (count > 0) pmean /= (Double_t)count;
+  else pmean = 0.0;
+
+  return pmean;
+}
+
+//_____________________________________________________________________________
+Bool_t AliRsnEvent::GetAngleDistr
+(Double_t &angleMean, Double_t &angleRMS, AliRsnDaughter leading)
+{
+//
+// 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.
+//
+
+  if (!leading.IsOK()) return kFALSE;
+
+  Int_t i, count, nTracks = fRef->GetNumberOfTracks();
+  Double_t angle, angle2Mean = 0.0;
+
+  angleMean = angle2Mean = 0.0;
+
+  for (i = 0, count = 0; i < nTracks; i++) {
+    AliRsnDaughter trk = GetDaughter(i);
+    if (trk.GetID() == leading.GetID()) continue;
+
+    angle = leading.P().Angle(trk.P().Vect());
+
+    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;
 }
-//--------------------------------------------------------------------------------------------------------