From bbad69c871b8ee9533bcd5f566a518093f215cd2 Mon Sep 17 00:00:00 2001 From: richterm Date: Tue, 6 Jul 2010 09:12:10 +0000 Subject: [PATCH] Adding base class of HLTOUT handler for TObjects to be merged into hltEsd. Class can be used directly for single, streamed objects in the HLTOUT. --- HLT/BASE/AliHLTOUTHandlerEsdBranch.cxx | 178 +++++++++++++++++++++++++ HLT/BASE/AliHLTOUTHandlerEsdBranch.h | 127 ++++++++++++++++++ HLT/BASE/HLTbaseLinkDef.h | 1 + HLT/libHLTbase.pkg | 1 + 4 files changed, 307 insertions(+) create mode 100644 HLT/BASE/AliHLTOUTHandlerEsdBranch.cxx create mode 100644 HLT/BASE/AliHLTOUTHandlerEsdBranch.h diff --git a/HLT/BASE/AliHLTOUTHandlerEsdBranch.cxx b/HLT/BASE/AliHLTOUTHandlerEsdBranch.cxx new file mode 100644 index 00000000000..b11e4363818 --- /dev/null +++ b/HLT/BASE/AliHLTOUTHandlerEsdBranch.cxx @@ -0,0 +1,178 @@ +// $Id$ + +//************************************************************************** +//* This file is property of and copyright by the ALICE HLT Project * +//* ALICE Experiment at CERN, All rights reserved. * +//* * +//* Primary Authors: Matthias Richter * +//* 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 AliHLTOUTHandlerEsdBranch.cxx +/// @author Matthias Richter +/// @date 01.07.2010 +/// @brief HLTOUT handler of type kEsd to merge objects into the hltEsd. + +#include "AliHLTOUTHandlerEsdBranch.h" +#include "AliHLTOUT.h" +#include "AliHLTMessage.h" +#include "AliHLTErrorGuard.h" +#include "AliESDEvent.h" +#include "TString.h" +#include "TObjString.h" +#include "TObjArray.h" +#include "TArrayC.h" +#include + +/** ROOT macro for the implementation of ROOT specific class methods */ +ClassImp(AliHLTOUTHandlerEsdBranch) + +AliHLTOUTHandlerEsdBranch::AliHLTOUTHandlerEsdBranch(const char* branchname) + : AliHLTOUTHandler() + , fBranch(branchname) + , fESD(NULL) + , fpData(NULL) + , fSize(0) +{ + // see header file for class documentation + // or + // refer to README to build package + // or + // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt +} + +AliHLTOUTHandlerEsdBranch::~AliHLTOUTHandlerEsdBranch() +{ + // see header file for class documentation +} + +int AliHLTOUTHandlerEsdBranch::ProcessData(AliHLTOUT* pData) +{ + // see header file for class documentation + if (!pData) return -EINVAL; + int iResult=0; + + if (CheckStatus(kHandlerError)) { + HLTWarning("kEsd handler for ESD branch '%s' in error state, skipping processing of associated HLTOUT blocks", fBranch.Data()); + return -EPERM; + } + + if (!fESD) { + // create the ESD container, but without std content + fESD = new AliESDEvent; + } + if (!fpData) fpData=new TArrayC; + if (fESD && fpData) { + fESD->Reset(); + iResult=ExtractAndAddObjects(pData); + } + + AliHLTMessage* pMsg=AliHLTMessage::Stream(fESD); + if (pMsg) { + if (!pMsg->CompBuffer()) { + fSize=pMsg->Length(); + fpData->Set(fSize, pMsg->Buffer()); + } else { + fSize=pMsg->CompLength(); + fpData->Set(fSize, pMsg->CompBuffer()); + } + delete pMsg; + pMsg=NULL; + } else { + HLTError("streaming of object failed"); + } + + return iResult; +} + +int AliHLTOUTHandlerEsdBranch::ExtractAndAddObjects(AliHLTOUT* pData) +{ + // Default method + // Extract streamed object from the HLTOUT and add to ESD + // The default method works only for single blocks in the HLTOUT, + // A specific child class is required if multiple blocks should be + // treated. + + int iResult=0; + iResult=pData->SelectFirstDataBlock(); + if (iResult<0) return iResult; + + TObject* pObject=pData->GetDataObject(); + if (pObject) { + TString bname=fBranch; + if (bname.IsNull()) { + bname=pObject->GetName(); + if (bname.CompareTo(pObject->ClassName())==0) { + ALIHLTERRORGUARD(5, "no branch name specified for unnamed object %s, not added to ESD", bname.Data()); + bname=""; + } + } + if (!bname.IsNull()) { + iResult=Add(pObject, bname.Data()); + } else { + iResult=-EBADF; + } + pData->ReleaseDataObject(pObject); + pObject=NULL; + } else { + AliHLTComponentDataType dt=kAliHLTVoidDataType; + AliHLTUInt32_t spec=kAliHLTVoidDataSpec; + pData->GetDataBlockDescription(dt, spec); + HLTError("Can not get TObject from HLTOUT buffer for block %s 0x%x", AliHLTComponent::DataType2Text(dt).c_str(), spec); + iResult=-ENODATA; + } + + if (pData->SelectNextDataBlock()>=0) { + ALIHLTERRORGUARD(5, "the default function can only handle one single data block/object"); + } + + return iResult; +} + +int AliHLTOUTHandlerEsdBranch::Add(TObject* object, const char* branchname) +{ + // add object to the specified branch in the internal ESD + if (fESD && object) { + TObject* pESDObject=fESD->FindListObject(branchname); + if (pESDObject) { + // copy the content to the already existing object + object->Copy(*pESDObject); + } else { + // add a new object + fESD->AddObject(object->Clone()); + } + } + return 0; +} + +int AliHLTOUTHandlerEsdBranch::GetProcessedData(const AliHLTUInt8_t* &pData) +{ + // see header file for class documentation + if (!fpData) { + pData=NULL; + return 0; + } + + pData=reinterpret_cast(fpData->GetArray()); + return fSize; +} + +int AliHLTOUTHandlerEsdBranch::ReleaseProcessedData(const AliHLTUInt8_t* pData, int size) +{ + // see header file for class documentation + int iResult=0; + if (!fpData || size != fSize || + const_cast(pData) != reinterpret_cast(fpData->GetArray())) { + HLTError("attempt to release to wrong data buffer %p size %d, expected %p size %d", pData, size, fpData?fpData->GetArray():NULL, fSize); + } + fSize=0; + return iResult; +} diff --git a/HLT/BASE/AliHLTOUTHandlerEsdBranch.h b/HLT/BASE/AliHLTOUTHandlerEsdBranch.h new file mode 100644 index 00000000000..f2f1d438345 --- /dev/null +++ b/HLT/BASE/AliHLTOUTHandlerEsdBranch.h @@ -0,0 +1,127 @@ +//-*- Mode: C++ -*- +// $Id$ + +#ifndef ALIHLTOUTHANDLERESDBRANCH_H +#define ALIHLTOUTHANDLERESDBRANCH_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 AliHLTOUTHandlerEsdBranch.h +/// @author Matthias Richter +/// @date 01.07.2010 +/// @brief HLTOUT handler of type kEsd to merge objects into the hltEsd. + +#include "AliHLTOUTHandler.h" +#include "TString.h" + +class TArrayC; +class AliESDEvent; + +/** + * @class AliHLTOUTHandlerEsdBranch + * An HLTOUT handler of type kEsd to add objects to hltEsd branches. + * + * The handler extracts objects from HLTOUT data blocks or converts + * data to objects to be added to hltEsd branches. The default implementation + * covers the first case right away, the class can be used directly for single + * objects streamed to the HLTOUT. + * + *

