- AliHLTOUTHandlerChain: base class and default handler for type kChain handlers
- AliHLTOUTTask: output of analysis chains creates an HLTOUT sub-collection
- AliHLTOUTPublisherComponent handles input from current HLTOUT object
--- /dev/null
+// $Id$
+
+//**************************************************************************
+//* This file is property of and copyright by the ALICE HLT Project *
+//* ALICE Experiment at CERN, All rights reserved. *
+//* *
+//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
+//* for The ALICE HLT Project. *
+//* *
+//* Permission to use, copy, modify and distribute this software and its *
+//* documentation strictly for non-commercial purposes is hereby granted *
+//* without fee, provided that the above copyright notice appears in all *
+//* copies and that both the copyright notice and this permission notice *
+//* appear in the supporting documentation. The authors make no claims *
+//* about the suitability of this software for any purpose. It is *
+//* provided "as is" without express or implied warranty. *
+//**************************************************************************
+
+/** @file AliHLTOUTHandlerChain.cxx
+ @author Matthias Richter
+ @date 24.06.2008
+ @brief HLTOUT handler of type kChain.
+*/
+
+#include "AliHLTOUTHandlerChain.h"
+#include "AliHLTOUT.h"
+#include "AliHLTSystem.h"
+#include "AliHLTOUTTask.h"
+#include "TString.h"
+#include "TObjString.h"
+#include "TObjArray.h"
+
+/** ROOT macro for the implementation of ROOT specific class methods */
+ClassImp(AliHLTOUTHandlerChain)
+
+AliHLTOUTHandlerChain::AliHLTOUTHandlerChain(const char* arguments)
+ :
+ fChains(),
+ fOptions(),
+ fpSystem(NULL),
+ fpTask(NULL)
+{
+ // see header file for class documentation
+ // or
+ // refer to README to build package
+ // or
+ // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
+ if (arguments) {
+ TString args=arguments;
+ TObjArray* pTokens=args.Tokenize(" ");
+ if (pTokens) {
+ int iEntries=pTokens->GetEntries();
+ for (int i=0; i<iEntries; i++) {
+ TString token=(((TObjString*)pTokens->At(i))->GetString());
+ if (token.Contains("chains=")) {
+ TString param=token.ReplaceAll("chains=", "");
+ fChains=param.ReplaceAll(",", " ");
+ } else {
+ if (!fOptions.IsNull()) fOptions+=" ";
+ fOptions+=token;
+ }
+ }
+ delete pTokens;
+ }
+ }
+}
+
+AliHLTOUTHandlerChain::~AliHLTOUTHandlerChain()
+{
+ // see header file for class documentation
+ if (fpSystem) {
+ delete fpSystem;
+ }
+}
+
+int AliHLTOUTHandlerChain::ProcessData(AliHLTOUT* pData)
+{
+ // see header file for class documentation
+ if (!pData) return -EINVAL;
+ int iResult=0;
+
+ if (CheckStatus(kHandlerError)) {
+ HLTWarning("kChain handler '%s' in error state, skipping processing of associated HLTOUT blocks", fChains.Data());
+ return -EPERM;
+ }
+
+ if (!fpSystem && (iResult=InitSystem())<0) {
+ return iResult;
+ }
+
+ if (fpSystem->CheckStatus(AliHLTSystem::kError)) {
+ HLTWarning("kChain handler '%s': system in error state, skipping processing of associated HLTOUT blocks", fChains.Data());
+ return -EACCES;
+ }
+
+ // run one event and do not stop the chain
+ {
+ AliHLTOUT::AliHLTOUTGlobalInstanceGuard g(pData);
+ if ((iResult=fpSystem->Run(1,0))>=0) {
+ // sub-collection is going to be reset from the
+ // parent HLTOUT collection
+ AliHLTOUT* pSubCollection=dynamic_cast<AliHLTOUT*>(fpTask);
+ pSubCollection->Init();
+ pData->AddSubCollection(pSubCollection);
+ } else {
+ fpTask->Reset();
+ }
+ }
+
+ return iResult;
+}
+
+int AliHLTOUTHandlerChain::CreateConfigurations(AliHLTConfigurationHandler* /*handler*/)
+{
+ //default implementation, nothing to do
+ return 0;
+}
+
+int AliHLTOUTHandlerChain::InitSystem()
+{
+ // see header file for class documentation
+ int iResult=0;
+ if (!fpSystem) {
+ // init AliHLTSystem
+ fpSystem = new AliHLTSystem(GetGlobalLoggingLevel());
+ if (fpSystem) {
+ if ((iResult=fpSystem->ScanOptions(fOptions.Data()))>=0) {
+ // load configurations if not specified by external macro
+ if (!fOptions.Contains("config="))
+ iResult=CreateConfigurations(fpSystem->fpConfigurationHandler);
+
+ if (iResult>=0) {
+ iResult=fpSystem->BuildTaskList(fChains.Data());
+ }
+
+ // add AliHLTOUTTask on top of the configuartions in order to
+ // collect the data
+ fpTask=new AliHLTOUTTask(fChains.Data());
+ }
+ } else {
+ iResult=-ENOMEM;
+ }
+ if (iResult>=0 && fpSystem && fpTask) {
+ if (fpTask->GetConf() && fpTask->GetConf()->SourcesResolved()>=0) {
+ iResult=fpSystem->InsertTask(fpTask);
+ } else {
+ HLTError("HLTOUT task (%s) sources not resolved", fpTask->GetName());
+ iResult=-ENOENT;
+ }
+ }
+ if (iResult<0 || !fpTask) {
+ SetStatusFlag(kHandlerError);
+ if (fpSystem) delete fpSystem; fpSystem=NULL;
+ if (fpTask) delete fpTask; fpTask=NULL;
+ }
+ }
+ return iResult;
+}
--- /dev/null
+//-*- Mode: C++ -*-
+// $Id$
+
+#ifndef ALIHLTOUTHANDLERCHAIN_H
+#define ALIHLTOUTHANDLERCHAIN_H
+//* This file is property of and copyright by the ALICE HLT Project *
+//* ALICE Experiment at CERN, All rights reserved. *
+//* See cxx source for full Copyright notice *
+
+/** @file AliHLTOUTHandlerChain.h
+ @author Matthias Richter
+ @date 24.06.2008
+ @brief HLTOUT handler of type kChain.
+*/
+
+#include "AliHLTOUTHandler.h"
+#include "TString.h"
+
+class AliHLTSystem;
+class AliHLTOUTTask;
+class AliHLTConfiguration;
+class AliHLTConfigurationHandler;
+
+/**
+ * @class AliHLTOUTHandlerChain
+ * The default HLTOUT handler for type kChain.
+ *
+ * The handler implements the kChain processing of HLTOUT data.
+ * The ids of the chains to be run during processing are provided
+ * as parameter to the constructor. The AliHLTModuleAgent
+ * can just create a new instance and specify the chains in order
+ * to define the HLTOUT handling of type kChain for a certain data
+ * block. The same instance can be returned for multiple data blocks.
+ * The handler will run once on all data blocks.
+ *
+ * The AliHLTOUTPublisherComponent must be used as data source in order
+ * to publish the data blocks from HLTOUT into the chain. The component
+ * publishes all data blocks selected for the handler. Additional
+ * filter rules can be applied.
+ *
+ * <h2>Chain configuration</h2>
+ * The tasks in the chain to be run can be defined either by
+ * the AliHLTModuleAgent in conjunction with all other configurations or
+ * by an implementation of CreateConfigurations().
+ *
+ * The handler is controlled by arguments passed to the constructor, the
+ * syntax is equal to the AliHLTSystem (see AliHLTSystem::ScanOptions).
+ *
+ * <h2>Usage example:</h2>
+ * An agent implementation for some sample histograms. Asumes a chain to
+ * be registered with name 'SAMPLE-my-histo-converter'
+ * <pre>
+ * AliHLTOUTHandler* AliHLTMyAgent::GetOutputHandler(AliHLTComponentDataType dt,
+ * AliHLTUInt32_t spec)
+ * {
+ * // afterburner for some histograms
+ * if (dt==kAliHLTDataTypeHistogram|kAliHLTDataOriginSample) {
+ * return new AliHLTOUTHandlerChain("chains=SAMPLE-my-histo-converter");
+ * }
+ *
+ * return NULL;
+ * }
+ * </pre>
+ *
+ * <h2>Data output</h2>
+ * The chain can produce output data as usual. All produced data blocks are
+ * added to the HLTOUT. This means a chain can e.g. produce ESD data blocks
+ * out of the HLT output by applying a converter component as an afterburner.
+ * The produced output of the chain is automatically subject to HLTOUT
+ * standard processing.
+ *
+ * HLTOUT processing sequence:
+ * - first handlers of type kChain
+ * - handlers of type kEsd
+ * - handlers of type kProprietary
+ *
+ * @ingroup alihlt_aliroot_reconstruction
+ */
+class AliHLTOUTHandlerChain : public AliHLTOUTHandler {
+ public:
+ /** constructor */
+ AliHLTOUTHandlerChain(const char* arguments);
+ /** standard destructor */
+ virtual ~AliHLTOUTHandlerChain();
+
+ /**
+ * Process a data block.
+ * The handler retrieves the data and it's properties and derives the
+ * equipment id from it. The default behavior returns the specification as
+ * equipment id and does not touch the data itself.
+ * @return equipment id the block should be used for.
+ */
+ virtual int ProcessData(AliHLTOUT* pData);
+ protected:
+ /**
+ * Create configurations.
+ * The configurations of the chain to be run can be defined either by
+ * the AliHLTModuleAgent in conjunction with all other configurations or
+ * by an implementation of the function.
+ */
+ virtual int CreateConfigurations(AliHLTConfigurationHandler* handler);
+
+ private:
+ /** standard constructor prohibited */
+ AliHLTOUTHandlerChain();
+ /** copy constructor prohibited */
+ AliHLTOUTHandlerChain(const AliHLTOUTHandlerChain&);
+ /** assignment operator prohibited */
+ AliHLTOUTHandlerChain& operator=(const AliHLTOUTHandlerChain&);
+
+ /**
+ * Create and init AliHLTSystem.
+ * Read the arguments and create the AliHLTOUTTask as data dump.
+ */
+ int InitSystem();
+
+ TString fChains; //! transient
+ TString fOptions; //! transient
+
+ AliHLTSystem* fpSystem; //!transient
+ AliHLTOUTTask* fpTask; //!transient
+
+ ClassDef(AliHLTOUTHandlerChain, 0)
+};
+#endif
--- /dev/null
+// $Id$
+
+//**************************************************************************
+//* This file is property of and copyright by the ALICE HLT Project *
+//* ALICE Experiment at CERN, All rights reserved. *
+//* *
+//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
+//* for The ALICE HLT Project. *
+//* *
+//* Permission to use, copy, modify and distribute this software and its *
+//* documentation strictly for non-commercial purposes is hereby granted *
+//* without fee, provided that the above copyright notice appears in all *
+//* copies and that both the copyright notice and this permission notice *
+//* appear in the supporting documentation. The authors make no claims *
+//* about the suitability of this software for any purpose. It is *
+//* provided "as is" without express or implied warranty. *
+//**************************************************************************
+
+/** @file AliHLTOUTTask.cxx
+ @author Matthias Richter
+ @date
+ @brief A special HLTOUT sibling working as a data sink in chains
+*/
+
+#include "AliHLTOUTTask.h"
+
+/** ROOT macro for the implementation of ROOT specific class methods */
+ClassImp(AliHLTOUTTask)
+
+AliHLTOUTTask::AliHLTOUTTask(const char* chains)
+ :
+ AliHLTOUT(),
+ AliHLTTask(),
+ fpDummyTask(NULL),
+ fpDummyConfiguration(NULL),
+ fBlockDescList()
+{
+ // see header file for class documentation
+ // or
+ // refer to README to build package
+ // or
+ // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
+ TString taskname=chains;
+ taskname.ReplaceAll(" ", "_");
+ taskname+="_hltouttask";
+
+ // This is just a trick to use the existing Task handling, especially the
+ // ProcessTask function.
+ // 1. The 'BlockFilter' just forwards the data blocks of all specified chains
+ // 2. A dummy task is added to the target list in order to set the data segments
+ // after forwarding. In case of an empty target list the data is just discarded.
+ // That's maybe not the most elegant solution but far less awkward as one would
+ // expect.
+ fpConfiguration=new AliHLTConfiguration(taskname.Data(), "BlockFilter", chains, NULL);
+ TString dummyname=chains;
+ dummyname.ReplaceAll(" ", "_");
+ dummyname+="_never_used_dummy_";
+ fpDummyConfiguration=new AliHLTConfiguration(dummyname.Data(), "BlockFilter", taskname.Data(), NULL);
+ if (fpDummyConfiguration) {
+ fpDummyTask=new AliHLTTask(fpDummyConfiguration);
+ SetTarget(fpDummyTask);
+ }
+}
+
+AliHLTOUTTask::~AliHLTOUTTask()
+{
+ // see header file for class documentation
+
+ // UnsetTarget called automatically
+ if (fpDummyTask) delete fpDummyTask;
+ fpDummyTask=NULL;
+
+ if (fpDummyConfiguration) delete fpDummyConfiguration;
+ fpDummyConfiguration=NULL;
+
+ if (fpConfiguration) delete fpConfiguration;
+ fpConfiguration=NULL;
+}
+
+int AliHLTOUTTask::CustomInit(AliHLTComponentHandler* pCH)
+{
+ // see header file for class documentation
+ if (!fpDummyTask) return -ENOENT;
+ return fpDummyTask->Init(NULL, pCH);
+}
+
+int AliHLTOUTTask::CustomCleanup()
+{
+ // see header file for class documentation
+ if (!fpDummyTask) return -ENOENT;
+ return fpDummyTask->Deinit();
+}
+
+int AliHLTOUTTask::GenerateIndex()
+{
+ // see header file for class documentation
+ int iResult=0;
+ if (fpDataBuffer) {
+ if (!fpDataBuffer->FindConsumer(fpDummyTask->GetComponent())) {
+ // in order to subscribe to the buffers the dummy consumer
+ // needs to be set. The dummy task is not in the AliHLTSystem chain
+ // and therefor not automatically set.
+ fpDataBuffer->SetConsumer(fpDummyTask->GetComponent());
+ }
+ fBlockDescList.clear();
+ if (fpDataBuffer->GetNofSegments()>0) {
+ if ((iResult=fpDataBuffer->Subscribe(fpDummyTask->GetComponent(), fBlockDescList))>=0) {
+ for (unsigned int i=0; i<fBlockDescList.size(); i++) {
+ AliHLTOUTBlockDescriptor desc(fBlockDescList[i].fDataType, fBlockDescList[i].fSpecification, i, this);
+ //HLTDebug("adding block %d: %s %#x", i, AliHLTComponent::DataType2Text(fBlockDescList[i].fDataType).c_str(), fBlockDescList[i].fSpecification);
+ iResult=AddBlockDescriptor(desc);
+ }
+ } else {
+ HLTError("failed to subscribe to data buffer");
+ }
+ }
+ } else {
+ HLTWarning("no data buffer available");
+ }
+ return iResult;
+}
+
+int AliHLTOUTTask::GetDataBuffer(AliHLTUInt32_t index, const AliHLTUInt8_t* &pBuffer,
+ AliHLTUInt32_t& size)
+{
+ // see header file for class documentation
+ int iResult=0;
+ if (index>=fBlockDescList.size()) return -ENOENT;
+ pBuffer=reinterpret_cast<AliHLTUInt8_t*>(fBlockDescList[index].fPtr);
+ size=fBlockDescList[index].fSize;
+ return iResult;
+}
+
+AliHLTOUT::AliHLTOUTByteOrder AliHLTOUTTask::CheckBlockByteOrder(AliHLTUInt32_t /*index*/)
+{
+ // see header file for class documentation
+ return kInvalidByteOrder;
+}
+
+int AliHLTOUTTask::CheckBlockAlignment(AliHLTUInt32_t /*index*/, AliHLTOUT::AliHLTOUTDataType /*type*/)
+{
+ // see header file for class documentation
+ int iResult=0;
+ return iResult;
+}
+
+int AliHLTOUTTask::ResetInput()
+{
+ // see header file for class documentation
+ int iResult=0;
+ for (unsigned int i=0; i<fBlockDescList.size(); i++) {
+ fpDataBuffer->Release(&(fBlockDescList[i]), fpDummyTask->GetComponent(), this);
+ }
+ fBlockDescList.clear();
+ return iResult;
+}
--- /dev/null
+//-*- Mode: C++ -*-
+// $Id$
+#ifndef ALIHLTOUTTASK_H
+#define ALIHLTOUTTASK_H
+//* This file is property of and copyright by the ALICE HLT Project *
+//* ALICE Experiment at CERN, All rights reserved. *
+//* See cxx source for full Copyright notice *
+
+/** @file AliHLTOUTTask.h
+ @author Matthias Richter
+ @date
+ @brief A special HLTOUT sibling working as a data sink in chains
+*/
+
+#include "AliHLTOUT.h"
+#include "AliHLTTask.h"
+
+/**
+ * @class AliHLTOUTTask
+ * A special HLTOUT sibling implementing AliHLTDataSink functionality in
+ * order to be run at the end of a reconstruction chain and generation of
+ * an HLTOUT sub-collection.
+ *
+ */
+class AliHLTOUTTask : public AliHLTOUT, public AliHLTTask {
+ public:
+ /** constructor */
+ AliHLTOUTTask(const char* chains);
+ /** standard destructor */
+ virtual ~AliHLTOUTTask();
+
+ protected:
+
+ private:
+ /** standard constructor prohibited */
+ AliHLTOUTTask();
+ /** copy constructor prohibited */
+ AliHLTOUTTask(const AliHLTOUTTask&);
+ /** assignment operator prohibited */
+ AliHLTOUTTask& operator=(const AliHLTOUTTask&);
+
+ /**
+ * Custom initialization for child tasks.
+ * Create and init the dummy task.
+ */
+ int CustomInit(AliHLTComponentHandler* pCH);
+
+ /**
+ * Custom clean up for child tasks.
+ */
+ int CustomCleanup();
+
+ /**
+ * Generate the index of the HLTOUT data.
+ * Must be implemented by the child classes.
+ */
+ int GenerateIndex();
+
+ /**
+ * Cleanup and reset the data input.
+ */
+ int ResetInput();
+
+ /**
+ * Get the data buffer
+ * @param index [in] index of the block
+ * @param pBuffer [out] buffer of the selected data block
+ * @param size [out] size of the selected data block
+ */
+ int GetDataBuffer(AliHLTUInt32_t index, const AliHLTUInt8_t* &pBuffer,
+ AliHLTUInt32_t& size);
+
+ /**
+ * Check byte order of data block
+ */
+ AliHLTOUTByteOrder CheckBlockByteOrder(AliHLTUInt32_t index);
+
+ /**
+ * Check alignment of data block
+ */
+ int CheckBlockAlignment(AliHLTUInt32_t index, AliHLTOUT::AliHLTOUTDataType type);
+
+ /** a dummy task to pretend existence of a consumer */
+ AliHLTTask* fpDummyTask; //!transient
+
+ /** the configuration for the dummy task */
+ AliHLTConfiguration* fpDummyConfiguration; //!transient
+
+ /** list of block descriptors of the output */
+ AliHLTComponentBlockDataList fBlockDescList;
+
+ ClassDef(AliHLTOUTTask, 0)
+};
+#endif
// TODO: we have to think about the optional environment parameter,
// currently just set to NULL.
iResult=pCH->CreateComponent(fpConfiguration->GetComponentID(), NULL, argc, argv, fpComponent);
- if (fpComponent || iResult<=0) {
+ if (fpComponent && iResult>=0) {
//HLTDebug("component %s (%p) created", fpComponent->GetComponentID(), fpComponent);
} else {
//HLTError("can not find component \"%s\" (%d)", fpConfiguration->GetComponentID(), iResult);
HLTError("configuration object instance needed for task initialization");
iResult=-EINVAL;
}
+ if (iResult>=0) {
+ iResult=CustomInit(pCH);
+ }
return iResult;
}
{
// see header file for function documentation
int iResult=0;
+ CustomCleanup();
AliHLTComponent* pComponent=GetComponent();
fpComponent=NULL;
if (pComponent) {
HLTMessage(" task \"%s\" not initialized", GetName());
}
}
+
+int AliHLTTask::CustomInit(AliHLTComponentHandler* /*pCH*/)
+{
+ // default implementation nothing to do
+ return 0;
+}
+
+int AliHLTTask::CustomCleanup()
+{
+ // default implementation nothing to do
+ return 0;
+}
/** prohibited assignment operator */
AliHLTTask& operator=(const AliHLTTask&);
+ /**
+ * Custom initialization for child tasks.
+ */
+ virtual int CustomInit(AliHLTComponentHandler* pCH);
+
+ /**
+ * Custom clean up for child tasks.
+ */
+ virtual int CustomCleanup();
+
+ protected:
/** the configuration descriptor (external pointer) */
AliHLTConfiguration* fpConfiguration; //! transient
/** the component described by this task (created and deleted internally) */
AliHLTComponent* fpComponent; //! transient
/** the data buffer for the component processing */
AliHLTDataBuffer* fpDataBuffer; //! transient
+
+ private:
/** the list of targets (tasks which depend upon the current one) */
TList fListTargets; // see above
/** the list of sources (tasks upon which the current one depends) */
unsigned int offset=0;
AliHLTOUT* pHLTOUT=NULL;
AliRawReader* pRawReader=GetRawReader();
+ if ((pHLTOUT=AliHLTOUT::GetGlobalInstance())!=NULL) {
+ // this is the HLTOUT instance set globally by the AliHLTOUT::AliHLTOUTGlobalInstanceGuard
+ // used for data input from the HLTOUT to the publishers of a kChain handler
+ } else
if (pRawReader) {
pRawReader->Reset();
pHLTOUT=AliHLTOUT::New(pRawReader);
+ if (pHLTOUT) iResult=pHLTOUT->Init();
// } else {
// this is just a hack and work-around for the missing HLT AliLoader.
// Because of that the AliRoot framework does not provide the digit tree.
iResult=-ENODEV;
}
if (iResult>=0 && pHLTOUT) {
- if ((iResult=pHLTOUT->Init())>=0) {
+ if (true) { // condition was deprecated but keep for the sake of diff
for (iResult=pHLTOUT->SelectFirstDataBlock();
iResult>=0;
iResult=pHLTOUT->SelectNextDataBlock()) {
}
// finally set the output size
- size=offset;
+ if (iResult>=0)
+ size=offset;
+ else
+ size=0;
return iResult;
}
AliHLTEsdManager.h \
AliHLTOUT.h \
AliHLTOUTHomerBuffer.h \
+ AliHLTOUTTask.h \
AliHLTOUTHandler.h \
AliHLTOUTHandlerEquId.h \
+ AliHLTOUTHandlerChain.h \
AliHLTMemoryFile.h \
AliHLTMessage.h \
AliHLTEventStatistics.h \