2 // *** Class AliRsnLoopPair ***
4 // "Core" method for defining the work on a pari of particles.
5 // For one analysis, one must setup one of this for each pair he wants to analyze,
6 // adding to it all analysis which he desires to do.
7 // Here he defines the cuts, and the particle types and charges, and can add
8 // functions which do different operations on the same pair, and some binning
9 // with respect to some kinematic variables (eta, momentum)
11 // authors: A. Pulvirenti (email: alberto.pulvirenti@ct.infn.it)
12 // M. Vala (email: martin.vala@cern.ch)
16 #include <TEntryList.h>
20 #include "AliRsnMother.h"
21 #include "AliRsnCutSet.h"
22 #include "AliRsnDaughterSelector.h"
24 #include "AliRsnLoopPair.h"
26 ClassImp(AliRsnLoopPair)
28 //_____________________________________________________________________________
29 AliRsnLoopPair::AliRsnLoopPair(const char *name, AliRsnPairDef *def, Bool_t isMixed) :
30 AliRsnLoop(name, isMixed),
38 // Default constructor
45 //_____________________________________________________________________________
46 AliRsnLoopPair::AliRsnLoopPair(const AliRsnLoopPair& copy) :
48 fOnlyTrue(copy.fOnlyTrue),
49 fCheckDecay(copy.fCheckDecay),
50 fPairDef(copy.fPairDef),
51 fPairCuts(copy.fPairCuts),
58 fListID[0] = copy.fListID[0];
59 fListID[1] = copy.fListID[1];
62 //_____________________________________________________________________________
63 AliRsnLoopPair& AliRsnLoopPair::operator=(const AliRsnLoopPair& copy)
65 AliRsnLoop::operator=(copy);
67 fOnlyTrue = copy.fOnlyTrue;
68 fCheckDecay = copy.fCheckDecay;
69 fPairDef = copy.fPairDef;
70 fPairCuts = copy.fPairCuts;
71 fMother = copy.fMother;
72 fListID[0] = copy.fListID[0];
73 fListID[1] = copy.fListID[1];
78 //_____________________________________________________________________________
79 AliRsnLoopPair::~AliRsnLoopPair()
86 //_____________________________________________________________________________
87 void AliRsnLoopPair::Print(Option_t* /*option*/) const
90 // Prints info about pair
96 //_____________________________________________________________________________
97 Bool_t AliRsnLoopPair::Init(const char *prefix, TList *list)
100 // Initialization function.
101 // Loops on all functions and eventual the ntuple, to initialize output objects.
104 // assign data members relations
105 fMother.SetDaughter(0, &fDaughter[0]);
106 fMother.SetDaughter(1, &fDaughter[1]);
107 AliInfo(Form("[%s] Initialization", GetName()));
109 TString name(prefix);
112 if (IsMixed()) name.Prepend("mix_");
114 return AliRsnLoop::Init(name.Data(), list);
117 //_____________________________________________________________________________
118 Int_t AliRsnLoopPair::DoLoop
119 (AliRsnEvent *evMain, AliRsnDaughterSelector *selMain, AliRsnEvent *evMix, AliRsnDaughterSelector *selMix)
123 // Computes what is needed from passed events.
124 // Returns the number of pairs successfully processed.
128 AliDebugClass(1, Form("[%s]: event-mixing loop", GetName()));
129 if (!evMix || !selMix) {
130 AliError(Form("[%s] NULL mixed event when mixing is required: cannot process", GetName()));
134 AliDebugClass(1, Form("[%s]: single-event loop", GetName()));
138 fMother.SetRefEvent(evMain);
141 if (!OkEvent(evMain)) {
142 AliDebugClass(1, Form("[%s]: main event not accepted", GetName()));
145 if (!OkEvent(evMix)) {
146 AliDebugClass(1, Form("[%s]: mixed event not accepted", GetName()));
150 Int_t i0, i1, start, npairs = 0;
152 TEntryList *list0 = selMain->GetSelected(fListID[0], fPairDef->GetDef1().GetChargeC());
153 TEntryList *list1 = selMix ->GetSelected(fListID[1], fPairDef->GetDef2().GetChargeC());
154 if (!list0 || !list1) {
155 AliError("Can't process NULL lists");
158 AliDebugClass(2, Form("[%s]: list counts: %d, %d", GetName(), (Int_t)list0->GetN(), (Int_t)list1->GetN()));
159 if (!list0->GetN() || !list1->GetN()) {
160 AliDebugClass(2, Form("[%s]: at least one list is empty", GetName()));
164 TObjArrayIter next(&fOutputs);
165 AliRsnListOutput *out = 0x0;
167 for (i0 = 0; i0 < list0->GetN(); i0++) {
168 evMain->SetDaughterAbs(fDaughter[0], (Int_t)list0->GetEntry(i0));
170 if (!fDaughter[0].GetRef()) {
171 AliDebugClass(3, Form("[%s]: daughte #1 has NULL ref", GetName()));
174 if (!fDaughter[0].IsOK()) {
175 AliDebugClass(3, Form("[%s]: daughte #1 is BAD", GetName()));
178 if (!fIsMixed && list0 == list1) start = i0 + 1;
179 for (i1 = start; i1 < list1->GetN(); i1++) {
180 evMix->SetDaughterAbs(fDaughter[1], (Int_t)list1->GetEntry(i1));
181 if (!fDaughter[1].GetRef()) {
182 AliDebugClass(3, Form("[%s]: daughte #2 has NULL ref", GetName()));
185 if (!fDaughter[1].IsOK()) {
186 AliDebugClass(3, Form("[%s]: daughte #2 is BAD", GetName()));
191 AliDebugClass(2, Form("[%s]: candidate mother didn't pass the cuts", GetName()));
196 while ( (out = (AliRsnListOutput*)next()) ) {
197 if (out->Fill(&fMother)) npairs++;
198 else AliDebugClass(3, Form("[%s]: failed computation", GetName()));
206 //_____________________________________________________________________________
207 Bool_t AliRsnLoopPair::MotherOK()
210 // Checks that first argument matches definitions for first daughter
211 // and the same for second argument, where the order is defined by
212 // the AliRsnPairDef data member.
213 // If the matching is successful, the AliRsnMother data member is
214 // initialized using the mass hypotheses defined here and the momenta
215 // in the passed daughters.
216 // The third argument is necessary to choose which one of the possible two
217 // events owning the two daughter will be used as reference.
220 // check matching and exit if one of them fails
221 // if true pair is required, this is taken into account:
222 // if both true pairs and correct decay tree is required,
223 // then we must be sure that also the true PID of daughters matches,
224 // instead if correct decay tree is not required this additional check is not done
225 fPairDef->GetDef1().SetOnlyTrue(fOnlyTrue && fCheckDecay);
226 fPairDef->GetDef2().SetOnlyTrue(fOnlyTrue && fCheckDecay);
227 if (!fPairDef->GetDef1().MatchesDaughter(&fDaughter[0])) return kFALSE;
228 if (!fPairDef->GetDef2().MatchesDaughter(&fDaughter[1])) return kFALSE;
230 // if matching is successful
231 // compute 4-momenta of daughters and mother
232 fMother.ComputeSum(fPairDef->GetDef1().GetMass(), fPairDef->GetDef2().GetMass());
234 // if required a true pair, check this here and eventually return a fail message
235 // this is done using the method AliRsnMother::CommonMother with 2 arguments
236 // passed by reference, where the real GEANT label of the particle is stored
237 // and one can check if these tracks are both really secondaries (ID >= 0)
239 Int_t m0, m1, common;
240 common = fMother.CommonMother(m0, m1);
241 if (m0 < 0 || m1 < 0) return kFALSE;
242 if (common != fPairDef->GetMotherPDG()) return kFALSE;
245 // point to first event as reference
246 // and checks the pair cuts,
247 // (done first because it is more likely
248 // that it is not passed and execution is faster)
250 return fPairCuts->IsSelected(&fMother);