Object conversion

+ * The method ExtractAndAddObjects() has to loop over all input blocks and + * provide an appropriate conversion. If the data block simply contains a + * streamed object it just needs to be extracted and added to the ESD using + * the function Add(). Thhis case is covered by the default implementation. + * Child classes can overload ExtractAndAddObjects() if there is further + * conversion/formatting required. + * + *

Usage example:

+ * An agent implementation must announce to ability to process a certain + * data block by implementing AliHLTModuleAgent::GetHandlerDescription() + * and AliHLTModuleAgent::GetOutputHandler(). See AliHLTModuleAgent for + * more details. + *
+ *  int AliHLTMyAgent::GetHandlerDescription(AliHLTComponentDataType dt,
+ *  					     AliHLTUInt32_t spec,
+ *  					     AliHLTOUTHandlerDesc& desc) const
+ *  {
+ *    // add TObject data blocks of type {ROOTTOBJ:SMPL} to ESD
+ *    if (dt==(kAliHLTDataTypeTObject|kAliHLTDataOriginSample)) {
+ *        desc=AliHLTOUTHandlerDesc(kEsd, dt, GetModuleId());
+ *        return 1;
+ *    }
+ *  
+ *    return 0;
+ *  }
+ *
+ *  AliHLTOUTHandler* AliHLTMyAgent::GetOutputHandler(AliHLTComponentDataType dt,
+ *                                                    AliHLTUInt32_t spec)
+ *  {
+ *   // merge my objects into the hltEsd
+ *   if (dt==(kAliHLTDataTypeTObject|kAliHLTDataOriginSample)) {
+ *     static AliHLTOUTHandlerEsdBranch handler;
+ *     return &handler;
+ *   }
+ *
+ *   return NULL;
+ *  }
+ * 
+ * + *

