]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG2/RESONANCES/AliRsnAnalysisPhiKK.cxx
4d0ef086e3515182f21e3a1364cf05bc9ebadd11
[u/mrichter/AliRoot.git] / PWG2 / RESONANCES / AliRsnAnalysisPhiKK.cxx
1 //
2 // Class AliRsnAnalysisPhiKK
3 //
4 // Virtual Class derivated from AliRsnVAnalysisTaskSE which will be base class
5 // for all RSN SE tasks
6 //
7 // authors: Martin Vala (martin.vala@cern.ch)
8 //          Alberto Pulvirenti (alberto.pulvirenti@ct.infn.it)
9 //
10
11 #include <Riostream.h>
12 #include <TList.h>
13
14 #include "AliRsnFunction.h"
15 #include "AliRsnAnalysisPhiKK.h"
16
17 ClassImp(AliRsnAnalysisPhiKK)
18
19 //_____________________________________________________________________________
20 AliRsnAnalysisPhiKK::AliRsnAnalysisPhiKK(const char *name, Bool_t useKine) :
21   AliRsnVAnalysisTaskSE(name, useKine),
22   
23   fPairDef(AliPID::kKaon, '+', AliPID::kKaon, '-', 333, 1.019455),
24   
25   fCutEvent      (Form("%s_cutEvent"   , name), AliRsnTarget::kEvent),
26   fCutTrackCommon(Form("%s_cutTrackCom", name), AliRsnTarget::kDaughter),
27   fCutTrackPos   (Form("%s_cutTrackPos", name), AliRsnTarget::kDaughter),
28   fCutTrackNeg   (Form("%s_cutTrackNeg", name), AliRsnTarget::kDaughter),
29   fCutPair       (Form("%s_cutPair", name), AliRsnTarget::kMother),
30   
31   fFuncPM  ("AliRsnFunction", 0),
32   fFuncPP  ("AliRsnFunction", 0),
33   fFuncMM  ("AliRsnFunction", 0),
34   fFuncTrue("AliRsnFunction", 0),
35   
36   fOutList(0x0)
37 {
38 //
39 // Default constructor.
40 // Defines another output slot for histograms/ntuples
41 //
42
43   DefineOutput(2, TList::Class());
44 }
45
46 //_____________________________________________________________________________
47 AliRsnAnalysisPhiKK::AliRsnAnalysisPhiKK(const AliRsnAnalysisPhiKK& copy) :
48   AliRsnVAnalysisTaskSE(copy),
49   
50   fPairDef(AliPID::kKaon, '+', AliPID::kKaon, '-', 333, 1.019455),
51   
52   fCutEvent      (copy.fCutEvent),
53   fCutTrackCommon(copy.fCutTrackCommon),
54   fCutTrackPos   (copy.fCutTrackPos),
55   fCutTrackNeg   (copy.fCutTrackNeg),
56   fCutPair       (copy.fCutPair),
57   
58   fFuncPM  (copy.fFuncPM),
59   fFuncPP  (copy.fFuncPP),
60   fFuncMM  (copy.fFuncMM),
61   fFuncTrue(copy.fFuncTrue),
62   
63   fOutList(0x0)
64 {
65 //
66 // Copy constructor.
67 //
68 }
69
70 //_____________________________________________________________________________
71 AliRsnAnalysisPhiKK& AliRsnAnalysisPhiKK::operator=(const AliRsnAnalysisPhiKK& copy)
72 {
73 //
74 // Assigment operator.
75 //
76
77   AliRsnVAnalysisTaskSE::operator=(copy);
78   
79   fFuncPM   = copy.fFuncPM;
80   fFuncPP   = copy.fFuncPP;
81   fFuncMM   = copy.fFuncMM;
82   fFuncTrue = copy.fFuncTrue;
83   
84   fCutEvent       = copy.fCutEvent;
85   fCutTrackCommon = copy.fCutTrackCommon;
86   fCutTrackPos    = copy.fCutTrackPos;
87   fCutTrackNeg    = copy.fCutTrackNeg;
88   fCutPair        = copy.fCutPair;
89   
90   if (fOutList) fOutList->Clear();
91   
92   return (*this);
93 }
94
95 //_____________________________________________________________________________
96 void AliRsnAnalysisPhiKK::AddFunction(AliRsnFunction* const fcn)
97 {
98 //
99 // Adds a new computing function to each collection,
100 // in order to have exactly the sames for each kind of pair.
101 //
102   
103   Int_t size = fFuncPM.GetEntries();
104   
105   new (fFuncPM  [size]) AliRsnFunction(*fcn);
106   new (fFuncPP  [size]) AliRsnFunction(*fcn);
107   new (fFuncMM  [size]) AliRsnFunction(*fcn);
108   new (fFuncTrue[size]) AliRsnFunction(*fcn);
109 }
110
111 //_____________________________________________________________________________
112 void AliRsnAnalysisPhiKK::RsnUserCreateOutputObjects()
113 {
114 //
115 // Creation of output objects.
116 // These are created through the utility methods in the analysis manager,
117 // which asks all the AliRsnPair objects to initialize their output which
118 // is then linked to the TList data member of this, which will contain all the output.
119 //
120
121   if (!fOutList) fOutList = new TList;
122   fOutList->Clear();
123   
124   Int_t   i, j, nFunc = fFuncPM.GetEntries();
125   TString hName(""), suf[4] = {"PM", "PP", "MM", "True"};
126   AliRsnFunction *fcn[4] = {0, 0, 0, 0};
127   
128   for (i = 0; i < nFunc; i++)
129   {
130     fcn[0] = (AliRsnFunction*)fFuncPM.At(i);
131     fcn[1] = (AliRsnFunction*)fFuncPP.At(i);
132     fcn[2] = (AliRsnFunction*)fFuncMM.At(i);
133     fcn[3] = (AliRsnFunction*)fFuncTrue.At(i);
134     for (j = 0; j < 4; j++)
135     {
136       hName  = GetName();
137       hName += '_';
138       hName += suf[j];
139       hName += '_';
140       hName += fcn[j]->GetName();
141       if (fcn[j]->IsUsingTH1()) fOutList->Add(fcn[j]->CreateHistogram(hName.Data(), ""));
142       else fOutList->Add(fcn[j]->CreateHistogramSparse(hName.Data(), ""));
143     }
144   }
145
146   PostData(2, fOutList);
147 }
148
149 //_____________________________________________________________________________
150 void AliRsnAnalysisPhiKK::RsnUserExec(Option_t*)
151 {
152 //
153 // Execution of the analysis task.
154 // Recovers the input event and processes it with all included pair objects,
155 // using 'reconstructed' or 'MonteCarlo' functions depending on MC-only flag.
156 //
157
158   // allocate statically all class objects used here
159   static TArrayI                   good(0);
160   static AliRsnDaughter            kaon[2], temp;
161   static AliRsnMother              phi;
162   static AliRsnDaughter::ERefType  type;
163   static AliRsnFunction           *fcn = 0x0;
164   static TClonesArray             *ref = 0x0;
165   
166   // define constants used for kinematics
167   static const Double_t kaonMass = 0.493677;
168   
169   // simpler variables are declared non static
170   Int_t  i, j, k, index, ngood = 0;
171   Int_t  tot = AliRsnTarget::GetCurrentEvent()->GetAbsoluteSum();
172   Bool_t assignOK, truePair;
173
174   // point to first event in the target 
175   AliRsnTarget::SwitchToFirst();
176   if (!AliRsnTarget::GetCurrentEvent()) return;
177   
178   // initially, set the array of good indexes 
179   // to the full number of tracks and reset the counter
180   good.Set(tot);
181   ngood = 0;
182   
183   // loop on tracks and get those which satisfy cuts
184   for (i = 0; i < tot; i++)
185   {
186     // assign track and skip all that are not charged tracks
187     assignOK = AliRsnTarget::GetCurrentEvent()->ConvertAbsoluteIndex(i, index, type);
188     if (!assignOK) continue;
189     if (type != AliRsnDaughter::kTrack) continue;
190     AliRsnTarget::GetCurrentEvent()->SetDaughter(temp, index, AliRsnDaughter::kTrack);
191     
192     // skip tracks which don't pass common cuts
193     if (!fCutTrackCommon.IsSelected(&temp)) continue;
194     
195     // accept tracks which pass also charge-related cuts
196     if ( (temp.Charge() > 0) && (fCutTrackPos.IsSelected(&temp)) )
197     {
198       good[ngood] = index;
199       ++ngood;
200     }
201     else if ( (temp.Charge() < 0) && (fCutTrackNeg.IsSelected(&temp)) )
202     {
203       good[ngood] = index;
204       ++ngood;
205     }
206   }
207   
208   // rese the arrays to the real counts
209   good.Set(ngood);
210   
211   // now that the 'tot' value is useless, set it to
212   // the total number of functions, which by construction 
213   // is THE SAME for all collections
214   tot = fFuncPM.GetEntries();
215   
216   // fill histograms: do a unique loop on all good indexes
217   // and choose the histogram to fill from track charges
218   for (i = 0; i < ngood; i++)
219   {
220     AliRsnTarget::GetCurrentEvent()->SetDaughter(kaon[0], good[i], AliRsnDaughter::kTrack);
221     
222     for (j = 0; j < ngood; j++)
223     {
224       // reject equal indexes
225       if (good[i] == good[j]) continue;
226       AliRsnTarget::GetCurrentEvent()->SetDaughter(kaon[1], good[j], AliRsnDaughter::kTrack);
227   
228       // adjust charges of pair def
229       fPairDef.SetDaughters(AliPID::kKaon, kaon[0].ChargeChar(), AliPID::kKaon, kaon[1].ChargeChar());
230     
231       // fill the pair using the kaon masses and the passed daughters
232       phi.SetDaughters(&kaon[0], kaonMass, &kaon[1], kaonMass);
233       
234       // check pair cuts
235       if (!fCutPair.IsSelected(&phi)) continue;
236       
237       // choose the functions to fill according to charges
238       if (fPairDef.IsLikeSign())
239       {
240         if (kaon[0].IsPos()) ref = &fFuncPP; else ref = &fFuncMM;
241         truePair = kFALSE;
242       }
243       else
244       {
245         ref = &fFuncPM;
246         truePair = IsTruePair(&kaon[0], &kaon[1]);
247       }
248         
249       // loop on functions in chosen collection and fill
250       for (k = 0; k < tot; k++)
251       {
252         // fill standard histogram
253         fcn = (AliRsnFunction*)fFuncPP[k];
254         fcn->SetPairDef(&fPairDef);
255         fcn->SetPair(&phi);
256         fcn->Fill();
257         
258         // in case of true pair, fill its histogram
259         if (truePair)
260         {
261           fcn = (AliRsnFunction*)fFuncTrue[k];
262           fcn->Fill();
263         }
264       }
265     } // end internal loop
266   } // end external loop
267   
268   PostData(2, fOutList);
269 }
270
271 //_____________________________________________________________________________
272 void AliRsnAnalysisPhiKK::RsnTerminate(Option_t*)
273 {
274 //
275 // Termination.
276 // Could be added some monitor histograms here.
277 //
278 }
279
280 //______________________________________________________________________________
281 Bool_t AliRsnAnalysisPhiKK::EventProcess()
282 {
283 //
284 // Customized event pre-processing.
285 // First checks if the current event passes all cuts,
286 // and if it does, updates the informations and then
287 // call the operations which are already defined in the
288 // omonyme function in mother class
289 //
290
291   // initially, an event is expected to be bad
292   fTaskInfo.SetEventUsed(kFALSE);
293   
294   // check #1: number of tracks in event (reject empty events)
295   Int_t ntracks = fRsnEvent.GetMultiplicity();
296   if (ntracks < 1) 
297   {
298     // empty events are rejected by default
299     fTaskInfo.SetEventUsed(kFALSE);
300     AliDebug(AliLog::kDebug, "Empty event. Skipping...");
301     return kFALSE;
302   }
303
304   // check the event cuts and update the info data accordingly
305   // events not passing the cuts must be rejected
306   if (!fCutEvent.IsSelected(&fRsnEvent))
307   {
308     fTaskInfo.SetEventUsed(kFALSE);
309     return kFALSE;
310   }
311   
312   // if we reach this point, cuts were passed;
313   // then additional operations can be done
314   
315   // find leading particle (without any PID/momentum restriction)
316   fRsnEvent.SelectLeadingParticle(0);
317   
318   // final return value is positive
319   // but call the mother class method which updates info object
320   fTaskInfo.SetEventUsed(kTRUE);
321   return AliRsnVAnalysisTaskSE::EventProcess();
322 }
323
324 //______________________________________________________________________________
325 Bool_t AliRsnAnalysisPhiKK::IsTruePair(AliRsnDaughter *d1, AliRsnDaughter *d2)
326 {
327 //
328 // Checks if the two daughters in argument come from the same phi resonance
329 // and, if they do, check also that they are both kaons
330 //
331
332   // constants related to PDG
333   static const Int_t phiPDG  = 333;
334   static const Int_t kaonPDG = 321;
335
336   // check #1: is MC present?
337   if (!d1->GetRefMC() || !d2->GetRefMC()) return kFALSE;
338
339   // check #2: same mother?
340   Int_t m1 = -1;
341   Int_t m2 = -2;
342   if (d1->IsESD() && d2->IsESD() )
343   {
344     if (d1->GetRefMCESD() && d2->GetRefMCESD())
345     {
346       m1 = d1->GetRefMCESD()->Particle()->GetFirstMother();
347       m2 = d2->GetRefMCESD()->Particle()->GetFirstMother();
348     }
349   }
350   if (d1->IsAOD() && d2->IsAOD())
351   {
352     if (d1->GetRefMCAOD() && d2->GetRefMCAOD())
353     {
354       m1 = d1->GetRefMCAOD()->GetMother();
355       m2 = d2->GetRefMCAOD()->GetMother();
356     }
357   }
358   if (m1 < 0 || m2 < 0 || (m1 > 0 && m2 > 0 && m1 != m2)) return kFALSE;
359   
360   // check #3: is the common mother a phi (PDG = 333)?
361   if (d1->GetMotherPDG() != phiPDG) return kFALSE;
362   
363   // check #4: are the two particles a K+K- pair?
364   m1 = d1->GetPDG();
365   m2 = d2->GetPDG();
366   if (m1 == kaonPDG && m2 == -kaonPDG) 
367     return kTRUE;
368   else if (m1 == -kaonPDG && m2 == kaonPDG)
369     return kTRUE;
370   else
371     return kFALSE;
372 }