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.
128 TString option = GetOption();
129 TObjArray* pTokens=option.Tokenize(" ");
132 int iEntries=pTokens->GetEntries();
133 for (int i=0; i<iEntries; i++) {
134 TString token=(((TObjString*)pTokens->At(i))->GetString());
135 if (token.Contains("loglevel=")) {
136 TString param=token.ReplaceAll("loglevel=", "");
137 if (param.IsDigit()) {
138 pSystem->SetGlobalLoggingLevel((AliHLTComponentLogSeverity)param.Atoi());
139 } else if (param.BeginsWith("0x") &&
140 param.Replace(0,2,"",0).IsHex()) {
142 sscanf(param.Data(),"%x", &severity);
143 pSystem->SetGlobalLoggingLevel((AliHLTComponentLogSeverity)severity);
145 AliWarning("wrong parameter for option \'loglevel=\', (hex) number expected");
147 } else if (token.Contains("alilog=off")) {
148 pSystem->SwitchAliLog(0);
149 } else if (token.CompareTo("ignore-hltout")==0) {
150 fFlags|=kAliHLTReconstructorIgnoreHLTOUT;
151 } else if (token.CompareTo("ignore-ctp")==0) {
152 fFlags|=kAliHLTReconstructorIgnoreCTP;
153 } else if (token.Contains("esdmanager=")) {
154 token.ReplaceAll("esdmanager=", "");
155 token.ReplaceAll(","," ");
156 token.ReplaceAll("'","");
157 esdManagerOptions=token;
159 if (option.Length()>0) option+=" ";
168 if ((fFlags&kAliHLTReconstructorIgnoreCTP)==0 &&
169 BuildCTPTriggerClassString(ctpParam)>=0) {
170 if (!ecsParam.IsNull()) ecsParam+=";";
171 ecsParam+="CTP_TRIGGER_CLASS=";
175 if (!ecsParam.IsNull()) {
180 if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
181 if (pSystem->ScanOptions(option.Data())<0) {
182 AliError("error setting options for HLT system");
185 if ((pSystem->Configure())<0) {
186 AliError("error during HLT system configuration");
191 fpEsdManager=AliHLTEsdManager::New();
192 fpEsdManager->SetOption(esdManagerOptions.Data());
194 AliHLTMisc::Instance().InitStreamerInfos(fgkCalibStreamerInfoEntry);
197 const char* AliHLTReconstructor::fgkCalibStreamerInfoEntry="HLT/Calib/StreamerInfo";
199 void AliHLTReconstructor::Reconstruct(AliRawReader* rawReader, TTree* /*clustersTree*/) const
201 // reconstruction of real data without writing of ESD
202 // For each event, HLT reconstruction chains can be executed and
203 // added to the existing HLTOUT data
204 // The HLTOUT data is finally processed in FillESD
206 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
211 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
214 if (pSystem->CheckStatus(AliHLTSystem::kError)) {
215 AliError("HLT system in error state");
218 if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
219 AliError("HLT system in wrong state");
222 if ((iResult=pSystem->Reconstruct(1, NULL, rawReader))>=0) {
227 void AliHLTReconstructor::FillESD(AliRawReader* rawReader, TTree* /*clustersTree*/,
228 AliESDEvent* esd) const
230 // reconstruct real data and fill ESD
231 if (!rawReader || !esd) {
232 AliError("missing raw reader or esd object");
237 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
241 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
244 if (pSystem->CheckStatus(AliHLTSystem::kError)) {
245 AliError("HLT system in error state");
248 if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
249 AliError("HLT system in wrong state");
252 pSystem->FillESD(-1, NULL, esd);
254 AliRawReader* input=NULL;
255 if ((fFlags&kAliHLTReconstructorIgnoreHLTOUT) == 0 ) {
258 AliHLTOUTRawReader* pHLTOUT=new AliHLTOUTRawReader(input, esd->GetEventNumberInFile(), fpEsdManager);
260 ProcessHLTOUT(pHLTOUT, esd, (pSystem->GetGlobalLoggingLevel()&kHLTLogDebug)!=0);
263 AliError("error creating HLTOUT handler");
268 void AliHLTReconstructor::Reconstruct(TTree* /*digitsTree*/, TTree* /*clustersTree*/) const
270 // reconstruct simulated data
272 // all reconstruction has been moved to FillESD
273 //AliReconstructor::Reconstruct(digitsTree,clustersTree);
274 AliInfo("running digit data reconstruction");
277 void AliHLTReconstructor::FillESD(TTree* /*digitsTree*/, TTree* /*clustersTree*/, AliESDEvent* esd) const
279 // reconstruct simulated data and fill ESD
281 // later this is the place to extract the simulated HLT data
282 // for now it's only an user failure condition as he tries to run HLT reconstruction
284 TString option = GetOption();
285 if (!option.IsNull() &&
286 (option.Contains("config=") || option.Contains("chains="))) {
287 AliWarning(Form("HLT reconstruction can be run embedded into Alireconstruction from\n"
288 "raw data (real or simulated)). Reconstruction of of digit data takes\n"
289 "place in AliSimulation, appropriate input conversion is needed.\n"
290 "Consider running embedded into AliSimulation."
291 " /*** run macro *****************************************/\n"
292 " AliSimulation sim;\n"
293 " sim.SetRunHLT(\"%s\");\n"
294 " sim.SetRunGeneration(kFALSE);\n"
295 " sim.SetMakeDigits(\"\");\n"
296 " sim.SetMakeSDigits(\"\");\n"
297 " sim.SetMakeDigitsFromHits(\"\");\n"
299 " /*********************************************************/", option.Data()));
302 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
306 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
308 if (pSystem->CheckStatus(AliHLTSystem::kError)) {
309 AliError("HLT system in error state");
312 if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
313 AliError("HLT system in wrong state");
317 AliHLTOUTDigitReader* pHLTOUT=new AliHLTOUTDigitReader(esd->GetEventNumberInFile(), fpEsdManager);
319 ProcessHLTOUT(pHLTOUT, esd, (pSystem->GetGlobalLoggingLevel()&kHLTLogDebug)!=0);
322 AliError("error creating HLTOUT handler");
327 void AliHLTReconstructor::ProcessHLTOUT(AliHLTOUT* pHLTOUT, AliESDEvent* esd, bool bVerbose) const
329 // treatment of simulated or real HLTOUT data
330 if (!pHLTOUT) return;
332 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
336 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
338 AliError("error getting HLT system instance");
342 if (pHLTOUT->Init()<0) {
343 AliError("error : initialization of HLTOUT handler failed");
348 PrintHLTOUTContent(pHLTOUT);
350 int blockindex=pHLTOUT->SelectFirstDataBlock(kAliHLTDataTypeStreamerInfo);
352 const AliHLTUInt8_t* pBuffer=NULL;
353 AliHLTUInt32_t size=0;
354 if (pHLTOUT->GetDataBuffer(pBuffer, size)>=0) {
355 TObject* pObject=AliHLTMessage::Extract(pBuffer, size);
357 TObjArray* pArray=dynamic_cast<TObjArray*>(pObject);
359 AliHLTMisc::Instance().InitStreamerInfos(pArray);
361 AliError(Form("wrong class type of streamer info list: expected TObjArray, but object is of type %s", pObject->Class()->GetName()));
364 AliError(Form("failed to extract object from data block of type %s", AliHLTComponent::DataType2Text(kAliHLTDataTypeStreamerInfo).c_str()));
367 AliError(Form("failed to get data buffer for block of type %s", AliHLTComponent::DataType2Text(kAliHLTDataTypeStreamerInfo).c_str()));
371 if (pSystem->ProcessHLTOUT(pHLTOUT, esd)<0) {
372 AliError("error processing HLTOUT");
376 AliInfo("HLT ESD content:");
382 void AliHLTReconstructor::ProcessHLTOUT(const char* digitFile, AliESDEvent* pEsd) const
384 // debugging/helper function to examine simulated data
385 if (!digitFile) return;
387 // read the number of events
389 if (f.IsZombie()) return;
391 f.GetObject("rawhltout", pTree);
393 AliWarning(Form("can not find tree rawhltout in file %s", digitFile));
396 int nofEvents=pTree->GetEntries();
398 //delete pTree; OF COURSE NOT! its an object in the file
401 for (int event=0; event<nofEvents; event++) {
402 AliHLTOUTDigitReader* pHLTOUT=new AliHLTOUTDigitReader(event, fpEsdManager, digitFile);
404 AliInfo(Form("event %d", event));
405 ProcessHLTOUT(pHLTOUT, pEsd, true);
408 AliError("error creating HLTOUT handler");
413 void AliHLTReconstructor::ProcessHLTOUT(AliRawReader* pRawReader, AliESDEvent* pEsd) const
415 // debugging/helper function to examine simulated or real HLTOUT data
416 if (!pRawReader) return;
418 pRawReader->RewindEvents();
419 for (int event=0; pRawReader->NextEvent(); event++) {
420 AliHLTOUTRawReader* pHLTOUT=new AliHLTOUTRawReader(pRawReader, event, fpEsdManager);
422 AliInfo(Form("event %d", event));
423 // the two event fields contain: period - orbit - bunch crossing counter
427 // | 28 bit | 24 bit | 12|
429 AliHLTUInt64_t eventId=0;
430 const UInt_t* rawreaderEventId=pRawReader->GetEventId();
431 if (rawreaderEventId) {
432 eventId=rawreaderEventId[0];
434 eventId|=rawreaderEventId[1];
436 AliInfo(Form("Event Id from rawreader:\t 0x%016llx", eventId));
437 ProcessHLTOUT(pHLTOUT, pEsd, true);
440 AliError("error creating HLTOUT handler");
445 void AliHLTReconstructor::PrintHLTOUTContent(AliHLTOUT* pHLTOUT) const
447 // print the block specifications of the HLTOUT data blocks
448 if (!pHLTOUT) return;
451 AliInfo(Form("Event Id from hltout:\t 0x%016llx", pHLTOUT->EventId()));
452 for (iResult=pHLTOUT->SelectFirstDataBlock();
454 iResult=pHLTOUT->SelectNextDataBlock()) {
455 AliHLTComponentDataType dt=kAliHLTVoidDataType;
456 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
457 pHLTOUT->GetDataBlockDescription(dt, spec);
458 const AliHLTUInt8_t* pBuffer=NULL;
459 AliHLTUInt32_t size=0;
460 if (pHLTOUT->GetDataBuffer(pBuffer, size)>=0) {
461 pHLTOUT->ReleaseDataBuffer(pBuffer);
462 pBuffer=NULL; // just a dummy
464 AliInfo(Form(" %s 0x%x: size %d", AliHLTComponent::DataType2Text(dt).c_str(), spec, size));
468 int AliHLTReconstructor::BuildCTPTriggerClassString(TString& triggerclasses) const
470 // build the CTP trigger class string from the OCDB entry of the CTP trigger
473 triggerclasses.Clear();
474 AliCentralTrigger* pCTP = new AliCentralTrigger();
475 AliTriggerConfiguration *config=NULL;
476 TString configstr("");
477 if (pCTP->LoadConfiguration(configstr) &&
478 (config = pCTP->GetConfiguration())!=NULL) {
479 const TObjArray& classesArray = config->GetClasses();
480 int nclasses = classesArray.GetEntriesFast();
481 for( int iclass=0; iclass < nclasses; iclass++ ) {
482 AliTriggerClass* trclass = NULL;
483 if (classesArray.At(iclass) && (trclass=dynamic_cast<AliTriggerClass*>(classesArray.At(iclass)))!=NULL) {
485 int trindex = TMath::Nint(TMath::Log2(trclass->GetMask()));
486 entry.Form("%02d:%s:", trindex, trclass->GetName());
487 AliTriggerCluster* cluster=NULL;
488 TObject* clusterobj=config->GetClusters().FindObject(trclass->GetCluster());
489 if (clusterobj && (cluster=dynamic_cast<AliTriggerCluster*>(clusterobj))!=NULL) {
490 TString detectors=cluster->GetDetectorsInCluster();
491 TObjArray* pTokens=detectors.Tokenize(" ");
493 for (int dix=0; dix<pTokens->GetEntriesFast(); dix++) {
494 int id=AliDAQ::DetectorID(((TObjString*)pTokens->At(dix))->GetString());
496 TString detstr; detstr.Form("%s%02d", dix>0?"-":"", id);
499 AliError(Form("invalid detector name extracted from trigger cluster: %s (%s)", ((TObjString*)pTokens->At(dix))->GetString().Data(), detectors.Data()));
507 AliError(Form("can not find trigger cluster %s in config", trclass->GetCluster()?trclass->GetCluster()->GetName():"NULL"));
511 if (!triggerclasses.IsNull()) triggerclasses+=",";
512 triggerclasses+=entry;