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