]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - STEER/AliRunDigitizer.cxx
Cleaning the task in the destructor if it was posted
[u/mrichter/AliRoot.git] / STEER / AliRunDigitizer.cxx
... / ...
CommitLineData
1/**************************************************************************
2* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3* *
4* Author: The ALICE Off-line Project. *
5* Contributors are mentioned in the code where appropriate. *
6* *
7* Permission to use, copy, modify and distribute this software and its *
8* documentation strictly for non-commercial purposes is hereby granted *
9* without fee, provided that the above copyright notice appears in all *
10* copies and that both the copyright notice and this permission notice *
11* appear in the supporting documentation. The authors make no claims *
12* about the suitability of this software for any purpose. It is *
13* provided "as is" without express or implied warranty. *
14**************************************************************************/
15
16/* $Id$ */
17
18//_______________________________________________________________________
19//
20// AliRunDigitizer.cxx
21//
22// Manager object for merging/digitization
23//
24// Instance of this class manages the digitization and/or merging of
25// Sdigits into Digits.
26//
27// Only one instance of this class is created in the macro:
28// AliRunDigitizer * manager =
29// new AliRunDigitizer(nInputStreams,SPERB);
30// where nInputStreams is number of input streams and SPERB is
31// signals per background variable, which determines how combinations
32// of signal and background events are generated.
33// Then instances of specific detector digitizers are created:
34// AliMUONDigitizer *dMUON = new AliMUONDigitizer(manager)
35// and the I/O configured (you have to specify input files
36// and an output file). The manager connects appropriate trees from
37// the input files according a combination returned by AliMergeCombi
38// class. It creates TreeD in the output and runs once per
39// event Digitize method of all existing AliDetDigitizers
40// (without any option). AliDetDigitizers ask manager
41// for a TTree with input (manager->GetInputTreeS(Int_t i),
42// merge all inputs, digitize it, and save it in the TreeD
43// obtained by manager->GetTreeD(). Output events are stored with
44// numbers from 0, this default can be changed by
45// manager->SetFirstOutputEventNr(Int_t) method. The particle numbers
46// in the output are shifted by MASK, which is taken from manager.
47//
48// The default output is to the signal file (stream 0). This can be
49// changed with the SetOutputFile(TString fn) method.
50//
51// Single input file is permitted. Maximum kMaxStreamsToMerge can be merged.
52// Input from the memory (on-the-fly merging) is not yet
53// supported, as well as access to the input data by invoking methods
54// on the output data.
55//
56// Access to the some data is via gAlice for now (supposing the
57// same geometry in all input files), gAlice is taken from the first
58// input file on the first stream.
59//
60// Example with MUON digitizer, no merging, just digitization
61//
62// AliRunDigitizer * manager = new AliRunDigitizer(1,1);
63// manager->SetInputStream(0,"galice.root");
64// AliMUONDigitizer *dMUON = new AliMUONDigitizer(manager);
65// manager->Exec("");
66//
67// Example with MUON digitizer, merge all events from
68// galice.root (signal) file with events from bgr.root
69// (background) file. Number of merged events is
70// min(number of events in galice.root, number of events in bgr.root)
71//
72// AliRunDigitizer * manager = new AliRunDigitizer(2,1);
73// manager->SetInputStream(0,"galice.root");
74// manager->SetInputStream(1,"bgr.root");
75// AliMUONDigitizer *dMUON = new AliMUONDigitizer(manager);
76// manager->Exec("");
77//
78// Example with MUON digitizer, save digits in a new file digits.root,
79// process only 1 event
80//
81// AliRunDigitizer * manager = new AliRunDigitizer(2,1);
82// manager->SetInputStream(0,"galice.root");
83// manager->SetInputStream(1,"bgr.root");
84// manager->SetOutputFile("digits.root");
85// AliMUONDigitizer *dMUON = new AliMUONDigitizer(manager);
86// manager->SetNrOfEventsToWrite(1);
87// manager->Exec("");
88//
89//_______________________________________________________________________
90
91// system includes
92
93#include <Riostream.h>
94
95// ROOT includes
96
97#include "TFile.h"
98#include "TList.h"
99#include "TTree.h"
100
101// AliROOT includes
102
103#include "AliDigitizer.h"
104#include "AliMergeCombi.h"
105#include "AliRunLoader.h"
106#include "AliLoader.h"
107#include "AliRun.h"
108#include "AliRunDigitizer.h"
109#include "AliStream.h"
110#include "AliHeader.h"
111
112ClassImp(AliRunDigitizer)
113
114const TString AliRunDigitizer::fgkDefOutFolderName("Output");
115const TString AliRunDigitizer::fgkBaseInFolderName("Input");
116
117
118//_______________________________________________________________________
119AliRunDigitizer::AliRunDigitizer():
120 fkMASKSTEP(0),
121 fOutputFileName(0),
122 fOutputDirName(0),
123 fEvent(0),
124 fNrOfEventsToWrite(0),
125 fNrOfEventsWritten(0),
126 fCopyTreesFromInput(0),
127 fNinputs(0),
128 fNinputsGiven(0),
129 fInputStreams(0x0),
130 fOutRunLoader(0x0),
131 fOutputInitialized(kFALSE),
132 fCombi(0),
133 fCombination(0),
134 fCombinationFileName(0),
135 fDebug(0)
136{
137// root requires default ctor, where no new objects can be created
138// do not use this ctor, it is supplied only for root needs
139
140// fOutputStream = 0x0;
141}
142
143//_______________________________________________________________________
144AliRunDigitizer::AliRunDigitizer(Int_t nInputStreams, Int_t sperb):
145 TTask("AliRunDigitizer","The manager for Merging"),
146 fkMASKSTEP(10000000),
147 fOutputFileName(""),
148 fOutputDirName("."),
149 fEvent(0),
150 fNrOfEventsToWrite(-1),
151 fNrOfEventsWritten(0),
152 fCopyTreesFromInput(-1),
153 fNinputs(nInputStreams),
154 fNinputsGiven(0),
155 fInputStreams(new TClonesArray("AliStream",nInputStreams)),
156 fOutRunLoader(0x0),
157 fOutputInitialized(kFALSE),
158 fCombi(new AliMergeCombi(nInputStreams,sperb)),
159 fCombination(kMaxStreamsToMerge),
160 fCombinationFileName(0),
161 fDebug(0)
162
163{
164// ctor which should be used to create a manager for merging/digitization
165 if (nInputStreams == 0)
166 {//kidding
167 Fatal("AliRunDigitizer","Specify nr of input streams");
168 return;
169 }
170 Int_t i;
171
172 fkMASK[0] = 0;
173
174 for (i=1;i<kMaxStreamsToMerge;i++)
175 {
176 fkMASK[i] = fkMASK[i-1] + fkMASKSTEP;
177 }
178
179 TClonesArray &lInputStreams = *fInputStreams;
180
181 for (i=0;i<nInputStreams;i++) {
182 new(lInputStreams[i]) AliStream(fgkBaseInFolderName+(Long_t)i,"UPDATE");
183 }
184}
185//_______________________________________________________________________
186
187AliRunDigitizer::AliRunDigitizer(const AliRunDigitizer& dig):
188 TTask(dig),
189 fkMASKSTEP(0),
190 fOutputFileName(0),
191 fOutputDirName(0),
192 fEvent(0),
193 fNrOfEventsToWrite(0),
194 fNrOfEventsWritten(0),
195 fCopyTreesFromInput(0),
196 fNinputs(0),
197 fNinputsGiven(0),
198 fInputStreams(0x0),
199 fOutRunLoader(0x0),
200 fOutputInitialized(kFALSE),
201 fCombi(0),
202 fCombination(0),
203 fCombinationFileName(0),
204 fDebug(0)
205{
206 //
207 // Copy ctor
208 //
209 dig.Copy(*this);
210}
211//_______________________________________________________________________
212
213void AliRunDigitizer::Copy(TObject&) const
214{
215 Fatal("Copy","Not installed\n");
216}
217
218//_______________________________________________________________________
219
220AliRunDigitizer::~AliRunDigitizer() {
221// dtor
222 if (GetListOfTasks())
223 GetListOfTasks()->Clear("nodelete");
224 delete fInputStreams;
225 delete fCombi;
226 delete fOutRunLoader;
227}
228//_______________________________________________________________________
229void AliRunDigitizer::AddDigitizer(AliDigitizer *digitizer)
230{
231// add digitizer to the list of active digitizers
232 this->Add(digitizer);
233}
234//_______________________________________________________________________
235void AliRunDigitizer::SetInputStream(Int_t i, const char *inputFile, TString foldername)
236{
237//
238// Sets the name of the input file
239//
240 if (i > fInputStreams->GetLast()) {
241 Error("SetInputStream","Input stream number too high");
242 return;
243 }
244 AliStream * stream = static_cast<AliStream*>(fInputStreams->At(i)) ;
245 if ( !foldername.IsNull() ) {
246 if ( i > 0 )
247 foldername += i ; // foldername should stay unchanged for the default output
248 stream->SetFolderName(foldername) ;
249 }
250 stream->AddFile(inputFile);
251}
252
253//_______________________________________________________________________
254void AliRunDigitizer::Digitize(Option_t* option)
255{
256// get a new combination of inputs, loads events to folders
257
258// take gAlice from the first input file. It is needed to access
259// geometry data
260// If gAlice is already in memory, use it
261 SetDebug(10);
262
263 if (!static_cast<AliStream*>(fInputStreams->At(0))->ImportgAlice())
264 {
265 Error("Digitize","Error occured while getting gAlice from Input 0");
266 return;
267 }
268
269 if (!InitGlobal()) //calls Init() for all (sub)digitizers
270 {
271 Error("Digitize","InitGlobal returned error");
272 return;
273 }
274
275 Int_t eventsCreated = 0;
276// loop until there is anything on the input in case fNrOfEventsToWrite < 0
277 while ((eventsCreated++ < fNrOfEventsToWrite) || (fNrOfEventsToWrite < 0))
278 {
279 if (!ConnectInputTrees()) break;
280 InitEvent();//this must be after call of Connect Input tress.
281 if (fOutRunLoader)
282 {
283 fOutRunLoader->SetEventNumber(eventsCreated-1);
284 }
285 static_cast<AliStream*>(fInputStreams->At(0))->ImportgAlice(); // use gAlice of the first input stream
286 ExecuteTasks(option);// loop over all registered digitizers and let them do the work
287 FinishEvent();
288 CleanTasks();
289 }
290 FinishGlobal();
291}
292
293//_______________________________________________________________________
294Bool_t AliRunDigitizer::ConnectInputTrees()
295{
296//loads events
297 Int_t eventNr[kMaxStreamsToMerge], delta[kMaxStreamsToMerge];
298 fCombi->Combination(eventNr, delta);
299 for (Int_t i=0;i<fNinputs;i++)
300 {
301 if (delta[i] == 1)
302 {
303 AliStream *iStream = static_cast<AliStream*>(fInputStreams->At(i));//gets the "i" defined in combination
304 if (!iStream->NextEventInStream()) return kFALSE; //sets serial number
305 }
306 else if (delta[i] != 0)
307 {
308 Error("ConnectInputTrees","Only delta 0 or 1 is implemented");
309 return kFALSE;
310 }
311 }
312
313 return kTRUE;
314}
315
316//_______________________________________________________________________
317Bool_t AliRunDigitizer::InitGlobal()
318{
319// called once before Digitize() is called, initialize digitizers and output
320 fOutputInitialized = kFALSE;
321 TList* subTasks = this->GetListOfTasks();
322 if (subTasks) {
323 TIter next(subTasks);
324 while (AliDigitizer * dig = (AliDigitizer *) next())
325 dig->Init();
326 }
327 return kTRUE;
328}
329
330//_______________________________________________________________________
331
332void AliRunDigitizer::SetOutputFile(TString fn)
333{
334// the output will be to separate file, not to the signal file
335 //here should be protection to avoid setting the same file as any input
336 Info("SetOutputFile","Setting Output File Name %s ",fn.Data());
337 fOutputFileName = fn;
338// InitOutputGlobal();
339}
340
341//_______________________________________________________________________
342Bool_t AliRunDigitizer::InitOutputGlobal()
343{
344// Creates the output file, called by InitEvent()
345//Needs to be called after all inputs are opened
346 if (fOutputInitialized) return kTRUE;
347
348 if ( !fOutputFileName.IsNull())
349 {
350 fOutRunLoader = AliRunLoader::Open(fOutputFileName,fgkDefOutFolderName,"recreate");
351
352 if (fOutRunLoader == 0x0)
353 {
354 Error("InitOutputGlobal","Can not open ooutput");
355 return kFALSE;
356 }
357 Info("InitOutputGlobal", " 1 %s = ", GetInputFolderName(0).Data()) ;
358 AliRunLoader* inrl = AliRunLoader::GetRunLoader(GetInputFolderName(0));
359 if (inrl == 0x0)
360 {
361 Error("InitOutputGlobal","Can not get Run Loader Input 0. Maybe yet not initialized?");
362 return kFALSE;
363 }
364 Info("InitOutputGlobal", " 2 %#x = ", inrl) ;
365
366 //Copy all detector loaders from input 0 to output
367 const TObjArray* inloaders = inrl->GetArrayOfLoaders();
368 TIter next(inloaders);
369 AliLoader *loader;
370 while((loader = (AliLoader*)next()))
371 {
372 AliLoader* cloneloader = (AliLoader*)loader->Clone();
373 cloneloader->Register(fOutRunLoader->GetEventFolder());//creates folders for this loader in Output Folder Structure
374 GetOutRunLoader()->AddLoader(cloneloader);//adds a loader for output
375 }
376
377 fOutRunLoader->MakeTree("E");
378
379 if (GetDebug()>2) Info("InitOutputGlobal","file %s was opened.",fOutputFileName.Data());
380 }
381 fOutputInitialized = kTRUE;
382 return kTRUE;
383}
384//_______________________________________________________________________
385
386void AliRunDigitizer::InitEvent()
387{
388//redirects output properly
389 if (GetDebug()>2)
390 {
391 Info("InitEvent","fEvent = %d",fEvent);
392 Info("InitEvent","fOutputFileName \"%s\"",fOutputFileName.Data());
393 }
394 if (fOutputInitialized == kFALSE) InitOutputGlobal();
395
396// if fOutputFileName was not given, write output to signal directory
397}
398//_______________________________________________________________________
399
400void AliRunDigitizer::FinishEvent()
401{
402// called at the end of loop over digitizers
403
404
405 if (GetOutRunLoader() == 0x0)
406 {
407 Error("FinishEvent","fOutRunLoader is null");
408 return;
409 }
410
411 fEvent++;
412 fNrOfEventsWritten++;
413
414 if (fOutRunLoader)
415 {
416 AliRunLoader* inrl = AliRunLoader::GetRunLoader(GetInputFolderName(0));
417 AliHeader* outheader = fOutRunLoader->GetHeader();
418 AliHeader* inheader = inrl->GetHeader();
419 if (inheader == 0x0)
420 {
421 inrl->LoadHeader();
422 inheader = inrl->GetHeader();
423 if (inheader == 0x0) Fatal("FinishEvent","Can not get header from input 0");
424 }
425
426 outheader->SetNprimary(inheader->GetNprimary());
427 outheader->SetNtrack(inheader->GetNtrack());
428 outheader->SetEvent(inheader->GetEvent());
429 outheader->SetEventNrInRun(inheader->GetEventNrInRun());
430 outheader->SetNvertex(inheader->GetNvertex());
431 fOutRunLoader->TreeE()->Fill();
432 }
433
434 if (fCopyTreesFromInput > -1)
435 {
436 //this is sensless since no information would be coherent in case of merging
437 //
438 cout<<"Copy trees from input: Copy or link files manually"<<endl;
439 return;
440 }
441}
442//_______________________________________________________________________
443
444void AliRunDigitizer::FinishGlobal()
445{
446// called at the end of Exec
447// save unique objects to the output file
448
449 if (GetOutRunLoader() == 0x0)
450 {
451 Error("FinishGlobal","Can not get RunLoader from Output Stream folder");
452 return;
453 }
454 TFile* file = TFile::Open(fOutputDirName + "/digitizer.root", "recreate");
455 this->Write();
456 file->Close();
457 delete file;
458 if (fOutRunLoader)
459 {
460 fOutRunLoader->WriteHeader("OVERWRITE");
461 fOutRunLoader->WriteRunLoader("OVERWRITE");
462 TFolder* outfolder = fOutRunLoader->GetEventFolder();
463 if (outfolder == 0x0)
464 {
465 Error("FinishEvent","Can not get Event Folder");
466 return;
467 }
468
469 AliRunLoader* inRN = AliRunLoader::GetRunLoader(GetInputFolderName(0));
470 outfolder->Add(inRN->GetAliRun());
471 fOutRunLoader->WriteAliRun("OVERWRITE");
472 }
473
474 if (fCopyTreesFromInput > -1)
475 {
476 //copy files manually
477 }
478}
479//_______________________________________________________________________
480
481Int_t AliRunDigitizer::GetNParticles(Int_t event) const
482{
483// return number of particles in all input files for a given
484// event (as numbered in the output file)
485// return -1 if some file cannot be accessed
486
487 Int_t sum = 0;
488 Int_t sumI;
489 for (Int_t i = 0; i < fNinputs; i++) {
490 sumI = GetNParticles(GetInputEventNumber(event,i), i);
491 if (sumI < 0) return -1;
492 sum += sumI;
493 }
494 return sum;
495}
496//_______________________________________________________________________
497
498Int_t AliRunDigitizer::GetNParticles(Int_t /*event*/, Int_t /*input*/) const
499{
500// return number of particles in input file input for a given
501// event (as numbered in this input file)
502// return -1 if some error
503
504// Must be revised in the version with AliStream
505
506 return -1;
507
508}
509
510//_______________________________________________________________________
511Int_t* AliRunDigitizer::GetInputEventNumbers(Int_t event) const
512{
513// return pointer to an int array with input event numbers which were
514// merged in the output event event
515
516// simplified for now, implement later
517 Int_t * a = new Int_t[kMaxStreamsToMerge];
518 for (Int_t i = 0; i < fNinputs; i++) {
519 a[i] = event;
520 }
521 return a;
522}
523//_______________________________________________________________________
524Int_t AliRunDigitizer::GetInputEventNumber(Int_t event, Int_t /*input*/) const
525{
526// return an event number of an eventInput from input file input
527// which was merged to create output event event
528
529// simplified for now, implement later
530 return event;
531}
532//_______________________________________________________________________
533TParticle* AliRunDigitizer::GetParticle(Int_t i, Int_t event) const
534{
535// return pointer to particle with index i (index with mask)
536
537// decode the MASK
538 Int_t input = i/fkMASKSTEP;
539 return GetParticle(i,input,GetInputEventNumber(event,input));
540}
541
542//_______________________________________________________________________
543TParticle* AliRunDigitizer::GetParticle(Int_t /*i*/, Int_t /*input*/, Int_t /*event*/) const
544{
545// return pointer to particle with index i in the input file input
546// (index without mask)
547// event is the event number in the file input
548// return 0 i fit does not exist
549
550// Must be revised in the version with AliStream
551
552 return 0;
553}
554
555//_______________________________________________________________________
556void AliRunDigitizer::ExecuteTask(Option_t* option)
557{
558// overwrite ExecuteTask to do Digitize only
559
560 if (!IsActive()) return;
561 Digitize(option);
562 fHasExecuted = kTRUE;
563 return;
564}
565
566//_______________________________________________________________________
567const TString& AliRunDigitizer::GetInputFolderName(Int_t i) const
568{
569 AliStream* stream = dynamic_cast<AliStream*>(fInputStreams->At(i));
570 if (stream == 0x0)
571 {
572 Fatal("GetInputFolderName","Can not get the input stream. Index = %d. Exiting",i);
573 }
574 return stream->GetFolderName();
575}
576//_______________________________________________________________________
577
578const char* AliRunDigitizer::GetOutputFolderName()
579{
580 return GetOutRunLoader()->GetEventFolder()->GetName();
581}
582//_______________________________________________________________________
583
584AliRunLoader* AliRunDigitizer::GetOutRunLoader()
585{
586 if (fOutRunLoader) return fOutRunLoader;
587
588 if ( fOutputFileName.IsNull() )
589 {//guard that sombody calls it without settting file name
590 cout<<"Output file name is empty. Using Input 0 for output\n";
591 return AliRunLoader::GetRunLoader(GetInputFolderName(0));
592 }
593// InitOutputGlobal();
594 return fOutRunLoader;
595}
596//_______________________________________________________________________
597
598TString AliRunDigitizer::GetInputFileName(Int_t input, Int_t order) const
599{
600// returns file name of the order-th file in the input stream input
601// returns empty string if such file does not exist
602// first input stream is 0
603// first file in the input stream is 0
604 TString fileName("");
605 if (input >= fNinputs) return fileName;
606 AliStream * stream = static_cast<AliStream*>(fInputStreams->At(input));
607 if (order > stream->GetNInputFiles()) return fileName;
608 fileName = stream->GetFileName(order);
609 return fileName;
610}