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