3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project *
5 //* ALICE Experiment at CERN, All rights reserved. *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 //* for The ALICE HLT Project. *
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 //**************************************************************************
19 /** @file AliHLTReconstructor.cxx
20 @author Matthias Richter
22 @brief Binding class for HLT reconstruction in AliRoot. */
25 #include <TObjString.h>
29 #include "TObjArray.h"
31 #include "TStreamerInfo.h"
32 #include "AliHLTReconstructor.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"
48 ClassImp(AliHLTReconstructor)
50 AliHLTReconstructor::AliHLTReconstructor()
53 fFctProcessHLTOUT(NULL),
55 fpPluginBase(new AliHLTPluginBase)
61 AliHLTReconstructor::AliHLTReconstructor(const char* options)
64 fFctProcessHLTOUT(NULL),
66 fpPluginBase(new AliHLTPluginBase)
70 if (options) Init(options);
73 AliHLTReconstructor::~AliHLTReconstructor()
78 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
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);
90 if (fpEsdManager) AliHLTEsdManager::Delete(fpEsdManager);
94 void AliHLTReconstructor::Init(const char* options)
96 // init the reconstructor
101 void AliHLTReconstructor::Init()
103 // init the reconstructor
105 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
109 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
111 AliError("can not create AliHLTSystem object");
114 if (pSystem->CheckStatus(AliHLTSystem::kError)) {
115 AliError("HLT system in error state");
119 TString esdManagerOptions;
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.
125 TString option = GetOption();
126 TObjArray* pTokens=option.Tokenize(" ");
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()) {
139 sscanf(param.Data(),"%x", &severity);
140 pSystem->SetGlobalLoggingLevel((AliHLTComponentLogSeverity)severity);
142 AliWarning("wrong parameter for option \'loglevel=\', (hex) number expected");
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")) {
157 if (option.Length()>0) option+=" ";
164 if (!libs.IsNull() &&
165 (!pSystem->CheckStatus(AliHLTSystem::kLibrariesLoaded)) &&
166 (pSystem->LoadComponentLibraries(libs.Data())<0)) {
167 AliError("error while loading HLT libraries");
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"));
176 if ((pFunc)(pSystem, option.Data())<0) {
177 AliError("error setting options for HLT system");
180 } else if (option.Length()>0) {
181 AliError(Form("version of HLT system does not support the options \'%s\'", option.Data()));
184 if ((pSystem->Configure())<0) {
185 AliError("error during HLT system configuration");
190 gSystem->Load("libHLTinterface.so");
191 fFctProcessHLTOUT=(void (*)())gSystem->DynFindSymbol("libHLTinterface.so", "AliHLTSystemProcessHLTOUT");
193 fpEsdManager=AliHLTEsdManager::New();
194 fpEsdManager->SetOption(esdManagerOptions.Data());
199 const char* AliHLTReconstructor::fgkCalibStreamerInfoEntry="HLT/Calib/StreamerInfo";
201 int AliHLTReconstructor::InitStreamerInfos()
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
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)
218 TObjArray* pSchemas=dynamic_cast<TObjArray*>(pObject);
221 AliError(Form("internal mismatch in OCDB entry %s: wrong class type", fgkCalibStreamerInfoEntry));
224 AliWarning(Form("missing HLT reco data (%s), skipping initialization of streamer info for TObjects in HLT raw data payload", fgkCalibStreamerInfoEntry));
229 int AliHLTReconstructor::InitStreamerInfos(TObjArray* pSchemas) const
231 // init streamer infos for HLT reconstruction from an array of TStreamerInfo objects
233 for (int i=0; i<pSchemas->GetEntriesFast(); i++) {
234 if (pSchemas->At(i)) {
235 TStreamerInfo* pSchema=dynamic_cast<TStreamerInfo*>(pSchemas->At(i));
237 int version=pSchema->GetClassVersion();
238 TClass* pClass=TClass::GetClass(pSchema->GetName());
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()));
244 TObjArray* pInfos=pClass->GetStreamerInfos();
245 if (pInfos /*&& version<pInfos->GetEntriesFast()*/) {
246 if (pInfos->At(version)==NULL) {
247 TStreamerInfo* pClone=(TStreamerInfo*)pSchema->Clone();
249 pClone->SetClass(pClass);
251 pInfos->AddAtAndExpand(pClone, version);
252 AliDebug(0,Form("adding schema definition %d version %d to class %s", i, version, pSchema->GetName()));
254 AliError(Form("skipping schema definition %d (%s), unable to create clone object", i, pSchema->GetName()));
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()));
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));
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));
268 AliError(Form("skipping schema definition %d (%s), unable to find class", i, pSchema->GetName()));
271 AliError(Form("skipping schema definition %d, not of TStreamerInfo", i));
277 void AliHLTReconstructor::Reconstruct(AliRawReader* rawReader, TTree* /*clustersTree*/) const
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
284 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
289 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
292 if (pSystem->CheckStatus(AliHLTSystem::kError)) {
293 AliError("HLT system in error state");
296 if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
297 AliError("HLT system in wrong state");
300 if ((iResult=pSystem->Reconstruct(1, NULL, rawReader))>=0) {
305 void AliHLTReconstructor::FillESD(AliRawReader* rawReader, TTree* /*clustersTree*/,
306 AliESDEvent* esd) const
308 // reconstruct real data and fill ESD
309 if (!rawReader || !esd) {
310 AliError("missing raw reader or esd object");
315 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
319 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
322 if (pSystem->CheckStatus(AliHLTSystem::kError)) {
323 AliError("HLT system in error state");
326 if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
327 AliError("HLT system in wrong state");
330 pSystem->FillESD(-1, NULL, esd);
332 AliRawReader* input=NULL;
333 if ((fFlags&kAliHLTReconstructorIgnoreHLTOUT) == 0 ) {
336 AliHLTOUTRawReader* pHLTOUT=new AliHLTOUTRawReader(input, esd->GetEventNumberInFile(), fpEsdManager);
338 ProcessHLTOUT(pHLTOUT, esd);
341 AliError("error creating HLTOUT handler");
346 void AliHLTReconstructor::Reconstruct(TTree* /*digitsTree*/, TTree* /*clustersTree*/) const
348 // reconstruct simulated data
350 // all reconstruction has been moved to FillESD
351 //AliReconstructor::Reconstruct(digitsTree,clustersTree);
352 AliInfo("running digit data reconstruction");
355 void AliHLTReconstructor::FillESD(TTree* /*digitsTree*/, TTree* /*clustersTree*/, AliESDEvent* esd) const
357 // reconstruct simulated data and fill ESD
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
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"
377 " /*********************************************************/", option.Data()));
380 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
384 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
386 if (pSystem->CheckStatus(AliHLTSystem::kError)) {
387 AliError("HLT system in error state");
390 if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
391 AliError("HLT system in wrong state");
395 AliHLTOUTDigitReader* pHLTOUT=new AliHLTOUTDigitReader(esd->GetEventNumberInFile(), fpEsdManager);
397 ProcessHLTOUT(pHLTOUT, esd);
400 AliError("error creating HLTOUT handler");
405 void AliHLTReconstructor::ProcessHLTOUT(AliHLTOUT* pHLTOUT, AliESDEvent* esd, bool bVerbose) const
407 // treatment of simulated or real HLTOUT data
408 if (!pHLTOUT) return;
410 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
414 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
416 AliError("error getting HLT system instance");
420 if (pHLTOUT->Init()<0) {
421 AliError("error : initialization of HLTOUT handler failed");
426 PrintHLTOUTContent(pHLTOUT);
428 int blockindex=pHLTOUT->SelectFirstDataBlock(kAliHLTDataTypeStreamerInfo);
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);
435 TObjArray* pArray=dynamic_cast<TObjArray*>(pObject);
437 InitStreamerInfos(pArray);
439 AliError(Form("wrong class type of streamer info list: expected TObjArray, but object is of type %s", pObject->Class()->GetName()));
442 AliError(Form("failed to extract object from data block of type %s", AliHLTComponent::DataType2Text(kAliHLTDataTypeStreamerInfo).c_str()));
445 AliError(Form("failed to get data buffer for block of type %s", AliHLTComponent::DataType2Text(kAliHLTDataTypeStreamerInfo).c_str()));
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");
459 void AliHLTReconstructor::ProcessHLTOUT(const char* digitFile, AliESDEvent* pEsd) const
461 // debugging/helper function to examine simulated data
462 if (!digitFile) return;
464 // read the number of events
466 if (f.IsZombie()) return;
468 f.GetObject("rawhltout", pTree);
470 AliWarning(Form("can not find tree rawhltout in file %s", digitFile));
473 int nofEvents=pTree->GetEntries();
475 //delete pTree; OF COURSE NOT! its an object in the file
478 for (int event=0; event<nofEvents; event++) {
479 AliHLTOUTDigitReader* pHLTOUT=new AliHLTOUTDigitReader(event, fpEsdManager, digitFile);
481 AliInfo(Form("event %d", event));
482 ProcessHLTOUT(pHLTOUT, pEsd, true);
485 AliError("error creating HLTOUT handler");
490 void AliHLTReconstructor::ProcessHLTOUT(AliRawReader* pRawReader, AliESDEvent* pEsd) const
492 // debugging/helper function to examine simulated or real HLTOUT data
493 if (!pRawReader) return;
495 pRawReader->RewindEvents();
496 for (int event=0; pRawReader->NextEvent(); event++) {
497 AliHLTOUTRawReader* pHLTOUT=new AliHLTOUTRawReader(pRawReader, event, fpEsdManager);
499 AliInfo(Form("event %d", event));
500 // the two event fields contain: period - orbit - bunch crossing counter
504 // | 28 bit | 24 bit | 12|
506 AliHLTUInt64_t eventId=0;
507 const UInt_t* rawreaderEventId=pRawReader->GetEventId();
508 if (rawreaderEventId) {
509 eventId=rawreaderEventId[0];
511 eventId|=rawreaderEventId[1];
513 AliInfo(Form("Event Id from rawreader:\t 0x%016llx", eventId));
514 ProcessHLTOUT(pHLTOUT, pEsd, true);
517 AliError("error creating HLTOUT handler");
522 void AliHLTReconstructor::PrintHLTOUTContent(AliHLTOUT* pHLTOUT) const
524 // print the block specifications of the HLTOUT data blocks
525 if (!pHLTOUT) return;
528 AliInfo(Form("Event Id from hltout:\t 0x%016llx", pHLTOUT->EventId()));
529 for (iResult=pHLTOUT->SelectFirstDataBlock();
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
541 AliInfo(Form(" %s 0x%x: size %d", AliHLTComponent::DataType2Text(dt).c_str(), spec, size));