Implemented rotated background (experimental)
authorpulvir <pulvir@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 16 Jun 2011 15:40:59 +0000 (15:40 +0000)
committerpulvir <pulvir@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 16 Jun 2011 15:40:59 +0000 (15:40 +0000)
PWG2/RESONANCES/AliRsnMiniAnalysisTask.cxx
PWG2/RESONANCES/AliRsnMiniAnalysisTask.h
PWG2/RESONANCES/AliRsnMiniOutput.cxx
PWG2/RESONANCES/AliRsnMiniOutput.h
PWG2/RESONANCES/AliRsnMiniPair.cxx
PWG2/RESONANCES/AliRsnMiniPair.h

index 3db1437..ecbe118 100644 (file)
 
 #include <Riostream.h>
 
-#include <TList.h>
 #include <TH1.h>
-#include <TH2.h>
-#include <TH3.h>
-#include <THnSparse.h>
+#include <TList.h>
+#include <TTree.h>
 
 #include "AliLog.h"
+#include "AliEventplane.h"
+#include "AliMultiplicity.h"
+#include "AliTriggerAnalysis.h"
 #include "AliAnalysisManager.h"
+#include "AliInputEventHandler.h"
+
 #include "AliESDtrackCuts.h"
 #include "AliESDUtils.h"
-#include "AliMultiplicity.h"
-#include "AliInputEventHandler.h"
-#include "AliTriggerAnalysis.h"
-#include "AliMCEvent.h"
+
 #include "AliAODEvent.h"
-#include "AliMCParticle.h"
 #include "AliAODMCParticle.h"
-#include "AliEventplane.h"
 
 #include "AliRsnCutSet.h"
+#include "AliRsnMiniPair.h"
 #include "AliRsnMiniEvent.h"
 #include "AliRsnMiniParticle.h"
-#include "AliRsnMiniPair.h"
 
 #include "AliRsnMiniAnalysisTask.h"
 
@@ -61,7 +59,8 @@ AliRsnMiniAnalysisTask::AliRsnMiniAnalysisTask() :
    fEvBuffer(0x0),
    fNMixed(0),
    fTriggerAna(0x0),
