]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - STEER/AliSimulation.cxx
ApplyDisplacements method renamed to ApplyAlignObjsToGeom. Automatic check of overlap...
[u/mrichter/AliRoot.git] / STEER / AliSimulation.cxx
... / ...
CommitLineData
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 default output format of the raw data are DDL files. They are //
80// converted to a DATE file, if a file name is given as second argument. //
81// For this conversion the program "dateStream" is required. If the file //
82// name has the extension ".root", the DATE file is converted to a root //
83// file. The program "alimdc" is used for this purpose. For the conversion //
84// to DATE and root format the two conversion programs have to be installed. //
85// Only the raw data in the final format is kept if the third argument is //
86// kTRUE. //
87// //
88// The methods RunSimulation, RunSDigitization, RunDigitization, //
89// RunHitsDigitization and WriteRawData can be used to run only parts of //
90// the full simulation chain. The creation of raw data DDL files and their //
91// conversion to the DATE or root format can be run directly by calling //
92// the methods WriteRawFiles, ConvertRawFilesToDate and ConvertDateToRoot. //
93// //
94// The default number of events per file, which is usually set in the //
95// config file, can be changed for individual detectors and data types //
96// by calling //
97// //
98// sim.SetEventsPerFile("PHOS", "Reconstructed Points", 3); //
99// //
100// The first argument is the detector, the second one the data type and the //
101// last one the number of events per file. Valid data types are "Hits", //
102// "Summable Digits", "Digits", "Reconstructed Points" and "Tracks". //
103// The number of events per file has to be set before the simulation of //
104// hits. Otherwise it has no effect. //
105// //
106///////////////////////////////////////////////////////////////////////////////
107
108#include <TGeoManager.h>
109#include <TObjString.h>
110#include <TStopwatch.h>
111#include <TSystem.h>
112#include <TFile.h>
113
114#include "AliCDBStorage.h"
115#include "AliCDBEntry.h"
116#include "AliCDBManager.h"
117#include "AliAlignObj.h"
118#include "AliCentralTrigger.h"
119#include "AliDAQConfig.h"
120#include "AliDigitizer.h"
121#include "AliGenerator.h"
122#include "AliLog.h"
123#include "AliModule.h"
124#include "AliRun.h"
125#include "AliRunDigitizer.h"
126#include "AliRunLoader.h"
127#include "AliSimulation.h"
128#include "AliVertexGenFile.h"
129#include "AliCentralTrigger.h"
130
131ClassImp(AliSimulation)
132
133
134//_____________________________________________________________________________
135AliSimulation::AliSimulation(const char* configFileName,
136 const char* name, const char* title) :
137 TNamed(name, title),
138
139 fRunGeneration(kTRUE),
140 fRunSimulation(kTRUE),
141 fMakeSDigits("ALL"),
142 fMakeDigits("ALL"),
143 fMakeTrigger(""),
144 fMakeDigitsFromHits(""),
145 fWriteRawData(""),
146 fRawDataFileName(""),
147 fDeleteIntermediateFiles(kFALSE),
148 fStopOnError(kFALSE),
149
150 fNEvents(1),
151 fConfigFileName(configFileName),
152 fGAliceFileName("galice.root"),
153 fEventsPerFile(),
154 fBkgrdFileNames(NULL),
155 fAlignObjArray(NULL),
156 fUseBkgrdVertex(kTRUE),
157 fRegionOfInterest(kFALSE)
158{
159// create simulation object with default parameters
160
161 SetGAliceFile("galice.root");
162}
163
164//_____________________________________________________________________________
165AliSimulation::AliSimulation(const AliSimulation& sim) :
166 TNamed(sim),
167
168 fRunGeneration(sim.fRunGeneration),
169 fRunSimulation(sim.fRunSimulation),
170 fMakeSDigits(sim.fMakeSDigits),
171 fMakeDigits(sim.fMakeDigits),
172 fMakeTrigger(sim.fMakeTrigger),
173 fMakeDigitsFromHits(sim.fMakeDigitsFromHits),
174 fWriteRawData(sim.fWriteRawData),
175 fRawDataFileName(""),
176 fDeleteIntermediateFiles(kFALSE),
177 fStopOnError(sim.fStopOnError),
178
179 fNEvents(sim.fNEvents),
180 fConfigFileName(sim.fConfigFileName),
181 fGAliceFileName(sim.fGAliceFileName),
182 fEventsPerFile(),
183 fBkgrdFileNames(NULL),
184 fAlignObjArray(NULL),
185 fUseBkgrdVertex(sim.fUseBkgrdVertex),
186 fRegionOfInterest(sim.fRegionOfInterest)
187{
188// copy constructor
189
190 for (Int_t i = 0; i < sim.fEventsPerFile.GetEntriesFast(); i++) {
191 if (!sim.fEventsPerFile[i]) continue;
192 fEventsPerFile.Add(sim.fEventsPerFile[i]->Clone());
193 }
194
195 fBkgrdFileNames = new TObjArray;
196 for (Int_t i = 0; i < sim.fBkgrdFileNames->GetEntriesFast(); i++) {
197 if (!sim.fBkgrdFileNames->At(i)) continue;
198 fBkgrdFileNames->Add(sim.fBkgrdFileNames->At(i)->Clone());
199 }
200}
201
202//_____________________________________________________________________________
203AliSimulation& AliSimulation::operator = (const AliSimulation& sim)
204{
205// assignment operator
206
207 this->~AliSimulation();
208 new(this) AliSimulation(sim);
209 return *this;
210}
211
212//_____________________________________________________________________________
213AliSimulation::~AliSimulation()
214{
215// clean up
216
217 fEventsPerFile.Delete();
218
219 if (fBkgrdFileNames) {
220 fBkgrdFileNames->Delete();
221 delete fBkgrdFileNames;
222 }
223}
224
225
226//_____________________________________________________________________________
227void AliSimulation::SetNumberOfEvents(Int_t nEvents)
228{
229// set the number of events for one run
230
231 fNEvents = nEvents;
232}
233
234//_____________________________________________________________________________
235void AliSimulation::SetConfigFile(const char* fileName)
236{
237// set the name of the config file
238
239 fConfigFileName = fileName;
240}
241
242//_____________________________________________________________________________
243void AliSimulation::SetGAliceFile(const char* fileName)
244{
245// set the name of the galice file
246// the path is converted to an absolute one if it is relative
247
248 fGAliceFileName = fileName;
249 if (!gSystem->IsAbsoluteFileName(fGAliceFileName)) {
250 char* absFileName = gSystem->ConcatFileName(gSystem->WorkingDirectory(),
251 fGAliceFileName);
252 fGAliceFileName = absFileName;
253 delete[] absFileName;
254 }
255
256 AliDebug(2, Form("galice file name set to %s", fileName));
257}
258
259//_____________________________________________________________________________
260void AliSimulation::SetEventsPerFile(const char* detector, const char* type,
261 Int_t nEvents)
262{
263// set the number of events per file for the given detector and data type
264// ("Hits", "Summable Digits", "Digits", "Reconstructed Points" or "Tracks")
265
266 TNamed* obj = new TNamed(detector, type);
267 obj->SetUniqueID(nEvents);
268 fEventsPerFile.Add(obj);
269}
270
271//_____________________________________________________________________________
272Bool_t AliSimulation::ApplyAlignObjsToGeom(const char* fileName, const char* clArrayName)
273{
274 // read collection of alignment objects (AliAlignObj derived) saved
275 // in the TClonesArray ClArrayName in the file fileName and apply
276 // them to the TGeo geometry passed as argument
277 //
278
279 TFile* inFile = TFile::Open(fileName,"READ");
280 if (!inFile || !inFile->IsOpen()) {
281 AliErrorClass(Form("Could not open file %s !",fileName));
282 return kFALSE;
283 }
284
285 TClonesArray* alObjArray = ((TClonesArray*) inFile->Get(clArrayName));
286 inFile->Close();
287 if (!alObjArray) {
288 AliErrorClass(Form("Could not get array (%s) from file (%s) !",clArrayName,fileName));
289 return kFALSE;
290 }
291
292 return gAlice->ApplyAlignObjsToGeom(alObjArray);
293
294}
295
296//_____________________________________________________________________________
297Bool_t AliSimulation::ApplyAlignObjsToGeom(AliCDBParam* param, AliCDBId& Id)
298{
299 // read collection of alignment objects (AliAlignObj derived) saved
300 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
301 // param (to get the AliCDBStorage) and Id; apply the alignment objects
302 // to the TGeo geometry passed as argument
303 //
304
305 AliCDBStorage* storage = AliCDBManager::Instance()->GetStorage(param);
306 AliCDBEntry* entry = storage->Get(Id);
307 TClonesArray* AlObjArray = ((TClonesArray*) entry->GetObject());
308
309 return gAlice->ApplyAlignObjsToGeom(AlObjArray);
310
311}
312
313//_____________________________________________________________________________
314Bool_t AliSimulation::ApplyAlignObjsToGeom(const char* uri, const char* path, Int_t runnum, Int_t version, Int_t sversion)
315{
316 // read collection of alignment objects (AliAlignObj derived) saved
317 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
318 // param (to get the AliCDBStorage) and Id; apply the alignment objects
319 // to the TGeo geometry passed as argument
320 //
321
322 AliCDBParam* param = AliCDBManager::Instance()->CreateParameter(uri);
323 AliCDBId id(path, runnum, runnum, version, sversion);
324
325 return ApplyAlignObjsToGeom(param, id);
326
327}
328
329//_____________________________________________________________________________
330void AliSimulation::MergeWith(const char* fileName, Int_t nSignalPerBkgrd)
331{
332// add a file with background events for merging
333
334 TObjString* fileNameStr = new TObjString(fileName);
335 fileNameStr->SetUniqueID(nSignalPerBkgrd);
336 if (!fBkgrdFileNames) fBkgrdFileNames = new TObjArray;
337 fBkgrdFileNames->Add(fileNameStr);
338}
339
340
341//_____________________________________________________________________________
342Bool_t AliSimulation::Run(Int_t nEvents)
343{
344// run the generation, simulation and digitization
345
346 // First check if we have any CDB storage set, because it is used
347 // to retrieve the calibration and alignment constants
348
349 AliCDBManager* man = AliCDBManager::Instance();
350 if (!man->IsDefaultStorageSet())
351 {
352 AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
353 AliWarning("No default CDB storage set, so I will use $ALICE_ROOT");
354 AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
355 man->SetDefaultStorage("local://$ALICE_ROOT");
356 }
357
358 if (nEvents > 0) fNEvents = nEvents;
359
360 // generation and simulation -> hits
361 if (fRunGeneration) {
362 if (!RunSimulation()) if (fStopOnError) return kFALSE;
363 }
364
365 // hits -> summable digits
366 if (!fMakeSDigits.IsNull()) {
367 if (!RunSDigitization(fMakeSDigits)) if (fStopOnError) return kFALSE;
368 }
369
370 // summable digits -> digits
371 if (!fMakeDigits.IsNull()) {
372 if (!RunDigitization(fMakeDigits, fMakeDigitsFromHits)) {
373 if (fStopOnError) return kFALSE;
374 }
375 }
376
377 // hits -> digits
378 if (!fMakeDigitsFromHits.IsNull()) {
379 if (fBkgrdFileNames && (fBkgrdFileNames->GetEntriesFast() > 0)) {
380 AliWarning(Form("Merging and direct creation of digits from hits "
381 "was selected for some detectors. "
382 "No merging will be done for the following detectors: %s",
383 fMakeDigitsFromHits.Data()));
384 }
385 if (!RunHitsDigitization(fMakeDigitsFromHits)) {
386 if (fStopOnError) return kFALSE;
387 }
388 }
389
390 // digits -> trigger
391 if (!fMakeTrigger.IsNull()) {
392 if (!RunTrigger(fMakeTrigger)) {
393 if (fStopOnError) return kFALSE;
394 }
395 }
396
397 // digits -> raw data
398 if (!fWriteRawData.IsNull()) {
399 if (!WriteRawData(fWriteRawData, fRawDataFileName,
400 fDeleteIntermediateFiles)) {
401 if (fStopOnError) return kFALSE;
402 }
403 }
404
405 return kTRUE;
406}
407
408//_____________________________________________________________________________
409Bool_t AliSimulation::RunTrigger(const char* descriptors)
410{
411 // run the trigger
412
413 TStopwatch stopwatch;
414 stopwatch.Start();
415
416 AliRunLoader* runLoader = LoadRun("READ");
417 if (!runLoader) return kFALSE;
418 TString des = descriptors;
419 // Load Descriptors
420 AliCentralTrigger* aCTP = new AliCentralTrigger( des );
421
422 // digits -> trigger
423 if( !aCTP->RunTrigger( runLoader ) ) {
424 if (fStopOnError) {
425 delete aCTP;
426 return kFALSE;
427 }
428 }
429
430/*
431 // Process each event
432 for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
433 AliInfo(Form("processing event %d", iEvent));
434 runLoader->GetEvent(iEvent);
435
436 TObjArray* detArray = runLoader->GetAliRun()->Detectors();
437 for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
438 AliModule* det = (AliModule*) detArray->At(iDet);
439 if (!det || !det->IsActive()) continue;
440 if (IsSelected(det->GetName(), detStr)) {
441 AliInfo(Form("triggering from digits for %s", det->GetName()));
442
443 // AliLoader* loader = fLoader[iDet];
444 // loader->LoadDigits("read");
445 // TTree* digitsTree = loader->TreeD();
446 // det->Trigger( digitsTree );
447 // or
448 AliTriggerDetector* tdet = det->CreateTriggerDetector();
449 TObjArray* detInp = dtrg->GetTriggerInputs();
450 for( Int_t i=0; i<detInp->GetEntriesFast(); i++ )
451 fInputs.AddLast( detInp->At(i) );
452
453 AliInfo(Form("Execution time for %s: R:%.2fs C:%.2fs",
454 det->GetName(),stopwatchDet.RealTime(),stopwatchDet.CpuTime()));
455 }
456 }
457
458 if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
459 AliError(Form("the following detectors were not found: %s",
460 detStr.Data()));
461 if (fStopOnError) {
462 delete centralTP;
463 return kFALSE;
464 }
465 }
466
467 // Check trigger conditions
468 centralTP->TriggerConditions();
469
470 // Write trigger ????
471 centralTP->Write();
472
473 } */
474
475 AliInfo(Form("Execution time: R:%.2fs C:%.2fs",
476 stopwatch.RealTime(),stopwatch.CpuTime()));
477
478 delete aCTP;
479 delete runLoader;
480
481 return kTRUE;
482}
483
484
485
486//_____________________________________________________________________________
487Bool_t AliSimulation::RunSimulation(Int_t nEvents)
488{
489// run the generation and simulation
490
491 TStopwatch stopwatch;
492 stopwatch.Start();
493
494 if (!gAlice) {
495 AliError("no gAlice object. Restart aliroot and try again.");
496 return kFALSE;
497 }
498 if (gAlice->Modules()->GetEntries() > 0) {
499 AliError("gAlice was already run. Restart aliroot and try again.");
500 return kFALSE;
501 }
502
503 AliInfo(Form("initializing gAlice with config file %s",
504 fConfigFileName.Data()));
505 StdoutToAliInfo(StderrToAliError(
506 gAlice->Init(fConfigFileName.Data());
507 ););
508
509 // Check if the array with alignment objects was
510 // provided by the user. If yes, apply the objects
511 // to the present TGeo geometry
512 if (fAlignObjArray) {
513 if (gGeoManager && gGeoManager->IsClosed()) {
514 if (gAlice->ApplyAlignObjsToGeom(fAlignObjArray) == kFALSE) {
515 AliError("The application of misalignment failed! Restart aliroot and try again. ");
516 return kFALSE;
517 }
518 }
519 else {
520 AliError("Can't apply the misalignment! gGeoManager doesn't exist or it is still opened!");
521 return kFALSE;
522 }
523 }
524
525 // Export TGeo geometry
526 if (gGeoManager) gGeoManager->Export("geometry.root");
527
528 AliRunLoader* runLoader = gAlice->GetRunLoader();
529 if (!runLoader) {
530 AliError(Form("gAlice has no run loader object. "
531 "Check your config file: %s", fConfigFileName.Data()));
532 return kFALSE;
533 }
534 SetGAliceFile(runLoader->GetFileName());
535
536 if (!gAlice->Generator()) {
537 AliError(Form("gAlice has no generator object. "
538 "Check your config file: %s", fConfigFileName.Data()));
539 return kFALSE;
540 }
541 if (nEvents <= 0) nEvents = fNEvents;
542
543 // get vertex from background file in case of merging
544 if (fUseBkgrdVertex &&
545 fBkgrdFileNames && (fBkgrdFileNames->GetEntriesFast() > 0)) {
546 Int_t signalPerBkgrd = GetNSignalPerBkgrd(nEvents);
547 const char* fileName = ((TObjString*)
548 (fBkgrdFileNames->At(0)))->GetName();
549 AliInfo(Form("The vertex will be taken from the background "
550 "file %s with nSignalPerBackground = %d",
551 fileName, signalPerBkgrd));
552 AliVertexGenFile* vtxGen = new AliVertexGenFile(fileName, signalPerBkgrd);
553 gAlice->Generator()->SetVertexGenerator(vtxGen);
554 }
555
556 if (!fRunSimulation) {
557 gAlice->Generator()->SetTrackingFlag(0);
558 }
559
560 // set the number of events per file for given detectors and data types
561 for (Int_t i = 0; i < fEventsPerFile.GetEntriesFast(); i++) {
562 if (!fEventsPerFile[i]) continue;
563 const char* detName = fEventsPerFile[i]->GetName();
564 const char* typeName = fEventsPerFile[i]->GetTitle();
565 TString loaderName(detName);
566 loaderName += "Loader";
567 AliLoader* loader = runLoader->GetLoader(loaderName);
568 if (!loader) {
569 AliError(Form("RunSimulation", "no loader for %s found\n"
570 "Number of events per file not set for %s %s",
571 detName, typeName, detName));
572 continue;
573 }
574 AliDataLoader* dataLoader =
575 loader->GetDataLoader(typeName);
576 if (!dataLoader) {
577 AliError(Form("no data loader for %s found\n"
578 "Number of events per file not set for %s %s",
579 typeName, detName, typeName));
580 continue;
581 }
582 dataLoader->SetNumberOfEventsPerFile(fEventsPerFile[i]->GetUniqueID());
583 AliDebug(1, Form("number of events per file set to %d for %s %s",
584 fEventsPerFile[i]->GetUniqueID(), detName, typeName));
585 }
586
587 AliInfo("running gAlice");
588 StdoutToAliInfo(StderrToAliError(
589 gAlice->Run(nEvents);
590 ););
591
592 delete runLoader;
593
594 AliInfo(Form("Execution time: R:%.2fs C:%.2fs",
595 stopwatch.RealTime(),stopwatch.CpuTime()));
596
597 return kTRUE;
598}
599
600//_____________________________________________________________________________
601Bool_t AliSimulation::RunSDigitization(const char* detectors)
602{
603// run the digitization and produce summable digits
604
605 TStopwatch stopwatch;
606 stopwatch.Start();
607
608 AliRunLoader* runLoader = LoadRun();
609 if (!runLoader) return kFALSE;
610
611 TString detStr = detectors;
612 TObjArray* detArray = runLoader->GetAliRun()->Detectors();
613 for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
614 AliModule* det = (AliModule*) detArray->At(iDet);
615 if (!det || !det->IsActive()) continue;
616 if (IsSelected(det->GetName(), detStr)) {
617 AliInfo(Form("creating summable digits for %s", det->GetName()));
618 TStopwatch stopwatchDet;
619 stopwatchDet.Start();
620 det->Hits2SDigits();
621 AliInfo(Form("Execution time for %s: R:%.2fs C:%.2fs",
622 det->GetName(),stopwatchDet.RealTime(),stopwatchDet.CpuTime()));
623 }
624 }
625
626 if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
627 AliError(Form("the following detectors were not found: %s",
628 detStr.Data()));
629 if (fStopOnError) return kFALSE;
630 }
631
632 delete runLoader;
633
634 AliInfo(Form("Execution time: R:%.2fs C:%.2fs",
635 stopwatch.RealTime(),stopwatch.CpuTime()));
636
637 return kTRUE;
638}
639
640
641//_____________________________________________________________________________
642Bool_t AliSimulation::RunDigitization(const char* detectors,
643 const char* excludeDetectors)
644{
645// run the digitization and produce digits from sdigits
646
647 TStopwatch stopwatch;
648 stopwatch.Start();
649
650 while (AliRunLoader::GetRunLoader()) delete AliRunLoader::GetRunLoader();
651 if (gAlice) delete gAlice;
652 gAlice = NULL;
653
654 Int_t nStreams = 1;
655 if (fBkgrdFileNames) nStreams = fBkgrdFileNames->GetEntriesFast() + 1;
656 Int_t signalPerBkgrd = GetNSignalPerBkgrd();
657 AliRunDigitizer* manager = new AliRunDigitizer(nStreams, signalPerBkgrd);
658 manager->SetInputStream(0, fGAliceFileName.Data());
659 for (Int_t iStream = 1; iStream < nStreams; iStream++) {
660 const char* fileName = ((TObjString*)
661 (fBkgrdFileNames->At(iStream-1)))->GetName();
662 manager->SetInputStream(iStream, fileName);
663 }
664
665 TString detStr = detectors;
666 TString detExcl = excludeDetectors;
667 manager->GetInputStream(0)->ImportgAlice();
668 AliRunLoader* runLoader =
669 AliRunLoader::GetRunLoader(manager->GetInputStream(0)->GetFolderName());
670 TObjArray* detArray = runLoader->GetAliRun()->Detectors();
671 for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
672 AliModule* det = (AliModule*) detArray->At(iDet);
673 if (!det || !det->IsActive()) continue;
674 if (IsSelected(det->GetName(), detStr) &&
675 !IsSelected(det->GetName(), detExcl)) {
676 AliDigitizer* digitizer = det->CreateDigitizer(manager);
677 if (!digitizer) {
678 AliError(Form("no digitizer for %s", det->GetName()));
679 if (fStopOnError) return kFALSE;
680 } else {
681 digitizer->SetRegionOfInterest(fRegionOfInterest);
682 }
683 }
684 }
685
686 if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
687 AliError(Form("the following detectors were not found: %s",
688 detStr.Data()));
689 if (fStopOnError) return kFALSE;
690 }
691
692 if (!manager->GetListOfTasks()->IsEmpty()) {
693 AliInfo("executing digitization");
694 manager->Exec("");
695 }
696
697 delete manager;
698
699 AliInfo(Form("Execution time: R:%.2fs C:%.2fs",
700 stopwatch.RealTime(),stopwatch.CpuTime()));
701
702 return kTRUE;
703}
704
705//_____________________________________________________________________________
706Bool_t AliSimulation::RunHitsDigitization(const char* detectors)
707{
708// run the digitization and produce digits from hits
709
710 TStopwatch stopwatch;
711 stopwatch.Start();
712
713 AliRunLoader* runLoader = LoadRun("READ");
714 if (!runLoader) return kFALSE;
715
716 TString detStr = detectors;
717 TObjArray* detArray = runLoader->GetAliRun()->Detectors();
718 for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
719 AliModule* det = (AliModule*) detArray->At(iDet);
720 if (!det || !det->IsActive()) continue;
721 if (IsSelected(det->GetName(), detStr)) {
722 AliInfo(Form("creating digits from hits for %s", det->GetName()));
723 det->Hits2Digits();
724 }
725 }
726
727 if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
728 AliError(Form("the following detectors were not found: %s",
729 detStr.Data()));
730 if (fStopOnError) return kFALSE;
731 }
732
733 delete runLoader;
734 //PH Temporary fix to avoid interference with the PHOS loder/getter
735 //PH The problem has to be solved in more general way 09/06/05
736
737 AliInfo(Form("Execution time: R:%.2fs C:%.2fs",
738 stopwatch.RealTime(),stopwatch.CpuTime()));
739
740 return kTRUE;
741}
742
743//_____________________________________________________________________________
744Bool_t AliSimulation::WriteRawData(const char* detectors,
745 const char* fileName,
746 Bool_t deleteIntermediateFiles)
747{
748// convert the digits to raw data
749// First DDL raw data files for the given detectors are created.
750// If a file name is given, the DDL files are then converted to a DATE file.
751// If deleteIntermediateFiles is true, the DDL raw files are deleted
752// afterwards.
753// If the file name has the extension ".root", the DATE file is converted
754// to a root file.
755// If deleteIntermediateFiles is true, the DATE file is deleted afterwards.
756
757 TStopwatch stopwatch;
758 stopwatch.Start();
759
760 if (!WriteRawFiles(detectors)) {
761 if (fStopOnError) return kFALSE;
762 }
763
764 TString dateFileName(fileName);
765 if (!dateFileName.IsNull()) {
766 Bool_t rootOutput = dateFileName.EndsWith(".root");
767 if (rootOutput) dateFileName += ".date";
768 if (!ConvertRawFilesToDate(dateFileName)) {
769 if (fStopOnError) return kFALSE;
770 }
771 if (deleteIntermediateFiles) {
772 AliRunLoader* runLoader = LoadRun("READ");
773 if (runLoader) for (Int_t iEvent = 0;
774 iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
775 char command[256];
776 sprintf(command, "rm -r raw%d", iEvent);
777 gSystem->Exec(command);
778 }
779 }
780
781 if (rootOutput) {
782 if (!ConvertDateToRoot(dateFileName, fileName)) {
783 if (fStopOnError) return kFALSE;
784 }
785 if (deleteIntermediateFiles) {
786 gSystem->Unlink(dateFileName);
787 }
788 }
789 }
790
791 AliInfo(Form("Execution time: R:%.2fs C:%.2fs",
792 stopwatch.RealTime(),stopwatch.CpuTime()));
793
794 return kTRUE;
795}
796
797//_____________________________________________________________________________
798Bool_t AliSimulation::WriteRawFiles(const char* detectors)
799{
800// convert the digits to raw data DDL files
801
802 AliRunLoader* runLoader = LoadRun("READ");
803 if (!runLoader) return kFALSE;
804
805 // write raw data to DDL files
806 for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
807 AliInfo(Form("processing event %d", iEvent));
808 runLoader->GetEvent(iEvent);
809 TString baseDir = gSystem->WorkingDirectory();
810 char dirName[256];
811 sprintf(dirName, "raw%d", iEvent);
812 gSystem->MakeDirectory(dirName);
813 if (!gSystem->ChangeDirectory(dirName)) {
814 AliError(Form("couldn't change to directory %s", dirName));
815 if (fStopOnError) return kFALSE; else continue;
816 }
817
818 TString detStr = detectors;
819 TObjArray* detArray = runLoader->GetAliRun()->Detectors();
820 for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
821 AliModule* det = (AliModule*) detArray->At(iDet);
822 if (!det || !det->IsActive()) continue;
823 if (IsSelected(det->GetName(), detStr)) {
824 AliInfo(Form("creating raw data from digits for %s", det->GetName()));
825 det->Digits2Raw();
826 }
827 }
828
829 gSystem->ChangeDirectory(baseDir);
830 if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
831 AliError(Form("the following detectors were not found: %s",
832 detStr.Data()));
833 if (fStopOnError) return kFALSE;
834 }
835 }
836
837 delete runLoader;
838 return kTRUE;
839}
840
841//_____________________________________________________________________________
842Bool_t AliSimulation::ConvertRawFilesToDate(const char* dateFileName)
843{
844// convert raw data DDL files to a DATE file with the program "dateStream"
845
846 char* path = gSystem->Which(gSystem->Getenv("PATH"), "dateStream");
847 if (!path) {
848 AliError("the program dateStream was not found");
849 if (fStopOnError) return kFALSE;
850 } else {
851 delete[] path;
852 }
853
854 AliRunLoader* runLoader = LoadRun("READ");
855 if (!runLoader) return kFALSE;
856
857 AliInfo(Form("converting raw data DDL files to DATE file %s", dateFileName));
858 char command[256];
859 sprintf(command, "dateStream -o %s -# %d -C",
860 dateFileName, runLoader->GetNumberOfEvents());
861 FILE* pipe = gSystem->OpenPipe(command, "w");
862
863 for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
864 fprintf(pipe, "GDC\n");
865 Float_t ldc = 0;
866 Int_t prevLDC = -1;
867
868 // loop over detectors and DDLs
869 for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
870 for (Int_t iDDL = 0; iDDL < kDetectorDDLs[iDet]; iDDL++) {
871
872 Int_t ddlID = 0x100*iDet + iDDL;
873 Int_t ldcID = Int_t(ldc + 0.0001);
874 ldc += kDetectorLDCs[iDet] / kDetectorDDLs[iDet];
875
876 char rawFileName[256];
877 sprintf(rawFileName, "raw%d/%s_%d.ddl",
878 iEvent, kDetectors[iDet], ddlID);
879
880 // check existence and size of raw data file
881 FILE* file = fopen(rawFileName, "rb");
882 if (!file) continue;
883 fseek(file, 0, SEEK_END);
884 unsigned long size = ftell(file);
885 fclose(file);
886 if (!size) continue;
887
888 if (ldcID != prevLDC) {
889 fprintf(pipe, " LDC Id %d\n", ldcID);
890 prevLDC = ldcID;
891 }
892 fprintf(pipe, " Equipment Id %d Payload %s\n", ddlID, rawFileName);
893 }
894 }
895 }
896
897 Int_t result = gSystem->ClosePipe(pipe);
898
899 delete runLoader;
900 return (result == 0);
901}
902
903//_____________________________________________________________________________
904Bool_t AliSimulation::ConvertDateToRoot(const char* dateFileName,
905 const char* rootFileName)
906{
907// convert a DATE file to a root file with the program "alimdc"
908
909 // ALIMDC setup
910 const Int_t kDBSize = 1000000000;
911 const Int_t kTagDBSize = 1000000000;
912 const Bool_t kFilter = kFALSE;
913 const Int_t kCompression = 1;
914
915 char* path = gSystem->Which(gSystem->Getenv("PATH"), "alimdc");
916 if (!path) {
917 AliError("the program alimdc was not found");
918 if (fStopOnError) return kFALSE;
919 } else {
920 delete[] path;
921 }
922
923 AliInfo(Form("converting DATE file %s to root file %s",
924 dateFileName, rootFileName));
925
926 gSystem->Exec("rm -rf /tmp/mdc1");
927 gSystem->Exec("rm -rf /tmp/mdc2");
928
929 gSystem->Exec("mkdir /tmp/mdc1");
930 gSystem->Exec("mkdir /tmp/mdc2");
931
932 char command[256];
933 sprintf(command, "alimdc %d %d %d %d %s",
934 kDBSize, kTagDBSize, kFilter, kCompression, dateFileName);
935 Int_t result = gSystem->Exec(command);
936 sprintf(command, "mv /tmp/mdc1/*.root %s", rootFileName);
937 gSystem->Exec(command);
938 gSystem->Exec("rm -rf /tmp/mdc1");
939 gSystem->Exec("rm -rf /tmp/mdc2");
940
941 return (result == 0);
942}
943
944
945//_____________________________________________________________________________
946AliRunLoader* AliSimulation::LoadRun(const char* mode) const
947{
948// delete existing run loaders, open a new one and load gAlice
949
950 while (AliRunLoader::GetRunLoader()) delete AliRunLoader::GetRunLoader();
951 AliRunLoader* runLoader =
952 AliRunLoader::Open(fGAliceFileName.Data(),
953 AliConfig::GetDefaultEventFolderName(), mode);
954 if (!runLoader) {
955 AliError(Form("no run loader found in file %s", fGAliceFileName.Data()));
956 return NULL;
957 }
958 runLoader->LoadgAlice();
959 gAlice = runLoader->GetAliRun();
960 if (!gAlice) {
961 AliError(Form("no gAlice object found in file %s",
962 fGAliceFileName.Data()));
963 return NULL;
964 }
965 return runLoader;
966}
967
968//_____________________________________________________________________________
969Int_t AliSimulation::GetNSignalPerBkgrd(Int_t nEvents) const
970{
971// get or calculate the number of signal events per background event
972
973 if (!fBkgrdFileNames) return 1;
974 Int_t nBkgrdFiles = fBkgrdFileNames->GetEntriesFast();
975 if (nBkgrdFiles == 0) return 1;
976
977 // get the number of signal events
978 if (nEvents <= 0) {
979 AliRunLoader* runLoader =
980 AliRunLoader::Open(fGAliceFileName.Data(), "SIGNAL");
981 if (!runLoader) return 1;
982 nEvents = runLoader->GetNumberOfEvents();
983 delete runLoader;
984 }
985
986 Int_t result = 0;
987 for (Int_t iBkgrdFile = 0; iBkgrdFile < nBkgrdFiles; iBkgrdFile++) {
988 // get the number of background events
989 const char* fileName = ((TObjString*)
990 (fBkgrdFileNames->At(iBkgrdFile)))->GetName();
991 AliRunLoader* runLoader =
992 AliRunLoader::Open(fileName, "BKGRD");
993 if (!runLoader) continue;
994 Int_t nBkgrdEvents = runLoader->GetNumberOfEvents();
995 delete runLoader;
996
997 // get or calculate the number of signal per background events
998 Int_t nSignalPerBkgrd = fBkgrdFileNames->At(iBkgrdFile)->GetUniqueID();
999 if (nSignalPerBkgrd <= 0) {
1000 nSignalPerBkgrd = (nEvents-1) / nBkgrdEvents + 1;
1001 } else if (result && (result != nSignalPerBkgrd)) {
1002 AliInfo(Form("the number of signal events per background event "
1003 "will be changed from %d to %d for stream %d",
1004 nSignalPerBkgrd, result, iBkgrdFile+1));
1005 nSignalPerBkgrd = result;
1006 }
1007
1008 if (!result) result = nSignalPerBkgrd;
1009 if (nSignalPerBkgrd * nBkgrdEvents < nEvents) {
1010 AliWarning(Form("not enough background events (%d) for %d signal events "
1011 "using %d signal per background events for stream %d",
1012 nBkgrdEvents, nEvents, nSignalPerBkgrd, iBkgrdFile+1));
1013 }
1014 }
1015
1016 return result;
1017}
1018
1019//_____________________________________________________________________________
1020Bool_t AliSimulation::IsSelected(TString detName, TString& detectors) const
1021{
1022// check whether detName is contained in detectors
1023// if yes, it is removed from detectors
1024
1025 // check if all detectors are selected
1026 if ((detectors.CompareTo("ALL") == 0) ||
1027 detectors.BeginsWith("ALL ") ||
1028 detectors.EndsWith(" ALL") ||
1029 detectors.Contains(" ALL ")) {
1030 detectors = "ALL";
1031 return kTRUE;
1032 }
1033
1034 // search for the given detector
1035 Bool_t result = kFALSE;
1036 if ((detectors.CompareTo(detName) == 0) ||
1037 detectors.BeginsWith(detName+" ") ||
1038 detectors.EndsWith(" "+detName) ||
1039 detectors.Contains(" "+detName+" ")) {
1040 detectors.ReplaceAll(detName, "");
1041 result = kTRUE;
1042 }
1043
1044 // clean up the detectors string
1045 while (detectors.Contains(" ")) detectors.ReplaceAll(" ", " ");
1046 while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
1047 while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
1048
1049 return result;
1050}