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