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.Contains("esdmanager=")) {
154 token.ReplaceAll("esdmanager=", "");
155 token.ReplaceAll(","," ");
156 token.ReplaceAll("'","");
157 esdManagerOptions=token;
158 } else if (token.BeginsWith("lib") && token.EndsWith(".so")) {
162 if (option.Length()>0) option+=" ";
171 if (BuildCTPTriggerClassString(ctpParam)>=0) {
172 if (!ecsParam.IsNull()) ecsParam+=";";
173 ecsParam+="CTP_TRIGGER_CLASS=";
177 if (!ecsParam.IsNull()) {
182 if (!libs.IsNull() &&
183 (!pSystem->CheckStatus(AliHLTSystem::kLibrariesLoaded)) &&
184 (pSystem->LoadComponentLibraries(libs.Data())<0)) {
185 AliError("error while loading HLT libraries");
189 if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
190 typedef int (*AliHLTSystemSetOptions)(AliHLTSystem* pInstance, const char* options);
191 gSystem->Load("libHLTinterface.so");
192 AliHLTSystemSetOptions pFunc=(AliHLTSystemSetOptions)(gSystem->DynFindSymbol("libHLTinterface.so", "AliHLTSystemSetOptions"));
194 if ((pFunc)(pSystem, option.Data())<0) {
195 AliError("error setting options for HLT system");
198 } else if (option.Length()>0) {
199 AliError(Form("version of HLT system does not support the options \'%s\'", option.Data()));
202 if ((pSystem->Configure())<0) {
203 AliError("error during HLT system configuration");
208 gSystem->Load("libHLTinterface.so");
209 fFctProcessHLTOUT=(void (*)())gSystem->DynFindSymbol("libHLTinterface.so", "AliHLTSystemProcessHLTOUT");
211 fpEsdManager=AliHLTEsdManager::New();
212 fpEsdManager->SetOption(esdManagerOptions.Data());
217 const char* AliHLTReconstructor::fgkCalibStreamerInfoEntry="HLT/Calib/StreamerInfo";
219 int AliHLTReconstructor::InitStreamerInfos()
221 // init streamer infos for HLT reconstruction
222 // Root schema evolution is not enabled for AliHLTMessage and all streamed objects.
223 // Objects in the raw data payload rely on the availability of the correct stream info.
224 // The relevant streamer info for a specific run is stored in the OCDB.
225 // The method evaluates the following entries:
226 // - HLT/Calib/StreamerInfo
229 // to be activated later, this is supposed to go as patch into the v4-17-Release branch
230 // which doe snot have the AliHLTMisc implementation
231 //AliCDBEntry* pEntry=AliHLTMisc::Instance().LoadOCDBEntry(fgkCalibStreamerInfoEntry);
232 AliCDBEntry* pEntry=AliCDBManager::Instance()->Get(fgkCalibStreamerInfoEntry);
233 TObject* pObject=NULL;
234 //if (pEntry && (pObject=AliHLTMisc::Instance().ExtractObject(pEntry))!=NULL)
235 if (pEntry && (pObject=pEntry->GetObject())!=NULL)
237 TObjArray* pSchemas=dynamic_cast<TObjArray*>(pObject);
239 iResult=InitStreamerInfos(pSchemas);
241 AliError(Form("internal mismatch in OCDB entry %s: wrong class type", fgkCalibStreamerInfoEntry));
244 AliWarning(Form("missing HLT reco data (%s), skipping initialization of streamer info for TObjects in HLT raw data payload", fgkCalibStreamerInfoEntry));
249 int AliHLTReconstructor::InitStreamerInfos(TObjArray* pSchemas) const
251 // init streamer infos for HLT reconstruction from an array of TStreamerInfo objects
253 for (int i=0; i<pSchemas->GetEntriesFast(); i++) {
254 if (pSchemas->At(i)) {
255 TStreamerInfo* pSchema=dynamic_cast<TStreamerInfo*>(pSchemas->At(i));
257 int version=pSchema->GetClassVersion();
258 TClass* pClass=TClass::GetClass(pSchema->GetName());
260 if (pClass->GetClassVersion()==version) {
261 AliDebug(0,Form("skipping schema definition %d version %d to class %s as this is the native version", i, version, pSchema->GetName()));
264 TObjArray* pInfos=pClass->GetStreamerInfos();
265 if (pInfos /*&& version<pInfos->GetEntriesFast()*/) {
266 if (pInfos->At(version)==NULL) {
267 TStreamerInfo* pClone=(TStreamerInfo*)pSchema->Clone();
269 pClone->SetClass(pClass);
271 pInfos->AddAtAndExpand(pClone, version);
272 AliDebug(0,Form("adding schema definition %d version %d to class %s", i, version, pSchema->GetName()));
274 AliError(Form("skipping schema definition %d (%s), unable to create clone object", i, pSchema->GetName()));
277 TStreamerInfo* pInfo=dynamic_cast<TStreamerInfo*>(pInfos->At(version));
278 if (pInfo && pInfo->GetClassVersion()==version) {
279 AliDebug(0,Form("schema definition %d version %d already available in class %s, skipping ...", i, version, pSchema->GetName()));
281 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));
285 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));
288 AliError(Form("skipping schema definition %d (%s), unable to find class", i, pSchema->GetName()));
291 AliError(Form("skipping schema definition %d, not of TStreamerInfo", i));
299 void AliHLTReconstructor::Reconstruct(AliRawReader* rawReader, TTree* /*clustersTree*/) const
301 // reconstruction of real data without writing of ESD
302 // For each event, HLT reconstruction chains can be executed and
303 // added to the existing HLTOUT data
304 // The HLTOUT data is finally processed in FillESD
306 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
311 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
314 if (pSystem->CheckStatus(AliHLTSystem::kError)) {
315 AliError("HLT system in error state");
318 if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
319 AliError("HLT system in wrong state");
322 if ((iResult=pSystem->Reconstruct(1, NULL, rawReader))>=0) {
327 void AliHLTReconstructor::FillESD(AliRawReader* rawReader, TTree* /*clustersTree*/,
328 AliESDEvent* esd) const
330 // reconstruct real data and fill ESD
331 if (!rawReader || !esd) {
332 AliError("missing raw reader or esd object");
337 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
341 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
344 if (pSystem->CheckStatus(AliHLTSystem::kError)) {
345 AliError("HLT system in error state");
348 if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
349 AliError("HLT system in wrong state");
352 pSystem->FillESD(-1, NULL, esd);
354 AliRawReader* input=NULL;
355 if ((fFlags&kAliHLTReconstructorIgnoreHLTOUT) == 0 ) {
358 AliHLTOUTRawReader* pHLTOUT=new AliHLTOUTRawReader(input, esd->GetEventNumberInFile(), fpEsdManager);
360 ProcessHLTOUT(pHLTOUT, esd);
363 AliError("error creating HLTOUT handler");
368 void AliHLTReconstructor::Reconstruct(TTree* /*digitsTree*/, TTree* /*clustersTree*/) const
370 // reconstruct simulated data
372 // all reconstruction has been moved to FillESD
373 //AliReconstructor::Reconstruct(digitsTree,clustersTree);
374 AliInfo("running digit data reconstruction");
377 void AliHLTReconstructor::FillESD(TTree* /*digitsTree*/, TTree* /*clustersTree*/, AliESDEvent* esd) const
379 // reconstruct simulated data and fill ESD
381 // later this is the place to extract the simulated HLT data
382 // for now it's only an user failure condition as he tries to run HLT reconstruction
384 TString option = GetOption();
385 if (!option.IsNull() &&
386 (option.Contains("config=") || option.Contains("chains="))) {
387 AliWarning(Form("HLT reconstruction can be run embedded into Alireconstruction from\n"
388 "raw data (real or simulated)). Reconstruction of of digit data takes\n"
389 "place in AliSimulation, appropriate input conversion is needed.\n"
390 "Consider running embedded into AliSimulation."
391 " /*** run macro *****************************************/\n"
392 " AliSimulation sim;\n"
393 " sim.SetRunHLT(\"%s\");\n"
394 " sim.SetRunGeneration(kFALSE);\n"
395 " sim.SetMakeDigits(\"\");\n"
396 " sim.SetMakeSDigits(\"\");\n"
397 " sim.SetMakeDigitsFromHits(\"\");\n"
399 " /*********************************************************/", option.Data()));
402 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
406 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
408 if (pSystem->CheckStatus(AliHLTSystem::kError)) {
409 AliError("HLT system in error state");
412 if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
413 AliError("HLT system in wrong state");
417 AliHLTOUTDigitReader* pHLTOUT=new AliHLTOUTDigitReader(esd->GetEventNumberInFile(), fpEsdManager);
419 ProcessHLTOUT(pHLTOUT, esd);
422 AliError("error creating HLTOUT handler");
427 void AliHLTReconstructor::ProcessHLTOUT(AliHLTOUT* pHLTOUT, AliESDEvent* esd, bool bVerbose) const
429 // treatment of simulated or real HLTOUT data
430 if (!pHLTOUT) return;
432 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
436 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
438 AliError("error getting HLT system instance");
442 if (pHLTOUT->Init()<0) {
443 AliError("error : initialization of HLTOUT handler failed");
448 PrintHLTOUTContent(pHLTOUT);
450 int blockindex=pHLTOUT->SelectFirstDataBlock(kAliHLTDataTypeStreamerInfo);
452 const AliHLTUInt8_t* pBuffer=NULL;
453 AliHLTUInt32_t size=0;
454 if (pHLTOUT->GetDataBuffer(pBuffer, size)>=0) {
455 TObject* pObject=AliHLTMessage::Extract(pBuffer, size);
457 TObjArray* pArray=dynamic_cast<TObjArray*>(pObject);
459 InitStreamerInfos(pArray);
461 AliError(Form("wrong class type of streamer info list: expected TObjArray, but object is of type %s", pObject->Class()->GetName()));
464 AliError(Form("failed to extract object from data block of type %s", AliHLTComponent::DataType2Text(kAliHLTDataTypeStreamerInfo).c_str()));
467 AliError(Form("failed to get data buffer for block of type %s", AliHLTComponent::DataType2Text(kAliHLTDataTypeStreamerInfo).c_str()));
471 if (fFctProcessHLTOUT) {
472 typedef int (*AliHLTSystemProcessHLTOUT)(AliHLTSystem* pInstance, AliHLTOUT* pHLTOUT, AliESDEvent* esd);
473 AliHLTSystemProcessHLTOUT pFunc=(AliHLTSystemProcessHLTOUT)fFctProcessHLTOUT;
474 if ((pFunc)(pSystem, pHLTOUT, esd)<0) {
475 AliError("error processing HLTOUT");
481 void AliHLTReconstructor::ProcessHLTOUT(const char* digitFile, AliESDEvent* pEsd) const
483 // debugging/helper function to examine simulated data
484 if (!digitFile) return;
486 // read the number of events
488 if (f.IsZombie()) return;
490 f.GetObject("rawhltout", pTree);
492 AliWarning(Form("can not find tree rawhltout in file %s", digitFile));
495 int nofEvents=pTree->GetEntries();
497 //delete pTree; OF COURSE NOT! its an object in the file
500 for (int event=0; event<nofEvents; event++) {
501 AliHLTOUTDigitReader* pHLTOUT=new AliHLTOUTDigitReader(event, fpEsdManager, digitFile);
503 AliInfo(Form("event %d", event));
504 ProcessHLTOUT(pHLTOUT, pEsd, true);
507 AliError("error creating HLTOUT handler");
512 void AliHLTReconstructor::ProcessHLTOUT(AliRawReader* pRawReader, AliESDEvent* pEsd) const
514 // debugging/helper function to examine simulated or real HLTOUT data
515 if (!pRawReader) return;
517 pRawReader->RewindEvents();
518 for (int event=0; pRawReader->NextEvent(); event++) {
519 AliHLTOUTRawReader* pHLTOUT=new AliHLTOUTRawReader(pRawReader, event, fpEsdManager);
521 AliInfo(Form("event %d", event));
522 // the two event fields contain: period - orbit - bunch crossing counter
526 // | 28 bit | 24 bit | 12|
528 AliHLTUInt64_t eventId=0;
529 const UInt_t* rawreaderEventId=pRawReader->GetEventId();
530 if (rawreaderEventId) {
531 eventId=rawreaderEventId[0];
533 eventId|=rawreaderEventId[1];
535 AliInfo(Form("Event Id from rawreader:\t 0x%016llx", eventId));
536 ProcessHLTOUT(pHLTOUT, pEsd, true);
539 AliError("error creating HLTOUT handler");
544 void AliHLTReconstructor::PrintHLTOUTContent(AliHLTOUT* pHLTOUT) const
546 // print the block specifications of the HLTOUT data blocks
547 if (!pHLTOUT) return;
550 AliInfo(Form("Event Id from hltout:\t 0x%016llx", pHLTOUT->EventId()));
551 for (iResult=pHLTOUT->SelectFirstDataBlock();
553 iResult=pHLTOUT->SelectNextDataBlock()) {
554 AliHLTComponentDataType dt=kAliHLTVoidDataType;
555 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
556 pHLTOUT->GetDataBlockDescription(dt, spec);
557 const AliHLTUInt8_t* pBuffer=NULL;
558 AliHLTUInt32_t size=0;
559 if (pHLTOUT->GetDataBuffer(pBuffer, size)>=0) {
560 pHLTOUT->ReleaseDataBuffer(pBuffer);
561 pBuffer=NULL; // just a dummy
563 AliInfo(Form(" %s 0x%x: size %d", AliHLTComponent::DataType2Text(dt).c_str(), spec, size));
567 int AliHLTReconstructor::BuildCTPTriggerClassString(TString& triggerclasses) const
569 // build the CTP trigger class string from the OCDB entry of the CTP trigger
572 triggerclasses.Clear();
573 AliCentralTrigger* pCTP = new AliCentralTrigger();
574 AliTriggerConfiguration *config=NULL;
575 TString configstr("");
576 if (pCTP->LoadConfiguration(configstr) &&
577 (config = pCTP->GetConfiguration())!=NULL) {
578 const TObjArray& classesArray = config->GetClasses();
579 int nclasses = classesArray.GetEntriesFast();
580 for( int iclass=0; iclass < nclasses; iclass++ ) {
581 AliTriggerClass* trclass = NULL;
582 if (classesArray.At(iclass) && (trclass=dynamic_cast<AliTriggerClass*>(classesArray.At(iclass)))!=NULL) {
584 int trindex = TMath::Nint(TMath::Log2(trclass->GetMask()));
585 entry.Form("%02d:%s:", trindex, trclass->GetName());
586 AliTriggerCluster* cluster=NULL;
587 TObject* clusterobj=config->GetClusters().FindObject(trclass->GetCluster());
588 if (clusterobj && (cluster=dynamic_cast<AliTriggerCluster*>(clusterobj))!=NULL) {
589 TString detectors=cluster->GetDetectorsInCluster();
590 TObjArray* pTokens=detectors.Tokenize(" ");
592 for (int dix=0; dix<pTokens->GetEntriesFast(); dix++) {
593 int id=AliDAQ::DetectorID(((TObjString*)pTokens->At(dix))->GetString());
595 TString detstr; detstr.Form("%s%02d", dix>0?"-":"", id);
598 AliError(Form("invalid detector name extracted from trigger cluster: %s (%s)", ((TObjString*)pTokens->At(dix))->GetString().Data(), detectors.Data()));
606 AliError(Form("can not find trigger cluster %s in config", trclass->GetCluster()));
610 if (!triggerclasses.IsNull()) triggerclasses+=",";
611 triggerclasses+=entry;