2726a6477975dc58e812ca4f03a7e2eb0d508545
[u/mrichter/AliRoot.git] / HLT / sim / AliHLTSimulation.cxx
1 // $Id$
2
3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project        * 
5 //* ALICE Experiment at CERN, All rights reserved.                         *
6 //*                                                                        *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
8 //*                  for The ALICE HLT Project.                            *
9 //*                                                                        *
10 //* Permission to use, copy, modify and distribute this software and its   *
11 //* documentation strictly for non-commercial purposes is hereby granted   *
12 //* without fee, provided that the above copyright notice appears in all   *
13 //* copies and that both the copyright notice and this permission notice   *
14 //* appear in the supporting documentation. The authors make no claims     *
15 //* about the suitability of this software for any purpose. It is          *
16 //* provided "as is" without express or implied warranty.                  *
17 //**************************************************************************
18
19 /** @file   AliHLTSimulation.cxx
20     @author Matthias Richter
21     @date   
22     @brief  Binding class for HLT simulation in AliRoot. */
23
24 #include <cassert>
25 #include <cerrno>
26 #include "TObjArray.h"
27 #include "TObjString.h"
28 #include "AliHLTSimulation.h"
29 #include "AliSimulation.h"
30 #include "AliLog.h"
31 #include "AliRun.h"
32 #include "AliRunLoader.h"
33 #include "AliHeader.h"
34 #include "AliCDBManager.h"
35 #include "AliCDBEntry.h"
36 #include "AliCDBPath.h"
37 #include "AliCDBId.h"
38 #include "AliCDBMetaData.h"
39 #include "AliCDBStorage.h"
40 #include "AliGRPObject.h"
41 #include "AliHLTSystem.h"
42 #include "AliHLTPluginBase.h"
43 #include "AliRawReaderFile.h"
44 #include "AliRawReaderDate.h"
45 #include "AliRawReaderRoot.h"
46 #include "AliESDEvent.h"
47 #include "AliHLTOUTComponent.h"
48 #include "AliMagF.h"
49 #include "TGeoGlobalMagField.h"
50 #include "TSystem.h"
51 #include "TMath.h"
52
53 #if ALIHLTSIMULATION_LIBRARY_VERSION != LIBHLTSIM_VERSION
54 #error library version in header file and lib*.pkg do not match
55 #endif
56
57 /** ROOT macro for the implementation of ROOT specific class methods */
58 ClassImp(AliHLTSimulation);
59
60 AliHLTSimulation::AliHLTSimulation()
61   :
62   fOptions(),
63   fpPluginBase(new AliHLTPluginBase),
64   fpRawReader(NULL)
65 {
66   // see header file for class documentation
67   // or
68   // refer to README to build package
69   // or
70   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
71 }
72
73 AliHLTSimulation::~AliHLTSimulation()
74 {
75   // see header file for function documentation
76   if (fpPluginBase) delete fpPluginBase;
77   fpPluginBase=NULL;
78
79   if (fpRawReader) {
80     delete fpRawReader;
81   }
82   fpRawReader=NULL;
83 }
84
85 AliHLTSimulation* AliHLTSimulation::CreateInstance()
86 {
87   // see header file for function documentation
88   return new AliHLTSimulation;
89 }
90
91 int AliHLTSimulation::DeleteInstance(AliHLTSimulation* pSim)
92 {
93   // see header file for function documentation
94   assert(pSim!=NULL);
95   delete pSim;
96   return 0;
97 }
98
99 int AliHLTSimulation::Init(AliRunLoader* pRunLoader, const char* options)
100 {
101   // init the simulation
102   fOptions=options;
103   TString sysOp;
104
105   if(!fpPluginBase) {
106     AliError("internal initialization failed");
107     return -EINVAL;
108   }
109
110   AliHLTSystem* pSystem=fpPluginBase->GetInstance();
111   if (!pSystem) {
112     AliError("can not get AliHLTSystem instance");
113     return -ENOMEM;
114   }
115   if (pSystem->CheckStatus(AliHLTSystem::kError)) {
116     AliError("HLT system in error state");
117     return -EFAULT;
118   }
119
120   // scan options for specific entries
121   TObjArray* pTokens=fOptions.Tokenize(" ");
122   if (pTokens) {
123     int iEntries=pTokens->GetEntries();
124     for (int i=0; i<iEntries; i++) {
125       TString token=(((TObjString*)pTokens->At(i))->GetString());
126       if (token.Contains("rawfile=")) {
127         TString param=token.ReplaceAll("rawfile=", "");
128         if (param.EndsWith("/")) {
129           AliInfo(Form("creating AliRawReaderFile (%s)", param.Data()));
130           fpRawReader = new AliRawReaderFile(param);
131         } else if (param.EndsWith(".root")) {
132           AliInfo(Form("creating AliRawReaderRoot (%s)", param.Data()));
133           fpRawReader = new AliRawReaderRoot(param);
134         } else if (!param.IsNull()) {
135           AliInfo(Form("creating AliRawReaderDate (%s)", param.Data()));
136           fpRawReader = new AliRawReaderDate(param);
137         }
138         if (fpRawReader) {
139             fpRawReader->RewindEvents();
140             int count=0;
141             for ( ; fpRawReader->NextEvent(); count++) {/* empty body */};
142             if (count!=pRunLoader->GetNumberOfEvents()) {
143               AliError(Form("mismatch in event count: runloader %d, rawreader %d; ignoring rawreader", 
144                             pRunLoader->GetNumberOfEvents(), count));
145               count=0;
146             }
147             if (count>0) {
148               fpRawReader->RewindEvents();
149               fpRawReader->NextEvent();
150             } else {
151               delete fpRawReader;
152               fpRawReader=NULL;
153             }
154         }
155       } else if (token.Contains("writerawfiles=")) {
156         if (!token.ReplaceAll("writerawfiles=", "").Contains("HLT")) {
157           AliHLTOUTComponent::ClearGlobalOption(AliHLTOUTComponent::kWriteRawFiles);
158         }
159       } else {
160         if (sysOp.Length()>0) sysOp+=" ";
161         sysOp+=token;
162       }
163     }
164     delete pTokens;
165   }
166
167   AliCDBManager* man = AliCDBManager::Instance();
168   if (man && man->IsDefaultStorageSet())
169   {
170     int runNo=pRunLoader->GetHeader()->GetRun();
171
172     // init solenoid field
173     Double_t solenoidBz=0;
174     AliMagF *field = (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
175     if (field) {
176       // this field definition is rather awkward: AliMagF::SolenoidField returns
177       // a signed value, the amazing thing is that the sign is opposite to that
178       // one in the factor. So the abs value has to be used. Lets assume, there
179       // is a reason for that confusing implementation ...
180       solenoidBz=TMath::Abs(field->SolenoidField())*field->Factor();
181       AliDebug(0,Form("magnetic field: %f %f", field->SolenoidField(),field->Factor()));
182     } else {
183       // workaround for bug #51285
184       AliError("can not get the AliMagF instance, falling back to GRP entry");
185       AliCDBEntry *pGRPEntry = man->Get("GRP/GRP/Data", runNo);
186       if (pGRPEntry) {
187         AliGRPObject* pGRPData=dynamic_cast<AliGRPObject*>(pGRPEntry->GetObject());
188         assert(pGRPData!=NULL);
189         if (pGRPData) {
190           // this is just a workaround at the moment, common functionality in AliReconstruction
191           // is needed to reconstruct the magnetic field in a common way
192           // the code is partly taken from AliReconstruction::InitGRP
193           Bool_t ok = kTRUE;
194           Float_t l3Current = pGRPData->GetL3Current((AliGRPObject::Stats)0);
195           if (l3Current == AliGRPObject::GetInvalidFloat()) {
196             AliError("GRP/GRP/Data entry:  missing value for the L3 current !");
197             ok = kFALSE;
198           }
199     
200           Char_t l3Polarity = pGRPData->GetL3Polarity();
201           if (l3Polarity == AliGRPObject::GetInvalidChar()) {
202             AliError("GRP/GRP/Data entry:  missing value for the L3 polarity !");
203             ok = kFALSE;
204           }
205           
206           if (ok) {
207             solenoidBz=l3Current/6000;
208             if (l3Polarity) solenoidBz*=-1;
209           } else {
210             AliError("invalid L3 field information in GRP entry");
211           }
212         }
213       }
214     }
215     const char* cdbSolenoidPath="HLT/ConfigHLT/SolenoidBz";
216     TString cdbSolenoidParam;
217     cdbSolenoidParam.Form("-solenoidBz %f", solenoidBz);
218
219     // check if the entry is already there
220     AliCDBEntry *pEntry = man->Get(cdbSolenoidPath, runNo);
221     TObjString* pString=NULL;
222     if (pEntry) pString=dynamic_cast<TObjString*>(pEntry->GetObject());
223
224     if (!pEntry || !pString || pString->GetString().CompareTo(cdbSolenoidParam)!=0) {
225       TObjString obj(cdbSolenoidParam);
226       AliCDBPath cdbSolenoidEntry(cdbSolenoidPath);
227       AliCDBId cdbSolenoidId(cdbSolenoidEntry, runNo, runNo, 0, 0);
228       AliCDBMetaData cdbMetaData;
229       cdbMetaData.SetResponsible("Matthias.Richter@cern.ch");
230       cdbMetaData.SetComment("Automatically produced GRP entry (AliHLTSimulation) for the magnetic field initialization of HLT components");
231       man->Put(&obj, cdbSolenoidId, &cdbMetaData);
232
233       // unload the cache due to bug #51281
234       man->UnloadFromCache(cdbSolenoidPath);
235     }
236   } else if (man) {
237     AliError("OCDB default storage not yet set, can not prepare OCDB entries");    
238   } else {
239     AliError("unable to get instance of AliCDBMetaData, can not prepare OCDB entries");    
240   }
241
242   // scan options
243   if (pSystem->ScanOptions(sysOp.Data())<0) {
244     AliError("error setting options for HLT system");
245     return -EINVAL;     
246   }
247
248   if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
249     if ((pSystem->Configure(fpRawReader, pRunLoader))<0) {
250       AliError("error during HLT system configuration");
251       return -EFAULT;
252     }
253   }
254
255   return 0;
256 }
257
258
259 int AliHLTSimulation::Run(AliRunLoader* pRunLoader)
260 {
261   // HLT reconstruction for simulated data  
262   if(!fpPluginBase) {
263     AliError("internal initialization failed");
264     return -EINVAL;
265   }
266
267   if(!pRunLoader) {
268     AliError("Missing RunLoader! 0x0");
269     return -EINVAL;
270   }
271
272   int nEvents = pRunLoader->GetNumberOfEvents();
273   int iResult=0;
274
275   AliHLTSystem* pSystem=fpPluginBase->GetInstance();
276   if (!pSystem) {
277     AliError("can not get AliHLTSystem instance");
278     return -ENOMEM;
279   }
280
281   if (pSystem->CheckStatus(AliHLTSystem::kError)) {
282     AliError("HLT system in error state");
283     return -EFAULT;
284   }
285
286   // Note: the rawreader is already placed at the first event
287   if ((iResult=pSystem->Reconstruct(1, pRunLoader, fpRawReader))>=0) {
288     pSystem->FillESD(0, pRunLoader, NULL);
289     for (int i=1; i<nEvents; i++) {
290       if (fpRawReader && !fpRawReader->NextEvent()) {
291         AliError("mismatch in event count, rawreader corrupted");
292         break;
293       }
294       pSystem->Reconstruct(1, pRunLoader, fpRawReader);
295       pSystem->FillESD(i, pRunLoader, NULL);
296     }
297     // send specific 'event' to execute the stop sequence
298     pSystem->Reconstruct(0, NULL, NULL);
299   }
300   return iResult;
301 }
302
303
304 AliHLTSimulation* AliHLTSimulationCreateInstance()
305 {
306   // see header file for function documentation
307   return AliHLTSimulation::CreateInstance();
308 }
309
310 int AliHLTSimulationDeleteInstance(AliHLTSimulation* pSim)
311 {
312   // see header file for function documentation
313   return AliHLTSimulation::DeleteInstance(pSim);
314 }
315
316 int AliHLTSimulationInit(AliHLTSimulation* pSim, AliRunLoader* pRunLoader, const char* options)
317 {
318   assert(pSim!=NULL);
319   if (pSim) {
320     return pSim->Init(pRunLoader, options);
321   }
322   return -ENODEV;
323 }
324
325 int AliHLTSimulationRun(AliHLTSimulation* pSim, AliRunLoader* pRunLoader)
326 {
327   assert(pSim!=NULL);
328   if (pSim) {
329     return pSim->Run(pRunLoader);
330   }
331   return -ENODEV;
332 }
333
334 int AliHLTSimulationGetLibraryVersion()
335 {
336   // see header file for function documentation
337   return LIBHLTSIM_VERSION;
338 }
339
340 int AliHLTSimulationSetup(AliHLTSimulation* /*pHLTSim*/, AliSimulation* pSim, const char* specificObjects)
341 {
342   // see header file for function documentation
343
344   // this is an attempt to solve issue #48360
345   // since there are many jobs running in parallel during the production,
346   // all the jobs want to put entries into the OCDB. The solution is to
347   // make them temporary, since they are only used to propagate information
348   // from the simulation to the reconstruction.
349
350   if (!pSim) return -EINVAL;
351   const char* entries[]={
352     "HLT/ConfigHLT/SolenoidBz",
353     NULL
354   };
355
356   TString specificStorage; 
357   specificStorage.Form("local://%s",gSystem->pwd());
358   for (const char** pEntry=entries; *pEntry!=NULL; pEntry++) {
359     const char* pObject=specificObjects?strstr(specificObjects, *pEntry):NULL;
360     if (pObject) {
361       // skip this entry if it is found in the list and either
362       // last one or separated by a blank
363       pObject+=strlen(*pEntry);
364       if (*pObject==0 || *pObject==' ') continue;
365     }
366     pSim->SetSpecificStorage(*pEntry, specificStorage.Data());
367   }
368
369   return 0;
370 }
371
372 #ifndef HAVE_COMPILEINFO
373 extern "C" void CompileInfo(const char*& date, const char*& time)
374 {
375   // the fall back compile info of the HLTsim library
376   // this is not up-to-date if other files have been changed and recompiled
377   date=__DATE__; time=__TIME__;
378   return;
379 }
380 #endif