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