]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliSimulation.cxx
reduce printout
[u/mrichter/AliRoot.git] / STEER / AliSimulation.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 // class for running generation, simulation and digitization                 //
21 //                                                                           //
22 // Hits, sdigits and digits are created for all detectors by typing:         //
23 //                                                                           //
24 //   AliSimulation sim;                                                      //
25 //   sim.Run();                                                              //
26 //                                                                           //
27 // The Run method returns kTRUE in case of successful execution.             //
28 // The number of events can be given as argument to the Run method or it     //
29 // can be set by                                                             //
30 //                                                                           //
31 //   sim.SetNumberOfEvents(n);                                               //
32 //                                                                           //
33 // The name of the configuration file can be passed as argument to the       //
34 // AliSimulation constructor or can be specified by                          //
35 //                                                                           //
36 //   sim.SetConfigFile("...");                                               //
37 //                                                                           //
38 // The generation of particles and the simulation of detector hits can be    //
39 // switched on or off by                                                     //
40 //                                                                           //
41 //   sim.SetRunGeneration(kTRUE);   // generation of primary particles       //
42 //   sim.SetRunSimulation(kFALSE);  // but no tracking                       //
43 //                                                                           //
44 // For which detectors sdigits and digits will be created, can be steered    //
45 // by                                                                        //
46 //                                                                           //
47 //   sim.SetMakeSDigits("ALL");     // make sdigits for all detectors        //
48 //   sim.SetMakeDigits("ITS TPC");  // make digits only for ITS and TPC      //
49 //                                                                           //
50 // The argument is a (case sensitive) string with the names of the           //
51 // detectors separated by a space. An empty string ("") can be used to       //
52 // disable the creation of sdigits or digits. The special string "ALL"       //
53 // selects all available detectors. This is the default.                     //
54 //                                                                           //
55 // The creation of digits from hits instead of from sdigits can be selected  //
56 // by                                                                        //
57 //                                                                           //
58 //   sim.SetMakeDigitsFromHits("TRD");                                       //
59 //                                                                           //
60 // The argument is again a string with the selected detectors. Be aware that //
61 // this feature is not available for all detectors and that merging is not   //
62 // possible, when digits are created directly from hits.                     //
63 //                                                                           //
64 // Background events can be merged by calling                                //
65 //                                                                           //
66 //   sim.MergeWith("background/galice.root", 2);                             //
67 //                                                                           //
68 // The first argument is the file name of the background galice file. The    //
69 // second argument is the number of signal events per background event.      //
70 // By default this number is calculated from the number of available         //
71 // background events. MergeWith can be called several times to merge more    //
72 // than two event streams. It is assumed that the sdigits were already       //
73 // produced for the background events.                                       //
74 //                                                                           //
75 // The output of raw data can be switched on by calling                      //
76 //                                                                           //
77 //   sim.SetWriteRawData("MUON");   // write raw data for MUON               //
78 //                                                                           //
79 // The methods RunSimulation, RunSDigitization, RunDigitization,             //
80 // RunHitsDigitization and WriteRawData can be used to run only parts of     //
81 // the full simulation chain.                                                //
82 //                                                                           //
83 ///////////////////////////////////////////////////////////////////////////////
84
85 #include <TObjString.h>
86 #include <TStopwatch.h>
87 #include <TSystem.h>
88
89 #include "AliDigitizer.h"
90 #include "AliGenerator.h"
91 #include "AliModule.h"
92 #include "AliRun.h"
93 #include "AliRunDigitizer.h"
94 #include "AliRunLoader.h"
95 #include "AliSimulation.h"
96 #include "AliVertexGenFile.h"
97
98 ClassImp(AliSimulation)
99
100
101 //_____________________________________________________________________________
102 AliSimulation::AliSimulation(const char* configFileName,
103                              const char* name, const char* title) :
104   TNamed(name, title),
105
106   fRunGeneration(kTRUE),
107   fRunSimulation(kTRUE),
108   fMakeSDigits("ALL"),
109   fMakeDigits("ALL"),
110   fMakeDigitsFromHits(""),
111   fWriteRawData(""),
112   fStopOnError(kFALSE),
113
114   fNEvents(1),
115   fConfigFileName(configFileName),
116   fGAliceFileName("galice.root"),
117   fBkgrdFileNames(NULL),
118   fUseBkgrdVertex(kTRUE),
119   fRegionOfInterest(kTRUE)
120 {
121 // create simulation object with default parameters
122
123   SetGAliceFile("galice.root");
124 }
125
126 //_____________________________________________________________________________
127 AliSimulation::AliSimulation(const AliSimulation& sim) :
128   TNamed(sim),
129
130   fRunGeneration(sim.fRunGeneration),
131   fRunSimulation(sim.fRunSimulation),
132   fMakeSDigits(sim.fMakeSDigits),
133   fMakeDigits(sim.fMakeDigits),
134   fMakeDigitsFromHits(sim.fMakeDigitsFromHits),
135   fWriteRawData(sim.fWriteRawData),
136   fStopOnError(sim.fStopOnError),
137
138   fNEvents(sim.fNEvents),
139   fConfigFileName(sim.fConfigFileName),
140   fGAliceFileName(sim.fGAliceFileName),
141   fBkgrdFileNames(NULL),
142   fUseBkgrdVertex(sim.fUseBkgrdVertex),
143   fRegionOfInterest(sim.fRegionOfInterest)
144 {
145 // copy constructor
146
147   fBkgrdFileNames = new TObjArray;
148   for (Int_t i = 0; i < sim.fBkgrdFileNames->GetEntriesFast(); i++) {
149     if (!sim.fBkgrdFileNames->At(i)) continue;
150     fBkgrdFileNames->Add(sim.fBkgrdFileNames->At(i)->Clone());
151   }
152 }
153
154 //_____________________________________________________________________________
155 AliSimulation& AliSimulation::operator = (const AliSimulation& sim)
156 {
157 // assignment operator
158
159   this->~AliSimulation();
160   new(this) AliSimulation(sim);
161   return *this;
162 }
163
164 //_____________________________________________________________________________
165 AliSimulation::~AliSimulation()
166 {
167 // clean up
168
169   if (fBkgrdFileNames) {
170     fBkgrdFileNames->Delete();
171     delete fBkgrdFileNames;
172   }
173 }
174
175
176 //_____________________________________________________________________________
177 void AliSimulation::SetNumberOfEvents(Int_t nEvents)
178 {
179 // set the number of events for one run
180
181   fNEvents = nEvents;
182 }
183
184 //_____________________________________________________________________________
185 void AliSimulation::SetConfigFile(const char* fileName)
186 {
187 // set the name of the config file
188
189   fConfigFileName = fileName;
190 }
191
192 //_____________________________________________________________________________
193 void AliSimulation::SetGAliceFile(const char* fileName)
194 {
195 // set the name of the galice file
196 // the path is converted to an absolute one if it is relative
197
198   fGAliceFileName = fileName;
199   if (!gSystem->IsAbsoluteFileName(fGAliceFileName)) {
200     char* absFileName = gSystem->ConcatFileName(gSystem->WorkingDirectory(),
201                                                 fGAliceFileName);
202     fGAliceFileName = absFileName;
203     delete[] absFileName;
204   }
205 }
206
207 //_____________________________________________________________________________
208 void AliSimulation::MergeWith(const char* fileName, Int_t nSignalPerBkgrd)
209 {
210 // add a file with background events for merging
211
212   TObjString* fileNameStr = new TObjString(fileName);
213   fileNameStr->SetUniqueID(nSignalPerBkgrd);
214   if (!fBkgrdFileNames) fBkgrdFileNames = new TObjArray;
215   fBkgrdFileNames->Add(fileNameStr);
216 }
217
218
219 //_____________________________________________________________________________
220 Bool_t AliSimulation::Run(Int_t nEvents)
221 {
222 // run the generation, simulation and digitization
223
224   if (nEvents > 0) fNEvents = nEvents;
225
226   // generation and simulation -> hits
227   if (fRunGeneration) {
228     if (!RunSimulation()) if (fStopOnError) return kFALSE;
229   }
230
231   // hits -> summable digits
232   if (!fMakeSDigits.IsNull()) {
233     if (!RunSDigitization(fMakeSDigits)) if (fStopOnError) return kFALSE;
234   }
235
236   // summable digits -> digits
237   if (!fMakeDigits.IsNull()) {
238     if (!RunDigitization(fMakeDigits, fMakeDigitsFromHits)) {
239       if (fStopOnError) return kFALSE;
240     }
241   }
242
243   // hits -> digits
244   if (!fMakeDigitsFromHits.IsNull()) {
245     if (fBkgrdFileNames && (fBkgrdFileNames->GetEntriesFast() > 0)) {
246       Warning("Run", "Merging and direct creation of digits from hits " 
247               "was selected for some detectors. "
248               "No merging will be done for the following detectors: %s",
249               fMakeDigitsFromHits.Data());
250     }
251     if (!RunHitsDigitization(fMakeDigitsFromHits)) {
252       if (fStopOnError) return kFALSE;
253     }
254   }
255
256   // digits -> raw data
257   if (!fWriteRawData.IsNull()) {
258     if (!WriteRawData(fWriteRawData)) {
259       if (fStopOnError) return kFALSE;
260     }
261   }
262
263   return kTRUE;
264 }
265
266 //_____________________________________________________________________________
267 Bool_t AliSimulation::RunSimulation(Int_t nEvents)
268 {
269 // run the generation and simulation
270
271   TStopwatch stopwatch;
272   stopwatch.Start();
273
274   if (!gAlice) {
275     Error("RunSimulation", "no gAlice object. Restart aliroot and try again.");
276     return kFALSE;
277   }
278   if (gAlice->Modules()->GetEntries() > 0) {
279     Error("RunSimulation", 
280           "gAlice was already run. Restart aliroot and try again.");
281     return kFALSE;
282   }
283
284   Info("RunSimulation", "initializing gAlice with config file %s",
285        fConfigFileName.Data());
286   gAlice->Init(fConfigFileName.Data());
287   AliRunLoader* runLoader = gAlice->GetRunLoader();
288   if (!runLoader) {
289     Error("RunSimulation", "gAlice has no run loader object. "
290           "Check your config file: %s", fConfigFileName.Data());
291     return kFALSE;
292   }
293   SetGAliceFile(runLoader->GetFileName());
294
295   if (!gAlice->Generator()) {
296     Error("RunSimulation", "gAlice has no generator object. "
297           "Check your config file: %s", fConfigFileName.Data());
298     return kFALSE;
299   }
300   if (nEvents <= 0) nEvents = fNEvents;
301
302   // get vertex from background file in case of merging
303   if (fUseBkgrdVertex &&
304       fBkgrdFileNames && (fBkgrdFileNames->GetEntriesFast() > 0)) {
305     Int_t signalPerBkgrd = GetNSignalPerBkgrd(nEvents);
306     const char* fileName = ((TObjString*)
307                             (fBkgrdFileNames->At(0)))->GetName();
308     Info("RunSimulation", "The vertex will be taken from the background "
309          "file %s with nSignalPerBackground = %d", 
310          fileName, signalPerBkgrd);
311     AliVertexGenFile* vtxGen = new AliVertexGenFile(fileName, signalPerBkgrd);
312     gAlice->Generator()->SetVertexGenerator(vtxGen);
313   }
314
315   if (!fRunSimulation) {
316     gAlice->Generator()->SetTrackingFlag(0);
317   }
318
319   Info("RunSimulation", "running gAlice");
320   gAlice->Run(nEvents);
321
322   delete runLoader;
323
324   Info("RunSimulation", "execution time:");
325   stopwatch.Print();
326
327   return kTRUE;
328 }
329
330 //_____________________________________________________________________________
331 Bool_t AliSimulation::RunSDigitization(const char* detectors)
332 {
333 // run the digitization and produce summable digits
334
335   TStopwatch stopwatch;
336   stopwatch.Start();
337
338   AliRunLoader* runLoader = LoadRun();
339   if (!runLoader) return kFALSE;
340
341   TString detStr = detectors;
342   TObjArray* detArray = runLoader->GetAliRun()->Detectors();
343   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
344     AliModule* det = (AliModule*) detArray->At(iDet);
345     if (!det || !det->IsActive()) continue;
346     if (IsSelected(det->GetName(), detStr)) {
347       Info("RunSDigitization", "creating summable digits for %s", 
348            det->GetName());
349       TStopwatch stopwatchDet;
350       stopwatchDet.Start();
351       det->Hits2SDigits();
352       Info("RunSDigitization", "execution time for %s:", det->GetName());
353       stopwatchDet.Print();
354     }
355   }
356
357   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
358     Error("RunSDigitization", "the following detectors were not found: %s", 
359           detStr.Data());
360     if (fStopOnError) return kFALSE;
361   }
362
363   delete runLoader;
364
365   Info("RunSDigitization", "execution time:");
366   stopwatch.Print();
367
368   return kTRUE;
369 }
370
371
372 //_____________________________________________________________________________
373 Bool_t AliSimulation::RunDigitization(const char* detectors, 
374                                       const char* excludeDetectors)
375 {
376 // run the digitization and produce digits from sdigits
377
378   TStopwatch stopwatch;
379   stopwatch.Start();
380
381   while (AliRunLoader::GetRunLoader()) delete AliRunLoader::GetRunLoader();
382   if (gAlice) delete gAlice;
383   gAlice = NULL;
384
385   Int_t nStreams = 1;
386   if (fBkgrdFileNames) nStreams = fBkgrdFileNames->GetEntriesFast() + 1;
387   Int_t signalPerBkgrd = GetNSignalPerBkgrd();
388   AliRunDigitizer* manager = new AliRunDigitizer(nStreams, signalPerBkgrd);
389   manager->SetInputStream(0, fGAliceFileName.Data());
390   for (Int_t iStream = 1; iStream < nStreams; iStream++) {
391     const char* fileName = ((TObjString*)
392                             (fBkgrdFileNames->At(iStream-1)))->GetName();
393     manager->SetInputStream(iStream, fileName);
394   }
395
396   TString detStr = detectors;
397   TString detExcl = excludeDetectors;
398   manager->GetInputStream(0)->ImportgAlice();
399   AliRunLoader* runLoader = 
400     AliRunLoader::GetRunLoader(manager->GetInputStream(0)->GetFolderName());
401   TObjArray* detArray = runLoader->GetAliRun()->Detectors();
402   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
403     AliModule* det = (AliModule*) detArray->At(iDet);
404     if (!det || !det->IsActive()) continue;
405     if (IsSelected(det->GetName(), detStr) && 
406         !IsSelected(det->GetName(), detExcl)) {
407       AliDigitizer* digitizer = det->CreateDigitizer(manager);
408       if (!digitizer) {
409         Error("RunDigitization", "no digitizer for %s", det->GetName());
410         if (fStopOnError) return kFALSE;
411       } else {
412         digitizer->SetRegionOfInterest(fRegionOfInterest);
413       }
414     }
415   }
416
417   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
418     Error("RunDigitization", "the following detectors were not found: %s", 
419           detStr.Data());
420     if (fStopOnError) return kFALSE;
421   }
422
423   if (!manager->GetListOfTasks()->IsEmpty()) {
424     Info("RunDigitization", "executing digitization");
425     manager->Exec("");
426   }
427
428   delete manager;
429
430   Info("RunDigitization", "execution time:");
431   stopwatch.Print();
432
433   return kTRUE;
434 }
435
436 //_____________________________________________________________________________
437 Bool_t AliSimulation::RunHitsDigitization(const char* detectors)
438 {
439 // run the digitization and produce digits from hits
440
441   TStopwatch stopwatch;
442   stopwatch.Start();
443
444   AliRunLoader* runLoader = LoadRun();
445   if (!runLoader) return kFALSE;
446
447   TString detStr = detectors;
448   TObjArray* detArray = runLoader->GetAliRun()->Detectors();
449   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
450     AliModule* det = (AliModule*) detArray->At(iDet);
451     if (!det || !det->IsActive()) continue;
452     if (IsSelected(det->GetName(), detStr)) {
453       Info("RunHitsDigitization", "creating digits from hits for %s", 
454            det->GetName());
455       det->Hits2Digits();
456     }
457   }
458
459   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
460     Error("RunHitsDigitization", "the following detectors were not found: %s", 
461           detStr.Data());
462     if (fStopOnError) return kFALSE;
463   }
464
465   delete runLoader;
466
467   Info("RunHitsDigitization", "execution time:");
468   stopwatch.Print();
469
470   return kTRUE;
471 }
472
473 //_____________________________________________________________________________
474 Bool_t AliSimulation::WriteRawData(const char* detectors)
475 {
476 // convert the digits to raw data
477
478   TStopwatch stopwatch;
479   stopwatch.Start();
480
481   AliRunLoader* runLoader = LoadRun();
482   if (!runLoader) return kFALSE;
483
484   for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
485     Info("WriteRawData", "processing event %d", iEvent);
486     runLoader->GetEvent(iEvent);
487     TString baseDir = gSystem->WorkingDirectory();
488     char dirName[256];
489     sprintf(dirName, "raw%d", iEvent);
490     gSystem->MakeDirectory(dirName);
491     if (!gSystem->ChangeDirectory(dirName)) {
492       Error("WriteRawData", "couldn't change to directory %s", dirName);
493       if (fStopOnError) return kFALSE; else continue;
494     }
495
496     TString detStr = detectors;
497     TObjArray* detArray = runLoader->GetAliRun()->Detectors();
498     for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
499       AliModule* det = (AliModule*) detArray->At(iDet);
500       if (!det || !det->IsActive()) continue;
501       if (IsSelected(det->GetName(), detStr)) {
502         Info("WriteRawData", "creating raw data from digits for %s", 
503              det->GetName());
504         det->Digits2Raw();
505       }
506     }
507
508     gSystem->ChangeDirectory(baseDir);
509     if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
510       Error("WriteRawData", "the following detectors were not found: %s", 
511             detStr.Data());
512       if (fStopOnError) return kFALSE;
513     }
514   }
515
516   delete runLoader;
517
518   Info("WriteRawData", "execution time:");
519   stopwatch.Print();
520
521   return kTRUE;
522 }
523
524
525 //_____________________________________________________________________________
526 AliRunLoader* AliSimulation::LoadRun() const
527 {
528 // delete existing run loaders, open a new one and load gAlice
529
530   while (AliRunLoader::GetRunLoader()) delete AliRunLoader::GetRunLoader();
531   AliRunLoader* runLoader = 
532     AliRunLoader::Open(fGAliceFileName.Data(), 
533                        AliConfig::GetDefaultEventFolderName(), "UPDATE");
534   if (!runLoader) {
535     Error("LoadRun", "no run loader found in file %s", 
536           fGAliceFileName.Data());
537     return NULL;
538   }
539   runLoader->LoadgAlice();
540   gAlice = runLoader->GetAliRun();
541   if (!gAlice) {
542     Error("LoadRun", "no gAlice object found in file %s", 
543           fGAliceFileName.Data());
544     return NULL;
545   }
546   return runLoader;
547 }
548
549 //_____________________________________________________________________________
550 Int_t AliSimulation::GetNSignalPerBkgrd(Int_t nEvents) const
551 {
552 // get or calculate the number of signal events per background event
553
554   if (!fBkgrdFileNames) return 1;
555   Int_t nBkgrdFiles = fBkgrdFileNames->GetEntriesFast();
556   if (nBkgrdFiles == 0) return 1;
557
558   // get the number of signal events
559   if (nEvents <= 0) {
560     AliRunLoader* runLoader = 
561       AliRunLoader::Open(fGAliceFileName.Data(), "SIGNAL");
562     if (!runLoader) return 1;
563     nEvents = runLoader->GetNumberOfEvents();
564     delete runLoader;
565   }
566
567   Int_t result = 0;
568   for (Int_t iBkgrdFile = 0; iBkgrdFile < nBkgrdFiles; iBkgrdFile++) {
569     // get the number of background events
570     const char* fileName = ((TObjString*)
571                             (fBkgrdFileNames->At(iBkgrdFile)))->GetName();
572     AliRunLoader* runLoader = 
573       AliRunLoader::Open(fileName, "BKGRD");
574     if (!runLoader) continue;
575     Int_t nBkgrdEvents = runLoader->GetNumberOfEvents();
576     delete runLoader;
577
578     // get or calculate the number of signal per background events
579     Int_t nSignalPerBkgrd = fBkgrdFileNames->At(iBkgrdFile)->GetUniqueID();
580     if (nSignalPerBkgrd <= 0) {
581       nSignalPerBkgrd = (nEvents-1) / nBkgrdEvents + 1;
582     } else if (result && (result != nSignalPerBkgrd)) {
583       Info("GetNSignalPerBkgrd", "the number of signal events per "
584            "background event will be changed from %d to %d for stream %d", 
585            nSignalPerBkgrd, result, iBkgrdFile+1);
586       nSignalPerBkgrd = result;
587     }
588
589     if (!result) result = nSignalPerBkgrd;
590     if (nSignalPerBkgrd * nBkgrdEvents < nEvents) {
591       Warning("GetNSignalPerBkgrd", "not enough background events (%d) for "
592               "%d signal events using %d signal per background events for "
593               "stream %d", 
594               nBkgrdEvents, nEvents, nSignalPerBkgrd, iBkgrdFile+1);
595     }
596   }
597
598   return result;
599 }
600
601 //_____________________________________________________________________________
602 Bool_t AliSimulation::IsSelected(TString detName, TString& detectors) const
603 {
604 // check whether detName is contained in detectors
605 // if yes, it is removed from detectors
606
607   // check if all detectors are selected
608   if ((detectors.CompareTo("ALL") == 0) ||
609       detectors.BeginsWith("ALL ") ||
610       detectors.EndsWith(" ALL") ||
611       detectors.Contains(" ALL ")) {
612     detectors = "ALL";
613     return kTRUE;
614   }
615
616   // search for the given detector
617   Bool_t result = kFALSE;
618   if ((detectors.CompareTo(detName) == 0) ||
619       detectors.BeginsWith(detName+" ") ||
620       detectors.EndsWith(" "+detName) ||
621       detectors.Contains(" "+detName+" ")) {
622     detectors.ReplaceAll(detName, "");
623     result = kTRUE;
624   }
625
626   // clean up the detectors string
627   while (detectors.Contains("  ")) detectors.ReplaceAll("  ", " ");
628   while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
629   while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
630
631   return result;
632 }