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