//* provided "as is" without express or implied warranty. *
//**************************************************************************
-/** @file AliHLTReconstructor.cxx
- @author Matthias Richter
- @date
- @brief Binding class for HLT reconstruction in AliRoot. */
+// @file AliHLTReconstructor.cxx
+// @author Matthias Richter
+// @date
+// @brief Binding class for HLT reconstruction in AliRoot
+// Implements bot the interface to run HLT chains embedded into
+// AliReconstruction and the unpacking and treatment of HLTOUT
#include <TSystem.h>
#include <TObjString.h>
#include "TFile.h"
#include "TTree.h"
+#include "TObject.h"
+#include "TObjArray.h"
+#include "TClass.h"
+#include "TStreamerInfo.h"
#include "AliHLTReconstructor.h"
#include "AliLog.h"
#include "AliRawReader.h"
#include "AliHLTOUTRawReader.h"
#include "AliHLTOUTDigitReader.h"
#include "AliHLTEsdManager.h"
-
+#include "AliHLTPluginBase.h"
+#include "AliHLTMisc.h"
+#include "AliCDBManager.h"
+#include "AliCDBEntry.h"
+#include "AliHLTMessage.h"
+#include "AliCentralTrigger.h"
+#include "AliTriggerConfiguration.h"
+#include "AliTriggerClass.h"
+#include "AliTriggerCluster.h"
+#include "AliDAQ.h"
+
+class AliCDBEntry;
+
+/** ROOT macro for the implementation of ROOT specific class methods */
ClassImp(AliHLTReconstructor)
AliHLTReconstructor::AliHLTReconstructor()
- :
- AliReconstructor(),
- AliHLTPluginBase(),
- fFctProcessHLTOUT(NULL),
- fpEsdManager(NULL)
+ : AliReconstructor()
+ , fpEsdManager(NULL)
+ , fpPluginBase(new AliHLTPluginBase)
+ , fFlags(0)
{
//constructor
}
AliHLTReconstructor::AliHLTReconstructor(const char* options)
- :
- AliReconstructor(),
- AliHLTPluginBase(),
- fFctProcessHLTOUT(NULL),
- fpEsdManager(NULL)
+ : AliReconstructor()
+ , fpEsdManager(NULL)
+ , fpPluginBase(new AliHLTPluginBase)
+ , fFlags(0)
{
//constructor
if (options) Init(options);
{
//destructor
- AliHLTSystem* pSystem=GetInstance();
+ if (fpPluginBase) {
+ AliHLTSystem* pSystem=fpPluginBase->GetInstance();
if (pSystem) {
- AliDebug(0, Form("delete HLT system: status %#x", pSystem->GetStatusFlags()));
+ AliDebug(0, Form("terminate HLT system: status %#x", pSystem->GetStatusFlags()));
if (pSystem->CheckStatus(AliHLTSystem::kStarted)) {
// send specific 'event' to execute the stop sequence
pSystem->Reconstruct(0, NULL, NULL);
}
}
+ delete fpPluginBase;
+ }
+ fpPluginBase=NULL;
if (fpEsdManager) AliHLTEsdManager::Delete(fpEsdManager);
fpEsdManager=NULL;
void AliHLTReconstructor::Init()
{
// init the reconstructor
- AliHLTSystem* pSystem=GetInstance();
+ if (!fpPluginBase) {
+ AliError("internal memory error: can not get AliHLTSystem instance from plugin");
+ return;
+ }
+
+ AliHLTSystem* pSystem=fpPluginBase->GetInstance();
if (!pSystem) {
AliError("can not create AliHLTSystem object");
return;
return;
}
+ TString esdManagerOptions;
+
// the options scan has been moved to AliHLTSystem, the old code
// here is kept to be able to run an older version of the HLT code
// with newer AliRoot versions.
}
} else if (token.Contains("alilog=off")) {
pSystem->SwitchAliLog(0);
+ } else if (token.CompareTo("ignore-hltout")==0) {
+ fFlags|=kAliHLTReconstructorIgnoreHLTOUT;
+ } else if (token.CompareTo("ignore-ctp")==0) {
+ fFlags|=kAliHLTReconstructorIgnoreCTP;
+ } else if (token.Contains("esdmanager=")) {
+ token.ReplaceAll("esdmanager=", "");
+ token.ReplaceAll(","," ");
+ token.ReplaceAll("'","");
+ esdManagerOptions=token;
} else if (token.BeginsWith("lib") && token.EndsWith(".so")) {
libs+=token;
libs+=" ";
delete pTokens;
}
+ TString ecsParam;
+ TString ctpParam;
+ if ((fFlags&kAliHLTReconstructorIgnoreCTP)==0 &&
+ BuildCTPTriggerClassString(ctpParam)>=0) {
+ if (!ecsParam.IsNull()) ecsParam+=";";
+ ecsParam+="CTP_TRIGGER_CLASS=";
+ ecsParam+=ctpParam;
+ }
+
+ if (!ecsParam.IsNull()) {
+ option+=" ECS=";
+ option+=ecsParam;
+ }
+
if (!libs.IsNull() &&
(!pSystem->CheckStatus(AliHLTSystem::kLibrariesLoaded)) &&
(pSystem->LoadComponentLibraries(libs.Data())<0)) {
}
if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
- typedef int (*AliHLTSystemSetOptions)(AliHLTSystem* pInstance, const char* options);
- gSystem->Load("libHLTinterface.so");
- AliHLTSystemSetOptions pFunc=(AliHLTSystemSetOptions)(gSystem->DynFindSymbol("libHLTinterface.so", "AliHLTSystemSetOptions"));
- if (pFunc) {
- if ((pFunc)(pSystem, option.Data())<0) {
+ if (pSystem->ScanOptions(option.Data())<0) {
AliError("error setting options for HLT system");
- return;
- }
- } else if (option.Length()>0) {
- AliError(Form("version of HLT system does not support the options \'%s\'", option.Data()));
return;
}
if ((pSystem->Configure())<0) {
}
}
- gSystem->Load("libHLTinterface.so");
- fFctProcessHLTOUT=(void (*)())gSystem->DynFindSymbol("libHLTinterface.so", "AliHLTSystemProcessHLTOUT");
-
fpEsdManager=AliHLTEsdManager::New();
+ fpEsdManager->SetOption(esdManagerOptions.Data());
+
+ InitStreamerInfos();
+}
+
+const char* AliHLTReconstructor::fgkCalibStreamerInfoEntry="HLT/Calib/StreamerInfo";
+
+int AliHLTReconstructor::InitStreamerInfos()
+{
+ // init streamer infos for HLT reconstruction
+ // Root schema evolution is not enabled for AliHLTMessage and all streamed objects.
+ // Objects in the raw data payload rely on the availability of the correct stream info.
+ // The relevant streamer info for a specific run is stored in the OCDB.
+ // The method evaluates the following entries:
+ // - HLT/Calib/StreamerInfo
+ int iResult=0;
+
+ // to be activated later, this is supposed to go as patch into the v4-17-Release branch
+ // which doe snot have the AliHLTMisc implementation
+ //AliCDBEntry* pEntry=AliHLTMisc::Instance().LoadOCDBEntry(fgkCalibStreamerInfoEntry);
+ AliCDBEntry* pEntry=AliCDBManager::Instance()->Get(fgkCalibStreamerInfoEntry);
+ TObject* pObject=NULL;
+ //if (pEntry && (pObject=AliHLTMisc::Instance().ExtractObject(pEntry))!=NULL)
+ if (pEntry && (pObject=pEntry->GetObject())!=NULL)
+ {
+ TObjArray* pSchemas=dynamic_cast<TObjArray*>(pObject);
+ if (pSchemas) {
+ iResult=InitStreamerInfos(pSchemas);
+ } else {
+ AliError(Form("internal mismatch in OCDB entry %s: wrong class type", fgkCalibStreamerInfoEntry));
+ }
+ } else {
+ AliWarning(Form("missing HLT reco data (%s), skipping initialization of streamer info for TObjects in HLT raw data payload", fgkCalibStreamerInfoEntry));
+ }
+ return iResult;
+}
+
+int AliHLTReconstructor::InitStreamerInfos(TObjArray* pSchemas) const
+{
+ // init streamer infos for HLT reconstruction from an array of TStreamerInfo objects
+
+ for (int i=0; i<pSchemas->GetEntriesFast(); i++) {
+ if (pSchemas->At(i)) {
+ TStreamerInfo* pSchema=dynamic_cast<TStreamerInfo*>(pSchemas->At(i));
+ if (pSchema) {
+ int version=pSchema->GetClassVersion();
+ TClass* pClass=TClass::GetClass(pSchema->GetName());
+ if (pClass) {
+ if (pClass->GetClassVersion()==version) {
+ AliDebug(0,Form("skipping schema definition %d version %d to class %s as this is the native version", i, version, pSchema->GetName()));
+ continue;
+ }
+ TObjArray* pInfos=pClass->GetStreamerInfos();
+ if (pInfos /*&& version<pInfos->GetEntriesFast()*/) {
+ if (pInfos->At(version)==NULL) {
+ TStreamerInfo* pClone=(TStreamerInfo*)pSchema->Clone();
+ if (pClone) {
+ pClone->SetClass(pClass);
+ pClone->BuildOld();
+ pInfos->AddAtAndExpand(pClone, version);
+ AliDebug(0,Form("adding schema definition %d version %d to class %s", i, version, pSchema->GetName()));
+ } else {
+ AliError(Form("skipping schema definition %d (%s), unable to create clone object", i, pSchema->GetName()));
+ }
+ } else {
+ TStreamerInfo* pInfo=dynamic_cast<TStreamerInfo*>(pInfos->At(version));
+ if (pInfo && pInfo->GetClassVersion()==version) {
+ AliDebug(0,Form("schema definition %d version %d already available in class %s, skipping ...", i, version, pSchema->GetName()));
+ } else {
+ 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));
+ }
+ }
+ } else {
+ 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));
+ }
+ } else {
+ AliError(Form("skipping schema definition %d (%s), unable to find class", i, pSchema->GetName()));
+ }
+ } else {
+ AliError(Form("skipping schema definition %d, not of TStreamerInfo", i));
+ }
+ }
+ }
+
+ return 0;
}
void AliHLTReconstructor::Reconstruct(AliRawReader* rawReader, TTree* /*clustersTree*/) const
// For each event, HLT reconstruction chains can be executed and
// added to the existing HLTOUT data
// The HLTOUT data is finally processed in FillESD
+ if (!fpPluginBase) {
+ AliError("internal memory error: can not get AliHLTSystem instance from plugin");
+ return;
+ }
+
int iResult=0;
- AliHLTSystem* pSystem=GetInstance();
+ AliHLTSystem* pSystem=fpPluginBase->GetInstance();
if (pSystem) {
if (pSystem->CheckStatus(AliHLTSystem::kError)) {
return;
}
- AliHLTSystem* pSystem=GetInstance();
+ if (!fpPluginBase) {
+ AliError("internal memory error: can not get AliHLTSystem instance from plugin");
+ return;
+ }
+
+ AliHLTSystem* pSystem=fpPluginBase->GetInstance();
if (pSystem) {
if (pSystem->CheckStatus(AliHLTSystem::kError)) {
}
pSystem->FillESD(-1, NULL, esd);
- AliHLTOUTRawReader* pHLTOUT=new AliHLTOUTRawReader(rawReader, esd->GetEventNumberInFile(), fpEsdManager);
+ AliRawReader* input=NULL;
+ if ((fFlags&kAliHLTReconstructorIgnoreHLTOUT) == 0 ) {
+ input=rawReader;
+ }
+ AliHLTOUTRawReader* pHLTOUT=new AliHLTOUTRawReader(input, esd->GetEventNumberInFile(), fpEsdManager);
if (pHLTOUT) {
- ProcessHLTOUT(pHLTOUT, esd);
+ ProcessHLTOUT(pHLTOUT, esd, (pSystem->GetGlobalLoggingLevel()&kHLTLogDebug)!=0);
delete pHLTOUT;
} else {
AliError("error creating HLTOUT handler");
" sim.Run();\n"
" /*********************************************************/", option.Data()));
}
- AliHLTSystem* pSystem=GetInstance();
+ if (!fpPluginBase) {
+ AliError("internal memory error: can not get AliHLTSystem instance from plugin");
+ return;
+ }
+
+ AliHLTSystem* pSystem=fpPluginBase->GetInstance();
if (pSystem) {
if (pSystem->CheckStatus(AliHLTSystem::kError)) {
AliError("HLT system in error state");
AliHLTOUTDigitReader* pHLTOUT=new AliHLTOUTDigitReader(esd->GetEventNumberInFile(), fpEsdManager);
if (pHLTOUT) {
- ProcessHLTOUT(pHLTOUT, esd);
+ ProcessHLTOUT(pHLTOUT, esd, (pSystem->GetGlobalLoggingLevel()&kHLTLogDebug)!=0);
delete pHLTOUT;
} else {
AliError("error creating HLTOUT handler");
{
// treatment of simulated or real HLTOUT data
if (!pHLTOUT) return;
- AliHLTSystem* pSystem=GetInstance();
+ if (!fpPluginBase) {
+ AliError("internal memory error: can not get AliHLTSystem instance from plugin");
+ return;
+ }
+
+ AliHLTSystem* pSystem=fpPluginBase->GetInstance();
if (!pSystem) {
AliError("error getting HLT system instance");
return;
if (bVerbose)
PrintHLTOUTContent(pHLTOUT);
- if (fFctProcessHLTOUT) {
- typedef int (*AliHLTSystemProcessHLTOUT)(AliHLTSystem* pInstance, AliHLTOUT* pHLTOUT, AliESDEvent* esd);
- AliHLTSystemProcessHLTOUT pFunc=(AliHLTSystemProcessHLTOUT)fFctProcessHLTOUT;
- if ((pFunc)(pSystem, pHLTOUT, esd)<0) {
- AliError("error processing HLTOUT");
+ int blockindex=pHLTOUT->SelectFirstDataBlock(kAliHLTDataTypeStreamerInfo);
+ if (blockindex>=0) {
+ const AliHLTUInt8_t* pBuffer=NULL;
+ AliHLTUInt32_t size=0;
+ if (pHLTOUT->GetDataBuffer(pBuffer, size)>=0) {
+ TObject* pObject=AliHLTMessage::Extract(pBuffer, size);
+ if (pObject) {
+ TObjArray* pArray=dynamic_cast<TObjArray*>(pObject);
+ if (pArray) {
+ InitStreamerInfos(pArray);
+ } else {
+ AliError(Form("wrong class type of streamer info list: expected TObjArray, but object is of type %s", pObject->Class()->GetName()));
+ }
+ } else {
+ AliError(Form("failed to extract object from data block of type %s", AliHLTComponent::DataType2Text(kAliHLTDataTypeStreamerInfo).c_str()));
+ }
+ } else {
+ AliError(Form("failed to get data buffer for block of type %s", AliHLTComponent::DataType2Text(kAliHLTDataTypeStreamerInfo).c_str()));
}
}
+
+ if (pSystem->ProcessHLTOUT(pHLTOUT, esd)<0) {
+ AliError("error processing HLTOUT");
+ }
+
+ if (bVerbose) {
+ AliInfo("HLT ESD content:");
+ esd->Print();
+ }
pHLTOUT->Reset();
}
AliHLTOUTRawReader* pHLTOUT=new AliHLTOUTRawReader(pRawReader, event, fpEsdManager);
if (pHLTOUT) {
AliInfo(Form("event %d", event));
+ // the two event fields contain: period - orbit - bunch crossing counter
+ // id[0] id[1]
+ // |32 0|32 0|
+ //
+ // | 28 bit | 24 bit | 12|
+ // period orbit bcc
+ AliHLTUInt64_t eventId=0;
+ const UInt_t* rawreaderEventId=pRawReader->GetEventId();
+ if (rawreaderEventId) {
+ eventId=rawreaderEventId[0];
+ eventId=eventId<<32;
+ eventId|=rawreaderEventId[1];
+ }
+ AliInfo(Form("Event Id from rawreader:\t 0x%016llx", eventId));
ProcessHLTOUT(pHLTOUT, pEsd, true);
delete pHLTOUT;
} else {
if (!pHLTOUT) return;
int iResult=0;
+ AliInfo(Form("Event Id from hltout:\t 0x%016llx", pHLTOUT->EventId()));
for (iResult=pHLTOUT->SelectFirstDataBlock();
iResult>=0;
iResult=pHLTOUT->SelectNextDataBlock()) {
AliInfo(Form(" %s 0x%x: size %d", AliHLTComponent::DataType2Text(dt).c_str(), spec, size));
}
}
+
+int AliHLTReconstructor::BuildCTPTriggerClassString(TString& triggerclasses) const
+{
+ // build the CTP trigger class string from the OCDB entry of the CTP trigger
+ int iResult=0;
+
+ triggerclasses.Clear();
+ AliCentralTrigger* pCTP = new AliCentralTrigger();
+ AliTriggerConfiguration *config=NULL;
+ TString configstr("");
+ if (pCTP->LoadConfiguration(configstr) &&
+ (config = pCTP->GetConfiguration())!=NULL) {
+ const TObjArray& classesArray = config->GetClasses();
+ int nclasses = classesArray.GetEntriesFast();
+ for( int iclass=0; iclass < nclasses; iclass++ ) {
+ AliTriggerClass* trclass = NULL;
+ if (classesArray.At(iclass) && (trclass=dynamic_cast<AliTriggerClass*>(classesArray.At(iclass)))!=NULL) {
+ TString entry;
+ int trindex = TMath::Nint(TMath::Log2(trclass->GetMask()));
+ entry.Form("%02d:%s:", trindex, trclass->GetName());
+ AliTriggerCluster* cluster=NULL;
+ TObject* clusterobj=config->GetClusters().FindObject(trclass->GetCluster());
+ if (clusterobj && (cluster=dynamic_cast<AliTriggerCluster*>(clusterobj))!=NULL) {
+ TString detectors=cluster->GetDetectorsInCluster();
+ TObjArray* pTokens=detectors.Tokenize(" ");
+ if (pTokens) {
+ for (int dix=0; dix<pTokens->GetEntriesFast(); dix++) {
+ int id=AliDAQ::DetectorID(((TObjString*)pTokens->At(dix))->GetString());
+ if (id>=0) {
+ TString detstr; detstr.Form("%s%02d", dix>0?"-":"", id);
+ entry+=detstr;
+ } else {
+ AliError(Form("invalid detector name extracted from trigger cluster: %s (%s)", ((TObjString*)pTokens->At(dix))->GetString().Data(), detectors.Data()));
+ iResult=-EPROTO;
+ break;
+ }
+ }
+ delete pTokens;
+ }
+ } else {
+ AliError(Form("can not find trigger cluster %s in config", trclass->GetCluster()));
+ iResult=-EPROTO;
+ break;
+ }
+ if (!triggerclasses.IsNull()) triggerclasses+=",";
+ triggerclasses+=entry;
+ }
+ }
+ }
+
+ return iResult;
+}