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