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 -)
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 "AliDielectronDebugTree.h"
62 #include "AliDielectron.h"
64 ClassImp(AliDielectron)
66 const char* AliDielectron::fgkTrackClassNames[4] = {
73 const char* AliDielectron::fgkPairClassNames[10] = {
86 //________________________________________________________________
87 AliDielectron::AliDielectron() :
88 TNamed("AliDielectron","AliDielectron"),
89 fEventFilter("EventFilter"),
90 fTrackFilter("TrackFilter"),
91 fPairPreFilter("PairPreFilter"),
92 fPairPreFilterLegs("PairPreFilterLegs"),
93 fPairFilter("PairFilter"),
98 fPairCandidates(new TObjArray(10)),
103 // Default constructor
108 //________________________________________________________________
109 AliDielectron::AliDielectron(const char* name, const char* title) :
111 fEventFilter("EventFilter"),
112 fTrackFilter("TrackFilter"),
113 fPairPreFilter("PairPreFilter"),
114 fPairPreFilterLegs("PairPreFilterLegs"),
115 fPairFilter("PairFilter"),
120 fPairCandidates(new TObjArray(10)),
130 //________________________________________________________________
131 AliDielectron::~AliDielectron()
134 // Default destructor
136 if (fHistos) delete fHistos;
137 if (fPairCandidates) delete fPairCandidates;
138 if (fDebugTree) delete fDebugTree;
141 //________________________________________________________________
142 void AliDielectron::Init()
145 // Initialise objects
147 if (fCfManagerPair) fCfManagerPair->InitialiseContainer(fPairFilter);
148 if (fDebugTree) fDebugTree->SetDielectron(this);
151 //________________________________________________________________
152 void AliDielectron::Process(AliVEvent *ev1, AliVEvent *ev2)
155 // Process the events
158 AliDielectronVarManager::SetEvent(ev1);
160 //in case we have MC load the MC event and process the MC particles
161 if (AliDielectronMC::Instance()->HasMC()) {
162 if (!AliDielectronMC::Instance()->ConnectMCEvent()){
163 AliError("Could not properly connect the MC event, skipping this event!");
169 //if candidate array doesn't exist, create it
170 if (!fPairCandidates->UncheckedAt(0)) {
171 InitPairCandidateArrays();
176 //mask used to require that all cuts are fulfilled
177 UInt_t selectedMask=(1<<fEventFilter.GetCuts()->GetEntries())-1;
180 if ((ev1&&fEventFilter.IsSelected(ev1)!=selectedMask) ||
181 (ev2&&fEventFilter.IsSelected(ev2)!=selectedMask)) return;
183 AliDielectronVarManager::SetEvent(ev1);
185 //fill track arrays for the first event
186 if (ev1) FillTrackArrays(ev1);
188 //fill track arrays for the second event
189 if (ev2) FillTrackArrays(ev2,1);
191 // create pairs and fill pair candidate arrays
192 for (Int_t itrackArr1=0; itrackArr1<4; ++itrackArr1){
193 for (Int_t itrackArr2=itrackArr1; itrackArr2<4; ++itrackArr2){
194 FillPairArrays(itrackArr1, itrackArr2);
198 //in case there is a histogram manager, fill the QA histograms
199 if (fHistos) FillHistograms(ev1);
201 //fill debug tree if a manager is attached
202 if (fDebugTree) FillDebugTree();
205 //________________________________________________________________
206 void AliDielectron::ProcessMC()
209 // Process the MC data
212 //loop over all MC data and Fill the CF container if it exist
213 if (!fCfManagerPair) return;
214 fCfManagerPair->SetPdgMother(fPdgMother);
215 AliDielectronMC *dieMC=AliDielectronMC::Instance();
216 for (Int_t ipart=0; ipart<dieMC->GetNMCTracks();++ipart){
217 //TODO: MC truth cut properly!!!
218 AliVParticle *mcPart=dieMC->GetMCTrackFromMCEvent(ipart);
219 if (!dieMC->IsMCMotherToEE(mcPart, fPdgMother)) continue;
220 fCfManagerPair->FillMC(mcPart);
224 //________________________________________________________________
225 void AliDielectron::FillHistograms(const AliVEvent *ev)
228 // Fill Histogram information for tracks and pairs
231 TString className,className2;
232 Double_t values[AliDielectronVarManager::kNMaxValues];
233 //Fill event information
234 AliDielectronVarManager::Fill(ev, values);
235 if (fHistos->GetHistogramList()->FindObject("Event"))
236 fHistos->FillClass("Event", AliDielectronVarManager::kNMaxValues, values);
238 //Fill track information, separately for the track array candidates
239 for (Int_t i=0; i<4; ++i){
240 className.Form("Track_%s",fgkTrackClassNames[i]);
241 if (!fHistos->GetHistogramList()->FindObject(className.Data())) continue;
242 Int_t ntracks=fTracks[i].GetEntriesFast();
243 for (Int_t itrack=0; itrack<ntracks; ++itrack){
244 AliDielectronVarManager::Fill(fTracks[i].UncheckedAt(itrack), values);
245 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
249 //Fill Pair information, separately for all pair candidate arrays and the legs
250 TObjArray arrLegs(100);
251 for (Int_t i=0; i<10; ++i){
252 className.Form("Pair_%s",fgkPairClassNames[i]);
253 className2.Form("Track_Legs_%s",fgkPairClassNames[i]);
254 Bool_t pairClass=fHistos->GetHistogramList()->FindObject(className.Data())!=0x0;
255 Bool_t legClass=fHistos->GetHistogramList()->FindObject(className2.Data())!=0x0;
256 if (!pairClass&&!legClass) continue;
257 Int_t ntracks=PairArray(i)->GetEntriesFast();
258 for (Int_t ipair=0; ipair<ntracks; ++ipair){
259 AliDielectronPair *pair=static_cast<AliDielectronPair*>(PairArray(i)->UncheckedAt(ipair));
261 //fill pair information
263 AliDielectronVarManager::Fill(pair, values);
264 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
267 //fill leg information, don't fill the information twice
269 AliVParticle *d1=pair->GetFirstDaughter();
270 AliVParticle *d2=pair->GetSecondDaughter();
271 if (!arrLegs.FindObject(d1)){
272 AliDielectronVarManager::Fill(d1, values);
273 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
276 if (!arrLegs.FindObject(d2)){
277 AliDielectronVarManager::Fill(d2, values);
278 fHistos->FillClass(className2, AliDielectronVarManager::kNMaxValues, values);
283 if (legClass) arrLegs.Clear();
288 //________________________________________________________________
289 void AliDielectron::FillTrackArrays(AliVEvent * const ev, Int_t eventNr)
292 // select tracks and fill track candidate arrays
293 // eventNr = 0: First event, use track arrays 0 and 1
294 // eventNr = 1: Second event, use track arrays 2 and 3
297 Int_t ntracks=ev->GetNumberOfTracks();
298 UInt_t selectedMask=(1<<fTrackFilter.GetCuts()->GetEntries())-1;
299 for (Int_t itrack=0; itrack<ntracks; ++itrack){
301 AliVParticle *particle=ev->GetTrack(itrack);
302 //TODO: temporary solution, perhaps think about a better implementation
303 // This is needed to use AliESDpidCuts, which relies on the ESD event
304 // is set as a AliESDtrack attribute... somehow ugly!
305 if (ev->IsA()==AliESDEvent::Class()){
306 AliESDtrack *track=static_cast<AliESDtrack*>(particle);
307 track->SetESDEvent(static_cast<AliESDEvent*>(ev)); //only in trunk...
311 if (fTrackFilter.IsSelected(particle)!=selectedMask) continue;
313 //fill selected particle into the corresponding track arrays
314 Short_t charge=particle->Charge();
315 if (charge>0) fTracks[eventNr*2].Add(particle);
316 else if (charge<0) fTracks[eventNr*2+1].Add(particle);
320 //________________________________________________________________
321 void AliDielectron::PairPreFilter(Int_t arr1, Int_t arr2, TObjArray &arrTracks1, TObjArray &arrTracks2) {
323 // Prefilter tracks from pairs
324 // Needed for datlitz rejections
325 // remove all tracks from the Single track arrays that pass the cuts in this filter
327 Int_t pairIndex=GetPairIndex(arr1,arr2);
329 Int_t ntrack1=arrTracks1.GetEntriesFast();
330 Int_t ntrack2=arrTracks2.GetEntriesFast();
332 AliDielectronPair candidate;
334 UInt_t selectedMask=(1<<fPairPreFilter.GetCuts()->GetEntries())-1;
336 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
338 if (arr1==arr2) end=itrack1;
339 Bool_t accepted=kFALSE;
340 for (Int_t itrack2=0; itrack2<end; ++itrack2){
341 AliVTrack *track1=static_cast<AliVTrack*>(arrTracks1.UncheckedAt(itrack1));
342 AliVTrack *track2=static_cast<AliVTrack*>(arrTracks2.UncheckedAt(itrack2));
343 if (!track1 || !track2) continue;
345 candidate.SetTracks(track1, fPdgLeg1,
347 candidate.SetType(pairIndex);
348 candidate.SetLabel(AliDielectronMC::Instance()->GetLabelMotherWithPdg(&candidate,fPdgMother));
351 UInt_t cutMask=fPairPreFilter.IsSelected(&candidate);
354 if (cutMask!=selectedMask) continue;
356 //remove the tracks from the Track arrays
357 arrTracks2.AddAt(0x0,itrack2);
358 //in case of like sign remove the track from both arrays!
359 if (arr1==arr2) arrTracks1.AddAt(0x0, itrack2);
361 if ( accepted ) arrTracks1.AddAt(0x0,itrack1);
363 //compress the track arrays
364 arrTracks1.Compress();
365 arrTracks2.Compress();
367 //apply leg cuts after the pre filter
368 if ( fPairPreFilterLegs.GetCuts()->GetEntries()>0 ) {
369 selectedMask=(1<<fPairPreFilterLegs.GetCuts()->GetEntries())-1;
370 //loop over tracks from array 1
371 for (Int_t itrack=0; itrack<arrTracks1.GetEntriesFast();++itrack){
373 UInt_t cutMask=fPairPreFilterLegs.IsSelected(arrTracks1.UncheckedAt(itrack));
375 if (cutMask!=selectedMask) arrTracks1.AddAt(0x0,itrack);;
377 arrTracks1.Compress();
379 //in case of like sign don't loop over second array
381 arrTracks2=arrTracks1;
384 //loop over tracks from array 2
385 for (Int_t itrack=0; itrack<arrTracks2.GetEntriesFast();++itrack){
387 UInt_t cutMask=fPairPreFilterLegs.IsSelected(arrTracks2.UncheckedAt(itrack));
389 if (cutMask!=selectedMask) arrTracks2.AddAt(0x0,itrack);
391 arrTracks2.Compress();
397 //________________________________________________________________
398 void AliDielectron::FillPairArrays(Int_t arr1, Int_t arr2) {
400 // select pairs and fill pair candidate arrays
403 TObjArray arrTracks1=fTracks[arr1];
404 TObjArray arrTracks2=fTracks[arr2];
406 //process pre filter if set
407 if ( fPairPreFilter.GetCuts()->GetEntries()>0 ) PairPreFilter(arr1, arr2, arrTracks1, arrTracks2);
409 Int_t pairIndex=GetPairIndex(arr1,arr2);
411 Int_t ntrack1=arrTracks1.GetEntriesFast();
412 Int_t ntrack2=arrTracks2.GetEntriesFast();
414 AliDielectronPair *candidate=new AliDielectronPair;
416 UInt_t selectedMask=(1<<fPairFilter.GetCuts()->GetEntries())-1;
418 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
420 if (arr1==arr2) end=itrack1;
421 for (Int_t itrack2=0; itrack2<end; ++itrack2){
423 candidate->SetTracks(static_cast<AliVTrack*>(arrTracks1.UncheckedAt(itrack1)), fPdgLeg1,
424 static_cast<AliVTrack*>(arrTracks2.UncheckedAt(itrack2)), fPdgLeg2);
425 candidate->SetType(pairIndex);
426 candidate->SetLabel(AliDielectronMC::Instance()->GetLabelMotherWithPdg(candidate,fPdgMother));
429 UInt_t cutMask=fPairFilter.IsSelected(candidate);
431 //CF manager for the pair
432 if (fCfManagerPair) fCfManagerPair->Fill(cutMask,candidate);
435 if (cutMask!=selectedMask) continue;
437 //add the candidate to the candidate array
438 PairArray(pairIndex)->Add(candidate);
439 //get a new candidate
440 candidate=new AliDielectronPair;
443 //delete the surplus candidate
447 //________________________________________________________________
448 void AliDielectron::FillDebugTree()
451 // Fill Histogram information for tracks and pairs
455 for (Int_t i=0; i<10; ++i){
456 Int_t ntracks=PairArray(i)->GetEntriesFast();
457 for (Int_t ipair=0; ipair<ntracks; ++ipair){
458 fDebugTree->Fill(static_cast<AliDielectronPair*>(PairArray(i)->UncheckedAt(ipair)));
463 //________________________________________________________________
464 void AliDielectron::SaveDebugTree()
467 // delete the debug tree, this will also write the tree
469 if (fDebugTree) fDebugTree->DeleteStreamer();