]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG3/dielectron/AliDielectron.cxx
remove dependency to aliroot libraries, access of ESDEvent object through abstract...
[u/mrichter/AliRoot.git] / PWG3 / dielectron / AliDielectron.cxx
1 /*************************************************************************
2 * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
3 *                                                                        *
4 * Author: The ALICE Off-line Project.                                    *
5 * Contributors are mentioned in the code where appropriate.              *
6 *                                                                        *
7 * Permission to use, copy, modify and distribute this software and its   *
8 * documentation strictly for non-commercial purposes is hereby granted   *
9 * without fee, provided that the above copyright notice appears in all   *
10 * copies and that both the copyright notice and this permission notice   *
11 * appear in the supporting documentation. The authors make no claims     *
12 * about the suitability of this software for any purpose. It is          *
13 * provided "as is" without express or implied warranty.                  *
14 **************************************************************************/
15
16 ///////////////////////////////////////////////////////////////////////////
17 //                Dielectron Analysis Main class                         //
18 //                                                                       //
19 /*
20 Framework to perform event selectoin, single track selection and track pair
21 selection.
22
23 Convention for the signs of the pair in fPairCandidates:
24 The names are available via the function PairClassName(Int_t i)
25
26 0: ev1+ ev1+  (same event like sign +)
27 1: ev1+ ev1-  (same event unlike sign)
28 2: ev1- ev1-  (same event like sign -)
29
30 3: ev1+ ev2+  (mixed event like sign +)
31 4: ev1- ev2+  (mixed event unlike sign -+)
32 6: ev1+ ev2-  (mixed event unlike sign +-)
33 7: ev1- ev2-  (mixed event like sign -)
34
35 5: ev2+ ev2+  (same event like sign +)
36 8: ev2+ ev2-  (same event unlike sign)
37 9: ev2- ev2-  (same event like sign -)
38
39 10: ev1+ ev1- (same event track rotation)
40
41 */
42 //                                                                       //
43 ///////////////////////////////////////////////////////////////////////////
44
45 #include <TString.h>
46 #include <TList.h>
47 #include <TMath.h>
48
49 #include <AliESDEvent.h>
50 #include <AliESDtrack.h>
51
52 #include <AliVEvent.h>
53 #include <AliVParticle.h>
54 #include <AliVTrack.h>
55 #include "AliDielectronPair.h"
56 #include "AliDielectronHistos.h"
57 #include "AliDielectronCF.h"
58 #include "AliDielectronMC.h"
59 #include "AliDielectronVarManager.h"
60 #include "AliDielectronTrackRotator.h"
61 #include "AliDielectronDebugTree.h"
62
63 #include "AliDielectron.h"
64
65 ClassImp(AliDielectron)
66
67 const char* AliDielectron::fgkTrackClassNames[4] = {
68   "ev1+",
69   "ev1-",
70   "ev2+",
71   "ev2-"
72 };
73
74 const char* AliDielectron::fgkPairClassNames[11] = {
75   "ev1+_ev1+",
76   "ev1+_ev1-",
77   "ev1-_ev1-",
78   "ev1+_ev2+",
79   "ev1-_ev2+",
80   "ev2+_ev2+",
81   "ev1+_ev2-",
82   "ev1-_ev2-",
83   "ev2+_ev2-",
84   "ev2-_ev2-",
85   "ev1+_ev1-_TR"
86 };
87
88 //________________________________________________________________
89 AliDielectron::AliDielectron() :
90   TNamed("AliDielectron","AliDielectron"),
91   fEventFilter("EventFilter"),
92   fTrackFilter("TrackFilter"),
93   fPairPreFilter("PairPreFilter"),
94   fPairPreFilterLegs("PairPreFilterLegs"),
95   fPairFilter("PairFilter"),
96   fPdgMother(443),
97   fPdgLeg1(11),
98   fPdgLeg2(11),
99   fNoPairing(kFALSE),
100   fHistos(0x0),
101   fPairCandidates(new TObjArray(10)),
102   fCfManagerPair(0x0),
103   fTrackRotator(0x0),
104   fDebugTree(0x0),
105   fPreFilterUnlikeOnly(kFALSE)
106 {
107   //
108   // Default constructor
109   //
110
111 }
112
113 //________________________________________________________________
114 AliDielectron::AliDielectron(const char* name, const char* title) :
115   TNamed(name,title),
116   fEventFilter("EventFilter"),
117   fTrackFilter("TrackFilter"),
118   fPairPreFilter("PairPreFilter"),
119   fPairPreFilterLegs("PairPreFilterLegs"),
120   fPairFilter("PairFilter"),
121   fPdgMother(443),
122   fPdgLeg1(11),
123   fPdgLeg2(11),
124   fNoPairing(kFALSE),
125   fHistos(0x0),
126   fPairCandidates(new TObjArray(10)),
127   fCfManagerPair(0x0),
128   fTrackRotator(0x0),
129   fDebugTree(0x0),
130   fPreFilterUnlikeOnly(kFALSE)
131 {
132   //
133   // Named constructor
134   //
135   
136 }
137
138 //________________________________________________________________
139 AliDielectron::~AliDielectron()
140 {
141   //
142   // Default destructor
143   //
144   if (fHistos) delete fHistos;
145   if (fPairCandidates) delete fPairCandidates;
146   if (fDebugTree) delete fDebugTree;
147 }
148
149 //________________________________________________________________
150 void AliDielectron::Init()
151 {
152   //
153   // Initialise objects
154   //
155   if (fCfManagerPair) fCfManagerPair->InitialiseContainer(fPairFilter);
156   if (fTrackRotator)  fTrackRotator->SetTrackArrays(&fTracks[0],&fTracks[1]);
157   if (fDebugTree) fDebugTree->SetDielectron(this);
158
159
160 //________________________________________________________________
161 void AliDielectron::Process(AliVEvent *ev1, AliVEvent *ev2)
162 {
163   //
164   // Process the events
165   //
166
167   //at least first event is needed!
168   if (!ev1){
169     AliError("At least first event must be set!");
170     return;
171   }
172     
173   AliDielectronVarManager::SetEvent(ev1);
174    
175   //in case we have MC load the MC event and process the MC particles
176   if (AliDielectronMC::Instance()->HasMC()) {
177     if (!AliDielectronMC::Instance()->ConnectMCEvent()){
178       AliError("Could not properly connect the MC event, skipping this event!");
179       return;
180     }
181     ProcessMC();
182   }
183   
184   //if candidate array doesn't exist, create it
185   if (!fPairCandidates->UncheckedAt(0)) {
186     InitPairCandidateArrays();
187   } else {
188     ClearArrays();
189   }
190
191   //mask used to require that all cuts are fulfilled
192   UInt_t selectedMask=(1<<fEventFilter.GetCuts()->GetEntries())-1;
193
194   //apply event cuts
195     if ((ev1&&fEventFilter.IsSelected(ev1)!=selectedMask) ||
196         (ev2&&fEventFilter.IsSelected(ev2)!=selectedMask)) return;
197   
198   AliDielectronVarManager::SetEvent(ev1);
199   
200   //fill track arrays for the first event
201   if (ev1){
202     FillTrackArrays(ev1);
203     if ((fPreFilterUnlikeOnly) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) PairPreFilter(0, 1, fTracks[0], fTracks[1]);
204   }
205
206
207   //fill track arrays for the second event
208   if (ev2) {
209     FillTrackArrays(ev2,1);
210     if ((fPreFilterUnlikeOnly) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) PairPreFilter(2, 3, fTracks[2], fTracks[3]);
211   }
212
213   if (!fNoPairing){
214     // create pairs and fill pair candidate arrays
215     for (Int_t itrackArr1=0; itrackArr1<4; ++itrackArr1){
216       for (Int_t itrackArr2=itrackArr1; itrackArr2<4; ++itrackArr2){
217         FillPairArrays(itrackArr1, itrackArr2);
218       }
219     }
220
221     //track rotation
222     if (fTrackRotator) FillPairArrayTR();
223   }
224   
225   //in case there is a histogram manager, fill the QA histograms
226   if (fHistos) FillHistograms(ev1);
227
228   //fill debug tree if a manager is attached
229   if (fDebugTree) FillDebugTree();
230 }
231
232 //________________________________________________________________
233 void AliDielectron::ProcessMC()
234 {
235   //
236   // Process the MC data
237   //
238
239   //loop over all MC data and Fill the CF container if it exist
240   if (!fCfManagerPair) return;
241   fCfManagerPair->SetPdgMother(fPdgMother);
242   AliDielectronMC *dieMC=AliDielectronMC::Instance();
243   for (Int_t ipart=0; ipart<dieMC->GetNMCTracks();++ipart){
244     //TODO: MC truth cut properly!!!
245     AliVParticle *mcPart=dieMC->GetMCTrackFromMCEvent(ipart);
246     if (!dieMC->IsMCMotherToEE(mcPart, fPdgMother)) continue;
247     fCfManagerPair->FillMC(mcPart);
248   }
249 }
250
251 //________________________________________________________________
252 void AliDielectron::FillHistogramsTracks(TObjArray **tracks)
253 {
254   //
255   // Fill Histogram information for tracks after prefilter
256   // ignore mixed events - for prefilter, only single tracks +/- are relevant 
257   //
258   
259   TString  className,className2;
260   Double_t values[AliDielectronVarManager::kNMaxValues];
261   
262   //Fill track information, separately for the track array candidates
263   for (Int_t i=0; i<2; ++i){
264     className.Form("Pre_%s",fgkTrackClassNames[i]);
265     if (!fHistos->GetHistogramList()->FindObject(className.Data())) continue;
266     Int_t ntracks=tracks[i]->GetEntriesFast();
267     for (Int_t itrack=0; itrack<ntracks; ++itrack){
268       AliDielectronVarManager::Fill(tracks[i]->UncheckedAt(itrack), values);
269       fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
270     }
271   }
272 }
273 //________________________________________________________________
274 void AliDielectron::FillHistograms(const AliVEvent *ev)
275 {
276   //
277   // Fill Histogram information for tracks and pairs
278   //
279   
280   TString  className,className2;
281   Double_t values[AliDielectronVarManager::kNMaxValues];
282   //Fill event information
283   AliDielectronVarManager::Fill(ev, values);
284   if (fHistos->GetHistogramList()->FindObject("Event"))
285     fHistos->FillClass("Event", AliDielectronVarManager::kNMaxValues, values);
286   
287   //Fill track information, separately for the track array candidates
288   for (Int_t i=0; i<4; ++i){
289     className.Form("Track_%s",fgkTrackClassNames[i]);
290     if (!fHistos->GetHistogramList()->FindObject(className.Data())) continue;
291     Int_t ntracks=fTracks[i].GetEntriesFast();
292     for (Int_t itrack=0; itrack<ntracks; ++itrack){
293       AliDielectronVarManager::Fill(fTracks[i].UncheckedAt(itrack), values);
294       fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
295     }
296   }
297
298   //Fill Pair information, separately for all pair candidate arrays and the legs
299   TObjArray arrLegs(100);
300   for (Int_t i=0; i<10; ++i){
301     className.Form("Pair_%s",fgkPairClassNames[i]);
302     className2.Form("Track_Legs_%s",fgkPairClassNames[i]);
303     Bool_t pairClass=fHistos->GetHistogramList()->FindObject(className.Data())!=0x0;
304     Bool_t legClass=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
305     if (!pairClass&&!legClass) continue;
306     Int_t ntracks=PairArray(i)->GetEntriesFast();
307     for (Int_t ipair=0; ipair<ntracks; ++ipair){
308       AliDielectronPair *pair=static_cast<AliDielectronPair*>(PairArray(i)->UncheckedAt(ipair));
309       
310       //fill pair information
311       if (pairClass){
312         AliDielectronVarManager::Fill(pair, values);
313         fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
314       }
315
316       //fill leg information, don't fill the information twice
317       if (legClass){
318         AliVParticle *d1=pair->GetFirstDaughter();
319         AliVParticle *d2=pair->GetSecondDaughter();
320         if (!arrLegs.FindObject(d1)){
321           AliDielectronVarManager::Fill(d1, values);
322           fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
323           arrLegs.Add(d1);
324         }
325         if (!arrLegs.FindObject(d2)){
326           AliDielectronVarManager::Fill(d2, values);
327           fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
328           arrLegs.Add(d2);
329         }
330       }
331     }
332     if (legClass) arrLegs.Clear();
333   }
334   
335 }
336 //________________________________________________________________
337 void AliDielectron::FillHistogramsPair(AliDielectronPair *pair,Bool_t fromPreFilter/*=kFALSE*/)
338 {
339   //
340   // Fill Histogram information for pairs and the track in the pair
341   // NOTE: in this funtion the leg information may be filled multiple
342   //       times. This funtion is used in the track rotation pairing
343   //       and those legs are not saved!
344   //
345   TString  className,className2;
346   Double_t values[AliDielectronVarManager::kNMaxValues];
347   
348   //Fill Pair information, separately for all pair candidate arrays and the legs
349   TObjArray arrLegs(100);
350   const Int_t type=pair->GetType();
351   if (fromPreFilter) {
352     className.Form("RejPair_%s",fgkPairClassNames[type]);
353     className2.Form("RejTrack_%s",fgkPairClassNames[type]);
354   } else {
355     className.Form("Pair_%s",fgkPairClassNames[type]);
356     className2.Form("Track_Legs_%s",fgkPairClassNames[type]);
357   }
358   
359   Bool_t pairClass=fHistos->GetHistogramList()->FindObject(className.Data())!=0x0;
360   Bool_t legClass=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
361   
362   //fill pair information
363   if (pairClass){
364     AliDielectronVarManager::Fill(pair, values);
365     fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
366   }
367
368   if (legClass){
369     AliVParticle *d1=pair->GetFirstDaughter();
370     AliDielectronVarManager::Fill(d1, values);
371     fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
372     
373     AliVParticle *d2=pair->GetSecondDaughter();
374     AliDielectronVarManager::Fill(d2, values);
375     fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
376   }
377 }
378
379 //________________________________________________________________
380 void AliDielectron::FillTrackArrays(AliVEvent * const ev, Int_t eventNr)
381 {
382   //
383   // select tracks and fill track candidate arrays
384   // eventNr = 0: First  event, use track arrays 0 and 1
385   // eventNr = 1: Second event, use track arrays 2 and 3
386   //
387   
388   Int_t ntracks=ev->GetNumberOfTracks();
389   UInt_t selectedMask=(1<<fTrackFilter.GetCuts()->GetEntries())-1;
390   for (Int_t itrack=0; itrack<ntracks; ++itrack){
391     //get particle
392     AliVParticle *particle=ev->GetTrack(itrack);
393     //TODO: temporary solution, perhaps think about a better implementation
394     //      This is needed to use AliESDpidCuts, which relies on the ESD event
395     //      is set as a AliESDtrack attribute... somehow ugly!
396     if (ev->IsA()==AliESDEvent::Class()){
397       AliESDtrack *track=static_cast<AliESDtrack*>(particle);
398       track->SetESDEvent(static_cast<AliESDEvent*>(ev)); //only in trunk...
399     }
400     
401     //apply track cuts
402     if (fTrackFilter.IsSelected(particle)!=selectedMask) continue;
403     
404     //fill selected particle into the corresponding track arrays
405     Short_t charge=particle->Charge();
406     if (charge>0)      fTracks[eventNr*2].Add(particle);
407     else if (charge<0) fTracks[eventNr*2+1].Add(particle);
408   }
409 }
410
411 //________________________________________________________________
412 void AliDielectron::PairPreFilter(Int_t arr1, Int_t arr2, TObjArray &arrTracks1, TObjArray &arrTracks2)
413 {
414   //
415   // Prefilter tracks from pairs
416   // Needed for datlitz rejections
417   // remove all tracks from the Single track arrays that pass the cuts in this filter
418   //
419   Int_t pairIndex=GetPairIndex(arr1,arr2);
420   
421   Int_t ntrack1=arrTracks1.GetEntriesFast();
422   Int_t ntrack2=arrTracks2.GetEntriesFast();
423   
424   AliDielectronPair candidate;
425   
426   UInt_t selectedMask=(1<<fPairPreFilter.GetCuts()->GetEntries())-1;
427   UInt_t selectedMaskPair=(1<<fPairFilter.GetCuts()->GetEntries())-1;
428   
429   for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
430     Int_t end=ntrack2;
431     if (arr1==arr2) end=itrack1;
432     Bool_t accepted=kFALSE;
433     for (Int_t itrack2=0; itrack2<end; ++itrack2){
434       AliVTrack *track1=static_cast<AliVTrack*>(arrTracks1.UncheckedAt(itrack1));
435       AliVTrack *track2=static_cast<AliVTrack*>(arrTracks2.UncheckedAt(itrack2));
436       if (!track1 || !track2) continue;
437       //create the pair
438       candidate.SetTracks(track1, fPdgLeg1,
439                           track2, fPdgLeg2);
440       candidate.SetType(pairIndex);
441       candidate.SetLabel(AliDielectronMC::Instance()->GetLabelMotherWithPdg(&candidate,fPdgMother));
442       
443       //pair cuts
444       UInt_t cutMask=fPairPreFilter.IsSelected(&candidate);
445       
446       //apply cut
447       if (cutMask!=selectedMask) continue;
448       if (fCfManagerPair) fCfManagerPair->Fill(selectedMaskPair+1 ,&candidate);
449       accepted=kTRUE;
450       FillHistogramsPair(&candidate,kTRUE);
451       //remove the tracks from the Track arrays
452       arrTracks2.AddAt(0x0,itrack2);
453       //in case of like sign remove the track from both arrays!
454       if (arr1==arr2) arrTracks1.AddAt(0x0, itrack2);
455     }
456     if ( accepted ) arrTracks1.AddAt(0x0,itrack1);
457   }
458   //compress the track arrays
459   
460
461
462   arrTracks1.Compress();
463   arrTracks2.Compress();
464   
465   //apply leg cuts after the pre filter
466   if ( fPairPreFilterLegs.GetCuts()->GetEntries()>0 ) {
467     selectedMask=(1<<fPairPreFilterLegs.GetCuts()->GetEntries())-1;
468     //loop over tracks from array 1
469     for (Int_t itrack=0; itrack<arrTracks1.GetEntriesFast();++itrack){
470       //test cuts
471       UInt_t cutMask=fPairPreFilterLegs.IsSelected(arrTracks1.UncheckedAt(itrack));
472       
473       //apply cut
474       if (cutMask!=selectedMask) arrTracks1.AddAt(0x0,itrack);;
475     }
476     arrTracks1.Compress();
477     
478     //in case of like sign don't loop over second array
479     if (arr1==arr2) {
480       arrTracks2=arrTracks1;
481     } else {
482       
483       //loop over tracks from array 2
484       for (Int_t itrack=0; itrack<arrTracks2.GetEntriesFast();++itrack){
485       //test cuts
486         UInt_t cutMask=fPairPreFilterLegs.IsSelected(arrTracks2.UncheckedAt(itrack));
487       //apply cut
488         if (cutMask!=selectedMask) arrTracks2.AddAt(0x0,itrack);
489       }
490       arrTracks2.Compress();
491       
492     }
493   }
494   //For unlike-sign monitor track-cuts:
495   if (arr1!=arr2) {
496     TObjArray *unlikesignArray[2] = {&arrTracks1,&arrTracks2};
497     FillHistogramsTracks(unlikesignArray);
498   }
499 }
500
501 //________________________________________________________________
502 void AliDielectron::FillPairArrays(Int_t arr1, Int_t arr2)
503 {
504   //
505   // select pairs and fill pair candidate arrays
506   //
507
508   TObjArray arrTracks1=fTracks[arr1];
509   TObjArray arrTracks2=fTracks[arr2];
510
511   //process pre filter if set
512   if ((!fPreFilterUnlikeOnly) && ( fPairPreFilter.GetCuts()->GetEntries()>0 ))  PairPreFilter(arr1, arr2, arrTracks1, arrTracks2);
513   
514   Int_t pairIndex=GetPairIndex(arr1,arr2);
515
516   Int_t ntrack1=arrTracks1.GetEntriesFast();
517   Int_t ntrack2=arrTracks2.GetEntriesFast();
518
519   AliDielectronPair *candidate=new AliDielectronPair;
520
521   UInt_t selectedMask=(1<<fPairFilter.GetCuts()->GetEntries())-1;
522   
523   for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
524     Int_t end=ntrack2;
525     if (arr1==arr2) end=itrack1;
526     for (Int_t itrack2=0; itrack2<end; ++itrack2){
527       //create the pair
528       candidate->SetTracks(static_cast<AliVTrack*>(arrTracks1.UncheckedAt(itrack1)), fPdgLeg1,
529                            static_cast<AliVTrack*>(arrTracks2.UncheckedAt(itrack2)), fPdgLeg2);
530       candidate->SetType(pairIndex);
531       candidate->SetLabel(AliDielectronMC::Instance()->GetLabelMotherWithPdg(candidate,fPdgMother));
532
533       //pair cuts
534       UInt_t cutMask=fPairFilter.IsSelected(candidate);
535       
536       //CF manager for the pair
537       if (fCfManagerPair) fCfManagerPair->Fill(cutMask,candidate);
538
539       //apply cut
540       if (cutMask!=selectedMask) continue;
541
542       //add the candidate to the candidate array 
543       PairArray(pairIndex)->Add(candidate);
544       //get a new candidate
545       candidate=new AliDielectronPair;
546     }
547   }
548   //delete the surplus candidate
549   delete candidate;
550 }
551
552 //________________________________________________________________
553 void AliDielectron::FillPairArrayTR()
554 {
555   //
556   // select pairs and fill pair candidate arrays
557   //
558   UInt_t selectedMask=(1<<fPairFilter.GetCuts()->GetEntries())-1;
559   
560   while ( fTrackRotator->NextCombination() ){
561     AliDielectronPair candidate;
562     candidate.SetTracks(fTrackRotator->GetTrackP(), fPdgLeg1, fTrackRotator->GetTrackN(), fPdgLeg2);
563     candidate.SetType(kEv1PMRot);
564     
565     //pair cuts
566     UInt_t cutMask=fPairFilter.IsSelected(&candidate);
567     
568     //CF manager for the pair
569     if (fCfManagerPair) fCfManagerPair->Fill(cutMask,&candidate);
570     
571     //apply cut
572     if (cutMask==selectedMask&&fHistos) FillHistogramsPair(&candidate);
573   }
574 }
575
576 //________________________________________________________________
577 void AliDielectron::FillDebugTree()
578 {
579   //
580   // Fill Histogram information for tracks and pairs
581   //
582   
583   //Fill Debug tree
584   for (Int_t i=0; i<10; ++i){
585     Int_t ntracks=PairArray(i)->GetEntriesFast();
586     for (Int_t ipair=0; ipair<ntracks; ++ipair){
587       fDebugTree->Fill(static_cast<AliDielectronPair*>(PairArray(i)->UncheckedAt(ipair)));
588     }
589   }
590 }
591
592 //________________________________________________________________
593 void AliDielectron::SaveDebugTree()
594 {
595   //
596   // delete the debug tree, this will also write the tree
597   //
598   if (fDebugTree) fDebugTree->DeleteStreamer();
599 }
600