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