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"
52 #include "AliRunLoader.h"
56 /** ROOT macro for the implementation of ROOT specific class methods */
57 ClassImp(AliHLTReconstructor)
59 AliHLTReconstructor::AliHLTReconstructor()
62 , fpPluginBase(new AliHLTPluginBase)
68 AliHLTReconstructor::AliHLTReconstructor(const char* options)
71 , fpPluginBase(new AliHLTPluginBase)
75 if (options) Init(options);
78 AliHLTReconstructor::~AliHLTReconstructor()
82 if (fpEsdManager) AliHLTEsdManager::Delete(fpEsdManager);
86 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
88 AliDebug(0, Form("terminate HLT system: status %#x", pSystem->GetStatusFlags()));
89 if (pSystem->CheckStatus(AliHLTSystem::kStarted)) {
90 // send specific 'event' to execute the stop sequence
91 pSystem->Reconstruct(0, NULL, NULL);
100 void AliHLTReconstructor::Init(const char* options)
102 // init the reconstructor
107 void AliHLTReconstructor::Init()
109 // init the reconstructor
111 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
115 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
117 AliError("can not create AliHLTSystem object");
120 if (pSystem->CheckStatus(AliHLTSystem::kError)) {
121 AliError("HLT system in error state");
125 TString esdManagerOptions;
127 // the options scan has been moved to AliHLTSystem, the old code
128 // here is kept to be able to run an older version of the HLT code
129 // 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("run-online-config")==0) {
154 fFlags|=kAliHLTReconstructorIgnoreHLTOUT;
155 if (option.Length()>0) option+=" ";
157 } else if (token.CompareTo("ignore-ctp")==0) {
158 fFlags|=kAliHLTReconstructorIgnoreCTP;
159 } else if (token.Contains("esdmanager=")) {
160 token.ReplaceAll("esdmanager=", "");
161 token.ReplaceAll(","," ");
162 token.ReplaceAll("'","");
163 esdManagerOptions=token;
165 if (option.Length()>0) option+=" ";
174 if ((fFlags&kAliHLTReconstructorIgnoreCTP)==0 &&
175 BuildCTPTriggerClassString(ctpParam)>=0) {
176 if (!ecsParam.IsNull()) ecsParam+=";";
177 ecsParam+="CTP_TRIGGER_CLASS=";
181 if (!ecsParam.IsNull()) {
186 if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
187 if (pSystem->ScanOptions(option.Data())<0) {
188 AliError("error setting options for HLT system");
191 if ((pSystem->Configure())<0) {
192 AliError("error during HLT system configuration");
197 fpEsdManager=AliHLTEsdManager::New();
199 fpEsdManager->SetOption(esdManagerOptions.Data());
202 AliHLTMisc::Instance().InitStreamerInfos(fgkCalibStreamerInfoEntry);
205 void AliHLTReconstructor::Terminate() const
207 AliInfo("terminating");
209 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
211 AliDebug(0, Form("terminate HLT system: status %#x", pSystem->GetStatusFlags()));
212 if (pSystem->CheckStatus(AliHLTSystem::kStarted)) {
213 // send specific 'event' to execute the stop sequence
214 pSystem->Reconstruct(0, NULL, NULL);
220 const char* AliHLTReconstructor::fgkCalibStreamerInfoEntry="HLT/Calib/StreamerInfo";
222 void AliHLTReconstructor::Reconstruct(AliRawReader* rawReader, TTree* /*clustersTree*/) const
224 // reconstruction of real data without writing of ESD
225 // For each event, HLT reconstruction chains can be executed and
226 // added to the existing HLTOUT data
227 // The HLTOUT data is finally processed in FillESD
230 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
235 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
238 AliHLTOUT* pHLTOUT=NULL;
239 pSystem->InvalidateHLTOUT(&pHLTOUT);
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");
253 // init the HLTOUT instance for the current event
254 // not nice. Have to query the global run loader to get the current event no.
256 AliRunLoader* runloader = AliRunLoader::Instance();
258 eventNo=runloader->GetEventNumber();
261 AliRawReader* input=NULL;
262 if ((fFlags&kAliHLTReconstructorIgnoreHLTOUT) == 0 ) {
265 pHLTOUT=new AliHLTOUTRawReader(input, eventNo, fpEsdManager);
267 if (pHLTOUT->Init()>=0) {
268 pSystem->InitHLTOUT(pHLTOUT);
270 AliError("error : initialization of HLTOUT handler failed");
273 AliError("memory allocation failed: can not create AliHLTOUT object");
276 AliError("can not get event number");
279 if ((iResult=pSystem->Reconstruct(1, NULL, rawReader))>=0) {
284 void AliHLTReconstructor::FillESD(AliRawReader* rawReader, TTree* /*clustersTree*/,
285 AliESDEvent* esd) const
287 // reconstruct real data and fill ESD
288 if (!rawReader || !esd) {
289 AliError("missing raw reader or esd object");
294 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
298 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
301 if (pSystem->CheckStatus(AliHLTSystem::kError)) {
302 AliError("HLT system in error state");
305 if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
306 AliError("HLT system in wrong state");
309 pSystem->FillESD(-1, NULL, esd);
311 // the HLTOUT handler has either been created in the AliHLTReconstructor::Reconstruct
312 // step of this event or is created now. In either case the instance is deleted after
314 AliHLTOUT* pHLTOUT=NULL;
315 pSystem->InvalidateHLTOUT(&pHLTOUT);
317 AliRawReader* input=NULL;
318 if ((fFlags&kAliHLTReconstructorIgnoreHLTOUT) == 0 ) {
321 pHLTOUT=new AliHLTOUTRawReader(input, esd->GetEventNumberInFile(), fpEsdManager);
324 ProcessHLTOUT(pHLTOUT, esd, (pSystem->GetGlobalLoggingLevel()&kHLTLogDebug)!=0);
327 AliError("error creating HLTOUT handler");
332 void AliHLTReconstructor::Reconstruct(TTree* /*digitsTree*/, TTree* /*clustersTree*/) const
334 // reconstruct simulated data
336 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
339 // create the HLTOUT instance in order to be available for other detector reconstruction
340 // first cleanup any existing instance
341 AliHLTOUT* pHLTOUT=NULL;
342 pSystem->InvalidateHLTOUT(&pHLTOUT);
348 // not nice. Have to query the global run loader to get the current event no.
349 // This is related to the missing AliLoader for HLT.
350 // Since AliReconstruction can not provide a digits tree, the file needs to be accessed
351 // explicitely, and the corresponding event needs to be selected.
353 AliRunLoader* runloader = AliRunLoader::Instance();
355 eventNo=runloader->GetEventNumber();
358 const char* digitfile=NULL;
359 if ((fFlags&kAliHLTReconstructorIgnoreHLTOUT) == 0 ) {
360 digitfile="HLT.Digits.root";
363 pHLTOUT=new AliHLTOUTDigitReader(eventNo, fpEsdManager, digitfile);
365 if (pHLTOUT->Init()>=0) {
366 pSystem->InitHLTOUT(pHLTOUT);
368 AliError("error : initialization of HLTOUT handler failed");
371 AliError("memory allocation failed: can not create AliHLTOUT object");
374 AliError("can not get event number");
377 // all data processing happens in FillESD
381 void AliHLTReconstructor::FillESD(TTree* /*digitsTree*/, TTree* /*clustersTree*/, AliESDEvent* esd) const
383 // reconstruct simulated data and fill ESD
385 // later this is the place to extract the simulated HLT data
386 // for now it's only an user failure condition as he tries to run HLT reconstruction
388 TString option = GetOption();
389 if (!option.IsNull() &&
390 (option.Contains("config=") || option.Contains("chains="))) {
391 AliWarning(Form("You are trying to run a custom HLT chain on digits data.\n\n"
392 "HLT reconstruction can be run embedded into AliReconstruction from\n"
393 "raw data (real or simulated)). Reconstruction of digit data takes\n"
394 "place in AliSimulation, appropriate input conversion is needed to\n"
395 "feed data from the detector digits into the HLT chain.\n"
396 "Consider running embedded into AliSimulation.\n"
397 " /*** run macro *****************************************/\n"
398 " AliSimulation sim;\n"
399 " sim.SetRunHLT(\"%s\");\n"
400 " sim.SetRunGeneration(kFALSE);\n"
401 " sim.SetMakeDigits(\"\");\n"
402 " sim.SetMakeSDigits(\"\");\n"
403 " sim.SetMakeDigitsFromHits(\"\");\n"
405 " /*********************************************************/\n\n",
409 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
413 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
415 if (pSystem->CheckStatus(AliHLTSystem::kError)) {
416 AliError("HLT system in error state");
419 if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
420 AliError("HLT system in wrong state");
424 // the HLTOUT handler has either been created in the AliHLTReconstructor::Reconstruct
425 // step of this event or is created now. In either case the instance is deleted after
427 AliHLTOUT* pHLTOUT=NULL;
428 pSystem->InvalidateHLTOUT(&pHLTOUT);
430 const char* digitfile=NULL;
431 if ((fFlags&kAliHLTReconstructorIgnoreHLTOUT) == 0 ) {
432 digitfile="HLT.Digits.root";
434 pHLTOUT=new AliHLTOUTDigitReader(esd->GetEventNumberInFile(), fpEsdManager, digitfile);
438 ProcessHLTOUT(pHLTOUT, esd, (pSystem->GetGlobalLoggingLevel()&kHLTLogDebug)!=0);
441 AliError("error creating HLTOUT handler");
446 void AliHLTReconstructor::ProcessHLTOUT(AliHLTOUT* pHLTOUT, AliESDEvent* esd, bool bVerbose) const
448 // treatment of simulated or real HLTOUT data
449 if (!pHLTOUT) return;
451 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
455 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
457 AliError("error getting HLT system instance");
461 if (pHLTOUT->Init()<0) {
462 AliError("error : initialization of HLTOUT handler failed");
467 PrintHLTOUTContent(pHLTOUT);
469 int blockindex=pHLTOUT->SelectFirstDataBlock(kAliHLTDataTypeStreamerInfo);
471 const AliHLTUInt8_t* pBuffer=NULL;
472 AliHLTUInt32_t size=0;
473 if (pHLTOUT->GetDataBuffer(pBuffer, size)>=0) {
474 TObject* pObject=AliHLTMessage::Extract(pBuffer, size);
476 TObjArray* pArray=dynamic_cast<TObjArray*>(pObject);
478 AliHLTMisc::Instance().InitStreamerInfos(pArray);
480 AliError(Form("wrong class type of streamer info list: expected TObjArray, but object is of type %s", pObject->Class()->GetName()));
483 AliError(Form("failed to extract object from data block of type %s", AliHLTComponent::DataType2Text(kAliHLTDataTypeStreamerInfo).c_str()));
486 AliError(Form("failed to get data buffer for block of type %s", AliHLTComponent::DataType2Text(kAliHLTDataTypeStreamerInfo).c_str()));
490 if (pSystem->ProcessHLTOUT(pHLTOUT, esd)<0) {
491 AliError("error processing HLTOUT");
494 if (bVerbose && esd) {
495 AliInfo("HLT ESD content:");
501 void AliHLTReconstructor::ProcessHLTOUT(const char* digitFile, AliESDEvent* pEsd) const
503 // debugging/helper function to examine simulated data
504 if (!digitFile) return;
506 // read the number of events
508 if (f.IsZombie()) return;
510 f.GetObject("rawhltout", pTree);
512 AliWarning(Form("can not find tree rawhltout in file %s", digitFile));
515 int nofEvents=pTree->GetEntries();
517 //delete pTree; OF COURSE NOT! its an object in the file
520 for (int event=0; event<nofEvents; event++) {
521 AliHLTOUTDigitReader* pHLTOUT=new AliHLTOUTDigitReader(event, fpEsdManager, digitFile);
523 AliInfo(Form("event %d", event));
524 ProcessHLTOUT(pHLTOUT, pEsd, true);
527 AliError("error creating HLTOUT handler");
532 void AliHLTReconstructor::ProcessHLTOUT(AliRawReader* pRawReader, AliESDEvent* pEsd) const
534 // debugging/helper function to examine simulated or real HLTOUT data
535 if (!pRawReader) return;
537 pRawReader->RewindEvents();
538 for (int event=0; pRawReader->NextEvent(); event++) {
539 AliHLTOUTRawReader* pHLTOUT=new AliHLTOUTRawReader(pRawReader, event, fpEsdManager);
541 AliInfo(Form("event %d", event));
542 // the two event fields contain: period - orbit - bunch crossing counter
546 // | 28 bit | 24 bit | 12|
548 AliHLTUInt64_t eventId=0;
549 const UInt_t* rawreaderEventId=pRawReader->GetEventId();
550 if (rawreaderEventId) {
551 eventId=rawreaderEventId[0];
553 eventId|=rawreaderEventId[1];
555 AliInfo(Form("Event Id from rawreader:\t 0x%016llx", eventId));
556 ProcessHLTOUT(pHLTOUT, pEsd, true);
559 AliError("error creating HLTOUT handler");
564 void AliHLTReconstructor::PrintHLTOUTContent(AliHLTOUT* pHLTOUT) const
566 // print the block specifications of the HLTOUT data blocks
567 if (!pHLTOUT) return;
570 AliInfo(Form("Event Id from hltout:\t 0x%016llx", pHLTOUT->EventId()));
571 for (iResult=pHLTOUT->SelectFirstDataBlock();
573 iResult=pHLTOUT->SelectNextDataBlock()) {
574 AliHLTComponentDataType dt=kAliHLTVoidDataType;
575 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
576 pHLTOUT->GetDataBlockDescription(dt, spec);
577 const AliHLTUInt8_t* pBuffer=NULL;
578 AliHLTUInt32_t size=0;
579 if (pHLTOUT->GetDataBuffer(pBuffer, size)>=0) {
580 pHLTOUT->ReleaseDataBuffer(pBuffer);
581 pBuffer=NULL; // just a dummy
583 AliInfo(Form(" %s 0x%x: size %d", AliHLTComponent::DataType2Text(dt).c_str(), spec, size));
587 int AliHLTReconstructor::BuildCTPTriggerClassString(TString& triggerclasses) const
589 // build the CTP trigger class string from the OCDB entry of the CTP trigger
592 triggerclasses.Clear();
593 AliCentralTrigger* pCTP = new AliCentralTrigger();
594 AliTriggerConfiguration *config=NULL;
595 TString configstr("");
596 if (pCTP->LoadConfiguration(configstr) &&
597 (config = pCTP->GetConfiguration())!=NULL) {
598 const TObjArray& classesArray = config->GetClasses();
599 int nclasses = classesArray.GetEntriesFast();
600 for( int iclass=0; iclass < nclasses; iclass++ ) {
601 AliTriggerClass* trclass = NULL;
602 if (classesArray.At(iclass) && (trclass=dynamic_cast<AliTriggerClass*>(classesArray.At(iclass)))!=NULL) {
604 int trindex = TMath::Nint(TMath::Log2(trclass->GetMask()));
605 entry.Form("%02d:%s:", trindex, trclass->GetName());
606 AliTriggerCluster* cluster=NULL;
607 TObject* clusterobj=config->GetClusters().FindObject(trclass->GetCluster());
608 if (clusterobj && (cluster=dynamic_cast<AliTriggerCluster*>(clusterobj))!=NULL) {
609 TString detectors=cluster->GetDetectorsInCluster();
610 TObjArray* pTokens=detectors.Tokenize(" ");
612 for (int dix=0; dix<pTokens->GetEntriesFast(); dix++) {
613 int id=AliDAQ::DetectorID(((TObjString*)pTokens->At(dix))->GetString());
615 TString detstr; detstr.Form("%s%02d", dix>0?"-":"", id);
618 AliError(Form("invalid detector name extracted from trigger cluster: %s (%s)", ((TObjString*)pTokens->At(dix))->GetString().Data(), detectors.Data()));
626 AliError(Form("can not find trigger cluster %s in config", trclass->GetCluster()?trclass->GetCluster()->GetName():"NULL"));
630 if (!triggerclasses.IsNull()) triggerclasses+=",";
631 triggerclasses+=entry;