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