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