Coding rule violations corrected.
[u/mrichter/AliRoot.git] / STEER / AOD / AliAODHandler.cxx
CommitLineData
3fbf06a3 1
ec4af4c1 2/**************************************************************************
3 * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
4 * *
5 * Author: The ALICE Off-line Project. *
6 * Contributors are mentioned in the code where appropriate. *
7 * *
8 * Permission to use, copy, modify and distribute this software and its *
9 * documentation strictly for non-commercial purposes is hereby granted *
10 * without fee, provided that the above copyright notice appears in all *
11 * copies and that both the copyright notice and this permission notice *
12 * appear in the supporting documentation. The authors make no claims *
13 * about the suitability of this software for any purpose. It is *
14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
16
17/* $Id$ */
18
19//-------------------------------------------------------------------------
20// Implementation of the Virtual Event Handler Interface for AOD
21// Author: Andreas Morsch, CERN
22//-------------------------------------------------------------------------
23
052994fb 24
ec4af4c1 25#include <TTree.h>
e910dd36 26#include <TFile.h>
7970f4ac 27#include <TString.h>
dce1b636 28#include <TList.h>
160959a9 29#include <TROOT.h>
e910dd36 30
da97a08a 31#include "AliLog.h"
ec4af4c1 32#include "AliAODHandler.h"
33#include "AliAODEvent.h"
aa7e002c 34#include "AliAODExtension.h"
da97a08a 35#include "AliAODTracklets.h"
36#include "AliStack.h"
37#include "AliAODMCParticle.h"
dce1b636 38#include "AliAODMCHeader.h"
da97a08a 39#include "AliMCEventHandler.h"
40#include "AliMCEvent.h"
dce1b636 41#include "AliGenEventHeader.h"
42#include "AliGenHijingEventHeader.h"
43#include "AliGenDPMjetEventHeader.h"
44#include "AliGenPythiaEventHeader.h"
45#include "AliGenCocktailEventHeader.h"
26ba01d4 46#include "AliCodeTimer.h"
47#include "AliAODBranchReplicator.h"
48#include "Riostream.h"
ec4af4c1 49
50ClassImp(AliAODHandler)
51
52//______________________________________________________________________________
53AliAODHandler::AliAODHandler() :
f3214a54 54 AliVEventHandler(),
78f7f935 55 fIsStandard(kTRUE),
da97a08a 56 fFillAOD(kTRUE),
41b01ae4 57 fFillAODRun(kTRUE),
ca2834f6 58 fFillExtension(kTRUE),
7c3a9fbf 59 fNeedsHeaderReplication(kFALSE),
75754ba8 60 fNeedsTracksBranchReplication(kFALSE),
61 fNeedsVerticesBranchReplication(kFALSE),
62 fNeedsV0sBranchReplication(kFALSE),
e0107012 63 fNeedsCascadesBranchReplication(kFALSE),
75754ba8 64 fNeedsTrackletsBranchReplication(kFALSE),
65 fNeedsPMDClustersBranchReplication(kFALSE),
66 fNeedsJetsBranchReplication(kFALSE),
67 fNeedsFMDClustersBranchReplication(kFALSE),
68 fNeedsCaloClustersBranchReplication(kFALSE),
720f7306 69 fNeedsCaloTriggerBranchReplication(kFALSE),
3549c522 70 fNeedsMCParticlesBranchReplication(kFALSE),
866d8d78 71 fNeedsDimuonsBranchReplication(kFALSE),
75754ba8 72 fAODIsReplicated(kFALSE),
ec4af4c1 73 fAODEvent(NULL),
da97a08a 74 fMCEventH(NULL),
e910dd36 75 fTreeA(NULL),
76 fFileA(NULL),
9066c676 77 fFileName(""),
582cfeb5 78 fExtensions(NULL),
79 fFilters(NULL)
ec4af4c1 80{
81 // default constructor
82}
83
84//______________________________________________________________________________
85AliAODHandler::AliAODHandler(const char* name, const char* title):
f3214a54 86 AliVEventHandler(name, title),
78f7f935 87 fIsStandard(kTRUE),
da97a08a 88 fFillAOD(kTRUE),
41b01ae4 89 fFillAODRun(kTRUE),
ca2834f6 90 fFillExtension(kTRUE),
7c3a9fbf 91 fNeedsHeaderReplication(kFALSE),
75754ba8 92 fNeedsTracksBranchReplication(kFALSE),
93 fNeedsVerticesBranchReplication(kFALSE),
94 fNeedsV0sBranchReplication(kFALSE),
e0107012 95 fNeedsCascadesBranchReplication(kFALSE),
75754ba8 96 fNeedsTrackletsBranchReplication(kFALSE),
97 fNeedsPMDClustersBranchReplication(kFALSE),
98 fNeedsJetsBranchReplication(kFALSE),
99 fNeedsFMDClustersBranchReplication(kFALSE),
100 fNeedsCaloClustersBranchReplication(kFALSE),
720f7306 101 fNeedsCaloTriggerBranchReplication(kFALSE),
3549c522 102 fNeedsMCParticlesBranchReplication(kFALSE),
866d8d78 103 fNeedsDimuonsBranchReplication(kFALSE),
75754ba8 104 fAODIsReplicated(kFALSE),
ec4af4c1 105 fAODEvent(NULL),
da97a08a 106 fMCEventH(NULL),
e910dd36 107 fTreeA(NULL),
108 fFileA(NULL),
9066c676 109 fFileName(""),
582cfeb5 110 fExtensions(NULL),
111 fFilters(NULL)
ec4af4c1 112{
582cfeb5 113// Normal constructor.
ec4af4c1 114}
115
116//______________________________________________________________________________
117AliAODHandler::~AliAODHandler()
118{
9066c676 119 // Destructor.
14d6fad5 120
121 delete fAODEvent;
122
123 if (fFileA)
124 {
6989bff3 125 // is already handled in TerminateIO
126 fFileA->Close();
127 delete fFileA;
128 }
74e11085 129
14d6fad5 130 delete fTreeA;
131 delete fExtensions;
132 delete fFilters;
ec4af4c1 133}
134
7970f4ac 135//______________________________________________________________________________
300d5701 136Bool_t AliAODHandler::Init(Option_t* opt)
ec4af4c1 137{
6989bff3 138 // Initialize IO
139 //
140 // Create the AODevent object
e0107012 141
4e6d5854 142 Bool_t createStdAOD = fIsStandard || fFillAOD;
aa399a26 143 if(!fAODEvent && createStdAOD){
ec4af4c1 144 fAODEvent = new AliAODEvent();
c8fe2783 145 if (fIsStandard)
146 fAODEvent->CreateStdContent();
6989bff3 147 }
148 //
149 // File opening according to execution mode
7970f4ac 150 TString option(opt);
151 option.ToLower();
aa399a26 152 if (createStdAOD) {
153 TDirectory *owd = gDirectory;
154 if (option.Contains("proof")) {
155 // proof
156 // Merging via files. Need to access analysis manager via interpreter.
157 gROOT->ProcessLine(Form("AliAnalysisDataContainer *c_common_out = AliAnalysisManager::GetAnalysisManager()->GetCommonOutputContainer();"));
158 gROOT->ProcessLine(Form("AliAnalysisManager::GetAnalysisManager()->OpenProofFile(c_common_out, \"RECREATE\");"));
159 fFileA = gFile;
160 } else {
161 // local and grid
162 fFileA = new TFile(fFileName.Data(), "RECREATE");
163 }
164 CreateTree(1);
165 owd->cd();
166 }
9066c676 167 if (fExtensions) {
168 TIter next(fExtensions);
169 AliAODExtension *ext;
170 while ((ext=(AliAODExtension*)next())) ext->Init(option);
171 }
582cfeb5 172 if (fFilters) {
173 TIter nextf(fFilters);
174 AliAODExtension *filteredAOD;
175 while ((filteredAOD=(AliAODExtension*)nextf())) {
176 filteredAOD->SetEvent(fAODEvent);
177 filteredAOD->Init(option);
14d6fad5 178 }
582cfeb5 179 }
14d6fad5 180
6989bff3 181 return kTRUE;
ec4af4c1 182}
183
26ba01d4 184//______________________________________________________________________________
185void AliAODHandler::Print(Option_t* opt) const
186{
187 // Print info about this object
188
189 cout << opt << Form("IsStandard %d filename=%s",fIsStandard,fFileName.Data()) << endl;
190
191 if ( fExtensions )
192 {
193 cout << opt << fExtensions->GetEntries() << " extensions :" << endl;
b5b9155e 194 PrintExtensions(*fExtensions);
26ba01d4 195 }
196 if ( fFilters )
197 {
198 cout << opt << fFilters->GetEntries() << " filters :" << endl;
b5b9155e 199 PrintExtensions(*fFilters);
26ba01d4 200 }
201}
202
203//______________________________________________________________________________
b5b9155e 204void AliAODHandler::PrintExtensions(const TObjArray& array) const
26ba01d4 205{
206 // Show the list of aod extensions
207 TIter next(&array);
208 AliAODExtension* ext(0x0);
209 while ( ( ext = static_cast<AliAODExtension*>(next()) ) )
210 {
211 ext->Print(" ");
212 }
213}
214
9066c676 215//______________________________________________________________________________
da97a08a 216void AliAODHandler::StoreMCParticles(){
dce1b636 217
da97a08a 218 //
219 // Remap the labels from ESD stack and store
220 // the AODMCParticles, makes only sense if we have
221 // the mcparticles branch
222 // has to be done here since we cannot know in advance
223 // which particles are needed (e.g. by the tracks etc.)
224 //
225 // Particles have been selected by AliMCEventhanlder->SelectParticle()
226 // To use the MCEventhandler here we need to set it from the outside
227 // can vanish when Handler go to the ANALYSISalice library
dce1b636 228 //
229 // The Branch booking for mcParticles and mcHeader has to happen
230 // in an external task for now since the AODHandler does not have access
231 // the AnalysisManager. For the same reason the pointer t o the MCEventH
232 // has to passed to the AOD Handler by this task
233 // (doing this in the steering macro would not work on PROOF)
da97a08a 234
aa399a26 235 if (!fAODEvent) return;
da97a08a 236 TClonesArray *mcarray = (TClonesArray*)fAODEvent->FindListObject(AliAODMCParticle::StdBranchName());
237 if(!mcarray)return;
da97a08a 238
dce1b636 239 AliAODMCHeader *mcHeader = (AliAODMCHeader*)fAODEvent->FindListObject(AliAODMCHeader::StdBranchName());
240 if(!mcHeader)return;
241
da97a08a 242 // Get the MC Infos.. Handler needs to be set before
243 // while adding the branch
244 // This needs to be done, not to depend on the AnalysisManager
245
246 if(!fMCEventH)return;
247 if(!fMCEventH->MCEvent())return;
248 AliStack *pStack = fMCEventH->MCEvent()->Stack();
249 if(!pStack)return;
250
251 fMCEventH->CreateLabelMap();
252
dce1b636 253 //
254 // Get the Event Header
255 //
256
257 AliHeader* header = fMCEventH->MCEvent()->Header();
9efd8e10 258 // get the MC vertex
259 AliGenEventHeader* genHeader = 0;
260 if (header) genHeader = header->GenEventHeader();
261 if (genHeader) {
262 TArrayF vtxMC(3);
263 genHeader->PrimaryVertex(vtxMC);
264 mcHeader->SetVertex(vtxMC[0],vtxMC[1],vtxMC[2]);
265
266 // we search the MCEventHeaders first
267 // Two cases, cocktail or not...
268 AliGenCocktailEventHeader* genCocktailHeader = dynamic_cast<AliGenCocktailEventHeader*>(genHeader);
269 if(genCocktailHeader){
270 // we have a coktail header
271 mcHeader->AddGeneratorName(genHeader->GetName());
272 // Loop from the back so that the first one sets the process type
273 TList* headerList = genCocktailHeader->GetHeaders();
274 for(int i = headerList->GetEntries()-1;i>=0;--i){
275 AliGenEventHeader *headerEntry = dynamic_cast<AliGenEventHeader*>(headerList->At(i));
c9e2b9f3 276 if (!headerEntry) {
277 AliFatal("AliGenEventHeader entry not found in the header list");
278 } else {
279 SetMCHeaderInfo(mcHeader,headerEntry);
280 }
9efd8e10 281 }
282 }
283 else{
284 // No Cocktail just take the first one
285 SetMCHeaderInfo(mcHeader,genHeader);
286 }
dce1b636 287 }
9efd8e10 288
dce1b636 289
290
291
292
293 // Store the AliAODParticlesMC
93836e1b 294 AliMCEvent* mcEvent = fMCEventH->MCEvent();
295
296 Int_t np = mcEvent->GetNumberOfTracks();
297 Int_t nprim = mcEvent->GetNumberOfPrimaries();
da97a08a 298
299
300 Int_t j = 0;
301 TClonesArray& l = *mcarray;
302
93836e1b 303 for(int i = 0; i < np; ++i){
304 if(fMCEventH->IsParticleSelected(i)){
305 Int_t flag = 0;
6cd07d0a 306 AliMCParticle* mcpart = (AliMCParticle*) mcEvent->GetTrack(i);
93836e1b 307 if(i<nprim)flag |= AliAODMCParticle::kPrimary;
308
309 if(mcEvent->IsPhysicalPrimary(i))flag |= AliAODMCParticle::kPhysicalPrim;
310
311 if(fMCEventH->GetNewLabel(i)!=j){
312 AliError(Form("MISMATCH New label %d j: %d",fMCEventH->GetNewLabel(i),j));
da97a08a 313 }
da97a08a 314
77f43bb7 315 AliAODMCParticle mcpartTmp(mcpart,i,flag);
93836e1b 316
77f43bb7 317 mcpartTmp.SetStatus(mcpart->Particle()->GetStatusCode());
93836e1b 318 //
77f43bb7 319 Int_t d0 = mcpartTmp.GetDaughter(0);
320 Int_t d1 = mcpartTmp.GetDaughter(1);
321 Int_t m = mcpartTmp.GetMother();
93836e1b 322
323 // other than for the track labels, negative values mean
324 // no daughter/mother so preserve it
325
326 if(d0<0 && d1<0){
327 // no first daughter -> no second daughter
328 // nothing to be done
329 // second condition not needed just for sanity check at the end
77f43bb7 330 mcpartTmp.SetDaughter(0,d0);
331 mcpartTmp.SetDaughter(1,d1);
93836e1b 332 } else if(d1 < 0 && d0 >= 0) {
333 // Only one daughter
334 // second condition not needed just for sanity check at the end
335 if(fMCEventH->IsParticleSelected(d0)){
77f43bb7 336 mcpartTmp.SetDaughter(0,fMCEventH->GetNewLabel(d0));
93836e1b 337 } else {
77f43bb7 338 mcpartTmp.SetDaughter(0,-1);
93836e1b 339 }
77f43bb7 340 mcpartTmp.SetDaughter(1,d1);
93836e1b 341 }
342 else if (d0 > 0 && d1 > 0 ){
343 // we have two or more daughters loop on the stack to see if they are
344 // selected
77f43bb7 345 Int_t d0Tmp = -1;
346 Int_t d1Tmp = -1;
93836e1b 347 for(int id = d0; id<=d1;++id){
348 if(fMCEventH->IsParticleSelected(id)){
77f43bb7 349 if(d0Tmp==-1){
93836e1b 350 // first time
77f43bb7 351 d0Tmp = fMCEventH->GetNewLabel(id);
352 d1Tmp = d0Tmp; // this is to have the same schema as on the stack i.e. with one daugther d0 and d1 are the same
93836e1b 353 }
77f43bb7 354 else d1Tmp = fMCEventH->GetNewLabel(id);
93836e1b 355 }
356 }
77f43bb7 357 mcpartTmp.SetDaughter(0,d0Tmp);
358 mcpartTmp.SetDaughter(1,d1Tmp);
93836e1b 359 } else {
360 AliError(Form("Unxpected indices %d %d",d0,d1));
361 }
362
363 if(m<0){
77f43bb7 364 mcpartTmp.SetMother(m);
93836e1b 365 } else {
77f43bb7 366 if(fMCEventH->IsParticleSelected(m))mcpartTmp.SetMother(fMCEventH->GetNewLabel(m));
93836e1b 367 else AliError(Form("PROBLEM Mother not selected %d \n", m));
368 }
6326aeae 369
77f43bb7 370 new (l[j++]) AliAODMCParticle(mcpartTmp);
93836e1b 371
da97a08a 372 }
da97a08a 373 }
93836e1b 374 AliInfo(Form("AliAODHandler::StoreMCParticles: Selected %d (Primaries %d / total %d) after validation \n",
da97a08a 375 j,nprim,np));
376
377 // Set the labels in the AOD output...
378 // Remapping
379
380 // AODTracks
381 TClonesArray* tracks = fAODEvent->GetTracks();
382 if(tracks){
383 for(int it = 0; it < fAODEvent->GetNTracks();++it){
384 AliAODTrack *track = fAODEvent->GetTrack(it);
385
91dece68 386 Int_t sign = 1;
387 Int_t label = track->GetLabel();
388 if(label<0){ // preserve the sign for later usage
389 label *= -1;
390 sign = -1;
391 }
392
93836e1b 393 if (label >= AliMCEvent::BgLabelOffset()) label = mcEvent->BgLabelToIndex(label);
93836e1b 394 if(label > np || track->GetLabel() == 0){
395 AliWarning(Form("Wrong ESD track label %5d (%5d)",track->GetLabel(), label));
da97a08a 396 }
93836e1b 397 if(fMCEventH->GetNewLabel(label) == 0){
398 AliWarning(Form("New label not found for %5d (%5d)",track->GetLabel(), label));
da97a08a 399 }
91dece68 400 track->SetLabel(sign*fMCEventH->GetNewLabel(label));
da97a08a 401 }
402 }
403
404 // AOD calo cluster
405 TClonesArray *clusters = fAODEvent->GetCaloClusters();
406 if(clusters){
c8fe2783 407 for (Int_t iClust = 0;iClust < fAODEvent->GetNumberOfCaloClusters(); ++iClust) {
da97a08a 408 AliAODCaloCluster * cluster = fAODEvent->GetCaloCluster(iClust);
c8fe2783 409 UInt_t nLabel = cluster->GetNLabels();
da97a08a 410 // Ugly but do not want to fragment memory by creating
411 // new Int_t (nLabel)
412 Int_t* labels = const_cast<Int_t*>(cluster->GetLabels());
413 if (labels){
414 for(UInt_t i = 0;i < nLabel;++i){
c8fe2783 415 labels[i] = fMCEventH->GetNewLabel(cluster->GetLabelAt(i));
da97a08a 416 }
417 }
418 // cluster->SetLabels(labels,nLabel);
419 }// iClust
420 }// clusters
421
422 // AOD tracklets
423 AliAODTracklets *tracklets = fAODEvent->GetTracklets();
424 if(tracklets){
425 for(int it = 0;it < tracklets->GetNumberOfTracklets();++it){
426 int label0 = tracklets->GetLabel(it,0);
427 int label1 = tracklets->GetLabel(it,1);
428 if(label0>=0)label0 = fMCEventH->GetNewLabel(label0);
429 if(label1>=0)label1 = fMCEventH->GetNewLabel(label1);
430 tracklets->SetLabel(it,0,label0);
431 tracklets->SetLabel(it,1,label1);
432 }
433 }
434
435}
436
9066c676 437//______________________________________________________________________________
5f380da9 438Bool_t AliAODHandler::FinishEvent()
ec4af4c1 439{
da97a08a 440 // Fill data structures
4e6d5854 441 if(fFillAOD && fFillAODRun && fAODEvent){
b8b7dd5c 442 fAODEvent->MakeEntriesReferencable();
e0107012 443 fTreeA->BranchRef();
b8b7dd5c 444 FillTree();
4e6d5854 445 }
f133e976 446
ca2834f6 447 if ((fFillAOD && fFillAODRun) || fFillExtension) {
307b6330 448 if (fExtensions && fFillExtension) {
449 // fFillExtension can be set by the ESD filter or by a delta filter in case of AOD inputs
14d6fad5 450 TIter next(fExtensions);
451 AliAODExtension *ext;
452 while ((ext=(AliAODExtension*)next())) ext->FinishEvent();
453 }
307b6330 454 if (fFilters && fFillAOD && fFillAODRun) {
14d6fad5 455 TIter nextf(fFilters);
456 AliAODExtension *ext;
457 while ((ext=(AliAODExtension*)nextf())) {
b8b7dd5c 458 ext->FinishEvent();
14d6fad5 459 }
460 }
aa399a26 461 }
14d6fad5 462
dddc33c5 463 if (fIsStandard && fAODEvent)
14d6fad5 464 {
465 fAODEvent->ResetStd();
466 }
467
468 if (fAODEvent)
469 {
470 TClonesArray *mcarray = static_cast<TClonesArray*>(fAODEvent->FindListObject(AliAODMCParticle::StdBranchName()));
ef89f372 471 if(mcarray) mcarray->Delete();
472
14d6fad5 473 AliAODMCHeader *mcHeader = static_cast<AliAODMCHeader*>(fAODEvent->FindListObject(AliAODMCHeader::StdBranchName()));
ef89f372 474 if(mcHeader) mcHeader->Reset();
475 }
14d6fad5 476
da97a08a 477 // Reset AOD replication flag
478 fAODIsReplicated = kFALSE;
479 return kTRUE;
ec4af4c1 480}
481
7970f4ac 482//______________________________________________________________________________
ec4af4c1 483Bool_t AliAODHandler::Terminate()
484{
9066c676 485 // Terminate
486 AddAODtoTreeUserInfo();
14d6fad5 487
488 TIter nextF(fFilters);
489 AliAODExtension *ext;
490 while ((ext=static_cast<AliAODExtension*>(nextF())))
491 {
492 ext->AddAODtoTreeUserInfo();
493 }
494
495 TIter nextE(fExtensions);
496 while ((ext=static_cast<AliAODExtension*>(nextE())))
497 {
498 ext->AddAODtoTreeUserInfo();
499 }
500
9066c676 501 return kTRUE;
ec4af4c1 502}
503
7970f4ac 504//______________________________________________________________________________
ec4af4c1 505Bool_t AliAODHandler::TerminateIO()
506{
9066c676 507 // Terminate IO
508 if (fFileA) {
aa399a26 509 fFileA->Write();
9066c676 510 fFileA->Close();
511 delete fFileA;
512 fFileA = 0;
48f1c230 513 // When closing the file, the tree is also deleted.
514 fTreeA = 0;
9066c676 515 }
14d6fad5 516
517 TIter nextF(fFilters);
518 AliAODExtension *ext;
519 while ((ext=static_cast<AliAODExtension*>(nextF())))
520 {
521 ext->TerminateIO();
9066c676 522 }
14d6fad5 523
524 TIter nextE(fExtensions);
525 while ((ext=static_cast<AliAODExtension*>(nextE())))
526 {
527 ext->TerminateIO();
582cfeb5 528 }
14d6fad5 529
9066c676 530 return kTRUE;
ec4af4c1 531}
532
7970f4ac 533//______________________________________________________________________________
954526ed 534void AliAODHandler::CreateTree(Int_t flag)
ec4af4c1 535{
536 // Creates the AOD Tree
f3214a54 537 fTreeA = new TTree("aodTree", "AliAOD tree");
ec4af4c1 538 fTreeA->Branch(fAODEvent->GetList());
954526ed 539 if (flag == 0) fTreeA->SetDirectory(0);
ec4af4c1 540}
541
7970f4ac 542//______________________________________________________________________________
ec4af4c1 543void AliAODHandler::FillTree()
544{
866d8d78 545
ec4af4c1 546 // Fill the AOD Tree
e0107012 547 fTreeA->Fill();
ec4af4c1 548}
549
7970f4ac 550//______________________________________________________________________________
ec4af4c1 551void AliAODHandler::AddAODtoTreeUserInfo()
552{
dce1b636 553 // Add aod event to tree user info
aa399a26 554 if (fTreeA) fTreeA->GetUserInfo()->Add(fAODEvent);
48f1c230 555 // Now the tree owns our fAODEvent...
556 fAODEvent = 0;
ec4af4c1 557}
490e9023 558
7970f4ac 559//______________________________________________________________________________
9066c676 560void AliAODHandler::AddBranch(const char* cname, void* addobj, const char* filename)
490e9023 561{
14d6fad5 562 // Add a new branch to the aod. Added optional filename parameter if the
563 // branch should be written to a separate file.
564
565 if (strlen(filename))
566 {
567 AliAODExtension *ext = AddExtension(filename);
568 ext->AddBranch(cname, addobj);
569 return;
570 }
571
572 // Add branch to all filters
573 // Add branch to all filters
574 if (fFilters) {
575 TIter next(fFilters);
576 AliAODExtension *ext;
577 while ((ext=(AliAODExtension*)next())) ext->AddBranch(cname, addobj);
578 }
579
580 TDirectory *owd = gDirectory;
581 if (fFileA)
582 {
583 fFileA->cd();
584 }
dce1b636 585
14d6fad5 586 char** apointer = (char**) addobj;
587 TObject* obj = (TObject*) *apointer;
588
589 fAODEvent->AddObject(obj);
590
591 const Int_t kSplitlevel = 99; // default value in TTree::Branch()
592 const Int_t kBufsize = 32000; // default value in TTree::Branch()
593
594 if (!fTreeA->FindBranch(obj->GetName()))
595 {
596 // Do the same as if we book via
597 // TTree::Branch(TCollection*)
598
599 fTreeA->Bronch(obj->GetName(), cname, fAODEvent->GetList()->GetObjectRef(obj),
600 kBufsize, kSplitlevel - 1);
601 }
602 owd->cd();
490e9023 603}
7970f4ac 604
9066c676 605//______________________________________________________________________________
606AliAODExtension *AliAODHandler::AddExtension(const char *filename, const char *title)
607{
14d6fad5 608 // Add an AOD extension with some branches in a different file.
26ba01d4 609
14d6fad5 610 TString fname(filename);
611 if (!fname.EndsWith(".root")) fname += ".root";
612 if (!fExtensions) {
613 fExtensions = new TObjArray();
614 fExtensions->SetOwner();
615 }
616 AliAODExtension *ext = (AliAODExtension*)fExtensions->FindObject(fname);
617 if (!ext) {
618 ext = new AliAODExtension(fname, title);
619 fExtensions->Add(ext);
620 }
621 return ext;
9066c676 622}
582cfeb5 623
624//______________________________________________________________________________
625AliAODExtension *AliAODHandler::GetExtension(const char *filename) const
626{
14d6fad5 627 // Getter for AOD extensions via file name.
628 if (!fExtensions) return NULL;
629 return (AliAODExtension*)fExtensions->FindObject(filename);
582cfeb5 630}
631
632//______________________________________________________________________________
633AliAODExtension *AliAODHandler::AddFilteredAOD(const char *filename, const char *filtername)
634{
14d6fad5 635 // Add an AOD extension that can write only AOD events that pass a user filter.
636 if (!fFilters) {
637 fFilters = new TObjArray();
638 fFilters->SetOwner();
639 }
640 AliAODExtension *filter = (AliAODExtension*)fFilters->FindObject(filename);
641 if (!filter) {
642 filter = new AliAODExtension(filename, filtername, kTRUE);
643 fFilters->Add(filter);
644 }
645 return filter;
582cfeb5 646}
647
648//______________________________________________________________________________
649AliAODExtension *AliAODHandler::GetFilteredAOD(const char *filename) const
650{
14d6fad5 651 // Getter for AOD filters via file name.
652 if (!fFilters) return NULL;
653 return (AliAODExtension*)fFilters->FindObject(filename);
582cfeb5 654}
14d6fad5 655
7970f4ac 656//______________________________________________________________________________
657void AliAODHandler::SetOutputFileName(const char* fname)
658{
659// Set file name.
660 fFileName = fname;
661}
662
663//______________________________________________________________________________
664const char *AliAODHandler::GetOutputFileName()
665{
666// Get file name.
667 return fFileName.Data();
668}
dce1b636 669
90d50a8c 670//______________________________________________________________________________
671const char *AliAODHandler::GetExtraOutputs() const
672{
14d6fad5 673 // Get extra outputs as a string separated by commas.
674 static TString eoutputs;
675 eoutputs = "";
676 TObject *obj;
677 if (fExtensions) {
678 TIter next1(fExtensions);
679 while ((obj=next1())) {
680 if (!eoutputs.IsNull()) eoutputs += ",";
681 eoutputs += obj->GetName();
682 }
683 }
684 if (fFilters) {
685 TIter next2(fFilters);
686 while ((obj=next2())) {
687 if (!eoutputs.IsNull()) eoutputs += ",";
688 eoutputs += obj->GetName();
689 }
690 }
691 return eoutputs.Data();
692}
693
694//______________________________________________________________________________
695Bool_t AliAODHandler::HasExtensions() const
696{
697 // Whether or not we manage extensions
698
699 if ( fExtensions && fExtensions->GetEntries()>0 ) return kTRUE;
700
701 return kFALSE;
90d50a8c 702}
703
9066c676 704//______________________________________________________________________________
dce1b636 705void AliAODHandler::SetMCHeaderInfo(AliAODMCHeader *mcHeader,AliGenEventHeader *genHeader){
706
707
708 // Utility function to cover different cases for the AliGenEventHeader
709 // Needed since different ProcessType and ImpactParamter are not
710 // in the base class...
711 // We don't encode process types for event cocktails yet
9066c676 712 // could be done e.g. by adding offsets depnding on the generator
dce1b636 713
dce1b636 714 if(!genHeader)return;
4986ae9e 715 mcHeader->AddGeneratorName(genHeader->GetName());
dce1b636 716 AliGenPythiaEventHeader *pythiaGenHeader = dynamic_cast<AliGenPythiaEventHeader*>(genHeader);
717 if (pythiaGenHeader) {
718 mcHeader->SetEventType(pythiaGenHeader->ProcessType());
0fd37a1f 719 mcHeader->SetPtHard(pythiaGenHeader->GetPtHard());
dce1b636 720 return;
721 }
722
723 AliGenDPMjetEventHeader* dpmJetGenHeader = dynamic_cast<AliGenDPMjetEventHeader*>(genHeader);
724
725 if (dpmJetGenHeader){
726 mcHeader->SetEventType(dpmJetGenHeader->ProcessType());
727 return;
728 }
729
730 AliGenHijingEventHeader* hijingGenHeader = dynamic_cast<AliGenHijingEventHeader*>(genHeader);
731 if(hijingGenHeader){
732 mcHeader->SetImpactParameter(hijingGenHeader->ImpactParameter());
733 return;
734 }
735
736 AliWarning(Form("MC Eventheader not known: %s",genHeader->GetName()));
737
738}
9066c676 739