1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 //_______________________________________________________________________
20 // AliRunDigitizer.cxx
22 // Manager object for merging/digitization
24 // Instance of this class manages the digitization and/or merging of
25 // Sdigits into Digits.
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.
48 // The default output is to the signal file (stream 0). This can be
49 // changed with the SetOutputFile(TString fn) method.
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.
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.
60 // Example with MUON digitizer, no merging, just digitization
62 // AliRunDigitizer * manager = new AliRunDigitizer(1,1);
63 // manager->SetInputStream(0,"galice.root");
64 // AliMUONDigitizer *dMUON = new AliMUONDigitizer(manager);
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)
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);
78 // Example with MUON digitizer, save digits in a new file digits.root,
79 // process only 1 event
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);
89 //_______________________________________________________________________
95 #include <Riostream.h>
100 #include "AliDigitizer.h"
101 #include "AliHeader.h"
102 #include "AliLoader.h"
103 #include "AliMergeCombi.h"
105 #include "AliRunDigitizer.h"
106 #include "AliRunLoader.h"
108 ClassImp(AliRunDigitizer)
110 const TString AliRunDigitizer::fgkDefOutFolderName("Output");
111 const TString AliRunDigitizer::fgkBaseInFolderName("Input");
114 //_______________________________________________________________________
115 AliRunDigitizer::AliRunDigitizer(): TTask("AliRunDigitizer","The manager for Merging"),
120 fNrOfEventsToWrite(0),
121 fNrOfEventsWritten(0),
122 fCopyTreesFromInput(0),
127 fOutputInitialized(kFALSE),
130 fCombinationFileName(0),
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
138 //_______________________________________________________________________
139 AliRunDigitizer::AliRunDigitizer(Int_t nInputStreams, Int_t sperb):
140 TTask("AliRunDigitizer","The manager for Merging"),
141 fkMASKSTEP(10000000),
145 fNrOfEventsToWrite(-1),
146 fNrOfEventsWritten(0),
147 fCopyTreesFromInput(-1),
148 fNinputs(nInputStreams),
150 fInputStreams(new TClonesArray("AliStream",nInputStreams)),
152 fOutputInitialized(kFALSE),
153 fCombi(new AliMergeCombi(nInputStreams,sperb)),
154 fCombination(MAXSTREAMSTOMERGE),
155 fCombinationFileName(0),
160 // ctor which should be used to create
161 // a manager for merging/digitization
163 if (nInputStreams == 0)
165 Fatal("AliRunDigitizer","Specify nr of input streams");
172 for (i=1;i<MAXSTREAMSTOMERGE;i++)
174 fkMASK[i] = fkMASK[i-1] + fkMASKSTEP;
177 TClonesArray &lInputStreams = *fInputStreams;
179 new(lInputStreams[0]) AliStream(fgkBaseInFolderName+(Long_t)0,"UPDATE");
180 for (i=1;i<nInputStreams;i++) {
181 new(lInputStreams[i]) AliStream(fgkBaseInFolderName+(Long_t)i,"READ");
184 //_______________________________________________________________________
186 AliRunDigitizer::AliRunDigitizer(const AliRunDigitizer& dig):
192 fNrOfEventsToWrite(0),
193 fNrOfEventsWritten(0),
194 fCopyTreesFromInput(0),
199 fOutputInitialized(kFALSE),
202 fCombinationFileName(0),
210 //_______________________________________________________________________
212 void AliRunDigitizer::Copy(TObject&) const
215 // Non implemented copy function
217 Fatal("Copy","Not installed\n");
220 //_______________________________________________________________________
222 AliRunDigitizer::~AliRunDigitizer()
227 delete fInputStreams;
229 delete fOutRunLoader;
231 //_______________________________________________________________________
232 void AliRunDigitizer::AddDigitizer(AliDigitizer *digitizer)
235 // add digitizer to the list of active digitizers
237 this->Add(digitizer);
239 //_______________________________________________________________________
240 void AliRunDigitizer::SetInputStream(Int_t i, const char *inputFile, TString foldername)
243 // Sets the name of the input file
245 if (i > fInputStreams->GetLast()) {
246 Error("SetInputStream","Input stream number too high");
249 AliStream * stream = static_cast<AliStream*>(fInputStreams->At(i)) ;
250 if ( !foldername.IsNull() ) {
252 foldername += i ; // foldername should stay unchanged for the default output
253 stream->SetFolderName(foldername) ;
255 stream->AddFile(inputFile);
258 //_______________________________________________________________________
259 void AliRunDigitizer::Digitize(Option_t* option)
261 // get a new combination of inputs, loads events to folders
263 // take gAlice from the first input file. It is needed to access
265 // If gAlice is already in memory, use it
267 if (!static_cast<AliStream*>(fInputStreams->At(0))->ImportgAlice())
269 Error("Digitize","Error occured while getting gAlice from Input 0");
273 if (!InitGlobal()) //calls Init() for all (sub)digitizers
275 Error("Digitize","InitGlobal returned error");
279 Int_t eventsCreated = 0;
280 // loop until there is anything on the input in case fNrOfEventsToWrite < 0
281 while ((eventsCreated++ < fNrOfEventsToWrite) || (fNrOfEventsToWrite < 0))
283 if (!ConnectInputTrees()) break;
284 InitEvent();//this must be after call of Connect Input tress.
287 fOutRunLoader->SetEventNumber(eventsCreated-1);
289 static_cast<AliStream*>(fInputStreams->At(0))->ImportgAlice(); // use gAlice of the first input stream
290 ExecuteTasks(option);// loop over all registered digitizers and let them do the work
297 //_______________________________________________________________________
298 Bool_t AliRunDigitizer::ConnectInputTrees()
303 Int_t eventNr[MAXSTREAMSTOMERGE], delta[MAXSTREAMSTOMERGE];
304 fCombi->Combination(eventNr, delta);
305 for (Int_t i=0;i<fNinputs;i++)
309 AliStream *iStream = static_cast<AliStream*>(fInputStreams->At(i));//gets the "i" defined in combination
310 if (!iStream->NextEventInStream()) return kFALSE; //sets serial number
312 else if (delta[i] != 0)
314 Error("ConnectInputTrees","Only delta 0 or 1 is implemented");
322 //_______________________________________________________________________
323 Bool_t AliRunDigitizer::InitGlobal()
326 // Method called once before Digitize() is called
327 // initialize digitizers and output
329 fOutputInitialized = kFALSE;
330 TList* subTasks = this->GetListOfTasks();
332 TIter next(subTasks);
333 while (AliDigitizer * dig = (AliDigitizer *) next())
339 //_______________________________________________________________________
341 void AliRunDigitizer::SetOutputFile(TString fn)
344 // The output will be to separate file,
345 // not to the signal file here should be protection
346 //to avoid setting the same file as any input
348 Info("SetOutputFile","Setting Output File Name %s ",fn.Data());
349 fOutputFileName = fn;
350 // InitOutputGlobal();
353 //_______________________________________________________________________
354 Bool_t AliRunDigitizer::InitOutputGlobal()
357 // Creates the output file, called by InitEvent()
358 // Needs to be called after all inputs are opened
360 if (fOutputInitialized) return kTRUE;
362 if ( !fOutputFileName.IsNull())
364 fOutRunLoader = AliRunLoader::Open(fOutputFileName,fgkDefOutFolderName,"recreate");
366 if (fOutRunLoader == 0x0)
368 Error("InitOutputGlobal","Can not open ooutput");
371 Info("InitOutputGlobal", " 1 %s = ", GetInputFolderName(0).Data()) ;
372 AliRunLoader* inrl = AliRunLoader::GetRunLoader(GetInputFolderName(0));
375 Error("InitOutputGlobal","Can not get Run Loader Input 0. Maybe yet not initialized?");
378 Info("InitOutputGlobal", " 2 %#x = ", inrl) ;
380 //Copy all detector loaders from input 0 to output
381 const TObjArray* inloaders = inrl->GetArrayOfLoaders();
382 TIter next(inloaders);
384 while((loader = (AliLoader*)next()))
386 AliLoader* cloneloader = (AliLoader*)loader->Clone();
387 cloneloader->Register(fOutRunLoader->GetEventFolder());//creates folders for this loader in Output Folder Structure
388 GetOutRunLoader()->AddLoader(cloneloader);//adds a loader for output
391 fOutRunLoader->MakeTree("E");
393 if (GetDebug()>2) Info("InitOutputGlobal","file %s was opened.",fOutputFileName.Data());
395 fOutputInitialized = kTRUE;
398 //_______________________________________________________________________
400 void AliRunDigitizer::InitEvent()
403 // redirects output properly
407 Info("InitEvent","fEvent = %d",fEvent);
408 Info("InitEvent","fOutputFileName \"%s\"",fOutputFileName.Data());
410 if (fOutputInitialized == kFALSE) InitOutputGlobal();
412 // if fOutputFileName was not given, write output to signal directory
414 //_______________________________________________________________________
416 void AliRunDigitizer::FinishEvent()
419 // called at the end of loop over digitizers
422 if (GetOutRunLoader() == 0x0)
424 Error("FinishEvent","fOutRunLoader is null");
429 fNrOfEventsWritten++;
433 AliRunLoader* inrl = AliRunLoader::GetRunLoader(GetInputFolderName(0));
434 AliHeader* outheader = fOutRunLoader->GetHeader();
435 AliHeader* inheader = inrl->GetHeader();
439 inheader = inrl->GetHeader();
440 if (inheader == 0x0) Fatal("FinishEvent","Can not get header from input 0");
443 outheader->SetNprimary(inheader->GetNprimary());
444 outheader->SetNtrack(inheader->GetNtrack());
445 outheader->SetEvent(inheader->GetEvent());
446 outheader->SetEventNrInRun(inheader->GetEventNrInRun());
447 outheader->SetNvertex(inheader->GetNvertex());
448 fOutRunLoader->TreeE()->Fill();
451 if (fCopyTreesFromInput > -1)
453 //this is sensless since no information would be coherent in case of merging
455 cout<<"Copy trees from input: Copy or link files manually"<<endl;
459 //_______________________________________________________________________
461 void AliRunDigitizer::FinishGlobal()
464 // called at the end of Exec
465 // save unique objects to the output file
467 if (GetOutRunLoader() == 0x0)
469 Error("FinishGlobal","Can not get RunLoader from Output Stream folder");
472 GetOutRunLoader()->CdGAFile();
473 this->Write(NULL, TObject::kOverwrite);
476 fOutRunLoader->WriteHeader("OVERWRITE");
477 fOutRunLoader->WriteRunLoader("OVERWRITE");
478 TFolder* outfolder = fOutRunLoader->GetEventFolder();
479 if (outfolder == 0x0)
481 Error("FinishEvent","Can not get Event Folder");
485 AliRunLoader* inRN = AliRunLoader::GetRunLoader(GetInputFolderName(0));
486 outfolder->Add(inRN->GetAliRun());
487 fOutRunLoader->WriteAliRun("OVERWRITE");
490 if (fCopyTreesFromInput > -1)
492 //copy files manually
495 //_______________________________________________________________________
497 Int_t AliRunDigitizer::GetNParticles(Int_t event) const
499 // return number of particles in all input files for a given
500 // event (as numbered in the output file)
501 // return -1 if some file cannot be accessed
505 for (Int_t i = 0; i < fNinputs; i++) {
506 sumI = GetNParticles(GetInputEventNumber(event,i), i);
507 if (sumI < 0) return -1;
512 //_______________________________________________________________________
514 Int_t AliRunDigitizer::GetNParticles(Int_t /*event*/, Int_t /*input*/) const
516 // return number of particles in input file input for a given
517 // event (as numbered in this input file)
518 // return -1 if some error
520 // Must be revised in the version with AliStream
526 //_______________________________________________________________________
527 Int_t* AliRunDigitizer::GetInputEventNumbers(Int_t event) const
529 // return pointer to an int array with input event numbers which were
530 // merged in the output event event
532 // simplified for now, implement later
533 Int_t * a = new Int_t[MAXSTREAMSTOMERGE];
534 for (Int_t i = 0; i < fNinputs; i++) {
539 //_______________________________________________________________________
540 Int_t AliRunDigitizer::GetInputEventNumber(Int_t event, Int_t /*input*/) const
542 // return an event number of an eventInput from input file input
543 // which was merged to create output event event
545 // simplified for now, implement later
548 //_______________________________________________________________________
549 TParticle* AliRunDigitizer::GetParticle(Int_t i, Int_t event) const
551 // return pointer to particle with index i (index with mask)
554 Int_t input = i/fkMASKSTEP;
555 return GetParticle(i,input,GetInputEventNumber(event,input));
558 //_______________________________________________________________________
559 TParticle* AliRunDigitizer::GetParticle(Int_t /*i*/, Int_t /*input*/, Int_t /*event*/) const
561 // return pointer to particle with index i in the input file input
562 // (index without mask)
563 // event is the event number in the file input
564 // return 0 i fit does not exist
566 // Must be revised in the version with AliStream
571 //_______________________________________________________________________
572 void AliRunDigitizer::ExecuteTask(Option_t* option)
575 // overwrite ExecuteTask to do Digitize only
577 if (!IsActive()) return;
579 fHasExecuted = kTRUE;
583 //_______________________________________________________________________
584 const TString& AliRunDigitizer::GetInputFolderName(Int_t i) const
587 // Get the input Folder Name
589 AliStream* stream = dynamic_cast<AliStream*>(fInputStreams->At(i));
591 Fatal("GetInputFolderName","Can not get the input stream. Index = %d. Exiting",i);
592 return stream->GetFolderName();
594 //_______________________________________________________________________
596 const char* AliRunDigitizer::GetOutputFolderName()
599 // Get output folder name
601 return GetOutRunLoader()->GetEventFolder()->GetName();
603 //_______________________________________________________________________
605 AliRunLoader* AliRunDigitizer::GetOutRunLoader()
608 // Returns Run Loader
610 if (fOutRunLoader) return fOutRunLoader;
612 if ( fOutputFileName.IsNull() )
613 {//guard that sombody calls it without settting file name
615 Info("GetOutRunLoader",
616 "Output file name is empty. Using Input 0 for output");
618 return AliRunLoader::GetRunLoader(GetInputFolderName(0));
620 // InitOutputGlobal();
621 return fOutRunLoader;
623 //_______________________________________________________________________
625 TString AliRunDigitizer::GetInputFileName(Int_t input, Int_t order) const
627 // returns file name of the order-th file in the input stream input
628 // returns empty string if such file does not exist
629 // first input stream is 0
630 // first file in the input stream is 0
631 TString fileName("");
632 if (input >= fNinputs) return fileName;
633 AliStream * stream = static_cast<AliStream*>(fInputStreams->At(input));
634 if (order > stream->GetNInputFiles()) return fileName;
635 fileName = stream->GetFileName(order);