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 fPairFilter("PairFilter"),
94 fPairCandidates(new TObjArray(10)),
99 // Default constructor
104 //________________________________________________________________
105 AliDielectron::AliDielectron(const char* name, const char* title) :
107 fEventFilter("EventFilter"),
108 fTrackFilter("TrackFilter"),
109 fPairFilter("PairFilter"),
112 fPairCandidates(new TObjArray(10)),
122 //________________________________________________________________
123 AliDielectron::~AliDielectron()
126 // Default destructor
128 if (fHistos) delete fHistos;
129 if (fPairCandidates) delete fPairCandidates;
130 if (fDebugTree) delete fDebugTree;
133 //________________________________________________________________
134 void AliDielectron::Init()
137 // Initialise objects
139 if (fCfManagerPair) fCfManagerPair->InitialiseContainer(fPairFilter);
143 //________________________________________________________________
144 void AliDielectron::Process(AliVEvent *ev1, AliVEvent *ev2)
147 // Process the events
150 AliDielectronVarManager::SetEvent(ev1);
152 //in case we have MC load the MC event and process the MC particles
153 if (AliDielectronMC::Instance()->HasMC()) {
154 AliDielectronMC::Instance()->ConnectMCEvent();
158 //if candidate array doesn't exist, create it
159 if (!fPairCandidates->UncheckedAt(0)) {
160 InitPairCandidateArrays();
165 //mask used to require that all cuts are fulfilled
166 UInt_t selectedMask=(1<<fEventFilter.GetCuts()->GetEntries())-1;
169 if ((ev1&&fEventFilter.IsSelected(ev1)!=selectedMask) ||
170 (ev2&&fEventFilter.IsSelected(ev2)!=selectedMask)) return;
172 AliDielectronVarManager::SetEvent(ev1);
174 //fill track arrays for the first event
175 if (ev1) FillTrackArrays(ev1);
177 //fill track arrays for the second event
178 if (ev2) FillTrackArrays(ev2,1);
180 // create pairs and fill pair candidate arrays
181 for (Int_t itrackArr1=0; itrackArr1<4; ++itrackArr1){
182 for (Int_t itrackArr2=itrackArr1; itrackArr2<4; ++itrackArr2){
183 FillPairArrays(itrackArr1, itrackArr2);
187 //in case there is a histogram manager, fill the QA histograms
188 if (fHistos) FillHistograms(ev1);
190 //fill debug tree if a manager is attached
191 if (fDebugTree) FillDebugTree();
194 //________________________________________________________________
195 void AliDielectron::ProcessMC()
198 // Process the MC data
201 //loop over all MC data and Fill the CF container if it exist
202 if (!fCfManagerPair) return;
203 fCfManagerPair->SetPdgMother(fPdgMother);
204 AliDielectronMC *dieMC=AliDielectronMC::Instance();
205 for (Int_t ipart=0; ipart<dieMC->GetNMCTracks();++ipart){
206 //TODO: MC truth cut properly!!!
207 AliVParticle *mcPart=dieMC->GetMCTrackFromMCEvent(ipart);
208 if (!dieMC->IsMCMotherToEE(mcPart, fPdgMother)) continue;
209 fCfManagerPair->FillMC(mcPart);
213 //________________________________________________________________
214 void AliDielectron::FillHistograms(const AliVEvent *ev)
217 // Fill Histogram information for tracks and pairs
221 Double_t values[AliDielectronVarManager::kNMaxValues];
222 //Fill event information
223 AliDielectronVarManager::Fill(ev, values);
224 fHistos->FillClass("Event", AliDielectronVarManager::kNMaxValues, values);
226 //Fill track information, separately for the track array candidates
227 for (Int_t i=0; i<4; ++i){
228 className.Form("Track_%s",fgkTrackClassNames[i]);
229 Int_t ntracks=fTracks[i].GetEntriesFast();
230 for (Int_t itrack=0; itrack<ntracks; ++itrack){
231 AliDielectronVarManager::Fill(fTracks[i].UncheckedAt(itrack), values);
232 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
236 //Fill Pair information, separately for all pair candidate arrays
237 for (Int_t i=0; i<10; ++i){
238 className.Form("Pair_%s",fgkPairClassNames[i]);
239 Int_t ntracks=PairArray(i)->GetEntriesFast();
240 for (Int_t ipair=0; ipair<ntracks; ++ipair){
241 AliDielectronVarManager::Fill(PairArray(i)->UncheckedAt(ipair), values);
242 fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
248 //________________________________________________________________
249 void AliDielectron::FillTrackArrays(AliVEvent * const ev, Int_t eventNr)
252 // select tracks and fill track candidate arrays
253 // eventNr = 0: First event, use track arrays 0 and 1
254 // eventNr = 1: Second event, use track arrays 2 and 3
257 Int_t ntracks=ev->GetNumberOfTracks();
258 UInt_t selectedMask=(1<<fTrackFilter.GetCuts()->GetEntries())-1;
259 for (Int_t itrack=0; itrack<ntracks; ++itrack){
261 AliVParticle *particle=ev->GetTrack(itrack);
262 //TODO: temporary solution, perhaps think about a better implementation
263 // This is needed to use AliESDpidCuts, which relies on the ESD event
264 // is set as a AliESDtrack attribute... somehow ugly!
265 if (ev->IsA()==AliESDEvent::Class()){
266 AliESDtrack *track=static_cast<AliESDtrack*>(particle);
267 track->SetESDEvent(static_cast<AliESDEvent*>(ev)); //only in trunk...
271 if (fTrackFilter.IsSelected(particle)!=selectedMask) continue;
273 //fill selected particle into the corresponding track arrays
274 Short_t charge=particle->Charge();
275 if (charge>0) fTracks[eventNr*2].Add(particle);
276 else if (charge<0) fTracks[eventNr*2+1].Add(particle);
280 //________________________________________________________________
281 void AliDielectron::FillPairArrays(Int_t arr1, Int_t arr2) {
283 // select pairs and fill pair candidate arrays
285 Int_t pairIndex=GetPairIndex(arr1,arr2);
287 Int_t ntrack1=fTracks[arr1].GetEntriesFast();
288 Int_t ntrack2=fTracks[arr2].GetEntriesFast();
290 AliDielectronPair *candidate=new AliDielectronPair;
292 UInt_t selectedMask=(1<<fPairFilter.GetCuts()->GetEntries())-1;
294 for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
296 if (arr1==arr2) end=itrack1;
297 for (Int_t itrack2=0; itrack2<end; ++itrack2){
298 //create the pair TODO: change hardcoded PID of tracks
299 candidate->SetTracks(static_cast<AliVTrack*>(fTracks[arr1].UncheckedAt(itrack1)), 11,
300 static_cast<AliVTrack*>(fTracks[arr2].UncheckedAt(itrack2)), 11);
301 candidate->SetType(pairIndex);
302 candidate->SetLabel(AliDielectronMC::Instance()->GetLabelMotherWithPdg(candidate,fPdgMother));
305 UInt_t cutMask=fPairFilter.IsSelected(candidate);
307 //CF manager for the pair
308 if (fCfManagerPair) fCfManagerPair->Fill(cutMask,candidate);
311 if (cutMask!=selectedMask) continue;
313 //add the candidate to the candidate array
314 PairArray(pairIndex)->Add(candidate);
315 //get a new candidate
316 candidate=new AliDielectronPair;
319 //delete the surplus candidate
323 //________________________________________________________________
324 void AliDielectron::FillDebugTree()
327 // Fill Histogram information for tracks and pairs
331 for (Int_t i=0; i<10; ++i){
332 Int_t ntracks=PairArray(i)->GetEntriesFast();
333 for (Int_t ipair=0; ipair<ntracks; ++ipair){
334 fDebugTree->Fill(static_cast<AliDielectronPair*>(PairArray(i)->UncheckedAt(ipair)));
339 //________________________________________________________________
340 void AliDielectron::SaveDebugTree()
343 // delete the debug tree, this will also write the tree
345 if (fDebugTree) fDebugTree->DeleteStreamer();