]> git.uio.no Git - u/mrichter/AliRoot.git/blame - STEER/AliAODHandler.cxx
By default all events go into one run-loader's file. Allows to remove the correspondi...
[u/mrichter/AliRoot.git] / STEER / AliAODHandler.cxx
CommitLineData
ec4af4c1 1/**************************************************************************
2 * Copyright(c) 1998-2007, 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/* $Id$ */
17
18//-------------------------------------------------------------------------
19// Implementation of the Virtual Event Handler Interface for AOD
20// Author: Andreas Morsch, CERN
21//-------------------------------------------------------------------------
22
052994fb 23
ec4af4c1 24#include <TTree.h>
e910dd36 25#include <TFile.h>
7970f4ac 26#include <TString.h>
dce1b636 27#include <TList.h>
e910dd36 28
da97a08a 29#include "AliLog.h"
ec4af4c1 30#include "AliAODHandler.h"
31#include "AliAODEvent.h"
da97a08a 32#include "AliAODTracklets.h"
33#include "AliStack.h"
34#include "AliAODMCParticle.h"
dce1b636 35#include "AliAODMCHeader.h"
da97a08a 36#include "AliMCEventHandler.h"
37#include "AliMCEvent.h"
dce1b636 38#include "AliGenEventHeader.h"
39#include "AliGenHijingEventHeader.h"
40#include "AliGenDPMjetEventHeader.h"
41#include "AliGenPythiaEventHeader.h"
42#include "AliGenCocktailEventHeader.h"
43
44
ec4af4c1 45
46ClassImp(AliAODHandler)
47
48//______________________________________________________________________________
49AliAODHandler::AliAODHandler() :
f3214a54 50 AliVEventHandler(),
78f7f935 51 fIsStandard(kTRUE),
da97a08a 52 fFillAOD(kTRUE),
7c3a9fbf 53 fNeedsHeaderReplication(kFALSE),
75754ba8 54 fNeedsTracksBranchReplication(kFALSE),
55 fNeedsVerticesBranchReplication(kFALSE),
56 fNeedsV0sBranchReplication(kFALSE),
57 fNeedsTrackletsBranchReplication(kFALSE),
58 fNeedsPMDClustersBranchReplication(kFALSE),
59 fNeedsJetsBranchReplication(kFALSE),
60 fNeedsFMDClustersBranchReplication(kFALSE),
61 fNeedsCaloClustersBranchReplication(kFALSE),
62 fAODIsReplicated(kFALSE),
ec4af4c1 63 fAODEvent(NULL),
da97a08a 64 fMCEventH(NULL),
e910dd36 65 fTreeA(NULL),
66 fFileA(NULL),
7970f4ac 67 fFileName("")
ec4af4c1 68{
69 // default constructor
70}
71
72//______________________________________________________________________________
73AliAODHandler::AliAODHandler(const char* name, const char* title):
f3214a54 74 AliVEventHandler(name, title),
78f7f935 75 fIsStandard(kTRUE),
da97a08a 76 fFillAOD(kTRUE),
7c3a9fbf 77 fNeedsHeaderReplication(kFALSE),
75754ba8 78 fNeedsTracksBranchReplication(kFALSE),
79 fNeedsVerticesBranchReplication(kFALSE),
80 fNeedsV0sBranchReplication(kFALSE),
81 fNeedsTrackletsBranchReplication(kFALSE),
82 fNeedsPMDClustersBranchReplication(kFALSE),
83 fNeedsJetsBranchReplication(kFALSE),
84 fNeedsFMDClustersBranchReplication(kFALSE),
85 fNeedsCaloClustersBranchReplication(kFALSE),
86 fAODIsReplicated(kFALSE),
ec4af4c1 87 fAODEvent(NULL),
da97a08a 88 fMCEventH(NULL),
e910dd36 89 fTreeA(NULL),
90 fFileA(NULL),
7970f4ac 91 fFileName("")
ec4af4c1 92{
93}
94
95//______________________________________________________________________________
96AliAODHandler::~AliAODHandler()
97{
6989bff3 98 delete fAODEvent;
99 if(fFileA){
100 // is already handled in TerminateIO
101 fFileA->Close();
102 delete fFileA;
103 }
104 delete fTreeA;
6989bff3 105 // destructor
ec4af4c1 106}
107
7970f4ac 108//______________________________________________________________________________
300d5701 109Bool_t AliAODHandler::Init(Option_t* opt)
ec4af4c1 110{
6989bff3 111 // Initialize IO
112 //
113 // Create the AODevent object
114 if(!fAODEvent){
ec4af4c1 115 fAODEvent = new AliAODEvent();
78f7f935 116 if (fIsStandard) fAODEvent->CreateStdContent();
6989bff3 117 }
118 //
119 // File opening according to execution mode
7970f4ac 120 TString option(opt);
121 option.ToLower();
122 if (option.Contains("proof")) {
6989bff3 123 // proof
7970f4ac 124 if (option.Contains("special")) {
125 // File for tree already opened on slave -> merging via files
126 fFileA = gFile;
127 CreateTree(1);
128 } else {
129 // Merging in memory
130 CreateTree(0);
131 }
6989bff3 132 } else {
133 // local and grid
26b9ac7a 134 TDirectory *owd = gDirectory;
7970f4ac 135 fFileA = new TFile(fFileName.Data(), "RECREATE");
6989bff3 136 CreateTree(1);
26b9ac7a 137 owd->cd();
6989bff3 138 }
139 return kTRUE;
ec4af4c1 140}
141
da97a08a 142
143void AliAODHandler::StoreMCParticles(){
dce1b636 144
da97a08a 145 //
146 // Remap the labels from ESD stack and store
147 // the AODMCParticles, makes only sense if we have
148 // the mcparticles branch
149 // has to be done here since we cannot know in advance
150 // which particles are needed (e.g. by the tracks etc.)
151 //
152 // Particles have been selected by AliMCEventhanlder->SelectParticle()
153 // To use the MCEventhandler here we need to set it from the outside
154 // can vanish when Handler go to the ANALYSISalice library
dce1b636 155 //
156 // The Branch booking for mcParticles and mcHeader has to happen
157 // in an external task for now since the AODHandler does not have access
158 // the AnalysisManager. For the same reason the pointer t o the MCEventH
159 // has to passed to the AOD Handler by this task
160 // (doing this in the steering macro would not work on PROOF)
da97a08a 161
162 TClonesArray *mcarray = (TClonesArray*)fAODEvent->FindListObject(AliAODMCParticle::StdBranchName());
163 if(!mcarray)return;
164 mcarray->Delete();
165
dce1b636 166 AliAODMCHeader *mcHeader = (AliAODMCHeader*)fAODEvent->FindListObject(AliAODMCHeader::StdBranchName());
167 if(!mcHeader)return;
168
169 mcHeader->Reset();
170
da97a08a 171 // Get the MC Infos.. Handler needs to be set before
172 // while adding the branch
173 // This needs to be done, not to depend on the AnalysisManager
174
175 if(!fMCEventH)return;
176 if(!fMCEventH->MCEvent())return;
177 AliStack *pStack = fMCEventH->MCEvent()->Stack();
178 if(!pStack)return;
179
180 fMCEventH->CreateLabelMap();
181
dce1b636 182 //
183 // Get the Event Header
184 //
185
186 AliHeader* header = fMCEventH->MCEvent()->Header();
187 if (!header)return;
188
189 // get the MC vertex
190 AliGenEventHeader* genHeader = header->GenEventHeader();
191 TArrayF vtxMC(3);
192 genHeader->PrimaryVertex(vtxMC);
193 mcHeader->SetVertex(vtxMC[0],vtxMC[1],vtxMC[2]);
194
195 // we search the MCEventHeaders first
196 // Two cases, cocktail or not...
197 AliGenCocktailEventHeader* genCocktailHeader = dynamic_cast<AliGenCocktailEventHeader*>(genHeader);
198 if(genCocktailHeader){
199 // we have a coktail header
200 mcHeader->AddGeneratorName(genHeader->GetName());
201 // Loop from the back so that the first one sets the process type
202 TList* headerList = genCocktailHeader->GetHeaders();
203 for(int i = headerList->GetEntries()-1;i>=0;--i){
204 AliGenEventHeader *headerEntry = dynamic_cast<AliGenEventHeader*>(headerList->At(i));
205 SetMCHeaderInfo(mcHeader,headerEntry);
206 }
207 }
208 else{
209 // No Cocktail just take the first one
210 SetMCHeaderInfo(mcHeader,genHeader);
211 }
212
213
214
215
216 // Store the AliAODParticlesMC
da97a08a 217
218 Int_t np = pStack->GetNtrack();
219 Int_t nprim = pStack->GetNprimary();
220
221
222 Int_t j = 0;
223 TClonesArray& l = *mcarray;
224
225 for(int i = 0;i < np;++i){
226 if(fMCEventH->IsParticleSelected(i)){
227
228 Int_t flag = 0;
229 TParticle *part = pStack->Particle(i);
230 if(i<nprim)flag |= AliAODMCParticle::kPrimary;
231 if(pStack->IsPhysicalPrimary(i))flag |= AliAODMCParticle::kPhysicalPrim;
232
233 if(fMCEventH->GetNewLabel(i)!=j){
234 AliError(Form("MISMATCH New label %d j: %d",fMCEventH->GetNewLabel(i),j));
235 }
236 AliAODMCParticle mcpart_tmp(part,i,flag);
237
238 //
239 Int_t d0 = mcpart_tmp.GetDaughter(0);
240 Int_t d1 = mcpart_tmp.GetDaughter(1);
241 Int_t m = mcpart_tmp.GetMother();
242
243 // other than for the track labels, negative values mean
244 // no daughter/mother so preserve it
245
246 if(d0<0 && d1<0){
247 // no first daughter -> no second daughter
248 // nothing to be done
249 // second condition not needed just for sanity check at the end
250 mcpart_tmp.SetDaughter(0,d0);
251 mcpart_tmp.SetDaughter(1,d1);
252 }
253 else if(d1 < 0 && d0 >= 0){
254 // Only one daughter
255 // second condition not needed just for sanity check at the end
256 if(fMCEventH->IsParticleSelected(d0)){
257 mcpart_tmp.SetDaughter(0,fMCEventH->GetNewLabel(d0));
258 }
259 else{
260 mcpart_tmp.SetDaughter(0,-1);
261 }
262 mcpart_tmp.SetDaughter(1,d1);
263 }
264 else if (d0 > 0 && d1 > 0 ){
265 // we have two or more daughters loop on the stack to see if they are
266 // selected
267 Int_t d0_tmp = -1;
268 Int_t d1_tmp = -1;
269 for(int id = d0; id<=d1;++id){
270 if(fMCEventH->IsParticleSelected(id)){
271 if(d0_tmp==-1){
272 // first time
273 d0_tmp = fMCEventH->GetNewLabel(id);
274 d1_tmp = d0_tmp; // this is to have the same schema as on the stack i.e. with one daugther d0 and d1 are the same
275 }
276 else d1_tmp = fMCEventH->GetNewLabel(id);
277 }
278 }
279 mcpart_tmp.SetDaughter(0,d0_tmp);
280 mcpart_tmp.SetDaughter(1,d1_tmp);
281 }
282 else{
283 AliError(Form("Unxpected indices %d %d",d0,d1));
284 }
285
286 if(m<0){
287 mcpart_tmp.SetMother(m);
288 }
289 else{
290 if(fMCEventH->IsParticleSelected(m))mcpart_tmp.SetMother(fMCEventH->GetNewLabel(m));
291 else AliError("PROBLEM Mother not selected");
292 }
293
294 new (l[j++]) AliAODMCParticle(mcpart_tmp);
295
296 }
297 }
298 AliInfo(Form("AliAODHandler::StoreMCParticles: Selected %d (Primaries %d / total %d) after validation",
299 j,nprim,np));
300
301 // Set the labels in the AOD output...
302 // Remapping
303
304 // AODTracks
305 TClonesArray* tracks = fAODEvent->GetTracks();
306 if(tracks){
307 for(int it = 0; it < fAODEvent->GetNTracks();++it){
308 AliAODTrack *track = fAODEvent->GetTrack(it);
309
310 if(TMath::Abs(track->GetLabel())>np||track->GetLabel()==0){
311 AliWarning(Form("Wrong ESD track label %d",track->GetLabel()));
312 }
313 if(fMCEventH->GetNewLabel(track->GetLabel())==0){
314 AliWarning(Form("New label not found for %d",track->GetLabel()));
315 }
316 track->SetLabel(fMCEventH->GetNewLabel(track->GetLabel()));
317 }
318 }
319
320 // AOD calo cluster
321 TClonesArray *clusters = fAODEvent->GetCaloClusters();
322 if(clusters){
323 for (Int_t iClust = 0;iClust < fAODEvent->GetNCaloClusters(); ++iClust) {
324 AliAODCaloCluster * cluster = fAODEvent->GetCaloCluster(iClust);
325 UInt_t nLabel = cluster->GetNLabel();
326 // Ugly but do not want to fragment memory by creating
327 // new Int_t (nLabel)
328 Int_t* labels = const_cast<Int_t*>(cluster->GetLabels());
329 if (labels){
330 for(UInt_t i = 0;i < nLabel;++i){
331 labels[i] = fMCEventH->GetNewLabel(cluster->GetLabel(i));
332 }
333 }
334 // cluster->SetLabels(labels,nLabel);
335 }// iClust
336 }// clusters
337
338 // AOD tracklets
339 AliAODTracklets *tracklets = fAODEvent->GetTracklets();
340 if(tracklets){
341 for(int it = 0;it < tracklets->GetNumberOfTracklets();++it){
342 int label0 = tracklets->GetLabel(it,0);
343 int label1 = tracklets->GetLabel(it,1);
344 if(label0>=0)label0 = fMCEventH->GetNewLabel(label0);
345 if(label1>=0)label1 = fMCEventH->GetNewLabel(label1);
346 tracklets->SetLabel(it,0,label0);
347 tracklets->SetLabel(it,1,label1);
348 }
349 }
350
351}
352
5f380da9 353Bool_t AliAODHandler::FinishEvent()
ec4af4c1 354{
da97a08a 355 // Fill data structures
356 if(fFillAOD){
f4e5f8d5 357 fAODEvent->MakeEntriesReferencable();
da97a08a 358 StoreMCParticles();
ec4af4c1 359 FillTree();
da97a08a 360 }
361
362 if (fIsStandard) fAODEvent->ResetStd();
363 // Reset AOD replication flag
364 fAODIsReplicated = kFALSE;
365 return kTRUE;
ec4af4c1 366}
367
7970f4ac 368//______________________________________________________________________________
ec4af4c1 369Bool_t AliAODHandler::Terminate()
370{
371 // Terminate
372 AddAODtoTreeUserInfo();
373 return kTRUE;
374}
375
7970f4ac 376//______________________________________________________________________________
ec4af4c1 377Bool_t AliAODHandler::TerminateIO()
378{
379 // Terminate IO
21501411 380 if (fFileA) {
381 fFileA->Close();
382 delete fFileA;
383 }
ec4af4c1 384 return kTRUE;
385}
386
7970f4ac 387//______________________________________________________________________________
954526ed 388void AliAODHandler::CreateTree(Int_t flag)
ec4af4c1 389{
390 // Creates the AOD Tree
f3214a54 391 fTreeA = new TTree("aodTree", "AliAOD tree");
ec4af4c1 392 fTreeA->Branch(fAODEvent->GetList());
954526ed 393 if (flag == 0) fTreeA->SetDirectory(0);
ec4af4c1 394}
395
7970f4ac 396//______________________________________________________________________________
ec4af4c1 397void AliAODHandler::FillTree()
398{
399 // Fill the AOD Tree
da97a08a 400 fTreeA->Fill();
ec4af4c1 401}
402
7970f4ac 403//______________________________________________________________________________
ec4af4c1 404void AliAODHandler::AddAODtoTreeUserInfo()
405{
dce1b636 406 // Add aod event to tree user info
da97a08a 407 fTreeA->GetUserInfo()->Add(fAODEvent);
ec4af4c1 408}
490e9023 409
7970f4ac 410//______________________________________________________________________________
0134949d 411void AliAODHandler::AddBranch(const char* cname, void* addobj)
490e9023 412{
413 // Add a new branch to the aod
414 TDirectory *owd = gDirectory;
415 if (fFileA) {
dce1b636 416 fFileA->cd();
490e9023 417 }
0134949d 418 char** apointer = (char**) addobj;
419 TObject* obj = (TObject*) *apointer;
dce1b636 420
0134949d 421 fAODEvent->AddObject(obj);
dce1b636 422
423 const Int_t kSplitlevel = 99; // default value in TTree::Branch()
424 const Int_t kBufsize = 32000; // default value in TTree::Branch()
425
426 if (!fTreeA->FindBranch(obj->GetName())) {
427 // Do the same as if we book via
428 // TTree::Branch(TCollection*)
429
430 fTreeA->Bronch(obj->GetName(), cname, fAODEvent->GetList()->GetObjectRef(obj),
431 kBufsize, kSplitlevel - 1);
432 // fTreeA->Branch(obj->GetName(), cname, addobj);
433 }
490e9023 434 owd->cd();
435}
7970f4ac 436
437//______________________________________________________________________________
438void AliAODHandler::SetOutputFileName(const char* fname)
439{
440// Set file name.
441 fFileName = fname;
442}
443
444//______________________________________________________________________________
445const char *AliAODHandler::GetOutputFileName()
446{
447// Get file name.
448 return fFileName.Data();
449}
dce1b636 450
451void AliAODHandler::SetMCHeaderInfo(AliAODMCHeader *mcHeader,AliGenEventHeader *genHeader){
452
453
454 // Utility function to cover different cases for the AliGenEventHeader
455 // Needed since different ProcessType and ImpactParamter are not
456 // in the base class...
457 // We don't encode process types for event cocktails yet
458 // coul be done e.g. by adding offsets depnding on the generator
459
460
461 mcHeader->AddGeneratorName(genHeader->GetName());
462
463
464
465 if(!genHeader)return;
466 AliGenPythiaEventHeader *pythiaGenHeader = dynamic_cast<AliGenPythiaEventHeader*>(genHeader);
467 if (pythiaGenHeader) {
468 mcHeader->SetEventType(pythiaGenHeader->ProcessType());
469 return;
470 }
471
472 AliGenDPMjetEventHeader* dpmJetGenHeader = dynamic_cast<AliGenDPMjetEventHeader*>(genHeader);
473
474 if (dpmJetGenHeader){
475 mcHeader->SetEventType(dpmJetGenHeader->ProcessType());
476 return;
477 }
478
479 AliGenHijingEventHeader* hijingGenHeader = dynamic_cast<AliGenHijingEventHeader*>(genHeader);
480 if(hijingGenHeader){
481 mcHeader->SetImpactParameter(hijingGenHeader->ImpactParameter());
482 return;
483 }
484
485 AliWarning(Form("MC Eventheader not known: %s",genHeader->GetName()));
486
487}