]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - STEER/AliRunDigitizer.cxx
Quick fix for bug 71658
[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 MAXSTREAMSTOMERGE 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// ROOT includes
94
95#include <Riostream.h>
96class TList;
97
98// AliROOT includes
99
100#include "AliLog.h"
101#include "AliDigitizer.h"
102#include "AliHeader.h"
103#include "AliLoader.h"
104#include "AliMergeCombi.h"
105#include "AliRun.h"
106#include "AliRunDigitizer.h"
107#include "AliRunLoader.h"
108
109ClassImp(AliRunDigitizer)
110
111const TString AliRunDigitizer::fgkDefOutFolderName("Output");
112const TString AliRunDigitizer::fgkBaseInFolderName("Input");
113
114
115//_______________________________________________________________________
116AliRunDigitizer::AliRunDigitizer(): TTask("AliRunDigitizer","The manager for Merging"),
117 fkMASKSTEP(0),
118 fOutputFileName(0),
119 fOutputDirName(0),
120 fEvent(0),
121 fNrOfEventsToWrite(0),
122 fNrOfEventsWritten(0),
123 fCopyTreesFromInput(0),
124 fNinputs(0),
125 fNinputsGiven(0),
126 fInputStreams(0x0),
127 fOutRunLoader(0x0),
128 fOutputInitialized(kFALSE),
129 fCombi(0),
130 fCombination(0),
131 fCombinationFileName(0)
132{
133 //
134 // root requires default ctor, where no new objects can be created
135 // do not use this ctor, it is supplied only for root needs
136}
137
138//_______________________________________________________________________
139AliRunDigitizer::AliRunDigitizer(Int_t nInputStreams, Int_t sperb):
140 TTask("AliRunDigitizer","The manager for Merging"),
141 fkMASKSTEP(10000000),
142 fOutputFileName(""),
143 fOutputDirName("."),
144 fEvent(0),
145 fNrOfEventsToWrite(-1),
146 fNrOfEventsWritten(0),
147 fCopyTreesFromInput(-1),
148 fNinputs(nInputStreams),
149 fNinputsGiven(0),
150 fInputStreams(new TClonesArray("AliStream",nInputStreams)),
151 fOutRunLoader(0x0),
152 fOutputInitialized(kFALSE),
153 fCombi(new AliMergeCombi(nInputStreams,sperb)),
154 fCombination(MAXSTREAMSTOMERGE),
155 fCombinationFileName(0)
156
157{
158 //
159 // ctor which should be used to create
160 // a manager for merging/digitization
161 //
162 if (nInputStreams == 0)
163 {//kidding
164 AliFatal("Specify nr of input streams");
165 return;
166 }
167 Int_t i;
168
169 fkMASK[0] = 0;
170
171 for (i=1;i<MAXSTREAMSTOMERGE;i++)
172 {
173 fkMASK[i] = fkMASK[i-1] + fkMASKSTEP;
174 }
175
176 TClonesArray &lInputStreams = *fInputStreams;
177
178 new(lInputStreams[0]) AliStream(fgkBaseInFolderName+(Long_t)0,"UPDATE");
179 for (i=1;i<nInputStreams;i++) {
180 new(lInputStreams[i]) AliStream(fgkBaseInFolderName+(Long_t)i,"READ");
181 }
182}
183//_______________________________________________________________________
184
185AliRunDigitizer::AliRunDigitizer(const AliRunDigitizer& dig):
186 TTask(dig),
187 fkMASKSTEP(0),
188 fOutputFileName(0),
189 fOutputDirName(0),
190 fEvent(0),
191 fNrOfEventsToWrite(0),
192 fNrOfEventsWritten(0),
193 fCopyTreesFromInput(0),
194 fNinputs(0),
195 fNinputsGiven(0),
196 fInputStreams(0x0),
197 fOutRunLoader(0x0),
198 fOutputInitialized(kFALSE),
199 fCombi(0),
200 fCombination(0),
201 fCombinationFileName(0)
202{
203 //
204 // Copy ctor
205 //
206 dig.Copy(*this);
207}
208//_______________________________________________________________________
209
210void AliRunDigitizer::Copy(TObject&) const
211{
212 //
213 // Non implemented copy function
214 //
215 AliFatal("Not installed");
216}
217
218//_______________________________________________________________________
219
220AliRunDigitizer::~AliRunDigitizer()
221{
222 //
223 // dtor
224 //
225 delete fInputStreams;
226 delete fCombi;
227 delete fOutRunLoader;
228}
229//_______________________________________________________________________
230void AliRunDigitizer::AddDigitizer(AliDigitizer *digitizer)
231{
232 //
233 // add digitizer to the list of active digitizers
234 //
235 this->Add(digitizer);
236}
237//_______________________________________________________________________
238void AliRunDigitizer::SetInputStream(Int_t i, const char *inputFile, TString foldername)
239{
240//
241// Sets the name of the input file
242//
243 if (i > fInputStreams->GetLast()) {
244 AliError("Input stream number too high");
245 return;
246 }
247 AliStream * stream = static_cast<AliStream*>(fInputStreams->At(i)) ;
248 if ( !foldername.IsNull() ) {
249 if ( i > 0 )
250 foldername += i ; // foldername should stay unchanged for the default output
251 stream->SetFolderName(foldername) ;
252 }
253 stream->AddFile(inputFile);
254}
255
256//_______________________________________________________________________
257void AliRunDigitizer::Digitize(Option_t* option)
258{
259// get a new combination of inputs, loads events to folders
260
261// take gAlice from the first input file. It is needed to access
262// geometry data
263// If gAlice is already in memory, use it
264
265 if (!static_cast<AliStream*>(fInputStreams->At(0))->ImportgAlice())
266 {
267 AliError("Error occured while getting gAlice from Input 0");
268 return;
269 }
270
271 if (!InitGlobal()) //calls Init() for all (sub)digitizers
272 {
273 AliError("InitGlobal returned error");
274 return;
275 }
276
277 Int_t eventsCreated = 0;
278// loop until there is anything on the input in case fNrOfEventsToWrite < 0
279 while ((eventsCreated++ < fNrOfEventsToWrite) || (fNrOfEventsToWrite < 0))
280 {
281 if (!ConnectInputTrees()) break;
282 InitEvent();//this must be after call of Connect Input tress.
283 if (fOutRunLoader)
284 {
285 fOutRunLoader->SetEventNumber(eventsCreated-1);
286 }
287 static_cast<AliStream*>(fInputStreams->At(0))->ImportgAlice(); // use gAlice of the first input stream
288 ExecuteTasks(option);// loop over all registered digitizers and let them do the work
289 FinishEvent();
290 CleanTasks();
291 }
292 FinishGlobal();
293}
294
295//_______________________________________________________________________
296Bool_t AliRunDigitizer::ConnectInputTrees()
297{
298 //
299 // loads events
300 //
301 Int_t eventNr[MAXSTREAMSTOMERGE], delta[MAXSTREAMSTOMERGE];
302 fCombi->Combination(eventNr, delta);
303 for (Int_t i=0;i<fNinputs;i++)
304 {
305 if (delta[i] == 1)
306 {
307 AliStream *iStream = static_cast<AliStream*>(fInputStreams->At(i));//gets the "i" defined in combination
308 if (!iStream->NextEventInStream()) return kFALSE; //sets serial number
309 }
310 else if (delta[i] != 0)
311 {
312 AliError("Only delta 0 or 1 is implemented");
313 return kFALSE;
314 }
315 }
316
317 return kTRUE;
318}
319
320//_______________________________________________________________________
321Bool_t AliRunDigitizer::InitGlobal()
322{
323 //
324 // Method called once before Digitize() is called
325 // initialize digitizers and output
326 //
327 fOutputInitialized = kFALSE;
328 TList* subTasks = this->GetListOfTasks();
329 if (subTasks) {
330 TIter next(subTasks);
331 while (AliDigitizer * dig = (AliDigitizer *) next())
332 dig->Init();
333 }
334 return kTRUE;
335}
336
337//_______________________________________________________________________
338
339void AliRunDigitizer::SetOutputFile(TString fn)
340{
341 //
342 // The output will be to separate file,
343 // not to the signal file here should be protection
344 //to avoid setting the same file as any input
345 //
346 AliInfo(Form("Setting Output File Name %s ",fn.Data()));
347 fOutputFileName = fn;
348 // InitOutputGlobal();
349}
350
351//_______________________________________________________________________
352Bool_t AliRunDigitizer::InitOutputGlobal()
353{
354 //
355 // Creates the output file, called by InitEvent()
356 // Needs to be called after all inputs are opened
357 //
358 if (fOutputInitialized) return kTRUE;
359
360 if ( !fOutputFileName.IsNull())
361 {
362 fOutRunLoader = AliRunLoader::Open(fOutputFileName,fgkDefOutFolderName,"recreate");
363
364 if (fOutRunLoader == 0x0)
365 {
366 AliError("Can not open output");
367 return kFALSE;
368 }
369 Info("InitOutputGlobal", " 1 %s = ", GetInputFolderName(0).Data()) ;
370 AliRunLoader* inrl = AliRunLoader::GetRunLoader(GetInputFolderName(0));
371 if (inrl == 0x0)
372 {
373 AliError("Can not get Run Loader Input 0. Maybe yet not initialized?");
374 return kFALSE;
375 }
376 AliDebug(2, Form(" 2 %p = ", inrl)) ;
377
378 //Copy all detector loaders from input 0 to output
379 const TObjArray* inloaders = inrl->GetArrayOfLoaders();
380 TIter next(inloaders);
381 AliLoader *loader;
382 while((loader = (AliLoader*)next()))
383 {
384 AliLoader* cloneloader = (AliLoader*)loader->Clone();
385 cloneloader->Register(fOutRunLoader->GetEventFolder());//creates folders for this loader in Output Folder Structure
386 GetOutRunLoader()->AddLoader(cloneloader);//adds a loader for output
387 }
388
389 fOutRunLoader->MakeTree("E");
390
391 AliDebug(3,Form("file %s was opened.",fOutputFileName.Data()));
392 }
393 fOutputInitialized = kTRUE;
394 return kTRUE;
395}
396//_______________________________________________________________________
397
398void AliRunDigitizer::InitEvent()
399{
400 //
401 // redirects output properly
402 //
403 AliDebug(3,Form("fEvent = %d",fEvent));
404 AliDebug(3,Form("fOutputFileName \"%s\"",fOutputFileName.Data()));
405 if (fOutputInitialized == kFALSE) InitOutputGlobal();
406
407 // if fOutputFileName was not given, write output to signal directory
408}
409//_______________________________________________________________________
410
411void AliRunDigitizer::FinishEvent()
412{
413 //
414 // called at the end of loop over digitizers
415 //
416
417 if (GetOutRunLoader() == 0x0)
418 {
419 AliError("fOutRunLoader is null");
420 return;
421 }
422
423 fEvent++;
424 fNrOfEventsWritten++;
425
426 if (fOutRunLoader)
427 {
428 AliRunLoader* inrl = AliRunLoader::GetRunLoader(GetInputFolderName(0));
429 AliHeader* outheader = fOutRunLoader->GetHeader();
430 AliHeader* inheader = inrl->GetHeader();
431 if (inheader == 0x0)
432 {
433 inrl->LoadHeader();
434 inheader = inrl->GetHeader();
435 if (inheader == 0x0) AliFatal("Can not get header from input 0");
436 }
437
438 outheader->SetNprimary(inheader->GetNprimary());
439 outheader->SetNtrack(inheader->GetNtrack());
440 outheader->SetEvent(inheader->GetEvent());
441 outheader->SetEventNrInRun(inheader->GetEventNrInRun());
442 outheader->SetNvertex(inheader->GetNvertex());
443 fOutRunLoader->TreeE()->Fill();
444 }
445
446 if (fCopyTreesFromInput > -1)
447 {
448 //this is sensless since no information would be coherent in case of merging
449 //
450 AliWarning("Copy trees from input: Copy or link files manually");
451 return;
452 }
453}
454//_______________________________________________________________________
455
456void AliRunDigitizer::FinishGlobal()
457{
458 //
459 // called at the end of Exec
460 // save unique objects to the output file
461 //
462 if (GetOutRunLoader() == 0x0)
463 {
464 AliError("Can not get RunLoader from Output Stream folder");
465 return;
466 }
467 GetOutRunLoader()->CdGAFile();
468 this->Write(NULL, TObject::kOverwrite);
469 if (fOutRunLoader)
470 {
471 fOutRunLoader->WriteHeader("OVERWRITE");
472 fOutRunLoader->WriteRunLoader("OVERWRITE");
473 TFolder* outfolder = fOutRunLoader->GetEventFolder();
474 if (outfolder == 0x0)
475 {
476 AliError("Can not get Event Folder");
477 return;
478 }
479
480 AliRunLoader* inRN = AliRunLoader::GetRunLoader(GetInputFolderName(0));
481 outfolder->Add(inRN->GetAliRun());
482 fOutRunLoader->WriteAliRun("OVERWRITE");
483 }
484
485 if (fCopyTreesFromInput > -1)
486 {
487 //copy files manually
488 }
489}
490//_______________________________________________________________________
491
492Int_t AliRunDigitizer::GetNParticles(Int_t event) const
493{
494// return number of particles in all input files for a given
495// event (as numbered in the output file)
496// return -1 if some file cannot be accessed
497
498 Int_t sum = 0;
499 Int_t sumI;
500 for (Int_t i = 0; i < fNinputs; i++) {
501 sumI = GetNParticles(GetInputEventNumber(event,i), i);
502 if (sumI < 0) return -1;
503 sum += sumI;
504 }
505 return sum;
506}
507//_______________________________________________________________________
508
509Int_t AliRunDigitizer::GetNParticles(Int_t /*event*/, Int_t /*input*/) const
510{
511// return number of particles in input file input for a given
512// event (as numbered in this input file)
513// return -1 if some error
514
515// Must be revised in the version with AliStream
516
517 return -1;
518
519}
520
521//_______________________________________________________________________
522Int_t* AliRunDigitizer::GetInputEventNumbers(Int_t event) const
523{
524// return pointer to an int array with input event numbers which were
525// merged in the output event event
526
527// simplified for now, implement later
528 Int_t * a = new Int_t[MAXSTREAMSTOMERGE];
529 for (Int_t i = 0; i < fNinputs; i++) {
530 a[i] = event;
531 }
532 return a;
533}
534//_______________________________________________________________________
535Int_t AliRunDigitizer::GetInputEventNumber(Int_t event, Int_t /*input*/) const
536{
537// return an event number of an eventInput from input file input
538// which was merged to create output event event
539
540// simplified for now, implement later
541 return event;
542}
543//_______________________________________________________________________
544TParticle* AliRunDigitizer::GetParticle(Int_t i, Int_t event) const
545{
546// return pointer to particle with index i (index with mask)
547
548// decode the MASK
549 Int_t input = i/fkMASKSTEP;
550 return GetParticle(i,input,GetInputEventNumber(event,input));
551}
552
553//_______________________________________________________________________
554TParticle* AliRunDigitizer::GetParticle(Int_t /*i*/, Int_t /*input*/, Int_t /*event*/) const
555{
556// return pointer to particle with index i in the input file input
557// (index without mask)
558// event is the event number in the file input
559// return 0 i fit does not exist
560
561// Must be revised in the version with AliStream
562
563 return 0;
564}
565
566//_______________________________________________________________________
567void AliRunDigitizer::ExecuteTask(Option_t* option)
568{
569 //
570 // overwrite ExecuteTask to do Digitize only
571 //
572 if (!IsActive()) return;
573 Digitize(option);
574 fHasExecuted = kTRUE;
575 return;
576}
577
578//_______________________________________________________________________
579const TString& AliRunDigitizer::GetInputFolderName(Int_t i) const
580{
581 //
582 // Get the input Folder Name
583 //
584 AliStream* stream = dynamic_cast<AliStream*>(fInputStreams->At(i));
585 if (stream == 0x0)
586 AliFatal(Form("Can not get the input stream. Index = %d. Exiting",i));
587 return stream->GetFolderName();
588}
589//_______________________________________________________________________
590
591const char* AliRunDigitizer::GetOutputFolderName()
592{
593 //
594 // Get output folder name
595 //
596 return GetOutRunLoader()->GetEventFolder()->GetName();
597}
598//_______________________________________________________________________
599
600AliRunLoader* AliRunDigitizer::GetOutRunLoader()
601{
602 //
603 // Returns Run Loader
604 //
605 if (fOutRunLoader) return fOutRunLoader;
606
607 if ( fOutputFileName.IsNull() )
608 {//guard that sombody calls it without settting file name
609 AliDebug(1,"Output file name is empty. Using Input 0 for output");
610 return AliRunLoader::GetRunLoader(GetInputFolderName(0));
611 }
612// InitOutputGlobal();
613 return fOutRunLoader;
614}
615//_______________________________________________________________________
616
617TString AliRunDigitizer::GetInputFileName(Int_t input, Int_t order) const
618{
619// returns file name of the order-th file in the input stream input
620// returns empty string if such file does not exist
621// first input stream is 0
622// first file in the input stream is 0
623 TString fileName("");
624 if (input >= fNinputs) return fileName;
625 AliStream * stream = static_cast<AliStream*>(fInputStreams->At(input));
626 if (order > stream->GetNInputFiles()) return fileName;
627 fileName = stream->GetFileName(order);
628 return fileName;
629}