7bacab9f770d9bcdf5a0a6d07c398191fe48141f
[u/mrichter/AliRoot.git] / HLT / rec / AliHLTMiscImplementation.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   AliHLTMisc.cxx
20 /// @author Matthias Richter
21 /// @date   
22 /// @brief  Miscellaneous methods for the HLT AliRoot integration
23
24 #include "AliHLTMiscImplementation.h"
25 #include "AliHLTLogging.h"
26 #include "AliLog.h"
27 #include "AliCDBManager.h"
28 #include "AliCDBStorage.h"
29 #include "AliCDBEntry.h"
30 #include "AliGRPManager.h"
31 #include "AliRawReader.h"
32 #include "AliRawEventHeaderBase.h"
33 #include "AliTracker.h"
34 #ifndef HAVE_NOT_ALIESDHLTDECISION
35 #include "AliESDHLTDecision.h"
36 #endif //HAVE_NOT_ALIESDHLTDECISION
37 #include "TGeoGlobalMagField.h"
38 #include "AliHLTGlobalTriggerDecision.h"
39 #include "TClass.h"
40 #include "TStreamerInfo.h"
41 #include "TObjArray.h"
42
43 /** ROOT macro for the implementation of ROOT specific class methods */
44 ClassImp(AliHLTMiscImplementation);
45
46 AliHLTMiscImplementation::AliHLTMiscImplementation()
47 {
48 }
49
50 AliHLTMiscImplementation::~AliHLTMiscImplementation()
51 {
52   // see header file for function documentation
53 }
54
55 int AliHLTMiscImplementation::InitCDB(const char* cdbpath)
56 {
57   // see header file for function documentation
58   int iResult=0;
59   AliCDBManager* pCDB = AliCDBManager::Instance();
60   AliHLTLogging log;
61   if (!pCDB) {
62     log.Logging(kHLTLogError, "InitCDB", "CDB handling", "Could not get CDB instance");
63   } else {
64     if (cdbpath && cdbpath[0]!=0) {
65       TString uri=cdbpath;
66       if (!uri.BeginsWith("local://") &&
67           !uri.Contains("://")) {
68         // assume a local path if no uri specifier is found
69         uri="local://";
70         uri+=cdbpath;
71       }
72       pCDB->SetDefaultStorage(uri);
73       log.Logging(kHLTLogDebug, "InitCDB", "CDB handling", "CDB instance 0x%x", pCDB);
74     } else if (!pCDB->IsDefaultStorageSet()) {
75       const char* cdbUri="local://$ALICE_ROOT/OCDB";
76       pCDB->SetDefaultStorage(cdbUri);
77       pCDB->SetRun(0);
78       log.Logging(kHLTLogInfo, "InitCDB", "CDB handling", "set default URI: %s", cdbUri);
79     }
80   }
81   return iResult;
82 }
83
84 int AliHLTMiscImplementation::SetCDBRunNo(int runNo)
85 {
86   // see header file for function documentation
87   int iResult=0;
88   AliCDBManager* pCDB = AliCDBManager::Instance();
89   AliHLTLogging log;
90   if (!pCDB) {
91     log.Logging(kHLTLogError, "SetCDBRunNo", "CDB handling", "Could not get CDB instance");
92   } else {
93     pCDB->SetRun(runNo);
94   }
95   return iResult;
96 }
97
98 int AliHLTMiscImplementation::GetCDBRunNo() const
99 {
100   // see header file for function documentation
101   AliCDBManager* pCDB = AliCDBManager::Instance();
102   AliHLTLogging log;
103   if (!pCDB) {
104     log.Logging(kHLTLogError, "SetCDBRunNo", "CDB handling", "Could not get CDB instance");
105   } else {
106     return pCDB->GetRun();
107   }
108   return -1;
109 }
110
111 AliCDBEntry* AliHLTMiscImplementation::LoadOCDBEntry(const char* path, int runNo, int version, int subVersion) const
112 {
113   // see header file for function documentation
114   AliCDBManager* man = AliCDBManager::Instance();
115   if (!man) return NULL;
116   if (runNo<0) runNo=man->GetRun();
117
118   const char* uri=man->GetURI(path);
119   if (!uri) return NULL;
120
121   AliCDBStorage* store = AliCDBManager::Instance()->GetStorage(uri);
122   if (!store) {
123     return NULL;
124   }
125
126   TString strUri=store->GetURI();
127   bool bIsGrid=strUri.BeginsWith("alien://");
128
129   if (version<0) version = store->GetLatestVersion(path, runNo);
130
131   // OCDB objects on GRID have no sub version
132   if (subVersion<0 && !bIsGrid) subVersion = store->GetLatestSubVersion(path, runNo, version);
133   AliCDBEntry* entry=man->Get(path, runNo, version, subVersion);
134   if (entry) {
135     // there seems to be a problem with the caching of objects in the CDBManager
136     // regardless what version is specified it returns the object from the cache
137     AliCDBId id=entry->GetId();
138     if ((version<0 || id.GetVersion()==version) &&
139         (subVersion<0 || id.GetSubVersion()==subVersion)) {
140       // entry in the cache has the correct version
141       return entry;
142     }
143   }
144   return store->Get(path, runNo, version, subVersion);
145 }
146
147 TObject* AliHLTMiscImplementation::ExtractObject(AliCDBEntry* entry) const
148 {
149   // see header file for function documentation
150   if (!entry) return NULL;
151   return entry->GetObject();
152 }
153
154 int AliHLTMiscImplementation::CheckOCDBEntries(const TMap* const pMap) const
155 {
156   // check the availability of the OCDB entry descriptions in the TMap
157   //  key : complete OCDB path of the entry
158   //  value : auxiliary object - short description
159   int iResult=0;
160   if (!pMap) return -EINVAL;
161
162   const TMap* pStorages=AliCDBManager::Instance()->GetStorageMap();
163   Int_t runNo = GetCDBRunNo();
164
165   TIterator* next=pMap->MakeIterator();
166   if (!next) return -ENOENT;
167
168   TObject* pEntry=NULL;
169   while ((pEntry=next->Next())) {
170     // check if the entry has specific storage
171     AliCDBStorage* pStorage=NULL;
172     TObject* pStorageId=pStorages->GetValue(pEntry->GetName());
173     if (pStorageId) {
174       pStorage=AliCDBManager::Instance()->GetStorage(pStorageId->GetName());
175     } else {
176       pStorage=AliCDBManager::Instance()->GetDefaultStorage();
177     }
178
179     // FIXME: this will fail as soon as we have several specific storages
180     // access to the internal mapping information for specific storages is needed
181     if (pStorage->GetLatestVersion(pEntry->GetName(), runNo)<0) {
182       AliHLTLogging log;
183       log.Logging(kHLTLogError, "CheckOCDBEntries", "CDB handling", "can not find required OCDB object %s for run number %d in storage %s", pEntry->GetName(), runNo, pStorage->GetURI().Data());
184       iResult=-ENOENT;
185     } else {
186       AliHLTLogging log;
187       log.Logging(kHLTLogDebug, "CheckOCDBEntries", "CDB handling", "found required OCDB object %s for run number %d in storage %s", pEntry->GetName(), runNo, pStorage->GetURI().Data());
188     }
189   }
190   delete next;
191   next=NULL;
192
193   return iResult;
194 }
195
196 int AliHLTMiscImplementation::InitMagneticField() const
197 {
198   // see header file for function documentation
199
200   // BAD: unit test fails if I call TGeoGlobalMagField::Instance()
201   // at this point. Something goes wrong in the cleaning of the global
202   // ROOT onject
203   /*
204   if (TGeoGlobalMagField::Instance()->GetField()) {
205     // everything set, but think about storing the currents for
206     // a cross-check
207     return 0;
208   }
209   */
210
211   // The magnetic field is initialized once at the start
212   // of run. The fields are supposed to be constant througout the
213   // data taking of one run. The run is aborted if the changes
214   // exceed a certain limit.
215   AliGRPManager grpman;
216   if (grpman.ReadGRPEntry() && grpman.SetMagField()) {
217     return 0;
218   }
219
220   return -ENOENT;
221 }
222
223 AliHLTUInt64_t AliHLTMiscImplementation::GetTriggerMask(AliRawReader* rawReader) const
224 {
225   // see header file for function documentation
226   if (!rawReader) return 0;
227   AliHLTUInt64_t trgMask=0;
228   if (rawReader) {
229     const UInt_t* pattern=rawReader->GetTriggerPattern();
230     trgMask=pattern[1]&0xfffffff; // 28 upper bits of the 50 bit mask
231     trgMask<<=32;
232     trgMask|=pattern[0]; // 32 lower bits of the mask
233   }
234   return trgMask;
235 }
236
237 AliHLTUInt32_t AliHLTMiscImplementation::GetTimeStamp(AliRawReader* rawReader) const
238 {
239   // extract time stamp of the event from the event header
240   if (!rawReader) return 0;
241   const AliRawEventHeaderBase* eventHeader = rawReader->GetEventHeader();
242   if (!eventHeader) return 0;
243   return eventHeader->Get("Timestamp");
244 }
245
246 AliHLTUInt32_t AliHLTMiscImplementation::GetEventType(AliRawReader* rawReader) const
247 {
248   // extract event type from the event header
249   if (!rawReader) return 0;
250   const AliRawEventHeaderBase* eventHeader = rawReader->GetEventHeader();
251   if (!eventHeader) return 0;
252   return eventHeader->Get("Type");
253 }
254
255 const char* AliHLTMiscImplementation::GetBeamTypeFromGRP() const
256 {
257   // get beam type from GRP
258   return NULL;
259 }
260
261 Double_t AliHLTMiscImplementation::GetBz()
262 {
263   // Returns Bz.
264   return AliTracker::GetBz();
265 }
266
267 Double_t AliHLTMiscImplementation::GetBz(const Double_t *r)
268 {
269   // Returns Bz (kG) at the point "r" .
270   return AliTracker::GetBz(r);
271 }
272
273 void AliHLTMiscImplementation::GetBxByBz(const Double_t r[3], Double_t b[3])
274 {
275   // Returns Bx, By and Bz (kG) at the point "r" .
276   return AliTracker::GetBxByBz(r, b);
277 }
278
279 const TClass* AliHLTMiscImplementation::IsAliESDHLTDecision() const
280 {
281   // Return the IsA of the AliESDHLTDecision class
282 #ifndef HAVE_NOT_ALIESDHLTDECISION
283   return AliESDHLTDecision::Class();
284 #else // HAVE_NOT_ALIESDHLTDECISION
285   return NULL;
286 #endif // HAVE_NOT_ALIESDHLTDECISION
287 }
288
289 int AliHLTMiscImplementation::Copy(const AliHLTGlobalTriggerDecision* pDecision, TObject* object) const
290 {
291   // Copy HLT global trigger decision to AliESDHLTDecision container
292   if (!pDecision || !object) return -EINVAL;
293 #ifndef HAVE_NOT_ALIESDHLTDECISION
294   AliESDHLTDecision* pESDHLTDecision=NULL;
295   if (object->IsA()==NULL ||
296       object->IsA() != AliESDHLTDecision::Class() ||
297       (pESDHLTDecision=dynamic_cast<AliESDHLTDecision*>(object))==NULL) {
298 //     HLTError("can not copy HLT global decision to object of class \"%s\"", 
299 //           object->IsA()?object->IsA()->GetName():"NULL");
300     return -EINVAL;
301   }
302
303   pESDHLTDecision->~AliESDHLTDecision();
304   new (pESDHLTDecision) AliESDHLTDecision(pDecision->Result(), pDecision->GetTitle());
305
306 #endif // HAVE_NOT_ALIESDHLTDECISION
307   return 0;
308 }
309
310 int AliHLTMiscImplementation::InitStreamerInfos(const char* ocdbEntry) const
311 {
312   // init streamer infos for HLT reconstruction
313   // Root schema evolution is not enabled for AliHLTMessage and all streamed objects.
314   // Objects in the raw data payload rely on the availability of the correct stream info.
315   // The relevant streamer info for a specific run is stored in the OCDB.
316   int iResult=0;
317
318   AliCDBEntry* pEntry=LoadOCDBEntry(ocdbEntry);
319   TObject* pObject=NULL;
320   if (pEntry && (pObject=ExtractObject(pEntry))!=NULL)
321     {
322     TObjArray* pSchemas=dynamic_cast<TObjArray*>(pObject);
323     if (pSchemas) {
324       iResult=InitStreamerInfos(pSchemas);
325     } else {
326       AliError(Form("internal mismatch in OCDB entry %s: wrong class type", ocdbEntry));
327     }
328   } else {
329     AliWarning(Form("missing HLT reco data (%s), skipping initialization of streamer info for TObjects in HLT raw data payload", ocdbEntry));
330   }
331   return iResult;
332 }
333
334 int AliHLTMiscImplementation::InitStreamerInfos(TObjArray* pSchemas) const
335 {
336   // init streamer infos for HLT reconstruction from an array of TStreamerInfo objects
337
338   for (int i=0; i<pSchemas->GetEntriesFast(); i++) {
339     if (pSchemas->At(i)) {
340       TStreamerInfo* pSchema=dynamic_cast<TStreamerInfo*>(pSchemas->At(i));
341       if (pSchema) {
342         int version=pSchema->GetClassVersion();
343         TClass* pClass=TClass::GetClass(pSchema->GetName());
344         if (pClass) {
345           if (pClass->GetClassVersion()==version) {
346             AliDebug(0,Form("skipping schema definition %d version %d to class %s as this is the native version", i, version, pSchema->GetName()));
347             continue;
348           }
349           TObjArray* pInfos=pClass->GetStreamerInfos();
350           if (pInfos /*&& version<pInfos->GetEntriesFast()*/) {
351             if (pInfos->At(version)==NULL) {
352               TStreamerInfo* pClone=(TStreamerInfo*)pSchema->Clone();
353               if (pClone) {
354                 pClone->SetClass(pClass);
355                 pClone->BuildOld();
356                 pInfos->AddAtAndExpand(pClone, version);
357                 AliDebug(0,Form("adding schema definition %d version %d to class %s", i, version, pSchema->GetName()));
358               } else {
359                 AliError(Form("skipping schema definition %d (%s), unable to create clone object", i, pSchema->GetName()));
360               }
361             } else {
362               TStreamerInfo* pInfo=dynamic_cast<TStreamerInfo*>(pInfos->At(version));
363               if (pInfo && pInfo->GetClassVersion()==version) {
364                 AliDebug(0,Form("schema definition %d version %d already available in class %s, skipping ...", i, version, pSchema->GetName()));
365               } else {
366                 AliError(Form("can not verify version for already existing schema definition %d (%s) version %d: version of existing definition is %d", i, pSchema->GetName(), version, pInfo?pInfo->GetClassVersion():-1));
367               }
368             }
369           } else {
370             AliError(Form("skipping schema definition %d (%s), unable to set version %d in info array of size %d", i, pSchema->GetName(), version, pInfos?pInfos->GetEntriesFast():-1));
371           }
372         } else {
373           AliError(Form("skipping schema definition %d (%s), unable to find class", i, pSchema->GetName()));
374         }
375       } else {
376         AliError(Form("skipping schema definition %d, not of TStreamerInfo", i));
377       }
378     }
379   }
380
381   return 0;
382 }