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