]> git.uio.no Git - u/mrichter/AliRoot.git/blame - STEER/AliAODHandler.cxx
Improved muon AOD's from Laurent
[u/mrichter/AliRoot.git] / STEER / 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"
da97a08a 34#include "AliAODTracklets.h"
35#include "AliStack.h"
36#include "AliAODMCParticle.h"
dce1b636 37#include "AliAODMCHeader.h"
da97a08a 38#include "AliMCEventHandler.h"
39#include "AliMCEvent.h"
dce1b636 40#include "AliGenEventHeader.h"
41#include "AliGenHijingEventHeader.h"
42#include "AliGenDPMjetEventHeader.h"
43#include "AliGenPythiaEventHeader.h"
44#include "AliGenCocktailEventHeader.h"
26ba01d4 45#include "AliCodeTimer.h"
46#include "AliAODBranchReplicator.h"
47#include "Riostream.h"
ec4af4c1 48
49ClassImp(AliAODHandler)
50
51//______________________________________________________________________________
52AliAODHandler::AliAODHandler() :
f3214a54 53 AliVEventHandler(),
78f7f935 54 fIsStandard(kTRUE),
da97a08a 55 fFillAOD(kTRUE),
41b01ae4 56 fFillAODRun(kTRUE),
7c3a9fbf 57 fNeedsHeaderReplication(kFALSE),
75754ba8 58 fNeedsTracksBranchReplication(kFALSE),
59 fNeedsVerticesBranchReplication(kFALSE),
60 fNeedsV0sBranchReplication(kFALSE),
e0107012 61 fNeedsCascadesBranchReplication(kFALSE),
75754ba8 62 fNeedsTrackletsBranchReplication(kFALSE),
63 fNeedsPMDClustersBranchReplication(kFALSE),
64 fNeedsJetsBranchReplication(kFALSE),
65 fNeedsFMDClustersBranchReplication(kFALSE),
66 fNeedsCaloClustersBranchReplication(kFALSE),
3549c522 67 fNeedsMCParticlesBranchReplication(kFALSE),
866d8d78 68 fNeedsDimuonsBranchReplication(kFALSE),
75754ba8 69 fAODIsReplicated(kFALSE),
ec4af4c1 70 fAODEvent(NULL),
da97a08a 71 fMCEventH(NULL),
e910dd36 72 fTreeA(NULL),
73 fFileA(NULL),
9066c676 74 fFileName(""),
582cfeb5 75 fExtensions(NULL),
76 fFilters(NULL)
ec4af4c1 77{
78 // default constructor
79}
80
81//______________________________________________________________________________
82AliAODHandler::AliAODHandler(const char* name, const char* title):
f3214a54 83 AliVEventHandler(name, title),
78f7f935 84 fIsStandard(kTRUE),
da97a08a 85 fFillAOD(kTRUE),
41b01ae4 86 fFillAODRun(kTRUE),
7c3a9fbf 87 fNeedsHeaderReplication(kFALSE),
75754ba8 88 fNeedsTracksBranchReplication(kFALSE),
89 fNeedsVerticesBranchReplication(kFALSE),
90 fNeedsV0sBranchReplication(kFALSE),
e0107012 91 fNeedsCascadesBranchReplication(kFALSE),
75754ba8 92 fNeedsTrackletsBranchReplication(kFALSE),
93 fNeedsPMDClustersBranchReplication(kFALSE),
94 fNeedsJetsBranchReplication(kFALSE),
95 fNeedsFMDClustersBranchReplication(kFALSE),
96 fNeedsCaloClustersBranchReplication(kFALSE),
3549c522 97 fNeedsMCParticlesBranchReplication(kFALSE),
866d8d78 98 fNeedsDimuonsBranchReplication(kFALSE),
75754ba8 99 fAODIsReplicated(kFALSE),
ec4af4c1 100 fAODEvent(NULL),
da97a08a 101 fMCEventH(NULL),
e910dd36 102 fTreeA(NULL),
103 fFileA(NULL),
9066c676 104 fFileName(""),
582cfeb5 105 fExtensions(NULL),
106 fFilters(NULL)
ec4af4c1 107{
582cfeb5 108// Normal constructor.
ec4af4c1 109}
110
111//______________________________________________________________________________
112AliAODHandler::~AliAODHandler()
113{
9066c676 114 // Destructor.
48f1c230 115 if (fAODEvent) delete fAODEvent;
6989bff3 116 if(fFileA){
117 // is already handled in TerminateIO
118 fFileA->Close();
119 delete fFileA;
48f1c230 120 fTreeA = 0;
6989bff3 121 }
48f1c230 122 if (fTreeA) delete fTreeA;
123 if (fExtensions) {fExtensions->Delete(); delete fExtensions;}
124 if (fFilters) {fFilters->Delete(); delete fFilters;}
ec4af4c1 125}
126
7970f4ac 127//______________________________________________________________________________
300d5701 128Bool_t AliAODHandler::Init(Option_t* opt)
ec4af4c1 129{
6989bff3 130 // Initialize IO
131 //
132 // Create the AODevent object
e0107012 133
4e6d5854 134 Bool_t createStdAOD = fIsStandard || fFillAOD;
aa399a26 135 if(!fAODEvent && createStdAOD){
ec4af4c1 136 fAODEvent = new AliAODEvent();
c8fe2783 137 if (fIsStandard)
138 fAODEvent->CreateStdContent();
6989bff3 139 }
140 //
141 // File opening according to execution mode
7970f4ac 142 TString option(opt);
143 option.ToLower();
aa399a26 144 if (createStdAOD) {
145 TDirectory *owd = gDirectory;
146 if (option.Contains("proof")) {
147 // proof
148 // Merging via files. Need to access analysis manager via interpreter.
149 gROOT->ProcessLine(Form("AliAnalysisDataContainer *c_common_out = AliAnalysisManager::GetAnalysisManager()->GetCommonOutputContainer();"));
150 gROOT->ProcessLine(Form("AliAnalysisManager::GetAnalysisManager()->OpenProofFile(c_common_out, \"RECREATE\");"));
151 fFileA = gFile;
152 } else {
153 // local and grid
154 fFileA = new TFile(fFileName.Data(), "RECREATE");
155 }
156 CreateTree(1);
157 owd->cd();
158 }
9066c676 159 if (fExtensions) {
160 TIter next(fExtensions);
161 AliAODExtension *ext;
162 while ((ext=(AliAODExtension*)next())) ext->Init(option);
163 }
582cfeb5 164 if (fFilters) {
165 TIter nextf(fFilters);
166 AliAODExtension *filteredAOD;
167 while ((filteredAOD=(AliAODExtension*)nextf())) {
168 filteredAOD->SetEvent(fAODEvent);
169 filteredAOD->Init(option);
170 }
171 }
6989bff3 172 return kTRUE;
ec4af4c1 173}
174
26ba01d4 175//______________________________________________________________________________
176void AliAODHandler::Print(Option_t* opt) const
177{
178 // Print info about this object
179
180 cout << opt << Form("IsStandard %d filename=%s",fIsStandard,fFileName.Data()) << endl;
181
182 if ( fExtensions )
183 {
184 cout << opt << fExtensions->GetEntries() << " extensions :" << endl;
185 PrintExtensions("Extensions",*fExtensions);
186 }
187 if ( fFilters )
188 {
189 cout << opt << fFilters->GetEntries() << " filters :" << endl;
190 PrintExtensions("Filters",*fFilters);
191 }
192}
193
194//______________________________________________________________________________
195void AliAODHandler::PrintExtensions(const char* name, const TObjArray& array) const
196{
197 // Show the list of aod extensions
198 TIter next(&array);
199 AliAODExtension* ext(0x0);
200 while ( ( ext = static_cast<AliAODExtension*>(next()) ) )
201 {
202 ext->Print(" ");
203 }
204}
205
9066c676 206//______________________________________________________________________________
da97a08a 207void AliAODHandler::StoreMCParticles(){
dce1b636 208
da97a08a 209 //
210 // Remap the labels from ESD stack and store
211 // the AODMCParticles, makes only sense if we have
212 // the mcparticles branch
213 // has to be done here since we cannot know in advance
214 // which particles are needed (e.g. by the tracks etc.)
215 //
216 // Particles have been selected by AliMCEventhanlder->SelectParticle()
217 // To use the MCEventhandler here we need to set it from the outside
218 // can vanish when Handler go to the ANALYSISalice library
dce1b636 219 //
220 // The Branch booking for mcParticles and mcHeader has to happen
221 // in an external task for now since the AODHandler does not have access
222 // the AnalysisManager. For the same reason the pointer t o the MCEventH
223 // has to passed to the AOD Handler by this task
224 // (doing this in the steering macro would not work on PROOF)
da97a08a 225
aa399a26 226 if (!fAODEvent) return;
da97a08a 227 TClonesArray *mcarray = (TClonesArray*)fAODEvent->FindListObject(AliAODMCParticle::StdBranchName());
228 if(!mcarray)return;
da97a08a 229
dce1b636 230 AliAODMCHeader *mcHeader = (AliAODMCHeader*)fAODEvent->FindListObject(AliAODMCHeader::StdBranchName());
231 if(!mcHeader)return;
232
da97a08a 233 // Get the MC Infos.. Handler needs to be set before
234 // while adding the branch
235 // This needs to be done, not to depend on the AnalysisManager
236
237 if(!fMCEventH)return;
238 if(!fMCEventH->MCEvent())return;
239 AliStack *pStack = fMCEventH->MCEvent()->Stack();
240 if(!pStack)return;
241
242 fMCEventH->CreateLabelMap();
243
dce1b636 244 //
245 // Get the Event Header
246 //
247
248 AliHeader* header = fMCEventH->MCEvent()->Header();
9efd8e10 249 // get the MC vertex
250 AliGenEventHeader* genHeader = 0;
251 if (header) genHeader = header->GenEventHeader();
252 if (genHeader) {
253 TArrayF vtxMC(3);
254 genHeader->PrimaryVertex(vtxMC);
255 mcHeader->SetVertex(vtxMC[0],vtxMC[1],vtxMC[2]);
256
257 // we search the MCEventHeaders first
258 // Two cases, cocktail or not...
259 AliGenCocktailEventHeader* genCocktailHeader = dynamic_cast<AliGenCocktailEventHeader*>(genHeader);
260 if(genCocktailHeader){
261 // we have a coktail header
262 mcHeader->AddGeneratorName(genHeader->GetName());
263 // Loop from the back so that the first one sets the process type
264 TList* headerList = genCocktailHeader->GetHeaders();
265 for(int i = headerList->GetEntries()-1;i>=0;--i){
266 AliGenEventHeader *headerEntry = dynamic_cast<AliGenEventHeader*>(headerList->At(i));
267 SetMCHeaderInfo(mcHeader,headerEntry);
268 }
269 }
270 else{
271 // No Cocktail just take the first one
272 SetMCHeaderInfo(mcHeader,genHeader);
273 }
dce1b636 274 }
9efd8e10 275
dce1b636 276
277
278
279
280 // Store the AliAODParticlesMC
93836e1b 281 AliMCEvent* mcEvent = fMCEventH->MCEvent();
282
283 Int_t np = mcEvent->GetNumberOfTracks();
284 Int_t nprim = mcEvent->GetNumberOfPrimaries();
da97a08a 285
286
287 Int_t j = 0;
288 TClonesArray& l = *mcarray;
289
93836e1b 290 for(int i = 0; i < np; ++i){
291 if(fMCEventH->IsParticleSelected(i)){
292 Int_t flag = 0;
6cd07d0a 293 AliMCParticle* mcpart = (AliMCParticle*) mcEvent->GetTrack(i);
93836e1b 294 if(i<nprim)flag |= AliAODMCParticle::kPrimary;
295
296 if(mcEvent->IsPhysicalPrimary(i))flag |= AliAODMCParticle::kPhysicalPrim;
297
298 if(fMCEventH->GetNewLabel(i)!=j){
299 AliError(Form("MISMATCH New label %d j: %d",fMCEventH->GetNewLabel(i),j));
da97a08a 300 }
da97a08a 301
93836e1b 302 AliAODMCParticle mcpart_tmp(mcpart,i,flag);
303
6326aeae 304 mcpart_tmp.SetStatus(mcpart->Particle()->GetStatusCode());
93836e1b 305 //
306 Int_t d0 = mcpart_tmp.GetDaughter(0);
307 Int_t d1 = mcpart_tmp.GetDaughter(1);
308 Int_t m = mcpart_tmp.GetMother();
309
310 // other than for the track labels, negative values mean
311 // no daughter/mother so preserve it
312
313 if(d0<0 && d1<0){
314 // no first daughter -> no second daughter
315 // nothing to be done
316 // second condition not needed just for sanity check at the end
317 mcpart_tmp.SetDaughter(0,d0);
318 mcpart_tmp.SetDaughter(1,d1);
319 } else if(d1 < 0 && d0 >= 0) {
320 // Only one daughter
321 // second condition not needed just for sanity check at the end
322 if(fMCEventH->IsParticleSelected(d0)){
323 mcpart_tmp.SetDaughter(0,fMCEventH->GetNewLabel(d0));
324 } else {
325 mcpart_tmp.SetDaughter(0,-1);
326 }
327 mcpart_tmp.SetDaughter(1,d1);
328 }
329 else if (d0 > 0 && d1 > 0 ){
330 // we have two or more daughters loop on the stack to see if they are
331 // selected
332 Int_t d0_tmp = -1;
333 Int_t d1_tmp = -1;
334 for(int id = d0; id<=d1;++id){
335 if(fMCEventH->IsParticleSelected(id)){
336 if(d0_tmp==-1){
337 // first time
338 d0_tmp = fMCEventH->GetNewLabel(id);
339 d1_tmp = d0_tmp; // this is to have the same schema as on the stack i.e. with one daugther d0 and d1 are the same
340 }
341 else d1_tmp = fMCEventH->GetNewLabel(id);
342 }
343 }
344 mcpart_tmp.SetDaughter(0,d0_tmp);
345 mcpart_tmp.SetDaughter(1,d1_tmp);
346 } else {
347 AliError(Form("Unxpected indices %d %d",d0,d1));
348 }
349
350 if(m<0){
351 mcpart_tmp.SetMother(m);
352 } else {
353 if(fMCEventH->IsParticleSelected(m))mcpart_tmp.SetMother(fMCEventH->GetNewLabel(m));
354 else AliError(Form("PROBLEM Mother not selected %d \n", m));
355 }
6326aeae 356
93836e1b 357 new (l[j++]) AliAODMCParticle(mcpart_tmp);
358
da97a08a 359 }
da97a08a 360 }
93836e1b 361 AliInfo(Form("AliAODHandler::StoreMCParticles: Selected %d (Primaries %d / total %d) after validation \n",
da97a08a 362 j,nprim,np));
363
364 // Set the labels in the AOD output...
365 // Remapping
366
367 // AODTracks
368 TClonesArray* tracks = fAODEvent->GetTracks();
369 if(tracks){
370 for(int it = 0; it < fAODEvent->GetNTracks();++it){
371 AliAODTrack *track = fAODEvent->GetTrack(it);
372
91dece68 373 Int_t sign = 1;
374 Int_t label = track->GetLabel();
375 if(label<0){ // preserve the sign for later usage
376 label *= -1;
377 sign = -1;
378 }
379
93836e1b 380 if (label >= AliMCEvent::BgLabelOffset()) label = mcEvent->BgLabelToIndex(label);
93836e1b 381 if(label > np || track->GetLabel() == 0){
382 AliWarning(Form("Wrong ESD track label %5d (%5d)",track->GetLabel(), label));
da97a08a 383 }
93836e1b 384 if(fMCEventH->GetNewLabel(label) == 0){
385 AliWarning(Form("New label not found for %5d (%5d)",track->GetLabel(), label));
da97a08a 386 }
91dece68 387 track->SetLabel(sign*fMCEventH->GetNewLabel(label));
da97a08a 388 }
389 }
390
391 // AOD calo cluster
392 TClonesArray *clusters = fAODEvent->GetCaloClusters();
393 if(clusters){
c8fe2783 394 for (Int_t iClust = 0;iClust < fAODEvent->GetNumberOfCaloClusters(); ++iClust) {
da97a08a 395 AliAODCaloCluster * cluster = fAODEvent->GetCaloCluster(iClust);
c8fe2783 396 UInt_t nLabel = cluster->GetNLabels();
da97a08a 397 // Ugly but do not want to fragment memory by creating
398 // new Int_t (nLabel)
399 Int_t* labels = const_cast<Int_t*>(cluster->GetLabels());
400 if (labels){
401 for(UInt_t i = 0;i < nLabel;++i){
c8fe2783 402 labels[i] = fMCEventH->GetNewLabel(cluster->GetLabelAt(i));
da97a08a 403 }
404 }
405 // cluster->SetLabels(labels,nLabel);
406 }// iClust
407 }// clusters
408
409 // AOD tracklets
410 AliAODTracklets *tracklets = fAODEvent->GetTracklets();
411 if(tracklets){
412 for(int it = 0;it < tracklets->GetNumberOfTracklets();++it){
413 int label0 = tracklets->GetLabel(it,0);
414 int label1 = tracklets->GetLabel(it,1);
415 if(label0>=0)label0 = fMCEventH->GetNewLabel(label0);
416 if(label1>=0)label1 = fMCEventH->GetNewLabel(label1);
417 tracklets->SetLabel(it,0,label0);
418 tracklets->SetLabel(it,1,label1);
419 }
420 }
421
422}
423
9066c676 424//______________________________________________________________________________
5f380da9 425Bool_t AliAODHandler::FinishEvent()
ec4af4c1 426{
da97a08a 427 // Fill data structures
4e6d5854 428 if(fFillAOD && fFillAODRun && fAODEvent){
b8b7dd5c 429 fAODEvent->MakeEntriesReferencable();
e0107012 430 fTreeA->BranchRef();
b8b7dd5c 431 FillTree();
4e6d5854 432 }
f133e976 433
0f2bf592 434 if (fFillAOD && fFillAODRun) {
b8b7dd5c 435 if (fExtensions) {
436 TIter next(fExtensions);
437 AliAODExtension *ext;
438 while ((ext=(AliAODExtension*)next())) ext->FinishEvent();
439 }
440 if (fFilters) {
441 TIter nextf(fFilters);
442 AliAODExtension *ext;
443 while ((ext=(AliAODExtension*)nextf())) {
444 ext->FinishEvent();
445 }
446 }
aa399a26 447 }
da97a08a 448 if (fIsStandard) fAODEvent->ResetStd();
ef89f372 449 if (fAODEvent) {
450 TClonesArray *mcarray = (TClonesArray*)fAODEvent->FindListObject(AliAODMCParticle::StdBranchName());
451 if(mcarray) mcarray->Delete();
452
453 AliAODMCHeader *mcHeader = (AliAODMCHeader*)fAODEvent->FindListObject(AliAODMCHeader::StdBranchName());
454 if(mcHeader) mcHeader->Reset();
455 }
da97a08a 456 // Reset AOD replication flag
457 fAODIsReplicated = kFALSE;
458 return kTRUE;
ec4af4c1 459}
460
7970f4ac 461//______________________________________________________________________________
ec4af4c1 462Bool_t AliAODHandler::Terminate()
463{
9066c676 464 // Terminate
465 AddAODtoTreeUserInfo();
466 if (fExtensions) {
467 TIter next(fExtensions);
468 AliAODExtension *ext;
469 while ((ext=(AliAODExtension*)next())) ext->GetTree()->GetUserInfo()->Add(ext->GetAOD());
470 }
471 return kTRUE;
ec4af4c1 472}
473
7970f4ac 474//______________________________________________________________________________
ec4af4c1 475Bool_t AliAODHandler::TerminateIO()
476{
9066c676 477 // Terminate IO
478 if (fFileA) {
aa399a26 479 fFileA->Write();
9066c676 480 fFileA->Close();
481 delete fFileA;
482 fFileA = 0;
48f1c230 483 // When closing the file, the tree is also deleted.
484 fTreeA = 0;
9066c676 485 }
486 if (fExtensions) {
487 TIter next(fExtensions);
488 AliAODExtension *ext;
489 while ((ext=(AliAODExtension*)next())) ext->TerminateIO();
490 }
582cfeb5 491 if (fFilters) {
492 TIter nextf(fFilters);
493 AliAODExtension *ext;
494 while ((ext=(AliAODExtension*)nextf())) ext->TerminateIO();
495 }
9066c676 496 return kTRUE;
ec4af4c1 497}
498
7970f4ac 499//______________________________________________________________________________
954526ed 500void AliAODHandler::CreateTree(Int_t flag)
ec4af4c1 501{
502 // Creates the AOD Tree
f3214a54 503 fTreeA = new TTree("aodTree", "AliAOD tree");
ec4af4c1 504 fTreeA->Branch(fAODEvent->GetList());
954526ed 505 if (flag == 0) fTreeA->SetDirectory(0);
ec4af4c1 506}
507
7970f4ac 508//______________________________________________________________________________
ec4af4c1 509void AliAODHandler::FillTree()
510{
866d8d78 511
ec4af4c1 512 // Fill the AOD Tree
e0107012 513 fTreeA->Fill();
ec4af4c1 514}
515
7970f4ac 516//______________________________________________________________________________
ec4af4c1 517void AliAODHandler::AddAODtoTreeUserInfo()
518{
dce1b636 519 // Add aod event to tree user info
aa399a26 520 if (fTreeA) fTreeA->GetUserInfo()->Add(fAODEvent);
48f1c230 521 // Now the tree owns our fAODEvent...
522 fAODEvent = 0;
ec4af4c1 523}
490e9023 524
7970f4ac 525//______________________________________________________________________________
9066c676 526void AliAODHandler::AddBranch(const char* cname, void* addobj, const char* filename)
490e9023 527{
9066c676 528 // Add a new branch to the aod. Added optional filename parameter if the
529 // branch should be written to a separate file.
530 if (strlen(filename)) {
531 AliAODExtension *ext = AddExtension(filename);
532 ext->AddBranch(cname, addobj);
533 return;
ee830d15 534 } else {
535 // Add branch to all filters
536 if (fFilters) {
537 TIter next(fFilters);
538 AliAODExtension *ext;
539 while ((ext=(AliAODExtension*)next())) ext->AddBranch(cname, addobj);
540 }
9066c676 541 }
490e9023 542 TDirectory *owd = gDirectory;
543 if (fFileA) {
dce1b636 544 fFileA->cd();
490e9023 545 }
0134949d 546 char** apointer = (char**) addobj;
547 TObject* obj = (TObject*) *apointer;
dce1b636 548
0134949d 549 fAODEvent->AddObject(obj);
dce1b636 550
551 const Int_t kSplitlevel = 99; // default value in TTree::Branch()
552 const Int_t kBufsize = 32000; // default value in TTree::Branch()
553
554 if (!fTreeA->FindBranch(obj->GetName())) {
555 // Do the same as if we book via
556 // TTree::Branch(TCollection*)
557
558 fTreeA->Bronch(obj->GetName(), cname, fAODEvent->GetList()->GetObjectRef(obj),
559 kBufsize, kSplitlevel - 1);
dce1b636 560 }
490e9023 561 owd->cd();
562}
7970f4ac 563
9066c676 564//______________________________________________________________________________
565AliAODExtension *AliAODHandler::AddExtension(const char *filename, const char *title)
566{
567// Add an AOD extension with some branches in a different file.
26ba01d4 568
9066c676 569 TString fname(filename);
570 if (!fname.EndsWith(".root")) fname += ".root";
571 if (!fExtensions) {
572 fExtensions = new TObjArray();
573 fExtensions->SetOwner();
574 }
575 AliAODExtension *ext = (AliAODExtension*)fExtensions->FindObject(fname);
576 if (!ext) {
577 ext = new AliAODExtension(fname, title);
578 fExtensions->Add(ext);
579 }
580 return ext;
581}
582cfeb5 582
583//______________________________________________________________________________
584AliAODExtension *AliAODHandler::GetExtension(const char *filename) const
585{
586// Getter for AOD extensions via file name.
587 if (!fExtensions) return NULL;
588 return (AliAODExtension*)fExtensions->FindObject(filename);
589}
590
591//______________________________________________________________________________
592AliAODExtension *AliAODHandler::AddFilteredAOD(const char *filename, const char *filtername)
593{
594// Add an AOD extension that can write only AOD events that pass a user filter.
595 if (!fFilters) {
596 fFilters = new TObjArray();
597 fFilters->SetOwner();
598 }
599 AliAODExtension *filter = (AliAODExtension*)fFilters->FindObject(filename);
600 if (!filter) {
601 filter = new AliAODExtension(filename, filtername, kTRUE);
602 fFilters->Add(filter);
603 }
604 return filter;
605}
606
607//______________________________________________________________________________
608AliAODExtension *AliAODHandler::GetFilteredAOD(const char *filename) const
609{
610// Getter for AOD filters via file name.
611 if (!fFilters) return NULL;
612 return (AliAODExtension*)fFilters->FindObject(filename);
613}
9066c676 614
7970f4ac 615//______________________________________________________________________________
616void AliAODHandler::SetOutputFileName(const char* fname)
617{
618// Set file name.
619 fFileName = fname;
620}
621
622//______________________________________________________________________________
623const char *AliAODHandler::GetOutputFileName()
624{
625// Get file name.
626 return fFileName.Data();
627}
dce1b636 628
90d50a8c 629//______________________________________________________________________________
630const char *AliAODHandler::GetExtraOutputs() const
631{
632// Get extra outputs as a string separated by commas.
633 static TString eoutputs;
634 eoutputs = "";
635 TObject *obj;
636 if (fExtensions) {
637 TIter next1(fExtensions);
638 while ((obj=next1())) {
639 if (!eoutputs.IsNull()) eoutputs += ",";
640 eoutputs += obj->GetName();
641 }
642 }
643 if (fFilters) {
644 TIter next2(fFilters);
645 while ((obj=next2())) {
646 if (!eoutputs.IsNull()) eoutputs += ",";
647 eoutputs += obj->GetName();
648 }
649 }
650 return eoutputs.Data();
651}
652
9066c676 653//______________________________________________________________________________
dce1b636 654void AliAODHandler::SetMCHeaderInfo(AliAODMCHeader *mcHeader,AliGenEventHeader *genHeader){
655
656
657 // Utility function to cover different cases for the AliGenEventHeader
658 // Needed since different ProcessType and ImpactParamter are not
659 // in the base class...
660 // We don't encode process types for event cocktails yet
9066c676 661 // could be done e.g. by adding offsets depnding on the generator
dce1b636 662
663 mcHeader->AddGeneratorName(genHeader->GetName());
dce1b636 664 if(!genHeader)return;
665 AliGenPythiaEventHeader *pythiaGenHeader = dynamic_cast<AliGenPythiaEventHeader*>(genHeader);
666 if (pythiaGenHeader) {
667 mcHeader->SetEventType(pythiaGenHeader->ProcessType());
0fd37a1f 668 mcHeader->SetPtHard(pythiaGenHeader->GetPtHard());
dce1b636 669 return;
670 }
671
672 AliGenDPMjetEventHeader* dpmJetGenHeader = dynamic_cast<AliGenDPMjetEventHeader*>(genHeader);
673
674 if (dpmJetGenHeader){
675 mcHeader->SetEventType(dpmJetGenHeader->ProcessType());
676 return;
677 }
678
679 AliGenHijingEventHeader* hijingGenHeader = dynamic_cast<AliGenHijingEventHeader*>(genHeader);
680 if(hijingGenHeader){
681 mcHeader->SetImpactParameter(hijingGenHeader->ImpactParameter());
682 return;
683 }
684
685 AliWarning(Form("MC Eventheader not known: %s",genHeader->GetName()));
686
687}
9066c676 688
689ClassImp(AliAODExtension)
690
691//-------------------------------------------------------------------------
692// Support class for AOD extensions. This is created by the user analysis
693// that requires a separate file for some AOD branches. The name of the
694// AliAODExtension object is the file name where the AOD branches will be
695// stored.
696//-------------------------------------------------------------------------
697
26ba01d4 698//______________________________________________________________________________
699AliAODExtension::AliAODExtension() : TNamed(),
700fAODEvent(0), fTreeE(0), fFileE(0), fNtotal(0), fNpassed(0),
701fSelected(kFALSE), fRepFiMap(0x0), fRepFiList(0x0), fEnableReferences(kTRUE), fObjectList(0x0)
702{
703 // default ctor
704}
705
582cfeb5 706//______________________________________________________________________________
707AliAODExtension::AliAODExtension(const char* name, const char* title, Bool_t isfilter)
708 :TNamed(name,title),
709 fAODEvent(0),
710 fTreeE(0),
711 fFileE(0),
712 fNtotal(0),
713 fNpassed(0),
26ba01d4 714 fSelected(kFALSE),
715fRepFiMap(0x0),
716fRepFiList(0x0),
717fEnableReferences(kTRUE),
718fObjectList(0x0)
582cfeb5 719{
720// Constructor.
48f1c230 721 if (isfilter) {
722 TObject::SetBit(kFilteredAOD);
723 printf("####### Added AOD filter %s\n", name);
724 } else printf("####### Added AOD extension %s\n", name);
582cfeb5 725}
726
9066c676 727//______________________________________________________________________________
728AliAODExtension::~AliAODExtension()
729{
730// Destructor.
9066c676 731 if(fFileE){
732 // is already handled in TerminateIO
733 fFileE->Close();
734 delete fFileE;
48f1c230 735 fTreeE = 0;
736 fAODEvent = 0;
9066c676 737 }
48f1c230 738 if (fTreeE) delete fTreeE;
26ba01d4 739 fRepFiMap->DeleteAll();
740 delete fRepFiMap; // the map is owner
741 delete fRepFiList; // the list is not
742 delete fObjectList; // not owner
9066c676 743}
744
745//______________________________________________________________________________
746void AliAODExtension::AddBranch(const char* cname, void* addobj)
747{
748 // Add a new branch to the aod
ee830d15 749// if (IsFilteredAOD()) {
750// Error("AddBranch", "Not allowed to add branched to filtered AOD's.");
751// return;
752// }
26ba01d4 753 AliCodeTimerAuto(GetName(),0);
754
d29168d6 755 if (!fAODEvent) {
756 char type[20];
03fdac6e 757 gROOT->ProcessLine(Form("TString s_tmp; AliAnalysisManager::GetAnalysisManager()->GetAnalysisTypeString(s_tmp); sprintf((char*)%p, \"%%s\", s_tmp.Data());", type));
d29168d6 758 Init(type);
759 }
9066c676 760 TDirectory *owd = gDirectory;
761 if (fFileE) {
762 fFileE->cd();
763 }
764 char** apointer = (char**) addobj;
765 TObject* obj = (TObject*) *apointer;
766
767 fAODEvent->AddObject(obj);
768
769 const Int_t kSplitlevel = 99; // default value in TTree::Branch()
770 const Int_t kBufsize = 32000; // default value in TTree::Branch()
771
772 if (!fTreeE->FindBranch(obj->GetName())) {
773 // Do the same as if we book via
774 // TTree::Branch(TCollection*)
9066c676 775 fTreeE->Bronch(obj->GetName(), cname, fAODEvent->GetList()->GetObjectRef(obj),
776 kBufsize, kSplitlevel - 1);
9066c676 777 }
778 owd->cd();
779}
780
582cfeb5 781//______________________________________________________________________________
782Bool_t AliAODExtension::FinishEvent()
783{
784// Fill current event.
785 fNtotal++;
786 if (!IsFilteredAOD()) {
787 fAODEvent->MakeEntriesReferencable();
788 fTreeE->Fill();
789 return kTRUE;
790 }
791 // Filtered AOD. Fill only if event is selected.
792 if (!fSelected) return kTRUE;
26ba01d4 793
794 TIter next(fRepFiList);
795
796 AliAODBranchReplicator* repfi;
797
798 while ( ( repfi = static_cast<AliAODBranchReplicator*>(next()) ) )
799 {
800 repfi->ReplicateAndFilter(*fAODEvent);
801 }
582cfeb5 802 fNpassed++;
803 fTreeE->Fill();
804 fSelected = kFALSE; // so that next event will not be selected unless demanded
805 return kTRUE;
806}
807
9066c676 808//______________________________________________________________________________
160959a9 809Bool_t AliAODExtension::Init(Option_t *option)
9066c676 810{
811// Initialize IO.
26ba01d4 812 AliCodeTimerAuto(GetName(),0);
813
814 if(!fAODEvent)
815 {
816 fAODEvent = new AliAODEvent();
817 }
818
9066c676 819 TDirectory *owd = gDirectory;
160959a9 820 TString opt(option);
821 opt.ToLower();
822 if (opt.Contains("proof")) {
823 // proof
824 // Merging via files. Need to access analysis manager via interpreter.
039e671e 825 gROOT->ProcessLine(Form("AliAnalysisDataContainer *c_common_out = AliAnalysisManager::GetAnalysisManager()->GetCommonOutputContainer();"));
826 gROOT->ProcessLine(Form("AliAnalysisManager::GetAnalysisManager()->OpenProofFile(c_common_out, \"RECREATE\", \"%s\");", fName.Data()));
160959a9 827 fFileE = gFile;
828 } else {
829 fFileE = new TFile(GetName(), "RECREATE");
830 }
9066c676 831 fTreeE = new TTree("aodTree", "AliAOD tree");
26ba01d4 832
833 delete fObjectList;
834 fObjectList = new TList;
835 fObjectList->SetOwner(kFALSE); // be explicit we're not the owner...
836 TIter next(fAODEvent->GetList());
837 TObject* o;
838
839 while ( ( o = next() ) )
840 {
841 if ( fRepFiMap )
842 {
843 TObject* specified = fRepFiMap->FindObject(o->GetName());
844 if (specified)
845 {
846 AliAODBranchReplicator* repfi = dynamic_cast<AliAODBranchReplicator*>(fRepFiMap->GetValue(o->GetName()));
847 if ( repfi )
848 {
849 TList* replicatedList = repfi->GetList();
850 if (replicatedList)
851 {
852 TIter nextRep(replicatedList);
853 TObject* objRep;
854 while ( ( objRep = nextRep() ) )
855 {
856 if (!fObjectList->FindObject(objRep))
857 {
858 fObjectList->Add(objRep);
859 }
860 }
861 }
862 else
863 {
864 AliError(Form("replicatedList from %s is null !",repfi->GetName()));
865 }
866 }
867 }
868 else
869 {
870 fObjectList->Add(o);
871 }
872 }
873 }
874
875 next.Reset();
876
877 while ( ( o = next() ) )
878 {
879 TObject* out = fObjectList->FindObject(o->GetName());
880 AliInfo(Form("OBJECT IN %20s %p -> OUT %p %s",o->GetName(),o,out,((out!=o && out) ? "REPLICATED":"-")));
881 }
882
883 fTreeE->Branch(fObjectList);
884
885 if (fEnableReferences) fTreeE->BranchRef();
886
9066c676 887 owd->cd();
26ba01d4 888
9066c676 889 return kTRUE;
890}
891
26ba01d4 892//______________________________________________________________________________
893void AliAODExtension::Print(Option_t* opt) const
894{
895 // Print info about this extension
896
897 cout << opt << Form("AliAODExtension - %s - %s",GetName(),GetTitle()) << endl;
898 cout << opt << opt << Form("References are %s enabled",fEnableReferences ? "" : "not") << endl;
899
900 TIter next(fRepFiMap);
901 TObjString* s;
902
903 TString skipped;
904
905 while ( ( s = static_cast<TObjString*>(next()) ) )
906 {
907 AliAODBranchReplicator* br = static_cast<AliAODBranchReplicator*>(fRepFiMap->GetValue(s->String().Data()));
908 if ( !br )
909 {
910 skipped += s->String();
911 skipped += ' ';
912 }
913 }
914
915 if ( skipped.Length() )
916 {
917 cout << opt << opt << "Branches that will be skipped altogether : " << skipped.Data() << endl;
918 }
919
920 next.Reset();
921
922 while ( ( s = static_cast<TObjString*>(next()) ) )
923 {
924 AliAODBranchReplicator* br = static_cast<AliAODBranchReplicator*>(fRepFiMap->GetValue(s->String().Data()));
925
926 if (br)
927 {
928 cout << opt << opt << "Branch " << s->String()
929 << " will be filtered by class " << br->ClassName() << endl;
930 }
931 }
932}
933
582cfeb5 934//______________________________________________________________________________
935void AliAODExtension::SetEvent(AliAODEvent *event)
936{
937// Connects to an external event
938 if (!IsFilteredAOD()) {
939 Error("SetEvent", "Not allowed to set external event for filtered AOD's");
940 return;
941 }
48f1c230 942 // Use the copy constructor or assignment operator to synchronize with external event.
943// AliAODEvent &other = *event;
944// if (!fAODEvent) fAODEvent = new AliAODEvent(other);
945// else if (fSelected) *fAODEvent = other;
582cfeb5 946 fAODEvent = event;
947}
948
9066c676 949//______________________________________________________________________________
950Bool_t AliAODExtension::TerminateIO()
951{
952 // Terminate IO
48f1c230 953 if (TObject::TestBit(kFilteredAOD))
954 printf("AOD Filter %s: events processed: %d passed: %d\n", GetName(), fNtotal, fNpassed);
955 else
956 printf("AOD extension %s: events processed: %d\n", GetName(), fNtotal);
9066c676 957 if (fFileE) {
958 fFileE->Write();
959 fFileE->Close();
960 delete fFileE;
961 fFileE = 0;
48f1c230 962 fTreeE = 0;
963 fAODEvent = 0;
9066c676 964 }
965 return kTRUE;
966}
26ba01d4 967
968//______________________________________________________________________________
969void AliAODExtension::FilterBranch(const char* branchName, AliAODBranchReplicator* repfi)
970{
971 // Specify a filter/replicator for a given branch
972 //
973 // If repfi=0x0, this will disable the branch (in the output) completely.
974 //
975 // repfi is adopted by this class, i.e. user should not delete it.
976 //
977 // WARNING : branch name must be exact.
978 //
979 // See also the documentation for AliAODBranchReplicator class.
980 //
981
982 if (!fRepFiMap)
983 {
984 fRepFiMap = new TMap;
985 fRepFiMap->SetOwnerKeyValue(kTRUE,kTRUE);
986 fRepFiList = new TList;
987 fRepFiList->SetOwner(kFALSE);
988 }
989
990 fRepFiMap->Add(new TObjString(branchName),repfi);
991
992 if (repfi && !fRepFiList->FindObject(repfi))
993 {
994 // insure we get unique and non-null replicators in this list
995 fRepFiList->Add(repfi);
996 }
997}