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"
45 #include "AliCentralTrigger.h"
46 #include "AliTriggerConfiguration.h"
47 #include "AliTriggerClass.h"
48 #include "AliTriggerCluster.h"
53 ClassImp(AliHLTReconstructor)
55 AliHLTReconstructor::AliHLTReconstructor()
58 fFctProcessHLTOUT(NULL),
60 fpPluginBase(new AliHLTPluginBase)
66 AliHLTReconstructor::AliHLTReconstructor(const char* options)
69 fFctProcessHLTOUT(NULL),
71 fpPluginBase(new AliHLTPluginBase)
75 if (options) Init(options);
78 AliHLTReconstructor::~AliHLTReconstructor()
83 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
85 AliDebug(0, Form("terminate HLT system: status %#x", pSystem->GetStatusFlags()));
86 if (pSystem->CheckStatus(AliHLTSystem::kStarted)) {
87 // send specific 'event' to execute the stop sequence
88 pSystem->Reconstruct(0, NULL, NULL);
95 if (fpEsdManager) AliHLTEsdManager::Delete(fpEsdManager);
99 void AliHLTReconstructor::Init(const char* options)
101 // init the reconstructor
106 void AliHLTReconstructor::Init()
108 // init the reconstructor
110 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
114 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
116 AliError("can not create AliHLTSystem object");
119 if (pSystem->CheckStatus(AliHLTSystem::kError)) {
120 AliError("HLT system in error state");
124 TString esdManagerOptions;
126 // the options scan has been moved to AliHLTSystem, the old code
127 // here is kept to be able to run an older version of the HLT code
128 // with newer AliRoot versions.
130 TString option = GetOption();
131 TObjArray* pTokens=option.Tokenize(" ");
134 int iEntries=pTokens->GetEntries();
135 for (int i=0; i<iEntries; i++) {
136 TString token=(((TObjString*)pTokens->At(i))->GetString());
137 if (token.Contains("loglevel=")) {
138 TString param=token.ReplaceAll("loglevel=", "");
139 if (param.IsDigit()) {
140 pSystem->SetGlobalLoggingLevel((AliHLTComponentLogSeverity)param.Atoi());
141 } else if (param.BeginsWith("0x") &&
142 param.Replace(0,2,"",0).IsHex()) {
144 sscanf(param.Data(),"%x", &severity);
145 pSystem->SetGlobalLoggingLevel((AliHLTComponentLogSeverity)severity);
147 AliWarning("wrong parameter for option \'loglevel=\', (hex) number expected");
149 } else if (token.Contains("alilog=off")) {
150 pSystem->SwitchAliLog(0);
151 } else if (token.CompareTo("ignore-hltout")==0) {
152 fFlags|=kAliHLTReconstructorIgnoreHLTOUT;
153 } else if (token.CompareTo("ignore-ctp")==0) {
154 fFlags|=kAliHLTReconstructorIgnoreCTP;
155 } else if (token.Contains("esdmanager=")) {
156 token.ReplaceAll("esdmanager=", "");
157 token.ReplaceAll(","," ");
158 token.ReplaceAll("'","");
159 esdManagerOptions=token;
160 } else if (token.BeginsWith("lib") && token.EndsWith(".so")) {
164 if (option.Length()>0) option+=" ";
173 if ((fFlags&kAliHLTReconstructorIgnoreCTP)==0 &&
174 BuildCTPTriggerClassString(ctpParam)>=0) {
175 if (!ecsParam.IsNull()) ecsParam+=";";
176 ecsParam+="CTP_TRIGGER_CLASS=";
180 if (!ecsParam.IsNull()) {
185 if (!libs.IsNull() &&
186 (!pSystem->CheckStatus(AliHLTSystem::kLibrariesLoaded)) &&
187 (pSystem->LoadComponentLibraries(libs.Data())<0)) {
188 AliError("error while loading HLT libraries");
192 if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
193 typedef int (*AliHLTSystemSetOptions)(AliHLTSystem* pInstance, const char* options);
194 gSystem->Load("libHLTinterface.so");
195 AliHLTSystemSetOptions pFunc=(AliHLTSystemSetOptions)(gSystem->DynFindSymbol("libHLTinterface.so", "AliHLTSystemSetOptions"));
197 if ((pFunc)(pSystem, option.Data())<0) {
198 AliError("error setting options for HLT system");
201 } else if (option.Length()>0) {
202 AliError(Form("version of HLT system does not support the options \'%s\'", option.Data()));
205 if ((pSystem->Configure())<0) {
206 AliError("error during HLT system configuration");
211 gSystem->Load("libHLTinterface.so");
212 fFctProcessHLTOUT=(void (*)())gSystem->DynFindSymbol("libHLTinterface.so", "AliHLTSystemProcessHLTOUT");
214 fpEsdManager=AliHLTEsdManager::New();
215 fpEsdManager->SetOption(esdManagerOptions.Data());
220 const char* AliHLTReconstructor::fgkCalibStreamerInfoEntry="HLT/Calib/StreamerInfo";
222 int AliHLTReconstructor::InitStreamerInfos()
224 // init streamer infos for HLT reconstruction
225 // Root schema evolution is not enabled for AliHLTMessage and all streamed objects.
226 // Objects in the raw data payload rely on the availability of the correct stream info.
227 // The relevant streamer info for a specific run is stored in the OCDB.
228 // The method evaluates the following entries:
229 // - HLT/Calib/StreamerInfo
232 // to be activated later, this is supposed to go as patch into the v4-17-Release branch
233 // which doe snot have the AliHLTMisc implementation
234 //AliCDBEntry* pEntry=AliHLTMisc::Instance().LoadOCDBEntry(fgkCalibStreamerInfoEntry);
235 AliCDBEntry* pEntry=AliCDBManager::Instance()->Get(fgkCalibStreamerInfoEntry);
236 TObject* pObject=NULL;
237 //if (pEntry && (pObject=AliHLTMisc::Instance().ExtractObject(pEntry))!=NULL)
238 if (pEntry && (pObject=pEntry->GetObject())!=NULL)
240 TObjArray* pSchemas=dynamic_cast<TObjArray*>(pObject);
242 iResult=InitStreamerInfos(pSchemas);
244 AliError(Form("internal mismatch in OCDB entry %s: wrong class type", fgkCalibStreamerInfoEntry));
247 AliWarning(Form("missing HLT reco data (%s), skipping initialization of streamer info for TObjects in HLT raw data payload", fgkCalibStreamerInfoEntry));
252 int AliHLTReconstructor::InitStreamerInfos(TObjArray* pSchemas) const
254 // init streamer infos for HLT reconstruction from an array of TStreamerInfo objects
256 for (int i=0; i<pSchemas->GetEntriesFast(); i++) {
257 if (pSchemas->At(i)) {
258 TStreamerInfo* pSchema=dynamic_cast<TStreamerInfo*>(pSchemas->At(i));
260 int version=pSchema->GetClassVersion();
261 TClass* pClass=TClass::GetClass(pSchema->GetName());
263 if (pClass->GetClassVersion()==version) {
264 AliDebug(0,Form("skipping schema definition %d version %d to class %s as this is the native version", i, version, pSchema->GetName()));
267 TObjArray* pInfos=pClass->GetStreamerInfos();
268 if (pInfos /*&& version<pInfos->GetEntriesFast()*/) {
269 if (pInfos->At(version)==NULL) {
270 TStreamerInfo* pClone=(TStreamerInfo*)pSchema->Clone();
272 pClone->SetClass(pClass);
274 pInfos->AddAtAndExpand(pClone, version);
275 AliDebug(0,Form("adding schema definition %d version %d to class %s", i, version, pSchema->GetName()));
277 AliError(Form("skipping schema definition %d (%s), unable to create clone object", i, pSchema->GetName()));
280 TStreamerInfo* pInfo=dynamic_cast<TStreamerInfo*>(pInfos->At(version));
281 if (pInfo && pInfo->GetClassVersion()==version) {
282 AliDebug(0,Form("schema definition %d version %d already available in class %s, skipping ...", i, version, pSchema->GetName()));
284 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));
288 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));
291 AliError(Form("skipping schema definition %d (%s), unable to find class", i, pSchema->GetName()));
294 AliError(Form("skipping schema definition %d, not of TStreamerInfo", i));
302 void AliHLTReconstructor::Reconstruct(AliRawReader* rawReader, TTree* /*clustersTree*/) const
304 // reconstruction of real data without writing of ESD
305 // For each event, HLT reconstruction chains can be executed and
306 // added to the existing HLTOUT data
307 // The HLTOUT data is finally processed in FillESD
309 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
314 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
317 if (pSystem->CheckStatus(AliHLTSystem::kError)) {
318 AliError("HLT system in error state");
321 if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
322 AliError("HLT system in wrong state");
325 if ((iResult=pSystem->Reconstruct(1, NULL, rawReader))>=0) {
330 void AliHLTReconstructor::FillESD(AliRawReader* rawReader, TTree* /*clustersTree*/,
331 AliESDEvent* esd) const
333 // reconstruct real data and fill ESD
334 if (!rawReader || !esd) {
335 AliError("missing raw reader or esd object");
340 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
344 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
347 if (pSystem->CheckStatus(AliHLTSystem::kError)) {
348 AliError("HLT system in error state");
351 if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
352 AliError("HLT system in wrong state");
355 pSystem->FillESD(-1, NULL, esd);
357 AliRawReader* input=NULL;
358 if ((fFlags&kAliHLTReconstructorIgnoreHLTOUT) == 0 ) {
361 AliHLTOUTRawReader* pHLTOUT=new AliHLTOUTRawReader(input, esd->GetEventNumberInFile(), fpEsdManager);
363 ProcessHLTOUT(pHLTOUT, esd, (pSystem->GetGlobalLoggingLevel()&kHLTLogDebug)!=0);
366 AliError("error creating HLTOUT handler");
371 void AliHLTReconstructor::Reconstruct(TTree* /*digitsTree*/, TTree* /*clustersTree*/) const
373 // reconstruct simulated data
375 // all reconstruction has been moved to FillESD
376 //AliReconstructor::Reconstruct(digitsTree,clustersTree);
377 AliInfo("running digit data reconstruction");
380 void AliHLTReconstructor::FillESD(TTree* /*digitsTree*/, TTree* /*clustersTree*/, AliESDEvent* esd) const
382 // reconstruct simulated data and fill ESD
384 // later this is the place to extract the simulated HLT data
385 // for now it's only an user failure condition as he tries to run HLT reconstruction
387 TString option = GetOption();
388 if (!option.IsNull() &&
389 (option.Contains("config=") || option.Contains("chains="))) {
390 AliWarning(Form("HLT reconstruction can be run embedded into Alireconstruction from\n"
391 "raw data (real or simulated)). Reconstruction of of digit data takes\n"
392 "place in AliSimulation, appropriate input conversion is needed.\n"
393 "Consider running embedded into AliSimulation."
394 " /*** run macro *****************************************/\n"
395 " AliSimulation sim;\n"
396 " sim.SetRunHLT(\"%s\");\n"
397 " sim.SetRunGeneration(kFALSE);\n"
398 " sim.SetMakeDigits(\"\");\n"
399 " sim.SetMakeSDigits(\"\");\n"
400 " sim.SetMakeDigitsFromHits(\"\");\n"
402 " /*********************************************************/", option.Data()));
405 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
409 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
411 if (pSystem->CheckStatus(AliHLTSystem::kError)) {
412 AliError("HLT system in error state");
415 if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
416 AliError("HLT system in wrong state");
420 AliHLTOUTDigitReader* pHLTOUT=new AliHLTOUTDigitReader(esd->GetEventNumberInFile(), fpEsdManager);
422 ProcessHLTOUT(pHLTOUT, esd, (pSystem->GetGlobalLoggingLevel()&kHLTLogDebug)!=0);
425 AliError("error creating HLTOUT handler");
430 void AliHLTReconstructor::ProcessHLTOUT(AliHLTOUT* pHLTOUT, AliESDEvent* esd, bool bVerbose) const
432 // treatment of simulated or real HLTOUT data
433 if (!pHLTOUT) return;
435 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
439 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
441 AliError("error getting HLT system instance");
445 if (pHLTOUT->Init()<0) {
446 AliError("error : initialization of HLTOUT handler failed");
451 PrintHLTOUTContent(pHLTOUT);
453 int blockindex=pHLTOUT->SelectFirstDataBlock(kAliHLTDataTypeStreamerInfo);
455 const AliHLTUInt8_t* pBuffer=NULL;
456 AliHLTUInt32_t size=0;
457 if (pHLTOUT->GetDataBuffer(pBuffer, size)>=0) {
458 TObject* pObject=AliHLTMessage::Extract(pBuffer, size);
460 TObjArray* pArray=dynamic_cast<TObjArray*>(pObject);
462 InitStreamerInfos(pArray);
464 AliError(Form("wrong class type of streamer info list: expected TObjArray, but object is of type %s", pObject->Class()->GetName()));
467 AliError(Form("failed to extract object from data block of type %s", AliHLTComponent::DataType2Text(kAliHLTDataTypeStreamerInfo).c_str()));
470 AliError(Form("failed to get data buffer for block of type %s", AliHLTComponent::DataType2Text(kAliHLTDataTypeStreamerInfo).c_str()));
474 if (fFctProcessHLTOUT) {
475 typedef int (*AliHLTSystemProcessHLTOUT)(AliHLTSystem* pInstance, AliHLTOUT* pHLTOUT, AliESDEvent* esd);
476 AliHLTSystemProcessHLTOUT pFunc=(AliHLTSystemProcessHLTOUT)fFctProcessHLTOUT;
477 if ((pFunc)(pSystem, pHLTOUT, esd)<0) {
478 AliError("error processing HLTOUT");
482 AliInfo("HLT ESD content:");
488 void AliHLTReconstructor::ProcessHLTOUT(const char* digitFile, AliESDEvent* pEsd) const
490 // debugging/helper function to examine simulated data
491 if (!digitFile) return;
493 // read the number of events
495 if (f.IsZombie()) return;
497 f.GetObject("rawhltout", pTree);
499 AliWarning(Form("can not find tree rawhltout in file %s", digitFile));
502 int nofEvents=pTree->GetEntries();
504 //delete pTree; OF COURSE NOT! its an object in the file
507 for (int event=0; event<nofEvents; event++) {
508 AliHLTOUTDigitReader* pHLTOUT=new AliHLTOUTDigitReader(event, fpEsdManager, digitFile);
510 AliInfo(Form("event %d", event));
511 ProcessHLTOUT(pHLTOUT, pEsd, true);
514 AliError("error creating HLTOUT handler");
519 void AliHLTReconstructor::ProcessHLTOUT(AliRawReader* pRawReader, AliESDEvent* pEsd) const
521 // debugging/helper function to examine simulated or real HLTOUT data
522 if (!pRawReader) return;
524 pRawReader->RewindEvents();
525 for (int event=0; pRawReader->NextEvent(); event++) {
526 AliHLTOUTRawReader* pHLTOUT=new AliHLTOUTRawReader(pRawReader, event, fpEsdManager);
528 AliInfo(Form("event %d", event));
529 // the two event fields contain: period - orbit - bunch crossing counter
533 // | 28 bit | 24 bit | 12|
535 AliHLTUInt64_t eventId=0;
536 const UInt_t* rawreaderEventId=pRawReader->GetEventId();
537 if (rawreaderEventId) {
538 eventId=rawreaderEventId[0];
540 eventId|=rawreaderEventId[1];
542 AliInfo(Form("Event Id from rawreader:\t 0x%016llx", eventId));
543 ProcessHLTOUT(pHLTOUT, pEsd, true);
546 AliError("error creating HLTOUT handler");
551 void AliHLTReconstructor::PrintHLTOUTContent(AliHLTOUT* pHLTOUT) const
553 // print the block specifications of the HLTOUT data blocks
554 if (!pHLTOUT) return;
557 AliInfo(Form("Event Id from hltout:\t 0x%016llx", pHLTOUT->EventId()));
558 for (iResult=pHLTOUT->SelectFirstDataBlock();
560 iResult=pHLTOUT->SelectNextDataBlock()) {
561 AliHLTComponentDataType dt=kAliHLTVoidDataType;
562 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
563 pHLTOUT->GetDataBlockDescription(dt, spec);
564 const AliHLTUInt8_t* pBuffer=NULL;
565 AliHLTUInt32_t size=0;
566 if (pHLTOUT->GetDataBuffer(pBuffer, size)>=0) {
567 pHLTOUT->ReleaseDataBuffer(pBuffer);
568 pBuffer=NULL; // just a dummy
570 AliInfo(Form(" %s 0x%x: size %d", AliHLTComponent::DataType2Text(dt).c_str(), spec, size));
574 int AliHLTReconstructor::BuildCTPTriggerClassString(TString& triggerclasses) const
576 // build the CTP trigger class string from the OCDB entry of the CTP trigger
579 triggerclasses.Clear();
580 AliCentralTrigger* pCTP = new AliCentralTrigger();
581 AliTriggerConfiguration *config=NULL;
582 TString configstr("");
583 if (pCTP->LoadConfiguration(configstr) &&
584 (config = pCTP->GetConfiguration())!=NULL) {
585 const TObjArray& classesArray = config->GetClasses();
586 int nclasses = classesArray.GetEntriesFast();
587 for( int iclass=0; iclass < nclasses; iclass++ ) {
588 AliTriggerClass* trclass = NULL;
589 if (classesArray.At(iclass) && (trclass=dynamic_cast<AliTriggerClass*>(classesArray.At(iclass)))!=NULL) {
591 int trindex = TMath::Nint(TMath::Log2(trclass->GetMask()));
592 entry.Form("%02d:%s:", trindex, trclass->GetName());
593 AliTriggerCluster* cluster=NULL;
594 TObject* clusterobj=config->GetClusters().FindObject(trclass->GetCluster());
595 if (clusterobj && (cluster=dynamic_cast<AliTriggerCluster*>(clusterobj))!=NULL) {
596 TString detectors=cluster->GetDetectorsInCluster();
597 TObjArray* pTokens=detectors.Tokenize(" ");
599 for (int dix=0; dix<pTokens->GetEntriesFast(); dix++) {
600 int id=AliDAQ::DetectorID(((TObjString*)pTokens->At(dix))->GetString());
602 TString detstr; detstr.Form("%s%02d", dix>0?"-":"", id);
605 AliError(Form("invalid detector name extracted from trigger cluster: %s (%s)", ((TObjString*)pTokens->At(dix))->GetString().Data(), detectors.Data()));
613 AliError(Form("can not find trigger cluster %s in config", trclass->GetCluster()));
617 if (!triggerclasses.IsNull()) triggerclasses+=",";
618 triggerclasses+=entry;