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 // AliDigitizationInput.cxx
21 // RS: Created from former AliDigitizationInput. It does not anymore manage digitization:
22 // (now it is steared by the AliSimulation) but just provides input info for
23 // AliDetector::SDigits2Ditits.
25 // Manager object for merging/digitization
27 // Instance of this class manages the digitization and/or merging of
28 // Sdigits into Digits.
30 // Only one instance of this class is created in the macro:
31 // AliDigitizationInput * manager =
32 // new AliDigitizationInput(nInputStreams,SPERB);
33 // where nInputStreams is number of input streams and SPERB is
34 // signals per background variable, which determines how combinations
35 // of signal and background events are generated.
36 // Then instances of specific detector digitizers are created:
37 // AliMUONDigitizer *dMUON = new AliMUONDigitizer(manager)
38 // and the I/O configured (you have to specify input files
39 // and an output file). The manager connects appropriate trees from
40 // the input files according a combination returned by AliMergeCombi
41 // class. It creates TreeD in the output and runs once per
42 // event Digitize method of all existing AliDetDigitizers
43 // (without any option). AliDetDigitizers ask manager
44 // for a TTree with input (manager->GetInputTreeS(Int_t i),
45 // merge all inputs, digitize it, and save it in the TreeD
46 // obtained by manager->GetTreeD(). Output events are stored with
47 // numbers from 0, this default can be changed by
48 // manager->SetFirstOutputEventNr(Int_t) method. The particle numbers
49 // in the output are shifted by MASK, which is taken from manager.
51 // The default output is to the signal file (stream 0). This can be
52 // changed with the SetOutputFile(TString fn) method.
54 // Single input file is permitted. Maximum MAXSTREAMSTOMERGE can be merged.
55 // Input from the memory (on-the-fly merging) is not yet
56 // supported, as well as access to the input data by invoking methods
57 // on the output data.
59 // Access to the some data is via gAlice for now (supposing the
60 // same geometry in all input files), gAlice is taken from the first
61 // input file on the first stream.
63 // Example with MUON digitizer, no merging, just digitization
65 // AliDigitizationInput * manager = new AliDigitizationInput(1,1);
66 // manager->SetInputStream(0,"galice.root");
67 // AliMUONDigitizer *dMUON = new AliMUONDigitizer(manager);
70 // Example with MUON digitizer, merge all events from
71 // galice.root (signal) file with events from bgr.root
72 // (background) file. Number of merged events is
73 // min(number of events in galice.root, number of events in bgr.root)
75 // AliDigitizationInput * manager = new AliDigitizationInput(2,1);
76 // manager->SetInputStream(0,"galice.root");
77 // manager->SetInputStream(1,"bgr.root");
78 // AliMUONDigitizer *dMUON = new AliMUONDigitizer(manager);
81 // Example with MUON digitizer, save digits in a new file digits.root,
82 // process only 1 event
84 // AliDigitizationInput * manager = new AliDigitizationInput(2,1);
85 // manager->SetInputStream(0,"galice.root");
86 // manager->SetInputStream(1,"bgr.root");
87 // manager->SetOutputFile("digits.root");
88 // AliMUONDigitizer *dMUON = new AliMUONDigitizer(manager);
89 // manager->SetNrOfEventsToWrite(1);
92 //_______________________________________________________________________
99 #include <Riostream.h>
105 #include "AliDigitizer.h"
106 #include "AliHeader.h"
107 #include "AliLoader.h"
108 #include "AliMergeCombi.h"
110 #include "AliDigitizationInput.h"
111 #include "AliRunLoader.h"
113 ClassImp(AliDigitizationInput)
115 const TString AliDigitizationInput::fgkDefOutFolderName("Output");
116 const TString AliDigitizationInput::fgkBaseInFolderName("Input");
119 //_______________________________________________________________________
120 AliDigitizationInput::AliDigitizationInput(): TNamed("AliDigitizationInput","The manager for Merging"),
125 fNrOfEventsToWrite(0),
126 fNrOfEventsWritten(0),
127 fCopyTreesFromInput(0),
130 fRegionOfInterest(kFALSE),
133 fOutputInitialized(kFALSE),
136 fCombinationFileName(0)
139 // root requires default ctor, where no new objects can be created
140 // do not use this ctor, it is supplied only for root needs
141 for (Int_t i=0; i<MAXSTREAMSTOMERGE; ++i) fkMASK[i]=0;
144 //_______________________________________________________________________
145 AliDigitizationInput::AliDigitizationInput(Int_t nInputStreams, Int_t sperb):
146 TNamed("AliDigitizationInput","The manager for Merging"),
147 fkMASKSTEP(10000000),
151 fNrOfEventsToWrite(-1),
152 fNrOfEventsWritten(0),
153 fCopyTreesFromInput(-1),
154 fNinputs(nInputStreams),
156 fRegionOfInterest(kFALSE),
157 fInputStreams(new TClonesArray("AliStream",nInputStreams)),
159 fOutputInitialized(kFALSE),
160 fCombi(new AliMergeCombi(nInputStreams,sperb)),
161 fCombination(MAXSTREAMSTOMERGE),
162 fCombinationFileName(0)
166 // ctor which should be used to create
167 // a manager for merging/digitization
169 if (nInputStreams == 0)
171 AliFatal("Specify nr of input streams");
178 for (i=1;i<MAXSTREAMSTOMERGE;i++)
180 fkMASK[i] = fkMASK[i-1] + fkMASKSTEP;
183 TClonesArray &lInputStreams = *fInputStreams;
185 new(lInputStreams[0]) AliStream(fgkBaseInFolderName+(Long_t)0,"UPDATE");
186 for (i=1;i<nInputStreams;i++) {
187 new(lInputStreams[i]) AliStream(fgkBaseInFolderName+(Long_t)i,"READ");
190 //_______________________________________________________________________
192 void AliDigitizationInput::Copy(TObject&) const
195 // Non implemented copy function
197 AliFatal("Not installed");
200 //_______________________________________________________________________
202 AliDigitizationInput::~AliDigitizationInput()
207 delete fInputStreams;
209 delete fOutRunLoader;
212 //_______________________________________________________________________
213 void AliDigitizationInput::SetInputStream(Int_t i, const char *inputFile, TString foldername)
216 // Sets the name of the input file
218 if (i > fInputStreams->GetLast()) {
219 AliError("Input stream number too high");
222 AliStream * stream = static_cast<AliStream*>(fInputStreams->At(i)) ;
223 if ( !foldername.IsNull() ) {
225 foldername += i ; // foldername should stay unchanged for the default output
226 stream->SetFolderName(foldername) ;
228 stream->AddFile(inputFile);
231 //_______________________________________________________________________
232 Bool_t AliDigitizationInput::ConnectInputTrees()
237 Int_t eventNr[MAXSTREAMSTOMERGE], delta[MAXSTREAMSTOMERGE];
238 fCombi->Combination(eventNr, delta);
239 for (Int_t i=0;i<fNinputs;i++)
243 AliStream *iStream = static_cast<AliStream*>(fInputStreams->At(i));//gets the "i" defined in combination
244 if (!iStream->NextEventInStream()) return kFALSE; //sets serial number
246 else if (delta[i] != 0)
248 AliError("Only delta 0 or 1 is implemented");
257 //_______________________________________________________________________
259 void AliDigitizationInput::SetOutputFile(TString fn)
262 // The output will be to separate file,
263 // not to the signal file here should be protection
264 //to avoid setting the same file as any input
266 AliInfo(Form("Setting Output File Name %s ",fn.Data()));
267 fOutputFileName = fn;
268 // InitOutputGlobal();
271 //_______________________________________________________________________
272 Bool_t AliDigitizationInput::InitOutputGlobal()
275 // Creates the output file, called by InitEvent()
276 // Needs to be called after all inputs are opened
278 if (fOutputInitialized) return kTRUE;
280 if ( !fOutputFileName.IsNull())
282 fOutRunLoader = AliRunLoader::Open(fOutputFileName,fgkDefOutFolderName,"recreate");
284 if (fOutRunLoader == 0x0)
286 AliError("Can not open output");
289 Info("InitOutputGlobal", " 1 %s = ", GetInputFolderName(0).Data()) ;
290 AliRunLoader* inrl = AliRunLoader::GetRunLoader(GetInputFolderName(0));
293 AliError("Can not get Run Loader Input 0. Maybe yet not initialized?");
296 AliDebug(2, Form(" 2 %p = ", inrl)) ;
298 //Copy all detector loaders from input 0 to output
299 const TObjArray* inloaders = inrl->GetArrayOfLoaders();
300 TIter next(inloaders);
302 while((loader = (AliLoader*)next()))
304 AliLoader* cloneloader = (AliLoader*)loader->Clone();
305 cloneloader->Register(fOutRunLoader->GetEventFolder());//creates folders for this loader in Output Folder Structure
306 GetOutRunLoader()->AddLoader(cloneloader);//adds a loader for output
309 fOutRunLoader->MakeTree("E");
311 AliDebug(3,Form("file %s was opened.",fOutputFileName.Data()));
313 fOutputInitialized = kTRUE;
316 //_______________________________________________________________________
318 void AliDigitizationInput::InitEvent()
321 // redirects output properly
323 AliDebug(3,Form("fEvent = %d",fEvent));
324 AliDebug(3,Form("fOutputFileName \"%s\"",fOutputFileName.Data()));
325 if (fOutputInitialized == kFALSE) InitOutputGlobal();
327 // if fOutputFileName was not given, write output to signal directory
329 //_______________________________________________________________________
331 void AliDigitizationInput::FinishEvent()
334 // called at the end of loop over digitizers
337 if (GetOutRunLoader() == 0x0)
339 AliError("fOutRunLoader is null");
344 fNrOfEventsWritten++;
348 AliRunLoader* inrl = AliRunLoader::GetRunLoader(GetInputFolderName(0));
349 AliHeader* outheader = fOutRunLoader->GetHeader();
350 AliHeader* inheader = inrl->GetHeader();
354 inheader = inrl->GetHeader();
355 if (inheader == 0x0) AliFatal("Can not get header from input 0");
358 outheader->SetNprimary(inheader->GetNprimary());
359 outheader->SetNtrack(inheader->GetNtrack());
360 outheader->SetEvent(inheader->GetEvent());
361 outheader->SetEventNrInRun(inheader->GetEventNrInRun());
362 outheader->SetNvertex(inheader->GetNvertex());
363 fOutRunLoader->TreeE()->Fill();
366 if (fCopyTreesFromInput > -1)
368 //this is sensless since no information would be coherent in case of merging
370 AliWarning("Copy trees from input: Copy or link files manually");
374 //_______________________________________________________________________
376 void AliDigitizationInput::FinishGlobal()
379 // called at the end of Exec
380 // save unique objects to the output file
382 if (GetOutRunLoader() == 0x0)
384 AliError("Can not get RunLoader from Output Stream folder");
387 GetOutRunLoader()->CdGAFile();
388 this->Write(NULL, TObject::kOverwrite);
391 fOutRunLoader->WriteHeader("OVERWRITE");
392 fOutRunLoader->WriteRunLoader("OVERWRITE");
393 TFolder* outfolder = fOutRunLoader->GetEventFolder();
394 if (outfolder == 0x0)
396 AliError("Can not get Event Folder");
400 AliRunLoader* inRN = AliRunLoader::GetRunLoader(GetInputFolderName(0));
401 outfolder->Add(inRN->GetAliRun());
402 fOutRunLoader->WriteAliRun("OVERWRITE");
405 if (fCopyTreesFromInput > -1)
407 //copy files manually
410 //_______________________________________________________________________
412 Int_t AliDigitizationInput::GetNParticles(Int_t event) const
414 // return number of particles in all input files for a given
415 // event (as numbered in the output file)
416 // return -1 if some file cannot be accessed
420 for (Int_t i = 0; i < fNinputs; i++) {
421 sumI = GetNParticles(GetInputEventNumber(event,i), i);
422 if (sumI < 0) return -1;
427 //_______________________________________________________________________
429 Int_t AliDigitizationInput::GetNParticles(Int_t /*event*/, Int_t /*input*/) const
431 // return number of particles in input file input for a given
432 // event (as numbered in this input file)
433 // return -1 if some error
435 // Must be revised in the version with AliStream
441 //_______________________________________________________________________
442 Int_t* AliDigitizationInput::GetInputEventNumbers(Int_t event) const
444 // return pointer to an int array with input event numbers which were
445 // merged in the output event event
447 // simplified for now, implement later
448 Int_t * a = new Int_t[MAXSTREAMSTOMERGE];
449 for (Int_t i = 0; i < fNinputs; i++) {
454 //_______________________________________________________________________
455 Int_t AliDigitizationInput::GetInputEventNumber(Int_t event, Int_t /*input*/) const
457 // return an event number of an eventInput from input file input
458 // which was merged to create output event event
460 // simplified for now, implement later
463 //_______________________________________________________________________
464 TParticle* AliDigitizationInput::GetParticle(Int_t i, Int_t event) const
466 // return pointer to particle with index i (index with mask)
469 Int_t input = i/fkMASKSTEP;
470 return GetParticle(i,input,GetInputEventNumber(event,input));
473 //_______________________________________________________________________
474 TParticle* AliDigitizationInput::GetParticle(Int_t /*i*/, Int_t /*input*/, Int_t /*event*/) const
476 // return pointer to particle with index i in the input file input
477 // (index without mask)
478 // event is the event number in the file input
479 // return 0 i fit does not exist
481 // Must be revised in the version with AliStream
486 //_______________________________________________________________________
487 const TString& AliDigitizationInput::GetInputFolderName(Int_t i) const
490 // Get the input Folder Name
492 AliStream* stream = dynamic_cast<AliStream*>(fInputStreams->At(i));
494 AliFatal(Form("Can not get the input stream. Index = %d. Exiting",i));
495 return stream->GetFolderName();
497 //_______________________________________________________________________
499 const char* AliDigitizationInput::GetOutputFolderName()
502 // Get output folder name
504 return GetOutRunLoader()->GetEventFolder()->GetName();
506 //_______________________________________________________________________
508 AliRunLoader* AliDigitizationInput::GetOutRunLoader()
511 // Returns Run Loader
513 if (fOutRunLoader) return fOutRunLoader;
515 if ( fOutputFileName.IsNull() )
516 {//guard that sombody calls it without settting file name
517 AliDebug(1,"Output file name is empty. Using Input 0 for output");
518 return AliRunLoader::GetRunLoader(GetInputFolderName(0));
520 // InitOutputGlobal();
521 return fOutRunLoader;
523 //_______________________________________________________________________
525 TString AliDigitizationInput::GetInputFileName(Int_t input, Int_t order) const
527 // returns file name of the order-th file in the input stream input
528 // returns empty string if such file does not exist
529 // first input stream is 0
530 // first file in the input stream is 0
531 TString fileName("");
532 if (input >= fNinputs) return fileName;
533 AliStream * stream = static_cast<AliStream*>(fInputStreams->At(input));
534 if (order > stream->GetNInputFiles()) return fileName;
535 fileName = stream->GetFileName(order);