--- /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 AliHLTRootSchemaEvolutionComponent.cxx
+ @author Matthias Richter
+ @date 2009-10-18
+ @brief Handler component for ROOT schema evolution of streamed objects
+*/
+
+#include "AliHLTRootSchemaEvolutionComponent.h"
+#include "AliHLTMessage.h"
+#include "TObjArray.h"
+#include "TStreamerInfo.h"
+#include "TList.h"
+
+/** ROOT macro for the implementation of ROOT specific class methods */
+ClassImp(AliHLTRootSchemaEvolutionComponent)
+
+AliHLTRootSchemaEvolutionComponent::AliHLTRootSchemaEvolutionComponent()
+ : AliHLTProcessor()
+ , fFlags(0)
+ , fpStreamerInfos(NULL)
+ , fFXSPrescaler(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
+
+}
+const char* AliHLTRootSchemaEvolutionComponent::fgkConfigurationObject=NULL;
+
+AliHLTRootSchemaEvolutionComponent::~AliHLTRootSchemaEvolutionComponent()
+{
+ // see header file for class documentation
+ if (fpStreamerInfos) {
+ fpStreamerInfos->Clear();
+ delete fpStreamerInfos;
+ }
+ fpStreamerInfos=NULL;
+}
+
+void AliHLTRootSchemaEvolutionComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
+{
+ // see header file for class documentation
+ list.push_back(kAliHLTAnyDataType);
+}
+
+AliHLTComponentDataType AliHLTRootSchemaEvolutionComponent::GetOutputDataType()
+{
+ // see header file for class documentation
+ return kAliHLTDataTypeStreamerInfo;
+}
+
+void AliHLTRootSchemaEvolutionComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
+{
+ // see header file for class documentation
+
+ // this is nothing more than an assumption, in fact it's very difficult to predict how
+ // much output the component produces
+ constBase=100*1024;
+ inputMultiplier=3;
+}
+
+int AliHLTRootSchemaEvolutionComponent::DoInit(int argc, const char** argv)
+{
+ // see header file for class documentation
+
+ int iResult=0;
+
+ // default configuration from CDB
+ if (iResult>=0 && fgkConfigurationObject!=NULL) iResult=ConfigureFromCDBTObjString(fgkConfigurationObject);
+
+ // custom configuration from command line arguments
+ if (iResult>=0 && argc>0) iResult=ConfigureFromArgumentString(argc, argv);
+
+ if (iResult>=0) {
+ fpStreamerInfos=new TObjArray();
+ if (!fpStreamerInfos) iResult=-ENOMEM;
+ }
+ return 0;
+}
+
+int AliHLTRootSchemaEvolutionComponent::DoDeinit()
+{
+ // see header file for class documentation
+ if (fpStreamerInfos) {
+ fpStreamerInfos->Clear();
+ delete fpStreamerInfos;
+ }
+ fpStreamerInfos=NULL;
+
+ return 0;
+}
+
+int AliHLTRootSchemaEvolutionComponent::DoEvent( const AliHLTComponentEventData& /*evtData*/,
+ AliHLTComponentTriggerData& /*trigData*/ )
+{
+ // see header file for class documentation
+ int iResult=0;
+ AliHLTUInt32_t eventType=gkAliEventTypeUnknown;
+ if (!IsDataEvent(&eventType) &&
+ eventType==gkAliEventTypeStartOfRun) {
+ return 0;
+ }
+
+ AliHLTMessage msg(kMESS_OBJECT);
+ msg.EnableSchemaEvolution();
+ for (const TObject* pObj=GetFirstInputObject();
+ pObj && iResult>=0;
+ pObj=GetNextInputObject()) {
+ msg.WriteObject(pObj);
+ iResult=UpdateStreamerInfos(msg.GetStreamerInfos(), fpStreamerInfos);
+ }
+
+ if (iResult>=0) {
+ if ((TestBits(kHLTOUTatFirstEvent) && GetEventCount()==0) ||
+ (TestBits(kHLTOUTatAllEvents)) ||
+ (TestBits(kHLTOUTatEOR) && eventType==gkAliEventTypeEndOfRun)) {
+ PushBack(fpStreamerInfos, kAliHLTDataTypeStreamerInfo);
+ }
+
+ if (TestBits(kFXS) && eventType==gkAliEventTypeEndOfRun) {
+ // push to FXS, needs to be implemented in the base class
+ }
+ }
+
+ return iResult;
+}
+
+int AliHLTRootSchemaEvolutionComponent::UpdateStreamerInfos(const TList* list, TObjArray* infos) const
+{
+ // see header file for class documentation
+ int iResult=0;
+ if (!list || !infos) {
+ return -EINVAL;
+ }
+
+ TObject* element=NULL;
+ TIter next((TList*)list);
+ while ((element = next())) {
+ TStreamerInfo* pInfo=dynamic_cast<TStreamerInfo*>(element);
+ if (!pInfo) continue;
+ TString name=pInfo->GetName();
+ int i=0;
+ for (; i<infos->GetEntriesFast(); i++) {
+ if (name.CompareTo(infos->At(i)->GetName())==0 &&
+ pInfo->GetClassVersion() == ((TStreamerInfo*)infos->At(i))->GetClassVersion()) {
+ // have it already
+ break;
+ }
+ }
+
+ // Add streamer info
+ infos->Add(pInfo);
+ }
+
+ return iResult;
+}
+
+int AliHLTRootSchemaEvolutionComponent::ScanConfigurationArgument(int argc, const char** argv)
+{
+ // see header file for class documentation
+ int iResult=0;
+ if (argc<=0) return 0;
+ int i=0;
+ TString argument=argv[i];
+
+ // -hltout=[all,first,eor,off]
+ if (argument.Contains("-hltout")) {
+ argument.ReplaceAll("-hltout", "");
+ argument.ReplaceAll("=", "");
+ if (argument.IsNull() || argument.CompareTo("all")) {
+ SetBits(kHLTOUTatAllEvents);
+ } else if (argument.CompareTo("first")) {
+ SetBits(kHLTOUTatFirstEvent);
+ } else if (argument.CompareTo("eor")) {
+ SetBits(kHLTOUTatEOR);
+ } else if (argument.CompareTo("off")) {
+ ClearBits(kHLTOUTatAllEvents | kHLTOUTatFirstEvent | kHLTOUTatEOR);
+ } else {
+ HLTError("invalid parameter for argument -hltout= : %s", argument.Data());
+ return -EINVAL;
+ }
+ return 1;
+ }
+
+ // -fxs=[n,off]
+ if (argument.Contains("-fxs")) {
+ argument.ReplaceAll("-fxs", "");
+ argument.ReplaceAll("=", "");
+ if (argument.IsNull()) {
+ SetBits(kFXS);
+ } else if (argument.CompareTo("off")) {
+ ClearBits(kFXS);
+ } else if (argument.IsDigit()) {
+ fFXSPrescaler=argument.Atoi();
+ } else {
+ HLTError("invalid parameter for argument -fxs= : %s", argument.Data());
+ return -EINVAL;
+ }
+ return 1;
+ }
+
+ return iResult;
+}
--- /dev/null
+// -*- Mode: C++ -*-
+// $Id$
+
+#ifndef ALIHLTROOTSCHEMAEVOLUTIONCOMPONENT_H
+#define ALIHLTROOTSCHEMAEVOLUTIONCOMPONENT_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 AliHLTRootSchemaEvolutionComponent.h
+ @author Matthias Richter
+ @date 2009-10-18
+ @brief Handler component for ROOT schema evolution of streamed objects
+*/
+
+#include "AliHLTProcessor.h"
+
+class TObjArray;
+
+/**
+ * @class AliHLTRootSchemaEvolutionComponent
+ *
+ * <h2>General properties:</h2>
+ *
+ * Component ID: \b ROOTFileWriter <br>
+ * Library: \b libAliHLTUtil.so <br>
+ * Input Data Types: ::kAliHLTAnyDataType <br>
+ * Output Data Types: none <br>
+ *
+ * <h2>Mandatory arguments:</h2>
+ * <!-- NOTE: ignore the \li. <i> and </i>: it's just doxygen formatting -->
+ *
+ * <h2>Optional arguments:</h2>
+ * <!-- NOTE: ignore the \li. <i> and </i>: it's just doxygen formatting -->
+ * \li -fxs<=off> <br>
+ * push streamer info to FXS, fetched by Shuttle and store in the entry
+ * HLT/Calib/StreamerInfo
+ * default off
+ * \li -hltout<=[all,first,eor,off]> <br>
+ * push streamer info to output, the streamer info is stored in the
+ * events in all, the first, and/or the EOR.
+ *
+ * <h2>Configuration:</h2>
+ * <!-- NOTE: ignore the \li. <i> and </i>: it's just doxygen formatting -->
+ * Configuration by component arguments.
+ *
+ * <h2>Default CDB entries:</h2>
+ * The component loads no CDB entries.
+ *
+ * <h2>Performance:</h2>
+ * The component does not process any event data.
+ *
+ * <h2>Memory consumption:</h2>
+ * The component does not process any event data.
+ *
+ * <h2>Output size:</h2>
+ * Depending on the mode.
+ *
+ * @ingroup alihlt_util_components
+ */
+class AliHLTRootSchemaEvolutionComponent : public AliHLTProcessor
+{
+ public:
+ /// standard constructor
+ AliHLTRootSchemaEvolutionComponent();
+ /// destructor
+ virtual ~AliHLTRootSchemaEvolutionComponent();
+
+ /// inherited from AliHLTComponent: return id of the component.
+ virtual const char* GetComponentID() {return "ROOTSchemaEvolutionComponent";};
+ /// inherited from AliHLTComponent: input data types
+ virtual void GetInputDataTypes(AliHLTComponentDataTypeList&);
+ /// inherited from AliHLTComponent: output data types
+ virtual AliHLTComponentDataType GetOutputDataType();
+ /// inherited from AliHLTComponent: output data size
+ virtual void GetOutputDataSize(unsigned long&, double&);
+
+ /// inherited from AliHLTComponent: spawn function, create an instance.
+ virtual AliHLTComponent* Spawn() {return new AliHLTRootSchemaEvolutionComponent;}
+
+ enum {
+ /// push streamer info to the HLTOUT for the first event
+ kHLTOUTatFirstEvent = 0x1,
+ /// push streamer info to the HLTOUT for all events
+ kHLTOUTatAllEvents = 0x2,
+ /// push streamer info to the HLTOUT at EOR, this has no relevance
+ /// for reconstruction as it is too late and just in one raw file,
+ /// but it allows archival at the end of the run
+ kHLTOUTatEOR = 0x4,
+ /// push streamer info to FXS
+ kFXS = 0x100,
+ };
+
+ /// Update the array of known streamer infos from a list of infos
+ /// Checks whether the provided infos are already there in the present version
+ /// and adds if it is a new info.
+ int UpdateStreamerInfos(const TList* list, TObjArray* infos) const;
+
+ protected:
+ /// inherited from AliHLTComponent: custom initialization
+ int DoInit( int argc, const char** argv );
+ /// inherited from AliHLTComponent: cleanup
+ int DoDeinit();
+
+ /// inherited from AliHLTProcessor processing
+ virtual int DoEvent( const AliHLTComponentEventData& evtData,
+ AliHLTComponentTriggerData& trigData );
+
+ using AliHLTProcessor::DoEvent;
+
+ /**
+ * Inherited from AliHLTComponent
+ * Scan one argument and adjacent parameters.
+ * @return number of scanned parameters, neg. error code if failed
+ */
+ virtual int ScanConfigurationArgument(int argc, const char** argv);
+
+ void SetBits(AliHLTUInt32_t b) {fFlags|=b;}
+ void ClearBits(AliHLTUInt32_t b) {fFlags&=~b;}
+ bool TestBits(AliHLTUInt32_t b) {return (fFlags&b) != 0;}
+
+private:
+ /** copy constructor prohibited */
+ AliHLTRootSchemaEvolutionComponent(const AliHLTRootSchemaEvolutionComponent&);
+ /** assignment operator prohibited */
+ AliHLTRootSchemaEvolutionComponent& operator=(const AliHLTRootSchemaEvolutionComponent&);
+
+ AliHLTUInt32_t fFlags; //! property flags
+
+ TObjArray* fpStreamerInfos; //! array of streamer infos
+
+ AliHLTUInt32_t fFXSPrescaler; //! prescalar for the publishing to FXS
+
+ static const char* fgkConfigurationObject; //! configuration object
+
+ ClassDef(AliHLTRootSchemaEvolutionComponent, 1) // ROOT schema evolution component
+};
+#endif