]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/rec/AliHLTMiscImplementation.cxx
881517b5f6e9014529955fd57bc265dbf9a861f7
[u/mrichter/AliRoot.git] / HLT / rec / AliHLTMiscImplementation.cxx
1 // $Id$
2
3 //**************************************************************************
4 //* This file is property of and copyright by the                          * 
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   2009-07-07
22 /// @brief  Implementation of various glue functions implemented in dynamically
23 ///         loaded libraries
24
25 #include "AliHLTMiscImplementation.h"
26 #include "AliHLTLogging.h"
27 #include "AliHLTErrorGuard.h"
28 #include "AliLog.h"
29 #include "AliCDBManager.h"
30 #include "AliCDBStorage.h"
31 #include "AliCDBEntry.h"
32 #include "AliGRPManager.h"
33 #include "AliRawReader.h"
34 #include "AliRawEventHeaderBase.h"
35 #include "AliTracker.h"
36 #include "AliESDtrack.h"
37 #include "AliESDHLTDecision.h"
38 #include "TGeoGlobalMagField.h"
39 #include "AliHLTGlobalTriggerDecision.h"
40 #include "TClass.h"
41 #include "TStreamerInfo.h"
42 #include "TObjArray.h"
43
44 /** ROOT macro for the implementation of ROOT specific class methods */
45 ClassImp(AliHLTMiscImplementation);
46
47 AliHLTMiscImplementation::AliHLTMiscImplementation()
48 {
49 }
50
51 AliHLTMiscImplementation::~AliHLTMiscImplementation()
52 {
53   // see header file for function documentation
54 }
55
56 int AliHLTMiscImplementation::InitCDB(const char* cdbpath)
57 {
58   // see header file for function documentation
59   int iResult=0;
60   AliCDBManager* pCDB = AliCDBManager::Instance();
61   AliHLTLogging log;
62   if (!pCDB) {
63     log.Logging(kHLTLogError, "InitCDB", "CDB handling", "Could not get CDB instance");
64   } else {
65     if (cdbpath && cdbpath[0]!=0) {
66       TString uri=cdbpath;
67       if (!uri.BeginsWith("local://") &&
68           !uri.Contains("://")) {
69         // assume a local path if no uri specifier is found
70         uri="local://";
71         uri+=cdbpath;
72       }
73       pCDB->SetDefaultStorage(uri);
74       log.Logging(kHLTLogDebug, "InitCDB", "CDB handling", "CDB instance 0x%x", pCDB);
75     } else if (!pCDB->IsDefaultStorageSet()) {
76       const char* cdbUri="local://$ALICE_ROOT/OCDB";
77       pCDB->SetDefaultStorage(cdbUri);
78       pCDB->SetRun(0);
79       log.Logging(kHLTLogInfo, "InitCDB", "CDB handling", "set default URI: %s", cdbUri);
80     }
81   }
82   return iResult;
83 }
84
85 int AliHLTMiscImplementation::SetCDBRunNo(int runNo)
86 {
87   // see header file for function documentation
88   int iResult=0;
89   AliCDBManager* pCDB = AliCDBManager::Instance();
90   AliHLTLogging log;
91   if (!pCDB) {
92     log.Logging(kHLTLogError, "SetCDBRunNo", "CDB handling", "Could not get CDB instance");
93   } else {
94     pCDB->SetRun(runNo);
95   }
96   return iResult;
97 }
98
99 int AliHLTMiscImplementation::GetCDBRunNo() const
100 {
101   // see header file for function documentation
102   AliCDBManager* pCDB = AliCDBManager::Instance();
103   AliHLTLogging log;
104   if (!pCDB) {
105     log.Logging(kHLTLogError, "SetCDBRunNo", "CDB handling", "Could not get CDB instance");
106   } else {
107     return pCDB->GetRun();
108   }
109   return -1;
110 }
111
112 AliCDBEntry* AliHLTMiscImplementation::LoadOCDBEntry(const char* path, int runNo) const
113 {
114   // see header file for function documentation
115   if (!path) return NULL;
116   AliHLTLogging log;
117
118   AliCDBManager* man = AliCDBManager::Instance();
119   if (!man) {
120     ALIHLTERRORGUARD(1, "failed to access CDB manager");
121     return NULL;
122   }
123   if (runNo<0) runNo=man->GetRun();
124
125   // check the cache first if no specific version required
126   { //condition was deprecated, but keep for formatting
127     const TMap* pCache=man->GetEntryCache();
128     TObject* pEntryObj=NULL;
129     if (pCache && (pEntryObj=pCache->GetValue(path))!=NULL) {
130       AliCDBEntry* pEntry=dynamic_cast<AliCDBEntry*>(pEntryObj);
131       if (pEntry) {
132         log.Logging(kHLTLogDebug, "AliHLTMiscImplementation::LoadOCDBEntry", "CDB handling", "using OCDB object %s from cache", path);
133         return pEntry;
134       } else {
135         log.Logging(kHLTLogError, "AliHLTMiscImplementation::LoadOCDBEntry", "CDB handling", "invalid OCDB object %s found in cache, not of type AliCDBEntry", path);
136       }
137     }
138   }
139
140   const char* uri=man->GetURI(path);
141   if (!uri) {
142     log.Logging(kHLTLogError, "AliHLTMiscImplementation::LoadOCDBEntry", "CDB handling", "can not find URI for CDB object \"%s\"", path);
143     return NULL;
144   }
145
146   AliCDBStorage* store = AliCDBManager::Instance()->GetStorage(uri);
147   if (!store) {
148     log.Logging(kHLTLogError, "AliHLTMiscImplementation::LoadOCDBEntry", "CDB handling", "can not find storage for URI \"%s\"", uri);
149     return NULL;
150   }
151
152   int latest = store->GetLatestVersion(path, runNo);
153   if (latest<0) {
154     log.Logging(kHLTLogError, "AliHLTMiscImplementation::LoadOCDBEntry", "CDB handling", "Could not find an entry for \"%s\" in storage \"%s\", run %d.", path, uri, runNo>=0?runNo:man->GetRun());
155     return NULL;
156   }
157
158   AliCDBEntry* entry=man->Get(path, runNo);
159   return entry;
160 }
161
162 TObject* AliHLTMiscImplementation::ExtractObject(AliCDBEntry* entry) const
163 {
164   // see header file for function documentation
165   if (!entry) return NULL;
166   return entry->GetObject();
167 }
168
169 int AliHLTMiscImplementation::CheckOCDBEntries(const TMap* const pMap) const
170 {
171   // check the availability of the OCDB entry descriptions in the TMap
172   //  key : complete OCDB path of the entry
173   //  value : auxiliary object - short description
174   // check uses AliCDBStorage::GetLatestVersion, which is the only method
175   // to check the existence without risking AliFatal
176
177   int iResult=0;
178   if (!pMap) return -EINVAL;
179   AliHLTLogging log;
180
181   AliCDBManager* man = AliCDBManager::Instance();
182   if (!man) {
183     ALIHLTERRORGUARD(1, "failed to access CDB manager");
184     return -ENOSYS;
185   }
186   const TMap* pCache=man->GetEntryCache();
187
188   Int_t runNo = GetCDBRunNo();
189
190   TIterator* next=pMap->MakeIterator();
191   if (!next) return -EFAULT;
192
193   TObject* pEntry=NULL;
194   while ((pEntry=next->Next())) {
195     // check if already on cache
196     if (pCache && pCache->GetValue(pEntry->GetName())!=NULL) {
197       log.Logging(kHLTLogDebug, "AliHLTMiscImplementation::CheckOCDBEntries", "CDB handling", "found OCDB object %s on cache", pEntry->GetName());      
198       continue;
199     }
200
201     // check if the entry has specific storage
202     const char* uri=man->GetURI(pEntry->GetName());
203     if (!uri) {
204       log.Logging(kHLTLogError, "AliHLTMiscImplementation::CheckOCDBEntries", "CDB handling", "can not find URI for CDB object \"%s\"", pEntry->GetName());
205       return -ENODEV;
206     }
207
208     AliCDBStorage* pStorage = AliCDBManager::Instance()->GetStorage(uri);
209     if (!pStorage) {
210       log.Logging(kHLTLogError, "AliHLTMiscImplementation::CheckOCDBEntries", "CDB handling", "can not find storage for URI \"%s\"", uri);
211       return -EBADF;
212     }
213
214     // GetLatestVersion is the only method to check the existence without potential AliFatal
215     if (pStorage->GetLatestVersion(pEntry->GetName(), runNo)<0) {
216       log.Logging(kHLTLogError, "AliHLTMiscImplementation::CheckOCDBEntries", "CDB handling", "can not find required OCDB object %s for run number %d in storage %s", pEntry->GetName(), runNo, pStorage->GetURI().Data());
217       iResult=-ENOENT;
218     } else {
219       log.Logging(kHLTLogDebug, "AliHLTMiscImplementation::CheckOCDBEntries", "CDB handling", "found required OCDB object %s for run number %d in storage %s", pEntry->GetName(), runNo, pStorage->GetURI().Data());
220     }
221   }
222   delete next;
223   next=NULL;
224
225   return iResult;
226 }
227
228 int AliHLTMiscImplementation::InitMagneticField() const
229 {
230   // see header file for function documentation
231
232   // BAD: unit test fails if I call TGeoGlobalMagField::Instance()
233   // at this point. Something goes wrong in the cleaning of the global
234   // ROOT onject
235   /*
236   if (TGeoGlobalMagField::Instance()->GetField()) {
237     // everything set, but think about storing the currents for
238     // a cross-check
239     return 0;
240   }
241   */
242
243   // The magnetic field is initialized once at the start
244   // of run. The fields are supposed to be constant througout the
245   // data taking of one run. The run is aborted if the changes
246   // exceed a certain limit.
247   AliGRPManager grpman;
248   if (grpman.ReadGRPEntry() && grpman.SetMagField()) {
249     return 0;
250   }
251
252   return -ENOENT;
253 }
254
255 AliHLTUInt64_t AliHLTMiscImplementation::GetTriggerMask(AliRawReader* rawReader) const
256 {
257   // see header file for function documentation
258   if (!rawReader) return 0;
259   AliHLTUInt64_t trgMask=0;
260   if (rawReader) {
261     const UInt_t* pattern=rawReader->GetTriggerPattern();
262     trgMask=pattern[1]&0xfffffff; // 28 upper bits of the 50 bit mask
263     trgMask<<=32;
264     trgMask|=pattern[0]; // 32 lower bits of the mask
265   }
266   return trgMask;
267 }
268
269 AliHLTUInt32_t AliHLTMiscImplementation::GetTimeStamp(AliRawReader* rawReader) const
270 {
271   // extract time stamp of the event from the event header
272   if (!rawReader) return kMaxUInt;
273   const AliRawEventHeaderBase* eventHeader = rawReader->GetEventHeader();
274   if (!eventHeader) return kMaxUInt;
275   return eventHeader->Get("Timestamp");
276 }
277
278 AliHLTUInt32_t AliHLTMiscImplementation::GetEventType(AliRawReader* rawReader) const
279 {
280   // extract event type from the event header
281   if (!rawReader) return 0;
282   const AliRawEventHeaderBase* eventHeader = rawReader->GetEventHeader();
283   if (!eventHeader) return 0;
284   return eventHeader->Get("Type");
285 }
286
287 const char* AliHLTMiscImplementation::GetBeamTypeFromGRP() const
288 {
289   // get beam type from GRP
290   return NULL;
291 }
292
293 Double_t AliHLTMiscImplementation::GetBz()
294 {
295   // Returns Bz.
296   return AliTracker::GetBz();
297 }
298
299 Double_t AliHLTMiscImplementation::GetBz(const Double_t *r)
300 {
301   // Returns Bz (kG) at the point "r" .
302   return AliTracker::GetBz(r);
303 }
304
305 void AliHLTMiscImplementation::GetBxByBz(const Double_t r[3], Double_t b[3])
306 {
307   // Returns Bx, By and Bz (kG) at the point "r" .
308   return AliTracker::GetBxByBz(r, b);
309 }
310
311 const TClass* AliHLTMiscImplementation::IsAliESDHLTDecision() const
312 {
313   // Return the IsA of the AliESDHLTDecision class
314   return AliESDHLTDecision::Class();
315 }
316
317 int AliHLTMiscImplementation::Copy(const AliHLTGlobalTriggerDecision* pDecision, TObject* object) const
318 {
319   // Copy HLT global trigger decision to AliESDHLTDecision container
320   if (!pDecision || !object) return -EINVAL;
321   AliESDHLTDecision* pESDHLTDecision=NULL;
322   if (object->IsA()==NULL ||
323       object->IsA() != AliESDHLTDecision::Class() ||
324       (pESDHLTDecision=dynamic_cast<AliESDHLTDecision*>(object))==NULL) {
325 //     HLTError("can not copy HLT global decision to object of class \"%s\"", 
326 //           object->IsA()?object->IsA()->GetName():"NULL");
327     return -EINVAL;
328   }
329
330   pESDHLTDecision->~AliESDHLTDecision();
331   new (pESDHLTDecision) AliESDHLTDecision(pDecision->Result(), pDecision->GetTitle());
332
333   return 0;
334 }
335
336 int AliHLTMiscImplementation::InitStreamerInfos(const char* ocdbEntry) const
337 {
338   // init streamer infos for HLT reconstruction
339   // Root schema evolution is not enabled for AliHLTMessage and all streamed objects.
340   // Objects in the raw data payload rely on the availability of the correct stream info.
341   // The relevant streamer info for a specific run is stored in the OCDB.
342   int iResult=0;
343
344   AliCDBEntry* pEntry=LoadOCDBEntry(ocdbEntry);
345   TObject* pObject=NULL;
346   if (pEntry && (pObject=ExtractObject(pEntry))!=NULL)
347     {
348     TObjArray* pSchemas=dynamic_cast<TObjArray*>(pObject);
349     if (pSchemas) {
350       iResult=InitStreamerInfos(pSchemas);
351     } else {
352       AliError(Form("internal mismatch in OCDB entry %s: wrong class type", ocdbEntry));
353     }
354   } else {
355     AliWarning(Form("missing HLT reco data (%s), skipping initialization of streamer info for TObjects in HLT raw data payload", ocdbEntry));
356   }
357   return iResult;
358 }
359
360 int AliHLTMiscImplementation::InitStreamerInfos(TObjArray* pSchemas) const
361 {
362   // init streamer infos for HLT reconstruction from an array of TStreamerInfo objects
363
364   for (int i=0; i<pSchemas->GetEntriesFast(); i++) {
365     if (pSchemas->At(i)) {
366       TStreamerInfo* pSchema=dynamic_cast<TStreamerInfo*>(pSchemas->At(i));
367       if (pSchema) {
368         int version=pSchema->GetClassVersion();
369         TClass* pClass=TClass::GetClass(pSchema->GetName());
370         if (pClass) {
371           if (pClass->GetClassVersion()==version) {
372             AliDebug(0,Form("skipping schema definition %d version %d to class %s as this is the native version", i, version, pSchema->GetName()));
373             continue;
374           }
375           TObjArray* pInfos=pClass->GetStreamerInfos();
376           if (pInfos /*&& version<pInfos->GetEntriesFast()*/) {
377             if (pInfos->At(version)==NULL) {
378               TStreamerInfo* pClone=(TStreamerInfo*)pSchema->Clone();
379               if (pClone) {
380                 pClone->SetClass(pClass);
381                 pClone->BuildOld();
382                 pInfos->AddAtAndExpand(pClone, version);
383                 AliDebug(0,Form("adding schema definition %d version %d to class %s", i, version, pSchema->GetName()));
384               } else {
385                 AliError(Form("skipping schema definition %d (%s), unable to create clone object", i, pSchema->GetName()));
386               }
387             } else {
388               TStreamerInfo* pInfo=dynamic_cast<TStreamerInfo*>(pInfos->At(version));
389               if (pInfo && pInfo->GetClassVersion()==version) {
390                 AliDebug(0,Form("schema definition %d version %d already available in class %s, skipping ...", i, version, pSchema->GetName()));
391               } else {
392                 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));
393               }
394             }
395           } else {
396             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));
397           }
398         } else {
399           AliError(Form("skipping schema definition %d (%s), unable to find class", i, pSchema->GetName()));
400         }
401       } else {
402         AliError(Form("skipping schema definition %d, not of TStreamerInfo", i));
403       }
404     }
405   }
406
407   return 0;
408 }
409
410 int AliHLTMiscImplementation::MergeStreamerInfo(TObjArray* tgt, const TObjArray* src, int iVerbosity) const
411 {
412   /// merge streamer info entries from source array to target array
413   /// return 1 if target array has been changed
414
415   // add all existing infos if not existing in the current one, or having
416   // different class version
417   int iResult=0;
418   if (!tgt || !src) return -EINVAL;
419
420   {
421     // check if all infos from the existing entry are in the new entry and with
422     // identical class version
423     TIter next(src);
424     TObject* nextobj=NULL;
425     while ((nextobj=next())) {
426       TStreamerInfo* srcInfo=dynamic_cast<TStreamerInfo*>(nextobj);
427       if (!srcInfo) continue;
428       TString srcInfoName=srcInfo->GetName();
429
430       int i=0;
431       for (; i<tgt->GetEntriesFast(); i++) {
432         if (tgt->At(i)==NULL) continue;
433         if (srcInfoName.CompareTo(tgt->At(i)->GetName())!=0) continue;
434         // TODO: 2010-08-23 some more detailed investigation is needed.
435         // Structures used for data exchange, e.g. AliHLTComponentDataType
436         // or AliHLTEventDDLV1 do not have a class version, but need to be stored in the
437         // streamer info. Strictly speaking not, because those structures are not supposed
438         // to be changed at all, so they should be the same in all versions in the future.
439         // There has been a problem with detecting whether the streamer info is already in
440         // the target array if the srcInfo has class version -1. As it just concerns
441         // structures not going to be changed we can safely skip checking the class version,
442         // as long as the entry is already in the target streamer infos it does not need
443         // to be copied again.
444         if (srcInfo->GetClassVersion()<0) break;
445         TStreamerInfo* tgtInfo=dynamic_cast<TStreamerInfo*>(tgt->At(i));
446         if (tgtInfo && tgtInfo->GetClassVersion()==srcInfo->GetClassVersion()) break;
447       }
448       if (i<tgt->GetEntriesFast()) continue;
449
450       iResult=1;
451       if (iVerbosity>0) {
452         AliInfo(Form("adding streamer info for class %s version %d", srcInfoName.Data(), srcInfo->GetClassVersion()));
453       }
454       tgt->Add(srcInfo);
455     }
456   }
457
458   return iResult;
459 }
460
461 void AliHLTMiscImplementation::SetAliESDtrackOnlineModeFlag(bool mode) const
462 {
463   /// set the online mode flag of AliESDtrack
464   AliESDtrack::OnlineMode(mode);
465 }
466
467 bool AliHLTMiscImplementation::GetAliESDtrackOnlineModeFlag() const
468 {
469   /// get status of the online mode flag of AliESDtrack
470   return AliESDtrack::OnlineMode();
471 }