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 const char* AliHLTReconstructor::fgkCalibStreamerInfoEntry="HLT/Calib/StreamerInfo";
207 void AliHLTReconstructor::Reconstruct(AliRawReader* rawReader, TTree* /*clustersTree*/) const
209 // reconstruction of real data without writing of ESD
210 // For each event, HLT reconstruction chains can be executed and
211 // added to the existing HLTOUT data
212 // The HLTOUT data is finally processed in FillESD
215 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
220 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
223 AliHLTOUT* pHLTOUT=NULL;
224 pSystem->InvalidateHLTOUT(&pHLTOUT);
229 if (pSystem->CheckStatus(AliHLTSystem::kError)) {
230 AliError("HLT system in error state");
233 if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
234 AliError("HLT system in wrong state");
238 // init the HLTOUT instance for the current event
239 // not nice. Have to query the global run loader to get the current event no.
241 AliRunLoader* runloader = AliRunLoader::Instance();
243 eventNo=runloader->GetEventNumber();
246 AliRawReader* input=NULL;
247 if ((fFlags&kAliHLTReconstructorIgnoreHLTOUT) == 0 ) {
250 pHLTOUT=new AliHLTOUTRawReader(input, eventNo, fpEsdManager);
252 if (pHLTOUT->Init()>=0) {
253 pSystem->InitHLTOUT(pHLTOUT);
255 AliError("error : initialization of HLTOUT handler failed");
258 AliError("memory allocation failed: can not create AliHLTOUT object");
261 AliError("can not get event number");
264 if ((iResult=pSystem->Reconstruct(1, NULL, rawReader))>=0) {
269 void AliHLTReconstructor::FillESD(AliRawReader* rawReader, TTree* /*clustersTree*/,
270 AliESDEvent* esd) const
272 // reconstruct real data and fill ESD
273 if (!rawReader || !esd) {
274 AliError("missing raw reader or esd object");
279 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
283 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
286 if (pSystem->CheckStatus(AliHLTSystem::kError)) {
287 AliError("HLT system in error state");
290 if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
291 AliError("HLT system in wrong state");
294 pSystem->FillESD(-1, NULL, esd);
296 // the HLTOUT handler has either been created in the AliHLTReconstructor::Reconstruct
297 // step of this event or is created now. In either case the instance is deleted after
299 AliHLTOUT* pHLTOUT=NULL;
300 pSystem->InvalidateHLTOUT(&pHLTOUT);
302 AliRawReader* input=NULL;
303 if ((fFlags&kAliHLTReconstructorIgnoreHLTOUT) == 0 ) {
306 pHLTOUT=new AliHLTOUTRawReader(input, esd->GetEventNumberInFile(), fpEsdManager);
309 ProcessHLTOUT(pHLTOUT, esd, (pSystem->GetGlobalLoggingLevel()&kHLTLogDebug)!=0);
312 AliError("error creating HLTOUT handler");
317 void AliHLTReconstructor::Reconstruct(TTree* /*digitsTree*/, TTree* /*clustersTree*/) const
319 // reconstruct simulated data
321 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
324 // create the HLTOUT instance in order to be available for other detector reconstruction
325 // first cleanup any existing instance
326 AliHLTOUT* pHLTOUT=NULL;
327 pSystem->InvalidateHLTOUT(&pHLTOUT);
333 // not nice. Have to query the global run loader to get the current event no.
334 // This is related to the missing AliLoader for HLT.
335 // Since AliReconstruction can not provide a digits tree, the file needs to be accessed
336 // explicitely, and the corresponding event needs to be selected.
338 AliRunLoader* runloader = AliRunLoader::Instance();
340 eventNo=runloader->GetEventNumber();
343 const char* digitfile=NULL;
344 if ((fFlags&kAliHLTReconstructorIgnoreHLTOUT) == 0 ) {
345 digitfile="HLT.Digits.root";
348 pHLTOUT=new AliHLTOUTDigitReader(eventNo, fpEsdManager, digitfile);
350 if (pHLTOUT->Init()>=0) {
351 pSystem->InitHLTOUT(pHLTOUT);
353 AliError("error : initialization of HLTOUT handler failed");
356 AliError("memory allocation failed: can not create AliHLTOUT object");
359 AliError("can not get event number");
362 // all data processing happens in FillESD
366 void AliHLTReconstructor::FillESD(TTree* /*digitsTree*/, TTree* /*clustersTree*/, AliESDEvent* esd) const
368 // reconstruct simulated data and fill ESD
370 // later this is the place to extract the simulated HLT data
371 // for now it's only an user failure condition as he tries to run HLT reconstruction
373 TString option = GetOption();
374 if (!option.IsNull() &&
375 (option.Contains("config=") || option.Contains("chains="))) {
376 AliWarning(Form("You are trying to run a custom HLT chain on digits data.\n\n"
377 "HLT reconstruction can be run embedded into AliReconstruction from\n"
378 "raw data (real or simulated)). Reconstruction of digit data takes\n"
379 "place in AliSimulation, appropriate input conversion is needed to\n"
380 "feed data from the detector digits into the HLT chain.\n"
381 "Consider running embedded into AliSimulation.\n"
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 " /*********************************************************/\n\n",
394 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
398 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
400 if (pSystem->CheckStatus(AliHLTSystem::kError)) {
401 AliError("HLT system in error state");
404 if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
405 AliError("HLT system in wrong state");
409 // the HLTOUT handler has either been created in the AliHLTReconstructor::Reconstruct
410 // step of this event or is created now. In either case the instance is deleted after
412 AliHLTOUT* pHLTOUT=NULL;
413 pSystem->InvalidateHLTOUT(&pHLTOUT);
415 const char* digitfile=NULL;
416 if ((fFlags&kAliHLTReconstructorIgnoreHLTOUT) == 0 ) {
417 digitfile="HLT.Digits.root";
419 pHLTOUT=new AliHLTOUTDigitReader(esd->GetEventNumberInFile(), fpEsdManager, digitfile);
423 ProcessHLTOUT(pHLTOUT, esd, (pSystem->GetGlobalLoggingLevel()&kHLTLogDebug)!=0);
426 AliError("error creating HLTOUT handler");
431 void AliHLTReconstructor::ProcessHLTOUT(AliHLTOUT* pHLTOUT, AliESDEvent* esd, bool bVerbose) const
433 // treatment of simulated or real HLTOUT data
434 if (!pHLTOUT) return;
436 AliError("internal memory error: can not get AliHLTSystem instance from plugin");
440 AliHLTSystem* pSystem=fpPluginBase->GetInstance();
442 AliError("error getting HLT system instance");
446 if (pHLTOUT->Init()<0) {
447 AliError("error : initialization of HLTOUT handler failed");
452 PrintHLTOUTContent(pHLTOUT);
454 int blockindex=pHLTOUT->SelectFirstDataBlock(kAliHLTDataTypeStreamerInfo);
456 const AliHLTUInt8_t* pBuffer=NULL;
457 AliHLTUInt32_t size=0;
458 if (pHLTOUT->GetDataBuffer(pBuffer, size)>=0) {
459 TObject* pObject=AliHLTMessage::Extract(pBuffer, size);
461 TObjArray* pArray=dynamic_cast<TObjArray*>(pObject);
463 AliHLTMisc::Instance().InitStreamerInfos(pArray);
465 AliError(Form("wrong class type of streamer info list: expected TObjArray, but object is of type %s", pObject->Class()->GetName()));
468 AliError(Form("failed to extract object from data block of type %s", AliHLTComponent::DataType2Text(kAliHLTDataTypeStreamerInfo).c_str()));
471 AliError(Form("failed to get data buffer for block of type %s", AliHLTComponent::DataType2Text(kAliHLTDataTypeStreamerInfo).c_str()));
475 if (pSystem->ProcessHLTOUT(pHLTOUT, esd)<0) {
476 AliError("error processing HLTOUT");
480 AliInfo("HLT ESD content:");
486 void AliHLTReconstructor::ProcessHLTOUT(const char* digitFile, AliESDEvent* pEsd) const
488 // debugging/helper function to examine simulated data
489 if (!digitFile) return;
491 // read the number of events
493 if (f.IsZombie()) return;
495 f.GetObject("rawhltout", pTree);
497 AliWarning(Form("can not find tree rawhltout in file %s", digitFile));
500 int nofEvents=pTree->GetEntries();
502 //delete pTree; OF COURSE NOT! its an object in the file
505 for (int event=0; event<nofEvents; event++) {
506 AliHLTOUTDigitReader* pHLTOUT=new AliHLTOUTDigitReader(event, fpEsdManager, digitFile);
508 AliInfo(Form("event %d", event));
509 ProcessHLTOUT(pHLTOUT, pEsd, true);
512 AliError("error creating HLTOUT handler");
517 void AliHLTReconstructor::ProcessHLTOUT(AliRawReader* pRawReader, AliESDEvent* pEsd) const
519 // debugging/helper function to examine simulated or real HLTOUT data
520 if (!pRawReader) return;
522 pRawReader->RewindEvents();
523 for (int event=0; pRawReader->NextEvent(); event++) {
524 AliHLTOUTRawReader* pHLTOUT=new AliHLTOUTRawReader(pRawReader, event, fpEsdManager);
526 AliInfo(Form("event %d", event));
527 // the two event fields contain: period - orbit - bunch crossing counter
531 // | 28 bit | 24 bit | 12|
533 AliHLTUInt64_t eventId=0;
534 const UInt_t* rawreaderEventId=pRawReader->GetEventId();
535 if (rawreaderEventId) {
536 eventId=rawreaderEventId[0];
538 eventId|=rawreaderEventId[1];
540 AliInfo(Form("Event Id from rawreader:\t 0x%016llx", eventId));
541 ProcessHLTOUT(pHLTOUT, pEsd, true);
544 AliError("error creating HLTOUT handler");
549 void AliHLTReconstructor::PrintHLTOUTContent(AliHLTOUT* pHLTOUT) const
551 // print the block specifications of the HLTOUT data blocks
552 if (!pHLTOUT) return;
555 AliInfo(Form("Event Id from hltout:\t 0x%016llx", pHLTOUT->EventId()));
556 for (iResult=pHLTOUT->SelectFirstDataBlock();
558 iResult=pHLTOUT->SelectNextDataBlock()) {
559 AliHLTComponentDataType dt=kAliHLTVoidDataType;
560 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
561 pHLTOUT->GetDataBlockDescription(dt, spec);
562 const AliHLTUInt8_t* pBuffer=NULL;
563 AliHLTUInt32_t size=0;
564 if (pHLTOUT->GetDataBuffer(pBuffer, size)>=0) {
565 pHLTOUT->ReleaseDataBuffer(pBuffer);
566 pBuffer=NULL; // just a dummy
568 AliInfo(Form(" %s 0x%x: size %d", AliHLTComponent::DataType2Text(dt).c_str(), spec, size));
572 int AliHLTReconstructor::BuildCTPTriggerClassString(TString& triggerclasses) const
574 // build the CTP trigger class string from the OCDB entry of the CTP trigger
577 triggerclasses.Clear();
578 AliCentralTrigger* pCTP = new AliCentralTrigger();
579 AliTriggerConfiguration *config=NULL;
580 TString configstr("");
581 if (pCTP->LoadConfiguration(configstr) &&
582 (config = pCTP->GetConfiguration())!=NULL) {
583 const TObjArray& classesArray = config->GetClasses();
584 int nclasses = classesArray.GetEntriesFast();
585 for( int iclass=0; iclass < nclasses; iclass++ ) {
586 AliTriggerClass* trclass = NULL;
587 if (classesArray.At(iclass) && (trclass=dynamic_cast<AliTriggerClass*>(classesArray.At(iclass)))!=NULL) {
589 int trindex = TMath::Nint(TMath::Log2(trclass->GetMask()));
590 entry.Form("%02d:%s:", trindex, trclass->GetName());
591 AliTriggerCluster* cluster=NULL;
592 TObject* clusterobj=config->GetClusters().FindObject(trclass->GetCluster());
593 if (clusterobj && (cluster=dynamic_cast<AliTriggerCluster*>(clusterobj))!=NULL) {
594 TString detectors=cluster->GetDetectorsInCluster();
595 TObjArray* pTokens=detectors.Tokenize(" ");
597 for (int dix=0; dix<pTokens->GetEntriesFast(); dix++) {
598 int id=AliDAQ::DetectorID(((TObjString*)pTokens->At(dix))->GetString());
600 TString detstr; detstr.Form("%s%02d", dix>0?"-":"", id);
603 AliError(Form("invalid detector name extracted from trigger cluster: %s (%s)", ((TObjString*)pTokens->At(dix))->GetString().Data(), detectors.Data()));
611 AliError(Form("can not find trigger cluster %s in config", trclass->GetCluster()?trclass->GetCluster()->GetName():"NULL"));
615 if (!triggerclasses.IsNull()) triggerclasses+=",";
616 triggerclasses+=entry;