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
23 // Implements bot the interface to run HLT chains embedded into
24 // AliReconstruction and the unpacking and treatment of HLTOUT
27 #include <TObjString.h>
31 #include "TObjArray.h"
33 #include "TStreamerInfo.h"
34 #include "AliHLTReconstructor.h"
36 #include "AliRawReader.h"
37 #include "AliESDEvent.h"
38 #include "AliHLTSystem.h"
39 #include "AliHLTOUTRawReader.h"
40 #include "AliHLTOUTDigitReader.h"
41 #include "AliHLTEsdManager.h"
42 #include "AliHLTPluginBase.h"
43 #include "AliHLTMisc.h"
44 #include "AliCDBManager.h"
45 #include "AliCDBEntry.h"
46 #include "AliHLTMessage.h"
47 #include "AliCentralTrigger.h"
48 #include "AliTriggerConfiguration.h"
49 #include "AliTriggerClass.h"
50 #include "AliTriggerCluster.h"
55 /** ROOT macro for the implementation of ROOT specific class methods */
56 ClassImp(AliHLTReconstructor)
58 AliHLTReconstructor::AliHLTReconstructor()
61 , fpPluginBase(new AliHLTPluginBase)
67 AliHLTReconstructor::AliHLTReconstructor(const char* options)
70 , fpPluginBase(new AliHLTPluginBase)
74 if (options) Init(options);
77 AliHLTReconstructor::~AliHLTReconstructor()
82 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
84 AliDebug(0, Form("terminate HLT system: status %#x", pSystem->GetStatusFlags()));
85 if (pSystem->CheckStatus(AliHLTSystem::kStarted)) {
86 // send specific 'event' to execute the stop sequence
87 pSystem->Reconstruct(0, NULL, NULL);
94 if (fpEsdManager) AliHLTEsdManager::Delete(fpEsdManager);
98 void AliHLTReconstructor::Init(const char* options)
100 // init the reconstructor
105 void AliHLTReconstructor::Init()
107 // init the reconstructor
109 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
113 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
115 AliError("can not create AliHLTSystem object");
118 if (pSystem->CheckStatus(AliHLTSystem::kError)) {
119 AliError("HLT system in error state");
123 TString esdManagerOptions;
125 // the options scan has been moved to AliHLTSystem, the old code
126 // here is kept to be able to run an older version of the HLT code
127 // with newer AliRoot versions.
129 TString option = GetOption();
130 TObjArray* pTokens=option.Tokenize(" ");
133 int iEntries=pTokens->GetEntries();
134 for (int i=0; i<iEntries; i++) {
135 TString token=(((TObjString*)pTokens->At(i))->GetString());
136 if (token.Contains("loglevel=")) {
137 TString param=token.ReplaceAll("loglevel=", "");
138 if (param.IsDigit()) {
139 pSystem->SetGlobalLoggingLevel((AliHLTComponentLogSeverity)param.Atoi());
140 } else if (param.BeginsWith("0x") &&
141 param.Replace(0,2,"",0).IsHex()) {
143 sscanf(param.Data(),"%x", &severity);
144 pSystem->SetGlobalLoggingLevel((AliHLTComponentLogSeverity)severity);
146 AliWarning("wrong parameter for option \'loglevel=\', (hex) number expected");
148 } else if (token.Contains("alilog=off")) {
149 pSystem->SwitchAliLog(0);
150 } else if (token.CompareTo("ignore-hltout")==0) {
151 fFlags|=kAliHLTReconstructorIgnoreHLTOUT;
152 } else if (token.CompareTo("ignore-ctp")==0) {
153 fFlags|=kAliHLTReconstructorIgnoreCTP;
154 } else if (token.Contains("esdmanager=")) {
155 token.ReplaceAll("esdmanager=", "");
156 token.ReplaceAll(","," ");
157 token.ReplaceAll("'","");
158 esdManagerOptions=token;
159 } else if (token.BeginsWith("lib") && token.EndsWith(".so")) {
163 if (option.Length()>0) option+=" ";
172 if ((fFlags&kAliHLTReconstructorIgnoreCTP)==0 &&
173 BuildCTPTriggerClassString(ctpParam)>=0) {
174 if (!ecsParam.IsNull()) ecsParam+=";";
175 ecsParam+="CTP_TRIGGER_CLASS=";
179 if (!ecsParam.IsNull()) {
184 if (!libs.IsNull() &&
185 (!pSystem->CheckStatus(AliHLTSystem::kLibrariesLoaded)) &&
186 (pSystem->LoadComponentLibraries(libs.Data())<0)) {
187 AliError("error while loading HLT libraries");
191 if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
192 if (pSystem->ScanOptions(option.Data())<0) {
193 AliError("error setting options for HLT system");
196 if ((pSystem->Configure())<0) {
197 AliError("error during HLT system configuration");
202 fpEsdManager=AliHLTEsdManager::New();
203 fpEsdManager->SetOption(esdManagerOptions.Data());
208 const char* AliHLTReconstructor::fgkCalibStreamerInfoEntry="HLT/Calib/StreamerInfo";
210 int AliHLTReconstructor::InitStreamerInfos()
212 // init streamer infos for HLT reconstruction
213 // Root schema evolution is not enabled for AliHLTMessage and all streamed objects.
214 // Objects in the raw data payload rely on the availability of the correct stream info.
215 // The relevant streamer info for a specific run is stored in the OCDB.
216 // The method evaluates the following entries:
217 // - HLT/Calib/StreamerInfo
220 // to be activated later, this is supposed to go as patch into the v4-17-Release branch
221 // which doe snot have the AliHLTMisc implementation
222 //AliCDBEntry* pEntry=AliHLTMisc::Instance().LoadOCDBEntry(fgkCalibStreamerInfoEntry);
223 AliCDBEntry* pEntry=AliCDBManager::Instance()->Get(fgkCalibStreamerInfoEntry);
224 TObject* pObject=NULL;
225 //if (pEntry && (pObject=AliHLTMisc::Instance().ExtractObject(pEntry))!=NULL)
226 if (pEntry && (pObject=pEntry->GetObject())!=NULL)
228 TObjArray* pSchemas=dynamic_cast<TObjArray*>(pObject);
230 iResult=InitStreamerInfos(pSchemas);
232 AliError(Form("internal mismatch in OCDB entry %s: wrong class type", fgkCalibStreamerInfoEntry));
235 AliWarning(Form("missing HLT reco data (%s), skipping initialization of streamer info for TObjects in HLT raw data payload", fgkCalibStreamerInfoEntry));
240 int AliHLTReconstructor::InitStreamerInfos(TObjArray* pSchemas) const
242 // init streamer infos for HLT reconstruction from an array of TStreamerInfo objects
244 for (int i=0; i<pSchemas->GetEntriesFast(); i++) {
245 if (pSchemas->At(i)) {
246 TStreamerInfo* pSchema=dynamic_cast<TStreamerInfo*>(pSchemas->At(i));
248 int version=pSchema->GetClassVersion();
249 TClass* pClass=TClass::GetClass(pSchema->GetName());
251 if (pClass->GetClassVersion()==version) {
252 AliDebug(0,Form("skipping schema definition %d version %d to class %s as this is the native version", i, version, pSchema->GetName()));
255 TObjArray* pInfos=pClass->GetStreamerInfos();
256 if (pInfos /*&& version<pInfos->GetEntriesFast()*/) {
257 if (pInfos->At(version)==NULL) {
258 TStreamerInfo* pClone=(TStreamerInfo*)pSchema->Clone();
260 pClone->SetClass(pClass);
262 pInfos->AddAtAndExpand(pClone, version);
263 AliDebug(0,Form("adding schema definition %d version %d to class %s", i, version, pSchema->GetName()));
265 AliError(Form("skipping schema definition %d (%s), unable to create clone object", i, pSchema->GetName()));
268 TStreamerInfo* pInfo=dynamic_cast<TStreamerInfo*>(pInfos->At(version));
269 if (pInfo && pInfo->GetClassVersion()==version) {
270 AliDebug(0,Form("schema definition %d version %d already available in class %s, skipping ...", i, version, pSchema->GetName()));
272 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));
276 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));
279 AliError(Form("skipping schema definition %d (%s), unable to find class", i, pSchema->GetName()));
282 AliError(Form("skipping schema definition %d, not of TStreamerInfo", i));
290 void AliHLTReconstructor::Reconstruct(AliRawReader* rawReader, TTree* /*clustersTree*/) const
292 // reconstruction of real data without writing of ESD
293 // For each event, HLT reconstruction chains can be executed and
294 // added to the existing HLTOUT data
295 // The HLTOUT data is finally processed in FillESD
297 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
302 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
305 if (pSystem->CheckStatus(AliHLTSystem::kError)) {
306 AliError("HLT system in error state");
309 if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
310 AliError("HLT system in wrong state");
313 if ((iResult=pSystem->Reconstruct(1, NULL, rawReader))>=0) {
318 void AliHLTReconstructor::FillESD(AliRawReader* rawReader, TTree* /*clustersTree*/,
319 AliESDEvent* esd) const
321 // reconstruct real data and fill ESD
322 if (!rawReader || !esd) {
323 AliError("missing raw reader or esd object");
328 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
332 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
335 if (pSystem->CheckStatus(AliHLTSystem::kError)) {
336 AliError("HLT system in error state");
339 if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
340 AliError("HLT system in wrong state");
343 pSystem->FillESD(-1, NULL, esd);
345 AliRawReader* input=NULL;
346 if ((fFlags&kAliHLTReconstructorIgnoreHLTOUT) == 0 ) {
349 AliHLTOUTRawReader* pHLTOUT=new AliHLTOUTRawReader(input, esd->GetEventNumberInFile(), fpEsdManager);
351 ProcessHLTOUT(pHLTOUT, esd, (pSystem->GetGlobalLoggingLevel()&kHLTLogDebug)!=0);
354 AliError("error creating HLTOUT handler");
359 void AliHLTReconstructor::Reconstruct(TTree* /*digitsTree*/, TTree* /*clustersTree*/) const
361 // reconstruct simulated data
363 // all reconstruction has been moved to FillESD
364 //AliReconstructor::Reconstruct(digitsTree,clustersTree);
365 AliInfo("running digit data reconstruction");
368 void AliHLTReconstructor::FillESD(TTree* /*digitsTree*/, TTree* /*clustersTree*/, AliESDEvent* esd) const
370 // reconstruct simulated data and fill ESD
372 // later this is the place to extract the simulated HLT data
373 // for now it's only an user failure condition as he tries to run HLT reconstruction
375 TString option = GetOption();
376 if (!option.IsNull() &&
377 (option.Contains("config=") || option.Contains("chains="))) {
378 AliWarning(Form("HLT reconstruction can be run embedded into Alireconstruction from\n"
379 "raw data (real or simulated)). Reconstruction of of digit data takes\n"
380 "place in AliSimulation, appropriate input conversion is needed.\n"
381 "Consider running embedded into AliSimulation."
382 " /*** run macro *****************************************/\n"
383 " AliSimulation sim;\n"
384 " sim.SetRunHLT(\"%s\");\n"
385 " sim.SetRunGeneration(kFALSE);\n"
386 " sim.SetMakeDigits(\"\");\n"
387 " sim.SetMakeSDigits(\"\");\n"
388 " sim.SetMakeDigitsFromHits(\"\");\n"
390 " /*********************************************************/", option.Data()));
393 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
397 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
399 if (pSystem->CheckStatus(AliHLTSystem::kError)) {
400 AliError("HLT system in error state");
403 if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
404 AliError("HLT system in wrong state");
408 AliHLTOUTDigitReader* pHLTOUT=new AliHLTOUTDigitReader(esd->GetEventNumberInFile(), fpEsdManager);
410 ProcessHLTOUT(pHLTOUT, esd, (pSystem->GetGlobalLoggingLevel()&kHLTLogDebug)!=0);
413 AliError("error creating HLTOUT handler");
418 void AliHLTReconstructor::ProcessHLTOUT(AliHLTOUT* pHLTOUT, AliESDEvent* esd, bool bVerbose) const
420 // treatment of simulated or real HLTOUT data
421 if (!pHLTOUT) return;
423 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
427 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
429 AliError("error getting HLT system instance");
433 if (pHLTOUT->Init()<0) {
434 AliError("error : initialization of HLTOUT handler failed");
439 PrintHLTOUTContent(pHLTOUT);
441 int blockindex=pHLTOUT->SelectFirstDataBlock(kAliHLTDataTypeStreamerInfo);
443 const AliHLTUInt8_t* pBuffer=NULL;
444 AliHLTUInt32_t size=0;
445 if (pHLTOUT->GetDataBuffer(pBuffer, size)>=0) {
446 TObject* pObject=AliHLTMessage::Extract(pBuffer, size);
448 TObjArray* pArray=dynamic_cast<TObjArray*>(pObject);
450 InitStreamerInfos(pArray);
452 AliError(Form("wrong class type of streamer info list: expected TObjArray, but object is of type %s", pObject->Class()->GetName()));
455 AliError(Form("failed to extract object from data block of type %s", AliHLTComponent::DataType2Text(kAliHLTDataTypeStreamerInfo).c_str()));
458 AliError(Form("failed to get data buffer for block of type %s", AliHLTComponent::DataType2Text(kAliHLTDataTypeStreamerInfo).c_str()));
462 if (pSystem->ProcessHLTOUT(pHLTOUT, esd)<0) {
463 AliError("error processing HLTOUT");
467 AliInfo("HLT ESD content:");
473 void AliHLTReconstructor::ProcessHLTOUT(const char* digitFile, AliESDEvent* pEsd) const
475 // debugging/helper function to examine simulated data
476 if (!digitFile) return;
478 // read the number of events
480 if (f.IsZombie()) return;
482 f.GetObject("rawhltout", pTree);
484 AliWarning(Form("can not find tree rawhltout in file %s", digitFile));
487 int nofEvents=pTree->GetEntries();
489 //delete pTree; OF COURSE NOT! its an object in the file
492 for (int event=0; event<nofEvents; event++) {
493 AliHLTOUTDigitReader* pHLTOUT=new AliHLTOUTDigitReader(event, fpEsdManager, digitFile);
495 AliInfo(Form("event %d", event));
496 ProcessHLTOUT(pHLTOUT, pEsd, true);
499 AliError("error creating HLTOUT handler");
504 void AliHLTReconstructor::ProcessHLTOUT(AliRawReader* pRawReader, AliESDEvent* pEsd) const
506 // debugging/helper function to examine simulated or real HLTOUT data
507 if (!pRawReader) return;
509 pRawReader->RewindEvents();
510 for (int event=0; pRawReader->NextEvent(); event++) {
511 AliHLTOUTRawReader* pHLTOUT=new AliHLTOUTRawReader(pRawReader, event, fpEsdManager);
513 AliInfo(Form("event %d", event));
514 // the two event fields contain: period - orbit - bunch crossing counter
518 // | 28 bit | 24 bit | 12|
520 AliHLTUInt64_t eventId=0;
521 const UInt_t* rawreaderEventId=pRawReader->GetEventId();
522 if (rawreaderEventId) {
523 eventId=rawreaderEventId[0];
525 eventId|=rawreaderEventId[1];
527 AliInfo(Form("Event Id from rawreader:\t 0x%016llx", eventId));
528 ProcessHLTOUT(pHLTOUT, pEsd, true);
531 AliError("error creating HLTOUT handler");
536 void AliHLTReconstructor::PrintHLTOUTContent(AliHLTOUT* pHLTOUT) const
538 // print the block specifications of the HLTOUT data blocks
539 if (!pHLTOUT) return;
542 AliInfo(Form("Event Id from hltout:\t 0x%016llx", pHLTOUT->EventId()));
543 for (iResult=pHLTOUT->SelectFirstDataBlock();
545 iResult=pHLTOUT->SelectNextDataBlock()) {
546 AliHLTComponentDataType dt=kAliHLTVoidDataType;
547 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
548 pHLTOUT->GetDataBlockDescription(dt, spec);
549 const AliHLTUInt8_t* pBuffer=NULL;
550 AliHLTUInt32_t size=0;
551 if (pHLTOUT->GetDataBuffer(pBuffer, size)>=0) {
552 pHLTOUT->ReleaseDataBuffer(pBuffer);
553 pBuffer=NULL; // just a dummy
555 AliInfo(Form(" %s 0x%x: size %d", AliHLTComponent::DataType2Text(dt).c_str(), spec, size));
559 int AliHLTReconstructor::BuildCTPTriggerClassString(TString& triggerclasses) const
561 // build the CTP trigger class string from the OCDB entry of the CTP trigger
564 triggerclasses.Clear();
565 AliCentralTrigger* pCTP = new AliCentralTrigger();
566 AliTriggerConfiguration *config=NULL;
567 TString configstr("");
568 if (pCTP->LoadConfiguration(configstr) &&
569 (config = pCTP->GetConfiguration())!=NULL) {
570 const TObjArray& classesArray = config->GetClasses();
571 int nclasses = classesArray.GetEntriesFast();
572 for( int iclass=0; iclass < nclasses; iclass++ ) {
573 AliTriggerClass* trclass = NULL;
574 if (classesArray.At(iclass) && (trclass=dynamic_cast<AliTriggerClass*>(classesArray.At(iclass)))!=NULL) {
576 int trindex = TMath::Nint(TMath::Log2(trclass->GetMask()));
577 entry.Form("%02d:%s:", trindex, trclass->GetName());
578 AliTriggerCluster* cluster=NULL;
579 TObject* clusterobj=config->GetClusters().FindObject(trclass->GetCluster());
580 if (clusterobj && (cluster=dynamic_cast<AliTriggerCluster*>(clusterobj))!=NULL) {
581 TString detectors=cluster->GetDetectorsInCluster();
582 TObjArray* pTokens=detectors.Tokenize(" ");
584 for (int dix=0; dix<pTokens->GetEntriesFast(); dix++) {
585 int id=AliDAQ::DetectorID(((TObjString*)pTokens->At(dix))->GetString());
587 TString detstr; detstr.Form("%s%02d", dix>0?"-":"", id);
590 AliError(Form("invalid detector name extracted from trigger cluster: %s (%s)", ((TObjString*)pTokens->At(dix))->GetString().Data(), detectors.Data()));
598 AliError(Form("can not find trigger cluster %s in config", trclass->GetCluster()));
602 if (!triggerclasses.IsNull()) triggerclasses+=",";
603 triggerclasses+=entry;