Data output

+ * The handler produces a partial ESD containing the data objects. The framework + * merges all the different partial ESDs in the AliHLTEsdManager, respectively the + * specific implementation AliHLTEsdManagerImplementation. + * + * HLTOUT processing sequence: + * - first handlers of type kChain + * - handlers of type kEsd + * - handlers of type kProprietary + * + * @ingroup alihlt_aliroot_reconstruction + */ +class AliHLTOUTHandlerEsdBranch : public AliHLTOUTHandler { + public: + /** constructor */ + AliHLTOUTHandlerEsdBranch(const char* branchname=NULL); + /** standard destructor */ + virtual ~AliHLTOUTHandlerEsdBranch(); + + /** + * Process a data block. + * @return + */ + int ProcessData(AliHLTOUT* pData); + + int GetProcessedData(const AliHLTUInt8_t* &pData); + int ReleaseProcessedData(const AliHLTUInt8_t* pData, int size); + + protected: + /** + * Extract and add objects + * Loop over input blocks and extract/format the objects. Child class + * can implement specific conversion. The default implementation just + * extracts and adds objects. + */ + virtual int ExtractAndAddObjects(AliHLTOUT* pData); + + /** + * Add object to internal ESD. + * If there is an object with 'branchname' the object is copied, otherwise + * added. + */ + virtual int Add(TObject* object, const char* branchname); + + private: + /** copy constructor prohibited */ + AliHLTOUTHandlerEsdBranch(const AliHLTOUTHandlerEsdBranch&); + /** assignment operator prohibited */ + AliHLTOUTHandlerEsdBranch& operator=(const AliHLTOUTHandlerEsdBranch&); + + TString fBranch; //! transient + AliESDEvent* fESD; //! transient + TArrayC* fpData; //! transient + int fSize; //! transient + + ClassDef(AliHLTOUTHandlerEsdBranch, 1) +}; +#endif diff --git a/HLT/BASE/HLTbaseLinkDef.h b/HLT/BASE/HLTbaseLinkDef.h index 16bb8695852..9ece9676bea 100644 --- a/HLT/BASE/HLTbaseLinkDef.h +++ b/HLT/BASE/HLTbaseLinkDef.h @@ -45,6 +45,7 @@ #pragma link C++ class AliHLTOUTHandlerEquId+; #pragma link C++ class AliHLTOUTHandlerDetectorDDL+; #pragma link C++ class AliHLTOUTHandlerChain+; +#pragma link C++ class AliHLTOUTHandlerEsdBranch+; #pragma link C++ class AliHLTMemoryFile+; #pragma link C++ class AliHLTMessage+; #pragma link C++ class AliHLTEventStatistics+; diff --git a/HLT/libHLTbase.pkg b/HLT/libHLTbase.pkg index f55aae9d51c..54b60f35113 100644 --- a/HLT/libHLTbase.pkg +++ b/HLT/libHLTbase.pkg @@ -44,6 +44,7 @@ CLASS_HDRS:= AliHLTComponent.h \ AliHLTOUTHandlerEquId.h \ AliHLTOUTHandlerDetectorDDL.h \ AliHLTOUTHandlerChain.h \ + AliHLTOUTHandlerEsdBranch.h \ AliHLTMemoryFile.h \ AliHLTMessage.h \ AliHLTEventStatistics.h \ -- 2.43.0