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 Revision 1.9 2001/11/15 09:00:11 jchudoba
19 Add special treatment for TPC and TRD, they use different trees than other detectors
21 Revision 1.8 2001/10/21 18:38:43 hristov
22 Several pointers were set to zero in the default constructors to avoid memory management problems
24 Revision 1.7 2001/10/04 15:56:07 jchudoba
27 Revision 1.4 2001/09/19 06:23:50 jchudoba
28 Move some tasks to AliStream and AliMergeCombi classes
30 Revision 1.3 2001/07/30 14:04:18 jchudoba
31 correct bug in the initialization
33 Revision 1.2 2001/07/28 10:44:32 hristov
34 Loop variable declared once; typos corrected
36 Revision 1.1 2001/07/27 12:59:00 jchudoba
37 Manager class for merging/digitization
41 ////////////////////////////////////////////////////////////////////////
43 // AliRunDigitizer.cxx
45 // Manager object for merging/digitization
47 // Instance of this class manages the digitization and/or merging of
48 // Sdigits into Digits.
50 // Only one instance of this class is created in the macro:
51 // AliRunDigitizer * manager =
52 // new AliRunDigitizer(nInputStreams,SPERB);
53 // where nInputStreams is number of input streams and SPERB is
54 // signals per background variable, which determines how combinations
55 // of signal and background events are generated.
56 // Then instances of specific detector digitizers are created:
57 // AliMUONDigitizer *dMUON = new AliMUONDigitizer(manager)
58 // and the I/O configured (you have to specify input files
59 // and an output file). The manager connects appropriate trees from
60 // the input files according a combination returned by AliMergeCombi
61 // class. It creates TreeD in the output and runs once per
62 // event Digitize method of all existing AliDetDigitizers
63 // (without any option). AliDetDigitizers ask manager
64 // for a TTree with input (manager->GetInputTreeS(Int_t i),
65 // merge all inputs, digitize it, and save it in the TreeD
66 // obtained by manager->GetTreeD(). Output events are stored with
67 // numbers from 0, this default can be changed by
68 // manager->SetFirstOutputEventNr(Int_t) method. The particle numbers
69 // in the output are shifted by MASK, which is taken from manager.
71 // The default output is to the signal file (stream 0). This can be
72 // changed with the SetOutputFile(TString fn) method.
74 // Single input file is permitted. Maximum kMaxStreamsToMerge can be merged.
75 // Input from the memory (on-the-fly merging) is not yet
76 // supported, as well as access to the input data by invoking methods
77 // on the output data.
79 // Access to the some data is via gAlice for now (supposing the
80 // same geometry in all input files), gAlice is taken from the first
81 // input file on the first stream.
83 // Example with MUON digitizer:
85 // AliRunDigitizer * manager = new AliRunDigitizer(2,1);
86 // manager->SetInputStream(0,"1track_10events_phi45_60.root");
87 // manager->SetInputStream(1,"1track_10events_phi120_135.root");
88 // manager->SetOutputFile("digits.root");
89 // AliMUONDigitizer *dMUON = new AliMUONDigitizer(manager);
90 // manager->SetNrOfEventsToWrite(1);
93 ////////////////////////////////////////////////////////////////////////
107 #include "AliRunDigitizer.h"
108 #include "AliDigitizer.h"
110 #include "AliHeader.h"
111 #include "TParticle.h"
112 #include "AliStream.h"
113 #include "AliMergeCombi.h"
115 ClassImp(AliRunDigitizer)
117 ////////////////////////////////////////////////////////////////////////
118 AliRunDigitizer::AliRunDigitizer(Int_t nInputStreams, Int_t sperb) : TTask("AliRunDigitizer","The manager for Merging")
121 if (nInputStreams == 0) {
122 Error("AliRunDigitizer","Specify nr of input streams");
126 fNinputs = nInputStreams;
127 fOutputFileName = "";
128 fOutputDirName = ".";
129 fCombination.Set(kMaxStreamsToMerge);
130 for (i=0;i<kMaxStreamsToMerge;i++) {
131 fArrayTreeS[i]=fArrayTreeH[i]=fArrayTreeTPCS[i]=NULL;
134 fkMASKSTEP = 10000000;
136 for (i=1;i<kMaxStreamsToMerge;i++) {
137 fkMASK[i] = fkMASK[i-1] + fkMASKSTEP;
139 fInputStreams = new TClonesArray("AliStream",nInputStreams);
140 TClonesArray &lInputStreams = *fInputStreams;
141 // the first Input is open RW to be output as well
142 new(lInputStreams[0]) AliStream("UPDATE");
143 for (i=1;i<nInputStreams;i++) {
144 new(lInputStreams[i]) AliStream();
148 fNrOfEventsToWrite = -1;
149 fNrOfEventsWritten = 0;
150 fCopyTreesFromInput = -1;
151 fCombi = new AliMergeCombi(nInputStreams,sperb);
157 for (i=0; i<kMaxStreamsToMerge; i++) fInputFiles[i]=0;
160 ////////////////////////////////////////////////////////////////////////
162 AliRunDigitizer::~AliRunDigitizer() {
166 delete fInputStreams;
175 ////////////////////////////////////////////////////////////////////////
176 void AliRunDigitizer::AddDigitizer(AliDigitizer *digitizer)
178 // add digitizer to the list of active digitizers
179 this->Add(digitizer);
181 ////////////////////////////////////////////////////////////////////////
182 void AliRunDigitizer::SetInputStream(Int_t i, char *inputFile)
184 if (i > fInputStreams->GetLast()) {
185 Error("SetInputStream","Input stream number too high");
188 static_cast<AliStream*>(fInputStreams->At(i))->AddFile(inputFile);
191 ////////////////////////////////////////////////////////////////////////
192 void AliRunDigitizer::Digitize(Option_t* option)
194 // get a new combination of inputs, connect input trees and loop
195 // over all digitizers
198 cerr<<"False from InitGlobal"<<endl;
201 // take gAlice from the first input file. It is needed to access
203 if (!static_cast<AliStream*>(fInputStreams->At(0))->ImportgAlice()) {
204 cerr<<"gAlice object not found in the first file of "
205 <<"the 1st stream"<<endl;
208 Int_t eventsCreated = 0;
209 // loop until there is anything on the input in case fNrOfEventsToWrite < 0
210 while ((eventsCreated++ < fNrOfEventsToWrite) || (fNrOfEventsToWrite < 0)) {
211 if (!ConnectInputTrees()) break;
213 // loop over all registered digitizers and let them do the work
221 ////////////////////////////////////////////////////////////////////////
222 Bool_t AliRunDigitizer::ConnectInputTrees()
224 // fill arrays fArrayTreeS, fArrayTreeH and fArrayTreeTPCS with
225 // pointers to the correct events according fCombination values
226 // null pointers can be in the output, AliDigitizer has to check it
231 Int_t eventNr[kMaxStreamsToMerge], delta[kMaxStreamsToMerge];
232 fCombi->Combination(eventNr, delta);
233 for (Int_t i=0;i<fNinputs;i++) {
235 AliStream *iStream = static_cast<AliStream*>(fInputStreams->At(i));
236 if (!iStream->NextEventInStream(serialNr)) return kFALSE;
237 fInputFiles[i]=iStream->CurrentFile();
238 sprintf(treeName,"TreeS%d",serialNr);
239 tree = static_cast<TTree*>(iStream->CurrentFile()->Get(treeName));
240 fArrayTreeS[i] = tree;
241 sprintf(treeName,"TreeH%d",serialNr);
242 tree = static_cast<TTree*>(iStream->CurrentFile()->Get(treeName));
243 fArrayTreeH[i] = tree;
244 sprintf(treeName,"TreeS_75x40_100x60_%d",serialNr);
245 tree = static_cast<TTree*>(iStream->CurrentFile()->Get(treeName));
246 fArrayTreeTPCS[i] = tree;
247 sprintf(treeName,"TreeS%d_TRD",serialNr);
248 tree = static_cast<TTree*>(iStream->CurrentFile()->Get(treeName));
249 fArrayTreeTRDS[i] = tree;
250 } else if (delta[i] != 0) {
251 Error("ConnectInputTrees","Only delta 0 or 1 is implemented");
258 ////////////////////////////////////////////////////////////////////////
259 Bool_t AliRunDigitizer::InitGlobal()
261 // called once before Digitize() is called, initialize digitizers and output
263 TList* subTasks = this->GetListOfTasks();
265 subTasks->ForEach(AliDigitizer,Init)();
270 ////////////////////////////////////////////////////////////////////////
272 void AliRunDigitizer::SetOutputFile(TString fn)
273 // the output will be to separate file, not to the signal file
275 fOutputFileName = fn;
276 (static_cast<AliStream*>(fInputStreams->At(0)))->ChangeMode("READ");
280 ////////////////////////////////////////////////////////////////////////
281 Bool_t AliRunDigitizer::InitOutputGlobal()
283 // Creates the output file, called by InitEvent()
286 fn = fOutputDirName + '/' + fOutputFileName;
287 fOutput = new TFile(fn,"recreate");
289 cerr<<"AliRunDigitizer::InitOutputGlobal(): file "<<fn.Data()<<" was opened"<<endl;
291 if (fOutput) return kTRUE;
292 Error("InitOutputGlobal","Could not create output file.");
297 ////////////////////////////////////////////////////////////////////////
298 void AliRunDigitizer::InitEvent()
300 // Creates TreeDxx in the output file, called from Digitize() once for
301 // each event. xx = fEvent
304 cerr<<"AliRunDigitizer::InitEvent: fEvent = "<<fEvent<<endl;
306 // if fOutputFileName was not given, write output to signal file
307 if (fOutputFileName == "") {
308 fOutput = (static_cast<AliStream*>(fInputStreams->At(0)))->CurrentFile();
312 sprintf(treeName,"TreeD%d",fEvent);
313 fTreeD = static_cast<TTree*>(fOutput->Get(treeName));
315 fTreeD = new TTree(treeName,"Digits");
316 fTreeD->Write(0,TObject::kOverwrite);
319 // special tree for TPC
320 sprintf(treeName,"TreeD_75x40_100x60_%d",fEvent);
321 fTreeDTPC = static_cast<TTree*>(fOutput->Get(treeName));
323 fTreeDTPC = new TTree(treeName,"TPC_Digits");
324 fTreeDTPC->Write(0,TObject::kOverwrite);
327 // special tree for TRD
328 sprintf(treeName,"TreeD%d_TRD",fEvent);
329 fTreeDTRD = static_cast<TTree*>(fOutput->Get(treeName));
331 fTreeDTRD = new TTree(treeName,"TRD_Digits");
332 fTreeDTRD->Write(0,TObject::kOverwrite);
337 ////////////////////////////////////////////////////////////////////////
338 void AliRunDigitizer::FinishEvent()
340 // called at the end of loop over digitizers
343 if (fCopyTreesFromInput > -1) {
345 Int_t i = fCopyTreesFromInput;
346 sprintf(treeName,"TreeK%d",fCombination[i]);
347 fInputFiles[i]->Get(treeName)->Clone()->Write();
348 sprintf(treeName,"TreeH%d",fCombination[i]);
349 fInputFiles[i]->Get(treeName)->Clone()->Write();
352 fNrOfEventsWritten++;
366 ////////////////////////////////////////////////////////////////////////
367 void AliRunDigitizer::FinishGlobal()
369 // called at the end of Exec
370 // save unique objects to the output file
374 if (fCopyTreesFromInput > -1) {
375 fInputFiles[fCopyTreesFromInput]->Get("TE")->Clone()->Write();
382 ////////////////////////////////////////////////////////////////////////
383 Int_t AliRunDigitizer::GetNParticles(Int_t event) const
385 // return number of particles in all input files for a given
386 // event (as numbered in the output file)
387 // return -1 if some file cannot be accessed
391 for (Int_t i = 0; i < fNinputs; i++) {
392 sumI = GetNParticles(GetInputEventNumber(event,i), i);
393 if (sumI < 0) return -1;
399 ////////////////////////////////////////////////////////////////////////
400 Int_t AliRunDigitizer::GetNParticles(Int_t event, Int_t input) const
402 // return number of particles in input file input for a given
403 // event (as numbered in this input file)
404 // return -1 if some error
406 // Must be revised in the version with AliStream
411 TFile *file = ConnectInputFile(input);
413 Error("GetNParticles","Cannot open input file");
417 // find the header and get Nprimaries and Nsecondaries
418 TTree* tE = (TTree *)file->Get("TE") ;
420 Error("GetNParticles","input file does not contain TE");
425 tE->SetBranchAddress("Header", &header);
426 if (!tE->GetEntry(event)) {
427 Error("GetNParticles","event %d not found",event);
431 cerr<<"Nprimary: "<< header->GetNprimary()<<endl;
432 cerr<<"Nsecondary: "<<header->GetNsecondary()<<endl;
434 return header->GetNprimary() + header->GetNsecondary();
438 ////////////////////////////////////////////////////////////////////////
439 Int_t* AliRunDigitizer::GetInputEventNumbers(Int_t event) const
441 // return pointer to an int array with input event numbers which were
442 // merged in the output event event
444 // simplified for now, implement later
445 Int_t * a = new Int_t[kMaxStreamsToMerge];
446 for (Int_t i = 0; i < fNinputs; i++) {
451 ////////////////////////////////////////////////////////////////////////
452 Int_t AliRunDigitizer::GetInputEventNumber(Int_t event, Int_t input) const
454 // return an event number of an eventInput from input file input
455 // which was merged to create output event event
457 // simplified for now, implement later
460 ////////////////////////////////////////////////////////////////////////
461 TParticle* AliRunDigitizer::GetParticle(Int_t i, Int_t event) const
463 // return pointer to particle with index i (index with mask)
466 Int_t input = i/fkMASKSTEP;
467 return GetParticle(i,input,GetInputEventNumber(event,input));
470 ////////////////////////////////////////////////////////////////////////
471 TParticle* AliRunDigitizer::GetParticle(Int_t i, Int_t input, Int_t event) const
473 // return pointer to particle with index i in the input file input
474 // (index without mask)
475 // event is the event number in the file input
476 // return 0 i fit does not exist
478 // Must be revised in the version with AliStream
482 TFile *file = ConnectInputFile(input);
484 Error("GetParticle","Cannot open input file");
488 // find the header and get Nprimaries and Nsecondaries
489 TTree* tE = (TTree *)file->Get("TE") ;
491 Error("GetParticle","input file does not contain TE");
496 tE->SetBranchAddress("Header", &header);
497 if (!tE->GetEntry(event)) {
498 Error("GetParticle","event %d not found",event);
504 sprintf(treeName,"TreeK%d",event);
505 TTree* tK = static_cast<TTree*>(file->Get(treeName));
507 Error("GetParticle","input file does not contain TreeK%d",event);
510 TParticle *particleBuffer;
512 tK->SetBranchAddress("Particles", &particleBuffer);
515 // algorithmic way of getting entry index
516 // (primary particles are filled after secondaries)
518 if (i<header->GetNprimary())
519 entry = i+header->GetNsecondary();
521 entry = i-header->GetNprimary();
522 Int_t bytesRead = tK->GetEntry(entry);
523 // new ((*fParticles)[nentries]) TParticle(*fParticleBuffer);
525 return particleBuffer;
530 ////////////////////////////////////////////////////////////////////////
531 void AliRunDigitizer::ExecuteTask(Option_t* option)
533 // overwrite ExecuteTask to do Digitize only
535 if (!IsActive()) return;
537 fHasExecuted = kTRUE;