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