]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/STEER/AliSimulation.cxx
removing the first implementation of the CDB snapshot (initial loading into memory...
[u/mrichter/AliRoot.git] / STEER / 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 <TCint.h>
109 #include <TFile.h>
110 #include <TGeoGlobalMagField.h>
111 #include <TGeoManager.h>
112 #include <TObjString.h>
113 #include <TROOT.h>
114 #include <TSystem.h>
115 #include <TVirtualMC.h>
116 #include <TVirtualMCApplication.h>
117 #include <TDatime.h>
118
119 #include "AliAlignObj.h"
120 #include "AliCDBEntry.h"
121 #include "AliCDBManager.h"
122 #include "AliGRPManager.h"
123 #include "AliCDBStorage.h"
124 #include "AliCTPRawData.h"
125 #include "AliCentralTrigger.h"
126 #include "AliCentralTrigger.h"
127 #include "AliCodeTimer.h"
128 #include "AliDAQ.h"
129 #include "AliDigitizer.h"
130 #include "AliESDEvent.h"
131 #include "AliGRPObject.h"
132 #include "AliGenEventHeader.h"
133 #include "AliGenerator.h"
134 #include "AliGeomManager.h"
135 #include "AliHLTSimulation.h"
136 #include "AliHeader.h"
137 #include "AliLego.h"
138 #include "AliLegoGenerator.h"
139 #include "AliLog.h"
140 #include "AliMC.h"
141 #include "AliMagF.h"
142 #include "AliModule.h"
143 #include "AliPDG.h"
144 #include "AliRawReaderDate.h"
145 #include "AliRawReaderFile.h"
146 #include "AliRawReaderRoot.h"
147 #include "AliRun.h"
148 #include "AliDigitizationInput.h"
149 #include "AliRunLoader.h"
150 #include "AliSimulation.h"
151 #include "AliSysInfo.h"
152 #include "AliVertexGenFile.h"
153
154 ClassImp(AliSimulation)
155
156 AliSimulation *AliSimulation::fgInstance = 0;
157 const char* AliSimulation::fgkDetectorName[AliSimulation::fgkNDetectors] = {"ITS", "TPC", "TRD", "TOF", "PHOS", "HMPID", "EMCAL", "MUON", "FMD", "ZDC", "PMD", "T0", "VZERO", "ACORDE"
158 // #ifdef MFT_UPGRADE
159 //                                                                             ,"MFT"
160 // #endif 
161                                                                             ,"MFT"    // AU
162                                                                             ,"HLT"
163 };
164
165 //_____________________________________________________________________________
166 AliSimulation::AliSimulation(const char* configFileName,
167                              const char* name, const char* title) :
168   TNamed(name, title),
169
170   fRunGeneration(kTRUE),
171   fRunSimulation(kTRUE),
172   fLoadAlignFromCDB(kTRUE),
173   fLoadAlObjsListOfDets("ALL"),
174   fMakeSDigits("ALL"),
175   fMakeDigits("ALL"),
176   fTriggerConfig(""),
177   fMakeDigitsFromHits(""),
178   fWriteRawData(""),
179   fRawDataFileName(""),
180   fDeleteIntermediateFiles(kFALSE),
181   fWriteSelRawData(kFALSE),
182   fStopOnError(kFALSE),
183   fNEvents(1),
184   fConfigFileName(configFileName),
185   fGAliceFileName("galice.root"),
186   fEventsPerFile(),
187   fBkgrdFileNames(NULL),
188   fAlignObjArray(NULL),
189   fUseBkgrdVertex(kTRUE),
190   fRegionOfInterest(kFALSE),
191   fCDBUri(""),
192   fQARefUri(""), 
193   fSpecCDBUri(),
194   fRun(-1),
195   fSeed(0),
196   fInitCDBCalled(kFALSE),
197   fInitRunNumberCalled(kFALSE),
198   fSetRunNumberFromDataCalled(kFALSE),
199   fEmbeddingFlag(kFALSE),
200   fLego(NULL),
201   fKey(0),
202   fUseVertexFromCDB(0),
203   fUseMagFieldFromGRP(0),
204   fGRPWriteLocation(Form("local://%s", gSystem->pwd())),
205   fUseTimeStampFromCDB(0),
206   fTimeStart(0),
207   fTimeEnd(0),
208   fQADetectors("ALL"),                  
209   fQATasks("ALL"),      
210   fRunQA(kTRUE), 
211   fEventSpecie(AliRecoParam::kDefault),
212   fWriteQAExpertData(kTRUE), 
213   fGeometryFile(),
214   fRunHLT("default"),
215   fpHLT(NULL),
216   fWriteGRPEntry(kTRUE)
217 {
218 // create simulation object with default parameters
219   fgInstance = this;
220   SetGAliceFile("galice.root");
221   
222 // for QA
223         AliQAManager * qam = AliQAManager::QAManager(AliQAv1::kSIMMODE) ; 
224         qam->SetActiveDetectors(fQADetectors) ; 
225         fQATasks = Form("%d %d %d", AliQAv1::kHITS, AliQAv1::kSDIGITS, AliQAv1::kDIGITS) ; 
226         qam->SetTasks(fQATasks) ;       
227 }
228
229 //_____________________________________________________________________________
230 AliSimulation::~AliSimulation()
231 {
232 // clean up
233
234   fEventsPerFile.Delete();
235 //  if(fAlignObjArray) fAlignObjArray->Delete(); // fAlignObjArray->RemoveAll() ???
236 //  delete fAlignObjArray; fAlignObjArray=0;
237
238   if (fBkgrdFileNames) {
239     fBkgrdFileNames->Delete();
240     delete fBkgrdFileNames;
241   }
242
243   fSpecCDBUri.Delete();
244   if (fgInstance==this) fgInstance = 0;
245
246   AliQAManager::QAManager()->ShowQA() ; 
247   AliQAManager::Destroy() ;     
248   AliCodeTimer::Instance()->Print();
249 }
250
251
252 //_____________________________________________________________________________
253 void AliSimulation::SetNumberOfEvents(Int_t nEvents)
254 {
255 // set the number of events for one run
256
257   fNEvents = nEvents;
258 }
259
260 //_____________________________________________________________________________
261 void AliSimulation::InitQA()
262 {
263   // activate a default CDB storage
264   // First check if we have any CDB storage set, because it is used 
265   // to retrieve the calibration and alignment constants
266   
267   if (fInitCDBCalled) return;
268   fInitCDBCalled = kTRUE;
269
270   AliQAManager * qam = AliQAManager::QAManager(AliQAv1::kSIMMODE) ; 
271   qam->SetActiveDetectors(fQADetectors) ; 
272   fQATasks = Form("%d %d %d", AliQAv1::kHITS, AliQAv1::kSDIGITS, AliQAv1::kDIGITS) ; 
273   qam->SetTasks(fQATasks) ;
274         if (fWriteQAExpertData)
275     qam->SetWriteExpert() ; 
276   
277   if (qam->IsDefaultStorageSet()) {
278     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
279     AliWarning("Default QA reference storage has been already set !");
280     AliWarning(Form("Ignoring the default storage declared in AliSimulation: %s",fQARefUri.Data()));
281     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
282     fQARefUri = qam->GetDefaultStorage()->GetURI();
283   } else {
284       if (fQARefUri.Length() > 0) {
285         AliDebug(2,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
286         AliDebug(2, Form("Default QA reference storage is set to: %s", fQARefUri.Data()));
287         AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
288       } else {
289         fQARefUri="local://$ALICE_ROOT/QARef";
290         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
291         AliWarning("Default QA reference storage not yet set !!!!");
292         AliWarning(Form("Setting it now to: %s", fQARefUri.Data()));
293         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
294       }
295     qam->SetDefaultStorage(fQARefUri);
296   }
297 }
298
299 //_____________________________________________________________________________
300 void AliSimulation::InitCDB()
301 {
302 // activate a default CDB storage
303 // First check if we have any CDB storage set, because it is used 
304 // to retrieve the calibration and alignment constants
305
306   if (fInitCDBCalled) return;
307   fInitCDBCalled = kTRUE;
308
309   AliCDBManager* man = AliCDBManager::Instance();
310   if (man->IsDefaultStorageSet())
311   {
312     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
313     AliWarning("Default CDB storage has been already set !");
314     AliWarning(Form("Ignoring the default storage declared in AliSimulation: %s",fCDBUri.Data()));
315     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
316     fCDBUri = man->GetDefaultStorage()->GetURI();
317   }
318   else {
319     if (fCDBUri.Length() > 0) 
320     {
321         AliDebug(2,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
322         AliDebug(2, Form("Default CDB storage is set to: %s", fCDBUri.Data()));
323         AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
324     } else {
325         fCDBUri="local://$ALICE_ROOT/OCDB";
326         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
327         AliWarning("Default CDB storage not yet set !!!!");
328         AliWarning(Form("Setting it now to: %s", fCDBUri.Data()));
329         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
330                 
331     }
332     man->SetDefaultStorage(fCDBUri);
333   }
334
335   // Now activate the detector specific CDB storage locations
336   for (Int_t i = 0; i < fSpecCDBUri.GetEntriesFast(); i++) {
337     TObject* obj = fSpecCDBUri[i];
338     if (!obj) continue;
339     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
340     AliDebug(2, Form("Specific CDB storage for %s is set to: %s",obj->GetName(),obj->GetTitle()));
341     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
342     man->SetSpecificStorage(obj->GetName(), obj->GetTitle());
343   }
344       
345 }
346
347 //_____________________________________________________________________________
348 void AliSimulation::InitRunNumber(){
349 // check run number. If not set, set it to 0 !!!!
350   
351   if (fInitRunNumberCalled) return;
352   fInitRunNumberCalled = kTRUE;
353   
354   AliCDBManager* man = AliCDBManager::Instance();
355   if (man->GetRun() >= 0)
356   {
357         AliFatal(Form("Run number cannot be set in AliCDBManager before start of simulation: "
358                         "Use external variable DC_RUN or AliSimulation::SetRun()!"));
359   }
360     
361   if(fRun >= 0) {
362         AliDebug(2, Form("Setting CDB run number to: %d",fRun));
363   } else {
364         fRun=0;
365         AliWarning(Form("Run number not yet set !!!! Setting it now to: %d",
366                         fRun));
367   }
368   man->SetRun(fRun);
369
370   man->Print();
371
372 }
373
374 //_____________________________________________________________________________
375 void AliSimulation::SetCDBLock() {
376   // Set CDB lock: from now on it is forbidden to reset the run number
377   // or the default storage or to activate any further storage!
378   
379   ULong_t key = AliCDBManager::Instance()->SetLock(1);
380   if (key) fKey = key;
381 }
382
383 //_____________________________________________________________________________
384 void AliSimulation::SetDefaultStorage(const char* uri) {
385   // Store the desired default CDB storage location
386   // Activate it later within the Run() method
387   
388   fCDBUri = uri;
389   
390 }
391
392 //_____________________________________________________________________________
393 void AliSimulation::SetQARefDefaultStorage(const char* uri) {
394   // Store the desired default CDB storage location
395   // Activate it later within the Run() method
396   
397   fQARefUri = uri;
398   AliQAv1::SetQARefStorage(fQARefUri.Data()) ;
399 }
400
401 //_____________________________________________________________________________
402 void AliSimulation::SetSpecificStorage(const char* calibType, const char* uri) {
403 // Store a detector-specific CDB storage location
404 // Activate it later within the Run() method
405
406   AliCDBPath aPath(calibType);
407   if(!aPath.IsValid()){
408         AliError(Form("Not a valid path: %s", calibType));
409         return;
410   }
411
412   TObject* obj = fSpecCDBUri.FindObject(calibType);
413   if (obj) fSpecCDBUri.Remove(obj);
414   fSpecCDBUri.Add(new TNamed(calibType, uri));
415
416 }
417
418 //_____________________________________________________________________________
419 void AliSimulation::SetRunNumber(Int_t run)
420 {
421 // sets run number
422 // Activate it later within the Run() method
423
424         fRun = run;
425 }
426
427 //_____________________________________________________________________________
428 void AliSimulation::SetSeed(Int_t seed)
429 {
430 // sets seed number
431 // Activate it later within the Run() method
432
433         fSeed = seed;
434 }
435
436 //_____________________________________________________________________________
437 Bool_t AliSimulation::SetRunNumberFromData()
438 {
439   // Set the CDB manager run number
440   // The run number is retrieved from gAlice
441
442     if (fSetRunNumberFromDataCalled) return kTRUE;
443     fSetRunNumberFromDataCalled = kTRUE;    
444   
445     AliCDBManager* man = AliCDBManager::Instance();
446     Int_t runData = -1, runCDB = -1;
447   
448     AliRunLoader* runLoader = LoadRun("READ");
449     if (!runLoader) return kFALSE;
450     else {
451         runData = runLoader->GetHeader()->GetRun();
452         delete runLoader;
453     }
454   
455     runCDB = man->GetRun();
456     if(runCDB >= 0) {
457         if (runCDB != runData) {
458                 AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
459                 AliWarning(Form("A run number was previously set in AliCDBManager: %d !", runCDB));
460                 AliWarning(Form("It will be replaced with the run number got from run header: %d !", runData));
461                 AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");    
462         }
463         
464     }
465       
466     man->SetRun(runData);
467     fRun = runData;
468     
469     if(man->GetRun() < 0) {
470         AliError("Run number not properly initalized!");
471         return kFALSE;
472     }
473   
474     man->Print();
475     
476     return kTRUE;
477 }
478
479 //_____________________________________________________________________________
480 void AliSimulation::SetConfigFile(const char* fileName)
481 {
482 // set the name of the config file
483
484   fConfigFileName = fileName;
485 }
486
487 //_____________________________________________________________________________
488 void AliSimulation::SetGAliceFile(const char* fileName)
489 {
490 // set the name of the galice file
491 // the path is converted to an absolute one if it is relative
492
493   fGAliceFileName = fileName;
494   if (!gSystem->IsAbsoluteFileName(fGAliceFileName)) {
495     char* absFileName = gSystem->ConcatFileName(gSystem->WorkingDirectory(),
496                                                 fGAliceFileName);
497     fGAliceFileName = absFileName;
498     delete[] absFileName;
499   }
500
501   AliDebug(2, Form("galice file name set to %s", fileName));
502 }
503
504 //_____________________________________________________________________________
505 void AliSimulation::SetEventsPerFile(const char* detector, const char* type, 
506                                      Int_t nEvents)
507 {
508 // set the number of events per file for the given detector and data type
509 // ("Hits", "Summable Digits", "Digits", "Reconstructed Points" or "Tracks")
510
511   TNamed* obj = new TNamed(detector, type);
512   obj->SetUniqueID(nEvents);
513   fEventsPerFile.Add(obj);
514 }
515
516 //_____________________________________________________________________________
517 Bool_t AliSimulation::MisalignGeometry(AliRunLoader *runLoader)
518 {
519   // Read the alignment objects from CDB.
520   // Each detector is supposed to have the
521   // alignment objects in DET/Align/Data CDB path.
522   // All the detector objects are then collected,
523   // sorted by geometry level (starting from ALIC) and
524   // then applied to the TGeo geometry.
525   // Finally an overlaps check is performed.
526
527   if (!AliGeomManager::GetGeometry() || !AliGeomManager::GetGeometry()->IsClosed()) {
528     AliError("Can't apply the misalignment! Geometry is not loaded or it is still opened!");
529     return kFALSE;
530   }  
531   
532   // initialize CDB storage, run number, set CDB lock
533   InitCDB();
534 //  if (!SetRunNumberFromData()) if (fStopOnError) return kFALSE;
535   SetCDBLock();
536     
537   Bool_t delRunLoader = kFALSE;
538   if (!runLoader) {
539     runLoader = LoadRun("READ");
540     if (!runLoader) return kFALSE;
541     delRunLoader = kTRUE;
542   }
543   
544   // Export ideal geometry 
545   if(!IsGeometryFromFile()) AliGeomManager::GetGeometry()->Export("geometry.root");
546
547   // Load alignment data from CDB and apply to geometry through AliGeomManager
548   if(fLoadAlignFromCDB){
549     
550     TString detStr = fLoadAlObjsListOfDets;
551     TString loadAlObjsListOfDets = "";
552     
553     TObjArray* detArray = runLoader->GetAliRun()->Detectors();
554     for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
555       AliModule* det = (AliModule*) detArray->At(iDet);
556       if (!det || !det->IsActive()) continue;
557       if (IsSelected(det->GetName(), detStr)) {
558         //add det to list of dets to be aligned from CDB
559         loadAlObjsListOfDets += det->GetName();
560         loadAlObjsListOfDets += " ";
561       }
562     } // end loop over detectors
563     loadAlObjsListOfDets.Prepend("GRP "); //add alignment objects for non-sensitive modules
564     AliGeomManager::ApplyAlignObjsFromCDB(loadAlObjsListOfDets.Data());
565   }else{
566     // Check if the array with alignment objects was
567     // provided by the user. If yes, apply the objects
568     // to the present TGeo geometry
569     if (fAlignObjArray) {
570       if (AliGeomManager::ApplyAlignObjsToGeom(*fAlignObjArray) == kFALSE) {
571         AliError("The misalignment of one or more volumes failed!"
572                  "Compare the list of simulated detectors and the list of detector alignment data!");
573         if (delRunLoader) delete runLoader;
574         return kFALSE;
575       }
576     }
577   }
578
579   // Update the internal geometry of modules (ITS needs it)
580   TString detStr = fLoadAlObjsListOfDets;
581   TObjArray* detArray = runLoader->GetAliRun()->Detectors();
582   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
583
584     AliModule* det = (AliModule*) detArray->At(iDet);
585     if (!det || !det->IsActive()) continue;
586     if (IsSelected(det->GetName(), detStr)) {
587       det->UpdateInternalGeometry();
588     }
589   } // end loop over detectors
590
591
592   if (delRunLoader) delete runLoader;
593
594   return kTRUE;
595 }
596
597 //_____________________________________________________________________________
598 void AliSimulation::MergeWith(const char* fileName, Int_t nSignalPerBkgrd)
599 {
600 // add a file with background events for merging
601
602   TObjString* fileNameStr = new TObjString(fileName);
603   fileNameStr->SetUniqueID(nSignalPerBkgrd);
604   if (!fBkgrdFileNames) fBkgrdFileNames = new TObjArray;
605   fBkgrdFileNames->Add(fileNameStr);
606 }
607
608 void AliSimulation::EmbedInto(const char* fileName, Int_t nSignalPerBkgrd)
609 {
610 // add a file with background events for embeddin
611   MergeWith(fileName, nSignalPerBkgrd);
612   fEmbeddingFlag = kTRUE;
613 }
614
615 //_____________________________________________________________________________
616 Bool_t AliSimulation::Run(Int_t nEvents)
617 {
618 // run the generation, simulation and digitization
619
620  
621   AliCodeTimerAuto("",0)
622   AliSysInfo::AddStamp("Start_Run");
623   
624   // Load run number and seed from environmental vars
625   ProcessEnvironmentVars();
626   AliSysInfo::AddStamp("ProcessEnvironmentVars");
627
628   gRandom->SetSeed(fSeed);
629    
630   if (nEvents > 0) fNEvents = nEvents;
631
632   // create and setup the HLT instance
633   if (!fRunHLT.IsNull() && !CreateHLT()) {
634     if (fStopOnError) return kFALSE;
635     // disable HLT
636     fRunHLT="";
637   }
638   
639   // generation and simulation -> hits
640   if (fRunGeneration) {
641     if (!RunSimulation()) if (fStopOnError) return kFALSE;
642   }
643   AliSysInfo::AddStamp("RunSimulation");
644            
645   // initialize CDB storage from external environment
646   // (either CDB manager or AliSimulation setters),
647   // if not already done in RunSimulation()
648   InitCDB();
649   AliSysInfo::AddStamp("InitCDB");
650   
651   // Set run number in CDBManager from data 
652   // From this point on the run number must be always loaded from data!
653   if (!SetRunNumberFromData()) if (fStopOnError) return kFALSE;
654   
655   // Set CDB lock: from now on it is forbidden to reset the run number
656   // or the default storage or to activate any further storage!
657   SetCDBLock();
658
659   // If RunSimulation was not called, load the geometry and misalign it
660   if (!AliGeomManager::GetGeometry()) {
661     // Initialize the geometry manager
662     AliGeomManager::LoadGeometry("geometry.root");
663     AliSysInfo::AddStamp("GetGeometry");
664 //    // Check that the consistency of symbolic names for the activated subdetectors
665 //    // in the geometry loaded by AliGeomManager
666 //    AliRunLoader* runLoader = LoadRun("READ");
667 //    if (!runLoader) return kFALSE;
668 //
669 //    TString detsToBeChecked = "";
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 //      detsToBeChecked += det->GetName();
675 //      detsToBeChecked += " ";
676 //    } // end loop over detectors
677 //    if(!AliGeomManager::CheckSymNamesLUT(detsToBeChecked.Data()))
678     if(!AliGeomManager::CheckSymNamesLUT("ALL"))
679         AliFatalClass("Current loaded geometry differs in the definition of symbolic names!");
680         
681     if (!AliGeomManager::GetGeometry()) if (fStopOnError) return kFALSE;
682     // Misalign geometry
683     if(!MisalignGeometry()) if (fStopOnError) return kFALSE;
684   }
685   AliSysInfo::AddStamp("MissalignGeometry");
686
687
688   // hits -> summable digits
689   AliSysInfo::AddStamp("Start_sdigitization");
690   if (!fMakeSDigits.IsNull()) {
691     if (!RunSDigitization(fMakeSDigits)) if (fStopOnError) return kFALSE;
692  
693   }
694   AliSysInfo::AddStamp("Stop_sdigitization");
695   
696   AliSysInfo::AddStamp("Start_digitization");  
697   // summable digits -> digits  
698   if (!fMakeDigits.IsNull()) {
699     if (!RunDigitization(fMakeDigits, fMakeDigitsFromHits)) {
700       if (fStopOnError) return kFALSE;
701     }
702    }
703   AliSysInfo::AddStamp("Stop_digitization");
704
705   
706   
707   // hits -> digits
708   if (!fMakeDigitsFromHits.IsNull()) {
709     if (fBkgrdFileNames && (fBkgrdFileNames->GetEntriesFast() > 0)) {
710       AliWarning(Form("Merging and direct creation of digits from hits " 
711                  "was selected for some detectors. "
712                  "No merging will be done for the following detectors: %s",
713                  fMakeDigitsFromHits.Data()));
714     }
715     if (!RunHitsDigitization(fMakeDigitsFromHits)) {
716       if (fStopOnError) return kFALSE;
717     }
718   }
719
720   AliSysInfo::AddStamp("Hits2Digits");
721   
722   
723   // digits -> trigger
724   if (!fTriggerConfig.IsNull() && !RunTrigger(fTriggerConfig,fMakeDigits)) {
725     if (fStopOnError) return kFALSE;
726   }
727
728   AliSysInfo::AddStamp("RunTrigger");
729   
730   
731   // digits -> raw data
732   if (!fWriteRawData.IsNull()) {
733     if (!WriteRawData(fWriteRawData, fRawDataFileName, 
734                       fDeleteIntermediateFiles,fWriteSelRawData)) {
735       if (fStopOnError) return kFALSE;
736     }
737   }
738
739   AliSysInfo::AddStamp("WriteRaw");
740   
741   // run HLT simulation on simulated digit data if raw data is not
742   // simulated, otherwise its called as part of WriteRawData
743   if (!fRunHLT.IsNull() && fWriteRawData.IsNull()) {
744     if (!RunHLT()) {
745       if (fStopOnError) return kFALSE;
746     }
747   }
748
749   AliSysInfo::AddStamp("RunHLT");
750   
751   //QA
752   if (fRunQA) {
753       Bool_t rv = RunQA() ; 
754       if (!rv)
755           if (fStopOnError) 
756               return kFALSE ;
757   }
758
759   AliSysInfo::AddStamp("RunQA");
760
761   TString snapshotFileOut("");
762   if(TString(gSystem->Getenv("OCDB_SNAPSHOT_CREATE")) == TString("kTRUE")){ 
763       AliInfo(" ******** Creating the snapshot! *********");
764       TString snapshotFile(gSystem->Getenv("OCDB_SNAPSHOT_FILENAME")); 
765       if(!(snapshotFile.IsNull() || snapshotFile.IsWhitespace())) 
766           snapshotFileOut = snapshotFile;
767       else 
768           snapshotFileOut="OCDB.root"; 
769       AliCDBManager::Instance()->DumpToSnapshotFile(snapshotFileOut.Data(),kFALSE); 
770   }
771
772   // Cleanup of CDB manager: cache and active storages!
773   AliCDBManager::Instance()->ClearCache();
774
775   return kTRUE;
776 }
777
778 //_______________________________________________________________________
779 Bool_t AliSimulation::RunLego(const char *setup, Int_t nc1, Float_t c1min,
780                      Float_t c1max,Int_t nc2,Float_t c2min,Float_t c2max,
781                      Float_t rmin,Float_t rmax,Float_t zmax, AliLegoGenerator* gener, Int_t nev)
782 {
783   //
784   // Generates lego plots of:
785   //    - radiation length map phi vs theta
786   //    - radiation length map phi vs eta
787   //    - interaction length map
788   //    - g/cm2 length map
789   //
790   //  ntheta    bins in theta, eta
791   //  themin    minimum angle in theta (degrees)
792   //  themax    maximum angle in theta (degrees)
793   //  nphi      bins in phi
794   //  phimin    minimum angle in phi (degrees)
795   //  phimax    maximum angle in phi (degrees)
796   //  rmin      minimum radius
797   //  rmax      maximum radius
798   //  
799   //
800   //  The number of events generated = ntheta*nphi
801   //  run input parameters in macro setup (default="Config.C")
802   //
803   //  Use macro "lego.C" to visualize the 3 lego plots in spherical coordinates
804   //Begin_Html
805   /*
806     <img src="picts/AliRunLego1.gif">
807   */
808   //End_Html
809   //Begin_Html
810   /*
811     <img src="picts/AliRunLego2.gif">
812   */
813   //End_Html
814   //Begin_Html
815   /*
816     <img src="picts/AliRunLego3.gif">
817   */
818   //End_Html
819   //
820
821 // run the generation and simulation
822
823   AliCodeTimerAuto("",0)
824
825   // initialize CDB storage and run number from external environment
826   // (either CDB manager or AliSimulation setters)
827   InitCDB();
828   InitRunNumber();
829   SetCDBLock();
830   
831   if (!gAlice) {
832     AliError("no gAlice object. Restart aliroot and try again.");
833     return kFALSE;
834   }
835   if (gAlice->Modules()->GetEntries() > 0) {
836     AliError("gAlice was already run. Restart aliroot and try again.");
837     return kFALSE;
838   }
839
840   AliInfo(Form("initializing gAlice with config file %s",
841           fConfigFileName.Data()));
842
843   // Number of events 
844     if (nev == -1) nev  = nc1 * nc2;
845     
846   // check if initialisation has been done
847   // If runloader has been initialized, set the number of events per file to nc1 * nc2
848     
849   // Set new generator
850   if (!gener) gener  = new AliLegoGenerator();
851   //
852   // Configure Generator
853
854   gener->SetRadiusRange(rmin, rmax);
855   gener->SetZMax(zmax);
856   gener->SetCoor1Range(nc1, c1min, c1max);
857   gener->SetCoor2Range(nc2, c2min, c2max);
858   
859   
860   //Create Lego object  
861   fLego = new AliLego("lego",gener);
862
863   //__________________________________________________________________________
864
865   gAlice->Announce();
866
867   gROOT->LoadMacro(setup);
868   gInterpreter->ProcessLine(gAlice->GetConfigFunction());
869
870   if(AliCDBManager::Instance()->GetRun() >= 0) { 
871     SetRunNumber(AliCDBManager::Instance()->GetRun());
872   } else {
873     AliWarning("Run number not initialized!!");
874   }
875
876   AliRunLoader::Instance()->CdGAFile();
877   
878   AliPDG::AddParticlesToPdgDataBase();  
879   
880   gMC->SetMagField(TGeoGlobalMagField::Instance()->GetField());
881
882   gAlice->GetMCApp()->Init();
883   
884   
885   //Must be here because some MCs (G4) adds detectors here and not in Config.C
886   gAlice->InitLoaders();
887   AliRunLoader::Instance()->MakeTree("E");
888   
889   //
890   // Save stuff at the beginning of the file to avoid file corruption
891   AliRunLoader::Instance()->CdGAFile();
892   gAlice->Write();
893
894   //Save current generator
895   AliGenerator *gen=gAlice->GetMCApp()->Generator();
896   gAlice->GetMCApp()->ResetGenerator(gener);
897   //Prepare MC for Lego Run
898   gMC->InitLego();
899   
900   //Run Lego Object
901   
902   
903   AliRunLoader::Instance()->SetNumberOfEventsPerFile(nev);
904   gMC->ProcessRun(nev);
905   
906   // End of this run, close files
907   FinishRun();
908   // Restore current generator
909   gAlice->GetMCApp()->ResetGenerator(gen);
910   // Delete Lego Object
911   delete fLego;
912
913   return kTRUE;
914 }
915
916 //_____________________________________________________________________________
917 Bool_t AliSimulation::RunTrigger(const char* config, const char* detectors)
918 {
919   // run the trigger
920
921   AliCodeTimerAuto("",0)
922
923   // initialize CDB storage from external environment
924   // (either CDB manager or AliSimulation setters),
925   // if not already done in RunSimulation()
926   InitCDB();
927   
928   // Set run number in CDBManager from data 
929   // From this point on the run number must be always loaded from data!
930   if (!SetRunNumberFromData()) if (fStopOnError) return kFALSE;
931   
932   // Set CDB lock: from now on it is forbidden to reset the run number
933   // or the default storage or to activate any further storage!
934   SetCDBLock();
935    
936    AliRunLoader* runLoader = LoadRun("READ");
937    if (!runLoader) return kFALSE;
938    TString trconfiguration = config;
939
940    if (trconfiguration.IsNull()) {
941      if(!fTriggerConfig.IsNull()) {
942        trconfiguration = fTriggerConfig;
943      }
944      else
945        AliWarning("No trigger descriptor is specified. Loading the one that is in the CDB.");
946    }
947
948    runLoader->MakeTree( "GG" );
949    AliCentralTrigger* aCTP = runLoader->GetTrigger();
950    // Load Configuration
951    if (!aCTP->LoadConfiguration( trconfiguration ))
952      return kFALSE;
953
954    // digits -> trigger
955    if( !aCTP->RunTrigger( runLoader , detectors ) ) {
956       if (fStopOnError) {
957         //  delete aCTP;
958         return kFALSE;
959       }
960    }
961
962    delete runLoader;
963
964    return kTRUE;
965 }
966
967 //_____________________________________________________________________________
968 Bool_t AliSimulation::WriteTriggerRawData()
969 {
970   // Writes the CTP (trigger) DDL raw data
971   // Details of the format are given in the
972   // trigger TDR - pages 134 and 135.
973   AliCTPRawData writer;
974   writer.RawData();
975
976   return kTRUE;
977 }
978
979 //_____________________________________________________________________________
980 Bool_t AliSimulation::RunSimulation(Int_t nEvents)
981 {
982 // run the generation and simulation
983
984   AliCodeTimerAuto("",0)
985
986   // initialize CDB storage and run number from external environment
987   // (either CDB manager or AliSimulation setters)
988   AliSysInfo::AddStamp("RunSimulation_Begin");
989   InitCDB();
990   AliSysInfo::AddStamp("RunSimulation_InitCDB");
991   InitRunNumber();
992
993   SetCDBLock();
994   AliSysInfo::AddStamp("RunSimulation_SetCDBLock");
995   
996   if (!gAlice) {
997     AliError("no gAlice object. Restart aliroot and try again.");
998     return kFALSE;
999   }
1000   if (gAlice->Modules()->GetEntries() > 0) {
1001     AliError("gAlice was already run. Restart aliroot and try again.");
1002     return kFALSE;
1003   }
1004
1005   AliInfo(Form("initializing gAlice with config file %s",
1006           fConfigFileName.Data()));
1007
1008   //
1009   // Initialize ALICE Simulation run
1010   //
1011   gAlice->Announce();
1012
1013   //
1014   // If requested set the mag. field from the GRP entry.
1015   // After this the field is loccked and cannot be changed by Config.C
1016   if (fUseMagFieldFromGRP) {
1017       AliGRPManager grpM;
1018       grpM.ReadGRPEntry();
1019       grpM.SetMagField();
1020       AliInfo("Field is locked now. It cannot be changed in Config.C");
1021   }
1022 //
1023 // Execute Config.C
1024   gROOT->LoadMacro(fConfigFileName.Data());
1025   gInterpreter->ProcessLine(gAlice->GetConfigFunction());
1026   AliSysInfo::AddStamp("RunSimulation_Config");
1027
1028 //
1029 // If requested obtain the vertex position and vertex sigma_z from the CDB
1030 // This overwrites the settings from the Config.C  
1031   if (fUseVertexFromCDB) {
1032       Double_t vtxPos[3] = {0., 0., 0.}; 
1033       Double_t vtxSig[3] = {0., 0., 0.};
1034       AliCDBEntry* entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertex");
1035       if (entry) {
1036           AliESDVertex* vertex = dynamic_cast<AliESDVertex*> (entry->GetObject());
1037           if (vertex) {
1038               if(vertex->GetXRes()>2.8) { // > pipe radius --> it's a dummy object, don't use it 
1039                   entry = AliCDBManager::Instance()->Get("GRP/Calib/MeanVertexSPD");
1040                   if (entry) vertex = dynamic_cast<AliESDVertex*> (entry->GetObject());
1041               }
1042           }
1043           if (vertex) {
1044               vertex->GetXYZ(vtxPos);
1045               vertex->GetSigmaXYZ(vtxSig);
1046               AliInfo("Overwriting Config.C vertex settings !");
1047               AliInfo(Form("Vertex position from OCDB entry: x = %13.3f, y = %13.3f, z = %13.3f (sigma = %13.3f)\n",
1048                            vtxPos[0], vtxPos[1], vtxPos[2], vtxSig[2]));
1049               
1050               AliGenerator *gen = gAlice->GetMCApp()->Generator();
1051               gen->SetOrigin(vtxPos[0], vtxPos[1], vtxPos[2]);   // vertex position
1052               gen->SetSigmaZ(vtxSig[2]);
1053           }
1054       }
1055   }
1056
1057   // If requested we take the SOR and EOR time-stamps from the GRP and use them
1058   // in order to generate the event time-stamps
1059   if (fUseTimeStampFromCDB) {
1060     AliGRPManager grpM;
1061     grpM.ReadGRPEntry();
1062     const AliGRPObject *grpObj = grpM.GetGRPData();
1063     if (!grpObj || (grpObj->GetTimeEnd() <= grpObj->GetTimeStart())) {
1064       AliError("Missing GRP or bad SOR/EOR time-stamps! Switching off the time-stamp generation from GRP!");
1065       fTimeStart = fTimeEnd = 0;
1066       fUseTimeStampFromCDB = kFALSE;
1067     }
1068     else {
1069       fTimeStart = grpObj->GetTimeStart();
1070       fTimeEnd = grpObj->GetTimeEnd();
1071     }
1072   }
1073   
1074   if(AliCDBManager::Instance()->GetRun() >= 0) { 
1075     AliRunLoader::Instance()->SetRunNumber(AliCDBManager::Instance()->GetRun());
1076     AliRunLoader::Instance()->SetNumberOfEventsPerRun(fNEvents);
1077   } else {
1078         AliWarning("Run number not initialized!!");
1079   }
1080   
1081    AliRunLoader::Instance()->CdGAFile();
1082    
1083
1084    AliPDG::AddParticlesToPdgDataBase();  
1085
1086    gMC->SetMagField(TGeoGlobalMagField::Instance()->GetField());
1087    AliSysInfo::AddStamp("RunSimulation_GetField");
1088    
1089    gAlice->GetMCApp()->Init();
1090    AliSysInfo::AddStamp("RunSimulation_InitMCApp");
1091
1092    //Must be here because some MCs (G4) adds detectors here and not in Config.C
1093    gAlice->InitLoaders();
1094    AliRunLoader::Instance()->MakeTree("E");
1095    AliRunLoader::Instance()->LoadKinematics("RECREATE");
1096    AliRunLoader::Instance()->LoadTrackRefs("RECREATE");
1097    AliRunLoader::Instance()->LoadHits("all","RECREATE");
1098    //
1099    // Save stuff at the beginning of the file to avoid file corruption
1100    AliRunLoader::Instance()->CdGAFile();
1101    gAlice->Write();
1102    gAlice->SetEventNrInRun(-1); //important - we start Begin event from increasing current number in run
1103    AliSysInfo::AddStamp("RunSimulation_InitLoaders");
1104   //___________________________________________________________________________________________
1105   
1106   AliSysInfo::AddStamp("RunSimulation_TriggerDescriptor");
1107
1108   // Set run number in CDBManager
1109   AliInfo(Form("Run number: %d",AliCDBManager::Instance()->GetRun()));
1110
1111   AliRunLoader* runLoader = AliRunLoader::Instance();
1112   if (!runLoader) {
1113              AliError(Form("gAlice has no run loader object. "
1114                              "Check your config file: %s", fConfigFileName.Data()));
1115              return kFALSE;
1116   }
1117   SetGAliceFile(runLoader->GetFileName());
1118       
1119   // Misalign geometry
1120 #if ROOT_VERSION_CODE < 331527
1121   AliGeomManager::SetGeometry(gGeoManager);
1122   
1123   // Check that the consistency of symbolic names for the activated subdetectors
1124   // in the geometry loaded by AliGeomManager
1125   TString detsToBeChecked = "";
1126   TObjArray* detArray = runLoader->GetAliRun()->Detectors();
1127   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
1128     AliModule* det = (AliModule*) detArray->At(iDet);
1129     if (!det || !det->IsActive()) continue;
1130     detsToBeChecked += det->GetName();
1131     detsToBeChecked += " ";
1132   } // end loop over detectors
1133   if(!AliGeomManager::CheckSymNamesLUT(detsToBeChecked.Data()))
1134     AliFatalClass("Current loaded geometry differs in the definition of symbolic names!");
1135   MisalignGeometry(runLoader);
1136   AliSysInfo::AddStamp("RunSimulation_MisalignGeometry");
1137 #endif
1138
1139 //   AliRunLoader* runLoader = AliRunLoader::Instance();
1140 //   if (!runLoader) {
1141 //     AliError(Form("gAlice has no run loader object. "
1142 //                   "Check your config file: %s", fConfigFileName.Data()));
1143 //     return kFALSE;
1144 //   }
1145 //   SetGAliceFile(runLoader->GetFileName());
1146
1147   if (!gAlice->GetMCApp()->Generator()) {
1148     AliError(Form("gAlice has no generator object. "
1149                   "Check your config file: %s", fConfigFileName.Data()));
1150     return kFALSE;
1151   }
1152
1153   // Write GRP entry corresponding to the setting found in Cofig.C
1154   if (fWriteGRPEntry)
1155     WriteGRPEntry();
1156   AliSysInfo::AddStamp("RunSimulation_WriteGRP");
1157
1158   if (nEvents <= 0) nEvents = fNEvents;
1159
1160   // get vertex from background file in case of merging
1161   if (fUseBkgrdVertex &&
1162       fBkgrdFileNames && (fBkgrdFileNames->GetEntriesFast() > 0)) {
1163     Int_t signalPerBkgrd = GetNSignalPerBkgrd(nEvents);
1164     const char* fileName = ((TObjString*)
1165                             (fBkgrdFileNames->At(0)))->GetName();
1166     AliInfo(Form("The vertex will be taken from the background "
1167                  "file %s with nSignalPerBackground = %d", 
1168                  fileName, signalPerBkgrd));
1169     AliVertexGenFile* vtxGen = new AliVertexGenFile(fileName, signalPerBkgrd);
1170     gAlice->GetMCApp()->Generator()->SetVertexGenerator(vtxGen);
1171   }
1172
1173   if (!fRunSimulation) {
1174     gAlice->GetMCApp()->Generator()->SetTrackingFlag(0);
1175   }
1176
1177   // set the number of events per file for given detectors and data types
1178   for (Int_t i = 0; i < fEventsPerFile.GetEntriesFast(); i++) {
1179     if (!fEventsPerFile[i]) continue;
1180     const char* detName = fEventsPerFile[i]->GetName();
1181     const char* typeName = fEventsPerFile[i]->GetTitle();
1182     TString loaderName(detName);
1183     loaderName += "Loader";
1184     AliLoader* loader = runLoader->GetLoader(loaderName);
1185     if (!loader) {
1186       AliError(Form("RunSimulation no loader for %s found\n Number of events per file not set for %s %s", 
1187                     detName, typeName, detName));
1188       continue;
1189     }
1190     AliDataLoader* dataLoader = 
1191       loader->GetDataLoader(typeName);
1192     if (!dataLoader) {
1193       AliError(Form("no data loader for %s found\n"
1194                     "Number of events per file not set for %s %s", 
1195                     typeName, detName, typeName));
1196       continue;
1197     }
1198     dataLoader->SetNumberOfEventsPerFile(fEventsPerFile[i]->GetUniqueID());
1199     AliDebug(1, Form("number of events per file set to %d for %s %s",
1200                      fEventsPerFile[i]->GetUniqueID(), detName, typeName));
1201   }
1202
1203   AliInfo("running gAlice");
1204   AliSysInfo::AddStamp("Start_ProcessRun");
1205
1206   // Create the Root Tree with one branch per detector
1207   //Hits moved to begin event -> now we are crating separate tree for each event
1208
1209   gMC->ProcessRun(nEvents);
1210
1211   // End of this run, close files
1212   if(nEvents>0) FinishRun();
1213
1214   AliSysInfo::AddStamp("Stop_ProcessRun");
1215   delete runLoader;
1216
1217   return kTRUE;
1218 }
1219
1220 //_____________________________________________________________________________
1221 Bool_t AliSimulation::RunSDigitization(const char* detectors)
1222 {
1223 // run the digitization and produce summable digits
1224   static Int_t eventNr=0;
1225   AliCodeTimerAuto("",0) ;
1226
1227   // initialize CDB storage, run number, set CDB lock
1228   InitCDB();
1229   if (!SetRunNumberFromData()) if (fStopOnError) return kFALSE;
1230   SetCDBLock();
1231   
1232   AliRunLoader* runLoader = LoadRun();
1233   if (!runLoader) return kFALSE;
1234
1235   TString detStr = detectors;
1236   TObjArray* detArray = runLoader->GetAliRun()->Detectors();
1237   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
1238     AliModule* det = (AliModule*) detArray->At(iDet);
1239     if (!det || !det->IsActive()) continue;
1240     if (IsSelected(det->GetName(), detStr)) {
1241       AliInfo(Form("creating summable digits for %s", det->GetName()));
1242       AliCodeTimerStart(Form("creating summable digits for %s", det->GetName()));
1243       det->Hits2SDigits();
1244       AliCodeTimerStop(Form("creating summable digits for %s", det->GetName()));
1245       AliSysInfo::AddStamp(Form("Digit_%s_%d",det->GetName(),eventNr), 0,1, eventNr);
1246     }
1247   }
1248
1249   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
1250     AliError(Form("the following detectors were not found: %s",
1251                   detStr.Data()));
1252     if (fStopOnError) return kFALSE;
1253   }
1254   eventNr++;
1255   delete runLoader;
1256
1257   return kTRUE;
1258 }
1259
1260
1261 //_____________________________________________________________________________
1262 Bool_t AliSimulation::RunDigitization(const char* detectors, 
1263                                       const char* excludeDetectors)
1264 {
1265 // run the digitization and produce digits from sdigits
1266
1267   AliCodeTimerAuto("",0)
1268
1269   // initialize CDB storage, run number, set CDB lock
1270   InitCDB();
1271   if (!SetRunNumberFromData()) if (fStopOnError) return kFALSE;
1272   SetCDBLock();
1273   
1274   delete AliRunLoader::Instance();
1275   delete gAlice;
1276   gAlice = NULL;
1277
1278   Int_t nStreams = 1;
1279   if (fBkgrdFileNames) nStreams = fBkgrdFileNames->GetEntriesFast() + 1;
1280   Int_t signalPerBkgrd = GetNSignalPerBkgrd();
1281   AliDigitizationInput digInp(nStreams, signalPerBkgrd);
1282   // digInp.SetEmbeddingFlag(fEmbeddingFlag);
1283   digInp.SetRegionOfInterest(fRegionOfInterest);
1284   digInp.SetInputStream(0, fGAliceFileName.Data());
1285   for (Int_t iStream = 1; iStream < nStreams; iStream++) {
1286     const char* fileName = ((TObjString*)(fBkgrdFileNames->At(iStream-1)))->GetName();
1287     digInp.SetInputStream(iStream, fileName);
1288   }
1289   TObjArray detArr;
1290   detArr.SetOwner(kTRUE);
1291   TString detStr = detectors;
1292   TString detExcl = excludeDetectors;
1293   if (!static_cast<AliStream*>(digInp.GetInputStream(0))->ImportgAlice()) {
1294     AliError("Error occured while getting gAlice from Input 0");
1295     return kFALSE;
1296   }
1297   AliRunLoader* runLoader = AliRunLoader::GetRunLoader(digInp.GetInputStream(0)->GetFolderName());
1298   TObjArray* detArray = runLoader->GetAliRun()->Detectors();
1299   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
1300     AliModule* det = (AliModule*) detArray->At(iDet);
1301     if (!det || !det->IsActive()) continue;
1302     if (!IsSelected(det->GetName(), detStr) || IsSelected(det->GetName(), detExcl)) continue;
1303     AliDigitizer* digitizer = det->CreateDigitizer(&digInp);
1304     if (!digitizer || !digitizer->Init()) {
1305       AliError(Form("no digitizer for %s", det->GetName()));
1306       if (fStopOnError) return kFALSE;
1307       else continue;
1308     }
1309     detArr.AddLast(digitizer);    
1310     AliInfo(Form("Created digitizer from SDigits -> Digits for %s", det->GetName()));    
1311   }
1312   //
1313   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
1314     AliError(Form("the following detectors were not found: %s", detStr.Data()));
1315     if (fStopOnError) return kFALSE;
1316   }
1317   //
1318   Int_t ndigs = detArr.GetEntriesFast();
1319   Int_t eventsCreated = 0;
1320   AliRunLoader* outRl =  digInp.GetOutRunLoader();
1321   while ((eventsCreated++ < fNEvents) || (fNEvents < 0)) {
1322     if (!digInp.ConnectInputTrees()) break;
1323     digInp.InitEvent(); //this must be after call of Connect Input tress.
1324     if (outRl) outRl->SetEventNumber(eventsCreated-1);
1325     static_cast<AliStream*>(digInp.GetInputStream(0))->ImportgAlice(); // use gAlice of the first input stream
1326     for (int id=0;id<ndigs;id++) ((AliDigitizer*)detArr[id])->Digitize("");
1327     digInp.FinishEvent();
1328   };
1329   digInp.FinishGlobal();
1330   //
1331   return kTRUE;
1332 }
1333
1334 //_____________________________________________________________________________
1335 Bool_t AliSimulation::RunHitsDigitization(const char* detectors)
1336 {
1337 // run the digitization and produce digits from hits
1338
1339   AliCodeTimerAuto("",0)
1340
1341   // initialize CDB storage, run number, set CDB lock
1342   InitCDB();
1343   if (!SetRunNumberFromData()) if (fStopOnError) return kFALSE;
1344   SetCDBLock();
1345   
1346   AliRunLoader* runLoader = LoadRun("READ");
1347   if (!runLoader) return kFALSE;
1348
1349   TString detStr = detectors;
1350   TObjArray* detArray = runLoader->GetAliRun()->Detectors();
1351   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
1352     AliModule* det = (AliModule*) detArray->At(iDet);
1353     if (!det || !det->IsActive()) continue;
1354     if (IsSelected(det->GetName(), detStr)) {
1355       AliInfo(Form("creating digits from hits for %s", det->GetName()));
1356       det->Hits2Digits();
1357     }
1358   }
1359
1360   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
1361     AliError(Form("the following detectors were not found: %s", 
1362                   detStr.Data()));
1363     if (fStopOnError) return kFALSE;
1364   }
1365
1366   return kTRUE;
1367 }
1368
1369 //_____________________________________________________________________________
1370 Bool_t AliSimulation::WriteRawData(const char* detectors, 
1371                                    const char* fileName,
1372                                    Bool_t deleteIntermediateFiles,
1373                                    Bool_t selrawdata)
1374 {
1375 // convert the digits to raw data
1376 // First DDL raw data files for the given detectors are created.
1377 // If a file name is given, the DDL files are then converted to a DATE file.
1378 // If deleteIntermediateFiles is true, the DDL raw files are deleted 
1379 // afterwards.
1380 // If the file name has the extension ".root", the DATE file is converted
1381 // to a root file.
1382 // If deleteIntermediateFiles is true, the DATE file is deleted afterwards.
1383 // 'selrawdata' flag can be used to enable writing of detectors raw data
1384 // accoring to the trigger cluster.
1385
1386   AliCodeTimerAuto("",0)
1387   AliSysInfo::AddStamp("WriteRawData_Start");
1388   
1389   TString detStr = detectors;
1390   if (!WriteRawFiles(detStr.Data())) {
1391     if (fStopOnError) return kFALSE;
1392   }
1393   AliSysInfo::AddStamp("WriteRawFiles");
1394
1395   // run HLT simulation on simulated DDL raw files
1396   // and produce HLT ddl raw files to be included in date/root file
1397   // bugfix 2009-06-26: the decision whether to write HLT raw data
1398   // is taken in RunHLT. Here HLT always needs to be run in order to
1399   // create HLT digits, unless its switched off. This is due to the
1400   // special placement of the HLT between the generation of DDL files
1401   // and conversion to DATE/Root file.
1402   detStr.ReplaceAll("HLT", "");
1403   if (!fRunHLT.IsNull()) {
1404     if (!RunHLT()) {
1405       if (fStopOnError) return kFALSE;
1406     }
1407   }
1408   AliSysInfo::AddStamp("WriteRawData_RunHLT");
1409
1410   TString dateFileName(fileName);
1411   if (!dateFileName.IsNull()) {
1412     Bool_t rootOutput = dateFileName.EndsWith(".root");
1413     if (rootOutput) dateFileName += ".date";
1414     TString selDateFileName;
1415     if (selrawdata) {
1416       selDateFileName = "selected.";
1417       selDateFileName+= dateFileName;
1418     }
1419     if (!ConvertRawFilesToDate(dateFileName,selDateFileName)) {
1420       if (fStopOnError) return kFALSE;
1421     }
1422     AliSysInfo::AddStamp("ConvertRawFilesToDate");
1423     if (deleteIntermediateFiles) {
1424       AliRunLoader* runLoader = LoadRun("READ");
1425       if (runLoader) for (Int_t iEvent = 0; 
1426                           iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
1427         char command[256];
1428         snprintf(command, 256, "rm -r raw%d", iEvent);
1429         gSystem->Exec(command);
1430       }
1431       delete runLoader;
1432     }
1433
1434     if (rootOutput) {
1435       if (!ConvertDateToRoot(dateFileName, fileName)) {
1436         if (fStopOnError) return kFALSE;
1437       }
1438       AliSysInfo::AddStamp("ConvertDateToRoot");
1439       if (deleteIntermediateFiles) {
1440         gSystem->Unlink(dateFileName);
1441       }
1442       if (selrawdata) {
1443         TString selFileName = "selected.";
1444         selFileName        += fileName;
1445         if (!ConvertDateToRoot(selDateFileName, selFileName)) {
1446           if (fStopOnError) return kFALSE;
1447         }
1448         if (deleteIntermediateFiles) {
1449           gSystem->Unlink(selDateFileName);
1450         }
1451       }
1452     }
1453   }
1454
1455   return kTRUE;
1456 }
1457
1458 //_____________________________________________________________________________
1459 Bool_t AliSimulation::WriteRawFiles(const char* detectors)
1460 {
1461 // convert the digits to raw data DDL files
1462
1463   AliCodeTimerAuto("",0)
1464   
1465   AliRunLoader* runLoader = LoadRun("READ");
1466   if (!runLoader) return kFALSE;
1467
1468   // write raw data to DDL files
1469   for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
1470     AliInfo(Form("processing event %d", iEvent));
1471     runLoader->GetEvent(iEvent);
1472     TString baseDir = gSystem->WorkingDirectory();
1473     char dirName[256];
1474     snprintf(dirName, 256, "raw%d", iEvent);
1475     gSystem->MakeDirectory(dirName);
1476     if (!gSystem->ChangeDirectory(dirName)) {
1477       AliError(Form("couldn't change to directory %s", dirName));
1478       if (fStopOnError) return kFALSE; else continue;
1479     }
1480
1481     ofstream runNbFile(Form("run%u",runLoader->GetHeader()->GetRun()));
1482     runNbFile.close();
1483
1484     TString detStr = detectors;
1485     if (IsSelected("HLT", detStr)) {
1486       // Do nothing. "HLT" will be removed from detStr and HLT raw
1487       // data files are generated in RunHLT.
1488     }
1489
1490     TObjArray* detArray = runLoader->GetAliRun()->Detectors();
1491     for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
1492       AliModule* det = (AliModule*) detArray->At(iDet);
1493       if (!det || !det->IsActive()) continue;
1494       if (IsSelected(det->GetName(), detStr)) {
1495         AliInfo(Form("creating raw data from digits for %s", det->GetName()));
1496         det->Digits2Raw();
1497       }
1498     }
1499
1500     if (!WriteTriggerRawData())
1501       if (fStopOnError) return kFALSE;
1502
1503     gSystem->ChangeDirectory(baseDir);
1504     if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
1505       AliError(Form("the following detectors were not found: %s", 
1506                     detStr.Data()));
1507       if (fStopOnError) return kFALSE;
1508     }
1509   }
1510
1511   delete runLoader;
1512   
1513   return kTRUE;
1514 }
1515
1516 //_____________________________________________________________________________
1517 Bool_t AliSimulation::ConvertRawFilesToDate(const char* dateFileName,
1518                                             const char* selDateFileName)
1519 {
1520 // convert raw data DDL files to a DATE file with the program "dateStream"
1521 // The second argument is not empty when the user decides to write
1522 // the detectors raw data according to the trigger cluster.
1523
1524   AliCodeTimerAuto("",0)
1525   
1526   char* path = gSystem->Which(gSystem->Getenv("PATH"), "dateStream");
1527   if (!path) {
1528     AliError("the program dateStream was not found");
1529     if (fStopOnError) return kFALSE;
1530   } else {
1531     delete[] path;
1532   }
1533
1534   AliRunLoader* runLoader = LoadRun("READ");
1535   if (!runLoader) return kFALSE;
1536
1537   AliInfo(Form("converting raw data DDL files to DATE file %s", dateFileName));
1538   Bool_t selrawdata = kFALSE;
1539   if (strcmp(selDateFileName,"") != 0) selrawdata = kTRUE;
1540
1541   char command[256];
1542   // Note the option -s. It is used in order to avoid
1543   // the generation of SOR/EOR events.
1544   snprintf(command, 256, "dateStream -c -s -D -o %s -# %d -C -run %d", 
1545           dateFileName, runLoader->GetNumberOfEvents(),runLoader->GetHeader()->GetRun());
1546   FILE* pipe = gSystem->OpenPipe(command, "w");
1547
1548   if (!pipe) {
1549     AliError(Form("Cannot execute command: %s",command));
1550     return kFALSE;
1551   }
1552
1553   Int_t selEvents = 0;
1554   for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
1555
1556     UInt_t detectorPattern = 0;
1557     runLoader->GetEvent(iEvent);
1558     if (!runLoader->LoadTrigger()) {
1559       AliCentralTrigger *aCTP = runLoader->GetTrigger();
1560       detectorPattern = aCTP->GetClusterMask();
1561       // Check if the event was triggered by CTP
1562       if (selrawdata) {
1563         if (aCTP->GetClassMask()) selEvents++;
1564       }
1565     }
1566     else {
1567       AliWarning("No trigger can be loaded! Some fields in the event header will be empty !");
1568       if (selrawdata) {
1569         AliWarning("No trigger can be loaded! Writing of selected raw data is abandoned !");
1570         selrawdata = kFALSE;
1571       }
1572     }
1573
1574     fprintf(pipe, "GDC DetectorPattern %u Timestamp %ld\n", detectorPattern, runLoader->GetHeader()->GetTimeStamp());
1575     Float_t ldc = 0;
1576     Int_t prevLDC = -1;
1577
1578     // loop over detectors and DDLs
1579     for (Int_t iDet = 0; iDet < AliDAQ::kNDetectors; iDet++) {
1580       for (Int_t iDDL = 0; iDDL < AliDAQ::NumberOfDdls(iDet); iDDL++) {
1581
1582         Int_t ddlID = AliDAQ::DdlID(iDet,iDDL);
1583         Int_t ldcID = Int_t(ldc + 0.0001);
1584         ldc += AliDAQ::NumberOfLdcs(iDet) / AliDAQ::NumberOfDdls(iDet);
1585
1586         char rawFileName[256];
1587         snprintf(rawFileName, 256, "raw%d/%s", 
1588                 iEvent, AliDAQ::DdlFileName(iDet,iDDL));
1589
1590         // check existence and size of raw data file
1591         FILE* file = fopen(rawFileName, "rb");
1592         if (!file) continue;
1593         fseek(file, 0, SEEK_END);
1594         unsigned long size = ftell(file);
1595         fclose(file);
1596         if (!size) continue;
1597
1598         if (ldcID != prevLDC) {
1599           fprintf(pipe, " LDC Id %d\n", ldcID);
1600           prevLDC = ldcID;
1601         }
1602         fprintf(pipe, "  Equipment Id %d Payload %s\n", ddlID, rawFileName);
1603       }
1604     }
1605   }
1606
1607   Int_t result = gSystem->ClosePipe(pipe);
1608
1609   if (!(selrawdata && selEvents > 0)) {
1610     delete runLoader;
1611     return (result == 0);
1612   }
1613
1614   AliInfo(Form("converting selected by trigger cluster raw data DDL files to DATE file %s", selDateFileName));
1615   
1616   snprintf(command, 256, "dateStream -c -s -D -o %s -# %d -C -run %d", 
1617           selDateFileName,selEvents,runLoader->GetHeader()->GetRun());
1618   FILE* pipe2 = gSystem->OpenPipe(command, "w");
1619
1620   for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
1621
1622     // Get the trigger decision and cluster
1623     UInt_t detectorPattern = 0;
1624     TString detClust;
1625     runLoader->GetEvent(iEvent);
1626     if (!runLoader->LoadTrigger()) {
1627       AliCentralTrigger *aCTP = runLoader->GetTrigger();
1628       if (aCTP->GetClassMask() == 0) continue;
1629       detectorPattern = aCTP->GetClusterMask();
1630       detClust = AliDAQ::ListOfTriggeredDetectors(detectorPattern);
1631       AliInfo(Form("List of detectors to be read out: %s",detClust.Data()));
1632     }
1633
1634     fprintf(pipe2, "GDC DetectorPattern %u Timestamp %ld\n", detectorPattern, runLoader->GetHeader()->GetTimeStamp());
1635     Float_t ldc = 0;
1636     Int_t prevLDC = -1;
1637
1638     // loop over detectors and DDLs
1639     for (Int_t iDet = 0; iDet < AliDAQ::kNDetectors; iDet++) {
1640       // Write only raw data from detectors that
1641       // are contained in the trigger cluster(s)
1642       if (!IsSelected(AliDAQ::DetectorName(iDet),detClust)) continue;
1643
1644       for (Int_t iDDL = 0; iDDL < AliDAQ::NumberOfDdls(iDet); iDDL++) {
1645
1646         Int_t ddlID = AliDAQ::DdlID(iDet,iDDL);
1647         Int_t ldcID = Int_t(ldc + 0.0001);
1648         ldc += AliDAQ::NumberOfLdcs(iDet) / AliDAQ::NumberOfDdls(iDet);
1649
1650         char rawFileName[256];
1651         snprintf(rawFileName, 256, "raw%d/%s", 
1652                 iEvent, AliDAQ::DdlFileName(iDet,iDDL));
1653
1654         // check existence and size of raw data file
1655         FILE* file = fopen(rawFileName, "rb");
1656         if (!file) continue;
1657         fseek(file, 0, SEEK_END);
1658         unsigned long size = ftell(file);
1659         fclose(file);
1660         if (!size) continue;
1661
1662         if (ldcID != prevLDC) {
1663           fprintf(pipe2, " LDC Id %d\n", ldcID);
1664           prevLDC = ldcID;
1665         }
1666         fprintf(pipe2, "  Equipment Id %d Payload %s\n", ddlID, rawFileName);
1667       }
1668     }
1669   }
1670
1671   Int_t result2 = gSystem->ClosePipe(pipe2);
1672
1673   delete runLoader;
1674   return ((result == 0) && (result2 == 0));
1675 }
1676
1677 //_____________________________________________________________________________
1678 Bool_t AliSimulation::ConvertDateToRoot(const char* dateFileName,
1679                                         const char* rootFileName)
1680 {
1681 // convert a DATE file to a root file with the program "alimdc"
1682
1683   // ALIMDC setup
1684   const Int_t kDBSize = 2000000000;
1685   const Int_t kTagDBSize = 1000000000;
1686   const Bool_t kFilter = kFALSE;
1687   const Int_t kCompression = 1;
1688
1689   char* path = gSystem->Which(gSystem->Getenv("PATH"), "alimdc");
1690   if (!path) {
1691     AliError("the program alimdc was not found");
1692     if (fStopOnError) return kFALSE;
1693   } else {
1694     delete[] path;
1695   }
1696
1697   AliInfo(Form("converting DATE file %s to root file %s", 
1698                dateFileName, rootFileName));
1699
1700   const char* rawDBFS[2] = { "/tmp/mdc1", "/tmp/mdc2" };
1701   const char* tagDBFS    = "/tmp/mdc1/tags";
1702
1703   // User defined file system locations
1704   if (gSystem->Getenv("ALIMDC_RAWDB1")) 
1705     rawDBFS[0] = gSystem->Getenv("ALIMDC_RAWDB1");
1706   if (gSystem->Getenv("ALIMDC_RAWDB2")) 
1707     rawDBFS[1] = gSystem->Getenv("ALIMDC_RAWDB2");
1708   if (gSystem->Getenv("ALIMDC_TAGDB")) 
1709     tagDBFS = gSystem->Getenv("ALIMDC_TAGDB");
1710
1711   gSystem->Exec(Form("rm -rf %s",rawDBFS[0]));
1712   gSystem->Exec(Form("rm -rf %s",rawDBFS[1]));
1713   gSystem->Exec(Form("rm -rf %s",tagDBFS));
1714
1715   gSystem->Exec(Form("mkdir %s",rawDBFS[0]));
1716   gSystem->Exec(Form("mkdir %s",rawDBFS[1]));
1717   gSystem->Exec(Form("mkdir %s",tagDBFS));
1718
1719   Int_t result = gSystem->Exec(Form("alimdc %d %d %d %d %s", 
1720                                     kDBSize, kTagDBSize, kFilter, kCompression, dateFileName));
1721   gSystem->Exec(Form("mv %s/*.root %s", rawDBFS[0], rootFileName));
1722
1723   gSystem->Exec(Form("rm -rf %s",rawDBFS[0]));
1724   gSystem->Exec(Form("rm -rf %s",rawDBFS[1]));
1725   gSystem->Exec(Form("rm -rf %s",tagDBFS));
1726
1727   return (result == 0);
1728 }
1729
1730
1731 //_____________________________________________________________________________
1732 AliRunLoader* AliSimulation::LoadRun(const char* mode) const
1733 {
1734 // delete existing run loaders, open a new one and load gAlice
1735
1736   delete AliRunLoader::Instance();
1737   AliRunLoader* runLoader = 
1738     AliRunLoader::Open(fGAliceFileName.Data(), 
1739                        AliConfig::GetDefaultEventFolderName(), mode);
1740   if (!runLoader) {
1741     AliError(Form("no run loader found in file %s", fGAliceFileName.Data()));
1742     return NULL;
1743   }
1744   runLoader->LoadgAlice();
1745   runLoader->LoadHeader();
1746   gAlice = runLoader->GetAliRun();
1747   if (!gAlice) {
1748     AliError(Form("no gAlice object found in file %s", 
1749                   fGAliceFileName.Data()));
1750     return NULL;
1751   }
1752   return runLoader;
1753 }
1754
1755 //_____________________________________________________________________________
1756 Int_t AliSimulation::GetNSignalPerBkgrd(Int_t nEvents) const
1757 {
1758 // get or calculate the number of signal events per background event
1759
1760   if (!fBkgrdFileNames) return 1;
1761   Int_t nBkgrdFiles = fBkgrdFileNames->GetEntriesFast();
1762   if (nBkgrdFiles == 0) return 1;
1763
1764   // get the number of signal events
1765   if (nEvents <= 0) {
1766     AliRunLoader* runLoader = 
1767         AliRunLoader::Open(fGAliceFileName.Data(), "SIGNAL");
1768     if (!runLoader) return 1;
1769     
1770     nEvents = runLoader->GetNumberOfEvents();
1771     delete runLoader;
1772   }
1773
1774   Int_t result = 0;
1775   for (Int_t iBkgrdFile = 0; iBkgrdFile < nBkgrdFiles; iBkgrdFile++) {
1776     // get the number of background events
1777     const char* fileName = ((TObjString*)
1778                             (fBkgrdFileNames->At(iBkgrdFile)))->GetName();
1779     AliRunLoader* runLoader =
1780       AliRunLoader::Open(fileName, "BKGRD");
1781     if (!runLoader) continue;
1782     Int_t nBkgrdEvents = runLoader->GetNumberOfEvents();
1783     delete runLoader;
1784   
1785     // get or calculate the number of signal per background events
1786     Int_t nSignalPerBkgrd = fBkgrdFileNames->At(iBkgrdFile)->GetUniqueID();
1787     if (nSignalPerBkgrd <= 0) {
1788       nSignalPerBkgrd = (nEvents-1) / nBkgrdEvents + 1;
1789     } else if (result && (result != nSignalPerBkgrd)) {
1790       AliInfo(Form("the number of signal events per background event "
1791                    "will be changed from %d to %d for stream %d", 
1792                    nSignalPerBkgrd, result, iBkgrdFile+1));
1793       nSignalPerBkgrd = result;
1794     }
1795
1796     if (!result) result = nSignalPerBkgrd;
1797     if (nSignalPerBkgrd * nBkgrdEvents < nEvents) {
1798       AliWarning(Form("not enough background events (%d) for %d signal events "
1799                       "using %d signal per background events for stream %d",
1800                       nBkgrdEvents, nEvents, nSignalPerBkgrd, iBkgrdFile+1));
1801     }
1802   }
1803
1804   return result;
1805 }
1806
1807 //_____________________________________________________________________________
1808 Bool_t AliSimulation::IsSelected(TString detName, TString& detectors) const
1809 {
1810 // check whether detName is contained in detectors
1811 // if yes, it is removed from detectors
1812
1813   // check if all detectors are selected
1814   if ((detectors.CompareTo("ALL") == 0) ||
1815       detectors.BeginsWith("ALL ") ||
1816       detectors.EndsWith(" ALL") ||
1817       detectors.Contains(" ALL ")) {
1818     detectors = "ALL";
1819     return kTRUE;
1820   }
1821
1822   // search for the given detector
1823   Bool_t result = kFALSE;
1824   if ((detectors.CompareTo(detName) == 0) ||
1825       detectors.BeginsWith(detName+" ") ||
1826       detectors.EndsWith(" "+detName) ||
1827       detectors.Contains(" "+detName+" ")) {
1828     detectors.ReplaceAll(detName, "");
1829     result = kTRUE;
1830   }
1831
1832   // clean up the detectors string
1833   while (detectors.Contains("  ")) detectors.ReplaceAll("  ", " ");
1834   while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
1835   while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
1836
1837   return result;
1838 }
1839
1840 //_____________________________________________________________________________
1841 Int_t AliSimulation::ConvertRaw2SDigits(const char* rawDirectory, const char* esdFileName, Int_t N) 
1842 {
1843 //
1844 // Steering routine  to convert raw data in directory rawDirectory/ to fake SDigits. 
1845 // These can be used for embedding of MC tracks into RAW data using the standard 
1846 // merging procedure.
1847 //
1848 // If an ESD file is given the reconstructed vertex is taken from it and stored in the event header.
1849 //
1850   if (!gAlice) {
1851     AliError("no gAlice object. Restart aliroot and try again.");
1852     return kFALSE;
1853   }
1854   if (gAlice->Modules()->GetEntries() > 0) {
1855     AliError("gAlice was already run. Restart aliroot and try again.");
1856     return kFALSE;
1857   }
1858   
1859   AliInfo(Form("initializing gAlice with config file %s",fConfigFileName.Data()));
1860   
1861   gAlice->Announce();
1862   
1863   gROOT->LoadMacro(fConfigFileName.Data());
1864   gInterpreter->ProcessLine(gAlice->GetConfigFunction());
1865   
1866   if(AliCDBManager::Instance()->GetRun() >= 0) { 
1867         SetRunNumber(AliCDBManager::Instance()->GetRun());
1868   } else {
1869         AliWarning("Run number not initialized!!");
1870   }
1871   
1872    AliRunLoader::Instance()->CdGAFile();
1873     
1874    AliPDG::AddParticlesToPdgDataBase();  
1875
1876    gMC->SetMagField(TGeoGlobalMagField::Instance()->GetField());
1877    
1878    gAlice->GetMCApp()->Init();
1879
1880    //Must be here because some MCs (G4) adds detectors here and not in Config.C
1881    gAlice->InitLoaders();
1882    AliRunLoader::Instance()->MakeTree("E");
1883    AliRunLoader::Instance()->LoadKinematics("RECREATE");
1884    AliRunLoader::Instance()->LoadTrackRefs("RECREATE");
1885    AliRunLoader::Instance()->LoadHits("all","RECREATE");
1886
1887    //
1888    // Save stuff at the beginning of the file to avoid file corruption
1889    AliRunLoader::Instance()->CdGAFile();
1890    gAlice->Write();
1891 //
1892 //  Initialize CDB     
1893     InitCDB();
1894     //AliCDBManager* man = AliCDBManager::Instance();
1895     //man->SetRun(0); // Should this come from rawdata header ?
1896     
1897     Int_t iDet;
1898     //
1899     // Get the runloader
1900     AliRunLoader* runLoader = AliRunLoader::Instance();
1901     //
1902     // Open esd file if available
1903     TFile* esdFile = 0;
1904     TTree* treeESD = 0;
1905     AliESDEvent* esd = 0;
1906     if (esdFileName && (strlen(esdFileName)>0)) {
1907       esdFile = TFile::Open(esdFileName);
1908       if (esdFile) {
1909         esd = new AliESDEvent();
1910         esdFile->GetObject("esdTree", treeESD);
1911         if (treeESD) esd->ReadFromTree(treeESD);
1912       }
1913     }
1914
1915     //
1916     // Create the RawReader
1917     TString fileName(rawDirectory);
1918     AliRawReader* rawReader = AliRawReader::Create(fileName.Data());
1919     if (!rawReader) return (kFALSE);
1920     
1921 //     if (!fEquipIdMap.IsNull() && fRawReader)
1922 //       fRawReader->LoadEquipmentIdsMap(fEquipIdMap);
1923     //
1924     // Get list of detectors
1925     TObjArray* detArray = runLoader->GetAliRun()->Detectors();
1926     //
1927     // Get Header
1928     AliHeader* header = runLoader->GetHeader();
1929     // Event loop
1930     Int_t nev = 0;
1931     while(kTRUE) {
1932         if (!(rawReader->NextEvent())) break;
1933         runLoader->SetEventNumber(nev);
1934         runLoader->GetHeader()->Reset(rawReader->GetRunNumber(), 
1935                                       nev, nev);
1936         runLoader->GetEvent(nev);
1937         AliInfo(Form("We are at event %d",nev));
1938         //
1939         // Detector loop
1940         TString detStr = fMakeSDigits;
1941         for (iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
1942             AliModule* det = (AliModule*) detArray->At(iDet);
1943             if (!det || !det->IsActive()) continue;
1944             if (IsSelected(det->GetName(), detStr)) {
1945               AliInfo(Form("Calling Raw2SDigits for %s", det->GetName()));
1946               det->Raw2SDigits(rawReader);
1947               rawReader->Reset();
1948             }
1949         } // detectors
1950         
1951
1952         //
1953         //  If ESD information available obtain reconstructed vertex and store in header.
1954         if (treeESD) {
1955                 AliInfo(Form("Selected event %d correspond to event %d ins raw and esd",nev,rawReader->GetEventIndex()));
1956             treeESD->GetEvent(rawReader->GetEventIndex());
1957             const AliESDVertex* esdVertex = esd->GetPrimaryVertex();
1958             Double_t position[3];
1959             esdVertex->GetXYZ(position);
1960             AliGenEventHeader* mcHeader = new  AliGenEventHeader("ESD");
1961             TArrayF mcV;
1962             mcV.Set(3);
1963             for (Int_t i = 0; i < 3; i++) mcV[i] = position[i];
1964             mcHeader->SetPrimaryVertex(mcV);
1965             header->Reset(0,nev);
1966             header->SetGenEventHeader(mcHeader);
1967             AliInfo(Form("***** Saved vertex %f %f %f \n", position[0], position[1], position[2]));
1968         }
1969 //
1970 //      Finish the event
1971         runLoader->TreeE()->Fill();
1972         AliInfo(Form("Finished event %d",nev));
1973         nev++;
1974         if (N>0&&nev>=N)
1975           break;
1976     } // events
1977  
1978     delete rawReader;
1979 //
1980 //  Finish the run 
1981     runLoader->CdGAFile();
1982     runLoader->WriteHeader("OVERWRITE");
1983     runLoader->WriteRunLoader();
1984
1985     return nev;
1986 }
1987
1988 //_____________________________________________________________________________
1989 void AliSimulation::FinishRun()
1990 {
1991   //
1992   // Called at the end of the run.
1993   //
1994
1995   if(IsLegoRun()) 
1996    {
1997     AliDebug(1, "Finish Lego");
1998     AliRunLoader::Instance()->CdGAFile();
1999     fLego->FinishRun();
2000    }
2001   
2002   // Clean detector information
2003   TIter next(gAlice->Modules());
2004   AliModule *detector;
2005   while((detector = dynamic_cast<AliModule*>(next()))) {
2006     AliDebug(2, Form("%s->FinishRun()", detector->GetName()));
2007     detector->FinishRun();
2008   }
2009   
2010   AliDebug(1, "AliRunLoader::Instance()->WriteHeader(OVERWRITE)");
2011   AliRunLoader::Instance()->WriteHeader("OVERWRITE");
2012
2013   // Write AliRun info and all detectors parameters
2014   AliRunLoader::Instance()->CdGAFile();
2015   gAlice->Write(0,TObject::kOverwrite);//write AliRun
2016   AliRunLoader::Instance()->Write(0,TObject::kOverwrite);//write RunLoader itself
2017   
2018   if(gAlice->GetMCApp()) gAlice->GetMCApp()->FinishRun();  
2019   AliRunLoader::Instance()->Synchronize();
2020 }
2021
2022 //_____________________________________________________________________________
2023 Int_t AliSimulation::GetDetIndex(const char* detector)
2024 {
2025   // return the detector index corresponding to detector
2026   Int_t index = -1 ; 
2027   for (index = 0; index < fgkNDetectors ; index++) {
2028     if ( strcmp(detector, fgkDetectorName[index]) == 0 )
2029           break ; 
2030   }     
2031   return index ; 
2032 }
2033
2034 //_____________________________________________________________________________
2035 Bool_t AliSimulation::CreateHLT()
2036 {
2037   // Init the HLT simulation.
2038   // The function  loads the library and creates the instance of AliHLTSimulation.
2039   // the main reason for the decoupled creation is to set the transient OCDB
2040   // objects before the OCDB is locked
2041
2042   // load the library dynamically
2043   gSystem->Load(ALIHLTSIMULATION_LIBRARY);
2044
2045   // check for the library version
2046   AliHLTSimulationGetLibraryVersion_t fctVersion=(AliHLTSimulationGetLibraryVersion_t)(gSystem->DynFindSymbol(ALIHLTSIMULATION_LIBRARY, ALIHLTSIMULATION_GET_LIBRARY_VERSION));
2047   if (!fctVersion) {
2048     AliError(Form("can not load library %s", ALIHLTSIMULATION_LIBRARY));
2049     return kFALSE;
2050   }
2051   if (fctVersion()!= ALIHLTSIMULATION_LIBRARY_VERSION) {
2052     AliWarning(Form("%s version does not match: compiled for version %d, loaded %d", ALIHLTSIMULATION_LIBRARY, ALIHLTSIMULATION_LIBRARY_VERSION, fctVersion()));
2053   }
2054
2055   // print compile info
2056   typedef void (*CompileInfo)( const char*& date, const char*& time);
2057   CompileInfo fctInfo=(CompileInfo)gSystem->DynFindSymbol(ALIHLTSIMULATION_LIBRARY, "CompileInfo");
2058   if (fctInfo) {
2059     const char* date="";
2060     const char* time="";
2061     (*fctInfo)(date, time);
2062     if (!date) date="unknown";
2063     if (!time) time="unknown";
2064     AliInfo(Form("%s build on %s (%s)", ALIHLTSIMULATION_LIBRARY, date, time));
2065   } else {
2066     AliInfo(Form("no build info available for %s", ALIHLTSIMULATION_LIBRARY));
2067   }
2068
2069   // create instance of the HLT simulation
2070   AliHLTSimulationCreateInstance_t fctCreate=(AliHLTSimulationCreateInstance_t)(gSystem->DynFindSymbol(ALIHLTSIMULATION_LIBRARY, ALIHLTSIMULATION_CREATE_INSTANCE));
2071   if (fctCreate==NULL || (fpHLT=(fctCreate()))==NULL) {
2072     AliError(Form("can not create instance of HLT simulation (creator %p)", fctCreate));
2073     return kFALSE;    
2074   }
2075
2076   TString specObjects;
2077   for (Int_t i = 0; i < fSpecCDBUri.GetEntriesFast(); i++) {
2078     if (specObjects.Length()>0) specObjects+=" ";
2079     specObjects+=fSpecCDBUri[i]->GetName();
2080   }
2081
2082   AliHLTSimulationSetup_t fctSetup=(AliHLTSimulationSetup_t)(gSystem->DynFindSymbol(ALIHLTSIMULATION_LIBRARY, ALIHLTSIMULATION_SETUP));
2083   if (fctSetup==NULL || fctSetup(fpHLT, this, specObjects.Data())<0) {
2084     AliWarning(Form("failed to setup HLT simulation (function %p)", fctSetup));
2085   }
2086
2087   return kTRUE;
2088 }
2089
2090 //_____________________________________________________________________________
2091 Bool_t AliSimulation::RunHLT()
2092 {
2093   // Run the HLT simulation
2094   // HLT simulation is implemented in HLT/sim/AliHLTSimulation
2095   // Disabled if fRunHLT is empty, default vaule is "default".
2096   // AliSimulation::SetRunHLT can be used to set the options for HLT simulation
2097   // The default simulation depends on the HLT component libraries and their
2098   // corresponding agents which define components and chains to run. See
2099   // http://web.ift.uib.no/~kjeks/doc/alice-hlt-current/
2100   // http://web.ift.uib.no/~kjeks/doc/alice-hlt-current/classAliHLTModuleAgent.html
2101   //
2102   // The libraries to be loaded can be specified as an option.
2103   // <pre>
2104   // AliSimulation sim;
2105   // sim.SetRunHLT("libAliHLTSample.so");
2106   // </pre>
2107   // will only load <tt>libAliHLTSample.so</tt>
2108
2109   // Other available options:
2110   // \li loglevel=<i>level</i> <br>
2111   //     logging level for this processing
2112   // \li alilog=off
2113   //     disable redirection of log messages to AliLog class
2114   // \li config=<i>macro</i>
2115   //     configuration macro
2116   // \li chains=<i>configuration</i>
2117   //     comma separated list of configurations to be run during simulation
2118   // \li rawfile=<i>file</i>
2119   //     source for the RawReader to be created, the default is <i>./</i> if
2120   //     raw data is simulated
2121
2122   int iResult=0;
2123
2124   if (!fpHLT && !CreateHLT()) {
2125     return kFALSE;
2126   }
2127   AliHLTSimulation* pHLT=fpHLT;
2128
2129   AliRunLoader* pRunLoader = LoadRun("READ");
2130   if (!pRunLoader) return kFALSE;
2131
2132   // initialize CDB storage, run number, set CDB lock
2133   // thats for the case of running HLT simulation without all the other steps
2134   // multiple calls are handled by the function, so we can just call
2135   InitCDB();
2136   if (!SetRunNumberFromData()) if (fStopOnError) return kFALSE;
2137   SetCDBLock();
2138   
2139   // init the HLT simulation
2140   TString options;
2141   if (fRunHLT.CompareTo("default")!=0) options=fRunHLT;
2142   TString detStr = fWriteRawData;
2143   if (!IsSelected("HLT", detStr)) {
2144     options+=" writerawfiles=";
2145   } else {
2146     options+=" writerawfiles=HLT";
2147   }
2148
2149   if (!detStr.IsNull() && !options.Contains("rawfile=")) {
2150     // as a matter of fact, HLT will run reconstruction and needs the RawReader
2151     // in order to get detector data. By default, RawReaderFile is used to read
2152     // the already simulated ddl files. Date and Root files from the raw data
2153     // are generated after the HLT simulation.
2154     options+=" rawfile=./";
2155   }
2156
2157   AliHLTSimulationInit_t fctInit=(AliHLTSimulationInit_t)(gSystem->DynFindSymbol(ALIHLTSIMULATION_LIBRARY, ALIHLTSIMULATION_INIT));
2158   if (fctInit==NULL || (iResult=(fctInit(pHLT, pRunLoader, options.Data())))<0) {
2159     AliError(Form("can not init HLT simulation: error %d (init %p)", iResult, fctInit));
2160   } else {
2161     // run the HLT simulation
2162     AliHLTSimulationRun_t fctRun=(AliHLTSimulationRun_t)(gSystem->DynFindSymbol(ALIHLTSIMULATION_LIBRARY, ALIHLTSIMULATION_RUN));
2163     if (fctRun==NULL || (iResult=(fctRun(pHLT, pRunLoader)))<0) {
2164       AliError(Form("can not run HLT simulation: error %d (run %p)", iResult, fctRun));
2165     }
2166   }
2167
2168   // delete the instance
2169   AliHLTSimulationDeleteInstance_t fctDelete=(AliHLTSimulationDeleteInstance_t)(gSystem->DynFindSymbol(ALIHLTSIMULATION_LIBRARY, ALIHLTSIMULATION_DELETE_INSTANCE));
2170   if (fctDelete==NULL || fctDelete(pHLT)<0) {
2171     AliError(Form("can not delete instance of HLT simulation (creator %p)", fctDelete));
2172   }
2173   pHLT=NULL;
2174
2175   return iResult>=0?kTRUE:kFALSE;
2176 }
2177
2178 //_____________________________________________________________________________
2179 Bool_t AliSimulation::RunQA()
2180 {
2181         // run the QA on summable hits, digits or digits
2182         
2183     //if(!gAlice) return kFALSE;
2184         AliQAManager::QAManager()->SetRunLoader(AliRunLoader::Instance()) ;
2185
2186         TString detectorsw("") ;  
2187         Bool_t rv = kTRUE ; 
2188   AliQAManager::QAManager()->SetEventSpecie(fEventSpecie) ;
2189         detectorsw = AliQAManager::QAManager()->Run(fQADetectors.Data()) ; 
2190         if ( detectorsw.IsNull() ) 
2191                 rv = kFALSE ; 
2192         return rv ; 
2193 }
2194
2195 //_____________________________________________________________________________
2196 Bool_t AliSimulation::SetRunQA(TString detAndAction) 
2197 {
2198         // Allows to run QA for a selected set of detectors
2199         // and a selected set of tasks among HITS, SDIGITS and DIGITS
2200         // all selected detectors run the same selected tasks
2201         
2202         if (!detAndAction.Contains(":")) {
2203                 AliError( Form("%s is a wrong syntax, use \"DetectorList:ActionList\" \n", detAndAction.Data()) ) ;
2204                 fRunQA = kFALSE ;
2205                 return kFALSE ;                 
2206         }
2207         Int_t colon = detAndAction.Index(":") ; 
2208         fQADetectors = detAndAction(0, colon) ; 
2209         if (fQADetectors.Contains("ALL") ){
2210     TString tmp = Form("%s %s", fMakeDigits.Data(), fMakeDigitsFromHits.Data()) ; 
2211     Int_t minus = fQADetectors.Last('-') ; 
2212     TString toKeep = Form("%s %s", fMakeDigits.Data(), fMakeDigitsFromHits.Data()) ; 
2213     TString toRemove("") ;
2214     while (minus >= 0) {
2215       toRemove = fQADetectors(minus+1, fQADetectors.Length()) ; 
2216       toRemove = toRemove.Strip() ; 
2217       toKeep.ReplaceAll(toRemove, "") ; 
2218       fQADetectors.ReplaceAll(Form("-%s", toRemove.Data()), "") ; 
2219       minus = fQADetectors.Last('-') ; 
2220     }
2221     fQADetectors = toKeep ; 
2222   }
2223   fQATasks   = detAndAction(colon+1, detAndAction.Sizeof() ) ; 
2224         if (fQATasks.Contains("ALL") ) {
2225                 fQATasks = Form("%d %d %d", AliQAv1::kHITS, AliQAv1::kSDIGITS, AliQAv1::kDIGITS) ; 
2226         } else {
2227                 fQATasks.ToUpper() ; 
2228                 TString tempo("") ; 
2229                 if ( fQATasks.Contains("HIT") ) 
2230                         tempo = Form("%d ", AliQAv1::kHITS) ; 
2231                 if ( fQATasks.Contains("SDIGIT") ) 
2232                         tempo += Form("%d ", AliQAv1::kSDIGITS) ; 
2233                 if ( fQATasks.Contains("DIGIT") ) 
2234                         tempo += Form("%d ", AliQAv1::kDIGITS) ; 
2235                 fQATasks = tempo ; 
2236                 if (fQATasks.IsNull()) {
2237                         AliInfo("No QA requested\n")  ;
2238                         fRunQA = kFALSE ;
2239                         return kTRUE ; 
2240                 }
2241         }       
2242         TString tempo(fQATasks) ; 
2243     tempo.ReplaceAll(Form("%d", AliQAv1::kHITS), AliQAv1::GetTaskName(AliQAv1::kHITS))  ;
2244     tempo.ReplaceAll(Form("%d", AliQAv1::kSDIGITS), AliQAv1::GetTaskName(AliQAv1::kSDIGITS)) ;  
2245     tempo.ReplaceAll(Form("%d", AliQAv1::kDIGITS), AliQAv1::GetTaskName(AliQAv1::kDIGITS)) ;    
2246         AliInfo( Form("QA will be done on \"%s\" for \"%s\"\n", fQADetectors.Data(), tempo.Data()) ) ;  
2247         fRunQA = kTRUE ;
2248         AliQAManager::QAManager()->SetActiveDetectors(fQADetectors) ; 
2249         AliQAManager::QAManager()->SetTasks(fQATasks) ; 
2250   for (Int_t det = 0 ; det < AliQAv1::kNDET ; det++) 
2251     AliQAManager::QAManager()->SetWriteExpert(AliQAv1::DETECTORINDEX_t(det)) ;
2252   
2253         return kTRUE; 
2254
2255
2256 //_____________________________________________________________________________
2257 void AliSimulation::ProcessEnvironmentVars()
2258 {
2259 // Extract run number and random generator seed from env variables
2260
2261     AliInfo("Processing environment variables");
2262     
2263     // Random Number seed
2264     
2265     // first check that seed is not already set
2266     if (fSeed == 0) {
2267         if (gSystem->Getenv("CONFIG_SEED")) {
2268                 fSeed = atoi(gSystem->Getenv("CONFIG_SEED"));
2269         }
2270     } else {
2271         if (gSystem->Getenv("CONFIG_SEED")) {
2272                 AliInfo(Form("Seed for random number generation already set (%d)"
2273                              ": CONFIG_SEED variable ignored!", fSeed));
2274         }
2275     }
2276    
2277     AliInfo(Form("Seed for random number generation = %d ", fSeed)); 
2278
2279     // Run Number
2280     
2281     // first check that run number is not already set
2282     if(fRun < 0) {    
2283         if (gSystem->Getenv("DC_RUN")) {
2284                 fRun = atoi(gSystem->Getenv("DC_RUN"));
2285         }
2286     } else {
2287         if (gSystem->Getenv("DC_RUN")) {
2288                 AliInfo(Form("Run number already set (%d): DC_RUN variable ignored!", fRun));
2289         }
2290     }
2291     
2292     AliInfo(Form("Run number = %d", fRun)); 
2293 }
2294
2295 //---------------------------------------------------------------------
2296 void AliSimulation::WriteGRPEntry()
2297 {
2298   // Get the necessary information from galice (generator, trigger etc) and
2299   // write a GRP entry corresponding to the settings in the Config.C used
2300   // note that Hall probes and Cavern and Surface Atmos pressures are not simulated.
2301
2302
2303   AliInfo("Writing global run parameters entry into the OCDB");
2304
2305   AliGRPObject* grpObj = new AliGRPObject();
2306
2307   grpObj->SetRunType("PHYSICS");
2308   grpObj->SetTimeStart(fTimeStart);
2309   grpObj->SetTimeEnd(fTimeEnd); 
2310   grpObj->SetBeamEnergyIsSqrtSHalfGeV(); // new format of GRP: store sqrt(s)/2 in GeV
2311
2312   const AliGenerator *gen = gAlice->GetMCApp()->Generator();
2313   Int_t a = 0;
2314   Int_t z = 0;
2315
2316   if (gen) {
2317     TString projectile;
2318     gen->GetProjectile(projectile,a,z);
2319     TString target;
2320     gen->GetTarget(target,a,z);
2321     TString beamType = projectile + "-" + target;
2322     beamType.ReplaceAll(" ","");
2323     if (!beamType.CompareTo("-")) {
2324       grpObj->SetBeamType("UNKNOWN");
2325       grpObj->SetBeamEnergy(gen->GetEnergyCMS()/2);
2326     }
2327     else {
2328       grpObj->SetBeamType(beamType);
2329       if (z != 0) {
2330           grpObj->SetBeamEnergy(gen->GetEnergyCMS()/2 * a / z);
2331       } else {
2332           grpObj->SetBeamEnergy(gen->GetEnergyCMS()/2 );
2333       }
2334       // Heavy ion run, the event specie is set to kHighMult
2335       fEventSpecie = AliRecoParam::kHighMult;
2336       if ((strcmp(beamType,"p-p") == 0) ||
2337           (strcmp(beamType,"p-")  == 0) ||
2338           (strcmp(beamType,"-p")  == 0) ||
2339           (strcmp(beamType,"P-P") == 0) ||
2340           (strcmp(beamType,"P-")  == 0) ||
2341           (strcmp(beamType,"-P")  == 0)) {
2342         // Proton run, the event specie is set to kLowMult
2343         fEventSpecie = AliRecoParam::kLowMult;
2344       } 
2345     }
2346   } else {
2347     AliWarning("Unknown beam type and energy! Setting energy to 0");
2348     grpObj->SetBeamEnergy(0);
2349     grpObj->SetBeamType("UNKNOWN");
2350   }
2351
2352   UInt_t detectorPattern  = 0;
2353   Int_t nDets = 0;
2354   TObjArray *detArray = gAlice->Detectors();
2355   for (Int_t iDet = 0; iDet < AliDAQ::kNDetectors-1; iDet++) {
2356     if (detArray->FindObject(AliDAQ::OfflineModuleName(iDet))) {
2357       AliDebug(1, Form("Detector #%d found: %s", iDet, AliDAQ::OfflineModuleName(iDet)));
2358       detectorPattern |= (1 << iDet);
2359       nDets++;
2360     }
2361   }
2362   // CTP
2363   if (!fTriggerConfig.IsNull())
2364     detectorPattern |= (1 << AliDAQ::DetectorID("TRG"));
2365
2366   // HLT
2367   if (!fRunHLT.IsNull())
2368     detectorPattern |= (1 << AliDAQ::kHLTId);
2369
2370   grpObj->SetNumberOfDetectors((Char_t)nDets);
2371   grpObj->SetDetectorMask((Int_t)detectorPattern);
2372   grpObj->SetLHCPeriod("LHC08c");
2373   grpObj->SetLHCState("STABLE_BEAMS");
2374   //
2375   AliMagF *field = (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
2376   Float_t solenoidField = field ? TMath::Abs(field->SolenoidField()) : 0;
2377
2378   Float_t factorSol     = field ? field->GetFactorSol() : 0;
2379   Float_t currentSol    = TMath::Abs(factorSol)>1E-6 ? 
2380     TMath::Nint(TMath::Abs(solenoidField/factorSol))/5.*30000.*TMath::Abs(factorSol) : 0;
2381   //
2382   Float_t factorDip     = field ? field->GetFactorDip() : 0;
2383   Float_t currentDip    = 6000.*TMath::Abs(factorDip);
2384   //
2385   grpObj->SetL3Current(currentSol,(AliGRPObject::Stats)0);
2386   grpObj->SetDipoleCurrent(currentDip,(AliGRPObject::Stats)0);  
2387   grpObj->SetL3Polarity(factorSol>0 ? 0:1);  
2388   grpObj->SetDipolePolarity(factorDip>0 ? 0:1);
2389   if (field) grpObj->SetUniformBMap(field->IsUniform()); // for special MC with k5kGUniform map
2390   grpObj->SetPolarityConventionLHC();                    // LHC convention +/+ current -> -/- field main components
2391   //
2392   grpObj->SetCavernTemperature(0,(AliGRPObject::Stats)0);
2393   
2394   //grpMap->Add(new TObjString("fCavernPressure"),new TObjString("0")); ---> not inserted in simulation with the new object, since it is now an AliDCSSensor
2395
2396   // Now store the entry in OCDB
2397   AliCDBManager* man = AliCDBManager::Instance();
2398   
2399   man->SetLock(0, fKey);
2400   
2401   AliCDBStorage* sto = man->GetStorage(fGRPWriteLocation.Data());
2402   
2403
2404   AliCDBId id("GRP/GRP/Data", man->GetRun(), man->GetRun(), 1, 1);
2405   AliCDBMetaData *metadata= new AliCDBMetaData();
2406
2407   metadata->SetResponsible("alice-off@cern.ch");
2408   metadata->SetComment("Automatically produced GRP entry for Monte Carlo");
2409  
2410   sto->Put(grpObj,id,metadata);
2411   man->SetLock(1, fKey);
2412 }
2413
2414 //_____________________________________________________________________________
2415 time_t AliSimulation::GenerateTimeStamp() const
2416 {
2417   // Generate event time-stamp according to
2418   // SOR/EOR time from GRP
2419   if (fUseTimeStampFromCDB)
2420     return fTimeStart + gRandom->Integer(fTimeEnd-fTimeStart);
2421   else
2422     return 0;
2423 }