1 /*************************************************************************
2 * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 ///////////////////////////////////////////////////////////////////////////
17 // Dielectron Analysis Main class //
20 Framework to perform event selectoin, single track selection and track pair
23 Convention for the signs of the pair in fPairCandidates:
24 The names are available via the function PairClassName(Int_t i)
26 0: ev1+ ev1+ (same event like sign +)
27 1: ev1+ ev1- (same event unlike sign)
28 2: ev1- ev1- (same event like sign -)
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 -)
35 5: ev2+ ev2+ (same event like sign +)
36 8: ev2+ ev2- (same event unlike sign)
37 9: ev2- ev2- (same event like sign -)
39 10: ev1+ ev1- (same event track rotation)
43 ///////////////////////////////////////////////////////////////////////////
49 #include <AliESDEvent.h>
50 #include <AliESDtrack.h>
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"
63 #include "AliDielectron.h"
65 ClassImp(AliDielectron)
67 const char* AliDielectron::fgkTrackClassNames[4] = {
74 const char* AliDielectron::fgkPairClassNames[11] = {
88 //________________________________________________________________
89 AliDielectron::AliDielectron() :
90 TNamed("AliDielectron","AliDielectron"),
91 fEventFilter("EventFilter"),
92 fTrackFilter("TrackFilter"),
93 fPairPreFilter("PairPreFilter"),
94 fPairPreFilterLegs("PairPreFilterLegs"),
95 fPairFilter("PairFilter"),
101 fPairCandidates(new TObjArray(10)),
105 fPreFilterUnlikeOnly(kFALSE)
108 // Default constructor
113 //________________________________________________________________
114 AliDielectron::AliDielectron(const char* name, const char* title) :
116 fEventFilter("EventFilter"),
117 fTrackFilter("TrackFilter"),
118 fPairPreFilter("PairPreFilter"),
119 fPairPreFilterLegs("PairPreFilterLegs"),
120 fPairFilter("PairFilter"),
126 fPairCandidates(new TObjArray(10)),
130 fPreFilterUnlikeOnly(kFALSE)
138 //________________________________________________________________
139 AliDielectron::~AliDielectron()
142 // Default destructor
144 if (fHistos) delete fHistos;
145 if (fPairCandidates) delete fPairCandidates;
146 if (fDebugTree) delete fDebugTree;
149 //________________________________________________________________
150 void AliDielectron::Init()
153 // Initialise objects
155 if (fCfManagerPair) fCfManagerPair->InitialiseContainer(fPairFilter);
156 if (fTrackRotator) fTrackRotator->SetTrackArrays(&fTracks[0],&fTracks[1]);
157 if (fDebugTree) fDebugTree->SetDielectron(this);
160 //________________________________________________________________
161 void AliDielectron::Process(AliVEvent *ev1, AliVEvent *ev2)
164 // Process the events
167 //at least first event is needed!
169 AliError("At least first event must be set!");
173 AliDielectronVarManager::SetEvent(ev1);
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!");
184 //if candidate array doesn't exist, create it
185 if (!fPairCandidates->UncheckedAt(0)) {
186 InitPairCandidateArrays();
191 //mask used to require that all cuts are fulfilled
192 UInt_t selectedMask=(1<<fEventFilter.GetCuts()->GetEntries())-1;
195 if ((ev1&&fEventFilter.IsSelected(ev1)!=selectedMask) ||
196 (ev2&&fEventFilter.IsSelected(ev2)!=selectedMask)) return;
198 AliDielectronVarManager::SetEvent(ev1);
200 //fill track arrays for the first event
202 FillTrackArrays(ev1);
203 if ((fPreFilterUnlikeOnly) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) PairPreFilter(0, 1, fTracks[0], fTracks[1]);
207 //fill track arrays for the second event
209 FillTrackArrays(ev2,1);
210 if ((fPreFilterUnlikeOnly) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) PairPreFilter(2, 3, fTracks[2], fTracks[3]);
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);
222 if (fTrackRotator) FillPairArrayTR();
225 //in case there is a histogram manager, fill the QA histograms
226 if (fHistos) FillHistograms(ev1);
228 //fill debug tree if a manager is attached
229 if (fDebugTree) FillDebugTree();
232 //________________________________________________________________
233 void AliDielectron::ProcessMC()
236 // Process the MC data
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);
251 //________________________________________________________________
252 void AliDielectron::FillHistogramsTracks(TObjArray **tracks)
255 // Fill Histogram information for tracks after prefilter
256 // ignore mixed events - for prefilter, only single tracks +/- are relevant
259 TString className,className2;
260 Double_t values[AliDielectronVarManager::kNMaxValues];
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);
273 //________________________________________________________________
274 void AliDielectron::FillHistograms(const AliVEvent *ev)
277 // Fill Histogram information for tracks and pairs
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);
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);
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));
310 //fill pair information
312 AliDielectronVarManager::Fill(pair, values);
313 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
316 //fill leg information, don't fill the information twice
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);
325 if (!arrLegs.FindObject(d2)){
326 AliDielectronVarManager::Fill(d2, values);
327 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
332 if (legClass) arrLegs.Clear();
336 //________________________________________________________________
337 void AliDielectron::FillHistogramsPair(AliDielectronPair *pair,Bool_t fromPreFilter/*=kFALSE*/)
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!
345 TString className,className2;
346 Double_t values[AliDielectronVarManager::kNMaxValues];
348 //Fill Pair information, separately for all pair candidate arrays and the legs
349 TObjArray arrLegs(100);
350 const Int_t type=pair->GetType();
352 className.Form("RejPair_%s",fgkPairClassNames[type]);
353 className2.Form("RejTrack_%s",fgkPairClassNames[type]);
355 className.Form("Pair_%s",fgkPairClassNames[type]);
356 className2.Form("Track_Legs_%s",fgkPairClassNames[type]);
359 Bool_t pairClass=fHistos->GetHistogramList()->FindObject(className.Data())!=0x0;
360 Bool_t legClass=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
362 //fill pair information
364 AliDielectronVarManager::Fill(pair, values);
365 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
369 AliVParticle *d1=pair->GetFirstDaughter();
370 AliDielectronVarManager::Fill(d1, values);
371 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
373 AliVParticle *d2=pair->GetSecondDaughter();
374 AliDielectronVarManager::Fill(d2, values);
375 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
379 //________________________________________________________________
380 void AliDielectron::FillTrackArrays(AliVEvent * const ev, Int_t eventNr)
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
388 Int_t ntracks=ev->GetNumberOfTracks();
389 UInt_t selectedMask=(1<<fTrackFilter.GetCuts()->GetEntries())-1;
390 for (Int_t itrack=0; itrack<ntracks; ++itrack){
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...
402 if (fTrackFilter.IsSelected(particle)!=selectedMask) continue;
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);
411 //________________________________________________________________
412 void AliDielectron::PairPreFilter(Int_t arr1, Int_t arr2, TObjArray &arrTracks1, TObjArray &arrTracks2)
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
419 Int_t pairIndex=GetPairIndex(arr1,arr2);
421 Int_t ntrack1=arrTracks1.GetEntriesFast();
422 Int_t ntrack2=arrTracks2.GetEntriesFast();
424 AliDielectronPair candidate;
426 UInt_t selectedMask=(1<<fPairPreFilter.GetCuts()->GetEntries())-1;
427 UInt_t selectedMaskPair=(1<<fPairFilter.GetCuts()->GetEntries())-1;
429 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
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;
438 candidate.SetTracks(track1, fPdgLeg1,
440 candidate.SetType(pairIndex);
441 candidate.SetLabel(AliDielectronMC::Instance()->GetLabelMotherWithPdg(&candidate,fPdgMother));
444 UInt_t cutMask=fPairPreFilter.IsSelected(&candidate);
447 if (cutMask!=selectedMask) continue;
448 if (fCfManagerPair) fCfManagerPair->Fill(selectedMaskPair+1 ,&candidate);
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);
456 if ( accepted ) arrTracks1.AddAt(0x0,itrack1);
458 //compress the track arrays
462 arrTracks1.Compress();
463 arrTracks2.Compress();
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){
471 UInt_t cutMask=fPairPreFilterLegs.IsSelected(arrTracks1.UncheckedAt(itrack));
474 if (cutMask!=selectedMask) arrTracks1.AddAt(0x0,itrack);;
476 arrTracks1.Compress();
478 //in case of like sign don't loop over second array
480 arrTracks2=arrTracks1;
483 //loop over tracks from array 2
484 for (Int_t itrack=0; itrack<arrTracks2.GetEntriesFast();++itrack){
486 UInt_t cutMask=fPairPreFilterLegs.IsSelected(arrTracks2.UncheckedAt(itrack));
488 if (cutMask!=selectedMask) arrTracks2.AddAt(0x0,itrack);
490 arrTracks2.Compress();
494 //For unlike-sign monitor track-cuts:
496 TObjArray *unlikesignArray[2] = {&arrTracks1,&arrTracks2};
497 FillHistogramsTracks(unlikesignArray);
501 //________________________________________________________________
502 void AliDielectron::FillPairArrays(Int_t arr1, Int_t arr2)
505 // select pairs and fill pair candidate arrays
508 TObjArray arrTracks1=fTracks[arr1];
509 TObjArray arrTracks2=fTracks[arr2];
511 //process pre filter if set
512 if ((!fPreFilterUnlikeOnly) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) PairPreFilter(arr1, arr2, arrTracks1, arrTracks2);
514 Int_t pairIndex=GetPairIndex(arr1,arr2);
516 Int_t ntrack1=arrTracks1.GetEntriesFast();
517 Int_t ntrack2=arrTracks2.GetEntriesFast();
519 AliDielectronPair *candidate=new AliDielectronPair;
521 UInt_t selectedMask=(1<<fPairFilter.GetCuts()->GetEntries())-1;
523 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
525 if (arr1==arr2) end=itrack1;
526 for (Int_t itrack2=0; itrack2<end; ++itrack2){
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));
534 UInt_t cutMask=fPairFilter.IsSelected(candidate);
536 //CF manager for the pair
537 if (fCfManagerPair) fCfManagerPair->Fill(cutMask,candidate);
540 if (cutMask!=selectedMask) continue;
542 //add the candidate to the candidate array
543 PairArray(pairIndex)->Add(candidate);
544 //get a new candidate
545 candidate=new AliDielectronPair;
548 //delete the surplus candidate
552 //________________________________________________________________
553 void AliDielectron::FillPairArrayTR()
556 // select pairs and fill pair candidate arrays
558 UInt_t selectedMask=(1<<fPairFilter.GetCuts()->GetEntries())-1;
560 while ( fTrackRotator->NextCombination() ){
561 AliDielectronPair candidate;
562 candidate.SetTracks(fTrackRotator->GetTrackP(), fPdgLeg1, fTrackRotator->GetTrackN(), fPdgLeg2);
563 candidate.SetType(kEv1PMRot);
566 UInt_t cutMask=fPairFilter.IsSelected(&candidate);
568 //CF manager for the pair
569 if (fCfManagerPair) fCfManagerPair->Fill(cutMask,&candidate);
572 if (cutMask==selectedMask&&fHistos) FillHistogramsPair(&candidate);
576 //________________________________________________________________
577 void AliDielectron::FillDebugTree()
580 // Fill Histogram information for tracks and pairs
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)));
592 //________________________________________________________________
593 void AliDielectron::SaveDebugTree()
596 // delete the debug tree, this will also write the tree
598 if (fDebugTree) fDebugTree->DeleteStreamer();