-   fESDtrackCuts(0x0)
+   fESDtrackCuts(0x0),
+   fMiniEvent(0x0)
 {
 //
 // Dummy constructor ALWAYS needed for I/O.
@@ -89,7 +88,8 @@ AliRsnMiniAnalysisTask::AliRsnMiniAnalysisTask(const char *name, Bool_t useMC) :
    fEvBuffer(0x0),
    fNMixed(0),
    fTriggerAna(0x0),
-   fESDtrackCuts(0x0)
+   fESDtrackCuts(0x0),
+   fMiniEvent(0x0)
 {
 //
 // Default constructor.
@@ -122,7 +122,8 @@ AliRsnMiniAnalysisTask::AliRsnMiniAnalysisTask(const AliRsnMiniAnalysisTask& cop
    fEvBuffer(0x0),
    fNMixed(0),
    fTriggerAna(copy.fTriggerAna),
-   fESDtrackCuts(copy.fESDtrackCuts)
+   fESDtrackCuts(copy.fESDtrackCuts),
+   fMiniEvent(0x0)
 {
 //
 // Copy constructor.
@@ -228,9 +229,9 @@ void AliRsnMiniAnalysisTask::UserCreateOutputObjects()
    fOutput->Add(fHEventStat);
    
    // create temporary tree for filtered events
-   AliRsnMiniEvent *mini = 0x0;
+   if (fMiniEvent) delete fMiniEvent;
    fEvBuffer = new TTree("EventBuffer", "Temporary buffer for mini events");
-   fEvBuffer->Branch("events", "AliRsnMiniEvent", &mini);
+   fEvBuffer->Branch("events", "AliRsnMiniEvent", &fMiniEvent);
    
    // create one histogram per each stored definition (event histograms)
    Int_t i, ndef = fHistograms.GetEntries();
@@ -257,11 +258,10 @@ void AliRsnMiniAnalysisTask::UserCreateOutputObjects()
 void AliRsnMiniAnalysisTask::UserExec(Option_t *)
 {
 //
-// Main computation loop.
-// To be precise, this loop only checks if events are OK and eventually
-// stores them in the temporary tree used for the analysis.
-// The computation of correlations is done only at the end,
-// in the automatic function which is called every time
+// Computation loop.
+// In this case, it checks if the event is acceptable, and eventually
+// creates the corresponding mini-event and stores it in the buffer.
+// The real histogram filling is done at the end, in "FinishTaskOutput".
 //
 
    // event counter
@@ -270,65 +270,28 @@ void AliRsnMiniAnalysisTask::UserExec(Option_t *)
    // check current event
    Char_t check = CheckCurrentEvent();
    if (!check) return;
-      
-   // if the check is successful, the mini-event is created and stored
-   AliRsnMiniEvent *miniEvent = 0x0;
-   fEvBuffer->SetBranchAddress("events", &miniEvent);
    
-   // assign event-related values
-   miniEvent = new AliRsnMiniEvent;
-   miniEvent->Vz() = fInputEvent->GetPrimaryVertex()->GetZ();
-   miniEvent->Angle() = ComputeAngle();
-   miniEvent->Mult() = ComputeCentrality((check == 'E'));
-   AliDebugClass(1, Form("Event %d: vz = %f -- mult = %f -- angle = %f", fEvNum, miniEvent->Vz(), miniEvent->Mult(), miniEvent->Angle()));
-   
-   // fill all histograms for events only
-   Int_t id, ndef = fHistograms.GetEntries();
-   AliRsnMiniOutput *def = 0x0;
-   for (id = 0; id < ndef; id++) {
-      def = (AliRsnMiniOutput*)fHistograms[id];
-      if (!def) continue;
-      if (!def->IsEventOnly()) continue;
-      def->Fill(miniEvent, &fValues);
+   // fill a mini-event from current
+   // and skip this event if no tracks were accepted
+   Int_t nacc = FillMiniEvent(check);
+   if (nacc < 1) {
+      AliDebugClass(1, Form("Event %d: skipping event with no tracks accepted", fEvNum));
+      return;
    }
    
-   // fill all histograms for mother only (if MC is present)
+   // fill MC based histograms on mothers,
+   // which do need the original event
    if (fUseMC) {
       if (fRsnEvent.IsESD() && fMCEvent)
-         FillTrueMotherESD(miniEvent);
+         FillTrueMotherESD(fMiniEvent);
       else if (fRsnEvent.IsAOD() && fRsnEvent.GetAODList())
-         FillTrueMotherAOD(miniEvent);
-   }
-   
-   // loop on daughters
-   // and store only those that pass at least one cut
-   Int_t it, ic, ncuts = fTrackCuts.GetEntries(), ntot = fRsnEvent.GetAbsoluteSum();
-   AliRsnDaughter cursor;
-   AliRsnMiniParticle miniParticle;
-   for (it = 0; it < ntot; it++) {
-      fRsnEvent.SetDaughter(cursor, it);
-      miniParticle.CopyDaughter(&cursor);
-      for (ic = 0; ic < ncuts; ic++) {
-         AliRsnCutSet *cuts = (AliRsnCutSet*)fTrackCuts[ic];
-         if (cuts->IsSelected(&cursor)) miniParticle.SetCutBit(ic);
-      }
-      AliDebugClass(3, Form("-- Track %d: REC px = %f -- py = %f -- pz = %f", it, miniParticle.Px(0), miniParticle.Py(0), miniParticle.Pz(0)));
-      AliDebugClass(3, Form("-- Track %d: SIM px = %f -- py = %f -- pz = %f", it, miniParticle.Px(1), miniParticle.Py(1), miniParticle.Pz(1)));
-      AliDebugClass(3, Form("-- Track %d: Charge = %c -- PDG = %d -- mother = %d -- motherPDG = %d", it, miniParticle.Charge(), miniParticle.PDG(), miniParticle.Mother(), miniParticle.MotherPDG()));
-      AliDebugClass(2, Form("-- Track %d: Cutbit = %u", it, miniParticle.CutBits()));
-      if (miniParticle.CutBits()) {
-         miniEvent->AddParticle(miniParticle);
-      }
+         FillTrueMotherAOD(fMiniEvent);
    }
-   AliDebugClass(1, Form("Event %d: selected tracks = %d", fEvNum, miniEvent->Particles().GetEntriesFast()));
    
    // store event
    fEvBuffer->Fill();
    
-   // process single event
-   ProcessEvents(miniEvent);
-   
-   // post outputs
+   // post data for computed stuff
    PostData(1, fOutput);
 }
 
@@ -336,47 +299,96 @@ void AliRsnMiniAnalysisTask::UserExec(Option_t *)
 void AliRsnMiniAnalysisTask::FinishTaskOutput()
 {
 //
-// At the end of execution, when the temporary tree is filled,
-// perform mixing with all found events
+// This function is called at the end of the loop on available events,
+// and then the buffer will be full with all the corresponding mini-events,
+// each one containing all tracks selected by each of the available track cuts.
+// Here a loop is done on each of these events, and both single-event and mixing are computed
 //
 
-   Int_t i1, i2, imix, nEvents = fEvBuffer->GetEntries();
-   AliRsnMiniEvent *evMix = 0x0, evMain;
-   fEvBuffer->SetBranchAddress("events", &evMix);
+   // security code: reassign the buffer to the mini-event cursor
+   fEvBuffer->SetBranchAddress("events", &fMiniEvent);
+   
+   Int_t ievt, nEvents = (Int_t)fEvBuffer->GetEntries();
+   Int_t idef, nDefs   = fHistograms.GetEntries();
+   Int_t imix, iloop;
+   AliRsnMiniOutput *def = 0x0;
+   AliRsnMiniOutput::EComputation compType;
+   AliRsnMiniEvent evMain;
    
    // initialize mixing counter
    fNMixed.Set(nEvents);
-   TString msg();
-   
-   // loop on events
-   for (i1 = 0; i1 < nEvents; i1++) {
-      if (fNMixed[i1] >= fNMix) continue;
-      fEvBuffer->GetEntry(i1);
-      evMain = (*evMix);
-      for (i2 = 1; i2 < nEvents; i2++) {
-         imix = i1 + i2;
-         if (imix >= nEvents) imix -= nEvents;
-         if (imix == i1) continue;
-         if (fNMixed[i1] >= fNMix) break;
-         if (fNMixed[imix] >= fNMix) continue;
-         fEvBuffer->GetEntry(imix);
-         // exit if events are not matched
-         if (TMath::Abs(evMain.Vz() - evMix->Vz()) > fMaxDiffVz) continue;
-         if (TMath::Abs(evMain.Mult() - evMix->Mult()) > fMaxDiffMult) continue;
-         if (TMath::Abs(evMain.Angle() - evMix->Angle()) > fMaxDiffAngle) continue;
-         // found a match: increment counter for both events
-         fNMixed[i1]++;
-         fNMixed[imix]++;
-         //cout << "Mixed " << i1 << " with " << imix << endl;
-         ProcessEvents(&evMain, evMix);
-         // if mixed enough times, stop
+   for (ievt = 0; ievt < nEvents; ievt++) fNMixed[ievt] = 0;
+
+   // loop on events, and for each one fill all outputs
+   // using the appropriate procedure depending on its type
+   // only mother-related histograms are filled in UserExec,
+   // since they require direct access to MC event
+   for (ievt = 0; ievt < nEvents; ievt++) {
+      // get next entry
+      fEvBuffer->GetEntry(ievt);
+      // store in temp variable
+      evMain = (*fMiniEvent);
+      // fill non-mixed histograms
+      for (idef = 0; idef < nDefs; idef++) {
+         def = (AliRsnMiniOutput*)fHistograms[idef];
+         if (!def) continue;
+         compType = def->GetComputation();
+         // execute computation in the appropriate way
+         switch (compType) {
+            case AliRsnMiniOutput::kEventOnly:
+               AliDebugClass(1, Form("Event %d, def %d: event-value histogram filling", ievt, idef));
+               def->Fill(&evMain, &fValues);
+               break;
+            case AliRsnMiniOutput::kTruePair:
+               AliDebugClass(1, Form("Event %d, def %d: true-pair histogram filling", ievt, idef));
+               ProcessEvents(&evMain, 0x0);
+               break;
+            case AliRsnMiniOutput::kTrackPair:
+               AliDebugClass(1, Form("Event %d, def %d: pair-value histogram filling", ievt, idef));
+               ProcessEvents(&evMain, 0x0);
+               break;
+            case AliRsnMiniOutput::kTrackPairRotated1:
+               AliDebugClass(1, Form("Event %d, def %d: rotated (1) background histogram filling", ievt, idef));
+               ProcessEvents(&evMain, 0x0);
+               break;
+            case AliRsnMiniOutput::kTrackPairRotated2:
+               AliDebugClass(1, Form("Event %d, def %d: rotated (2) background histogram filling", ievt, idef));
+               ProcessEvents(&evMain, 0x0);
+               break;
+            case AliRsnMiniOutput::kTrackPairMix:
+               for (iloop = 1; iloop < nEvents; iloop++) {
+                  imix = ievt + iloop;
+                  AliDebugClass(1, Form("Event %d, def %d: event mixing (%d with %d)", ievt, idef, ievt, imix));
+                  // restart from beginning if reached last event
+                  if (imix >= nEvents) imix -= nEvents;
+                  // avoid to mix an event with itself
+                  if (imix == ievt) continue;
+                  // skip all events already mixed enough times
+                  if (fNMixed[ievt] >= fNMix) break;
+                  if (fNMixed[imix] >= fNMix) continue;
+                  fEvBuffer->GetEntry(imix);
+                  // skip if events are not matched
+                  if (TMath::Abs(evMain.Vz()    - fMiniEvent->Vz()   ) > fMaxDiffVz   ) continue;
+                  if (TMath::Abs(evMain.Mult()  - fMiniEvent->Mult() ) > fMaxDiffMult ) continue;
+                  if (TMath::Abs(evMain.Angle() - fMiniEvent->Angle()) > fMaxDiffAngle) continue;
+                  // found a match: increment counter for both events
+                  fNMixed[ievt]++;
+                  fNMixed[imix]++;
+                  // process mixing
+                  ProcessEvents(&evMain, fMiniEvent);
+               }
+               break;
+            default:
+               // other kinds are processed elsewhere
+               AliDebugClass(2, Form("Computation = %d", (Int_t)compType));
+         }
       }
    }
    
-   // message
-   for (Int_t ii = 0; ii < nEvents; ii++) cout << Form("Event #%6d mixed %3d times", ii, fNMixed[ii]) << endl;
+   // print number of mixings done with each event
+   for (ievt = 0; ievt < nEvents; ievt++) cout << Form("Event #%6d mixed %3d times", ievt, fNMixed[ievt]) << endl;
    
-   // post outputs
+   // post computed data
    PostData(1, fOutput);
 }
 
@@ -531,6 +543,46 @@ Char_t AliRsnMiniAnalysisTask::CheckCurrentEvent()
 }
 
 //__________________________________________________________________________________________________
+Int_t AliRsnMiniAnalysisTask::FillMiniEvent(Char_t evType)
+{
+//
+// Refresh cursor mini-event data member to fill with current event.
+// Returns the total number of tracks selected.
+//
+
+   // assign event-related values
+   fMiniEvent = new AliRsnMiniEvent;
+   fMiniEvent->Vz()    = fInputEvent->GetPrimaryVertex()->GetZ();
+   fMiniEvent->Angle() = ComputeAngle();
+   fMiniEvent->Mult()  = ComputeCentrality((evType == 'E'));
+   AliDebugClass(1, Form("Event %d: type = %c -- vz = %f -- mult = %f -- angle = %f", fEvNum, evType, fMiniEvent->Vz(), fMiniEvent->Mult(), fMiniEvent->Angle()));
+   
+   // loop on daughters and assign track-related values
+   Int_t ic, ncuts = fTrackCuts.GetEntries();
+   Int_t ip, npart = fRsnEvent.GetAbsoluteSum();
+   AliRsnDaughter cursor;
+   AliRsnMiniParticle miniParticle;
+   for (ip = 0; ip < npart; ip++) {
+      // point cursor to next particle
+      fRsnEvent.SetDaughter(cursor, ip);
+      // copy momentum and MC info if present
+      miniParticle.CopyDaughter(&cursor);
+      // switch on the bits corresponding to passed cuts
+      for (ic = 0; ic < ncuts; ic++) {
+         AliRsnCutSet *cuts = (AliRsnCutSet*)fTrackCuts[ic];
+         if (cuts->IsSelected(&cursor)) miniParticle.SetCutBit(ic);
+      }
+      // if a track passes at least one track cut, it is added to the pool
+      if (miniParticle.CutBits()) fMiniEvent->AddParticle(miniParticle);
+   }
+   
+   // get number of accepted tracks
+   Int_t nacc = (Int_t)fMiniEvent->Particles().GetEntriesFast();
+   AliDebugClass(1, Form("Event %d: total = %d, accepted = %d", fEvNum, npart, nacc));
+   return nacc;
+}
+
+//__________________________________________________________________________________________________
 Double_t AliRsnMiniAnalysisTask::ComputeAngle()
 {
 //
@@ -711,7 +763,6 @@ void AliRsnMiniAnalysisTask::ProcessEvents(AliRsnMiniEvent *evMain, AliRsnMiniEv
       evMix = evMain;
       isMix = kFALSE;
    }
-   AliDebugClass(1, Form("Event %d: processing %s", fEvNum, (isMix ? "mixing" : "single event")));
    
    // 2 nested loops on tracks
    // inner starts from next track or from first, depending if is mixing or not
index edd5d38..03fe30e 100644 (file)
 // -- values to be computed.
 //
 
-#include "AliAnalysisTaskSE.h"
-
 #include <TString.h>
 #include <TClonesArray.h>
 
+#include "AliAnalysisTaskSE.h"
+
 #include "AliRsnEvent.h"
 #include "AliRsnMiniValue.h"
 #include "AliRsnMiniOutput.h"
 
 class TList;
+
 class AliTriggerAnalysis;
 class AliRsnMiniEvent;
 class AliRsnCutSet;
@@ -34,11 +35,6 @@ public:
    AliRsnMiniAnalysisTask& operator=(const AliRsnMiniAnalysisTask &copy);
    virtual ~AliRsnMiniAnalysisTask();
 
-   virtual void        UserCreateOutputObjects();
-   virtual void        UserExec(Option_t *option);
-   virtual void        Terminate(Option_t *);
-   virtual void        FinishTaskOutput();
-  
    void                UseMC(Bool_t yn = kTRUE)           {fUseMC = yn;}                     
    void                UseCentrality(const char *type)    {fUseCentrality = kTRUE; fCentralityType = type; fCentralityType.ToUpper();}
    void                UseMultiplicity(const char *type)  {fUseCentrality = kFALSE; fCentralityType = type; fCentralityType.ToUpper();}
@@ -48,9 +44,13 @@ public:
    void                SetMaxDiffAngle(Double_t val)      {fMaxDiffAngle = val;}
    void                SetEventCuts(AliRsnCutSet *cuts)   {fEventCuts    = cuts;}
    Int_t               AddTrackCuts(AliRsnCutSet *cuts);
+   TClonesArray       *Outputs()                          {return &fHistograms;}
+   TClonesArray       *Values()                           {return &fValues;}
    
-   TClonesArray       *Outputs()        {return &fHistograms;}
-   TClonesArray       *Values()         {return &fValues;}
+   virtual void        UserCreateOutputObjects();
+   virtual void        UserExec(Option_t*);
+   virtual void        Terminate(Option_t*);
+   virtual void        FinishTaskOutput();
    
    Int_t               ValueID(AliRsnMiniValue::EType type, Bool_t useMC = kFALSE);
    Int_t               CreateValue(AliRsnMiniValue::EType type, Bool_t useMC = kFALSE); 
@@ -60,6 +60,7 @@ public:
 private:
 
    Char_t   CheckCurrentEvent();
+   Int_t    FillMiniEvent(Char_t evType);
    Double_t ComputeAngle();
    Double_t ComputeCentrality(Bool_t isESD);
    void     FillTrueMotherESD(AliRsnMiniEvent *event);
@@ -89,6 +90,7 @@ private:
    TArrayI              fNMixed;          //! array to keep trace of how many times an event was mixed
    AliTriggerAnalysis  *fTriggerAna;      //! trigger analysis
    AliESDtrackCuts     *fESDtrackCuts;    //! quality cut for ESD tracks
+   AliRsnMiniEvent     *fMiniEvent;       //! mini-event cursor
 
    ClassDef(AliRsnMiniAnalysisTask, 1); // AliRsnMiniAnalysisTask
 };
index 12cb7e3..f7050d1 100644 (file)
@@ -94,15 +94,17 @@ AliRsnMiniOutput::AliRsnMiniOutput(const char *name, const char *outType, const
 // the user sets the type of output and computations through conventional strings:
 //
 // Output:
-//    -- "HIST"   --> common histogram (up to 3 dimensions)
-//    -- "SPARSE" --> sparse histogram
-//
-// Computation:
-//    -- "EVENT"  --> event-only computations
-//    -- "PAIR"   --> track pair computations (default)
-//    -- "MIX"    --> event mixing (like track pair, but different events)
-//    -- "TRUE"   --> true pairs (like track pair, but checking that come from same mother)
-//    -- "MOTHER" --> mother (loop on MC directly for mothers --> denominator of efficiency)
+//    -- "HIST"    --> common histogram (up to 3 dimensions)
+//    -- "SPARSE"  --> sparse histogram
+//                 
+// Computation:    
+//    -- "EVENT"   --> event-only computations
+//    -- "PAIR"    --> track pair computations (default)
+//    -- "MIX"     --> event mixing (like track pair, but different events)
+//    -- "ROTATE1" --> rotated background (rotate first track)
+//    -- "ROTATE2" --> rotated background (rotate second track)
+//    -- "TRUE"    --> true pairs (like track pair, but checking that come from same mother)
+//    -- "MOTHER"  --> mother (loop on MC directly for mothers --> denominator of efficiency)
 //
 
    TString input;
@@ -126,6 +128,10 @@ AliRsnMiniOutput::AliRsnMiniOutput(const char *name, const char *outType, const
       fComputation = kTrackPair;
    else if (!input.CompareTo("MIX"))
       fComputation = kTrackPairMix;
+   else if (!input.CompareTo("ROTATE1"))
+      fComputation = kTrackPairRotated1;
+   else if (!input.CompareTo("ROTATE2"))
+      fComputation = kTrackPairRotated2;
    else if (!input.CompareTo("TRUE"))
       fComputation = kTruePair;
    else if (!input.CompareTo("MOTHER"))
@@ -241,10 +247,10 @@ Bool_t AliRsnMiniOutput::Init(const char *prefix, TList *list)
 
    switch (fOutputType) {
       case kHistogram:
-         CreateHistogram(Form("hist_%s_%s", prefix, GetName()));
+         CreateHistogram(Form("%s_%s", prefix, GetName()));
          return kTRUE;
       case kHistogramSparse:
-         CreateHistogramSparse(Form("hsparse_%s_%s", prefix, GetName()));
+         CreateHistogramSparse(Form("%s_%s", prefix, GetName()));
          return kTRUE;
       default:
          AliError("Wrong output histogram definition");
@@ -383,7 +389,12 @@ Bool_t AliRsnMiniOutput::Fill
 //
 
    // check computation type
-   if (fComputation != kTrackPair && fComputation != kTrackPairMix && fComputation != kTruePair) {
+   Bool_t okComp = kFALSE;
+   if (fComputation == kTrackPair) okComp = kTRUE;
+   if (fComputation == kTrackPairMix) okComp = kTRUE;
+   if (fComputation == kTrackPairRotated1)  okComp = kTRUE;
+   if (fComputation == kTrackPairRotated2)  okComp = kTRUE;
+   if (!okComp) {
       AliError("This method can be called only for pair-based computations");
       return kFALSE;
    }
@@ -405,6 +416,14 @@ Bool_t AliRsnMiniOutput::Fill
       return kFALSE;
    }
    
+   // if required, rotate one of the two backgrounds
+   if (fComputation == kTrackPairRotated1) {
+      fPair.InvertP(kTRUE);
+   }
+   else if (fComputation == kTrackPairRotated2){
+      fPair.InvertP(kFALSE);
+   }
+   
    // if required, check that this is a true pair
    if (fComputation == kTruePair) {
       //cout << fPair.Mother() << ' ' << fPair.MotherPDG() << ' ';
index c3f94fa..7ea67d2 100644 (file)
@@ -38,6 +38,8 @@ public:
       kEventOnly,
       kTrackPair,
       kTrackPairMix,
+      kTrackPairRotated1,
+      kTrackPairRotated2,
       kTruePair,
       kMother,
       kComputations
index 15025ce..af33734 100644 (file)
@@ -67,3 +67,19 @@ Double_t AliRsnMiniPair::CosThetaStar(Bool_t useMC)
 
    return cosThetaStar;
 }
+
+//__________________________________________________________________________________________________
+void AliRsnMiniPair::InvertP(Bool_t first)
+{
+//
+// Inverts one 4-momentum and recompute sum
+//
+
+   Int_t i;
+   for (i = 0; i < 2; i++) {
+      if (first) fP1[i].Vect() *= -1.0;
+      else       fP2[i].Vect() *= -1.0;
+      fSum[i] = fP1[i] + fP2[i];
+      fRef[i].SetXYZM(fSum[i].X(), fSum[i].Y(), fSum[i].Z(), fRef[i].M());
+   }
+}
index 50cc35a..58413e4 100644 (file)
@@ -21,6 +21,7 @@ public:
    Int_t&          MotherPDG() {return fMotherPDG;}
    void            Fill(AliRsnMiniParticle *p1, AliRsnMiniParticle *p2, Double_t m1, Double_t m2, Double_t refMass);
    void            FillRef(Double_t mass);
+   void            InvertP(Bool_t first);
       
    Int_t           ID(Bool_t mc) const {if (mc) return 1; else return 0;}