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