* add tuned on data functionality for TOF (non-gaussian tails)
[u/mrichter/AliRoot.git] / STEER / AOD / AliAODHandler.cxx
CommitLineData
3fbf06a3 1
ec4af4c1 2/**************************************************************************
3 * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
4 * *
5 * Author: The ALICE Off-line Project. *
6 * Contributors are mentioned in the code where appropriate. *
7 * *
8 * Permission to use, copy, modify and distribute this software and its *
9 * documentation strictly for non-commercial purposes is hereby granted *
10 * without fee, provided that the above copyright notice appears in all *
11 * copies and that both the copyright notice and this permission notice *
12 * appear in the supporting documentation. The authors make no claims *
13 * about the suitability of this software for any purpose. It is *
14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
16
17/* $Id$ */
18
19//-------------------------------------------------------------------------
20// Implementation of the Virtual Event Handler Interface for AOD
21// Author: Andreas Morsch, CERN
22//-------------------------------------------------------------------------
23
052994fb 24
ec4af4c1 25#include <TTree.h>
e910dd36 26#include <TFile.h>
7970f4ac 27#include <TString.h>
dce1b636 28#include <TList.h>
160959a9 29#include <TROOT.h>
e910dd36 30
da97a08a 31#include "AliLog.h"
ec4af4c1 32#include "AliAODHandler.h"
33#include "AliAODEvent.h"
aa7e002c 34#include "AliAODExtension.h"
da97a08a 35#include "AliAODTracklets.h"
36#include "AliStack.h"
37#include "AliAODMCParticle.h"
dce1b636 38#include "AliAODMCHeader.h"
da97a08a 39#include "AliMCEventHandler.h"
40#include "AliMCEvent.h"
dce1b636 41#include "AliGenEventHeader.h"
42#include "AliGenHijingEventHeader.h"
43#include "AliGenDPMjetEventHeader.h"
44#include "AliGenPythiaEventHeader.h"
45#include "AliGenCocktailEventHeader.h"
26ba01d4 46#include "AliCodeTimer.h"
47#include "AliAODBranchReplicator.h"
48#include "Riostream.h"
ec4af4c1 49
66b0310c 50using std::endl;
51using std::cout;
ec4af4c1 52ClassImp(AliAODHandler)
53
54//______________________________________________________________________________
55AliAODHandler::AliAODHandler() :
f3214a54 56 AliVEventHandler(),
78f7f935 57 fIsStandard(kTRUE),
da97a08a 58 fFillAOD(kTRUE),
41b01ae4 59 fFillAODRun(kTRUE),
ca2834f6 60 fFillExtension(kTRUE),
7c3a9fbf 61 fNeedsHeaderReplication(kFALSE),
2981307f 62 fNeedsTOFHeaderReplication(kFALSE),
63 fNeedsVZEROReplication(kFALSE),
75754ba8 64 fNeedsTracksBranchReplication(kFALSE),
65 fNeedsVerticesBranchReplication(kFALSE),
66 fNeedsV0sBranchReplication(kFALSE),
e0107012 67 fNeedsCascadesBranchReplication(kFALSE),
75754ba8 68 fNeedsTrackletsBranchReplication(kFALSE),
69 fNeedsPMDClustersBranchReplication(kFALSE),
70 fNeedsJetsBranchReplication(kFALSE),
71 fNeedsFMDClustersBranchReplication(kFALSE),
72 fNeedsCaloClustersBranchReplication(kFALSE),
720f7306 73 fNeedsCaloTriggerBranchReplication(kFALSE),
3549c522 74 fNeedsMCParticlesBranchReplication(kFALSE),
866d8d78 75 fNeedsDimuonsBranchReplication(kFALSE),
fc05a533 76 fNeedsHMPIDBranchReplication(kFALSE),
75754ba8 77 fAODIsReplicated(kFALSE),
ec4af4c1 78 fAODEvent(NULL),
da97a08a 79 fMCEventH(NULL),
e910dd36 80 fTreeA(NULL),
81 fFileA(NULL),
9066c676 82 fFileName(""),
582cfeb5 83 fExtensions(NULL),
84 fFilters(NULL)
ec4af4c1 85{
86 // default constructor
87}
88
89//______________________________________________________________________________
90AliAODHandler::AliAODHandler(const char* name, const char* title):
f3214a54 91 AliVEventHandler(name, title),
78f7f935 92 fIsStandard(kTRUE),
da97a08a 93 fFillAOD(kTRUE),
41b01ae4 94 fFillAODRun(kTRUE),
ca2834f6 95 fFillExtension(kTRUE),
7c3a9fbf 96 fNeedsHeaderReplication(kFALSE),
2981307f 97 fNeedsTOFHeaderReplication(kFALSE),
98 fNeedsVZEROReplication(kFALSE),
75754ba8 99 fNeedsTracksBranchReplication(kFALSE),
100 fNeedsVerticesBranchReplication(kFALSE),
101 fNeedsV0sBranchReplication(kFALSE),
e0107012 102 fNeedsCascadesBranchReplication(kFALSE),
75754ba8 103 fNeedsTrackletsBranchReplication(kFALSE),
104 fNeedsPMDClustersBranchReplication(kFALSE),
105 fNeedsJetsBranchReplication(kFALSE),
106 fNeedsFMDClustersBranchReplication(kFALSE),
107 fNeedsCaloClustersBranchReplication(kFALSE),
fc05a533 108 fNeedsCaloTriggerBranchReplication(kFALSE),
3549c522 109 fNeedsMCParticlesBranchReplication(kFALSE),
866d8d78 110 fNeedsDimuonsBranchReplication(kFALSE),
fc05a533 111 fNeedsHMPIDBranchReplication(kFALSE),
75754ba8 112 fAODIsReplicated(kFALSE),
ec4af4c1 113 fAODEvent(NULL),
da97a08a 114 fMCEventH(NULL),
e910dd36 115 fTreeA(NULL),
116 fFileA(NULL),
9066c676 117 fFileName(""),
582cfeb5 118 fExtensions(NULL),
119 fFilters(NULL)
ec4af4c1 120{
582cfeb5 121// Normal constructor.
ec4af4c1 122}
123
124//______________________________________________________________________________
125AliAODHandler::~AliAODHandler()
126{
9066c676 127 // Destructor.
14d6fad5 128
129 delete fAODEvent;
130
9eb17d61 131 if (fFileA) fFileA->Close();
74e11085 132
9eb17d61 133 delete fFileA;
14d6fad5 134 delete fTreeA;
135 delete fExtensions;
136 delete fFilters;
ec4af4c1 137}
138
7970f4ac 139//______________________________________________________________________________
300d5701 140Bool_t AliAODHandler::Init(Option_t* opt)
ec4af4c1 141{
6989bff3 142 // Initialize IO
143 //
144 // Create the AODevent object
e0107012 145
4e6d5854 146 Bool_t createStdAOD = fIsStandard || fFillAOD;
aa399a26 147 if(!fAODEvent && createStdAOD){
ec4af4c1 148 fAODEvent = new AliAODEvent();
c8fe2783 149 if (fIsStandard)
150 fAODEvent->CreateStdContent();
6989bff3 151 }
152 //
153 // File opening according to execution mode
7970f4ac 154 TString option(opt);
155 option.ToLower();
aa399a26 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 }
9066c676 171 if (fExtensions) {
172 TIter next(fExtensions);
173 AliAODExtension *ext;
174 while ((ext=(AliAODExtension*)next())) ext->Init(option);
175 }
582cfeb5 176 if (fFilters) {
177 TIter nextf(fFilters);
178 AliAODExtension *filteredAOD;
179 while ((filteredAOD=(AliAODExtension*)nextf())) {
180 filteredAOD->SetEvent(fAODEvent);
181 filteredAOD->Init(option);
14d6fad5 182 }
582cfeb5 183 }
14d6fad5 184
6989bff3 185 return kTRUE;
ec4af4c1 186}
187
9066c676 188//______________________________________________________________________________
26ba01d4 189void 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;
b5b9155e 198 PrintExtensions(*fExtensions);
26ba01d4 199 }
200 if ( fFilters )
201 {
202 cout << opt << fFilters->GetEntries() << " filters :" << endl;
b5b9155e 203 PrintExtensions(*fFilters);
26ba01d4 204 }
205}
206
207//______________________________________________________________________________
b5b9155e 208void AliAODHandler::PrintExtensions(const TObjArray& array) const
26ba01d4 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//______________________________________________________________________________
da97a08a 220void AliAODHandler::StoreMCParticles(){
dce1b636 221
da97a08a 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
dce1b636 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)
da97a08a 238
aa399a26 239 if (!fAODEvent) return;
da97a08a 240 TClonesArray *mcarray = (TClonesArray*)fAODEvent->FindListObject(AliAODMCParticle::StdBranchName());
241 if(!mcarray)return;
da97a08a 242
dce1b636 243 AliAODMCHeader *mcHeader = (AliAODMCHeader*)fAODEvent->FindListObject(AliAODMCHeader::StdBranchName());
244 if(!mcHeader)return;
245
da97a08a 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
dce1b636 257 //
258 // Get the Event Header
259 //
260
261 AliHeader* header = fMCEventH->MCEvent()->Header();
9efd8e10 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]);
9efd8e10 269 // we search the MCEventHeaders first
270 // Two cases, cocktail or not...
271 AliGenCocktailEventHeader* genCocktailHeader = dynamic_cast<AliGenCocktailEventHeader*>(genHeader);
272 if(genCocktailHeader){
08078824 273 // we have a coktail header add the name once
9efd8e10 274 mcHeader->AddGeneratorName(genHeader->GetName());
9efd8e10 275 TList* headerList = genCocktailHeader->GetHeaders();
08078824 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 }
9efd8e10 283 }
284 else{
08078824 285 // No Cocktail just take the first one
286 SetMCHeaderInfo(mcHeader,genHeader);
9efd8e10 287 }
08078824 288 // Add all the headers and names, if no cocktail header
289 // there will be only one entry
290 mcHeader->AddCocktailHeaders(genHeader);
dce1b636 291 }
9efd8e10 292
dce1b636 293
294
295
296
297 // Store the AliAODParticlesMC
93836e1b 298 AliMCEvent* mcEvent = fMCEventH->MCEvent();
299
300 Int_t np = mcEvent->GetNumberOfTracks();
301 Int_t nprim = mcEvent->GetNumberOfPrimaries();
da97a08a 302
303
304 Int_t j = 0;
305 TClonesArray& l = *mcarray;
306
93836e1b 307 for(int i = 0; i < np; ++i){
308 if(fMCEventH->IsParticleSelected(i)){
309 Int_t flag = 0;
6cd07d0a 310 AliMCParticle* mcpart = (AliMCParticle*) mcEvent->GetTrack(i);
93836e1b 311 if(i<nprim)flag |= AliAODMCParticle::kPrimary;
312
313 if(mcEvent->IsPhysicalPrimary(i))flag |= AliAODMCParticle::kPhysicalPrim;
d4312c7a 314 if(mcEvent->IsSecondaryFromWeakDecay(i))flag |= AliAODMCParticle::kSecondaryFromWeakDecay;
315 if(mcEvent->IsSecondaryFromMaterial(i))flag |= AliAODMCParticle::kSecondaryFromMaterial;
6a9d52e4 316
93836e1b 317 if(fMCEventH->GetNewLabel(i)!=j){
318 AliError(Form("MISMATCH New label %d j: %d",fMCEventH->GetNewLabel(i),j));
da97a08a 319 }
da97a08a 320
77f43bb7 321 AliAODMCParticle mcpartTmp(mcpart,i,flag);
93836e1b 322
77f43bb7 323 mcpartTmp.SetStatus(mcpart->Particle()->GetStatusCode());
6a9d52e4 324 mcpartTmp.SetMCProcessCode(mcpart->Particle()->GetUniqueID());
93836e1b 325 //
77f43bb7 326 Int_t d0 = mcpartTmp.GetDaughter(0);
327 Int_t d1 = mcpartTmp.GetDaughter(1);
328 Int_t m = mcpartTmp.GetMother();
93836e1b 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
77f43bb7 337 mcpartTmp.SetDaughter(0,d0);
338 mcpartTmp.SetDaughter(1,d1);
93836e1b 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)){
77f43bb7 343 mcpartTmp.SetDaughter(0,fMCEventH->GetNewLabel(d0));
93836e1b 344 } else {
77f43bb7 345 mcpartTmp.SetDaughter(0,-1);
93836e1b 346 }
77f43bb7 347 mcpartTmp.SetDaughter(1,d1);
93836e1b 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
77f43bb7 352 Int_t d0Tmp = -1;
353 Int_t d1Tmp = -1;
93836e1b 354 for(int id = d0; id<=d1;++id){
355 if(fMCEventH->IsParticleSelected(id)){
77f43bb7 356 if(d0Tmp==-1){
93836e1b 357 // first time
77f43bb7 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
93836e1b 360 }
77f43bb7 361 else d1Tmp = fMCEventH->GetNewLabel(id);
93836e1b 362 }
363 }
77f43bb7 364 mcpartTmp.SetDaughter(0,d0Tmp);
365 mcpartTmp.SetDaughter(1,d1Tmp);
93836e1b 366 } else {
367 AliError(Form("Unxpected indices %d %d",d0,d1));
368 }
369
370 if(m<0){
77f43bb7 371 mcpartTmp.SetMother(m);
93836e1b 372 } else {
77f43bb7 373 if(fMCEventH->IsParticleSelected(m))mcpartTmp.SetMother(fMCEventH->GetNewLabel(m));
93836e1b 374 else AliError(Form("PROBLEM Mother not selected %d \n", m));
375 }
6326aeae 376
77f43bb7 377 new (l[j++]) AliAODMCParticle(mcpartTmp);
93836e1b 378
da97a08a 379 }
da97a08a 380 }
93836e1b 381 AliInfo(Form("AliAODHandler::StoreMCParticles: Selected %d (Primaries %d / total %d) after validation \n",
da97a08a 382 j,nprim,np));
383
384 // Set the labels in the AOD output...
385 // Remapping
386
387 // AODTracks
388 TClonesArray* tracks = fAODEvent->GetTracks();
a2c30af1 389 Int_t tofLabel[3];
da97a08a 390 if(tracks){
391 for(int it = 0; it < fAODEvent->GetNTracks();++it){
392 AliAODTrack *track = fAODEvent->GetTrack(it);
393
91dece68 394 Int_t sign = 1;
395 Int_t label = track->GetLabel();
396 if(label<0){ // preserve the sign for later usage
397 label *= -1;
398 sign = -1;
399 }
a2c30af1 400
93836e1b 401 if (label >= AliMCEvent::BgLabelOffset()) label = mcEvent->BgLabelToIndex(label);
93836e1b 402 if(label > np || track->GetLabel() == 0){
403 AliWarning(Form("Wrong ESD track label %5d (%5d)",track->GetLabel(), label));
da97a08a 404 }
93836e1b 405 if(fMCEventH->GetNewLabel(label) == 0){
406 AliWarning(Form("New label not found for %5d (%5d)",track->GetLabel(), label));
da97a08a 407 }
91dece68 408 track->SetLabel(sign*fMCEventH->GetNewLabel(label));
a2c30af1 409
410 track->GetTOFLabel(tofLabel);
411
412 for (Int_t i =0; i < 3; i++) {
413 label = tofLabel[i]; // esd label
414 Int_t nlabel = label; // new label
415 if (label < 0) continue;
416 if (label >= AliMCEvent::BgLabelOffset()) nlabel = mcEvent->BgLabelToIndex(label);
417 if(nlabel > np || label == 0) {
418 AliWarning(Form("Wrong TOF label %5d (%5d)", label, nlabel));
419 }
420 if(fMCEventH->GetNewLabel(label) == 0){
421 AliWarning(Form("New TOF label not found for %5d",label ));
422 }
423 tofLabel[i] = fMCEventH->GetNewLabel(label);
424 }
425 track->SetTOFLabel(tofLabel);
da97a08a 426 }
427 }
428
429 // AOD calo cluster
430 TClonesArray *clusters = fAODEvent->GetCaloClusters();
431 if(clusters){
c8fe2783 432 for (Int_t iClust = 0;iClust < fAODEvent->GetNumberOfCaloClusters(); ++iClust) {
da97a08a 433 AliAODCaloCluster * cluster = fAODEvent->GetCaloCluster(iClust);
c8fe2783 434 UInt_t nLabel = cluster->GetNLabels();
da97a08a 435 // Ugly but do not want to fragment memory by creating
436 // new Int_t (nLabel)
437 Int_t* labels = const_cast<Int_t*>(cluster->GetLabels());
438 if (labels){
439 for(UInt_t i = 0;i < nLabel;++i){
c8fe2783 440 labels[i] = fMCEventH->GetNewLabel(cluster->GetLabelAt(i));
da97a08a 441 }
442 }
443 // cluster->SetLabels(labels,nLabel);
444 }// iClust
445 }// clusters
60d77596 446
447 // AOD calo cells MC label re-index
448 Int_t iCell, nCell, cellMCLabel, cellMCLabelNew;;
449 Short_t cellAbsId;
450 Double_t cellE, cellT, cellEFrac;
451 AliAODCaloCells *cells;
452
453 // EMCal
454 cells = fAODEvent->GetEMCALCells();
455 if( cells ){
456 nCell = cells->GetNumberOfCells() ;
457 for( iCell = 0; iCell < nCell; iCell++ ){
458 cells->GetCell( iCell, cellAbsId, cellE, cellT, cellMCLabel, cellEFrac );
459 // GetNewLabel returns 1 in case when -1 is supplied
460 if( cellMCLabel < 0 )
461 cellMCLabelNew = cellMCLabel;
462 else
463 cellMCLabelNew = fMCEventH->GetNewLabel( cellMCLabel );
464
465 cells->SetCell( iCell, cellAbsId, cellE, cellT, cellMCLabelNew, cellEFrac );
466 }
467 }
468 // PHOS
469 cells = fAODEvent->GetPHOSCells();
470 if( cells ){
471 nCell = cells->GetNumberOfCells() ;
472 for( iCell = 0; iCell < nCell; iCell++ ){
473 cells->GetCell( iCell, cellAbsId, cellE, cellT, cellMCLabel, cellEFrac );
474 // GetNewLabel returns 1 in case when -1 is supplied
475 if( cellMCLabel < 0 )
476 cellMCLabelNew = cellMCLabel;
477 else
478 cellMCLabelNew = fMCEventH->GetNewLabel( cellMCLabel );
479
480 cells->SetCell( iCell, cellAbsId, cellE, cellT, cellMCLabelNew, cellEFrac );
481 }
482 }
da97a08a 483
484 // AOD tracklets
485 AliAODTracklets *tracklets = fAODEvent->GetTracklets();
486 if(tracklets){
487 for(int it = 0;it < tracklets->GetNumberOfTracklets();++it){
488 int label0 = tracklets->GetLabel(it,0);
489 int label1 = tracklets->GetLabel(it,1);
490 if(label0>=0)label0 = fMCEventH->GetNewLabel(label0);
491 if(label1>=0)label1 = fMCEventH->GetNewLabel(label1);
492 tracklets->SetLabel(it,0,label0);
493 tracklets->SetLabel(it,1,label1);
494 }
495 }
496
497}
498
9066c676 499//______________________________________________________________________________
5f380da9 500Bool_t AliAODHandler::FinishEvent()
ec4af4c1 501{
da97a08a 502 // Fill data structures
4e6d5854 503 if(fFillAOD && fFillAODRun && fAODEvent){
b8b7dd5c 504 fAODEvent->MakeEntriesReferencable();
e0107012 505 fTreeA->BranchRef();
b8b7dd5c 506 FillTree();
4e6d5854 507 }
f133e976 508
ca2834f6 509 if ((fFillAOD && fFillAODRun) || fFillExtension) {
307b6330 510 if (fExtensions && fFillExtension) {
511 // fFillExtension can be set by the ESD filter or by a delta filter in case of AOD inputs
14d6fad5 512 TIter next(fExtensions);
513 AliAODExtension *ext;
514 while ((ext=(AliAODExtension*)next())) ext->FinishEvent();
515 }
307b6330 516 if (fFilters && fFillAOD && fFillAODRun) {
14d6fad5 517 TIter nextf(fFilters);
518 AliAODExtension *ext;
519 while ((ext=(AliAODExtension*)nextf())) {
b8b7dd5c 520 ext->FinishEvent();
14d6fad5 521 }
522 }
aa399a26 523 }
14d6fad5 524
dddc33c5 525 if (fIsStandard && fAODEvent)
14d6fad5 526 {
527 fAODEvent->ResetStd();
528 }
529
530 if (fAODEvent)
531 {
532 TClonesArray *mcarray = static_cast<TClonesArray*>(fAODEvent->FindListObject(AliAODMCParticle::StdBranchName()));
ef89f372 533 if(mcarray) mcarray->Delete();
534
14d6fad5 535 AliAODMCHeader *mcHeader = static_cast<AliAODMCHeader*>(fAODEvent->FindListObject(AliAODMCHeader::StdBranchName()));
ef89f372 536 if(mcHeader) mcHeader->Reset();
537 }
14d6fad5 538
da97a08a 539 // Reset AOD replication flag
540 fAODIsReplicated = kFALSE;
541 return kTRUE;
ec4af4c1 542}
543
7970f4ac 544//______________________________________________________________________________
ec4af4c1 545Bool_t AliAODHandler::Terminate()
546{
9066c676 547 // Terminate
548 AddAODtoTreeUserInfo();
14d6fad5 549
550 TIter nextF(fFilters);
551 AliAODExtension *ext;
552 while ((ext=static_cast<AliAODExtension*>(nextF())))
553 {
554 ext->AddAODtoTreeUserInfo();
555 }
556
557 TIter nextE(fExtensions);
558 while ((ext=static_cast<AliAODExtension*>(nextE())))
559 {
560 ext->AddAODtoTreeUserInfo();
561 }
562
9066c676 563 return kTRUE;
ec4af4c1 564}
565
7970f4ac 566//______________________________________________________________________________
ec4af4c1 567Bool_t AliAODHandler::TerminateIO()
568{
9066c676 569 // Terminate IO
570 if (fFileA) {
aa399a26 571 fFileA->Write();
9066c676 572 fFileA->Close();
573 delete fFileA;
574 fFileA = 0;
48f1c230 575 // When closing the file, the tree is also deleted.
576 fTreeA = 0;
9066c676 577 }
14d6fad5 578
579 TIter nextF(fFilters);
580 AliAODExtension *ext;
581 while ((ext=static_cast<AliAODExtension*>(nextF())))
582 {
583 ext->TerminateIO();
9066c676 584 }
14d6fad5 585
586 TIter nextE(fExtensions);
587 while ((ext=static_cast<AliAODExtension*>(nextE())))
588 {
589 ext->TerminateIO();
582cfeb5 590 }
14d6fad5 591
9066c676 592 return kTRUE;
ec4af4c1 593}
594
7970f4ac 595//______________________________________________________________________________
954526ed 596void AliAODHandler::CreateTree(Int_t flag)
ec4af4c1 597{
598 // Creates the AOD Tree
f3214a54 599 fTreeA = new TTree("aodTree", "AliAOD tree");
ec4af4c1 600 fTreeA->Branch(fAODEvent->GetList());
954526ed 601 if (flag == 0) fTreeA->SetDirectory(0);
ec4af4c1 602}
603
7970f4ac 604//______________________________________________________________________________
ec4af4c1 605void AliAODHandler::FillTree()
606{
866d8d78 607
ec4af4c1 608 // Fill the AOD Tree
e0107012 609 fTreeA->Fill();
ec4af4c1 610}
611
7970f4ac 612//______________________________________________________________________________
ec4af4c1 613void AliAODHandler::AddAODtoTreeUserInfo()
614{
dce1b636 615 // Add aod event to tree user info
aa399a26 616 if (fTreeA) fTreeA->GetUserInfo()->Add(fAODEvent);
48f1c230 617 // Now the tree owns our fAODEvent...
618 fAODEvent = 0;
ec4af4c1 619}
490e9023 620
7970f4ac 621//______________________________________________________________________________
9066c676 622void AliAODHandler::AddBranch(const char* cname, void* addobj, const char* filename)
490e9023 623{
14d6fad5 624 // Add a new branch to the aod. Added optional filename parameter if the
625 // branch should be written to a separate file.
626
627 if (strlen(filename))
628 {
629 AliAODExtension *ext = AddExtension(filename);
630 ext->AddBranch(cname, addobj);
631 return;
632 }
633
634 // Add branch to all filters
635 // Add branch to all filters
636 if (fFilters) {
637 TIter next(fFilters);
638 AliAODExtension *ext;
639 while ((ext=(AliAODExtension*)next())) ext->AddBranch(cname, addobj);
640 }
641
642 TDirectory *owd = gDirectory;
643 if (fFileA)
644 {
645 fFileA->cd();
646 }
dce1b636 647
14d6fad5 648 char** apointer = (char**) addobj;
649 TObject* obj = (TObject*) *apointer;
650
651 fAODEvent->AddObject(obj);
652
653 const Int_t kSplitlevel = 99; // default value in TTree::Branch()
654 const Int_t kBufsize = 32000; // default value in TTree::Branch()
655
656 if (!fTreeA->FindBranch(obj->GetName()))
657 {
658 // Do the same as if we book via
659 // TTree::Branch(TCollection*)
660
661 fTreeA->Bronch(obj->GetName(), cname, fAODEvent->GetList()->GetObjectRef(obj),
662 kBufsize, kSplitlevel - 1);
663 }
664 owd->cd();
490e9023 665}
7970f4ac 666
667//______________________________________________________________________________
9066c676 668AliAODExtension *AliAODHandler::AddExtension(const char *filename, const char *title)
669{
14d6fad5 670 // Add an AOD extension with some branches in a different file.
26ba01d4 671
14d6fad5 672 TString fname(filename);
673 if (!fname.EndsWith(".root")) fname += ".root";
674 if (!fExtensions) {
675 fExtensions = new TObjArray();
676 fExtensions->SetOwner();
677 }
678 AliAODExtension *ext = (AliAODExtension*)fExtensions->FindObject(fname);
679 if (!ext) {
680 ext = new AliAODExtension(fname, title);
681 fExtensions->Add(ext);
682 }
683 return ext;
9066c676 684}
582cfeb5 685
686//______________________________________________________________________________
687AliAODExtension *AliAODHandler::GetExtension(const char *filename) const
688{
14d6fad5 689 // Getter for AOD extensions via file name.
690 if (!fExtensions) return NULL;
691 return (AliAODExtension*)fExtensions->FindObject(filename);
582cfeb5 692}
693
694//______________________________________________________________________________
695AliAODExtension *AliAODHandler::AddFilteredAOD(const char *filename, const char *filtername)
696{
14d6fad5 697 // Add an AOD extension that can write only AOD events that pass a user filter.
698 if (!fFilters) {
699 fFilters = new TObjArray();
700 fFilters->SetOwner();
701 }
702 AliAODExtension *filter = (AliAODExtension*)fFilters->FindObject(filename);
703 if (!filter) {
704 filter = new AliAODExtension(filename, filtername, kTRUE);
705 fFilters->Add(filter);
706 }
707 return filter;
582cfeb5 708}
709
710//______________________________________________________________________________
711AliAODExtension *AliAODHandler::GetFilteredAOD(const char *filename) const
712{
14d6fad5 713 // Getter for AOD filters via file name.
714 if (!fFilters) return NULL;
715 return (AliAODExtension*)fFilters->FindObject(filename);
582cfeb5 716}
14d6fad5 717
9066c676 718//______________________________________________________________________________
7970f4ac 719void AliAODHandler::SetOutputFileName(const char* fname)
720{
721// Set file name.
722 fFileName = fname;
723}
724
725//______________________________________________________________________________
fdbaa4ce 726const char *AliAODHandler::GetOutputFileName() const
7970f4ac 727{
728// Get file name.
729 return fFileName.Data();
730}
dce1b636 731
9066c676 732//______________________________________________________________________________
90d50a8c 733const char *AliAODHandler::GetExtraOutputs() const
734{
14d6fad5 735 // Get extra outputs as a string separated by commas.
736 static TString eoutputs;
737 eoutputs = "";
738 TObject *obj;
739 if (fExtensions) {
740 TIter next1(fExtensions);
741 while ((obj=next1())) {
742 if (!eoutputs.IsNull()) eoutputs += ",";
743 eoutputs += obj->GetName();
744 }
745 }
746 if (fFilters) {
747 TIter next2(fFilters);
748 while ((obj=next2())) {
749 if (!eoutputs.IsNull()) eoutputs += ",";
750 eoutputs += obj->GetName();
751 }
752 }
753 return eoutputs.Data();
754}
755
756//______________________________________________________________________________
757Bool_t AliAODHandler::HasExtensions() const
758{
759 // Whether or not we manage extensions
760
761 if ( fExtensions && fExtensions->GetEntries()>0 ) return kTRUE;
762
763 return kFALSE;
90d50a8c 764}
765
766//______________________________________________________________________________
dce1b636 767void AliAODHandler::SetMCHeaderInfo(AliAODMCHeader *mcHeader,AliGenEventHeader *genHeader){
768
769
770 // Utility function to cover different cases for the AliGenEventHeader
771 // Needed since different ProcessType and ImpactParamter are not
772 // in the base class...
dce1b636 773
dce1b636 774 if(!genHeader)return;
775 AliGenPythiaEventHeader *pythiaGenHeader = dynamic_cast<AliGenPythiaEventHeader*>(genHeader);
08078824 776 if (pythiaGenHeader) {
777 mcHeader->SetEventType(pythiaGenHeader->ProcessType());
778 mcHeader->SetPtHard(pythiaGenHeader->GetPtHard());
779 return;
780 }
781
782 AliGenDPMjetEventHeader* dpmJetGenHeader = dynamic_cast<AliGenDPMjetEventHeader*>(genHeader);
783
dce1b636 784 if (dpmJetGenHeader){
785 mcHeader->SetEventType(dpmJetGenHeader->ProcessType());
786 return;
787 }
788
789 AliGenHijingEventHeader* hijingGenHeader = dynamic_cast<AliGenHijingEventHeader*>(genHeader);
790 if(hijingGenHeader){
791 mcHeader->SetImpactParameter(hijingGenHeader->ImpactParameter());
792 return;
793 }
794
08078824 795 // AliWarning(Form("MC Eventheader not known: %s",genHeader->GetName()));
796
dce1b636 797}
9066c676 798