]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/rec/AliHLTReconstructor.cxx
extract streamer info from the HLTOUT payload and make it available before
[u/mrichter/AliRoot.git] / HLT / rec / AliHLTReconstructor.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   AliHLTReconstructor.cxx
20     @author Matthias Richter
21     @date   
22     @brief  Binding class for HLT reconstruction in AliRoot. */
23
24 #include <TSystem.h>
25 #include <TObjString.h>
26 #include "TFile.h"
27 #include "TTree.h"
28 #include "TObject.h"
29 #include "TObjArray.h"
30 #include "TClass.h"
31 #include "TStreamerInfo.h"
32 #include "AliHLTReconstructor.h"
33 #include "AliLog.h"
34 #include "AliRawReader.h"
35 #include "AliESDEvent.h"
36 #include "AliHLTSystem.h"
37 #include "AliHLTOUTRawReader.h"
38 #include "AliHLTOUTDigitReader.h"
39 #include "AliHLTEsdManager.h"
40 #include "AliHLTPluginBase.h"
41 #include "AliHLTMisc.h"
42 #include "AliCDBManager.h"
43 #include "AliCDBEntry.h"
44 #include "AliHLTMessage.h"
45
46 class AliCDBEntry;
47
48 ClassImp(AliHLTReconstructor)
49
50 AliHLTReconstructor::AliHLTReconstructor()
51   : 
52   AliReconstructor(),
53   fFctProcessHLTOUT(NULL),
54   fpEsdManager(NULL),
55   fpPluginBase(new AliHLTPluginBase)
56   , fFlags(0)
57
58   //constructor
59 }
60
61 AliHLTReconstructor::AliHLTReconstructor(const char* options)
62   : 
63   AliReconstructor(),
64   fFctProcessHLTOUT(NULL),
65   fpEsdManager(NULL),
66   fpPluginBase(new AliHLTPluginBase)
67   , fFlags(0)
68
69   //constructor
70   if (options) Init(options);
71 }
72
73 AliHLTReconstructor::~AliHLTReconstructor()
74
75   //destructor
76
77   if (fpPluginBase) {
78   AliHLTSystem* pSystem=fpPluginBase->GetInstance();
79   if (pSystem) {
80     AliDebug(0, Form("terminate HLT system: status %#x", pSystem->GetStatusFlags()));
81     if (pSystem->CheckStatus(AliHLTSystem::kStarted)) {
82       // send specific 'event' to execute the stop sequence
83       pSystem->Reconstruct(0, NULL, NULL);
84     }
85   }
86   delete fpPluginBase;
87   }
88   fpPluginBase=NULL;
89
90   if (fpEsdManager) AliHLTEsdManager::Delete(fpEsdManager);
91   fpEsdManager=NULL;
92 }
93
94 void AliHLTReconstructor::Init(const char* options)
95 {
96   // init the reconstructor
97   SetOption(options);
98   Init();
99 }
100
101 void AliHLTReconstructor::Init()
102 {
103   // init the reconstructor
104   if (!fpPluginBase) {
105     AliError("internal memory error: can not get AliHLTSystem instance from plugin");
106     return;
107   }
108
109   AliHLTSystem* pSystem=fpPluginBase->GetInstance();
110   if (!pSystem) {
111     AliError("can not create AliHLTSystem object");
112     return;
113   }
114   if (pSystem->CheckStatus(AliHLTSystem::kError)) {
115     AliError("HLT system in error state");
116     return;
117   }
118
119   TString esdManagerOptions;
120
121   // the options scan has been moved to AliHLTSystem, the old code
122   // here is kept to be able to run an older version of the HLT code
123   // with newer AliRoot versions.
124   TString libs("");
125   TString option = GetOption();
126   TObjArray* pTokens=option.Tokenize(" ");
127   option="";
128   if (pTokens) {
129     int iEntries=pTokens->GetEntries();
130     for (int i=0; i<iEntries; i++) {
131       TString token=(((TObjString*)pTokens->At(i))->GetString());
132       if (token.Contains("loglevel=")) {
133         TString param=token.ReplaceAll("loglevel=", "");
134         if (param.IsDigit()) {
135           pSystem->SetGlobalLoggingLevel((AliHLTComponentLogSeverity)param.Atoi());
136         } else if (param.BeginsWith("0x") &&
137                    param.Replace(0,2,"",0).IsHex()) {
138           int severity=0;
139           sscanf(param.Data(),"%x", &severity);
140           pSystem->SetGlobalLoggingLevel((AliHLTComponentLogSeverity)severity);
141         } else {
142           AliWarning("wrong parameter for option \'loglevel=\', (hex) number expected");
143         }
144       } else if (token.Contains("alilog=off")) {
145         pSystem->SwitchAliLog(0);
146       } else if (token.CompareTo("ignore-hltout")==0) {
147         fFlags|=kAliHLTReconstructorIgnoreHLTOUT;
148       } else if (token.Contains("esdmanager=")) {
149         token.ReplaceAll("esdmanager=", "");
150         token.ReplaceAll(","," ");
151         token.ReplaceAll("'","");
152         esdManagerOptions=token;
153       } else if (token.BeginsWith("lib") && token.EndsWith(".so")) {
154         libs+=token;
155         libs+=" ";
156       } else {
157         if (option.Length()>0) option+=" ";
158         option+=token;
159       }
160     }
161     delete pTokens;
162   }
163
164   if (!libs.IsNull() &&
165       (!pSystem->CheckStatus(AliHLTSystem::kLibrariesLoaded)) &&
166       (pSystem->LoadComponentLibraries(libs.Data())<0)) {
167     AliError("error while loading HLT libraries");
168     return;
169   }
170
171   if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
172     typedef int (*AliHLTSystemSetOptions)(AliHLTSystem* pInstance, const char* options);
173     gSystem->Load("libHLTinterface.so");
174     AliHLTSystemSetOptions pFunc=(AliHLTSystemSetOptions)(gSystem->DynFindSymbol("libHLTinterface.so", "AliHLTSystemSetOptions"));
175     if (pFunc) {
176       if ((pFunc)(pSystem, option.Data())<0) {
177       AliError("error setting options for HLT system");
178       return;   
179       }
180     } else if (option.Length()>0) {
181       AliError(Form("version of HLT system does not support the options \'%s\'", option.Data()));
182       return;
183     }
184     if ((pSystem->Configure())<0) {
185       AliError("error during HLT system configuration");
186       return;
187     }
188   }
189
190   gSystem->Load("libHLTinterface.so");
191   fFctProcessHLTOUT=(void (*)())gSystem->DynFindSymbol("libHLTinterface.so", "AliHLTSystemProcessHLTOUT");
192
193   fpEsdManager=AliHLTEsdManager::New();
194   fpEsdManager->SetOption(esdManagerOptions.Data());
195
196   InitStreamerInfos();
197 }
198
199 const char* AliHLTReconstructor::fgkCalibStreamerInfoEntry="HLT/Calib/StreamerInfo";
200
201 int AliHLTReconstructor::InitStreamerInfos()
202 {
203   // init streamer infos for HLT reconstruction
204   // Root schema evolution is not enabled for AliHLTMessage and all streamed objects.
205   // Objects in the raw data payload rely on the availability of the correct stream info.
206   // The relevant streamer info for a specific run is stored in the OCDB.
207   // The method evaluates the following entries:
208   // - HLT/Calib/StreamerInfo
209
210   // to be activated later, this is supposed to go as patch into the v4-17-Release branch
211   // which doe snot have the AliHLTMisc implementation
212   //AliCDBEntry* pEntry=AliHLTMisc::Instance().LoadOCDBEntry(fgkCalibStreamerInfoEntry);
213   AliCDBEntry* pEntry=AliCDBManager::Instance()->Get(fgkCalibStreamerInfoEntry);
214   TObject* pObject=NULL;
215   //if (pEntry && (pObject=AliHLTMisc::Instance().ExtractObject(pEntry))!=NULL)
216   if (pEntry && (pObject=pEntry->GetObject())!=NULL)
217     {
218     TObjArray* pSchemas=dynamic_cast<TObjArray*>(pObject);
219     if (pSchemas) {
220     } else {
221       AliError(Form("internal mismatch in OCDB entry %s: wrong class type", fgkCalibStreamerInfoEntry));
222     }
223   } else {
224     AliWarning(Form("missing HLT reco data (%s), skipping initialization of streamer info for TObjects in HLT raw data payload", fgkCalibStreamerInfoEntry));
225   }
226   return 0;
227 }
228
229 int AliHLTReconstructor::InitStreamerInfos(TObjArray* pSchemas) const
230 {
231   // init streamer infos for HLT reconstruction from an array of TStreamerInfo objects
232
233   for (int i=0; i<pSchemas->GetEntriesFast(); i++) {
234     if (pSchemas->At(i)) {
235       TStreamerInfo* pSchema=dynamic_cast<TStreamerInfo*>(pSchemas->At(i));
236       if (pSchema) {
237         int version=pSchema->GetClassVersion();
238         TClass* pClass=TClass::GetClass(pSchema->GetName());
239         if (pClass) {
240           if (pClass->GetClassVersion()==version) {
241             AliDebug(0,Form("skipping schema definition %d version %d to class %s as this is the native version", i, version, pSchema->GetName()));
242             continue;
243           }
244           TObjArray* pInfos=pClass->GetStreamerInfos();
245           if (pInfos /*&& version<pInfos->GetEntriesFast()*/) {
246             if (pInfos->At(version)==NULL) {
247               TStreamerInfo* pClone=(TStreamerInfo*)pSchema->Clone();
248               if (pClone) {
249                 pClone->SetClass(pClass);
250                 pClone->BuildOld();
251                 pInfos->AddAtAndExpand(pClone, version);
252                 AliDebug(0,Form("adding schema definition %d version %d to class %s", i, version, pSchema->GetName()));
253               } else {
254                 AliError(Form("skipping schema definition %d (%s), unable to create clone object", i, pSchema->GetName()));
255               }
256             } else {
257               TStreamerInfo* pInfo=dynamic_cast<TStreamerInfo*>(pInfos->At(version));
258               if (pInfo && pInfo->GetClassVersion()==version) {
259                 AliDebug(0,Form("schema definition %d version %d already available in class %s, skipping ...", i, version, pSchema->GetName()));
260               } else {
261                 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));
262               }
263             }
264           } else {
265             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));
266           }
267         } else {
268           AliError(Form("skipping schema definition %d (%s), unable to find class", i, pSchema->GetName()));
269         }
270       } else {
271         AliError(Form("skipping schema definition %d, not of TStreamerInfo", i));
272       }
273     }
274   }
275 }
276
277 void AliHLTReconstructor::Reconstruct(AliRawReader* rawReader, TTree* /*clustersTree*/) const 
278 {
279   // reconstruction of real data without writing of ESD
280   // For each event, HLT reconstruction chains can be executed and
281   // added to the existing HLTOUT data
282   // The HLTOUT data is finally processed in FillESD
283   if (!fpPluginBase) {
284     AliError("internal memory error: can not get AliHLTSystem instance from plugin");
285     return;
286   }
287
288   int iResult=0;
289   AliHLTSystem* pSystem=fpPluginBase->GetInstance();
290
291   if (pSystem) {
292     if (pSystem->CheckStatus(AliHLTSystem::kError)) {
293       AliError("HLT system in error state");
294       return;
295     }
296     if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
297       AliError("HLT system in wrong state");
298       return;
299     }
300     if ((iResult=pSystem->Reconstruct(1, NULL, rawReader))>=0) {
301     }
302   }
303 }
304
305 void AliHLTReconstructor::FillESD(AliRawReader* rawReader, TTree* /*clustersTree*/, 
306                                   AliESDEvent* esd) const
307 {
308   // reconstruct real data and fill ESD
309   if (!rawReader || !esd) {
310     AliError("missing raw reader or esd object");
311     return;
312   }
313
314   if (!fpPluginBase) {
315     AliError("internal memory error: can not get AliHLTSystem instance from plugin");
316     return;
317   }
318
319   AliHLTSystem* pSystem=fpPluginBase->GetInstance();
320
321   if (pSystem) {
322     if (pSystem->CheckStatus(AliHLTSystem::kError)) {
323       AliError("HLT system in error state");
324       return;
325     }
326     if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
327       AliError("HLT system in wrong state");
328       return;
329     }
330     pSystem->FillESD(-1, NULL, esd);
331
332     AliRawReader* input=NULL;
333     if ((fFlags&kAliHLTReconstructorIgnoreHLTOUT) == 0 ) {
334       input=rawReader;
335     }
336     AliHLTOUTRawReader* pHLTOUT=new AliHLTOUTRawReader(input, esd->GetEventNumberInFile(), fpEsdManager);
337     if (pHLTOUT) {
338       ProcessHLTOUT(pHLTOUT, esd);
339       delete pHLTOUT;
340     } else {
341       AliError("error creating HLTOUT handler");
342     }
343   }
344 }
345
346 void AliHLTReconstructor::Reconstruct(TTree* /*digitsTree*/, TTree* /*clustersTree*/) const
347 {
348   // reconstruct simulated data
349
350   // all reconstruction has been moved to FillESD
351   //AliReconstructor::Reconstruct(digitsTree,clustersTree);
352   AliInfo("running digit data reconstruction");
353 }
354
355 void AliHLTReconstructor::FillESD(TTree* /*digitsTree*/, TTree* /*clustersTree*/, AliESDEvent* esd) const
356 {
357   // reconstruct simulated data and fill ESD
358
359   // later this is the place to extract the simulated HLT data
360   // for now it's only an user failure condition as he tries to run HLT reconstruction
361   // on simulated data 
362   TString option = GetOption();
363   if (!option.IsNull() && 
364       (option.Contains("config=") || option.Contains("chains="))) {
365     AliWarning(Form("HLT reconstruction can be run embedded into Alireconstruction from\n"
366                     "raw data (real or simulated)). Reconstruction of of digit data takes\n"
367                     "place in AliSimulation, appropriate input conversion is needed.\n"
368                     "Consider running embedded into AliSimulation."
369                     "        /***  run macro *****************************************/\n"
370                     "        AliSimulation sim;\n"
371                     "        sim.SetRunHLT(\"%s\");\n"
372                     "        sim.SetRunGeneration(kFALSE);\n"
373                     "        sim.SetMakeDigits(\"\");\n"
374                     "        sim.SetMakeSDigits(\"\");\n"
375                     "        sim.SetMakeDigitsFromHits(\"\");\n"
376                     "        sim.Run();\n"
377                     "        /*********************************************************/", option.Data()));
378   }
379   if (!fpPluginBase) {
380     AliError("internal memory error: can not get AliHLTSystem instance from plugin");
381     return;
382   }
383
384   AliHLTSystem* pSystem=fpPluginBase->GetInstance();
385   if (pSystem) {
386     if (pSystem->CheckStatus(AliHLTSystem::kError)) {
387       AliError("HLT system in error state");
388       return;
389     }
390     if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
391       AliError("HLT system in wrong state");
392       return;
393     }
394
395     AliHLTOUTDigitReader* pHLTOUT=new AliHLTOUTDigitReader(esd->GetEventNumberInFile(), fpEsdManager);
396     if (pHLTOUT) {
397       ProcessHLTOUT(pHLTOUT, esd);
398       delete pHLTOUT;
399     } else {
400       AliError("error creating HLTOUT handler");
401     }
402   }
403 }
404
405 void AliHLTReconstructor::ProcessHLTOUT(AliHLTOUT* pHLTOUT, AliESDEvent* esd, bool bVerbose) const
406 {
407   // treatment of simulated or real HLTOUT data
408   if (!pHLTOUT) return;
409   if (!fpPluginBase) {
410     AliError("internal memory error: can not get AliHLTSystem instance from plugin");
411     return;
412   }
413
414   AliHLTSystem* pSystem=fpPluginBase->GetInstance();
415   if (!pSystem) {
416     AliError("error getting HLT system instance");
417     return;
418   }
419
420   if (pHLTOUT->Init()<0) {
421     AliError("error : initialization of HLTOUT handler failed");
422     return;
423   }
424
425   if (bVerbose)
426     PrintHLTOUTContent(pHLTOUT);
427
428   int blockindex=pHLTOUT->SelectFirstDataBlock(kAliHLTDataTypeStreamerInfo);
429   if (blockindex>=0) {
430     const AliHLTUInt8_t* pBuffer=NULL;
431     AliHLTUInt32_t size=0;
432     if (pHLTOUT->GetDataBuffer(pBuffer, size)>=0) {
433       TObject* pObject=AliHLTMessage::Extract(pBuffer, size);
434       if (pObject) {
435         TObjArray* pArray=dynamic_cast<TObjArray*>(pObject);
436         if (pArray) {
437           InitStreamerInfos(pArray);
438         } else {
439           AliError(Form("wrong class type of streamer info list: expected TObjArray, but object is of type %s", pObject->Class()->GetName()));
440         }
441       } else {
442         AliError(Form("failed to extract object from data block of type %s", AliHLTComponent::DataType2Text(kAliHLTDataTypeStreamerInfo).c_str()));
443       }
444     } else {
445       AliError(Form("failed to get data buffer for block of type %s", AliHLTComponent::DataType2Text(kAliHLTDataTypeStreamerInfo).c_str()));
446     }
447   }
448
449   if (fFctProcessHLTOUT) {
450     typedef int (*AliHLTSystemProcessHLTOUT)(AliHLTSystem* pInstance, AliHLTOUT* pHLTOUT, AliESDEvent* esd);
451     AliHLTSystemProcessHLTOUT pFunc=(AliHLTSystemProcessHLTOUT)fFctProcessHLTOUT;
452     if ((pFunc)(pSystem, pHLTOUT, esd)<0) {
453       AliError("error processing HLTOUT");
454     }
455   }
456   pHLTOUT->Reset();
457 }
458
459 void AliHLTReconstructor::ProcessHLTOUT(const char* digitFile, AliESDEvent* pEsd) const
460 {
461   // debugging/helper function to examine simulated data
462   if (!digitFile) return;
463
464   // read the number of events
465   TFile f(digitFile);
466   if (f.IsZombie()) return;
467   TTree* pTree=NULL;
468   f.GetObject("rawhltout", pTree);
469   if (!pTree) {
470     AliWarning(Form("can not find tree rawhltout in file %s", digitFile));
471     return ;
472   }
473   int nofEvents=pTree->GetEntries();
474   f.Close();
475   //delete pTree; OF COURSE NOT! its an object in the file
476   pTree=NULL;
477
478   for (int event=0; event<nofEvents; event++) {
479     AliHLTOUTDigitReader* pHLTOUT=new AliHLTOUTDigitReader(event, fpEsdManager, digitFile);
480     if (pHLTOUT) {
481       AliInfo(Form("event %d", event));
482       ProcessHLTOUT(pHLTOUT, pEsd, true);
483       delete pHLTOUT;
484     } else {
485       AliError("error creating HLTOUT handler");
486     }
487   }
488 }
489
490 void AliHLTReconstructor::ProcessHLTOUT(AliRawReader* pRawReader, AliESDEvent* pEsd) const
491 {
492   // debugging/helper function to examine simulated or real HLTOUT data
493   if (!pRawReader) return;
494
495   pRawReader->RewindEvents();
496   for (int event=0; pRawReader->NextEvent(); event++) {
497     AliHLTOUTRawReader* pHLTOUT=new AliHLTOUTRawReader(pRawReader, event, fpEsdManager);
498     if (pHLTOUT) {
499       AliInfo(Form("event %d", event));
500       // the two event fields contain: period - orbit - bunch crossing counter
501       //        id[0]               id[1]
502       // |32                0|32                0|
503       //
504       // |      28 bit    |       24 bit     | 12|
505       //        period          orbit         bcc
506       AliHLTUInt64_t eventId=0;
507       const UInt_t* rawreaderEventId=pRawReader->GetEventId();
508       if (rawreaderEventId) {
509         eventId=rawreaderEventId[0];
510         eventId=eventId<<32;
511         eventId|=rawreaderEventId[1];
512       }
513       AliInfo(Form("Event Id from rawreader:\t 0x%016llx", eventId));
514       ProcessHLTOUT(pHLTOUT, pEsd, true);
515       delete pHLTOUT;
516     } else {
517       AliError("error creating HLTOUT handler");
518     }
519   }
520 }
521
522 void AliHLTReconstructor::PrintHLTOUTContent(AliHLTOUT* pHLTOUT) const
523 {
524   // print the block specifications of the HLTOUT data blocks
525   if (!pHLTOUT) return;
526   int iResult=0;
527
528   AliInfo(Form("Event Id from hltout:\t 0x%016llx", pHLTOUT->EventId()));
529   for (iResult=pHLTOUT->SelectFirstDataBlock();
530        iResult>=0;
531        iResult=pHLTOUT->SelectNextDataBlock()) {
532     AliHLTComponentDataType dt=kAliHLTVoidDataType;
533     AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
534     pHLTOUT->GetDataBlockDescription(dt, spec);
535     const AliHLTUInt8_t* pBuffer=NULL;
536     AliHLTUInt32_t size=0;
537     if (pHLTOUT->GetDataBuffer(pBuffer, size)>=0) {
538       pHLTOUT->ReleaseDataBuffer(pBuffer);
539       pBuffer=NULL; // just a dummy
540     }
541     AliInfo(Form("   %s  0x%x: size %d", AliHLTComponent::DataType2Text(dt).c_str(), spec, size));
542   }
543 }