diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000000000000000000000000000000000..5fba28a15726e0a75a8848c004d90358f91fd6fd --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "faser-common"] + path = faser-common + url = https://:@gitlab.cern.ch:8443/faser/faser-common.git diff --git a/Event/FaserByteStreamCnvSvc/CMakeLists.txt b/Event/FaserByteStreamCnvSvc/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..80fae1ae449f093bc0e50a7d5ea886cfd415d4c7 --- /dev/null +++ b/Event/FaserByteStreamCnvSvc/CMakeLists.txt @@ -0,0 +1,109 @@ +################################################################################ +# Package: FaserByteStreamCnvSvc +################################################################################ + +# Declare the package name: +atlas_subdir( FaserByteStreamCnvSvc ) + +# Declare the package's dependencies: +atlas_depends_on_subdirs( + PUBLIC + Control/AthenaBaseComps + Event/ByteStreamCnvSvcBase + #Event/ByteStreamData + GaudiKernel + PRIVATE + Control/AthenaKernel + Control/SGTools + Control/StoreGate + Database/APR/CollectionBase + Database/APR/FileCatalog + Database/AthenaPOOL/AthenaPoolUtilities + Database/PersistentDataModel + Event/FaserEventStorage + Event/EventInfo + Event/xAOD/xAODEventInfo + Event/xAOD/xAODTrigger + EventFormats + Logging) + +# External dependencies: +find_package( Boost COMPONENTS system ) +find_package( CORAL COMPONENTS CoralBase ) +#find_package( tdaq-common COMPONENTS eformat_old eformat_write RawFileName +# DataReader DataWriter ) + +# Libraries in the package: +atlas_add_library( FaserByteStreamCnvSvcLib + FaserByteStreamCnvSvc/*.h src/*.h src/*.cxx + PUBLIC_HEADERS FaserByteStreamCnvSvc + PRIVATE_INCLUDE_DIRS ${Boost_INCLUDE_DIRS} + LINK_LIBRARIES AthenaBaseComps ByteStreamData GaudiKernel + ByteStreamCnvSvcLib ByteStreamCnvSvcBaseLib StoreGateLib rt + PRIVATE_LINK_LIBRARIES ${Boost_LIBRARIES} + AthenaKernel SGTools CollectionBase FileCatalog + AthenaPoolUtilities PersistentDataModel FaserEventStorageLib EventInfo + xAODEventInfo xAODTrigger) + +atlas_add_component( FaserByteStreamCnvSvc + src/components/*.cxx + LINK_LIBRARIES FaserByteStreamCnvSvcLib ) + +# Executables in the package: +# atlas_add_executable( AtlFindBSEvent test/AtlFindBSEvent.cxx +# INCLUDE_DIRS ${TDAQ-COMMON_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} +# LINK_LIBRARIES ${TDAQ-COMMON_LIBRARIES} ${Boost_LIBRARIES} ) + +# atlas_add_executable( AtlCopyBSEvent test/AtlCopyBSEvent.cxx +# INCLUDE_DIRS ${CORAL_INCLUDE_DIRS} ${TDAQ-COMMON_INCLUDE_DIRS} +# ${Boost_INCLUDE_DIRS} +# LINK_LIBRARIES ${CORAL_LIBRARIES} ${TDAQ-COMMON_LIBRARIES} ${Boost_LIBRARIES} +# CollectionBase FileCatalog PersistentDataModel ) + +# atlas_add_executable( AtlListBSEvents test/AtlListBSEvents.cxx +# INCLUDE_DIRS ${TDAQ-COMMON_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} +# LINK_LIBRARIES ${TDAQ-COMMON_LIBRARIES} ${Boost_LIBRARIES} ) + + +# Test(s) in the package: +# atlas_add_test( BSEventSelector +# SCRIPT "athena.py FaserByteStreamCnvSvc/BSEventSelector_test_jobOptions.py" +# LOG_SELECT_PATTERN "ByteStream.*Svc" ) + +# atlas_add_test( AtlCopyBSEvent1_test +# PRE_EXEC_SCRIPT "rm -f test.data" +# SCRIPT "AtlCopyBSEvent -e 186882810,187403142,187404922,187419528 -o test.data /cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/TrigP1Test/data17_13TeV.00327265.physics_EnhancedBias.merge.RAW._lb0100._SFO-1._0001.1" +# PROPERTIES DEPENDS FaserByteStreamCnvSvc_BSEventSelector_ctest ) + +# atlas_add_test( AtlFindBSEvent2_test +# SCRIPT "AtlFindBSEvent -e 187403142 test.data" +# PROPERTIES DEPENDS FaserByteStreamCnvSvc_AtlCopyBSEvent1_test_ctest ) + +# atlas_add_test( AtlCopyBSEvent3_test +# PRE_EXEC_SCRIPT "rm -f test_defl.data" +# SCRIPT "AtlCopyBSEvent -d -e 186882810,187403142,187419528 -o test_defl.data test.data" +# PROPERTIES DEPENDS FaserByteStreamCnvSvc_AtlCopyBSEvent1_test_ctest ) + +# atlas_add_test( AtlFindBSEvent4_test +# SCRIPT "AtlFindBSEvent -e 187403142 test_defl.data" +# LOG_IGNORE_PATTERN "+Timestamp" +# PROPERTIES DEPENDS FaserByteStreamCnvSvc_AtlCopyBSEvent3_test_ctest ) + +# atlas_add_test( AtlCopyBSEvent5_test +# PRE_EXEC_SCRIPT "rm -f test_infl.data" +# SCRIPT "AtlCopyBSEvent -e 186882810,187403142,187419528 -o test_infl.data test_defl.data" +# PROPERTIES DEPENDS FaserByteStreamCnvSvc_AtlCopyBSEvent3_test_ctest ) + +# atlas_add_test( AtlCopyBSEvent6_test +# PRE_EXEC_SCRIPT "rm -f empty*.data && python ${CMAKE_CURRENT_SOURCE_DIR}/test/create_empty_bsfile.py" +# SCRIPT "AtlCopyBSEvent -e all -o empty.data empty._0001.data" +# PROPERTIES DEPENDS FaserByteStreamCnvSvc_AtlCopyBSEvent5_test_ctest ) + +# atlas_add_test( FaserByteStreamConfigTest +# SCRIPT python -m FaserByteStreamCnvSvc.FaserByteStreamConfig +# POST_EXEC_SCRIPT nopost.sh ) + +# Install files from the package: +atlas_install_python_modules( python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} ) +atlas_install_joboptions( share/*.py ) +# atlas_install_scripts( share/catalogBytestreamFiles.sh ) diff --git a/Event/FaserByteStreamCnvSvc/FaserByteStreamCnvSvc/ByteStreamExceptions.h b/Event/FaserByteStreamCnvSvc/FaserByteStreamCnvSvc/ByteStreamExceptions.h new file mode 100644 index 0000000000000000000000000000000000000000..2a946c7846cd180fc8072fdbfc8642d0887f7ad4 --- /dev/null +++ b/Event/FaserByteStreamCnvSvc/FaserByteStreamCnvSvc/ByteStreamExceptions.h @@ -0,0 +1,40 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef BYTESTREAMCNVSVC_BYTESTREAMEXCEPTIONS_H +#define BYTESTREAMCNVSVC_BYTESTREAMEXCEPTIONS_H + +/** @file ByteExceptions.h + * $Id: ByteStreamInputSvc.h,v 1.51 2009-03-03 16:03:22 gemmeren Exp $ + **/ + +// EXCEPTIONS +namespace ByteStreamExceptions +{ + class fileAccessError + { + virtual const char* what() const throw() { + return "Problem accessing file"; + } + }; + class readError + { + virtual const char* what() const throw() { + return "Problem during DataReader getData"; + } + }; + class badFragment + { + virtual const char* what() const throw() { + return "Unable to build RawEvent, fragment does not match known formats."; + } + }; + class badFragmentData + { + virtual const char* what() const throw() { + return "RawEvent does not pass validation"; + } + }; +} +#endif diff --git a/Event/FaserByteStreamCnvSvc/FaserByteStreamCnvSvc/ByteStreamInputSvc.h b/Event/FaserByteStreamCnvSvc/FaserByteStreamCnvSvc/ByteStreamInputSvc.h new file mode 100644 index 0000000000000000000000000000000000000000..2d92e6523abf8bb76441fe830d0e72a0fab10833 --- /dev/null +++ b/Event/FaserByteStreamCnvSvc/FaserByteStreamCnvSvc/ByteStreamInputSvc.h @@ -0,0 +1,69 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef BYTESTREAMCNVSVC_BYTESTREAMINPUTSVC_H +#define BYTESTREAMCNVSVC_BYTESTREAMINPUTSVC_H + +/** @file ByteStreamInputSvc.h + * @brief This file contains the class definition for the ByteStreamInputSvc class. + * @author Peter van Gemmeren <gemmeren@anl.gov> + * $Id: ByteStreamInputSvc.h,v 1.51 2009-03-03 16:03:22 gemmeren Exp $ + **/ + +#include <exception> +#include "AthenaBaseComps/AthService.h" +#include "EventFormats/DAQFormats.hpp" + +//#include "ByteStreamData/RawEvent.h" +//#include "ByteStreamCnvSvc/ByteStreamExceptions.h" + + +/** @class ByteStreamInputSvc + * @brief This class provides the base class to services to read bytestream data. + * The concrete class can provide Raw event from a file, transient store, or through network. + **/ +class ByteStreamInputSvc : public ::AthService { + public: + /// constructor + ByteStreamInputSvc(const std::string& name, ISvcLocator* svcloc); + /// destructor + virtual ~ByteStreamInputSvc(void); + + /// Retrieve interface ID + static const InterfaceID& interfaceID(); + + /// virtual method for advance to the next event + virtual const DAQFormats::EventFull* nextEvent() = 0; + virtual const DAQFormats::EventFull* previousEvent() = 0; + virtual void setEvent(void* /*data*/, unsigned int /*status*/) {} + /// virtual method for accessing the current event + virtual const DAQFormats::EventFull* currentEvent() const = 0; + /// virtual method for accessing the current event status + virtual unsigned int currentEventStatus() const; + virtual std::pair<long,std::string> getBlockIterator(const std::string /* file */); + virtual void closeBlockIterator(bool); + virtual bool ready() const; + virtual StatusCode generateDataHeader(); + virtual long positionInBlock(); + virtual void validateEvent(); +}; + +inline const InterfaceID& ByteStreamInputSvc::interfaceID() { + /// Declaration of the interface ID ( interface id, major version, minor version) + static const InterfaceID IID_ByteStreamInputSvc("ByteStreamInputSvc", 1, 0); + return(IID_ByteStreamInputSvc); +} + +inline unsigned int ByteStreamInputSvc::currentEventStatus() const { + return(0); +} + +// Virtual methods needed for file input +inline std::pair<long,std::string> ByteStreamInputSvc::getBlockIterator(const std::string /* file */) {return std::make_pair(-1,"GUID");} +inline void ByteStreamInputSvc::closeBlockIterator(bool) {} +inline bool ByteStreamInputSvc::ready() const {return false;} +inline StatusCode ByteStreamInputSvc::generateDataHeader() {return StatusCode::SUCCESS;} +inline long ByteStreamInputSvc::positionInBlock() {return -1;} +inline void ByteStreamInputSvc::validateEvent() {} +#endif diff --git a/Event/FaserByteStreamCnvSvc/FaserByteStreamCnvSvc/FaserByteStreamCnvSvc.h b/Event/FaserByteStreamCnvSvc/FaserByteStreamCnvSvc/FaserByteStreamCnvSvc.h new file mode 100644 index 0000000000000000000000000000000000000000..1258f3869bb4f41f1a061a6e468d4709801bb6e6 --- /dev/null +++ b/Event/FaserByteStreamCnvSvc/FaserByteStreamCnvSvc/FaserByteStreamCnvSvc.h @@ -0,0 +1,102 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef FASERBYTESTREAMCNVSVC_FASERBYTESTREAMCNVSVC_H +#define FASERBYTESTREAMCNVSVC_FASERBYTESTREAMCNVSVC_H + +#include "ByteStreamCnvSvcBase/ByteStreamCnvSvcBase.h" +#include "StoreGate/StoreGateSvc.h" +#include "GaudiKernel/ServiceHandle.h" + +#include <map> + +class ByteStreamOutputSvc; +class FullEventAssemblerBase; + +/** @class FaserByteStreamCnvSvc + @brief Gaudi COnversion Service class for ByteStream Persistency + + This class is responsible for converting data object to and from BS format + It inherits from ByteStreamCnvSvcBase, which is used by HLT in online. + + When reading the ByteStream data, the ByteStream converters are called, which in turn call + IRODDataProviderSvc to retrieve the raw data. + + When writing the object data to ByteStream, an FullEventFragment is assembled + from lower level fragments using FullEventAssembler, and writen out to BS in commitOutput + method through ByteStreamOutputSvc. +*/ + +class FaserByteStreamCnvSvc : public ByteStreamCnvSvcBase/*, virtual public IService*/ { + +public: + /// Standard Constructor + FaserByteStreamCnvSvc(const std::string& name, ISvcLocator* svc); + + /// Standard Destructor + virtual ~FaserByteStreamCnvSvc(); + + /// Gaudi Service Interface method implementations: + virtual StatusCode initialize(); + virtual StatusCode finalize(); + + /// Implements ConversionSvc's connectOutput + virtual StatusCode connectOutput(const std::string& t, const std::string& mode); + virtual StatusCode connectOutput(const std::string& t); + + /// Implements ConversionSvc's commitOutput + virtual StatusCode commitOutput(const std::string& outputConnection, bool b); + + /// @brief Access to FullEventAssembler + template <class T> StatusCode getFullEventAssembler(T*&t, std::string nm); + +private: + /// name of the service + std::string m_ioSvcName; + + /// list of service names + Gaudi::Property<std::vector<std::string>> m_ioSvcNameList; + + /// Services for writing output + std::map<std::string, ByteStreamOutputSvc*> m_ioSvcMap; + + /// flags for Simulation EventType + Gaudi::Property<bool> m_isSimulation; + /// flags for TestBeam EventType + Gaudi::Property<bool> m_isTestbeam; + /// flags for Calibration EventType + Gaudi::Property<bool> m_isCalibration; + /// flags for getting Detector Mask from COOL + Gaudi::Property<bool> m_getDetectorMask; + + /// Event store. + ServiceHandle<StoreGateSvc> m_evtStore; + + /// user type + std::string m_userType; + + /// @brief common FEA, indexed by string key + std::map<std::string, FullEventAssemblerBase*> m_feaMap; +}; + +// Implementation of template method: +template <class T> StatusCode FaserByteStreamCnvSvc::getFullEventAssembler(T*& t, std::string nm) { + std::map<std::string, FullEventAssemblerBase*>::const_iterator it = m_feaMap.find(nm); + if (it != m_feaMap.end()) { + T* p = dynamic_cast<T*>((*it).second); + if (p == 0) { + ATH_MSG_WARNING(" Key = " << nm << " exists, but of different type"); + return(StatusCode::FAILURE); + } + t = p; + return(StatusCode::SUCCESS); + } + + // reach here if key does not exist + t = new T(); + m_feaMap[nm] = t; + return(StatusCode::SUCCESS); +} + +#endif diff --git a/Event/FaserByteStreamCnvSvc/python/ReadByteStream.py b/Event/FaserByteStreamCnvSvc/python/ReadByteStream.py new file mode 100644 index 0000000000000000000000000000000000000000..027eb59736f07a151134cf6ae3eda8a8f979733a --- /dev/null +++ b/Event/FaserByteStreamCnvSvc/python/ReadByteStream.py @@ -0,0 +1,69 @@ +# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration + +############################################################### +# +# module for reading EventStorage BS input file. +#============================================================== + +from AthenaCommon import CfgMgr +from AthenaCommon.AppMgr import ServiceMgr as svcMgr +from AthenaCommon.AppMgr import theApp + +# Load ByteStreamEventStorageInputSvc +if not hasattr (svcMgr, 'ByteStreamInputSvc'): + svcMgr += CfgMgr.FaserByteStreamInputSvc ("ByteStreamInputSvc") + +# Load ROBDataProviderSvc +if not hasattr (svcMgr, 'ROBDataProviderSvc'): + svcMgr += CfgMgr.ROBDataProviderSvc ("ROBDataProviderSvc") + +# Load EventSelectorByteStream +if not hasattr (svcMgr, 'EventSelector'): + svcMgr += CfgMgr.FaserEventSelectorByteStream ("EventSelector") +theApp.EvtSel = "EventSelector" + +from xAODEventInfoCnv.xAODEventInfoCnvConf import xAODMaker__EventInfoSelectorTool +xconv = xAODMaker__EventInfoSelectorTool() +svcMgr.EventSelector.HelperTools += [xconv] + +# Load ByteStreamCnvSvc +if not hasattr (svcMgr, 'ByteStreamCnvSvc'): + svcMgr += CfgMgr.FaserByteStreamCnvSvc ("ByteStreamCnvSvc") + +# Properties +svcMgr.EventSelector.ByteStreamInputSvc = "ByteStreamInputSvc" + +svcMgr.EventPersistencySvc.CnvServices += [ "ByteStreamCnvSvc" ] + +# Load ProxyProviderSvc +if not hasattr (svcMgr, 'ProxyProviderSvc'): + svcMgr += CfgMgr.ProxyProviderSvc() + +# Add in ByteStreamAddressProviderSvc +#if not hasattr (svcMgr, 'ByteStreamAddressProviderSvc'): +# svcMgr += CfgMgr.ByteStreamAddressProviderSvc ("ByteStreamAddressProviderSvc") +#svcMgr.ProxyProviderSvc.ProviderNames += [ "ByteStreamAddressProviderSvc" ] + +# Add in MetaDataSvc +#if not hasattr (svcMgr, 'MetaDataSvc'): +# svcMgr += CfgMgr.MetaDataSvc ("MetaDataSvc") +#svcMgr.ProxyProviderSvc.ProviderNames += [ "MetaDataSvc" ] + +# Add in MetaData Stores +from StoreGate.StoreGateConf import StoreGateSvc +#if not hasattr (svcMgr, 'InputMetaDataStore'): +# svcMgr += StoreGateSvc( "InputMetaDataStore" ) +#if not hasattr (svcMgr, 'MetaDataStore'): +# svcMgr += StoreGateSvc( "MetaDataStore" ) + +# enable IOVDbSvc to read metadata +#svcMgr.MetaDataSvc.MetaDataContainer = "MetaDataHdr" +#svcMgr.MetaDataSvc.MetaDataTools += [ "IOVDbMetaDataTool" ] + +#if not hasattr (svcMgr.ToolSvc, 'IOVDbMetaDataTool'): +# svcMgr.ToolSvc += CfgMgr.IOVDbMetaDataTool() + +# Enable ByteStream to read MetaData +#svcMgr.MetaDataSvc.MetaDataTools += [ "ByteStreamMetadataTool" ] +#if not hasattr (svcMgr.ToolSvc, 'ByteStreamMetadataTool'): +# svcMgr.ToolSvc += CfgMgr.ByteStreamMetadataTool() diff --git a/Event/FaserByteStreamCnvSvc/python/__init__.py b/Event/FaserByteStreamCnvSvc/python/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..74583d364ec2ca794156596c7254d9b234a940c6 --- /dev/null +++ b/Event/FaserByteStreamCnvSvc/python/__init__.py @@ -0,0 +1,2 @@ +# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + diff --git a/Event/FaserByteStreamCnvSvc/src/DumpFrags.h b/Event/FaserByteStreamCnvSvc/src/DumpFrags.h new file mode 100644 index 0000000000000000000000000000000000000000..af1553d6837704450a8c11986d503690c0f04295 --- /dev/null +++ b/Event/FaserByteStreamCnvSvc/src/DumpFrags.h @@ -0,0 +1,111 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration + -*-c++-*- +*/ + +/** + @class DumpFrags + @brief Dump header and payload fragments +*/ + +#ifndef BYTESTREAMCNVSVC_DUMPFRAGS +#define BYTESTREAMCNVSVC_DUMPFRAGS + +#include <iostream> +#include "EventFormats/DAQFormats.hpp" +#include "EventFormats/TLBDataFragment.hpp" +#include "EventFormats/TLBMonitoringFragment.hpp" +#include "EventFormats/DigitizerDataFragment.hpp" + +using namespace DAQFormats; + +class DumpFrags { + + public: + DumpFrags() {} + + /// dump fragments from FullEventFragment +static void dump(const EventFull* re) + { + + std::cout << " ---EventFull run number = " + << re->run_number() << " event number = " << re->event_counter() + << " Size = " << re->size() << std::endl; + + std::cout<<" Event id "<<re->event_id()<<std::endl; + std::cout<<" Event tag "<<re->event_tag()<< " ["; + switch (re->event_tag()) { + case PhysicsTag: + std::cout << "Physics]" << std::endl; + break; + case CalibrationTag: + std::cout << "Calibration]" << std::endl; + break; + case MonitoringTag: + std::cout << "Monitoring]" << std::endl; + break; + case TLBMonitoringTag: + std::cout << "TLBMonitoring]" << std::endl; + break; + case CorruptedTag: + std::cout << "Corrupted]" << std::endl; + break; + case IncompleteTag: + std::cout << "Incomplete]" << std::endl; + break; + case DuplicateTag: + std::cout << "Duplicate]" << std::endl; + break; + default: + std::cout << "Unknown]" << std::endl; + } + + std::cout<<" Status "<<re->status()<<std::endl; + std::cout<<" Bunch crossing id "<<re->bc_id()<<std::endl; + std::cout<<" Timestamp in microseconds "<<re->timestamp()<<std::endl; + std::cout<<" Trigger bits " << std::hex << re->trigger_bits()<<std::dec << std::endl; + + for(const auto &id : re->getFragmentIDs()) { + const EventFragment* frag=re->find_fragment(id); + std::cout << *frag << std::endl; + + switch (frag->source_id()&0xFFFF0000) { + case TriggerSourceID: + if (re->event_tag() == PhysicsTag ) { + TLBDataFragment tlb_data_frag = TLBDataFragment(frag->payload<const uint32_t*>(), frag->payload_size()); + std::cout<<"TLB data fragment:"<<std::endl; + std::cout<<tlb_data_frag<<std::endl; + } + else if (re->event_tag() == TLBMonitoringTag ) { + TLBMonitoringFragment tlb_mon_frag = TLBMonitoringFragment(frag->payload<const uint32_t*>(), frag->payload_size()); + std::cout<<"TLB monitoring fragment:"<<std::endl; + std::cout<<tlb_mon_frag<<std::endl; + } + + break; + case TrackerSourceID: //FIXME put in specific + case PMTSourceID: + if (re->event_tag() == PhysicsTag ) { + DigitizerDataFragment digitizer_data_frag = DigitizerDataFragment(frag->payload<const uint32_t*>(), frag->payload_size()); + std::cout<<"Digitizer data fragment:"<<std::endl; + std::cout<<digitizer_data_frag<<std::endl; + } + break; + default: + const uint32_t* payload=frag->payload<const uint32_t *>(); + unsigned int ii=0; + for(;ii<frag->payload_size()/4;ii++) { + if (ii%8==0) std::cout<<" "; + std::cout<<" 0x"<<std::setw(8)<<std::hex<<std::setfill('0')<<payload[ii]; + if (ii%8==7) std::cout<<std::endl; + } + if (ii%8!=0) std::cout<<std::endl; + std::cout<<std::dec<<std::setfill(' '); + break; + } + } + } +}; + +#endif + diff --git a/Event/FaserByteStreamCnvSvc/src/EventInfoByteStreamAuxCnv.cxx b/Event/FaserByteStreamCnvSvc/src/EventInfoByteStreamAuxCnv.cxx new file mode 100644 index 0000000000000000000000000000000000000000..a8ec0f18500cd866c00de9b2dca20d15a3dd0bb2 --- /dev/null +++ b/Event/FaserByteStreamCnvSvc/src/EventInfoByteStreamAuxCnv.cxx @@ -0,0 +1,284 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "EventInfoByteStreamAuxCnv.h" +#include "FaserByteStreamCnvSvc/FaserByteStreamCnvSvc.h" +#include "FaserByteStreamCnvSvc/ByteStreamInputSvc.h" + +#include "ByteStreamCnvSvcBase/ByteStreamAddress.h" +#include "ByteStreamCnvSvcBase/IROBDataProviderSvc.h" + +/* +#include "ByteStreamData/RawEvent.h" +#include "ByteStreamData/ByteStreamMetadata.h" +#include "ByteStreamData/ByteStreamMetadataContainer.h" +*/ + +#include "EventFormats/DAQFormats.hpp" + +#include "AthenaKernel/errorcheck.h" +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/StatusCode.h" +#include "GaudiKernel/DataObject.h" +#include "GaudiKernel/IRegistry.h" + +#include "xAODEventInfo/EventInfo.h" +#include "xAODEventInfo/EventAuxInfo.h" + +#include "StoreGate/StoreGateSvc.h" + +//#include "eformat/StreamTag.h" + +#include <time.h> + +using DAQFormats::EventFull; + +EventInfoByteStreamAuxCnv::EventInfoByteStreamAuxCnv(ISvcLocator* svcloc) + : Converter(storageType(), classID(), svcloc) + , AthMessaging(svcloc != nullptr ? msgSvc() : nullptr, "EventInfoByteStreamAuxCnv") + , m_ByteStreamCnvSvc(nullptr) + , m_robDataProvider("ROBDataProviderSvc", "EventInfoByteStreamAuxCnv") + // , m_mdSvc("InputMetaDataStore", "EventInfoByteStreamAuxCnv") + , m_isSimulation(false) + , m_isTestbeam(false) + , m_isCalibration(false) +{ +} + +const CLID& EventInfoByteStreamAuxCnv::classID() +{ + return ClassID_traits<xAOD::EventAuxInfo>::ID(); +} + +long EventInfoByteStreamAuxCnv::storageType() +{ + return ByteStreamAddress::storageType(); +} + +StatusCode EventInfoByteStreamAuxCnv::initialize() +{ + ATH_MSG_DEBUG("EventInfoByteStreamAuxCnv::Initialize"); + + CHECK(Converter::initialize()); + + // Check ByteStreamCnvSvc + IService* svc{nullptr}; + StatusCode sc = serviceLocator()->getService("ByteStreamCnvSvc", svc); + if (!sc.isSuccess()) { + ATH_MSG_ERROR("Cannot get ByteStreamCnvSvc "); + return sc; + } else { + ATH_MSG_DEBUG("Located ByteStreamCnvSvc"); + } + + m_ByteStreamCnvSvc = dynamic_cast<FaserByteStreamCnvSvc*>(svc); + if (!m_ByteStreamCnvSvc) { + ATH_MSG_ERROR("Cannot cast to ByteStreamCnvSvc"); + return StatusCode::FAILURE; + } + + //CHECK(m_robDataProvider.retrieve()); + //CHECK(m_mdSvc.retrieve()); + + SimpleProperty<bool> propIsSimulation("IsSimulation", m_isSimulation); + sc = m_ByteStreamCnvSvc->getProperty(&propIsSimulation); + if (sc.isSuccess()) { + m_isSimulation = propIsSimulation.value(); + ATH_MSG_INFO("IsSimulation : " << m_isSimulation); + } + else { + ATH_MSG_ERROR("Cannot get IsSimulation"); + return sc; + } + + SimpleProperty<bool> propIsTestbeam("IsTestbeam", m_isTestbeam); + sc = m_ByteStreamCnvSvc->getProperty(&propIsTestbeam); + if (sc.isSuccess()) { + m_isTestbeam = propIsTestbeam.value(); + ATH_MSG_INFO("IsTestbeam : " << m_isTestbeam); + } + else { + ATH_MSG_ERROR("Cannot get IsTestbeam"); + return sc; + } + + SimpleProperty<bool> propIsCalibration("IsCalibration", m_isCalibration); + sc = m_ByteStreamCnvSvc->getProperty(&propIsCalibration); + if (sc.isSuccess()) { + m_isCalibration = propIsCalibration.value(); + ATH_MSG_INFO("IsCalibration : " << m_isCalibration); + } + else { + ATH_MSG_ERROR("Cannot get IsCalibration"); + return sc; + } + + return StatusCode::SUCCESS; +} + +StatusCode EventInfoByteStreamAuxCnv::finalize() +{ + ATH_MSG_DEBUG("Finalize"); + + StatusCode sc = Converter::finalize(); + if (sc.isFailure()) { + ATH_MSG_WARNING("Converter::finalize() failed"); + } + return sc; +} + +StatusCode EventInfoByteStreamAuxCnv::createObj(IOpaqueAddress* pAddr, DataObject*& pObj) +{ + + ATH_MSG_DEBUG("EventInfoByteStreamAuxCnv::createObj() called"); + + ByteStreamAddress *pRE_Addr{nullptr}; + pRE_Addr = dynamic_cast<ByteStreamAddress*>(pAddr); + if (!pRE_Addr) { + ATH_MSG_ERROR("Cannot cast to ByteStreamAddress "); + return StatusCode::FAILURE; + } + + + // get RawEvent + const EventFull* re = reinterpret_cast<const EventFull*>(m_robDataProvider->getEvent()); + + if (!re) { + ATH_MSG_ERROR("Can not get RawEvent "); + return StatusCode::FAILURE; + } + + // Run Number + int runNumber = re->run_number(); + + // Event Number + uint64_t eventNumber = re->event_id(); + + // Time Stamp + uint32_t bc_time_sec = re->timestamp()/1E6; // timestamp in usec + uint32_t bc_time_ns = 1E9 * (re->timestamp() - 1E6 * bc_time_sec); + // bc_time_ns should be lt 1e9. + if (bc_time_ns > 1000000000) { + // For later runs, the nanosecond clock sometimes is not reset, making it overrun 1e9. Round it off to 1e9 + ATH_MSG_WARNING("bc_time nanosecond number larger than 1e9, it is " << bc_time_ns << ", reset it to 1 sec"); + bc_time_ns = 1000000000; + } + + // luminosity block number + uint16_t lumiBlock = 0; + + // bunch crossing identifier + uint16_t bcID = re->bc_id(); + + unsigned int detMask0 = 0xFFFFFFFF, detMask1 = 0xFFFFFFFF, detMask2 = 0xFFFFFFFF, detMask3 = 0xFFFFFFFF; + + xAOD::EventInfo evtInfo; + xAOD::EventAuxInfo* pEvtInfoAux = new xAOD::EventAuxInfo(); + evtInfo.setStore(pEvtInfoAux); + + evtInfo.setRunNumber(runNumber); + evtInfo.setEventNumber(eventNumber); + evtInfo.setLumiBlock(lumiBlock); + evtInfo.setTimeStamp(bc_time_sec); + evtInfo.setTimeStampNSOffset(bc_time_ns); + evtInfo.setBCID(bcID); + evtInfo.setDetectorMask(detMask0,detMask1); + evtInfo.setDetectorMaskExt(detMask2,detMask3); + + // The following values were implicitly set by the BS converter of the legacy EventInfo + // Setting them here too + evtInfo.setMCChannelNumber(0); + evtInfo.setMCEventNumber(0); + evtInfo.setMCEventWeights(std::vector<float>(1,1)); + + // Set Event Type + uint32_t eventTypeBitmask{0}; + if (m_isSimulation) { + eventTypeBitmask |= xAOD::EventInfo::IS_SIMULATION; + } + if (m_isTestbeam) { + eventTypeBitmask |= xAOD::EventInfo::IS_TESTBEAM; + } + if (m_isCalibration) { + eventTypeBitmask |= xAOD::EventInfo::IS_CALIBRATION; + } + evtInfo.setEventTypeBitmask(eventTypeBitmask); + + /* + // Trigger Info + const OFFLINE_FRAGMENTS_NAMESPACE::DataType* buffer; + // status element + re->status(buffer); + uint32_t statusElement = *buffer; + + // extended LVL1ID + uint32_t extendedLevel1ID = re->lvl1_id(); + + // LVL1 trigger type + uint32_t level1TriggerType = re->lvl1_trigger_type(); + */ + + // stream tag + /* + std::vector<xAOD::EventInfo::StreamTag> streamTags; + std::vector<eformat::helper::StreamTag> onl_streamTags; + re->stream_tag(buffer); + eformat::helper::decode(re->nstream_tag(), buffer, onl_streamTags); + for (const eformat::helper::StreamTag& onl_streamTag : onl_streamTags) { + std::set<uint32_t> tmp_off_dets = std::set<uint32_t>(); + if (!onl_streamTag.dets.empty()) { + std::set<eformat::SubDetector> tmp_onl_dets = onl_streamTag.dets; + for (const eformat::SubDetector& subdet : tmp_onl_dets) { + tmp_off_dets.insert((uint32_t) subdet); + } + } + streamTags.push_back(xAOD::EventInfo::StreamTag(onl_streamTag.name + , onl_streamTag.type + , onl_streamTag.obeys_lumiblock + , onl_streamTag.robs + , tmp_off_dets) + ); + } + + evtInfo.setStatusElement(statusElement); + evtInfo.setExtendedLevel1ID(extendedLevel1ID); + evtInfo.setLevel1TriggerType(level1TriggerType); + evtInfo.setStreamTags(streamTags); + */ + + // record EventInfo + evtInfo.setEventFlags(xAOD::EventInfo::Core, m_robDataProvider->getEventStatus()); + pObj = StoreGateSvc::asStorable(pEvtInfoAux); + + ATH_MSG_DEBUG(" New xAOD::EventAuxInfo made, run/event= " << runNumber + << " " << eventNumber + << " Time stamp = " << ascTime(bc_time_sec) + ); + + return StatusCode::SUCCESS; + +} + +StatusCode EventInfoByteStreamAuxCnv::createRep(DataObject* /*pObj*/, IOpaqueAddress*& /*pAddr*/) +{ + ATH_MSG_DEBUG("Nothing to be done for xAOD::EventAuxInfo createReps"); + return StatusCode::SUCCESS; +} + +const char* EventInfoByteStreamAuxCnv::ascTime(unsigned int tstamp) +{ + struct tm t; + t.tm_sec = tstamp; + t.tm_min = 0; + t.tm_hour = 0; + t.tm_mday = 0; + t.tm_mon = 0; + t.tm_year = 70; + t.tm_wday = 00; + t.tm_yday = 00; + t.tm_isdst = 0; + time_t ct = mktime(&t); + tm* t2 = gmtime(&ct); + return(asctime(t2)); +} diff --git a/Event/FaserByteStreamCnvSvc/src/EventInfoByteStreamAuxCnv.h b/Event/FaserByteStreamCnvSvc/src/EventInfoByteStreamAuxCnv.h new file mode 100644 index 0000000000000000000000000000000000000000..90fb3113ea6c384fb2788215dcf890e433c747f4 --- /dev/null +++ b/Event/FaserByteStreamCnvSvc/src/EventInfoByteStreamAuxCnv.h @@ -0,0 +1,60 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef FASEREVENTINFOBYTESTREAMAUXCNV_H +#define FASEREVENTINFOBYTESTREAMAUXCNV_H + +/** + * @file EventInfoByteStreamAuxCnv.h + * + * @class EventInfoByteStreamAuxCnv + * + * @brief This is the class definition of ByteStream converter for xAOD::EventInfoAux + * Event Info is built from RawEvent when reading. Nothing is done when writing ByteStream + * + */ + +#include "GaudiKernel/Converter.h" +#include "GaudiKernel/ServiceHandle.h" +#include "AthenaBaseComps/AthMessaging.h" + +class FaserByteStreamCnvSvc; +class IROBDataProviderSvc; +class StoreGateSvc; + +// Abstract factory to create the converter +template <class TYPE> class CnvFactory; + +class EventInfoByteStreamAuxCnv : public Converter, public AthMessaging +{ + public: + EventInfoByteStreamAuxCnv(ISvcLocator* svcloc); + virtual ~EventInfoByteStreamAuxCnv() override {} + + virtual StatusCode initialize() override; + virtual StatusCode finalize() override; + + /// converter method to create object + virtual StatusCode createObj(IOpaqueAddress* pAddr, DataObject*& pObj) override; + /// converter method to write object + virtual StatusCode createRep(DataObject* pObj, IOpaqueAddress*& pAddr) override; + + /// Storage type and class ID + virtual long repSvcType() const override { return i_repSvcType(); } + static long storageType(); + static const CLID& classID(); + + private: + const char* ascTime(unsigned int t); //!< convert timestamp to ascii time. + FaserByteStreamCnvSvc* m_ByteStreamCnvSvc; //!< pointer to BS CnvSvc + ServiceHandle<IROBDataProviderSvc> m_robDataProvider; //!< RODDataProviderSvc handle + //ServiceHandle<StoreGateSvc> m_mdSvc; //!< TDS handle + + // flags for EventType + bool m_isSimulation; + bool m_isTestbeam; + bool m_isCalibration; +}; + +#endif diff --git a/Event/FaserByteStreamCnvSvc/src/EventInfoByteStreamxAODCnv.cxx b/Event/FaserByteStreamCnvSvc/src/EventInfoByteStreamxAODCnv.cxx new file mode 100644 index 0000000000000000000000000000000000000000..8fd407d8fa04ae9bd3e6b8549cff386bb9b1461e --- /dev/null +++ b/Event/FaserByteStreamCnvSvc/src/EventInfoByteStreamxAODCnv.cxx @@ -0,0 +1,81 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "EventInfoByteStreamxAODCnv.h" +#include "ByteStreamCnvSvcBase/ByteStreamAddress.h" + +#include "AthenaKernel/errorcheck.h" +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/StatusCode.h" +#include "GaudiKernel/DataObject.h" +#include "GaudiKernel/IRegistry.h" + +#include "xAODEventInfo/EventInfo.h" +#include "xAODEventInfo/EventAuxInfo.h" + +#include "StoreGate/StoreGateSvc.h" + +EventInfoByteStreamxAODCnv::EventInfoByteStreamxAODCnv(ISvcLocator* svcloc) + : Converter(storageType(), classID(), svcloc) + , AthMessaging(svcloc != nullptr ? msgSvc() : nullptr, "EventInfoByteStreamxAODCnv") +{ +} + +const CLID& EventInfoByteStreamxAODCnv::classID() +{ + return ClassID_traits<xAOD::EventInfo>::ID(); +} + +long EventInfoByteStreamxAODCnv::storageType() +{ + return ByteStreamAddress::storageType(); +} + +StatusCode EventInfoByteStreamxAODCnv::initialize() +{ + ATH_MSG_DEBUG("EventInfoByteStreamxAODCnv::Initialize"); + CHECK(Converter::initialize()); + return StatusCode::SUCCESS; +} + +StatusCode EventInfoByteStreamxAODCnv::finalize() +{ + ATH_MSG_DEBUG("EventInfoByteStreamxAODCnv::Finalize"); + + StatusCode sc = Converter::finalize(); + if (sc.isFailure()) { + ATH_MSG_WARNING("Converter::finalize() failed"); + } + return sc; +} + +StatusCode EventInfoByteStreamxAODCnv::createObj(IOpaqueAddress* pAddr, DataObject*& pObj) +{ + ByteStreamAddress *pRE_Addr{nullptr}; + pRE_Addr = dynamic_cast<ByteStreamAddress*>(pAddr); + if (!pRE_Addr) { + ATH_MSG_ERROR("Cannot cast to ByteStreamAddress "); + return StatusCode::FAILURE; + } + + ATH_MSG_DEBUG("EventInfoByteStreamxAODCnv::Creating Objects"); + + const std::string nm = *(pRE_Addr->par()); + const std::string nmAux = nm + "Aux."; + + xAOD::EventInfo* pEvtInfo = new xAOD::EventInfo(); + DataLink<xAOD::EventAuxInfo> link(nmAux); + pEvtInfo->setStore(link); + pObj = StoreGateSvc::asStorable(pEvtInfo); + + ATH_MSG_DEBUG(" New EventInfo made, run/event= " << pEvtInfo->runNumber() << " " << pEvtInfo->eventNumber()); + + return StatusCode::SUCCESS; +} + +StatusCode EventInfoByteStreamxAODCnv::createRep(DataObject* /*pObj*/, IOpaqueAddress*& /*pAddr*/) +{ + ATH_MSG_DEBUG("Nothing to be done for xAOD::EventInfo createReps"); + return StatusCode::SUCCESS; +} diff --git a/Event/FaserByteStreamCnvSvc/src/EventInfoByteStreamxAODCnv.h b/Event/FaserByteStreamCnvSvc/src/EventInfoByteStreamxAODCnv.h new file mode 100644 index 0000000000000000000000000000000000000000..a3ec402be4583f298f19ad90e2abde25bf19c8ee --- /dev/null +++ b/Event/FaserByteStreamCnvSvc/src/EventInfoByteStreamxAODCnv.h @@ -0,0 +1,45 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef FASEREVENTINFOBYTESTREAMXAODCNV_H +#define FASEREVENTINFOBYTESTREAMXAODCNV_H + +/** + * @file EventInfoByteStreamxAODCnv.h + * + * @class EventInfoByteStreamxAODCnv + * + * @brief This is the class definition of ByteStream converter for xAOD::EventInfo + * Event Info is built from RawEvent when reading. Nothing is done when writing ByteStream + * + */ + +#include "GaudiKernel/Converter.h" +#include "AthenaBaseComps/AthMessaging.h" + +// Abstract factory to create the converter +template <class TYPE> class CnvFactory; + +class EventInfoByteStreamxAODCnv : public Converter, public AthMessaging +{ + public: + EventInfoByteStreamxAODCnv(ISvcLocator* svcloc); + virtual ~EventInfoByteStreamxAODCnv() override {} + + virtual StatusCode initialize() override; + virtual StatusCode finalize() override; + + /// converter method to create object + virtual StatusCode createObj(IOpaqueAddress* pAddr, DataObject*& pObj) override; + /// converter method to write object + virtual StatusCode createRep(DataObject* pObj, IOpaqueAddress*& pAddr) override; + + /// Storage type and class ID + virtual long repSvcType() const override { return i_repSvcType(); } + static long storageType(); + static const CLID& classID(); + +}; + +#endif diff --git a/Event/FaserByteStreamCnvSvc/src/FaserByteStreamCnvSvc.cxx b/Event/FaserByteStreamCnvSvc/src/FaserByteStreamCnvSvc.cxx new file mode 100644 index 0000000000000000000000000000000000000000..437f0f4ca7ef0a1aa432ec90d8cd21442704449d --- /dev/null +++ b/Event/FaserByteStreamCnvSvc/src/FaserByteStreamCnvSvc.cxx @@ -0,0 +1,292 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#include "FaserByteStreamCnvSvc/FaserByteStreamCnvSvc.h" +//#include "ByteStreamCnvSvc/ByteStreamOutputSvc.h" +#include "ByteStreamCnvSvcBase/FullEventAssembler.h" +#include "ByteStreamCnvSvcBase/ByteStreamAddress.h" + +#include "StoreGate/StoreGate.h" +#include "xAODEventInfo/EventInfo.h" +#include "xAODTrigger/TrigDecision.h" + +//#include "eformat/SourceIdentifier.h" +//#include "eformat/StreamTag.h" + +#include "AthenaKernel/IClassIDSvc.h" + +#include "AthenaPoolUtilities/CondAttrListCollection.h" + +#include <algorithm> + +/// Standard constructor +FaserByteStreamCnvSvc::FaserByteStreamCnvSvc(const std::string& name, ISvcLocator* pSvcLocator) + : ByteStreamCnvSvcBase(name, pSvcLocator), + m_evtStore ("StoreGateSvc", name) +{ + declareProperty("ByteStreamOutputSvc", m_ioSvcName); + declareProperty("ByteStreamOutputSvcList", m_ioSvcNameList); + declareProperty("IsSimulation", m_isSimulation = false); + declareProperty("IsTestbeam", m_isTestbeam = false); + declareProperty("IsCalibration", m_isCalibration= false); + declareProperty("GetDetectorMask", m_getDetectorMask = false); + declareProperty("UserType", m_userType = "RawEvent"); + declareProperty("EventStore", m_evtStore); +} + +/// Standard Destructor +FaserByteStreamCnvSvc::~FaserByteStreamCnvSvc() { +} + +/// Initialize the service. +StatusCode FaserByteStreamCnvSvc::initialize() { + if (!ByteStreamCnvSvcBase::initialize().isSuccess()) { + ATH_MSG_FATAL("FaserByteStreamCnvSvcBase::initialize() failed"); + return(StatusCode::FAILURE); + } + + ATH_CHECK( m_evtStore.retrieve() ); + + // get ready for output + std::vector<std::string> ioSvcNames = m_ioSvcNameList.value(); + if (!m_ioSvcName.empty()) { + // add ioSvcName if ioSvcNameList is missing it + std::vector<std::string>::iterator it = find(ioSvcNames.begin(), ioSvcNames.end(), m_ioSvcName); + if (it == ioSvcNames.end()) { + ioSvcNames.push_back(m_ioSvcName); + } + } + + if (ioSvcNames.size() != 0) { + // Check FaserByteStreamCnvSvc + for (std::vector<std::string>::iterator itSvc = ioSvcNames.begin(), itSvcE = ioSvcNames.end(); + itSvc != itSvcE; ++itSvc) { + ATH_MSG_DEBUG("get " << *itSvc); + + ATH_MSG_WARNING("not doing anything with" << *itSvc); + /* + // get service + IService* svc; + if (!service(*itSvc, svc).isSuccess()) { + ATH_MSG_FATAL("Cannot get ByteStreamOutputSvc"); + return(StatusCode::FAILURE); + } + ByteStreamOutputSvc* ioSvc = dynamic_cast<ByteStreamOutputSvc*>(svc); + if (ioSvc == 0) { + ATH_MSG_FATAL("Cannot cast to ByteStreamOutputSvc"); + return(StatusCode::FAILURE); + } + // get stream name + std::string bsOutputStreamName; + SimpleProperty<std::string> propBSO("BSOutputStreamName", bsOutputStreamName); + if (!ioSvc->getProperty(&propBSO).isSuccess()) { + ATH_MSG_FATAL("Cannot get BSOutputStreamName from " << *itSvc); + return(StatusCode::FAILURE); + } + bsOutputStreamName = propBSO.value(); + // append + m_ioSvcMap[bsOutputStreamName] = ioSvc; + */ + } + } + return(StatusCode::SUCCESS); +} + +StatusCode FaserByteStreamCnvSvc::finalize() { + return(ByteStreamCnvSvcBase::finalize()); +} + +StatusCode FaserByteStreamCnvSvc::connectOutput(const std::string& t, const std::string& /*mode*/) { + return(connectOutput(t)); +} + +StatusCode FaserByteStreamCnvSvc::connectOutput(const std::string& /*t*/) { + ATH_MSG_DEBUG("In connectOutput"); + + /* + // Get the EventInfo obj for run/event number + const xAOD::EventInfo* evtInfo{nullptr}; + ATH_CHECK( m_evtStore->retrieve(evtInfo) ); + uint64_t event = evtInfo->eventNumber(); + uint32_t run_no = evtInfo->runNumber(); + uint32_t bc_time_sec = evtInfo->timeStamp(); + uint32_t bc_time_ns = evtInfo->timeStampNSOffset(); + uint32_t run_type = 0; + uint32_t lvl1_id = evtInfo->extendedLevel1ID(); + if (lvl1_id == 0) { + lvl1_id = event; + } + uint32_t lvl1_type = evtInfo->level1TriggerType(); + uint64_t global_id = event; + uint16_t lumi_block = evtInfo->lumiBlock(); + uint16_t bc_id = evtInfo->bcid(); + static uint8_t nevt = 0; + nevt = nevt%255; + // create an empty RawEvent + eformat::helper::SourceIdentifier sid = eformat::helper::SourceIdentifier(eformat::FULL_SD_EVENT, nevt); + m_rawEventWrite = new RawEventWrite(sid.code(), bc_time_sec, bc_time_ns, global_id, run_type, run_no, lumi_block, lvl1_id, bc_id, lvl1_type); + */ + return(StatusCode::SUCCESS); +} + +StatusCode FaserByteStreamCnvSvc::commitOutput(const std::string& outputConnection, bool /*b*/) { + ATH_MSG_DEBUG("In flushOutput " << outputConnection); + + if (m_ioSvcMap.size() == 0) { + ATH_MSG_ERROR("FaserByteStreamCnvSvc not configure for output"); + return(StatusCode::FAILURE); + } + /* + writeFEA(); + + // Get EventInfo + const xAOD::EventInfo* evtInfo{nullptr}; + ATH_CHECK( m_evtStore->retrieve(evtInfo) ); + + // Try to get TrigDecision + const xAOD::TrigDecision* trigDecision{nullptr}; + if(m_evtStore->retrieve(trigDecision)!=StatusCode::SUCCESS) { + ATH_MSG_WARNING("Failed to retrieve xAOD::TrigDecision. Will write empty trigger decision vectors"); + trigDecision = nullptr; + } + + // change trigger info in Header + uint32_t *l1Buff{nullptr}; + uint32_t *l2Buff{nullptr}; + uint32_t *efBuff{nullptr}; + uint32_t *encTag{nullptr}; + + m_rawEventWrite->lvl1_id(evtInfo->extendedLevel1ID()); + m_rawEventWrite->lvl1_trigger_type((uint8_t)(evtInfo->level1TriggerType())); + + // LVL1 info + uint32_t l1Size{0}; + if(trigDecision) { + const std::vector<uint32_t>& tbp = trigDecision->tbp(); + const std::vector<uint32_t>& tap = trigDecision->tap(); + const std::vector<uint32_t>& tav = trigDecision->tav(); + size_t l1TotSize = tbp.size()+tap.size()+tav.size(); + if(l1TotSize>0) { + l1Buff = new uint32_t[l1TotSize]; + for(uint32_t tb : tbp) { + l1Buff[l1Size++] = tb; + } + for(uint32_t tb : tap) { + l1Buff[l1Size++] = tb; + } + for(uint32_t tb : tav) { + l1Buff[l1Size++] = tb; + } + } + } + m_rawEventWrite->lvl1_trigger_info(l1Size, l1Buff); + + // LVL2 info + uint32_t l2Size{0}; + if(trigDecision) { + const std::vector<uint32_t>& lvl2PP = trigDecision->lvl2PassedPhysics(); + if(lvl2PP.size()>0) { + l2Buff = new uint32_t[lvl2PP.size()]; + for(uint32_t tb : lvl2PP) { + l2Buff[l2Size++] = tb; + } + } + } + m_rawEventWrite->lvl2_trigger_info(l2Size, l2Buff); + + // EF info + uint32_t efSize{0}; + if(trigDecision) { + const std::vector<uint32_t>& efPP = trigDecision->efPassedPhysics(); + if(efPP.size()>0) { + efBuff = new uint32_t[efPP.size()]; + for(uint32_t tb : efPP) { + efBuff[efSize++] = tb; + } + } + } + m_rawEventWrite->event_filter_info(efSize, efBuff); + + // stream tag + std::vector<eformat::helper::StreamTag> on_streamTags; + const std::vector<xAOD::EventInfo::StreamTag>& off_streamTags = evtInfo->streamTags(); + for(const auto& sTag : off_streamTags) { + // convert offline -> online + eformat::helper::StreamTag tmpTag; + tmpTag.name = sTag.name(); + tmpTag.type = sTag.type(); + tmpTag.obeys_lumiblock = sTag.obeysLumiblock(); + for(uint32_t rob : sTag.robs()) { + tmpTag.robs.insert(rob); + } + for(uint32_t det : sTag.dets()) { + tmpTag.dets.insert((eformat::SubDetector)det); + } + on_streamTags.push_back(tmpTag); + } + // encode + uint32_t encSize = eformat::helper::size_word(on_streamTags); + encTag = new uint32_t[encSize]; + eformat::helper::encode(on_streamTags, encSize, encTag); + m_rawEventWrite->stream_tag(encSize, encTag); + + // convert RawEventWrite to RawEvent + uint32_t rawSize = m_rawEventWrite->size_word(); + OFFLINE_FRAGMENTS_NAMESPACE::DataType* buffer = new OFFLINE_FRAGMENTS_NAMESPACE::DataType[rawSize]; + uint32_t count = eformat::write::copy(*(m_rawEventWrite->bind()), buffer, rawSize); + if (count != rawSize) { + ATH_MSG_ERROR("Memcopy failed"); + return(StatusCode::FAILURE); + } + RawEvent rawEvent(buffer); + // check validity + try { + rawEvent.check_tree(); + } catch (...) { + ATH_MSG_ERROR("commitOutput failed, because FullEventFragment invalid"); + return(StatusCode::FAILURE); + } + ATH_MSG_DEBUG("commitOutput: Size of Event (words) = " << rawEvent.fragment_size_word()); + // put event to OutputSvc + if ((m_ioSvcMap.size() == 1) or (m_ioSvcMap.count(outputConnection) > 0)) { + std::map<std::string, ByteStreamOutputSvc*>::iterator itSvc = m_ioSvcMap.find(outputConnection); + // for backward compatibility + if (itSvc == m_ioSvcMap.end()) { + itSvc = m_ioSvcMap.begin(); + } + // put + if (!itSvc->second->putEvent(&rawEvent)) { + ATH_MSG_ERROR("commitOutput failed to send output"); + return(StatusCode::FAILURE); + } + } + // delete + delete [] buffer; buffer = 0; + delete m_rawEventWrite; m_rawEventWrite = 0; + delete [] l1Buff; l1Buff = 0; + delete [] l2Buff; l2Buff = 0; + delete [] efBuff; efBuff = 0; + delete [] encTag; encTag = 0; + // delete FEA + for (std::map<std::string, FullEventAssemblerBase*>::const_iterator it = m_feaMap.begin(), + itE = m_feaMap.end(); it != itE; it++) { + delete it->second; + } + m_feaMap.clear(); + +*/ + return(StatusCode::SUCCESS); +} + +/* +void FaserByteStreamCnvSvc::writeFEA() { + ATH_MSG_DEBUG("before FEAMAP size = " << m_feaMap.size()); + for (std::map<std::string, FullEventAssemblerBase*>::const_iterator it = m_feaMap.begin(), + itE = m_feaMap.end(); it != itE; it++) { + MsgStream log(msgSvc(), name()); + (*it).second->fill(m_rawEventWrite, log); + } + ATH_MSG_DEBUG("after FEAMAP size = " << m_feaMap.size()); +} +*/ diff --git a/Event/FaserByteStreamCnvSvc/src/FaserByteStreamInputSvc.cxx b/Event/FaserByteStreamCnvSvc/src/FaserByteStreamInputSvc.cxx new file mode 100644 index 0000000000000000000000000000000000000000..593bd1891c224ff6f9a16c32da062913b9adf041 --- /dev/null +++ b/Event/FaserByteStreamCnvSvc/src/FaserByteStreamInputSvc.cxx @@ -0,0 +1,465 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#include "FaserByteStreamInputSvc.h" +#include "DumpFrags.h" + +#include "ByteStreamData/ByteStreamMetadataContainer.h" +#include "ByteStreamCnvSvcBase/ByteStreamAddress.h" +#include "FaserEventStorage/pickFaserDataReader.h" + +#include "GaudiKernel/IJobOptionsSvc.h" +#include "GaudiKernel/Property.h" + +#include "PersistentDataModel/DataHeader.h" +#include "PersistentDataModel/Token.h" +#include "StoreGate/StoreGateSvc.h" +#include "xAODEventInfo/EventInfo.h" +#include "xAODEventInfo/EventAuxInfo.h" + +#include "EventFormats/DAQFormats.hpp" + +// Don't know what these do, comment for now +// #include "eformat/HeaderMarker.h" +// #include "eformat/SourceIdentifier.h" +// #include "eformat/Issue.h" +// #include "eformat/Problem.h" +// #include "eformat/Version.h" +// #include "eformat/Status.h" +// #include "eformat/old/util.h" + +#include <cstdio> +#include <string> +#include <vector> +#include <unistd.h> + +using DAQFormats::EventFull; + +// Constructor. +FaserByteStreamInputSvc::FaserByteStreamInputSvc( + const std::string& name, ISvcLocator* svcloc) + : ByteStreamInputSvc(name, svcloc) + , m_readerMutex() + , m_eventsCache() + , m_reader() + , m_evtOffsets() + , m_evtInFile(0) + , m_evtFileOffset(0) + , m_fileGUID("") + , m_storeGate ("StoreGateSvc", name) + //, m_inputMetadata("StoreGateSvc/InputMetaDataStore", name) + , m_robProvider ("ROBDataProviderSvc", name) + , m_sequential (this, "EnableSequential", false, "") + , m_dump (this, "DumpFlag", false, "Dump fragments") + , m_wait (this, "WaitSecs", 0., "Seconds to wait if input is in wait state") + , m_valEvent (this, "ValidateEvent", true, "switch on check_tree when reading events") + , m_eventInfoKey (this, "EventInfoKey", "EventInfo", "Key of EventInfo in metadata store") + +{ + assert(pSvcLocator != nullptr); + + declareProperty("EventStore", m_storeGate); + //declareProperty("MetaDataStore", m_inputMetadata); +} +//------------------------------------------------------------------------------ +FaserByteStreamInputSvc::~FaserByteStreamInputSvc() { +} +//------------------------------------------------------------------------------ +StatusCode FaserByteStreamInputSvc::initialize() { + ATH_MSG_INFO("Initializing " << name() << " - package version " << PACKAGE_VERSION); + + ATH_CHECK(ByteStreamInputSvc::initialize()); + //ATH_CHECK(m_inputMetadata.retrieve()); + ATH_CHECK(m_storeGate.retrieve()); + ATH_CHECK(m_robProvider.retrieve()); + + return(StatusCode::SUCCESS); +} +//________________________________________________________________________________ +StatusCode FaserByteStreamInputSvc::stop() { + ATH_MSG_DEBUG("Calling ByteStreamInputSvc::stop()"); + // close moved to EventSelector for explicit coupling with incident + return(StatusCode::SUCCESS); +} +//------------------------------------------------------------------------------ +StatusCode FaserByteStreamInputSvc::finalize() { + + ATH_CHECK(m_storeGate.release()); + ATH_CHECK(m_robProvider.release()); + //ATH_CHECK(m_inputMetadata.release()); + + return(ByteStreamInputSvc::finalize()); +} +//------------------------------------------------------------------------------ +long FaserByteStreamInputSvc::positionInBlock() +{ + return m_evtOffsets.size(); +} + +const EventFull* FaserByteStreamInputSvc::previousEvent() { + ATH_MSG_WARNING("previousEvent called, but not implemented!"); + return NULL; +} +//------------------------------------------------------------------------------ +// Read the next event. +const EventFull* FaserByteStreamInputSvc::nextEvent() { + + ATH_MSG_DEBUG("FaserByteStreamInputSvc::nextEvent() called"); + + std::lock_guard<std::mutex> lock( m_readerMutex ); + const EventContext context{ Gaudi::Hive::currentContext() }; + + // Load event from file + EventFull* theEvent=0; + + if (readerReady()) { + + m_evtInFile ++; // increment iterator + + if (m_evtInFile+1 > m_evtOffsets.size()) { + // get current event position (cast to long long until native tdaq implementation) + ATH_MSG_DEBUG("nextEvent _above_ high water mark"); + m_evtFileOffset = (long long)m_reader->getPosition(); + m_evtOffsets.push_back(m_evtFileOffset); + m_reader->getData(theEvent); + } + + else { + // Load from previous offset + ATH_MSG_DEBUG("nextEvent below high water mark"); + m_evtFileOffset = m_evtOffsets.at( m_evtInFile-1 ); + m_reader->getData( theEvent, m_evtFileOffset ); + } + + ATH_MSG_DEBUG("Read Event:\n" << *theEvent); + } + else { + ATH_MSG_ERROR("DataReader not ready. Need to getBlockIterator first"); + return 0; + } + + + EventCache* cache = m_eventsCache.get(context); + + // initialize before building RawEvent + cache->releaseEvent(); + + // Use buffer to build FullEventFragment + try { + buildEvent( cache, theEvent, true ); + } + catch (...) { + // rethrow any exceptions + throw; + } + + if ( cache->rawEvent == NULL ) { + ATH_MSG_ERROR("Failure to build fragment"); + return NULL; + } + + // Set it for the data provider + ATH_MSG_DEBUG( "call robProvider->setNextEvent "); + m_robProvider->setNextEvent(context, reinterpret_cast<const RawEvent*>(cache->rawEvent.get()) ); + m_robProvider->setEventStatus(context, cache->eventStatus ); + + // dump + if (m_dump) { + DumpFrags::dump(cache->rawEvent.get()); + } + + ATH_MSG_DEBUG( "switched to next event in slot " << context ); + return( cache->rawEvent.get() ); + +} + +void FaserByteStreamInputSvc::validateEvent() { + const EventContext& context{ Gaudi::Hive::currentContext() }; + const EventFull* const event = m_eventsCache.get(context)->rawEvent.get(); + m_eventsCache.get(context)->eventStatus = validateEvent( event ); +} + +unsigned FaserByteStreamInputSvc::validateEvent( const EventFull* const rawEvent ) const +{ + unsigned int status = 0; + if (m_valEvent) { + ATH_MSG_WARNING("validateEvent called, but not implemented"); + ATH_MSG_INFO("event:\n" << *rawEvent); + /* + // check validity + std::vector<eformat::FragmentProblem> p; + rawEvent->problems(p); + if (!p.empty()) { + status += 0x01000000; + // bad event + ATH_MSG_WARNING("Failed to create FullEventFragment"); + for (std::vector<eformat::FragmentProblem>::const_iterator i = p.begin(), iEnd = p.end(); + i != iEnd; i++) { + ATH_MSG_WARNING(eformat::helper::FragmentProblemDictionary.string(*i)); + } + // releaseCurrentEvent(); + throw ByteStreamExceptions::badFragmentData(); + } + if ( !ROBFragmentCheck( rawEvent ) ) { + status += 0x02000000; + // bad event + // releaseCurrentEvent(); + ATH_MSG_ERROR("Skipping bad event"); + throw ByteStreamExceptions::badFragmentData(); + } + */ + } + else { + ATH_MSG_DEBUG("Processing event without validating."); + } + return status; +} + +void FaserByteStreamInputSvc::buildEvent(EventCache* cache, EventFull* theEvent, bool validate) const +{ + ATH_MSG_DEBUG("FaserByteStreamInputSvc::buildEvent() called"); + + if (validate) { + // Nothing to do + } + + cache->eventStatus = 0; + //cache->rawEvent = std::make_unique<EventFull>(); + cache->rawEvent.reset(theEvent); +} + +//__________________________________________________________________________ +StatusCode FaserByteStreamInputSvc::generateDataHeader() +{ + ATH_MSG_DEBUG("FaserByteStreamInputSvc::generateDataHeader() called"); + + // get file GUID + m_fileGUID = m_reader->GUID(); + + // reader returns -1 when end of the file is reached + if (m_evtFileOffset != -1) { + ATH_MSG_DEBUG("ByteStream File GUID:" << m_fileGUID); + ATH_MSG_DEBUG("ByteStream Event Position in File: " << m_evtFileOffset); + + // To accomodate for skipEvents option in EventSelector + // While skipping BS event Selector does not return SUCCESS code, + // just advances silently through events. So SG content is not refreshed + // Lets do refresh of the event header here + std::string key = "ByteStreamDataHeader"; + ATH_CHECK(deleteEntry<DataHeader>(key)); + + + // Created data header element with BS provenance information + std::unique_ptr<DataHeaderElement> dataHeaderElement = makeBSProvenance(); + // Create data header itself + std::unique_ptr<DataHeader> dataHeader = std::make_unique<DataHeader>(); + // Declare header primary + dataHeader->setStatus(DataHeader::Input); + //add the data header elenebt self reference to the object vector + dataHeader->insert(*std::move(dataHeaderElement)); + + + // Clean up EventInfo from the previous event + key = m_eventInfoKey.value(); + ATH_CHECK(deleteEntry<xAOD::EventInfo>(key)); + // Now add ref to xAOD::EventInfo + std::unique_ptr<IOpaqueAddress> iopx = std::make_unique<ByteStreamAddress>( + ClassID_traits<xAOD::EventInfo>::ID(), key, ""); + ATH_CHECK(m_storeGate->recordAddress(key, iopx.release())); + const SG::DataProxy* ptmpx = m_storeGate->transientProxy( + ClassID_traits<xAOD::EventInfo>::ID(), key); + if (ptmpx != nullptr) { + DataHeaderElement element(ptmpx, 0, key); + dataHeader->insert(element); + } + + // Clean up auxiliary EventInfo from the previous event + key = m_eventInfoKey.value() + "Aux."; + ATH_CHECK(deleteEntry<xAOD::EventAuxInfo>(key)); + // Now add ref to xAOD::EventAuxInfo + std::unique_ptr<IOpaqueAddress> iopaux = std::make_unique<ByteStreamAddress>( + ClassID_traits<xAOD::EventAuxInfo>::ID(), key, ""); + ATH_CHECK(m_storeGate->recordAddress(key, iopaux.release())); + const SG::DataProxy* ptmpaux = m_storeGate->transientProxy( + ClassID_traits<xAOD::EventAuxInfo>::ID(), key); + if (ptmpaux !=0) { + DataHeaderElement element(ptmpaux, 0, key); + dataHeader->insert(element); + } + + // Record new data header.Boolean flags will allow it's deletionin case + // of skipped events. + ATH_CHECK(m_storeGate->record<DataHeader>(dataHeader.release(), + "ByteStreamDataHeader", true, false, true)); + } + return StatusCode::SUCCESS; +} + +/******************************************************************************/ +void +FaserByteStreamInputSvc::EventCache::releaseEvent() +{ + // cleanup parts of previous event and re-init them + if(rawEvent) { + rawEvent.reset(nullptr); + eventStatus = 0; + } +} + +/******************************************************************************/ +FaserByteStreamInputSvc::EventCache::~EventCache() +{ + releaseEvent(); +} + + + +/******************************************************************************/ +void +FaserByteStreamInputSvc::closeBlockIterator(bool clearMetadata) +{ + if (clearMetadata) { + ATH_MSG_WARNING("Clearing input metadata store"); + // StatusCode status = m_inputMetadata->clearStore(); + // if (!status.isSuccess()) { + // ATH_MSG_WARNING("Unable to clear Input MetaData Proxies"); + // } + } + + if (!readerReady()) { + ATH_MSG_INFO("No more events in this run, high water mark for this file = " + << m_evtOffsets.size()-1); + } + + m_reader.reset(); +} + + +/******************************************************************************/ +bool +FaserByteStreamInputSvc::setSequentialRead() +{ + // enable SequenceReading + m_reader->enableSequenceReading(); + return true; +} + +/******************************************************************************/ +bool +FaserByteStreamInputSvc::ready() const +{ + return readerReady(); +} + + +/******************************************************************************/ +std::pair<long,std::string> +FaserByteStreamInputSvc::getBlockIterator(const std::string fileName) +{ + // open the file + if(m_reader != 0) closeBlockIterator(); + + m_reader = std::unique_ptr<FaserEventStorage::DataReader>(pickFaserDataReader(fileName)); + + if(m_reader == nullptr) { + ATH_MSG_ERROR("Failed to open file " << fileName); + closeBlockIterator(); + return std::make_pair(-1,"END"); + } + + // Initilaize offset vector + m_evtOffsets.resize(m_reader->eventsInFile(), -1); + m_evtOffsets.clear(); + + m_evtInFile = 0; + + // enable sequentialReading if multiple files + if(m_sequential) { + bool test = setSequentialRead(); + if (!test) return std::make_pair(-1,"SEQ"); + } + + ATH_MSG_INFO("Picked valid file: " << m_reader->fileName()); + // initialize offsets and counters + m_evtOffsets.push_back(static_cast<long long>(m_reader->getPosition())); + return std::make_pair(m_reader->eventsInFile(), m_reader->GUID()); +} + + +//__________________________________________________________________________ +bool FaserByteStreamInputSvc::readerReady() const +{ + bool eofFlag(false); + if (m_reader!=0) eofFlag = m_reader->endOfFile(); + else { + ATH_MSG_INFO("eformat reader object not initialized"); + return false; + } + bool moreEvent = m_reader->good(); + + return (!eofFlag)&&moreEvent; +} +//__________________________________________________________________________ +void FaserByteStreamInputSvc::setEvent(void* data, unsigned int eventStatus) { + const EventContext context{ Gaudi::Hive::currentContext() }; + return setEvent( context, data, eventStatus ); +} + +void FaserByteStreamInputSvc::setEvent( const EventContext& context, void* data, unsigned int eventStatus ) +{ + ATH_MSG_DEBUG("FaserByteStreamInputSvc::setEvent() called"); + + EventCache* cache = m_eventsCache.get( context ); + cache->releaseEvent(); + + EventFull* event = reinterpret_cast<EventFull*>(data); + cache->rawEvent.reset(event); + cache->eventStatus = eventStatus; + + // Set it for the data provider + m_robProvider->setNextEvent(context, reinterpret_cast<const RawEvent*>(cache->rawEvent.get()) ); + m_robProvider->setEventStatus(context, cache->eventStatus ); + + // Build a DH for use by other components + StatusCode rec_sg = generateDataHeader(); + if (rec_sg != StatusCode::SUCCESS) { + ATH_MSG_ERROR("Fail to record BS DataHeader in StoreGate. Skipping events?! " << rec_sg); + } +} +//__________________________________________________________________________ +const EventFull* FaserByteStreamInputSvc::currentEvent() const { + const EventContext context{ Gaudi::Hive::currentContext() }; + return m_eventsCache.get(context)->rawEvent.get(); +} +//__________________________________________________________________________ +unsigned int FaserByteStreamInputSvc::currentEventStatus() const { + const EventContext context{ Gaudi::Hive::currentContext() }; + return m_eventsCache.get(context)->eventStatus; +} +//________________________________________________________________________________ +StatusCode FaserByteStreamInputSvc::queryInterface(const InterfaceID& riid, void** ppvInterface) { + if (ByteStreamInputSvc::interfaceID().versionMatch(riid)) { + *ppvInterface = dynamic_cast<ByteStreamInputSvc*>(this); + } else { + // Interface is not directly available: try out a base class + return(::AthService::queryInterface(riid, ppvInterface)); + } + addRef(); + return(StatusCode::SUCCESS); +} + + +std::unique_ptr<DataHeaderElement> +FaserByteStreamInputSvc::makeBSProvenance() const +{ + std::unique_ptr<Token> token = std::make_unique<Token>(); + token->setDb(m_fileGUID); + token->setTechnology(0x00001000); + token->setOid(Token::OID_t(0LL, m_evtFileOffset)); + + // note: passing ownership of token to DataHeaderElement + return std::make_unique<DataHeaderElement>(ClassID_traits<DataHeader>::ID(), + "StreamRAW", token.release()); +} + diff --git a/Event/FaserByteStreamCnvSvc/src/FaserByteStreamInputSvc.h b/Event/FaserByteStreamCnvSvc/src/FaserByteStreamInputSvc.h new file mode 100644 index 0000000000000000000000000000000000000000..00efecd0ad4c90e40901a544f05409e883876a1c --- /dev/null +++ b/Event/FaserByteStreamCnvSvc/src/FaserByteStreamInputSvc.h @@ -0,0 +1,135 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef FASERBYTESTREAMINPUTSVC_H +#define FASERBYTESTREAMINPUTSVC_H + +/** @file FaserByteStreaInputSvc.h + * @brief This file contains the class definition for the FaserByteStreamInputSvc class. + * @author Eric Torrence <torrence@uoregon.edu> + **/ + +// Originally copied from ByteStreamEventStorageInputSvc + +// Include files. +#include "FaserByteStreamCnvSvc/ByteStreamInputSvc.h" +#include "ByteStreamCnvSvcBase/IROBDataProviderSvc.h" +#include "AthenaKernel/SlotSpecificObj.h" +#include "FaserEventStorage/DataReader.h" + +// Do I want to try to update this? It looks like it is only used +// here and in the detector-specific code. Lets try without it. +//#include "ByteStreamData/RawEvent.h" + +// FrameWork includes +#include "GaudiKernel/ServiceHandle.h" + +//#include "EventFormats/DAQFormats.hpp" + +//typedef DAQFormats::EventFull RawEvent; +namespace DAQFormats { + class EventFull; +} +class StoreGateSvc; +class DataHeaderElement; + +/** @class ByteStreamFaserInputSvc + * @brief This class is the ByteStreamInputSvc for reading events written by Faser. + **/ +class FaserByteStreamInputSvc : public ByteStreamInputSvc { + +public: + /// Constructors: + FaserByteStreamInputSvc(const std::string& name, ISvcLocator* svcloc); + + /// Destructor. + virtual ~FaserByteStreamInputSvc(); + + /// Required of all Gaudi Services + virtual StatusCode initialize(); + virtual StatusCode stop(); + /// Required of all Gaudi Services + virtual StatusCode finalize(); + + /// Required of all Gaudi services: see Gaudi documentation for details + StatusCode queryInterface(const InterfaceID& riid, void** ppvInterface); + + /// Implementation of the ByteStreamInputSvc interface methods. + virtual const DAQFormats::EventFull* currentEvent() const; + virtual const DAQFormats::EventFull* nextEvent(); //!< ++, new + virtual const DAQFormats::EventFull* previousEvent(); //!< --, old + virtual void setEvent(void* data, unsigned int eventStatus); + + /// Return the current event status + virtual unsigned int currentEventStatus() const; + virtual void validateEvent(); + + + virtual long positionInBlock(); + virtual std::pair<long,std::string> getBlockIterator(const std::string fileName); + void closeBlockIterator(bool clearMetadata=true); + bool setSequentialRead(); + bool ready() const; + StatusCode generateDataHeader(); + +private: // data + std::mutex m_readerMutex; + + struct EventCache { + std::unique_ptr<DAQFormats::EventFull> rawEvent = NULL; + //DAQFormats::EventFull* rawEvent = 0; //!< current event + unsigned int eventStatus = 0; //!< check_tree() status of the current event + long long int eventOffset = 0; //!< event offset within a file, can be -1 + void releaseEvent(); //!< deletes event + virtual ~EventCache(); //!< calls releaseEvent + }; + + SG::SlotSpecificObj<EventCache> m_eventsCache; + std::unique_ptr<FaserEventStorage::DataReader> m_reader; //!< DataReader from EventStorage + + mutable std::vector<long long int> m_evtOffsets; //!< offset for event i in that file + unsigned int m_evtInFile; + long long int m_evtFileOffset = 0; //!< last read in event offset within a file, can be -1 + // Event back navigation info + std::string m_fileGUID; //!< current file GUID + + +private: // properties + ServiceHandle<StoreGateSvc> m_storeGate; //!< StoreGateSvc + //ServiceHandle<StoreGateSvc> m_inputMetadata; //!< StoreGateSvc + ServiceHandle<IROBDataProviderSvc> m_robProvider; + + + Gaudi::Property<bool> m_sequential; //!< enable sequential reading. + Gaudi::Property<bool> m_dump; + Gaudi::Property<float> m_wait; + Gaudi::Property<bool> m_valEvent; + Gaudi::Property<std::string> m_eventInfoKey; + +private: // internal helper functions + + // void buildFragment( EventCache* cache, void* data, uint32_t eventSize, bool validate ) const; + void buildEvent( EventCache* cache, DAQFormats::EventFull* theEvent, bool validate ) const; + bool readerReady() const; + unsigned validateEvent( const DAQFormats::EventFull* rawEvent ) const; + void setEvent( const EventContext& context, void* data, unsigned int eventStatus ); + + enum Advance{ PREVIOUS = -1, NEXT = 1 }; + const DAQFormats::EventFull* getEvent( Advance step ); + std::unique_ptr<DataHeaderElement> makeBSProvenance() const; + + + template<typename T> + StatusCode deleteEntry(const std::string& key) + { + if (m_storeGate->contains<T>(key)) { + const T* tmp = m_storeGate->tryConstRetrieve<T>(key); + if (tmp != nullptr) ATH_CHECK(m_storeGate->remove<T>(tmp)); + } + return StatusCode::SUCCESS; + } + +}; + +#endif diff --git a/Event/FaserByteStreamCnvSvc/src/FaserEventContextByteStream.cxx b/Event/FaserByteStreamCnvSvc/src/FaserEventContextByteStream.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f7d24aa9da7b410293a453fa2238864ce28a09ac --- /dev/null +++ b/Event/FaserByteStreamCnvSvc/src/FaserEventContextByteStream.cxx @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +/** @file FaserEventContextByteStream.cxx + * @brief This file contains the implementation for the FaserEventContextByteStream class. + * @author Peter van Gemmeren <gemmeren@bnl.gov> + * @author Hong Ma <hma@bnl.gov> + **/ + +#include "FaserEventContextByteStream.h" + +//________________________________________________________________________________ +FaserEventContextByteStream::FaserEventContextByteStream(const IEvtSelector* selector) : m_evtSelector(selector) { +} +//________________________________________________________________________________ +FaserEventContextByteStream::FaserEventContextByteStream(const FaserEventContextByteStream& ctxt) : IEvtSelector::Context(), + m_evtSelector(ctxt.m_evtSelector) { +} +//________________________________________________________________________________ +FaserEventContextByteStream::~FaserEventContextByteStream() { +} +//________________________________________________________________________________ +void* FaserEventContextByteStream::identifier() const { + return((void*)(m_evtSelector)); +} diff --git a/Event/FaserByteStreamCnvSvc/src/FaserEventContextByteStream.h b/Event/FaserByteStreamCnvSvc/src/FaserEventContextByteStream.h new file mode 100644 index 0000000000000000000000000000000000000000..7e277a1bc550de3c982160cd486914963f76ee8f --- /dev/null +++ b/Event/FaserByteStreamCnvSvc/src/FaserEventContextByteStream.h @@ -0,0 +1,38 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef EVENTCONTEXTBYTESTREAM_H +#define EVENTCONTEXTBYTESTREAM_H + +/** @file EventContextByteStream.h + * @brief This file contains the class definition for the EventContextByteStream class. + * @author Hong Ma <hma@bnl.gov> + **/ + +#include "GaudiKernel/IEvtSelector.h" + +class FaserEventSelectorByteStream; +class IOpaqueAddress; + +/** @class FaserEventContextByteStream + * @brief This class provides the Context for EventSelectorByteStream + **/ +class FaserEventContextByteStream : virtual public IEvtSelector::Context { + + public: + /// Constructor + FaserEventContextByteStream(const IEvtSelector* selector); + /// Copy constructor + FaserEventContextByteStream(const FaserEventContextByteStream& ctxt); + /// Destructor + virtual ~FaserEventContextByteStream(); + + /// Inequality operator. + virtual void* identifier() const; + + private: + const IEvtSelector* m_evtSelector; +}; + +#endif diff --git a/Event/FaserByteStreamCnvSvc/src/FaserEventSelectorByteStream.cxx b/Event/FaserByteStreamCnvSvc/src/FaserEventSelectorByteStream.cxx new file mode 100644 index 0000000000000000000000000000000000000000..6311fc550e8c4063b4fa4d15828481afccb2748a --- /dev/null +++ b/Event/FaserByteStreamCnvSvc/src/FaserEventSelectorByteStream.cxx @@ -0,0 +1,1041 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +//==================================================================== +// FaserEventSelectorByteStream.cxx +//==================================================================== +// +// Include files. +#include "FaserEventSelectorByteStream.h" +#include "FaserEventContextByteStream.h" +#include "FaserByteStreamInputSvc.h" +#include "FaserByteStreamCnvSvc/ByteStreamExceptions.h" +#include "ByteStreamCnvSvcBase/ByteStreamAddress.h" + +#include "GaudiKernel/ClassID.h" +#include "GaudiKernel/FileIncident.h" +#include "GaudiKernel/IIncidentSvc.h" +#include "GaudiKernel/IIoComponentMgr.h" +#include "GaudiKernel/IJobOptionsSvc.h" + +#include "AthenaKernel/IAthenaIPCTool.h" +#include "EventInfo/EventInfo.h" +#include "StoreGate/StoreGate.h" + +// EventInfoAttributeList includes +#include "AthenaPoolUtilities/AthenaAttributeList.h" +#include "EventInfo/TriggerInfo.h" +#include "PersistentDataModel/DataHeader.h" +#include "eformat/StreamTag.h" + +#include <vector> +#include <algorithm> + +using DAQFormats::EventFull; + +// Constructor. +FaserEventSelectorByteStream::FaserEventSelectorByteStream(const std::string& name, ISvcLocator* svcloc) : ::AthService(name, svcloc), + m_fileCount(0), + m_beginIter(0), + m_endIter(0), + m_eventSource(0), + m_incidentSvc("IncidentSvc", name), + m_evtStore( "StoreGateSvc", name ), + m_firstFileFired(false), + m_beginFileFired(false), + m_inputCollectionsFromIS(false), + m_NumEvents(0), + m_eventStreamingTool("", this), + m_helperTools(this), + m_counterTool("", this) { + declareProperty("ByteStreamInputSvc", m_eventSourceName); + declareProperty("Input", m_inputCollectionsProp); + declareProperty("MaxBadEvents", m_maxBadEvts = -1); + declareProperty("ProcessBadEvent", m_procBadEvent = false); + declareProperty("SkipEvents", m_SkipEvents = 0); + declareProperty("SkipEventSequence", m_skipEventSequenceProp); + + declareProperty("HelperTools", m_helperTools); + declareProperty("CounterTool", m_counterTool); + declareProperty("SharedMemoryTool", m_eventStreamingTool); + + // RunNumber, OldRunNumber and OverrideRunNumberFromInput are used + // to override the run number coming in on the input stream + declareProperty("RunNumber", m_runNo = 0); + m_runNo.verifier().setLower(0); + // The following properties are only for compatibility with + // McEventSelector and are not really used anywhere + declareProperty("EventsPerRun", m_eventsPerRun = 1000000); + m_eventsPerRun.verifier().setLower(0); + declareProperty("FirstEvent", m_firstEventNo = 0); + m_firstEventNo.verifier().setLower(0); + declareProperty("FirstLB", m_firstLBNo = 0); + m_firstLBNo.verifier().setLower(0); + declareProperty("EventsPerLB", m_eventsPerLB = 1000); + m_eventsPerLB.verifier().setLower(0); + declareProperty("InitialTimeStamp", m_initTimeStamp = 0); + m_initTimeStamp.verifier().setLower(0); + declareProperty("TimeStampInterval", m_timeStampInterval = 0); + declareProperty("OverrideRunNumber", m_overrideRunNumber = false); + declareProperty("OverrideEventNumber", m_overrideEventNumber = false); + declareProperty("OverrideTimeStamp", m_overrideTimeStamp = false); + declareProperty("FileBased", m_filebased = true); + + m_inputCollectionsProp.declareUpdateHandler(&FaserEventSelectorByteStream::inputCollectionsHandler, this); +} +//________________________________________________________________________________ +void FaserEventSelectorByteStream::inputCollectionsHandler(Property&) { + if (this->FSMState() != Gaudi::StateMachine::OFFLINE) { + this->reinit().ignore(); + } +} +//________________________________________________________________________________ +FaserEventSelectorByteStream::~FaserEventSelectorByteStream() { +} +//________________________________________________________________________________ +StatusCode FaserEventSelectorByteStream::initialize() { + ATH_MSG_INFO("Initializing " << name() << " - package version " << PACKAGE_VERSION); + if (!::AthService::initialize().isSuccess()) { + ATH_MSG_FATAL("Cannot initialize AthService base class."); + return(StatusCode::FAILURE); + } + + // Check for input setting + if (m_filebased && m_inputCollectionsProp.value().size() == 0) { + ATH_MSG_WARNING("InputCollections not properly set, checking EventStorageInputSvc properties"); + ServiceHandle<IJobOptionsSvc> joSvc("JobOptionsSvc", name()); + bool retrieve(false); + if (!joSvc.retrieve().isSuccess()) { + ATH_MSG_FATAL("Cannot get JobOptionsSvc."); + } else { + // Check if FullFileName is set in the InputSvc + typedef std::vector<const Property*> Properties_t; + const Properties_t* esProps = joSvc->getProperties("ByteStreamInputSvc"); + std::vector<const Property*>::const_iterator ii = esProps->begin(); + if (esProps != 0) { + while (ii != esProps->end()) { + if ((*ii)->name() == "FullFileName") { + StringArrayProperty temp; + if ((*ii)->load(temp)) { + retrieve = true; + m_inputCollectionsProp.assign(temp); + m_inputCollectionsFromIS = true; + ATH_MSG_INFO("Retrieved InputCollections from InputSvc"); + } + } + if ((*ii)->name() == "EventStore") { + StringProperty temp2; + if ((*ii)->load(temp2)) { + m_evtStore = ServiceHandle<StoreGateSvc>(temp2.value(),this->name()); + ATH_MSG_INFO("Retrieved StoreGateSvc name of " << temp2); + } + } + ++ii; + } + } else { + ATH_MSG_WARNING("Did not find InputSvc jobOptions properties"); + } + } + if (!retrieve) { + ATH_MSG_FATAL("Unable to retrieve valid input list"); + return(StatusCode::FAILURE); + } + } + m_skipEventSequence = m_skipEventSequenceProp.value(); + std::sort(m_skipEventSequence.begin(), m_skipEventSequence.end()); + + // Check ByteStreamCnvSvc + IService* svc; + if (!serviceLocator()->getService(m_eventSourceName, svc).isSuccess()) { + ATH_MSG_FATAL("Cannot get ByteStreamInputSvc"); + return(StatusCode::FAILURE); + } + m_eventSource = dynamic_cast<FaserByteStreamInputSvc*>(svc); + if (m_eventSource == 0) { + ATH_MSG_FATAL("Cannot cast ByteStreamInputSvc"); + return(StatusCode::FAILURE); + } + m_eventSource->addRef(); + if (!m_evtStore.retrieve().isSuccess()) { + ATH_MSG_FATAL("Cannot get StoreGateSvc"); + return(StatusCode::FAILURE); + } + + // Get CounterTool (if configured) + if (!m_counterTool.empty()) { + if (!m_counterTool.retrieve().isSuccess()) { + ATH_MSG_FATAL("Cannot get CounterTool."); + return(StatusCode::FAILURE); + } + } + // Get HelperTools + if (!m_helperTools.empty()) { + if (!m_helperTools.retrieve().isSuccess()) { + ATH_MSG_FATAL("Cannot get " << m_helperTools); + return(StatusCode::FAILURE); + } + } + // Get SharedMemoryTool (if configured) + if (!m_eventStreamingTool.empty() && !m_eventStreamingTool.retrieve().isSuccess()) { + ATH_MSG_FATAL("Cannot get AthenaSharedMemoryTool"); + return(StatusCode::FAILURE); + } + + // Register this service for 'I/O' events + ServiceHandle<IIoComponentMgr> iomgr("IoComponentMgr", name()); + if (!iomgr.retrieve().isSuccess()) { + ATH_MSG_FATAL("Cannot retrieve IoComponentMgr."); + return(StatusCode::FAILURE); + } + if (!iomgr->io_register(this).isSuccess()) { + ATH_MSG_FATAL("Cannot register myself with the IoComponentMgr."); + return(StatusCode::FAILURE); + } + + // Register the input files with the iomgr + bool allGood = true; + const std::vector<std::string>& incol = m_inputCollectionsProp.value(); + for (std::size_t icol = 0, imax = incol.size(); icol != imax; ++icol) { + if (!iomgr->io_register(this, IIoComponentMgr::IoMode::READ, incol[icol]).isSuccess()) { + ATH_MSG_FATAL("could not register [" << incol[icol] << "] for output !"); + allGood = false; + } else { + ATH_MSG_VERBOSE("io_register[" << this->name() << "](" << incol[icol] << ") [ok]"); + } + } + if (!allGood) { + return(StatusCode::FAILURE); + } + + // For backward compatibility, check InputSvc properties for bad events + ServiceHandle<IJobOptionsSvc> joSvc("JobOptionsSvc", name()); + if (!joSvc.retrieve().isSuccess()) { + ATH_MSG_FATAL("Cannot get JobOptionsSvc."); + return(StatusCode::FAILURE); + } + typedef std::vector<const Property*> Properties_t; + const Properties_t* esProps = joSvc->getProperties("ByteStreamInputSvc"); + if (esProps != 0) { + std::vector<const Property*>::const_iterator ii = esProps->begin(); + while (ii != esProps->end()) { + IntegerProperty temp; + if ((*ii)->name() == "MaxBadEvents") { // find it + if ((*ii)->load(temp)) { // load it + if (temp.value() != -1) { // check if it is set + m_maxBadEvts = temp.value(); + ATH_MSG_INFO("Retrieved MaxBadEvents=" << m_maxBadEvts << " from ByteStreamInputSvc"); + } + } + } + BooleanProperty temp2; + if ((*ii)->name() == "ProcessBadEvents") { // find it + if ((*ii)->load(temp)) { // load it + if (temp.value()) { // check if it is set + m_procBadEvent = temp.value(); + ATH_MSG_INFO("Retrieved ProcessBadEvents=" << m_procBadEvent << " from ByteStreamInputSvc"); + } + } + } + ++ii; + } + } else { + ATH_MSG_WARNING("Did not find ByteStreamInputSvc jobOptions properties"); + } + + // Must happen before trying to open a file + StatusCode risc = this->reinit(); + + return risc; +} +//__________________________________________________________________________ +StatusCode FaserEventSelectorByteStream::reinit() { + ATH_MSG_INFO("reinitialization..."); + // reset markers + if (m_inputCollectionsProp.value().size()>0) { + m_numEvt.resize(m_inputCollectionsProp.value().size(), -1); + m_firstEvt.resize(m_inputCollectionsProp.value().size(), -1); + } + else { + m_numEvt.resize(1); + m_firstEvt.resize(1); + } + + // Initialize InputCollectionsIterator + m_inputCollectionsIterator = m_inputCollectionsProp.value().begin(); + m_NumEvents = 0; + bool retError = false; + if (!m_helperTools.empty()) { + for (std::vector<ToolHandle<IAthenaSelectorTool> >::iterator iter = m_helperTools.begin(), + last = m_helperTools.end(); iter != last; iter++) { + if (!(*iter)->postInitialize().isSuccess()) { + ATH_MSG_FATAL("Failed to postInitialize() " << (*iter)->name()); + retError = true; + } + } + } + if (retError) { + ATH_MSG_FATAL("Failed to postInitialize() helperTools"); + return(StatusCode::FAILURE); + } + return(StatusCode::SUCCESS); +} + +//________________________________________________________________________________ +StatusCode FaserEventSelectorByteStream::start() { + ATH_MSG_DEBUG("Calling FaserEventSelectorByteStream::start()"); + // If file based input then fire appropriate incidents + if (m_filebased) { + if (!m_firstFileFired) { + FileIncident firstInputFileIncident(name(), "FirstInputFile", "BSF:" + *m_inputCollectionsIterator); + m_incidentSvc->fireIncident(firstInputFileIncident); + m_firstFileFired = true; + } + + // try to open a file + if (this->openNewRun().isFailure()) { + ATH_MSG_FATAL("Unable to open any file in initialize"); + return(StatusCode::FAILURE); + } + // should be in openNewRun, but see comment there + m_beginFileFired = true; + } + + // Create the begin and end iterator's for this selector. + m_beginIter = new FaserEventContextByteStream(this); + // Increment to get the new event in. + m_endIter = new FaserEventContextByteStream(0); + + return(StatusCode::SUCCESS); +} + +//________________________________________________________________________________ +StatusCode FaserEventSelectorByteStream::stop() { + ATH_MSG_DEBUG("Calling FaserEventSelectorByteStream::stop()"); + // Handle open files + if (m_filebased) { + // Close the file + if (m_eventSource->ready()) { + m_eventSource->closeBlockIterator(false); + FileIncident endInputFileIncident(name(), "EndInputFile", "stop"); + m_incidentSvc->fireIncident(endInputFileIncident); + } + // Fire LastInputFile incident + FileIncident lastInputFileIncident(name(), "LastInputFile", "stop"); + m_incidentSvc->fireIncident(lastInputFileIncident); + } + return(StatusCode::SUCCESS); +} + +//__________________________________________________________________________ +StatusCode FaserEventSelectorByteStream::finalize() { + if (!m_counterTool.empty()) { + if (!m_counterTool->preFinalize().isSuccess()) { + ATH_MSG_WARNING("Failed to preFinalize() CounterTool"); + } + } + for (std::vector<ToolHandle<IAthenaSelectorTool> >::iterator iter = m_helperTools.begin(), + last = m_helperTools.end(); iter != last; iter++) { + if (!(*iter)->preFinalize().isSuccess()) { + ATH_MSG_WARNING("Failed to preFinalize() " << (*iter)->name()); + } + } + delete m_beginIter; m_beginIter = 0; + delete m_endIter; m_endIter = 0; + // Release AthenaSharedMemoryTool + if (!m_eventStreamingTool.empty() && !m_eventStreamingTool.release().isSuccess()) { + ATH_MSG_WARNING("Cannot release AthenaSharedMemoryTool"); + } + // Release CounterTool + if (!m_counterTool.empty()) { + if (!m_counterTool.release().isSuccess()) { + ATH_MSG_WARNING("Cannot release CounterTool."); + } + } + // Release HelperTools + if (!m_helperTools.release().isSuccess()) { + ATH_MSG_WARNING("Cannot release " << m_helperTools); + } + if (m_eventSource) m_eventSource->release(); + // Finalize the Service base class. + return(AthService::finalize()); +} + +void FaserEventSelectorByteStream::nextFile() const { + ATH_MSG_DEBUG("nextFile() called"); + FileIncident endInputFileIncident(name(), "EndInputFile", "BSF:" + *m_inputCollectionsIterator); + m_incidentSvc->fireIncident(endInputFileIncident); + ++m_inputCollectionsIterator; + ++m_fileCount; +} + +StatusCode FaserEventSelectorByteStream::openNewRun() const { + ATH_MSG_DEBUG("openNewRun() called"); + // Should be protected upstream, but this is further protection + if (!m_filebased) { + ATH_MSG_ERROR("cannot open new run for non-filebased inputs"); + return(StatusCode::FAILURE); + } + // Check for end of file list + if (m_inputCollectionsIterator == m_inputCollectionsProp.value().end()) { + ATH_MSG_INFO("End of input file list reached"); + return(StatusCode::FAILURE); + } + std::string blockname = *m_inputCollectionsIterator; + // try to open a file, if failure go to next FIXME: PVG: silient failure? + //long nev = m_eventSource->getBlockIterator(blockname); + auto nevguid = m_eventSource->getBlockIterator(blockname); + long nev = nevguid.first; + if (nev == -1) { + ATH_MSG_FATAL("Unable to access file " << *m_inputCollectionsIterator << ", stopping here"); + throw ByteStreamExceptions::fileAccessError(); + } + // Fire the incident + if (!m_beginFileFired) { + FileIncident beginInputFileIncident(name(), "BeginInputFile", "BSF:" + *m_inputCollectionsIterator,nevguid.second); + m_incidentSvc->fireIncident(beginInputFileIncident); + //m_beginFileFired = true; // Should go here, but can't because IEvtSelector next is const + } + + // check if file is empty + if (nev == 0) { + ATH_MSG_WARNING("no events in file " << blockname << " try next"); + if (m_eventSource->ready()) m_eventSource->closeBlockIterator(true); + this->nextFile(); + return openNewRun(); + // check if skipping all events in that file (minus events already skipped) + } else if (m_SkipEvents - m_NumEvents > nev) { + ATH_MSG_WARNING("skipping more events " << m_SkipEvents-m_NumEvents << "(" << nev <<") than in file " << *m_inputCollectionsIterator << ", try next"); + m_NumEvents += nev; + m_numEvt[m_fileCount] = nev; + if (m_eventSource->ready()) m_eventSource->closeBlockIterator(true); + this->nextFile(); + return openNewRun(); + } + + ATH_MSG_DEBUG("Opened block/file " << blockname); + m_firstEvt[m_fileCount] = m_NumEvents; + m_numEvt[m_fileCount] = nev; + + return(StatusCode::SUCCESS); +} + +StatusCode FaserEventSelectorByteStream::createContext(IEvtSelector::Context*& it) const { + it = new FaserEventContextByteStream(this); + return(StatusCode::SUCCESS); +} + +StatusCode FaserEventSelectorByteStream::next(IEvtSelector::Context& it) const { + + static int n_bad_events = 0; // cross loop counter of bad events + // Check if this is an athenaMP client process + if (!m_eventStreamingTool.empty() && m_eventStreamingTool->isClient()) { + ATH_MSG_DEBUG("FaserEventSelectorByteStream::next() called for MT"); + void* source = 0; + unsigned int status = 0; + if (!m_eventStreamingTool->getLockedEvent(&source, status).isSuccess()) { + ATH_MSG_FATAL("Cannot get NextEvent from AthenaSharedMemoryTool"); + return(StatusCode::FAILURE); + } + m_eventSource->setEvent(static_cast<char*>(source), status); + return(StatusCode::SUCCESS); + } + + ATH_MSG_DEBUG("FaserEventSelectorByteStream::next() called for non-MT"); + + // Call all selector tool preNext before starting loop + for (std::vector<ToolHandle<IAthenaSelectorTool> >::const_iterator iter = m_helperTools.begin(), + last = m_helperTools.end(); iter != last; iter++) { + if (!(*iter)->preNext().isSuccess()) { + ATH_MSG_WARNING("Failed to preNext() " << (*iter)->name()); + } + } + if (!m_counterTool.empty()) { + if (!m_counterTool->preNext().isSuccess()) { + ATH_MSG_WARNING("Failed to preNext() CounterTool."); + } + } + // Find an event to return + for (;;) { + const EventFull* pre = 0; + bool badEvent(false); + // if event source not ready from init, try next file + if (m_filebased && !m_eventSource->ready()) { + // next file + this->nextFile(); + if (this->openNewRun().isFailure()) { + ATH_MSG_DEBUG("Event source found no more valid files left in input list"); + m_NumEvents = -1; + return StatusCode::FAILURE; + } + } + try { + ATH_MSG_DEBUG("Call eventSource->nextEvent()"); + pre = m_eventSource->nextEvent(); + } + catch (const ByteStreamExceptions::readError&) { + ATH_MSG_FATAL("Caught ByteStreamExceptions::readError"); + return StatusCode::FAILURE; + } + catch (const ByteStreamExceptions::badFragment&) { + ATH_MSG_ERROR("badFragment encountered"); + badEvent = true; + } + catch (const ByteStreamExceptions::badFragmentData&) { + ATH_MSG_ERROR("badFragment data encountered"); + badEvent = true; + } + // Check whether a RawEvent has actually been provided + if (pre == 0) { + ATH_MSG_INFO("No event built"); + it = *m_endIter; + return(StatusCode::FAILURE); + } + + // increment that an event was found + ++m_NumEvents; + + // check bad event flag and handle as configured + if (badEvent) { + ++n_bad_events; + ATH_MSG_INFO("Bad event encountered, current count at " << n_bad_events); + bool toomany = (m_maxBadEvts >= 0 && n_bad_events > m_maxBadEvts); + if (toomany) {ATH_MSG_FATAL("too many bad events ");} + if (!m_procBadEvent || toomany) { + // End of file + it = *m_endIter; + return(StatusCode::FAILURE); + } + ATH_MSG_WARNING("Continue with bad event"); + } + + // Build a DH for use by other components + StatusCode rec_sg = m_eventSource->generateDataHeader(); + if (rec_sg != StatusCode::SUCCESS) { + ATH_MSG_ERROR("Fail to record BS DataHeader in StoreGate. Skipping events?! " << rec_sg); + } + + // Check whether properties or tools reject this event + if ( m_NumEvents > m_SkipEvents && + (m_skipEventSequence.empty() || m_NumEvents != m_skipEventSequence.front()) ) { + StatusCode status(StatusCode::SUCCESS); + // Build event info attribute list + ATH_MSG_DEBUG("FaserEventSelectorByteStream::next() calling buildEventAttributeList()"); + if (buildEventAttributeList().isFailure()) ATH_MSG_WARNING("Unable to build event info att list"); + for (std::vector<ToolHandle<IAthenaSelectorTool> >::const_iterator iter = m_helperTools.begin(), + last = m_helperTools.end(); iter != last; iter++) { + StatusCode toolStatus = (*iter)->postNext(); + if (toolStatus.isRecoverable()) { + ATH_MSG_INFO("Request skipping event from: " << (*iter)->name()); + status = StatusCode::RECOVERABLE; + } else if (toolStatus.isFailure()) { + ATH_MSG_WARNING("Failed to postNext() " << (*iter)->name()); + status = StatusCode::FAILURE; + } + } + if (status.isRecoverable()) { + ATH_MSG_INFO("skipping event " << m_NumEvents); + } else if (status.isFailure()) { + ATH_MSG_WARNING("Failed to postNext() HelperTool."); + } else { + if (!m_counterTool.empty()) { + if (!m_counterTool->postNext().isSuccess()) { + ATH_MSG_WARNING("Failed to postNext() CounterTool."); + } + } + break; + } + + ATH_MSG_DEBUG("FaserEventSelectorByteStream::next() calling eventSource->validateEvent()"); + // Validate the event + try { + m_eventSource->validateEvent(); + } + catch (const ByteStreamExceptions::badFragmentData&) { + ATH_MSG_ERROR("badFragment data encountered"); + + ++n_bad_events; + ATH_MSG_INFO("Bad event encountered, current count at " << n_bad_events); + + bool toomany = (m_maxBadEvts >= 0 && n_bad_events > m_maxBadEvts); + if (toomany) {ATH_MSG_FATAL("too many bad events ");} + if (!m_procBadEvent || toomany) { + // End of file + it = *m_endIter; + return(StatusCode::FAILURE); + } + ATH_MSG_WARNING("Continue with bad event"); + } + } else { + if (!m_skipEventSequence.empty() && m_NumEvents == m_skipEventSequence.front()) { + m_skipEventSequence.erase(m_skipEventSequence.begin()); + } + ATH_MSG_DEBUG("Skipping event " << m_NumEvents - 1); + } + } // for loop + ATH_MSG_DEBUG("FaserEventSelectorByteStream::next() done"); + return(StatusCode::SUCCESS); +} + +//________________________________________________________________________________ +StatusCode FaserEventSelectorByteStream::next(IEvtSelector::Context& ctxt, int jump) const { + if (jump > 0) { + if ( m_NumEvents+jump != m_SkipEvents) { + // Save initial event count + unsigned int cntr = m_NumEvents; + // In case NumEvents increments multiple times in a single next call + while (m_NumEvents+1 <= cntr + jump) { + if (!next(ctxt).isSuccess()) { + return(StatusCode::FAILURE); + } + } + } + else ATH_MSG_DEBUG("Jump covered by skip event " << m_SkipEvents); + return(StatusCode::SUCCESS); + } + else { + ATH_MSG_WARNING("Called jump next with non-multiple jump"); + } + return(StatusCode::SUCCESS); +} +//________________________________________________________________________________ +StatusCode FaserEventSelectorByteStream::previous(IEvtSelector::Context& /*ctxt*/) const { + ATH_MSG_DEBUG(" ... previous"); + const EventFull* pre = 0; + bool badEvent(false); + // if event source not ready from init, try next file + if (m_eventSource->ready()) { + try { + pre = m_eventSource->previousEvent(); + } + catch (const ByteStreamExceptions::readError&) { + ATH_MSG_FATAL("Caught ByteStreamExceptions::readError"); + return StatusCode::FAILURE; + } + catch (const ByteStreamExceptions::badFragment&) { + ATH_MSG_ERROR("badFragment encountered"); + badEvent = true; + } + catch (const ByteStreamExceptions::badFragmentData&) { + ATH_MSG_ERROR("badFragment data encountered"); + badEvent = true; + } + // Check whether a RawEvent has actually been provided + if (pre == 0) { + ATH_MSG_ERROR("No event built"); + //it = *m_endIter; + return(StatusCode::FAILURE); + } + } + else { + ATH_MSG_FATAL("Attempt to read previous data on invalid reader"); + return(StatusCode::FAILURE); + } + // increment that an event was found + //++m_NumEvents; + + // check bad event flag and handle as configured + if (badEvent) { + ATH_MSG_ERROR("Called previous for bad event"); + if (!m_procBadEvent) { + // End of file + //it = *m_endIter; + return(StatusCode::FAILURE); + } + ATH_MSG_WARNING("Continue with bad event"); + } + + // Build a DH for use by other components + StatusCode rec_sg = m_eventSource->generateDataHeader(); + if (rec_sg != StatusCode::SUCCESS) { + ATH_MSG_ERROR("Fail to record BS DataHeader in StoreGate. Skipping events?! " << rec_sg); + } + + return StatusCode::SUCCESS; +} +//________________________________________________________________________________ +StatusCode FaserEventSelectorByteStream::previous(IEvtSelector::Context& ctxt, int jump) const { + if (jump > 0) { + for (int i = 0; i < jump; i++) { + if (!previous(ctxt).isSuccess()) { + return(StatusCode::FAILURE); + } + } + return(StatusCode::SUCCESS); + } + return(StatusCode::FAILURE); +} +//________________________________________________________________________________ +StatusCode FaserEventSelectorByteStream::last(IEvtSelector::Context& it)const { + if (it.identifier() == m_endIter->identifier()) { + ATH_MSG_DEBUG("last(): Last event in InputStream."); + return(StatusCode::SUCCESS); + } + return(StatusCode::FAILURE); +} +//________________________________________________________________________________ +StatusCode FaserEventSelectorByteStream::rewind(IEvtSelector::Context& /*it*/) const { + ATH_MSG_ERROR("rewind() not implemented"); + return(StatusCode::FAILURE); +} + +//________________________________________________________________________________ +StatusCode FaserEventSelectorByteStream::resetCriteria(const std::string& /*criteria*/, IEvtSelector::Context& /*ctxt*/) const { + return(StatusCode::SUCCESS); +} + +//__________________________________________________________________________ +StatusCode FaserEventSelectorByteStream::seek(Context& it, int evtNum) const { + // Check that input is seekable + if (!m_filebased) { + ATH_MSG_ERROR("Input not seekable, choose different input svc"); + return StatusCode::FAILURE; + } + // find the file index with that event + long fileNum = findEvent(evtNum); + if (fileNum == -1 && evtNum >= m_firstEvt[m_fileCount] && evtNum < m_NumEvents) { + fileNum = m_fileCount; + } + // if unable to locate file, exit + if (fileNum == -1) { + ATH_MSG_INFO("seek: Reached end of Input."); + return(StatusCode::RECOVERABLE); + } + // check if it is the current file + if (fileNum != m_fileCount) { // event in different file + // Close input file if open + if (m_eventSource->ready()) m_eventSource->closeBlockIterator(true); + ATH_MSG_DEBUG("Seek to item: \"" << m_inputCollectionsProp.value()[fileNum] << "\" from the explicit file list."); + std::string fileName = m_inputCollectionsProp.value()[fileNum]; + m_fileCount = fileNum; + // Open the correct file + auto nevguid = m_eventSource->getBlockIterator(fileName); + long nev = nevguid.first; + if (nev == -1) { + ATH_MSG_FATAL("Unable to open file with seeked event " << evtNum << " file " << fileName); + return StatusCode::FAILURE; + } + int delta = evtNum - m_firstEvt[m_fileCount]; + if (delta > 0) { + if (next(*m_beginIter,delta).isFailure()) return StatusCode::FAILURE; + } + else return this->seek(it, evtNum); + } + else { // event in current file + int delta = (evtNum - m_firstEvt[m_fileCount] + 1) - m_eventSource->positionInBlock(); + ATH_MSG_DEBUG("Seeking event " << evtNum << " in current file wiht delta " << delta); + if ( delta == 0 ) { // current event + // nothing to do + } + else if ( delta > 0 ) { // forward + if ( this->next(*m_beginIter, delta).isFailure() ) return StatusCode::FAILURE; + } + else if ( delta < 0 ) { // backward + if ( this->previous(*m_beginIter, -1*delta).isFailure() ) return(StatusCode::FAILURE); + } + } + return(StatusCode::SUCCESS); +} + +StatusCode FaserEventSelectorByteStream::buildEventAttributeList() const +{ + //ServiceHandle<StoreGateSvc> m_evtStore("StoreGateSvc/StoreGateSvc",this->name()); + //StatusCode sc = m_evtStore.retrieve(); + //if (sc.isFailure()) return StatusCode::FAILURE; + std::string listName("EventInfoAtts"); + //bool found = m_evtStore->contains<AthenaAttributeList>(listName); + //if (found) { + if (m_evtStore->contains<AthenaAttributeList>(listName)) { + const AthenaAttributeList* oldAttrList = nullptr; + if (!m_evtStore->retrieve(oldAttrList, listName).isSuccess()) { + ATH_MSG_ERROR("Cannot retrieve old AttributeList from StoreGate."); + return(StatusCode::FAILURE); + } + if (!m_evtStore->removeDataAndProxy(oldAttrList).isSuccess()) { + ATH_MSG_ERROR("Cannot remove old AttributeList from StoreGate."); + return(StatusCode::FAILURE); + } + //ATH_MSG_ERROR("Event store not cleared properly after previous event"); + //return StatusCode::FAILURE; + } + // build spec + // fill att list spec + coral::AttributeListSpecification* spec = new coral::AttributeListSpecification(); + AthenaAttributeList* attlist = new AthenaAttributeList(*spec); + attlist->extend("RunNumber" ,"long"); + attlist->extend("EventNumber","long"); + attlist->extend("Lumiblock" ,"int"); + attlist->extend("BunchID" ,"int"); + attlist->extend("CrossingTimeSec", "unsigned int"); + attlist->extend("CrossingTimeNSec", "unsigned int"); + + // fill attribute list + const EventFull* event = m_eventSource->currentEvent(); + + (*attlist)["RunNumber"].data<long>() = event->run_number(); + (*attlist)["EventNumber"].data<long>() = event->event_counter(); + (*attlist)["Lumiblock"].data<int>() = 0; + (*attlist)["BunchID"].data<int>() = event->bc_id(); + + // Timestamp is in microseconds + unsigned int bc_time_sec = event->timestamp() / 1E6; + unsigned int bc_time_ns = 1000 * (event->timestamp() - 1E6*bc_time_sec); + (*attlist)["CrossingTimeSec"].data<unsigned int>() = bc_time_sec; + (*attlist)["CrossingTimeNSec"].data<unsigned int>() = bc_time_ns; + + // Not used + attlist->extend("TriggerStatus","unsigned int"); + (*attlist)["TriggerStatus"].data<unsigned int>() = event->status(); + + // Not used + attlist->extend("ExtendedL1ID","unsigned int"); + attlist->extend("L1TriggerType","unsigned int"); + (*attlist)["ExtendedL1ID"].data<unsigned int>() = 0; + (*attlist)["L1TriggerType"].data<unsigned int>() = event->trigger_bits(); + + // Add our event tag + attlist->extend("EventTag", "unsigned int"); + (*attlist)["EventTag"].data<unsigned int>() = event->event_tag(); + + attlist->extend("Timestamp", "unsigned long"); + (*attlist)["Timestamp"].data<unsigned long>() = event->timestamp(); + + // And our us time + + // Grab stream tags + /* Not sure what do do with this + event->stream_tag(buffer); + std::vector<eformat::helper::StreamTag> onl_streamTags; + eformat::helper::decode(event->nstream_tag(), buffer, onl_streamTags); + for (std::vector<eformat::helper::StreamTag>::const_iterator itS = onl_streamTags.begin(), + itSE = onl_streamTags.end(); itS != itSE; ++itS) { + attlist->extend(itS->name,"string"); + (*attlist)[itS->name].data<std::string>() = itS->type; + } + */ + + // Pur our own event_tag + + // put result in event store + if (m_evtStore->record(attlist,"EventInfoAtts").isFailure()) return StatusCode::FAILURE; + + return(StatusCode::SUCCESS); +} + +//__________________________________________________________________________ +int FaserEventSelectorByteStream::findEvent(int evtNum) const { + // Loop over file event counts + //ATH_MSG_INFO("try to find evnum = " << evtNum << " in " << m_numEvt.size() << " files"); + for (size_t i = 0; i < m_inputCollectionsProp.value().size(); i++) { + if (m_inputCollectionsProp.value().size() != m_numEvt.size()) { + ATH_MSG_ERROR("vector size incompatibility"); + break; + } + // if file not opened yet, check it + if (m_numEvt[i] == -1) { + std::string fileName = m_inputCollectionsProp.value()[i]; + auto nevguid = m_eventSource->getBlockIterator(fileName); + long nev = nevguid.first; + // if failure on file open, exit + if (nev==-1) { + break; + } + // set initial event counter for that file + if (i > 0) { + m_firstEvt[i] = m_firstEvt[i - 1] + m_numEvt[i - 1]; + } else { + m_firstEvt[i] = 0; + } + // log number of events in that file + m_numEvt[i] = nev; + } + // if sought event is in this file, then return the index of that file + if (evtNum >= m_firstEvt[i] && evtNum < m_firstEvt[i] + m_numEvt[i]) { + ATH_MSG_INFO("found " << evtNum << " in file " << i); + return(i); + } + } + ATH_MSG_INFO("did not find ev " << evtNum); + // return file not found marker + return(-1); +} + +//__________________________________________________________________________ +int FaserEventSelectorByteStream::curEvent (const Context& /*it*/) const { + // event counter in IEvtSelectorSeek interface + return int(m_NumEvents); +} + +//__________________________________________________________________________ +int FaserEventSelectorByteStream::size (Context& /*it*/) const { + return -1; +} + +//________________________________________________________________________________ +StatusCode FaserEventSelectorByteStream::makeServer(int /*num*/) { + if (m_eventStreamingTool.empty()) { + return(StatusCode::FAILURE); + } + return(m_eventStreamingTool->makeServer(1)); +} + +//________________________________________________________________________________ +StatusCode FaserEventSelectorByteStream::makeClient(int /*num*/) { + if (m_eventStreamingTool.empty()) { + return(StatusCode::FAILURE); + } + return(m_eventStreamingTool->makeClient(0)); +} + +//________________________________________________________________________________ +StatusCode FaserEventSelectorByteStream::share(int evtNum) { + if (m_eventStreamingTool.empty()) { + return(StatusCode::FAILURE); + } + if (m_eventStreamingTool->isClient()) { + StatusCode sc = m_eventStreamingTool->lockEvent(evtNum); + while (sc.isRecoverable()) { + usleep(1000); + sc = m_eventStreamingTool->lockEvent(evtNum); + } + return(sc); + } + return(StatusCode::FAILURE); +} + +//________________________________________________________________________________ +StatusCode FaserEventSelectorByteStream::readEvent(int maxevt) { + + if (m_eventStreamingTool.empty()) { + return(StatusCode::FAILURE); + } + ATH_MSG_VERBOSE("Called read Event " << maxevt); + for (int i = 0; i < maxevt || maxevt == -1; ++i) { + //const RawEvent* pre = m_eventSource->nextEvent(); + const EventFull* pre = 0; + if (this->next(*m_beginIter).isSuccess()) { + pre = m_eventSource->currentEvent(); + } else { + if (m_NumEvents == -1) { + ATH_MSG_VERBOSE("Called read Event and read last event from input: " << i); + break; + } + ATH_MSG_ERROR("Unable to retrieve next event for " << i << "/" << maxevt); + return(StatusCode::FAILURE); + } + if (pre == 0) { + // End of file, wait for last event to be taken + StatusCode sc = m_eventStreamingTool->putEvent(0, 0, 0, 0); + while (sc.isRecoverable()) { + usleep(1000); + sc = m_eventStreamingTool->putEvent(0, 0, 0, 0); + } + if (!sc.isSuccess()) { + ATH_MSG_ERROR("Cannot put last Event marker to AthenaSharedMemoryTool"); + } + return(StatusCode::FAILURE); + } + if (m_eventStreamingTool->isServer()) { + + ATH_MSG_WARNING("Called FaserEventSelectorByteStream::readEvent() in the eventStreamingTool->isServer() section, but not implemented!"); + + /* + StatusCode sc = m_eventStreamingTool->putEvent(m_NumEvents - 1, pre->start(), pre->fragment_size_word() * sizeof(uint32_t), m_eventSource->currentEventStatus()); + while (sc.isRecoverable()) { + usleep(1000); + sc = m_eventStreamingTool->putEvent(m_NumEvents - 1, pre->start(), pre->fragment_size_word() * sizeof(uint32_t), m_eventSource->currentEventStatus()); + } + if (!sc.isSuccess()) { + ATH_MSG_ERROR("Cannot put Event " << m_NumEvents - 1 << " to AthenaSharedMemoryTool"); + return(StatusCode::FAILURE); + } + */ + } + } + return(StatusCode::SUCCESS); +} + +//________________________________________________________________________________ +StatusCode FaserEventSelectorByteStream::createAddress(const IEvtSelector::Context& /*it*/, + IOpaqueAddress*& iop) const { + SG::DataProxy* proxy = m_evtStore->proxy(ClassID_traits<DataHeader>::ID(),"ByteStreamDataHeader"); + if (proxy !=0) { + iop = proxy->address(); + return(StatusCode::SUCCESS); + } else { + iop = 0; + return(StatusCode::FAILURE); + } +} + +//________________________________________________________________________________ +StatusCode +FaserEventSelectorByteStream::releaseContext(IEvtSelector::Context*& /*it*/) const { + return(StatusCode::SUCCESS); +} + +//________________________________________________________________________________ +StatusCode FaserEventSelectorByteStream::queryInterface(const InterfaceID& riid, void** ppvInterface) { + if (riid == IEvtSelector::interfaceID()) { + *ppvInterface = dynamic_cast<IEvtSelector*>(this); + } else if (riid == IIoComponent::interfaceID()) { + *ppvInterface = dynamic_cast<IIoComponent*>(this); + } else if (riid == IProperty::interfaceID()) { + *ppvInterface = dynamic_cast<IProperty*>(this); + } else if (riid == IEvtSelectorSeek::interfaceID()) { + *ppvInterface = dynamic_cast<IEvtSelectorSeek*>(this); + } else if (riid == IEventShare::interfaceID()) { + *ppvInterface = dynamic_cast<IEventShare*>(this); + } else { + return(Service::queryInterface(riid, ppvInterface)); + } + addRef(); + return(StatusCode::SUCCESS); +} +//________________________________________________________________________________ +StatusCode FaserEventSelectorByteStream::io_reinit() { + ATH_MSG_INFO("I/O reinitialization..."); + ServiceHandle<IIoComponentMgr> iomgr("IoComponentMgr", name()); + if (!iomgr.retrieve().isSuccess()) { + ATH_MSG_FATAL("Could not retrieve IoComponentMgr !"); + return(StatusCode::FAILURE); + } + if (!iomgr->io_hasitem(this)) { + ATH_MSG_FATAL("IoComponentMgr does not know about myself !"); + return(StatusCode::FAILURE); + } + if (m_inputCollectionsFromIS) { + /* MN: don't copy the FullFileName again - rely on FileSchedulingTool + to modify the EventSelector Input property directly + IProperty* propertyServer = dynamic_cast<IProperty*>(m_eventSource); + std::vector<std::string> vect; + StringArrayProperty inputFileList("FullFileName", vect); + StatusCode sc = propertyServer->getProperty(&inputFileList); + if(sc.isFailure()) { + ATH_MSG_FATAL("Unable to retrieve ByteStreamInputSvc"); + return(StatusCode::FAILURE); + } + m_inputCollectionsProp = inputFileList; + */ + } + std::vector<std::string> inputCollections = m_inputCollectionsProp.value(); + for (std::size_t i = 0, imax = inputCollections.size(); i != imax; ++i) { + ATH_MSG_INFO("I/O reinitialization, file = " << inputCollections[i]); + std::string &fname = inputCollections[i]; + if (!iomgr->io_contains(this, fname)) { + ATH_MSG_ERROR("IoComponentMgr does not know about [" << fname << "] !"); + return(StatusCode::FAILURE); + } + if (!iomgr->io_retrieve(this, fname).isSuccess()) { + ATH_MSG_FATAL("Could not retrieve new value for [" << fname << "] !"); + return(StatusCode::FAILURE); + } + } + // all good... copy over. + m_beginFileFired = false; + m_inputCollectionsProp = inputCollections; + + return(this->reinit()); +} + + diff --git a/Event/FaserByteStreamCnvSvc/src/FaserEventSelectorByteStream.h b/Event/FaserByteStreamCnvSvc/src/FaserEventSelectorByteStream.h new file mode 100644 index 0000000000000000000000000000000000000000..34bdec974fd816c7404d42dcab5cdc4d4143d577 --- /dev/null +++ b/Event/FaserByteStreamCnvSvc/src/FaserEventSelectorByteStream.h @@ -0,0 +1,167 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef FASEREVENTSELECTORBYTESTREAM_H +#define FASEREVENTSELECTORBYTESTREAM_H + +/** @class FaserEventSelectorByteStream + @brief concrete implementation of IEvtSelector for ByteStream + + An event selector service that steps through Event + Filter packed raw events by use of an event source + object and an iterator object called EventIteratorByteStream. + The type of event source is specified at run time. It + can be a single file, a set of files or the network. +//--------------------------------------------------------------------- +*/ + +#include "GaudiKernel/IEvtSelector.h" +#include "GaudiKernel/ServiceHandle.h" +#include "GaudiKernel/ToolHandle.h" +#include "GaudiKernel/IIoComponent.h" + +#include "AthenaKernel/IAthenaSelectorTool.h" +#include "AthenaKernel/IEvtSelectorSeek.h" +#include "AthenaKernel/IEventShare.h" +#include "AthenaBaseComps/AthService.h" + +// #include "ByteStreamData/RawEvent.h" + +// Forward declarations. +class ISvcLocator; +class IAthenaIPCTool; +class FaserEventContextByteStream; +class FaserByteStreamInputSvc; +class IROBDataProviderSvc; + +// Class EventSelectorByteStream. +class FaserEventSelectorByteStream : public ::AthService, + virtual public IEvtSelector, + virtual public IEvtSelectorSeek, + virtual public IEventShare, + virtual public IIoComponent { + public: + /// Standard Constructor. + FaserEventSelectorByteStream(const std::string& name, ISvcLocator* svcloc); + /// Standard Destructor. + virtual ~FaserEventSelectorByteStream(); + + /// Implementation of Service base class methods. + virtual StatusCode initialize() override; + virtual StatusCode start() override; + virtual StatusCode stop() override; + virtual StatusCode finalize() override; + + // Implementation of IInterface methods. + virtual StatusCode queryInterface(const InterfaceID& riid, void** ppvInterface) override; + + /// Implementation of the IEvtSelector interface methods. + virtual StatusCode createContext(Context*& it) const override; + /// Implementation of the IEvtSelector interface methods. + virtual StatusCode next(Context& it) const override; + /// Implementation of the IEvtSelector interface methods. + virtual StatusCode next(Context& it, int jump) const override; + /// Implementation of the IEvtSelector interface methods. + virtual StatusCode previous(Context& it) const override; + /// Implementation of the IEvtSelector interface methods. + virtual StatusCode previous(Context& it, int jump) const override; + + /// Implementation of the IEvtSelector interface methods. + virtual StatusCode last(Context& it) const override; + /// Implementation of the IEvtSelector interface methods. + virtual StatusCode rewind(Context& it) const override; + + virtual StatusCode createAddress(const Context& it,IOpaqueAddress*& iop) const override; + virtual StatusCode releaseContext(Context*& it) const override; + virtual StatusCode resetCriteria(const std::string& criteria, Context& context) const override; + + /// Seek to a given event number. + /// @param evtnum [IN] The event number to which to seek. + virtual StatusCode seek (Context& it, int evtnum) const override; + + /// Return the current event number. + virtual int curEvent (const Context& it) const override; + + /// Always returns -1. + virtual int size (Context& it) const override; + + /// Make this a server. + virtual StatusCode makeServer(int num) override; + + /// Make this a client. + virtual StatusCode makeClient(int num) override; + + /// Request to share a given event number. + /// @param evtnum [IN] The event number to share. + virtual StatusCode share(int evtnum) override; + + /// Read the next maxevt events. + /// @param evtnum [IN] The number of events to read. + virtual StatusCode readEvent(int maxevt) override; + + /// Callback method to reinitialize the internal state of the component for I/O purposes (e.g. upon @c fork(2)) + virtual StatusCode io_reinit() override; + + private: // internal member functions + /// reinitialize the service when a @c fork() occured/was-issued + StatusCode reinit(); + StatusCode openNewRun() const; + void nextFile() const; + int findEvent(int evtNum) const; //>! Search for event number evtNum. + StatusCode buildEventAttributeList() const; + + private: + // property + std::string m_eventSourceName; + Gaudi::Property<int> m_maxBadEvts; //!< number of bad events allowed before quitting. + mutable int m_fileCount; //!< number of files to process. + + mutable std::vector<int> m_numEvt; + mutable std::vector<int> m_firstEvt; + + FaserEventContextByteStream* m_beginIter; + FaserEventContextByteStream* m_endIter; + FaserByteStreamInputSvc* m_eventSource; + Gaudi::Property<std::vector<std::string>> m_inputCollectionsProp; + mutable std::vector<std::string>::const_iterator m_inputCollectionsIterator; + void inputCollectionsHandler(Property&); + ServiceHandle<IIncidentSvc> m_incidentSvc; + ServiceHandle<StoreGateSvc> m_evtStore; + + long m_SkipEvents; // Number of events to skip at the beginning + Gaudi::Property<std::vector<long>> m_skipEventSequenceProp; + mutable std::vector<long> m_skipEventSequence; + + bool m_firstFileFired; + bool m_beginFileFired; + bool m_inputCollectionsFromIS; + mutable long m_NumEvents; // Number of Events read so far. + + mutable ToolHandle<IAthenaIPCTool> m_eventStreamingTool; + + Gaudi::Property<bool> m_procBadEvent; //!< process bad events, which fail check_tree(). + + /// HelperTools, vector of names of AlgTools that are executed by the EventSelector + ToolHandleArray<IAthenaSelectorTool> m_helperTools; + ToolHandle<IAthenaSelectorTool> m_counterTool; + + /**@name Athena standard EventSelector properties */ + + /// Flags to indicate override of run/event/time + /// These are almost always false. + Gaudi::Property<bool> m_overrideRunNumber; + Gaudi::Property<bool> m_overrideEventNumber; + Gaudi::Property<bool> m_overrideTimeStamp; + Gaudi::Property<bool> m_filebased; + + Gaudi::CheckedProperty<int> m_runNo; + Gaudi::CheckedProperty<int> m_firstEventNo; + Gaudi::CheckedProperty<int> m_eventsPerRun; + Gaudi::CheckedProperty<int> m_firstLBNo; + Gaudi::CheckedProperty<int> m_eventsPerLB; + Gaudi::CheckedProperty<int> m_initTimeStamp; + Gaudi::Property<int> m_timeStampInterval; + }; + +#endif diff --git a/Event/FaserByteStreamCnvSvc/src/components/FaserByteStreamCnvSvc_entries.cxx b/Event/FaserByteStreamCnvSvc/src/components/FaserByteStreamCnvSvc_entries.cxx new file mode 100644 index 0000000000000000000000000000000000000000..c3490e2bbea3e7f7fb47ee1e144323c1f90790cf --- /dev/null +++ b/Event/FaserByteStreamCnvSvc/src/components/FaserByteStreamCnvSvc_entries.cxx @@ -0,0 +1,28 @@ +#include "FaserByteStreamCnvSvc/FaserByteStreamCnvSvc.h" +#include "../FaserByteStreamInputSvc.h" +#include "../FaserEventSelectorByteStream.h" +#include "../EventInfoByteStreamxAODCnv.h" +#include "../EventInfoByteStreamAuxCnv.h" +/* +#include "../ByteStreamMergeOutputSvc.h" +#include "../ByteStreamRDP_OutputSvc.h" +#include "../ByteStreamEventStorageInputSvc.h" +#include "../ByteStreamEventStorageOutputSvc.h" +#include "../ByteStreamOutputStreamCopyTool.h" +#include "../ByteStreamMetadataTool.h" +*/ + +DECLARE_COMPONENT( FaserByteStreamCnvSvc ) +DECLARE_COMPONENT( FaserByteStreamInputSvc ) +DECLARE_COMPONENT( FaserEventSelectorByteStream ) +DECLARE_CONVERTER( EventInfoByteStreamxAODCnv ) +DECLARE_CONVERTER( EventInfoByteStreamAuxCnv ) +/* +DECLARE_COMPONENT( ByteStreamMergeOutputSvc ) +DECLARE_COMPONENT( ByteStreamRDP_OutputSvc ) +DECLARE_COMPONENT( ByteStreamEventStorageInputSvc ) +DECLARE_COMPONENT( ByteStreamEventStorageOutputSvc ) + +DECLARE_COMPONENT( ByteStreamOutputStreamCopyTool ) +DECLARE_COMPONENT( ByteStreamMetadataTool ) +*/ diff --git a/Event/FaserEventStorage/CMakeLists.txt b/Event/FaserEventStorage/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..9cd19ab2339a7bc9631d19b3b09fe2f5e06b8873 --- /dev/null +++ b/Event/FaserEventStorage/CMakeLists.txt @@ -0,0 +1,32 @@ +################################################################################ +# Package: FaserEventStorage +################################################################################ + +# Declare the package name: +atlas_subdir( FaserEventStorage ) + +atlas_depends_on_subdirs ( +PRIVATE +EventFormats +) + +# External dependencies: +find_package( tdaq-common COMPONENTS ers EventStorage ) +find_package( Boost COMPONENTS system ) + +atlas_add_library( FaserEventStorageLib + FaserEventStorage/*.h src/*.h src/*.cxx + PUBLIC_HEADERS FaserEventStorage + INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ${TDAQ-COMMON_INCLUDE_DIRS} + LINK_LIBRARIES ${Boost_LIBRARIES} ${TDAQ-COMMON_LIBRARIES} ) + + +# atlas_add_library(fReadPlain +# src/fReadPlain.h src/fReadPlain.cxx +# PUBLIC_HEADERS src +# INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ${TDAQ-COMMON_INCLUDE_DIRS} +# LINK_LIBRARIES ${Boost_LIBRARIES} ${TDAQ-COMMON_LIBRARIES} -rdynamic) + +# Install files from the package: +atlas_install_python_modules( python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} ) +atlas_install_joboptions( share/*.py ) diff --git a/Event/FaserEventStorage/FaserEventStorage/DRError.h b/Event/FaserEventStorage/FaserEventStorage/DRError.h new file mode 100644 index 0000000000000000000000000000000000000000..493df0e1536a6fa8d6bad2125667e176841a6d8f --- /dev/null +++ b/Event/FaserEventStorage/FaserEventStorage/DRError.h @@ -0,0 +1,21 @@ +#ifndef _ERROR_ESTORE_R_ +#define _ERROR_ESTORE_R_ + +/** + \brief Return codes of the DataReader interface. + \file EventStorage/DRError.h +*/ + +namespace FaserEventStorage { + + enum DRError { DROK = 0, /**< All OK */ + DRNOOK, /**< an error, no way to read more data */ + DRWAIT, /**< No way to read more data now, but there is a new file to which another process is writing. */ + DRNOSEQ, /**< Not possible to make a file sequence. File name does not end with <number>.data */ + DRWOFF /**< Wrong offset was given. No event data was found. You can still try another offset. */ + }; + +} + +#endif //_ERROR_ESTORE_R_ + diff --git a/Event/FaserEventStorage/FaserEventStorage/DataReader.h b/Event/FaserEventStorage/FaserEventStorage/DataReader.h new file mode 100644 index 0000000000000000000000000000000000000000..39282122b46c4f609a5827fc8c17b5acfaba7700 --- /dev/null +++ b/Event/FaserEventStorage/FaserEventStorage/DataReader.h @@ -0,0 +1,146 @@ +//Dear emacs, this is -*- c++ -*- + + +/** + \brief The API for reading of raw data data files + written by ATLAS TDAQ applications. + \author Szymon Gadomski + \date May 2002 - Feb 2007 + \file EventStorage/DataReader.h +*/ + +#ifndef FASEREVENTSTORAGE_DATAREADER_H +#define FASEREVENTSTORAGE_DATAREADER_H + +#include <vector> +#include <string> +#include <stdint.h> +#include <bitset> +#include "FaserEventStorage/DRError.h" +#include "FaserEventStorage/ESCompression.h" + +#include <boost/utility.hpp> + +namespace DAQFormats { + class EventFull; +} + +using namespace FaserEventStorage; + +namespace FaserEventStorage { + + class DataReader : boost::noncopyable + { + protected: + DataReader() {}; + + public: + /** the virual destructor */ + virtual ~DataReader() {}; + + public: + /** + The method to enamble reading of file sequences. + You need to call this method if you want to enable reading of + file sequences (*0001.data, *0002.data ...). + By default, i.e. unless you call this method, only one file will + be read + */ + virtual DRError enableSequenceReading() = 0; + + /** Feedback to user. Check if you can still read more data. */ + virtual bool good() const = 0; + + /** true if no more events left in the current file */ + virtual bool endOfFile() const = 0; + + /** true if no more events left in the file sequence */ + virtual bool endOfFileSequence() const = 0; + + /** number of the file currently open; make sense only if you are reading a sequence */ + virtual unsigned int currentFileNumber() const = 0; + + virtual unsigned int latestDataNumber() const = 0; + + + /** + read the event data + \param &eventSize the event (or data block) size will be returned here + \param **event start of the data block + \param pos if you give this parameter, you are trying to get an event from the offset pos + + Possible return codes are decribed in the file EventStorage/DataReader.h + */ + virtual DRError getData(DAQFormats::EventFull*& theEvent, int64_t pos) = 0; + virtual DRError getData(DAQFormats::EventFull*& theEvent) = 0; + // virtual DRError getDataPreAlloced(unsigned int &eventSize, char **event, int64_t allocSizeInBytes) = 0; + + // virtual DRError getDataPreAllocedWitPos(unsigned int &eventSize, char **event, int64_t allocSizeInBytes, int64_t pos = -1) = 0; + + + /** name of the current file */ + virtual std::string fileName() const = 0; + + /** get the current offset within the file */ + virtual int64_t getPosition() const = 0; + + /** + The following methogs give access to metadata stored in the files. + + Dates and times are the local time of the PC that was writing tha data file. + Human-readable encoding as integers was used. + For instance date 31012007 is 31 Jan 2007. + Time 184422 is 18:44:22. + + The following information is available without penalty at any stage during reading: + */ + virtual unsigned int fileStartDate() const = 0; ///< Date when the file writing has started. + virtual unsigned int fileStartTime() const = 0; ///< Time when the file writing was started. + virtual unsigned int fileSizeLimitInDataBlocks() const = 0; ///< Maximum number of data blocks that was given when writing. + virtual unsigned int fileSizeLimitInMB() const = 0; ///< Maximum size in MB given when writing. + virtual std::string appName() const = 0; ///< Name of the application that has written the file. + virtual std::string fileNameCore() const = 0; ///< File name not including ._<file number>.data + + /** + The following parameters of the run come from the Information System of the DAQ. + The information is also available without penalty at any stage during reading. + */ + virtual unsigned int runNumber() const = 0; ///< Run number + virtual unsigned int maxEvents() const = 0; ///< Maximum number of events specified for this run + virtual unsigned int recEnable() const = 0; ///< Was recording enabled? + virtual unsigned int triggerType() const = 0; ///< Trigger type + virtual std::bitset<128> detectorMask() const = 0; ///< Detector mask + virtual unsigned int beamType() const = 0; ///< Beam type + virtual unsigned int beamEnergy() const = 0; ///< Beam energy + virtual std::vector<std::string> freeMetaDataStrings() const = 0; ///< Vector of strings containing metadata + + /// Unique ID of the file represened as a string on POOL style. + /// For instance 10605EAF-52B1-DB11-94A4-000347D7BFE1 + virtual std::string GUID() const = 0; + + virtual CompressionType compression() const = 0; ///< File compression technology + + /** + The following methods will rewind to the end of file. + Reading of data can continue undisturbed. + */ + virtual unsigned int fileEndDate() = 0; ///< Date when writing has stopped. + virtual unsigned int fileEndTime() = 0; ///< Time when writing has stopped. + virtual unsigned int eventsInFile() = 0; ///< Number of events in this file. + virtual unsigned int dataMB_InFile() = 0; ///< Number of megabytes in this file. + virtual unsigned int eventsInFileSequence() = 0; ///< Number of events in this file sequence written so far. + virtual unsigned int dataMB_InFileSequence() = 0; ///< Number of MB in this file sequence written so far. + + virtual uint32_t lumiblockNumber() = 0; + virtual std::string stream() = 0; + virtual std::string projectTag() = 0; + + }; + +} + +#endif // EVENTSTORAGE_DATAREADER_H + + + + diff --git a/Event/FaserEventStorage/FaserEventStorage/ESCompression.h b/Event/FaserEventStorage/FaserEventStorage/ESCompression.h new file mode 100644 index 0000000000000000000000000000000000000000..bf6f1e9576e13faba26e355fb44cf8956e06ece3 --- /dev/null +++ b/Event/FaserEventStorage/FaserEventStorage/ESCompression.h @@ -0,0 +1,20 @@ +//Dear emacs, this is -*- c++ -*- + +#ifndef FASEREVENTSTORAGE_ESCOMPRESSION_H +#define FASEREVENTSTORAGE_ESCOMPRESSION_H + +#include <string> +#include "ers/ers.h" + +namespace FaserEventStorage { + + enum CompressionType { NONE, RESERVED, UNKNOWN, ZLIB}; + + static const std::string compressiontag("Compression"); + + CompressionType string_to_type(const std::string& type); + std::string type_to_string(const CompressionType& type); + +} + +#endif diff --git a/Event/FaserEventStorage/FaserEventStorage/EventStorageIssues.h b/Event/FaserEventStorage/FaserEventStorage/EventStorageIssues.h new file mode 100644 index 0000000000000000000000000000000000000000..c01990455bc8b56dca5ff6974dc9974f0ff8ca76 --- /dev/null +++ b/Event/FaserEventStorage/FaserEventStorage/EventStorageIssues.h @@ -0,0 +1,134 @@ +#ifndef FASEREVENTSTORAGEISSUES_H +#define FASEREVENTSTORAGEISSUES_H + +#include "ers/ers.h" + + +/** + To report problems with configuration data base +*/ + + + +ERS_DECLARE_ISSUE(FaserEventStorage, + WritingIssue, + "FaserEventStorage writing problem" << ": " << reason, + ((const char*) reason) + ) + +ERS_DECLARE_ISSUE_BASE(FaserEventStorage, + ES_SingleFile, + FaserEventStorage::WritingIssue, + "ES_SingleFile" << ": " << reason , + ((const char*) reason), ERS_EMPTY + ) + +ERS_DECLARE_ISSUE_BASE(FaserEventStorage, + ES_SingleFileAlreadyExists, + FaserEventStorage::WritingIssue, + "ES_SingleFileAlreadyExists" << ": " << reason , + ((const char*) reason), ERS_EMPTY + ) + + + + +ERS_DECLARE_ISSUE(FaserEventStorage, + ReadingIssue, + "FaserEventStorage reading problem" << ": " << reason, + ((const char*) reason) + ) + +ERS_DECLARE_ISSUE(FaserEventStorage, + RawFileNameIssue, + "FaserEventStorage problem with RawFileName" << ": " << reason, + ((const char*) reason) + ) + + +ERS_DECLARE_ISSUE_BASE(FaserEventStorage, + ES_InternalError, + FaserEventStorage::ReadingIssue, + "ES_InternalError" << ": " << reason , + ((const char*) reason), ERS_EMPTY + ) + + +ERS_DECLARE_ISSUE_BASE(FaserEventStorage, + ES_WrongFileFormat, + FaserEventStorage::ReadingIssue, + "ES_WrongFileFormat" << ": " << reason , + ((const char*) reason), ERS_EMPTY + ) + +ERS_DECLARE_ISSUE_BASE(FaserEventStorage, + ES_OutOfFileBoundary, + FaserEventStorage::ReadingIssue, + "ES_OutOfFileBoundary" << ": " << reason , + ((const char*) reason), ERS_EMPTY + ) + +ERS_DECLARE_ISSUE_BASE(FaserEventStorage, + ES_NoEventFound, + FaserEventStorage::ReadingIssue, + "ES_NoEventFound" << ": " << reason , + ((const char*) reason), ERS_EMPTY + ) + +ERS_DECLARE_ISSUE_BASE(FaserEventStorage, + ES_WrongEventSize, + FaserEventStorage::ReadingIssue, + "ES_WrongEventSize" << ": " << reason , + ((const char*) reason), ERS_EMPTY + ) + +ERS_DECLARE_ISSUE_BASE(FaserEventStorage, + ES_NoEndOfFileRecord, + FaserEventStorage::ReadingIssue, + "ES_NoEndOfFileRecord" << ": " << reason , + ((const char*) reason), ERS_EMPTY + ) + +ERS_DECLARE_ISSUE_BASE(FaserEventStorage, + ES_AllocatedMemoryTooLittle, + FaserEventStorage::ReadingIssue, + "ES_AllocatedMemoryTooLittle" << ": " << reason , + ((const char*) reason), ERS_EMPTY + ) + +ERS_DECLARE_ISSUE_BASE(FaserEventStorage, + ES_AllocatingMemoryFailed, + FaserEventStorage::ReadingIssue, + "ES_AllocatingMemoryFailed" << ": " << reason , + ((const char*) reason), ERS_EMPTY + ) + + + +ERS_DECLARE_ISSUE_BASE(FaserEventStorage, + ES_SquenceNextFileMissing, + FaserEventStorage::ReadingIssue, + "ES_SquenceNextFileMissing" << ": " << reason , + ((const char*) reason), ERS_EMPTY + ) + + + +/* +ES_InternalError + +ES_WrongFileFormat + +ES_OutOfFileBoundary +ES_NoEventFound +ES_WrongEventSize + + +ES_NoEndOfFileRecord +ES_AllocatedMemoryTooLittle + + + +*/ + +#endif diff --git a/Event/FaserEventStorage/FaserEventStorage/EventStorageRecords.h b/Event/FaserEventStorage/FaserEventStorage/EventStorageRecords.h new file mode 100644 index 0000000000000000000000000000000000000000..129b128df5c46ff87d5677cf2aafb2035133eaba --- /dev/null +++ b/Event/FaserEventStorage/FaserEventStorage/EventStorageRecords.h @@ -0,0 +1,126 @@ +/** + \brief metadata records for EventStorage library + \author Szymon Gadomski + \date January 2004 +*/ + +#ifndef FASEREVENTSTORAGE_RECORDS_H +#define FASEREVENTSTORAGE_RECORDS_H + +#include <string> +#include <vector> +#include <stdint.h> + +// version of file format +#define FILE_FORMAT_VERSION 0x00000006 + +// markers as in DAQ-1 +#define FILE_START_MARKER 0x1234aaaa +#define RUN_PARAMETERS_MARKER 0x1234bbbb + +#define EVENT_RECORD_MARKER 0x1234cccc + +#define STRING_SECTION_MARKER 0x1234aabb +#define FREE_STRINGS_MARKER 0x1234aabc + +#define FILE_END_MARKER 0x1234dddd +#define FILE_END_MARKER_LAST 0x1234eeee + +namespace FaserEventStorage { + + struct file_start_record + { + uint32_t marker; /* Start of record marker */ + uint32_t record_size; /* Total record size */ + uint32_t version; /* Format version number */ + uint32_t file_number; /* File number in the sequence */ + uint32_t date; /* Date of run start */ + uint32_t time; /* Time of run start */ + uint32_t sizeLimit_dataBlocks; /* Max number of data blocks in the file */ + uint32_t sizeLimit_MB; /* Max number of data blocks in the file */ + }; + + struct file_name_strings { + std::string appName; + std::string fileNameCore; + }; + + typedef std::vector<std::string> freeMetaDataStrings; + + struct run_parameters_record { + uint32_t marker; /* Start of record marker */ + uint32_t record_size; /* Total record size */ + uint32_t run_number; /* From IS */ + uint32_t max_events; /* From IS */ + uint32_t rec_enable; /* From IS */ + uint32_t trigger_type; /* From IS */ + uint64_t detector_mask_LS; /* From IS */ + uint64_t detector_mask_MS; /* From IS */ + uint32_t beam_type; /* From IS */ + uint32_t beam_energy; /* From IS */ + }; + + struct data_separator_record { + uint32_t marker; /* Start of record marker */ + uint32_t record_size; /* Total record size */ + uint32_t data_block_number; /* Index in the file sequence */ + uint32_t data_block_size; /* Size of the following block of data */ + }; + + struct file_end_record { + uint32_t marker; /* Start of record marker */ + uint32_t record_size; /* Total record size */ + uint32_t date; /* Date of run end */ + uint32_t time; /* Time of run end */ + uint32_t events_in_file; /* Number of events recorded */ + uint32_t data_in_file; /* Volume of data recorded */ + uint32_t events_in_run; /* Number of events recorded */ + uint32_t data_in_run; /* Volume of data recorded */ + uint32_t status; /* Used to mark the last file. Other use possible in the future.*/ + uint32_t end_marker; /* End of RUNEND marker */ + }; + + // implement patterns + const uint32_t file_name_strings_marker = STRING_SECTION_MARKER; + const uint32_t free_strings_marker = FREE_STRINGS_MARKER; + + const file_start_record file_start_pattern = { + FILE_START_MARKER, + sizeof(file_start_record)/sizeof(uint32_t), + FILE_FORMAT_VERSION, + 0, + 0, + 0, + 0, + 0 + }; + + const data_separator_record data_separator_pattern = { + EVENT_RECORD_MARKER, + sizeof(data_separator_record)/sizeof(uint32_t), + 0, + 0 + }; + + const file_end_record file_end_pattern = { + FILE_END_MARKER, + sizeof(file_end_record)/sizeof(uint32_t), + 0, + 0, + 0, + 0, + 0, + 0, + 0, + FILE_END_MARKER_LAST + }; + + std::string string_record(void *ri, const void *pi); + std::string string_record(file_name_strings nst); + void reset_record(void *ri, const void *pi); + +} // for namespace + +#endif // EVENTSTORAGE_RECORDS_H + + diff --git a/Event/FaserEventStorage/FaserEventStorage/FileNameCallback.h b/Event/FaserEventStorage/FaserEventStorage/FileNameCallback.h new file mode 100644 index 0000000000000000000000000000000000000000..4a536cd10d264a3c8305f364e208bf7e64dd52bf --- /dev/null +++ b/Event/FaserEventStorage/FaserEventStorage/FileNameCallback.h @@ -0,0 +1,39 @@ +/** + \brief an interface for a call back class + \file EventStorage/FileNameCallback.h + + a class to separate the generation of file names from the DataWriter + + \author Cyril Topfel + \date December 2009 +*/ + +#ifndef FASEREVENTSTORAGE_FILENAMECALLBACK_H +#define FASEREVENTSTORAGE_FILENAMECALLBACK_H + +#include <string> + +namespace FaserEventStorage { + +class FileNameCallback +{ + public: + virtual ~FileNameCallback() {}; + + virtual void advance() = 0; + virtual std::string getCurrentFileName(bool writing=false) = 0; + virtual std::string getCoreName() = 0; + /* virtual std::string getFileNameByIndex(int index);*/ + virtual unsigned int getIndex() = 0; + virtual void fileAlreadyExists() = 0; + + + +}; + +} +#endif // EVENTSTORAGE_FILENAMECALLBACK_H + + + + diff --git a/Event/FaserEventStorage/FaserEventStorage/RawFileName.h b/Event/FaserEventStorage/FaserEventStorage/RawFileName.h new file mode 100644 index 0000000000000000000000000000000000000000..b1c57ff748734ab883322a5ed8bafbc08862d417 --- /dev/null +++ b/Event/FaserEventStorage/FaserEventStorage/RawFileName.h @@ -0,0 +1,263 @@ +/** + \brief Class describing filenames of raw data in a format agreed for ATLAS; contruct, interpret and modify such file-names. + \author Kostas Kordas + \date Oct 2008 + \file EventStorage/RawFileName.h +*/ + +#ifndef FASEREVENTSTORAGE_ONLINEFILENAME_H +#define FASEREVENTSTORAGE_ONLINEFILENAME_H + +#include "FaserEventStorage/EventStorageIssues.h" +#include "FaserEventStorage/FileNameCallback.h" +//----------------- +// includes for ers +#include "ers/ers.h" +//----------------- + +#include <string> +#include <vector> +#include <iostream> +#include <sstream> +#include <iomanip> +#include <stdexcept> + + + +namespace daq +{ + + /** + * Constants associated with the RAW file name convention + * -------------------------------------------------------- + */ + // extenstions of files and delimiter between fields: + static const std::string RAWFILENAME_EXTENSION_UNFINISHED = ".writing"; + static const std::string RAWFILENAME_EXTENSION_FINISHED = ".data"; + static const std::string RAWFILENAME_DELIMITER = "."; + // defaults: + static const unsigned int RAWFILENAME_DEFAULT_UINT = 0; + static const std::string RAWFILENAME_DEFAULT_STRING = ""; + // width of some file name fields, for proper padding: + static const unsigned int RAWFILENAME_RUN_NUMBER_LENGTH = 8; + static const unsigned int RAWFILENAME_LB_NUMBER_LENGTH = 4; + static const unsigned int RAWFILENAME_FILE_NUMBER_LENGTH = 4; + static const unsigned int RAWFILENAME_RUN_NUMBER_LENGTH_OLD = 7; + static const unsigned int RAWFILENAME_FILE_NUMBER_LENGTH_OLD = 2; + + + /** + * Helper class for exceptions + */ + class BadConversion : public std::runtime_error { + public: + BadConversion(const std::string& s) : std::runtime_error(s) { } + }; + + /** + * The class implementing the online filename convention + */ + class RawFileName : public FaserEventStorage::FileNameCallback { + public: + /** + * Contructor with all ingredients given + * Note: Extension will be made to start with '.' (e.g., "data" -> ".data") + */ + RawFileName(std::string ProjectTag, + unsigned int RunNumber, + std::string StreamType, + std::string StreamName, + unsigned int LumiBlockNumber, + std::string ApplicationName, + std::string ProductionStep="daq", + std::string DataType="RAW", + unsigned int FileSequenceNumber=1, + std::string Extension=""); + + + + void advance(); + std::string getCurrentFileName(bool writing); + /* virtual std::string getFileNameByIndex(int index);*/ + + std::string getCoreName(); + + + unsigned int getIndex(); + void fileAlreadyExists(); + + + + /** + * Constructor with the FileNameCore, a FileSequenceNumber and + * the Extension only - + * Does not alter the FileNameCore, just attaches trailer fields + * to the fileNameCore; also, tries to interpret the resulting filename + * Note: Extension will be made to start with '.' (e.g., "data" -> ".data") + */ + RawFileName(std::string FileNameCore, + unsigned int FileSequenceNumber, + std::string Extension=""); + + /** + * Contructor with just the filename given: for interpretation + */ + RawFileName(std::string FileName); + + /** + * Destructor + */ + ~RawFileName(); + + /** + * given the ingedients, contruct the fileName + */ + void buildFileName(std::string ProjectTag, + unsigned int RunNumber, + std::string StreamType, + std::string StreamName, + unsigned int LumiBlockNumber, + std::string ApplicationName, + std::string ProductionStep, + std::string DataType, + unsigned int FileSequenceNumber, + std::string Extension); + + /** + * given the ingedients, contruct the fileNameCore + * and set m_core_known = true + */ + void buildFileNameCore(std::string ProjectTag, + unsigned int RunNumber, + std::string StreamType, + std::string StreamName, + unsigned int LumiBlockNumber, + std::string ApplicationName, + std::string ProductionStep, + std::string DataType); + + /** + * Complete the FileName, + * by appending a FileSequenceNumber and an Extension to the FileNameCore + * and set m_trailers_known = true + * Note: Extension will be made to start with '.' (e.g., "data" -> ".data") + */ + void buildFileNameTrailers(std::string FileNameCore, + unsigned int FileSequenceNumber, + std::string Extension); + + /** + * given the fileName, reconstruct the ingredients + */ + bool interpretFileName(std::string FileName); + + /** + * contruct the complain + */ + std::string complain(); + + /** + * print the content of this object + */ + void print(); + + /** + * Get methods: + * ------------ + */ + std::string project(); + unsigned int runNumber(); + std::string streamType(); + std::string streamName(); + std::string stream(); + unsigned int lumiBlockNumber(); + std::string applicationName(); + std::string productionStep(); + std::string dataType(); + unsigned int fileSequenceNumber(); + std::string extension(); + + std::string fileNameCore() { return m_fileNameCore; } + std::string fileName() { return m_fileName; } + + bool hasValidCore() { return m_core_known; } + bool hasValidTrailer() { return m_trailer_known; } + + std::string datasetName(); + + /** + * Set methods: + * ------------ + */ + + /** + * Default values for the filename fields + * If filename is valid, the correct values will be returned when asked. + */ + void setDefaults(); + + /** + * Modify the File Trailer fileds (FileSequence Number and Extension) + */ + void setTailers(unsigned int fsn_i, std::string extension_s); + + /** + * Modify the FileSequenceNumber at the file trailer fields + */ + void setFileSequenceNumber( unsigned int fsn_i ); + + /** + * Modify the File Extension at the file trailer fields + */ + void setExtension( std::string extension_s ); + + + public: + /** + * Helper methods: made static for use even without an object + * ------------------------------------------------------------ + */ + + /** + * given a string and a delimeter, split it in fields and return them in + * a vector of strings + */ + static std::vector<std::string> split(std::string const & s, + char delimiter); + + /** + * string to integer conversion + */ + static unsigned int convertToUINT(const std::string & s); + + + private: + /** + * Member data: + * ------------ + */ + std::string m_project; + unsigned int m_runNumber; + std::string m_streamType; + std::string m_streamName; + std::string m_stream; + unsigned int m_lumiBlockNumber; + std::string m_applicationName; + std::string m_productionStep; + std::string m_dataType; + std::string m_fileNameCore; + + unsigned int m_fileSequenceNumber; + std::string m_extension; + std::string m_fileName; + + std::string m_datasetName; + + bool m_core_known; + bool m_trailer_known; + + }; // end RawFileName class declaration + +} // end "daq" namespace + +#endif // EVENTSTORAGE_ONLINEFILENAME_H diff --git a/Event/FaserEventStorage/FaserEventStorage/fRead.h b/Event/FaserEventStorage/FaserEventStorage/fRead.h new file mode 100644 index 0000000000000000000000000000000000000000..ad4c1e8d932544754159f85de8f09be75a9da840 --- /dev/null +++ b/Event/FaserEventStorage/FaserEventStorage/fRead.h @@ -0,0 +1,70 @@ +/** + \brief EventStorage library, an abstract interface for file I/O operations + \author Szymon Gadomski + \file EventStorage/fRead.h + \date Feb 2006 - Feb 2007 + + This is needed to support dufferent file I/O libraries: + - castor files are accessible with shift library, + - plain disk files need to be readable on computers without the shift lib, + - dCache is an alternative to Castor used at various sites for ATLAS. +*/ + +#ifndef FREAD_H +#define FREAD_H + +#include <string> +#include <stdint.h> + +class fRead +{ + public: + fRead() + { + m_currentEndOfFile = -1; + }; + + virtual ~fRead() {}; + + uint32_t readuint32_t() + { + int64_t op = getPosition(); + uint32_t myint; + readData((char*)&myint, sizeof(uint32_t)); + setPosition(op); + return myint; + } + + virtual bool isOpen() = 0; + virtual bool isEoF() = 0; + virtual bool fileExists(std::string name) const = 0; + virtual void openFile(std::string name) = 0; + virtual void closeFile() = 0; + virtual void readData(char *buffer, unsigned int sizeBytes) = 0; + virtual int64_t getPosition() = 0; + virtual void setPosition(int64_t p) = 0; + virtual void setPositionFromEnd(int64_t p) = 0; + + void setCurrentEndOfFile(int64_t p) + { + m_currentEndOfFile = p; + } + + void setPositionFromEndSafe(int64_t p) + { + if (m_currentEndOfFile==-1) setPositionFromEnd(p); + else + setPosition( m_currentEndOfFile + p); + } + + virtual fRead * newReader() const = 0; + + private: + int64_t m_currentEndOfFile; + +}; + +extern "C" { + fRead *fReadFactory(); +} +#endif diff --git a/Event/FaserEventStorage/FaserEventStorage/loadfRead.h b/Event/FaserEventStorage/FaserEventStorage/loadfRead.h new file mode 100644 index 0000000000000000000000000000000000000000..284bc8dbf7005193d64b2fc3b813cb7b4118d950 --- /dev/null +++ b/Event/FaserEventStorage/FaserEventStorage/loadfRead.h @@ -0,0 +1,14 @@ +/** + \brief Function to load the file lib wrapper class. + \author Szymon Gadomski + \date February 2006 +*/ + +#ifndef FASEREVENTSTORAGE_LOADFREAD_H +#define FASEREVENTSTORAGE_LOADFREAD_H + +#include "FaserEventStorage/fRead.h" + +fRead * loadfRead(std::string libName); + +#endif diff --git a/Event/FaserEventStorage/FaserEventStorage/pickFaserDataReader.h b/Event/FaserEventStorage/FaserEventStorage/pickFaserDataReader.h new file mode 100644 index 0000000000000000000000000000000000000000..e809a363d4f7c68ea00e1b3c0b4eca85ae75a0bf --- /dev/null +++ b/Event/FaserEventStorage/FaserEventStorage/pickFaserDataReader.h @@ -0,0 +1,26 @@ +/** + \brief Function to choose the correct reader of the data files. + + It recognizes data file formats of 2003 and later. + It chooses a file I/O library for plain disk files, Castor + files or dCache files. + + \file EventStorage/pickDataReader.h + \author Szymon Gadomski + \date Feb 2004 - Feb 2007 +*/ + +#ifndef FASEREVENTSTORAGE_PICKDATAREADER_H +#define FASEREVENTSTORAGE_PICKDATAREADER_H + +#include "FaserEventStorage/DataReader.h" +#include <string> + +/** + \param fileName the name of the data file to read +*/ +FaserEventStorage::DataReader * pickFaserDataReader(std::string fileName); + + + +#endif diff --git a/Event/FaserEventStorage/README b/Event/FaserEventStorage/README new file mode 100644 index 0000000000000000000000000000000000000000..a2a79b9a1264b2458fded8ee38febcdfe14d2aff --- /dev/null +++ b/Event/FaserEventStorage/README @@ -0,0 +1,4 @@ +FaserEventStorage + +FASER version of utility pakcage EventStorage taken from here: +https://gitlab.cern.ch/atlas-tdaq-software/EventStorage/-/tree/master/ diff --git a/Event/FaserEventStorage/src/DataReaderController.cxx b/Event/FaserEventStorage/src/DataReaderController.cxx new file mode 100644 index 0000000000000000000000000000000000000000..10c545005339be54c23ca76a826390a5f8903793 --- /dev/null +++ b/Event/FaserEventStorage/src/DataReaderController.cxx @@ -0,0 +1,681 @@ +#include <memory> +#include <sstream> +#include <iomanip> + + +#include "ers/ers.h" +#include "FaserEventStorage/EventStorageIssues.h" +#include "FaserEventStorage/fRead.h" +#include "DataReaderController.h" +#include "EventStorage/RawFileName.h" +#include "EventStackLayer.h" +#include "ESLMultiFile.h" +//#include "ESLMergeFile.h" +#include "ESLOriginalFile.h" +#include "EventFormats/DAQFormats.hpp" + +using namespace std; +using namespace FaserEventStorage; + + +DataReaderController::DataReaderController(fRead *fR, string filename) +{ + m_fR = fR; //the raw reader + m_fileName = filename; //the initial filename + + m_sequenceReading = false; //seq reading off per default + m_finished = false; + m_last_file_finished = false ; + + m_markForDeletion = 0; + m_responsibleForMetaData = 0; + + //This is the entry Point, it always starts with a MultiFileReader + m_filehandler = new FESLMultiFile(m_fR); + + ERS_DEBUG(1,"filehandler instantiated " << m_filehandler->identify() ); + + m_filehandler->setFile(filename); + + ERS_DEBUG(3,"filehandler file set " << m_filehandler->identify() << " " << filename); + + // ET doesn't do anything, so OK + m_filehandler->prepare(); + + ERS_DEBUG(3,"filehandler " << m_filehandler->identify() << " prepared."); + + m_stack.push(m_filehandler); + + m_cFileNumber = 0; + m_sizeOfFileNumber = 0; + + initialize(); + + ERS_DEBUG(3,"Initialization complete. Exiting Controller Constructor "); +} + +DataReaderController::~DataReaderController() +{ + if (m_fR && m_fR->isOpen()) m_fR->closeFile(); + + while (!m_stack.empty()) { + EventStackLayer *tmp = m_stack.top(); + m_stack.pop(); + if (tmp != m_markForDeletion and tmp != m_filehandler) + delete tmp; + } + + if (m_markForDeletion != 0) + { + delete m_markForDeletion; + m_markForDeletion = 0; + } + + if(m_filehandler) delete m_filehandler; + if(m_fR) delete m_fR; +} + + +void DataReaderController::initialize() +{ + + //Now we load all the Instances onto the stack. filehandler will return an instance of type ESLMergeFile or ESLOriginalFile, this instance will report (method doneLoading) if it is finished. In case of the Originalfilereader, this will be true, in case of the MergeFileReader, this will be false, because the mergereader will want to load an originalfile inside. The process continues and the stack is filled. The resulting Stack should have a top element ready for Data to be read. + + bool done=false; + while (!done) + { + ERS_DEBUG(2, m_stack.top()->identify() << " openNext() called"); + EventStackLayer *ELSnew = m_stack.top()->openNext(); + ERS_DEBUG(2, ELSnew->identify() << " instantiated"); + + + //ELSnew->prepare(); + // prepare is already done in openNext. + + if (ELSnew->responsibleforMetaData()) + { + //if this lyer is responsible for metadata, it is linked to the internal pointer of Controller. Controller will the relay metadata requests to this layer. great. + m_responsibleForMetaData = ELSnew; + } + + ELSnew->setCaller(m_stack.top()); + + m_stack.push( ELSnew ); + ERS_DEBUG(2, ELSnew->identify() << " put on stack"); + + done = ELSnew->doneLoading(); + ERS_DEBUG(2, ELSnew->identify() << " reported doneLoading: " << done); + } + +} + +bool DataReaderController::good() const +{ + return m_stack.size()? m_stack.top()->moreEvents():false; +} + +bool DataReaderController::endOfFile() const +{ + //this is just to keep compatibility with calling code. they want to know i f a file just finished + + bool a = m_last_file_finished; + //m_last_file_finished = false; + return a; +} + +bool DataReaderController::endOfFileSequence() const +{ + return false; +} + + + +//DRError DataReaderController::getData(unsigned int &eventSize, char **event, int64_t pos = -1 , bool memAlreadyAlloc = false, int64_t allocSizeInBytes = -1) +DRError DataReaderController::getData(DAQFormats::EventFull*& theEvent, int64_t pos) +{ + + int64_t oldpos = 0; + m_last_file_finished=false; + + + if (m_markForDeletion != 0) + { + delete m_markForDeletion; + m_markForDeletion = 0; + } + + //if the position is defined, we need to remember the old position + //and jump to the given position + if ( pos != -1) + { + oldpos = this->getPosition(); + this->setPosition(pos); + } + + + DRError res = m_stack.top()->getData(theEvent, -1); + + + + //if position was defined, we need to jump back to the old position BEFORE checking for more events. Else if we are reading by offset, the program will crash. + if ( pos != -1) + { + this->setPosition(oldpos); + } + + + + if ( !(m_stack.top()->moreEvents()) ) + { + ERS_DEBUG(2, " No more Events on top of stack "); + //this is the "main loop". It handles the switching from one originalfile to the next, from one mergefile to the next etc. + while ( !m_stack.empty() && !m_stack.top()->moreEvents() ) +{ + ERS_DEBUG(2, m_stack.top()->identify() << " has more events?: answer was " << m_stack.top()->moreEvents() ); + + EventStackLayer *old = m_stack.top(); + bool success = old->finished(); + + //the following line we only use to report to the caller that just a file was closed + if ( m_responsibleForMetaData == old ) + m_last_file_finished = true; + + + ERS_DEBUG(2, old->identify() << " finished? " << success); + + m_stack.pop(); + + ERS_DEBUG(2, " Popping " << old->identify() << " from stack"); + + if (success && !m_stack.empty()) m_stack.top()->advance(); + + if (!m_stack.empty() && m_stack.top()->handlesContinuation()) + { + bool end = (old->endOfFileSequence() || !m_sequenceReading); + if (!end) +{ + //if the continuation is given, we ask for the next file + unsigned int nextSN = old->nextInSequence(m_cFileNumber); + ERS_DEBUG(2, " Next in Sequence is " << nextSN); + string next = this->nextInContinuation(nextSN); + + m_stack.top()->setContinuationFile(next); + +} + + } //if continuation is not handled, nothing happens + if (old != m_responsibleForMetaData && old != m_filehandler) + { + //we preserve the m_metaDataResponsible Object. + delete old; + } + else if (old == m_responsibleForMetaData) + { + //the user probably still wants to read metadata, so we keep in mind that in the next get_data, this must be deleted + m_markForDeletion = old; + } + //while-loop will just continue to pop + } //end of while loop + + if (m_stack.empty()) + { + //if the stack is empty, we are finished + ERS_DEBUG(1, " Run finished, no more events "); + m_finished = true; + } + else + { + ERS_DEBUG(2, " Continuing "); + //this will put the next redable item(s) on the stack + initialize(); + } + + }//end of moreEvents + + //now everything should be in order, so let's read data + + + return res; + +} + +DRError DataReaderController::getData(DAQFormats::EventFull*& theEvent) { + return getData(theEvent, -1); +} +/* +DRError DataReaderController::getDataPreAlloced(unsigned int &eventSize, char **event, int64_t allocSizeInBytes) +{ + return getData(eventSize, event, -1, true, allocSizeInBytes); +} + +DRError DataReaderController::getDataPreAllocedWitPos(unsigned int &eventSize, char **event, int64_t allocSizeInBytes, int64_t pos ) +{ + return getData(eventSize, event, pos, true, allocSizeInBytes); +} +*/ + + +void DataReaderController::setPosition(int64_t position) +{ + //if a setPosition takes place, only the instance on the stack that can handle position can do it. We are poppoing the stack until we find a responsible Instance. + + EventStackLayer *old = 0; + + while ( !m_stack.top()->handlesOffset() ) + { + + old = m_stack.top(); + m_stack.pop(); + //delete old; + // WARNING: possible memory leak, if more than one Layer is popped. This should not be possible in current implementation. + if (m_stack.empty()) + { + FaserEventStorage::ES_InternalError ci(ERS_HERE, "EventStack is empty. This should not happen."); + throw ci; + + } + } + //now we should be at the instance where the responisble instance is at top. + + //Please note: This only works if OriginalFile Layer is the last after Mergefile layer. There is however no reason yet to think this will change. famous last words :-~ + + EventStackLayer *off = m_stack.top()->loadAtOffset(position, old); + + if (! (m_stack.top() == off) ) + { + m_stack.push( off ); + } + + + if (old && old != off) //we need to delete the old one, if the new one is not the same as the old one + { + //ERS_DEBUG(1, " deleting old " << old); + delete old; + } + //after this procedure, the correct originalFilehandler should be on top of the stack and ready for reading + + m_finished = false;//we assume the user knows what he's doing and doesnt jump to an end of a file + + +} + +int64_t DataReaderController::getPosition() const +{ + return m_fR->getPosition(); +} + +std::string DataReaderController::fileName() const +{ + return m_responsibleForMetaData->fileName(); +} + +unsigned int DataReaderController::fileStartDate() const +{ + return m_responsibleForMetaData->fileStartDate(); +} + +unsigned int DataReaderController::fileStartTime() const +{ + return m_responsibleForMetaData->fileStartTime(); +} + + +unsigned int DataReaderController::currentFileNumber() const +{ + return m_cFileNumber; +} + + +DRError DataReaderController::enableSequenceReading() +{ + ERS_DEBUG(2,"DataReaderBase::enableSequenceReading() is called. " + <<"Try parsing file name\n"<<m_fileName); + + daq::RawFileName thename(m_fileName); + + if (!thename.hasValidTrailer()) + { + ERS_DEBUG(1," Test of file name parsing has failed. " + <<"File sequence reading not enabled."); + return DRNOSEQ; + } + else + { + m_sizeOfFileNumber = daq::RAWFILENAME_FILE_NUMBER_LENGTH; + m_cFileNumber = thename.fileSequenceNumber(); + m_fileNameCore = thename.fileNameCore(); + + ERS_DEBUG(1," fileNameCore: " << m_fileNameCore); + + m_sequenceReading=true; + + // check if the actual name of this file corresponds to + // the fileName reported inside the file + std::string test = fileName(); // name from meta-data inside the file + if(test != m_fileName) + { + ERS_DEBUG(1," The name of this file is different from the fileName " + << " reported inside the file itself. " + << "File sequence reading not enabled."); + return DRNOSEQ; + } + + return DROK; + } + + /**** OLD code here - will be trhown away in due time + + std::string tail= daq::RAWFILENAME_EXTENSION_FINISHED; + + std:: string::size_type tailPos=m_fileName.rfind(tail); + + if(tailPos==std::string::npos) { + ERS_DEBUG(3,"File name does not contain "<<tail); + return DRNOSEQ; + } + if(tailPos+tail.size() != m_fileName.size()) { + ERS_DEBUG(3,"File name does not end with "<<tail); + return DRNOSEQ; + } + + std::string nameCore=m_fileName.substr(0,tailPos); + ERS_DEBUG(3,"File name without the tail "<<nameCore); + + std::string digits("0123456789"); + std::string::size_type numPos=nameCore.find_last_not_of(digits); + ++numPos; + if(numPos==string::npos) return DRNOSEQ; + + std::string num=nameCore.substr(numPos,nameCore.size()); + ERS_DEBUG(3,"Expecting file number in this string <"<<num<<">."); + + m_sizeOfFileNumber=num.size(); + ERS_DEBUG(3,"Size of the number "<<m_sizeOfFileNumber); + if(m_sizeOfFileNumber==0) return DRNOSEQ; + + m_cFileNumber=atoi(num.c_str()); + ERS_DEBUG(3,"File number "<<m_cFileNumber); + + m_fileNameCore=nameCore.substr(0,numPos); + ERS_DEBUG(3,"File name core "<<nameCore); + + ERS_DEBUG(2,"Finished parsing, now test the result."); + + m_sequenceReading=true; + + std::string test = fileName(); + + if(test != m_fileName) { + ERS_DEBUG(1,"Test of file name parsing has failed. " + <<"File sequence reading not enabled."); + return DRNOSEQ; + } + + // --m_cFileNumber; // will be incremented at 1st open + return DROK; + + End of OLD code + ****/ +} + + +std::string DataReaderController::nextInContinuation(unsigned int expected) +{ + int numFailed=20; + m_cFileNumber = expected; + + while(numFailed){ + std::string next = this->sequenceFileName(true); + + if (m_fR->fileExists(next)){ + ERS_DEBUG(2, "fRead reported " << next << " exists"); + return next; + }else{ + ERS_DEBUG(2, "fRead reported " << next << " does not exist"); + m_cFileNumber++; + numFailed--; + } + } + + //Problem + FaserEventStorage::ES_SquenceNextFileMissing ci(ERS_HERE, "EndOfSequenceFlag was not found and 18 files with continuous sequnce number were not found. Aborting"); + throw ci; + + return ""; +} + + +unsigned int DataReaderController::runNumber() const +{ + return m_responsibleForMetaData->runNumber(); +} +unsigned int DataReaderController::maxEvents() const +{ + return m_responsibleForMetaData->maxEvents(); +} +unsigned int DataReaderController::recEnable() const +{ + return m_responsibleForMetaData->recEnable(); +} +unsigned int DataReaderController::triggerType() const +{ + return m_responsibleForMetaData->triggerType(); +} +std::bitset<128> DataReaderController::detectorMask() const +{ + return m_responsibleForMetaData->detectorMask(); +} +unsigned int DataReaderController::beamType() const +{ + return m_responsibleForMetaData->beamType(); +} +unsigned int DataReaderController::beamEnergy() const +{ + return m_responsibleForMetaData->beamEnergy(); +} + + +CompressionType DataReaderController::compression() const{ + return m_responsibleForMetaData->compression(); +} + +std::vector<std::string> DataReaderController::freeMetaDataStrings() const +{ + ERS_DEBUG(1, "Upper level is " << m_stack.top()->getCaller()->identify()); + + std::vector<std::string> result; + // if (m_stack.top()->getCaller()->identify()=="ESLMerge") + // { //if a mergefiles is read, always return empty metadata + // return result; + // } + // else + // { + result = m_responsibleForMetaData->freeMetaDataStrings(); + // } + + + ERS_DEBUG(1, "RESP " << m_responsibleForMetaData->identify() << " ;et"); + + + std::vector<std::string> cleaned_result; + + std::vector<std::string> reserved; + reserved.push_back("Stream="); + reserved.push_back("Project="); + reserved.push_back("LumiBlock="); + reserved.push_back("GUID="); + reserved.push_back("Compression="); + + + for (unsigned int i = 0 ; i < result.size(); i++) + { + //check for Stream + + int is_reserved = 0; + for (unsigned int res = 0 ; res < reserved.size(); res++) + { + std::string ptn = reserved.at(res); + std::string::size_type pos=result.at(i).find(ptn); + if (pos==std::string::npos) + { + //ERS_DEBUG(1, "String " << result.at(i) << "Not reserved"); + } + else + { + ERS_DEBUG(1, "String " << result.at(i) << "reserved"); + is_reserved=1; + } + } + if (!is_reserved) + cleaned_result.push_back(result.at(i)); + + } + + return cleaned_result; + + +} + +std::string DataReaderController::GUID() const +{ + return m_responsibleForMetaData->GUID(); +} + + + +unsigned int DataReaderController::fileEndDate() +{ + return m_responsibleForMetaData->fileEndDate(); +} +///< Date when writing has stopped. +unsigned int DataReaderController::fileEndTime() +{ + return m_responsibleForMetaData->fileEndTime(); +} +///< Time when writing has stopped. +unsigned int DataReaderController::eventsInFile() +{ + return m_responsibleForMetaData->eventsInFile(); +} +///< Number of events in this file. +unsigned int DataReaderController::dataMB_InFile() +{ + return m_responsibleForMetaData->dataMB_InFile(); +} +///< Number of megabytes in this file. +unsigned int DataReaderController::eventsInFileSequence() +{ + return m_responsibleForMetaData->eventsInFileSequence(); +} +///< Number of events in this file sequence written so far. + + +unsigned int DataReaderController::fileSizeLimitInDataBlocks() const +{ + return m_responsibleForMetaData->fileSizeLimitInDataBlocks(); +} + +unsigned int DataReaderController::fileSizeLimitInMB() const +{ + return m_responsibleForMetaData->fileSizeLimitInMB(); +} + +std::string DataReaderController::appName() const +{ + /*if (m_responsibleForMetaData->identify()=="ESLMerge") + { + return m_filehandler->getAppName(); + } + else + */ + return m_responsibleForMetaData->appName(); +} + +std::string DataReaderController::fileNameCore() const +{ + /*if (m_responsibleForMetaData->identify()=="ESLMerge") + { + return m_filehandler->getFileNameCore(); + } + else*/ + + return m_responsibleForMetaData->fileNameCore(); +} + +unsigned int DataReaderController::dataMB_InFileSequence() +{ + ERS_DEBUG(1,"DataReaderController::dataMB_InFileSequence called but not implemented."); + return 0; + //return m_filehandler->getSum(); +} + + + + +///< Number of MB in this file sequence written so far. +//unsigned int DataReaderController::fileStatusWord() +//{ +// return m_responsibleForMetaData->fileStatusWord(); +//} +///< Indicates an end of sequence. + + +std::string DataReaderController::sequenceFileName(bool isReady) const +{ + ERS_DEBUG(2,"DataReaderBase::sequenceFileName(...) is called."); + + daq::RawFileName name(m_fileNameCore, + m_cFileNumber, + isReady?daq::RAWFILENAME_EXTENSION_FINISHED:daq::RAWFILENAME_EXTENSION_UNFINISHED); + ERS_DEBUG(2," fileNameCore: " << m_fileNameCore); + + ERS_DEBUG(2,"sequenceFileName returns " << name.fileName()); + return name.fileName(); + + /**** OLD code here - will be trhown away in due time + std::ostringstream n; + + n << m_fileNameCore; + n << std::setw(m_sizeOfFileNumber) << std::setfill('0'); + n << m_cFileNumber; + + if(isReady) n << daq::RAWFILENAME_EXTENSION_FINISHED; + else n << daq::RAWFILENAME_EXTENSION_UNFINISHED; + + std::string name = n.str(); + + ERS_DEBUG(2,"sequenceFileName returns " << name); + return name; + + End of OLD code + ***/ +} + +uint32_t DataReaderController::lumiblockNumber() +{ + return m_responsibleForMetaData->lumiblockNumber(); +} +std::string DataReaderController::stream() +{ + return m_responsibleForMetaData->stream(); +} +std::string DataReaderController::projectTag() +{ + return m_responsibleForMetaData->projectTag(); +} + + + +unsigned int DataReaderController::latestDataNumber() const +{ + return 1; +} + + +//void mythrowE(std::string errormessage) +//{ +// FaserEventStorage::ReadingIssue ci(ERS_HERE, errormessage.c_str()); +// throw ci; +//} + + diff --git a/Event/FaserEventStorage/src/DataReaderController.h b/Event/FaserEventStorage/src/DataReaderController.h new file mode 100644 index 0000000000000000000000000000000000000000..c55745c4c97b0885919685ce9344901dad1741e8 --- /dev/null +++ b/Event/FaserEventStorage/src/DataReaderController.h @@ -0,0 +1,122 @@ +#ifndef FASERDATAREADERCONTOLLER_H +#define FASERDATAREADERCONTOLLER_H + +#include <fstream> +#include <vector> +#include <stack> +#include <stdint.h> + +#include "FaserEventStorage/DataReader.h" +#include "FaserEventStorage/EventStorageIssues.h" + +namespace DAQFormats { + class EventFull; +} +class EventStackLayer; +class fRead; +class FESLMultiFile; + +namespace FaserEventStorage +{ + + class DataReaderController : public DataReader + { + public: + DataReaderController(fRead *fR, std::string filename); + ~DataReaderController(); + + void initialize(); + + DRError enableSequenceReading(); + + void setPosition(); //sets global position in file + int64_t getPosition() const;//gets current position in the file + void setPosition(int64_t pos); + + bool good() const; + bool endOfFile() const; + bool endOfFileSequence() const; + + unsigned int currentFileNumber() const; + + + // DRError getData(unsigned int &eventSize, char **event, int64_t pos , bool memAlreadyAlloc, int64_t allocSizeInBytes ); + DRError getData(DAQFormats::EventFull*& theEvent); + DRError getData(DAQFormats::EventFull*& theEvent, int64_t pos); + + // DRError getDataPreAlloced(unsigned int &eventSize, char **event, int64_t allocSizeInBytes); + + //DRError getDataPreAllocedWitPos(unsigned int &eventSize, char **event, int64_t allocSizeInBytes, int64_t pos = -1); + + + /*methods to delete + virtual bool fileWasFound() const = 0; + + */ + + unsigned int runNumber() const ; + unsigned int maxEvents() const ; + unsigned int recEnable() const ; + unsigned int triggerType() const ; + std::bitset<128> detectorMask() const ; + unsigned int beamType() const ; + unsigned int beamEnergy() const ; + std::string GUID() const; + + + std::vector<std::string> freeMetaDataStrings() const; + + CompressionType compression() const; + + std::string fileName() const; + + unsigned int fileStartDate() const; + unsigned int fileStartTime() const; + + unsigned int fileEndDate(); ///< Date when writing has stopped. + unsigned int fileEndTime() ; ///< Time when writing has stopped. + unsigned int eventsInFile() ; ///< Number of events in this file. + unsigned int dataMB_InFile() ; ///< Number of megabytes in this file. + unsigned int eventsInFileSequence() ; ///< Number of events in this file sequence written so far. + unsigned int dataMB_InFileSequence() ; ///< Number of MB in this file sequence written so far. + //unsigned int fileStatusWord() ; ///< Indicates an end of sequence. + + unsigned int fileSizeLimitInDataBlocks() const ; + unsigned int fileSizeLimitInMB() const ; + std::string appName() const ; + std::string fileNameCore() const ; + + uint32_t lumiblockNumber(); + std::string stream(); + std::string projectTag(); + + unsigned int latestDataNumber() const; + + private: + std::string nextInContinuation(unsigned int expected); + std::string sequenceFileName(bool isReady) const; + + + private: + std::stack<EventStackLayer*> m_stack; + fRead* m_fR; + bool m_sequenceReading; + bool m_finished; + FESLMultiFile* m_filehandler; //the file handler //now unused + bool m_last_file_finished; + EventStackLayer* m_responsibleForMetaData; + EventStackLayer* m_markForDeletion; + + unsigned int m_sizeOfFileNumber; + unsigned int m_cFileNumber; + std::string m_fileNameCore; + std::string m_fileName; + }; + + // fRead *fReadFactory(); +} + +void mythrowE(std::string errormessage); + +#endif + diff --git a/Event/FaserEventStorage/src/ESLMultiFile.cxx b/Event/FaserEventStorage/src/ESLMultiFile.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f7378e1f734c04a6185aab44c3fc9fe896095944 --- /dev/null +++ b/Event/FaserEventStorage/src/ESLMultiFile.cxx @@ -0,0 +1,167 @@ +#include "FaserEventStorage/fRead.h" +#include "ESLMultiFile.h" +//#include "ESLMergeFile.h" +#include "ESLOriginalFile.h" +#include "DataReaderController.h" +//#include "MergedRawFile.h" +#include "EventStorage/RawFileName.h" + +FESLMultiFile::FESLMultiFile(fRead* fR) : EventStackLayer(fR) { + m_me = "FESLMulti"; + ERS_DEBUG(3, identify() << " Constructor called booya"); + m_currentFileIndex = 0 ; + m_sumsize = 0; + m_rawfilename = NULL; +} + +FESLMultiFile::FESLMultiFile(){ + m_rawfilename = NULL; +} + + +//This methods takes the next string from the vector, opens, the file and tries to look at the starting marker. According to this, it decides if the file is an originalfile or a mergefile. + +EventStackLayer* FESLMultiFile::openNext() +{ + + EventStackLayer* nextESL = 0; + + //m_currentFileIndex++; //this is already done in moreEvents; + + + if ( m_fR->isOpen() ) { + ERS_DEBUG(3, " Closing open file "); + m_fR->closeFile(); + } + + std::string next = m_filenames.at(m_currentFileIndex); + + ERS_DEBUG(3, this->identify() << " Trying to open next file: " << next); + + m_fR->openFile(next); + + ERS_DEBUG(3, this->identify() << " file opened " << next); + + m_fR->setCurrentEndOfFile(-1); + + ERS_DEBUG(3, this->identify() << " set current end of " << next); + + //m_rawfilename = new daq::RawFileName(next); + + // ET - no marker? + //uint32_t marker = m_fR->readuint32_t(); + + + ERS_DEBUG(3, this->identify() << " reading start " << next); + + // ET - comment out everything related to reading file start marker + //if ( marker == FILE_START_MARKER) //It's an Original File + // { + ERS_DEBUG(1, this->identify() << " found original file"); + + FESLOriginalFile* tmpofp = new FESLOriginalFile(m_fR); + tmpofp -> setFile(next); + tmpofp -> handleOffset(); + tmpofp -> setResponsibleForMetaData(); + + nextESL = tmpofp; + // } + // elseif ( marker == MergedRawFile::FileMarker ) //It's a Merged File + // { + + // ERS_DEBUG(1, this->identify() << " found merge file"); + + // ESLMergeFile* tmpmf = new ESLMergeFile(m_fR); + // tmpmf -> setFile(next); + // tmpmf -> handleOffset(); + // tmpmf -> setResponsibleForMetaData(); + + // nextESL = tmpmf; + // } + // else + // { + // FaserEventStorage::ES_WrongFileFormat ci(ERS_HERE, "file is of no know format. Abort."); + // throw ci; + + // } + + + nextESL->prepare(); + + // This looks for file-end sequence (which we don't have) + // but it is caught, so OK + try + { + m_sumsize += nextESL->dataMB_InFile(); + } + catch(...) + { + + } + + return nextESL; + +} + +bool FESLMultiFile::handlesContinuation() +{ + return true; +} + +void FESLMultiFile::prepare() +{ + return; +} + +bool FESLMultiFile::doneLoading() +{ + //multifile cannot be the last level, since it has to load either the mergefile or the originalfile. + return false; +} + +void FESLMultiFile::advance() +{ + m_currentFileIndex++; + ERS_DEBUG(1, this->identify() << " advancing to next file " << m_currentFileIndex); +} + +bool FESLMultiFile::moreEvents() +{ + ERS_DEBUG(3, this->identify() << " asked for more events "); + + + if (m_filenames.size() == 0 ) return false; + if (m_currentFileIndex > m_filenames.size()-1) + { + m_finished = true; + return false; + } + return true; +} + +unsigned int FESLMultiFile::getSum() +{ + return m_sumsize; + +} + + +void FESLMultiFile::setContinuationFile(std::string next) +{ + ERS_DEBUG(2, " Pushing : " << next << " on " << identify()); + m_filenames.push_back(next); + ERS_DEBUG(2, " size now : " << m_filenames.size() ); +} + +void FESLMultiFile::setFile(std::string filename) +{ + m_filenames.push_back(filename); +} + +void FESLMultiFile::setFiles(std::vector<std::string> filenames) +{ + m_filenames = filenames; +} + + + diff --git a/Event/FaserEventStorage/src/ESLMultiFile.h b/Event/FaserEventStorage/src/ESLMultiFile.h new file mode 100644 index 0000000000000000000000000000000000000000..5a810d6790afe1e4d98e920e632a839827bc21d2 --- /dev/null +++ b/Event/FaserEventStorage/src/ESLMultiFile.h @@ -0,0 +1,51 @@ +#ifndef FASERESLMULTIFILE_H +#define FASERESLMULTIFILE_H + + +#include "FaserEventStorage/fRead.h" +#include "EventStackLayer.h" +#include "EventStorage/RawFileName.h" +#include <vector> + +using namespace FaserEventStorage; + +class FESLMultiFile : public EventStackLayer +{ + protected: + FESLMultiFile(); + + public: + FESLMultiFile(fRead* fR); + + + EventStackLayer* openNext(); + + void prepare(); + bool doneLoading(); + + bool moreEvents() ; + bool handlesContinuation() ; + + void setContinuationFile(std::string next) ; + + void advance(); + + unsigned int getSum(); + + //distinct methods + void setFile(std::string filename); + void setFiles(std::vector<std::string> filenames); + + + + private: + std::vector<std::string> m_filenames; + unsigned int m_currentFileIndex; + unsigned int m_sumsize; + daq::RawFileName *m_rawfilename; + +}; + + +#endif + diff --git a/Event/FaserEventStorage/src/ESLOriginalFile.cxx b/Event/FaserEventStorage/src/ESLOriginalFile.cxx new file mode 100644 index 0000000000000000000000000000000000000000..5a5ad768110604778783946e415fe503260c8e4a --- /dev/null +++ b/Event/FaserEventStorage/src/ESLOriginalFile.cxx @@ -0,0 +1,654 @@ +#include "ESLOriginalFile.h" +#include "FaserEventStorage/EventStorageIssues.h" +#include "DataReaderController.h" +//#include "compression/compression.h" +//#include "compression/DataBuffer.h" +#include "EventFormats/DAQFormats.hpp" + +#include <stdio.h> +#include <string.h> + +FESLOriginalFile::FESLOriginalFile( fRead * m_fR) : EventStackLayer(m_fR) +{ + m_me = "FESLOriginal"; + + ERS_DEBUG(3, identify() << " Constructor called "); + + uint64_t cpos = m_fR->getPosition(); + m_fR->setPositionFromEnd(0); + m_cfilesize = m_fR->getPosition(); + m_fR->setPosition(cpos); + + ERS_DEBUG(3, identify() << " File size found: " << m_cfilesize); + + m_endOfFile = false; + m_fer_read = false; + m_advance_fer_updated = false; + + m_compression = FaserEventStorage::NONE; + //m_uncompressed = new compression::DataBuffer(); + +} + +FESLOriginalFile::~FESLOriginalFile() +{ + //delete m_uncompressed; + ERS_DEBUG(3, identify() <<" destroyed ") ; +} + + +EventStackLayer* FESLOriginalFile::openNext() +{ + return 0; + //does nothing +} + + +//DRError FESLOriginalFile::getData(unsigned int &eventSize, char **event, int64_t pos, bool memAlreadyAlloc, int64_t allocSizeInBytes) +DRError FESLOriginalFile::getData(DAQFormats::EventFull*& theEvent, int64_t pos) +{ + ERS_DEBUG(2,"Entered FESLOriginalFile::getData()."); + + if(pos>0) m_fR->setPosition(pos); +//uint64_t startofevent = m_fR->getPosition(); // we will need this in case of reading failure. + + // Don't allow stale data + if (theEvent != NULL) delete theEvent; + theEvent = new DAQFormats::EventFull(); + + // Read data header + size_t sizeofHeader = theEvent->header_size(); + char* buffer = new char[sizeofHeader]; + + if (NULL == buffer) { + ERS_DEBUG(1, " tried to allocate " << theEvent->header_size() << " bytes for header but failed!"); + FaserEventStorage::ES_AllocatingMemoryFailed ci(ERS_HERE, "FESLOriginalFile tried to allocate memory for header but failed. Abort."); + throw ci; + } + + m_fR->readData(buffer, sizeofHeader); + theEvent->loadHeader((uint8_t*)buffer, sizeofHeader); + + delete[] buffer; + + ERS_DEBUG(2,"DATA HEADER: Expected event size " << theEvent->size()); + + // Now we have the event length, create buffer to store this + size_t sizeofPayload = theEvent->payload_size(); + buffer = new char[sizeofPayload]; + + if (NULL == buffer) { + ERS_DEBUG(1, "Tried to allocate " << sizeofPayload << " bytes for payload but failed!"); + FaserEventStorage::ES_AllocatingMemoryFailed ci(ERS_HERE, "FESLOriginalFile tried to allocate memory for payload but failed. Abort."); + throw ci; + } + + // Check if we will read beyond the end of the file + uint64_t cpos = m_fR->getPosition(); + ERS_DEBUG(3, "currentposition" << cpos) ; + uint64_t remaining = m_cfilesize - cpos; + + if (remaining < sizeofPayload) { + ERS_DEBUG(1, "Requested " << sizeofHeader + << " bytes but only remains " << remaining << " in file "); + + FaserEventStorage::ES_OutOfFileBoundary ci(ERS_HERE, "Trying to read more data than remains in the file. This could mean that either your event is truncated, or that the event size record of this event is corrupted. If you still want to read the data, catch this exception and proceed. The data block contains the rest of the data. "); + throw ci; + + // In case this gets caught, although thee loadPayload will throw its own error + m_fR->readData(buffer, remaining); + theEvent->loadPayload((uint8_t*)buffer, remaining); + + return DRNOOK; + + } else { + + // OK, read event + m_fR->readData(buffer, sizeofPayload); + theEvent->loadPayload((uint8_t*)buffer, sizeofPayload); + + } + ERS_DEBUG(2, "Event:\n" << *theEvent); + + ERS_DEBUG(3,"Finished reading the event."); + + //CHECK FOR END OF FILE REACHED + if( /*m_fR->isEoF()*/ m_cfilesize<=m_fR->getPosition()) { + //isEoF only tells you an end of file if you already hit the eof. it doesn't tell you if ou are exactly at the limit. therefore we check like that + ReadingIssue ci(ERS_HERE,"no event record found where expected. A problem with file format. The file may not have been properly closed."); + ers::warning(ci); + m_error = true; + m_finished = true; + + + FaserEventStorage::ES_NoEndOfFileRecord rci(ERS_HERE, "End of File reached directly after Event. No end of File record found where expected. The file may not have been properly closed. To proceed anyway, catch this exception. However, the requested Data has been read correctly."); + throw rci; + + + return DRNOOK; + } + + // Need some check for end of file?? + + /* + // check for end of file record + if(unfile_record(&m_latest_fer,&file_end_pattern) != 0) { + ERS_DEBUG(3,"Found end of file record after an event."); + m_endOfFile = true; + m_fer_read = true; + m_finished = true; + + // check end of run + } + */ + return DROK; +} + + + +EventStackLayer* FESLOriginalFile::loadAtOffset(int64_t position, EventStackLayer *old) +{ + if(old){}; //Avoid compilation warning + + if (m_cfilesize <= position) + { + FaserEventStorage::ES_OutOfFileBoundary ci(ERS_HERE, "Trying to jump outside Filesize Boundary. Abort."); + throw ci; + + } + m_fR->setPosition(position); + return this; +} + +void FESLOriginalFile::prepare() +{ + // ET - Mainly reads metadata. + // No metadata, so basically skip this + + /* + ERS_DEBUG(2,"Read metadata from the beginning of the file."); + + file_start_record tmpfsr = file_start_pattern; + tmpfsr.version = 0x0; + + + if(unfile_record(&m_latest_fsr,&tmpfsr) == 0) { + ERS_DEBUG(2,"File start record not found after fopen."); + FaserEventStorage::ES_WrongFileFormat ci(ERS_HERE, "File start record not found after fopen.. FESLOriginalFile reported: File Format is not known. Abort"); + throw ci; + } + + ERS_DEBUG(2,"File start record found after fopen. version "<< m_latest_fsr.version); + + m_latest_fns=unfile_name_strings(); + + if(m_latest_fns.appName=="there was") { + ERS_DEBUG(3,"File name strings not found in file."); + FaserEventStorage::ES_WrongFileFormat ci(ERS_HERE, "FESLOriginalFile reported: File name strings not found in file."); + throw ci; + } else { + ERS_DEBUG(3,"File name strings found."); + } + + readOptionalFreeMetaDataStrings(); + + checkCompression(); + + if (m_latest_fsr.version == 0x2) { + ERS_DEBUG(3,"Version 2 found. Switching to compability mode."); + + v2_internal_run_parameters_record v2_internal_rpr; + if(unfile_record(&v2_internal_rpr,&v2_run_parameters_pattern) == 0) { + ERS_DEBUG(3,"Run parameters record not found in file."); + FaserEventStorage::ES_WrongFileFormat ci(ERS_HERE, "FESLOriginalFile reported: Old Run parameters record not found in file."); + throw ci; + } else { + ERS_DEBUG(3,"Run parameters record found."); + m_internal_latest_rpr.marker=v2_internal_rpr.marker; + m_internal_latest_rpr.record_size=v2_internal_rpr.record_size; + m_internal_latest_rpr.run_number=v2_internal_rpr.run_number; + m_internal_latest_rpr.max_events=v2_internal_rpr.max_events; + m_internal_latest_rpr.rec_enable=v2_internal_rpr.rec_enable; + m_internal_latest_rpr.trigger_type=v2_internal_rpr.trigger_type; + m_internal_latest_rpr.detector_mask_1of4=v2_internal_rpr.detector_mask; + m_internal_latest_rpr.detector_mask_2of4=0; + m_internal_latest_rpr.detector_mask_3of4=0; + m_internal_latest_rpr.detector_mask_4of4=0; + m_internal_latest_rpr.beam_type=v2_internal_rpr.beam_type; + m_internal_latest_rpr.beam_energy=v2_internal_rpr.beam_energy; + } + + } else if (m_latest_fsr.version == 0x5) { + ERS_DEBUG(3,"Version 5 found. Switching to compability mode."); + + v5_internal_run_parameters_record v5_internal_rpr; + if(unfile_record(&v5_internal_rpr,&v5_run_parameters_pattern) == 0) { + ERS_DEBUG(3,"Run parameters record not found in file."); + FaserEventStorage::ES_WrongFileFormat ci(ERS_HERE, "FESLOriginalFile reported: Old Run parameters record not found in file."); + throw ci; + } else { + ERS_DEBUG(3,"Run parameters record found."); + m_internal_latest_rpr.marker=v5_internal_rpr.marker; + m_internal_latest_rpr.record_size=v5_internal_rpr.record_size; + m_internal_latest_rpr.run_number=v5_internal_rpr.run_number; + m_internal_latest_rpr.max_events=v5_internal_rpr.max_events; + m_internal_latest_rpr.rec_enable=v5_internal_rpr.rec_enable; + m_internal_latest_rpr.trigger_type=v5_internal_rpr.trigger_type; + m_internal_latest_rpr.detector_mask_1of4=v5_internal_rpr.detector_mask_1of2; + m_internal_latest_rpr.detector_mask_2of4=v5_internal_rpr.detector_mask_2of2; + m_internal_latest_rpr.detector_mask_3of4=0; + m_internal_latest_rpr.detector_mask_4of4=0; + m_internal_latest_rpr.beam_type=v5_internal_rpr.beam_type; + m_internal_latest_rpr.beam_energy=v5_internal_rpr.beam_energy; + } + + } else if (m_latest_fsr.version == 0x6) { + ERS_DEBUG(3,"New version found."); + + if(unfile_record(&m_internal_latest_rpr,&run_parameters_pattern) == 0) { + ERS_DEBUG(1,"Run parameters record not found in file."); + FaserEventStorage::ES_WrongFileFormat ci(ERS_HERE, "FESLOriginalFile reported: Run parameters record not found in file."); + throw ci; + } else { + ERS_DEBUG(3,"Run parameters record found."); + } + } else { + FaserEventStorage::ES_WrongFileFormat ci(ERS_HERE, "FESLOriginalFile reported: File Format Version is not known. Abort"); + throw ci; + } + + ERS_DEBUG(2,"All metadata OK at the beginning of the file."); + + if(unfile_record(&m_latest_fer,&file_end_pattern) != 0) + { + //ERS_WARNING("No event data. This file contains only metadata. " + // <<"End of file metadata found after the run parameters record."); + ERS_DEBUG(3,"End Record right after metadata. This OriginalFile contains only metadata."); + + m_endOfFile = true; + m_fer_read = true; + + } + */ + ERS_DEBUG(1,"File " << fileName() << " ready for reading."); + +} + +bool FESLOriginalFile::doneLoading() +{ + return true; //an original file is not further merging anything +} + + +bool FESLOriginalFile::moreEvents() +{ + ERS_DEBUG(3, m_me <<" more events: "<< (!m_endOfFile && !m_error)); + return (!m_endOfFile && !m_error); +} + + +void FESLOriginalFile::readOptionalFreeMetaDataStrings() +{ + ERS_DEBUG(3,"readOptionalFreeMetaDataStrings not implemented!"); + } + +void FESLOriginalFile::checkCompression() +{ + // Always none + m_compression = FaserEventStorage::NONE; + /* + std::string comp = extractFromMetaData(FaserEventStorage::compressiontag+"="); + + if(comp != ""){ + m_compression = string_to_type(comp); + ERS_DEBUG(1,"Compressed file found. FMS: "<< comp << " Type: " + << m_compression); + } + */ +} + + +unsigned int FESLOriginalFile::fileStartDate() const +{ + return m_latest_fsr.date; +} + +unsigned int FESLOriginalFile::fileStartTime() const +{ + return m_latest_fsr.time; +} + + +std::vector<std::string> FESLOriginalFile::freeMetaDataStrings() const +{ + return m_fmdStrings; +} + +FaserEventStorage::CompressionType FESLOriginalFile::compression() const { + return m_compression; +} + +//Run parameter get records +unsigned int FESLOriginalFile::runNumber() const { + return m_internal_latest_rpr.run_number; +} + + +unsigned int FESLOriginalFile::maxEvents() const { + return m_internal_latest_rpr.max_events; +} + + +unsigned int FESLOriginalFile::recEnable() const { + return m_internal_latest_rpr.rec_enable; +} + + +unsigned int FESLOriginalFile::triggerType() const { + return m_internal_latest_rpr.trigger_type; +} + + +std::bitset<128> FESLOriginalFile::detectorMask() const { + + uint64_t tmp = m_internal_latest_rpr.detector_mask_4of4; + tmp <<= 32; + tmp |= m_internal_latest_rpr.detector_mask_3of4; + + std::bitset<128> mask(tmp); + mask <<= 64; + + tmp = m_internal_latest_rpr.detector_mask_2of4; + tmp <<= 32; + tmp |= m_internal_latest_rpr.detector_mask_1of4; + + mask |= tmp; + return mask; +} + +unsigned int FESLOriginalFile::beamType() const { + return m_internal_latest_rpr.beam_type; +} + +unsigned int FESLOriginalFile::beamEnergy() const { + return m_internal_latest_rpr.beam_energy; +} + + +unsigned int FESLOriginalFile::fileEndDate() +{ + + if(!m_advance_fer_updated) { + m_latest_fer = currentFileFER(); + m_advance_fer_updated = true; + } + + return m_latest_fer.date; +} + + +unsigned int FESLOriginalFile::fileEndTime() +{ + + if(!m_advance_fer_updated) { + m_latest_fer = currentFileFER(); + m_advance_fer_updated = true; + } + + return m_latest_fer.time; +} + + +// This doesn't really work... +unsigned int FESLOriginalFile::eventsInFile() +{ + + if(!m_advance_fer_updated) { + m_latest_fer = currentFileFER(); + m_advance_fer_updated = true; + } + + //return m_latest_fer.events_in_file; + return 2; // Avoid no events in file error +} + + +unsigned int FESLOriginalFile::dataMB_InFile() +{ + + if(!m_advance_fer_updated) { + m_latest_fer = currentFileFER(); + m_advance_fer_updated = true; + } + + return m_latest_fer.data_in_file; +} + + +unsigned int FESLOriginalFile::eventsInFileSequence() +{ + + if(!m_advance_fer_updated) { + m_latest_fer = currentFileFER(); + m_advance_fer_updated = true; + } + + return m_latest_fer.events_in_run; +} + + +unsigned int FESLOriginalFile::dataMB_InFileSequence() +{ + + if(!m_advance_fer_updated) { + m_latest_fer = currentFileFER(); + m_advance_fer_updated = true; + } + + return m_latest_fer.data_in_run; +} + + +unsigned int FESLOriginalFile::fileSizeLimitInDataBlocks() const +{ + return m_latest_fsr.sizeLimit_dataBlocks; +} + +unsigned int FESLOriginalFile::fileSizeLimitInMB() const +{ + return m_latest_fsr.sizeLimit_MB; +} + +std::string FESLOriginalFile::appName() const +{ + return m_latest_fns.appName; +} + +std::string FESLOriginalFile::fileNameCore() const +{ + return m_latest_fns.fileNameCore; +} + + + + + +unsigned int FESLOriginalFile::fileStatusWord() +{ + + if(!m_advance_fer_updated) { + m_latest_fer = currentFileFER(); + m_advance_fer_updated = true; + } + + return m_latest_fer.status; +} + +bool FESLOriginalFile::endOfFileSequence() +{ + if (m_error) return true; + ERS_DEBUG(3, identify() << " status word has value " << this->fileStatusWord()); + return this->fileStatusWord(); + +} + +unsigned int FESLOriginalFile::nextInSequence(unsigned int current) +{ + return current+1; //stupid, but original file format does not support next/prev +} + + +file_end_record FESLOriginalFile::currentFileFER() { + ERS_DEBUG(3,"FESLOriginalFile::currentFileFER() called."); + + file_end_record cfFER=file_end_pattern; + + /* + int64_t pos = m_fR->getPosition(); + + //forward to the end and reverse a bit now and + int64_t back=sizeof(file_end_pattern); + m_fR->setPositionFromEndSafe(-back); + + if (unfile_record(&cfFER,&file_end_pattern)!= 0) + { + m_advance_fer_updated = true; + }; + + // rewind back + m_fR->setPosition(pos); + + if(cfFER.date==0) + { + ERS_DEBUG(3,"No end of file record found"); + FaserEventStorage::ES_NoEndOfFileRecord ci(ERS_HERE, "FESLOriginalFile reported: File end record not found in file. If you still want to read data from this file, either catch these excpetions or don't ask for information inside the EOF Record"); + throw ci; + + } + */ + return cfFER; +} + +internal_run_parameters_record FESLOriginalFile::getRunParameterrecord() +{ + return m_internal_latest_rpr; +} + +std::string FESLOriginalFile::GUID() const +{ + ERS_DEBUG(2,"DataReaderBase::GUID() called."); + if(m_fmdStrings.size()==0) { + ERS_DEBUG(2,"No metadata strings in this file. Return empty GUID string."); + return std::string(""); + } + std::string guid = m_fmdStrings[0]; + std::string ptn("GUID="); + std::string::size_type pos=guid.find(ptn); + if(pos==std::string::npos) { + ERS_DEBUG(2,"No GUID in metadata strings of this file. Return empty GUID string."); + return std::string(""); + } + pos+=ptn.size(); + guid=guid.substr(pos,guid.size()); + + ERS_DEBUG(2,"Returning "<<guid); + return guid; +} + +uint32_t FESLOriginalFile::lumiblockNumber() +{ + ERS_DEBUG(2,"DataReaderBase::lumiblockNumber() called."); + std::string lumistring = extractFromMetaData("LumiBlock="); + if (lumistring =="") + { + ERS_DEBUG(2,"No Lumiblock Info found. returning 0"); + return 0; + } + std::istringstream i(lumistring); + i >> m_lumiblockNumber; + + return m_lumiblockNumber; +} + +std::string FESLOriginalFile::stream() +{ + m_stream = extractFromMetaData("Stream="); + return m_stream; +} + +std::string FESLOriginalFile::projectTag() +{ + m_projectTag = extractFromMetaData("Project="); + return m_projectTag; +} + + +file_name_strings FESLOriginalFile::unfile_name_strings() +{ + + int64_t pos = m_fR->getPosition(); + + uint32_t tst; + + FaserEventStorage::file_name_strings nst; + nst.appName="there was"; nst.fileNameCore="a problem"; + + m_fR->readData((char *)(&tst),sizeof(uint32_t)); + if(tst != FaserEventStorage::file_name_strings_marker) { + m_fR->setPosition(pos); + return nst; + } + + uint32_t size=0; + m_fR->readData((char *)(&size),sizeof(uint32_t)); + + char *csn=new char[size]; + m_fR->readData(csn,size); + std::string name(csn,size); + delete [] csn; + + char buf[4]; + char ns = size % 4; + if(ns) m_fR->readData(buf,4-ns); + + m_fR->readData((char *)(&size),sizeof(uint32_t)); + + char *cst=new char[size]; + m_fR->readData(cst,size); + std::string tag(cst,size); + delete [] cst; + + ns = size % 4; + if(ns) m_fR->readData(buf,4-ns); + + nst.appName = name; + nst.fileNameCore = tag; + + return nst; +} + +std::string FESLOriginalFile::extractFromMetaData(std::string token) +{ + ERS_DEBUG(2,"DataReaderBase::extractFromMetaData() called: " << token); + if(m_fmdStrings.size()==0) + { + ERS_DEBUG(2,"No metadata strings in this file. Return empty string"); + return ""; + } + for (unsigned int i=0; i< m_fmdStrings.size(); i++) + { + std::string cs = m_fmdStrings.at(i); + std::string::size_type pos=cs.find(token); + if(pos==std::string::npos) + { /*not foundokay */} + else + { + pos+=token.size(); + std::string result=cs.substr(pos,cs.size()); + return result; + } + } + ERS_DEBUG(2,"No "<< token <<" found in metadata strings of this file. Return emptystring."); + return ""; +} + diff --git a/Event/FaserEventStorage/src/ESLOriginalFile.h b/Event/FaserEventStorage/src/ESLOriginalFile.h new file mode 100644 index 0000000000000000000000000000000000000000..2ce8e3527e4e3d09ba53095ad874defce4f62ab4 --- /dev/null +++ b/Event/FaserEventStorage/src/ESLOriginalFile.h @@ -0,0 +1,111 @@ +#ifndef ESLORIGINALFILE_H +#define ESLORIGINALFILE_H + + +#include "EventStackLayer.h" +#include "FaserEventStorage/fRead.h" + +using namespace FaserEventStorage; + +// Forward declaration +namespace DAQFormats { + class EventFull; +} + +class FESLOriginalFile : public EventStackLayer +{ + + public: + FESLOriginalFile( fRead * fR); + ~FESLOriginalFile( ); + + EventStackLayer* openNext(); + EventStackLayer* loadAtOffset(int64_t position, EventStackLayer *old); + + void prepare(); + bool doneLoading(); + + //DRError getData(unsigned int &eventSize, char **event, int64_t pos, bool memAlreadyAlloc, int64_t allocSizeInBytes); + DRError getData(DAQFormats::EventFull*& theEvent, int64_t pos); + + bool moreEvents() ; + //bool handlesOffset() ; + //bool handlesContinuation() ; + //std::string nextInContinuation() ; + //bool endOfFileSequence() ; + + + //additonal + internal_run_parameters_record getRunParameterrecord(); + + std::string GUID() const; + + unsigned int runNumber() const ; + unsigned int maxEvents() const ; + unsigned int recEnable() const ; + unsigned int triggerType() const ; + std::bitset<128> detectorMask() const ; + unsigned int beamType() const ; + unsigned int beamEnergy() const ; + std::vector<std::string> freeMetaDataStrings() const; + CompressionType compression() const; + + unsigned int fileStartDate() const ; + unsigned int fileStartTime() const; + + unsigned int fileEndDate() ; + unsigned int fileEndTime() ; + unsigned int eventsInFile() ; + unsigned int dataMB_InFile() ; + unsigned int eventsInFileSequence() ; + unsigned int dataMB_InFileSequence(); + unsigned int fileStatusWord(); + bool endOfFileSequence() ; + unsigned int nextInSequence(unsigned int current) ; + + uint32_t lumiblockNumber(); + std::string stream(); + std::string projectTag(); + + unsigned int fileSizeLimitInDataBlocks() const ; + unsigned int fileSizeLimitInMB() const ; + std::string appName() const ; + std::string fileNameCore() const ; + + + + + private: + void readOptionalFreeMetaDataStrings(); + void checkCompression(); + file_end_record currentFileFER(); + + file_name_strings m_latest_fns; + + bool m_endOfFile; + bool m_fer_read; + + int64_t m_cfilesize; + + file_start_record m_latest_fsr; + data_separator_record m_latest_dsr; + + file_end_record m_latest_fer; + bool m_advance_fer_updated ; + uint32_t m_lumiblockNumber; + std::string m_stream; + std::string m_projectTag; + + file_name_strings unfile_name_strings(); + + FaserEventStorage::freeMetaDataStrings m_fmdStrings; + internal_run_parameters_record m_internal_latest_rpr; + + std::string extractFromMetaData(std::string token); + + FaserEventStorage::CompressionType m_compression; + //compression::DataBuffer * m_uncompressed; +}; + + +#endif diff --git a/Event/FaserEventStorage/src/EventStackLayer.cxx b/Event/FaserEventStorage/src/EventStackLayer.cxx new file mode 100644 index 0000000000000000000000000000000000000000..23dbc99fbd29d6392c7ed30816ffc03b37d45f16 --- /dev/null +++ b/Event/FaserEventStorage/src/EventStackLayer.cxx @@ -0,0 +1,281 @@ +#include "ers/ers.h" +#include <fstream> +#include <vector> +#include <stack> +#include "EventStackLayer.h" +#include "DataReaderController.h" +#include "FaserEventStorage/EventStorageIssues.h" + +#include "EventFormats/DAQFormats.hpp" + +EventStackLayer::EventStackLayer( fRead* fR ) +{ + //by default, this just sets the fileReader + ERS_DEBUG(2,"EventStackLayer gets fRead Object "); + m_fR = fR; + m_handleCont=false; + m_handleOffs=false; + m_responsibleMetaData=false; + m_finished = false; + m_error = false; + m_caller = NULL; +} + +bool EventStackLayer::finished() +{ + return m_finished; +} + +void EventStackLayer::advance() +{ + +} + + +DRError EventStackLayer::getData(DAQFormats::EventFull*& theEvent, int64_t pos) +{ + if (theEvent){}; + std::ostringstream os; + os << "EventStackLayerinterface::getData() was called, " + << " but should not have been called for this type of file!" + << " position: " << pos ; + + FaserEventStorage::ES_InternalError ci(ERS_HERE, os.str().c_str()); + throw ci; + + return DRNOOK; +} + +EventStackLayer* EventStackLayer::openNext() +{ + return 0; +} + + +EventStackLayer* +EventStackLayer::loadAtOffset(int64_t position, EventStackLayer *old) +{ + (void)old; + if (position < 0) ERS_DEBUG(2," called with negative position!"); + return 0; +} + +bool EventStackLayer::handlesOffset() +{ + return m_handleOffs; +} + +bool EventStackLayer::handlesContinuation() +{ + return m_handleCont; +} + +// std::string EventStackLayer::nextInContinuation() +//{ +//return ""; +//} + + +bool EventStackLayer::endOfFileSequence() +{ + return true; +} + +void EventStackLayer::setContinuationFile(std::string next) +{ + if ( next == "blabla" ) ERS_DEBUG(2, " this is a blabla test"); +} + +void EventStackLayer::setFile( std::string filename) +{ + ERS_DEBUG(3, " SETTING filename " << filename); + m_currentFile = filename; +} + +std::string EventStackLayer::fileName() +{ + return m_currentFile; +} + +bool EventStackLayer::responsibleforMetaData() +{ + return m_responsibleMetaData; +} + +void EventStackLayer::setResponsibleForMetaData() +{ + m_responsibleMetaData=true; +} + +std::string EventStackLayer::GUID() const +{ + return ""; +} + +void EventStackLayer::handleContinuation() +{ + m_handleCont=true; +} + + +unsigned int EventStackLayer::nextInSequence(unsigned int current) +{ + std::ostringstream os; + os << "EventStackLayerinterface::getData() was called, " + << " but should not have been called for this type of file!" + << " Current index: " << current; + + FaserEventStorage::ES_InternalError ci(ERS_HERE, os.str().c_str()); + throw ci; + + return 0; +} + + + +void EventStackLayer::handleOffset() +{ + m_handleOffs=true; +} + +unsigned int EventStackLayer::runNumber() const { FaserEventStorage::ES_InternalError ci(ERS_HERE, "ESL Interface called for metadata. This should not happen. Abort."); + throw ci;return 0;} +unsigned int EventStackLayer::maxEvents() const {FaserEventStorage::ES_InternalError ci(ERS_HERE, "ESL Interface called for metadata. This should not happen. Abort."); + throw ci; return 0;} +unsigned int EventStackLayer::recEnable() const {FaserEventStorage::ES_InternalError ci(ERS_HERE, "ESL Interface called for metadata. This should not happen. Abort."); + throw ci;return 0;} +unsigned int EventStackLayer::triggerType() const {FaserEventStorage::ES_InternalError ci(ERS_HERE, "ESL Interface called for metadata. This should not happen. Abort."); + throw ci; return 0;} +std::bitset<128> EventStackLayer::detectorMask() const {FaserEventStorage::ES_InternalError ci(ERS_HERE, "ESL Interface called for metadata. This should not happen. Abort."); + throw ci; return 0;} +unsigned int EventStackLayer::beamType() const { FaserEventStorage::ES_InternalError ci(ERS_HERE, "ESL Interface called for metadata. This should not happen. Abort."); + throw ci; return 0;} +unsigned int EventStackLayer::beamEnergy() const {FaserEventStorage::ES_InternalError ci(ERS_HERE, "ESL Interface called for metadata. This should not happen. Abort."); + throw ci; return 0;} +std::vector<std::string> EventStackLayer::freeMetaDataStrings() const { + FaserEventStorage::ES_InternalError ci(ERS_HERE, "ESL Interface called for metadata. This should not happen. Abort."); + throw ci; + std::vector<std::string> empty_vec; + return empty_vec; +} + +FaserEventStorage::CompressionType EventStackLayer::compression() const{ + FaserEventStorage::ES_InternalError ci(ERS_HERE, "ESL Interface called for metadata. This should not happen. Abort."); + throw ci; + return FaserEventStorage::NONE; +} + +unsigned int EventStackLayer::fileStartDate() const { FaserEventStorage::ES_InternalError ci(ERS_HERE, "ESL Interface called for metadata. This should not happen. Abort."); + throw ci; return 0; } +unsigned int EventStackLayer::fileStartTime() const { FaserEventStorage::ES_InternalError ci(ERS_HERE, "ESL Interface called for metadata. This should not happen. Abort."); + throw ci; return 0; } + +unsigned int EventStackLayer::fileEndDate() {FaserEventStorage::ES_InternalError ci(ERS_HERE, "ESL Interface called for metadata. This should not happen. Abort."); + throw ci; return 0;} ///< Date when writing has stopped. +unsigned int EventStackLayer::fileEndTime() {FaserEventStorage::ES_InternalError ci(ERS_HERE, "ESL Interface called for metadata. This should not happen. Abort."); + throw ci; return 0;} ///< Time when writing has stopped. +unsigned int EventStackLayer::eventsInFile() {FaserEventStorage::ES_InternalError ci(ERS_HERE, "ESL Interface called for metadata. This should not happen. Abort."); + throw ci; return 0;} ///< Number of events in this file. +unsigned int EventStackLayer::dataMB_InFile() {FaserEventStorage::ES_InternalError ci(ERS_HERE, "ESL Interface called for metadata. This should not happen. Abort."); + throw ci; return 0;} ///< Number of megabytes in this file. +unsigned int EventStackLayer::eventsInFileSequence() {FaserEventStorage::ES_InternalError ci(ERS_HERE, "ESL Interface called for metadata. This should not happen. Abort."); + throw ci; return 0;} ///< Number of events in this file sequence written so far. +// unsigned int EventStackLayer::dataMB_InFileSequence() {mythrowE("ESL Interface called for metadata. Abort"); return 0;} ///< Number of MB in this file sequence written so far. +// unsigned int EventStackLayer::fileStatusWord() {throw 14; return 0;} ///< Indicates an end of sequence. + + +unsigned int EventStackLayer::fileSizeLimitInDataBlocks() const +{ + FaserEventStorage::ES_InternalError ci(ERS_HERE, "ESL Interface called for metadata. This should not happen. Abort."); + throw ci; + return 0; +} + +unsigned int EventStackLayer::fileSizeLimitInMB() const +{ + FaserEventStorage::ES_InternalError ci(ERS_HERE, "ESL Interface called for metadata. This should not happen. Abort."); + throw ci; + return 0; +} + +std::string EventStackLayer::appName() const +{ + FaserEventStorage::ES_InternalError ci(ERS_HERE, "ESL Interface called for metadata. This should not happen. Abort."); + throw ci; + return ""; +} + +std::string EventStackLayer::fileNameCore() const +{ + FaserEventStorage::ES_InternalError ci(ERS_HERE, "ESL Interface called for metadata. This should not happen. Abort."); + throw ci; + return ""; +} + +unsigned int EventStackLayer::dataMB_InFileSequence() +{ + FaserEventStorage::ES_InternalError ci(ERS_HERE, "ESL Interface called for metadata. This should not happen. Abort."); + throw ci; + return 0; +} + + + + +uint32_t EventStackLayer::lumiblockNumber() +{FaserEventStorage::ES_InternalError ci(ERS_HERE, "ESL Interface called for metadata. This should not happen. Abort."); + throw ci; return 0; } + +std::string EventStackLayer::stream() +{FaserEventStorage::ES_InternalError ci(ERS_HERE, "ESL Interface called for metadata. This should not happen. Abort."); + throw ci; return ""; } + +std::string EventStackLayer::projectTag() +{FaserEventStorage::ES_InternalError ci(ERS_HERE, "ESL Interface called for metadata. This should not happen. Abort."); + throw ci; return ""; } + + + +int EventStackLayer::unfile_record(void *ri, const void *pi) +{ + ERS_DEBUG(3,"UNFILE RECORD called "); + uint32_t *record = (uint32_t *)ri; + uint32_t *pattern = (uint32_t *)pi; + int size=pattern[1]; + ERS_DEBUG(3,"reading record of size "<< size); + int64_t pos = m_fR->getPosition(); + + for(int i=0; i<size; i++) + { + ERS_DEBUG(3,"READING "); + if(pattern[i] != 0) +{ + uint32_t tst=0; + m_fR->readData((char *)(&tst),sizeof(uint32_t)); + ERS_DEBUG(3,"GOT "<< tst << " vs " << pattern[i] <<" expected"); + if(not (tst==pattern[i])) + { + m_fR->setPosition(pos); + return 0; + } +} + else +{ + m_fR->readData((char *)(record+i),sizeof(uint32_t)); + ERS_DEBUG(3,"GOT " << *(record+i)); +} + } + return size; +} + +void EventStackLayer::setCaller(EventStackLayer* caller) +{ +m_caller = caller; +} + +EventStackLayer* EventStackLayer::getCaller() +{ +return m_caller; +} + + diff --git a/Event/FaserEventStorage/src/EventStackLayer.h b/Event/FaserEventStorage/src/EventStackLayer.h new file mode 100644 index 0000000000000000000000000000000000000000..138f88aef64702470dd8fedd4899a90eaf810939 --- /dev/null +++ b/Event/FaserEventStorage/src/EventStackLayer.h @@ -0,0 +1,164 @@ +#ifndef FASEREVENTSTACKLAYER_H +#define FASEREVENTSTACKLAYER_H + +#include "ers/ers.h" +#include <fstream> +#include <vector> +#include <stack> +#include <bitset> +#include "FaserEventStorage/DRError.h" +#include "FaserEventStorage/fRead.h" +#include "FaserEventStorage/DRError.h" +#include "FaserEventStorage/EventStorageRecords.h" +#include "EventStorage/RawFileName.h" +#include "FaserEventStorage/ESCompression.h" + +#include "EventStorageInternalRecords.h" + +namespace DAQFormats { +class EventFull; +} + +using namespace FaserEventStorage; + + +class EventStackLayer //=ESL henceforward +{ + protected: + EventStackLayer(): + m_fR(NULL), + m_caller(NULL) + {} + + public: + EventStackLayer( fRead* fR ) ; + + virtual ~EventStackLayer() {}; + + virtual std::string identify() {return m_me;} + + //virtual DRError getData(unsigned int &eventSize, char **event, int64_t pos, bool memAlreadyAlloc, int64_t allocSizeInBytes); + virtual DRError getData(DAQFormats::EventFull*& theEvent, int64_t pos); + + //the interface to instantiate a son-ESL instance. + //e.g. MergeFileReader Instantiates an Originalfilereader + virtual EventStackLayer* openNext(); + + + //the instance that can handle offsets also needs to be able to "load" a new original file. + virtual EventStackLayer* loadAtOffset(int64_t position, EventStackLayer *old); + + + //the interface to prepare a recently instantiated ESL + //this should parse the header (if any), so that either data can be read, or openNext() can be called + virtual void prepare() = 0 ; + + //tells the caller if the instance is ready for data to be read. If true is given, the caller can start with getData. If false is given, openNext() should be called, so the current instance can create an Object to be put on the stack. + virtual bool doneLoading() = 0 ; + + + //tells the caller if more events can be read from this instance. + // - true should be returned if this is an Originalfile and reading is not finished. + // - True should be returned by MergeFileHandler and MultiFileHand have more Originalfiles or MergeFiles to load + // - False should be returned if a Originalfile reader reached the end of the originalfile, or the Mergefilereader has no more Originalfiles or the MultiFilereader is out of files. + virtual bool moreEvents() = 0 ; + + + //this tells the caller if the instance handles offsets inside files. This is important for the get/set Position stuff. If a setPosition is called, the stack will be emptied until an instance is found which can handle offsets. Returns true for mergefilereader and false for multifile. If Multifilereader loads originalfiles directly, Originalfile handles offsets. + virtual bool handlesOffset(); + + //tells the caller if continuation is handled by this instance on the stack + virtual bool handlesContinuation(); + + //if the intance can handle continuation, it needs to provide a ressource, e.g. a filename string to the loader. E.g. Multifilehandler is finished with a file, and it asks the old file which is the next + //virtual std::string nextInContinuation() ; + + //tells if the sequence is at an end + virtual bool endOfFileSequence() ; + + //sets the next "file" to be opened (by Mutifilereader) + virtual void setContinuationFile(std::string next); + + virtual void setFile( std::string filename); + + virtual std::string fileName(); + + //A ESl can be asked id it is rsponsible for metadata responsibiliry + virtual bool responsibleforMetaData(); + + virtual void setResponsibleForMetaData(); + + virtual std::string GUID() const; + + virtual bool finished(); + virtual void advance(); + + void handleContinuation() ; + virtual unsigned int nextInSequence(unsigned int current) ; + + + void handleOffset() ; + + //Run parameter get records + virtual unsigned int runNumber() const; + virtual unsigned int maxEvents() const; + virtual unsigned int recEnable() const ; + virtual unsigned int triggerType() const; + virtual std::bitset<128> detectorMask() const ; + virtual unsigned int beamType() const ; + virtual unsigned int beamEnergy() const; + virtual std::vector<std::string> freeMetaDataStrings() const; + virtual CompressionType compression() const; + + virtual unsigned int fileStartDate() const; + virtual unsigned int fileStartTime() const; + + virtual unsigned int fileEndDate(); ///< Date when writing has stopped. + virtual unsigned int fileEndTime(); ///< Time when writing has stopped. + virtual unsigned int eventsInFile(); ///< Number of events in this file. + virtual unsigned int dataMB_InFile(); ///< Number of megabytes in this file. + virtual unsigned int eventsInFileSequence(); ///< Number of events in this file sequence written so far. + + virtual unsigned int fileSizeLimitInDataBlocks() const ; + virtual unsigned int fileSizeLimitInMB() const ; + virtual std::string appName() const ; + virtual std::string fileNameCore() const ; + + virtual unsigned int dataMB_InFileSequence(); ///< Number of MB in this file sequence written so far. + //virtual unsigned int fileStatusWord(); ///< Indicates an end of sequence. + + virtual uint32_t lumiblockNumber(); + virtual std::string stream(); + virtual std::string projectTag(); + + virtual void setCaller(EventStackLayer* caller); + virtual EventStackLayer* getCaller(); + + + protected: + //This is the raw file access reader + //it is assigned in the constructor + fRead* m_fR; + + EventStackLayer* m_caller; + + bool m_finished; + bool m_error; + + std::string m_me; + bool m_handleCont; + bool m_handleOffs; + + bool m_responsibleMetaData; + std::string m_currentFile; + + //unfile record is used by the inheriting classes + //to read data from the file + int unfile_record(void *ri, const void *pi); + +}; + + + +#endif + diff --git a/Event/FaserEventStorage/src/EventStorageInternalRecords.h b/Event/FaserEventStorage/src/EventStorageInternalRecords.h new file mode 100644 index 0000000000000000000000000000000000000000..c0e5f35b2e0f7b32f1620975039c3830bf4d1bb2 --- /dev/null +++ b/Event/FaserEventStorage/src/EventStorageInternalRecords.h @@ -0,0 +1,91 @@ + +#ifndef FASEREVENTSTORAGE_INTERNAL_RECORDS_H +#define FASEREVENTSTORAGE_INTERNAL_RECORDS_H + + +namespace FaserEventStorage { + + struct internal_run_parameters_record { + uint32_t marker; + uint32_t record_size; + uint32_t run_number; + uint32_t max_events; + uint32_t rec_enable; + uint32_t trigger_type; + uint32_t detector_mask_1of4; + uint32_t detector_mask_2of4; + uint32_t detector_mask_3of4; + uint32_t detector_mask_4of4; + uint32_t beam_type; + uint32_t beam_energy; + }; + + struct v5_internal_run_parameters_record { + uint32_t marker; + uint32_t record_size; + uint32_t run_number; + uint32_t max_events; + uint32_t rec_enable; + uint32_t trigger_type; + uint32_t detector_mask_1of2; + uint32_t detector_mask_2of2; + uint32_t beam_type; + uint32_t beam_energy; + }; + + struct v2_internal_run_parameters_record { + uint32_t marker; + uint32_t record_size; + uint32_t run_number; + uint32_t max_events; + uint32_t rec_enable; + uint32_t trigger_type; + uint32_t detector_mask; + uint32_t beam_type; + uint32_t beam_energy; + }; + + + const internal_run_parameters_record run_parameters_pattern = { + RUN_PARAMETERS_MARKER, + sizeof(internal_run_parameters_record)/sizeof(uint32_t), + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + }; + + const v2_internal_run_parameters_record v2_run_parameters_pattern = { + RUN_PARAMETERS_MARKER, + sizeof(v2_internal_run_parameters_record)/sizeof(uint32_t), + 0, + 0, + 0, + 0, + 0, + 0, + 0 + }; + + const v5_internal_run_parameters_record v5_run_parameters_pattern = { + RUN_PARAMETERS_MARKER, + sizeof(v5_internal_run_parameters_record)/sizeof(uint32_t), + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + }; + +} + +#endif diff --git a/Event/FaserEventStorage/src/EventStorageRecords.cxx b/Event/FaserEventStorage/src/EventStorageRecords.cxx new file mode 100644 index 0000000000000000000000000000000000000000..8017446389d26870365dac63e6c2ea6d05b025b1 --- /dev/null +++ b/Event/FaserEventStorage/src/EventStorageRecords.cxx @@ -0,0 +1,59 @@ +// +// functions to convert records to strings +// for debugging +// +#include <sstream> + +#include "FaserEventStorage/EventStorageRecords.h" + +std::string FaserEventStorage::string_record(void *ri, const void *pi) { + + std::ostringstream s; + + uint32_t *record = (uint32_t *)ri; + uint32_t *pattern = (uint32_t *)pi; + int size=pattern[1]; + + for(int i=0; i<size; i++) { + if(pattern[i] != 0) { + s << std::hex << pattern[i] << std::dec << " "; + } else { + s << record[i] << " "; + } + } + + std::string rs = s.str(); + return rs; +} + +std::string FaserEventStorage::string_record(FaserEventStorage::file_name_strings nst) { + + std::ostringstream s; + + s << std::hex << FaserEventStorage::file_name_strings_marker << std::dec; + + s << " " << nst.appName.size(); + s << " " << nst.appName; + + char ns = nst.appName.size() % 4; + if(ns) s.write("____",4-ns); + + s << " " << nst.fileNameCore.size(); + s << " " << nst.fileNameCore; + + ns = nst.fileNameCore.size() % 4; + if(ns) s.write("____",4-ns); + + std::string rs = s.str(); + return rs; + +} + +void FaserEventStorage::reset_record(void *ri, const void *pi) { + + uint32_t *record = (uint32_t *)ri; + uint32_t *pattern = (uint32_t *)pi; + int size=pattern[1]; + + for(int i=0; i<size; i++) record[i] = pattern[i]; +} diff --git a/Event/FaserEventStorage/src/RawFileName.cxx b/Event/FaserEventStorage/src/RawFileName.cxx new file mode 100644 index 0000000000000000000000000000000000000000..728445a8da3a36b41220210eaac0503dbfed46fc --- /dev/null +++ b/Event/FaserEventStorage/src/RawFileName.cxx @@ -0,0 +1,738 @@ +#include "FaserEventStorage/RawFileName.h" +#include "FaserEventStorage/EventStorageIssues.h" +//----------------- +// includes for ers +#include "ers/ers.h" +//----------------- + +#include <iostream> +#include <sstream> +#include <iomanip> +#include <boost/tokenizer.hpp> + + +namespace daq { + + /** + * Contructor with ingredients given + */ + RawFileName::RawFileName(std::string ProjectTag, + unsigned int RunNumber, + std::string StreamType, + std::string StreamName, + unsigned int LumiBlockNumber, + std::string ApplicationName, + std::string ProductionStep, + std::string DataType, + unsigned int FileSequenceNumber, + std::string Extension): m_core_known(false), + m_trailer_known(false) + { + ERS_DEBUG(1," Constructor with explicit fields"); + + buildFileName(ProjectTag, + RunNumber, + StreamType, + StreamName, + LumiBlockNumber, + ApplicationName, + ProductionStep, + DataType, + FileSequenceNumber, + Extension); + } + + /** + * Constructor with the FileNameCore, a FileSequenceNumber and + * the Extension only - + * Does not alter the FileNameCore, just attaches trailer fields + * to the fileNameCore; also, tries to interpret the resulting filename + * Note: delimiter must be inside the Extension (e.g., ".data") + */ + RawFileName::RawFileName(std::string FileNameCore, + unsigned int FileSequenceNumber, + std::string Extension): m_core_known(false), + m_trailer_known(false) + { + ERS_DEBUG(1," Constructor with fileNameCore, sequenceNumber & extension"); + + setDefaults(); // in case the file name is not interpretable + + buildFileNameTrailers(FileNameCore, + FileSequenceNumber, + Extension); + + m_core_known = interpretFileName(m_fileName); + } + + + /** + * Contructor with just the filename given: for interpretation + */ + RawFileName::RawFileName(std::string FileName): m_core_known(false), + m_trailer_known(false) + { + ERS_DEBUG(1," Constructor with fileName only, for interpretation"); + + setDefaults(); // in case the file name is not interpretable + + m_fileName = FileName; + m_fileNameCore = m_fileName; // can not know any better now... + + m_core_known = interpretFileName(m_fileName); //if OK, made m_fileNameCore + } + + /** + * Destructor + */ + RawFileName::~RawFileName(){ + ERS_DEBUG(1," Destructor!"); + } + + + + std::string RawFileName::getCurrentFileName(bool writing) + { + if (writing) + setTailers(m_fileSequenceNumber, RAWFILENAME_EXTENSION_UNFINISHED); + else + setTailers(m_fileSequenceNumber, RAWFILENAME_EXTENSION_FINISHED); + + return fileName(); + } + + + std::string RawFileName::getCoreName() + { + return m_fileNameCore; + } + + unsigned int RawFileName::getIndex() + { + return m_fileSequenceNumber; + } + + + void RawFileName::fileAlreadyExists() + { + m_fileSequenceNumber+=100; + + } + + void RawFileName::advance() + { + m_fileSequenceNumber+=1; + + } + + + + + /** + * given the ingedients, contruct the fileName + */ + void RawFileName::buildFileName(std::string ProjectTag, + unsigned int RunNumber, + std::string StreamType, + std::string StreamName, + unsigned int LumiBlockNumber, + std::string ApplicationName, + std::string ProductionStep, + std::string DataType, + unsigned int FileSequenceNumber, + std::string Extension) + { + buildFileNameCore(ProjectTag, + RunNumber, + StreamType, + StreamName, + LumiBlockNumber, + ApplicationName, + ProductionStep, + DataType); + + buildFileNameTrailers(m_fileNameCore, // result of buildFileNameCore() + FileSequenceNumber, + Extension); + + return; + } + + /** + * given the ingedients, contruct the fileNameCore + * and set m_core_known = true + */ + void RawFileName::buildFileNameCore(std::string ProjectTag, + unsigned int RunNumber, + std::string StreamType, + std::string StreamName, + unsigned int LumiBlockNumber, + std::string ApplicationName, + std::string ProductionStep, + std::string DataType) + { + if (ProjectTag == "") { ProjectTag = "data_test"; } // default + m_project = ProjectTag; + m_runNumber = RunNumber; + m_streamType = StreamType; + m_streamName = StreamName; + + std::ostringstream stream; + stream << m_streamType << "_" << m_streamName; + m_stream = stream.str(); + + m_lumiBlockNumber = LumiBlockNumber; + m_applicationName = ApplicationName; + m_productionStep = ProductionStep; + m_dataType = DataType; + + std::ostringstream n; + n << ProjectTag << RAWFILENAME_DELIMITER; + n << std::setw(RAWFILENAME_RUN_NUMBER_LENGTH) + << std::setfill('0'); + n << RunNumber << RAWFILENAME_DELIMITER; + n << StreamType << "_"; + n << StreamName << RAWFILENAME_DELIMITER; + n << ProductionStep << RAWFILENAME_DELIMITER; + n << DataType; + m_datasetName = n.str(); + + n << RAWFILENAME_DELIMITER << "_lb"; + n << std::setw(RAWFILENAME_LB_NUMBER_LENGTH) + << std::setfill('0'); + n << LumiBlockNumber << RAWFILENAME_DELIMITER; + n << "_" << ApplicationName; + + m_fileNameCore = n.str(); + + m_core_known = true; // even the fileNameCore is OK to handle fileName + } + + + /** + * construct a complete FileName, by appending a FileSequenceNumber and + * an Extension to the given FileNameCore + * and set m_trailer_known = true + */ + void RawFileName::buildFileNameTrailers(std::string FileNameCore, + unsigned int FileSequenceNumber, + std::string Extension) + { + m_fileNameCore = FileNameCore; + m_fileSequenceNumber = FileSequenceNumber; + m_extension = Extension; + + std::ostringstream n; + n << FileNameCore; + n << RAWFILENAME_DELIMITER + << "_" + << std::setw(RAWFILENAME_FILE_NUMBER_LENGTH) + << std::setfill('0'); + n << FileSequenceNumber; + if ( Extension != "" ) { + if (Extension.c_str()[0] != RAWFILENAME_DELIMITER.c_str()[0]) + { + n << RAWFILENAME_DELIMITER << Extension; + m_extension = RAWFILENAME_DELIMITER + Extension; + } + else + { + n << Extension; // delimiter is already in Extension + } + } + m_fileName = n.str(); + + m_trailer_known = true; + } + + /** + * Default values for the filename fields + * If filename is valid, the correct values will be returned when asked. + */ + void RawFileName::setDefaults() { + m_project = RAWFILENAME_DEFAULT_STRING; + m_runNumber = RAWFILENAME_DEFAULT_UINT; + m_streamType = RAWFILENAME_DEFAULT_STRING; + m_streamName = RAWFILENAME_DEFAULT_STRING; + m_stream = RAWFILENAME_DEFAULT_STRING; + m_lumiBlockNumber = RAWFILENAME_DEFAULT_UINT; + m_applicationName = RAWFILENAME_DEFAULT_STRING; + m_productionStep = RAWFILENAME_DEFAULT_STRING; + m_dataType = RAWFILENAME_DEFAULT_STRING; + m_fileSequenceNumber = RAWFILENAME_DEFAULT_UINT; + m_extension = RAWFILENAME_DEFAULT_STRING; + + + m_fileNameCore = RAWFILENAME_DEFAULT_STRING; + m_fileName = RAWFILENAME_DEFAULT_STRING; + + m_datasetName = RAWFILENAME_DEFAULT_STRING; + + m_core_known = false; + m_trailer_known = false; + } + + /** + * Modify the File Trailer fileds (FileSequence Number and Extension) + */ + void RawFileName::setTailers(unsigned int fsn_i, std::string extension_s) + { + m_fileSequenceNumber = fsn_i; + m_extension = extension_s; + + buildFileNameTrailers(m_fileNameCore, + m_fileSequenceNumber, + m_extension); + + m_core_known = interpretFileName(m_fileName); + } + + /** + * Modify the FileSequenceNumber at the file trailer fields + */ + void RawFileName::setFileSequenceNumber( unsigned int fsn_i ) + { + m_fileSequenceNumber = fsn_i; + if ( !m_trailer_known ) { + m_extension = RAWFILENAME_DEFAULT_STRING; + } + + buildFileNameTrailers(m_fileNameCore, + m_fileSequenceNumber, + m_extension); + + m_core_known = interpretFileName(m_fileName); + } + + /** + * Modify the File Extension at the file trailer fields + */ + void RawFileName::setExtension( std::string extension_s ) + { + m_extension = extension_s; + if ( !m_trailer_known ) { + m_fileSequenceNumber = RAWFILENAME_DEFAULT_UINT; + std::string mystream = "File Sequence number not known. Set this first, before trying to set the extension"; + FaserEventStorage::RawFileNameIssue myissue(ERS_HERE, mystream.c_str() ); + throw myissue; + } + + buildFileNameTrailers(m_fileNameCore, + m_fileSequenceNumber, + m_extension); + + m_core_known = interpretFileName(m_fileName); + } + + + /** + * given the fileName, reconstruct the ingredients + */ + bool RawFileName::interpretFileName(std::string FileName) + { + + ERS_DEBUG(1," interpretFileName: " << FileName + << " (m_core_known = " << m_core_known + << " , m_trailer_known = " << m_trailer_known << " )"); + + /* + std::cout << " interpretFileName: FileName = " << FileName + << " (m_core_known = " << m_core_known + << " , m_trailer_known = " << m_trailer_known << " )" + << std::endl; + */ + + // Before diving into interpretation, check if work is already done + if ( m_core_known && m_trailer_known ) return true; + if ( FileName == "" ) { + m_core_known = false; + m_trailer_known = false; + return false; + } + + // Try to interpretate the filename fields + + // useful things for the spliting of the fileName in fields: + // when spliting with boost tokenizer : + typedef boost::tokenizer<boost::char_separator<char> > tokenizer; + boost::char_separator<char> sep(RAWFILENAME_DELIMITER.c_str(), + "", boost::keep_empty_tokens); + // when spliting with std::string::find() : + std:: string::size_type sepPos; + + // Assuming that the file finishes like: ._sequenceNumber.extension(s) + // we say that after the last "_" in the filename, we have the trailer, + // and before that "_" we have the fileNameCore + + sepPos=FileName.rfind("._"); + if(sepPos==std::string::npos) { + ERS_DEBUG(3,"File name does not contain ._ "); + return false; + } + + // fileNameCore: + m_fileNameCore = FileName.substr(0,sepPos); + + ERS_DEBUG(3,"Checking for . at the end of " << m_fileNameCore ); + if (m_fileNameCore.c_str()[m_fileNameCore.size()-1] == '.') { + m_fileNameCore = m_fileNameCore.substr(0, m_fileNameCore.size()-1); + } + ERS_DEBUG(3,"After removing possible . at the end: " << m_fileNameCore ); + + // tail: + std::string trailers_onestring; + trailers_onestring = FileName.substr(sepPos+2,std::string::npos); //to end + + std::vector<std::string> trailers; + /*** + trailers = split(trailers_onestring, + RAWFILENAME_DELIMITER.c_str()[0]); + ***/ + tokenizer trailer_tokens(trailers_onestring, sep); + trailers.assign(trailer_tokens.begin(), trailer_tokens.end()); + + + + // A) interpret trailers first: + // ---------------------------- + // if the 1st filed in the trailer is a number, + // we can intepret the trailer, else not + if ( !m_trailer_known) { + try { + m_fileSequenceNumber // = atoi( trailers[0].c_str() ); + = convertToUINT( trailers[0] ); + m_trailer_known = true; + std::ostringstream myext; + for (unsigned int i=1; i != trailers.size(); i++) { + if (i != 1) myext << RAWFILENAME_DELIMITER; + myext << trailers[i]; + } + m_extension = myext.str(); + + // build the file name again and set m_trailer_known = true + buildFileNameTrailers(m_fileNameCore, + m_fileSequenceNumber, + m_extension); + m_trailer_known = true; + + } catch (std::exception& ex) { + ERS_DEBUG(1," Can not interpret fileSequenceNumber: " << ex.what() ); + m_trailer_known = false; + m_fileSequenceNumber = RAWFILENAME_DEFAULT_UINT; + m_extension = RAWFILENAME_DEFAULT_STRING; + } + } // try only if trailer details are not known + + ERS_DEBUG(3," =====> Trailer string: " << trailers_onestring + << " has " << trailers_onestring.size() << " characters" + << " ; FileName: " << FileName + << " , fileNameCore: " << m_fileNameCore + << " , m_fileSequenceNumber = " << m_fileSequenceNumber + << " , m_extension = " << m_extension ); + + + // B) Try to interpret the fileNameCore now: + // ----------------------------------------- + if (m_core_known) { + return true; + } + + // we are here only if m_core_known is false: interepret now + std::vector<std::string> fields; + // fields = split( FileName, RAWFILENAME_DELIMITER.c_str()[0] ); + tokenizer core_tokens(FileName, sep); + fields.assign(core_tokens.begin(), core_tokens.end()); + for ( std::vector<std::string>::iterator it=fields.begin(); + it != fields.end(); ++it) { + ERS_DEBUG(3, " field = " << *it); + } + + ERS_DEBUG(3," number of . delimited fields found: " << fields.size()); + + bool can_interpret_core; + if (fields.size() >= 7 && fields[4] == "RAW") { + can_interpret_core=true; + } else { + can_interpret_core=false; + } + + if ( !can_interpret_core ) { + ERS_DEBUG(1," Can not interpret the core of FileName: " << FileName + << " , so keeping " << m_fileNameCore << " as core."); + m_core_known = false; + + } else { + + m_project = fields[0]; + try { + m_runNumber // = atoi( fields[1].c_str() ); + = convertToUINT( fields[1] ); + } catch (std::exception& ex) { + ERS_DEBUG(1," Can not interpret run-number : " << ex.what() ); + return false; // done with intrepreting the core... + } + + m_stream = fields[2]; + + sepPos=m_stream.find("_"); + if(sepPos==std::string::npos) { + ERS_DEBUG(3,"Stream does not contain _ "); + return false; + } + // first part is streamType: + m_streamType = m_stream.substr(0,sepPos); + // second part is streamName: + m_streamName = m_stream.substr(sepPos+1,std::string::npos); // to end + + m_productionStep = fields[3]; + m_dataType = fields[4]; + m_datasetName = "datasetName"; + + try { + sepPos = fields[5].find("b"); + m_lumiBlockNumber = + convertToUINT( fields[5].substr(sepPos+1, std::string::npos) ); + // atoi ( fields[5].substr(sepPos+1, std::string::npos).c_str() ); + } catch (std::exception& ex) { + ERS_DEBUG(1," Can not interpret lumi-block : " << ex.what() ); + // m_lumiBlockNumber = 0; + return false; // done with intrepreting the core... + } + + sepPos = fields[6].find("_"); + m_applicationName = fields[6].substr(sepPos+1, std::string::npos); + + // build the nameCore again and set m_core_known = true + buildFileNameCore(m_project, + m_runNumber, + m_streamType, + m_streamName, + m_lumiBlockNumber, + m_applicationName, + m_productionStep, + m_dataType); + m_core_known=true; + } // if ( !can_interpret_core ) ) + + return m_core_known; + } + + /** + * contruct the complain + */ + std::string RawFileName::complain() + { + std::stringstream mystream; + mystream << "FileName " << m_fileName << " has failed interpretation"; + return mystream.str(); + } + + + /** + * Get methods: + * ------------ + */ + std::string RawFileName::project() { + if ( hasValidCore() ) { + return m_project; + } else { + throw FaserEventStorage::RawFileNameIssue(ERS_HERE, complain().c_str() ); + //FaserEventStorage::RawFileNameIssue myIssue(ERS_HERE, complain() ); + // ers::warning(myIssue); + //throw myIssue; + } + } + + std::string RawFileName::datasetName() { + if ( hasValidCore() ) { + return m_datasetName; + } else { + throw FaserEventStorage::RawFileNameIssue(ERS_HERE, complain().c_str() ); + } + } + + unsigned int RawFileName::runNumber() { + if ( hasValidCore() ) { + return m_runNumber; + } else { + throw FaserEventStorage::RawFileNameIssue(ERS_HERE, complain().c_str() ); + } + } + + + std::string RawFileName::streamType() { + if ( hasValidCore() ) { + return m_streamType; + } else { + throw FaserEventStorage::RawFileNameIssue(ERS_HERE, complain().c_str() ); + } + } + + std::string RawFileName::streamName() { + if ( hasValidCore() ) { + return m_streamName; + } else { + throw FaserEventStorage::RawFileNameIssue(ERS_HERE, complain().c_str() ); + } + } + + + std::string RawFileName::stream() { + if ( hasValidCore() ) { + return m_stream; + } else { + throw FaserEventStorage::RawFileNameIssue(ERS_HERE, complain().c_str() ); + } + } + + unsigned int RawFileName::lumiBlockNumber() { + if ( hasValidCore() ) { + return m_lumiBlockNumber; + } else { + throw FaserEventStorage::RawFileNameIssue(ERS_HERE, complain().c_str() ); + } + } + + std::string RawFileName::applicationName() { + if ( hasValidCore() ) { + return m_applicationName; + } else { + throw FaserEventStorage::RawFileNameIssue(ERS_HERE, complain().c_str() ); + } + } + + std::string RawFileName::productionStep() { + if ( hasValidCore() ) { + return m_productionStep; + } else { + throw FaserEventStorage::RawFileNameIssue(ERS_HERE, complain().c_str() ); + } + } + + std::string RawFileName::dataType() { + if ( hasValidCore() ) { + return m_productionStep; + } else { + throw FaserEventStorage::RawFileNameIssue(ERS_HERE, complain().c_str() ); + } + } + + + unsigned int RawFileName::fileSequenceNumber() { + if ( hasValidTrailer() ) { + return m_fileSequenceNumber; + } else { + throw FaserEventStorage::RawFileNameIssue(ERS_HERE, complain().c_str() ); + } + } + + std::string RawFileName::extension() { + if ( hasValidTrailer() ) { + return m_extension; + } else { + throw FaserEventStorage::RawFileNameIssue(ERS_HERE, complain().c_str() ); + } + } + + + /** + * print the content of this object + */ + void RawFileName::print() + { + std::stringstream mystream; + + mystream << " full fileName: " << m_fileName << std::endl; + mystream << " fileNameCore: " << m_fileNameCore << std::endl; + if(m_core_known) + mystream << " datasetName: " << m_datasetName << std::endl; + + + if (!m_core_known) { + mystream << " Not all core fields known " << std::endl; + } else { + mystream << " project = " << m_project << std::endl; + mystream << " runNo = " << m_runNumber << std::endl; + mystream << " stream = " << m_stream +<< " ( type: " << m_streamType +<< " , name: " << m_streamName << " ) " +<< std::endl; + mystream << " prodStep = " << m_productionStep << std::endl; + mystream << " dataType = " << m_dataType << std::endl; + mystream << " lumiBlock = " << m_lumiBlockNumber << std::endl; + mystream << " appName = " << m_applicationName << std::endl; + } // end-if m_core_known + + if ( !m_trailer_known ) { + mystream << " Tailer fields not known " << std::endl; + } else { + mystream << " seqNumber = " << m_fileSequenceNumber << std::endl; + mystream << " extension = " << m_extension << std::endl; + } // end-if m_trailer_known + + mystream << std::endl; + + std::string tmp = mystream.str(); + + ERS_LOG(tmp.c_str()); + + return; + } + + + /** + * split a string in its fields, using a ONE-CHARACTER-LONG delimiter + */ + std::vector<std::string> RawFileName::split(std::string const & s, + char delimiter) + { + std::vector<std::string> container; + + typedef boost::tokenizer<boost::char_separator<char> > tokenizer; + + std::ostringstream os; + os << delimiter; + boost::char_separator<char> sep(os.str().c_str(), + "", boost::keep_empty_tokens); + + tokenizer tokens(s, sep); + container.assign(tokens.begin(), tokens.end()); + + return container; + } + + /** + * string to integer conversion + */ + unsigned int RawFileName::convertToUINT(const std::string & s) + { + unsigned int x = 0; + std::istringstream i(s); + // check if ALL characters in "s" are numbers; otherwise throw + for ( unsigned int it = 0; it != s.size(); ++it) { + std::ostringstream temp_out; temp_out << s.c_str()[it]; + std::istringstream temp_in(temp_out.str()); + x=0; + if (!(temp_in >> x)) { +std::string mystream = "Failed convertToUINT(\"" + s + "\")"; +FaserEventStorage::RawFileNameIssue myissue(ERS_HERE, mystream.c_str() ); +// ers::warning(ci); +throw myissue; +// throw daq::BadConversion("convertToUINT(\"" + s + "\")"); + } + } + + x=0; + if (!(i >> x)) { + std::string mystream = "Failed convertToUINT(\"" + s + "\")"; + FaserEventStorage::RawFileNameIssue myissue(ERS_HERE, mystream.c_str() ); + // ers::warning(ci); + throw myissue; + // throw daq::BadConversion("convertToUINT(\"" + s + "\")"); + } + + return x; + } + +} + diff --git a/Event/FaserEventStorage/src/fReadPlain.cxx b/Event/FaserEventStorage/src/fReadPlain.cxx new file mode 100644 index 0000000000000000000000000000000000000000..03c880d2a207229cfbbe9d2425a1b018de222ea1 --- /dev/null +++ b/Event/FaserEventStorage/src/fReadPlain.cxx @@ -0,0 +1,148 @@ +#include "ers/ers.h" +#include "fReadPlain.h" +#include "EventStorage/EventStorageIssues.h" + + +fReadPlain::fReadPlain() +{ +} + +fReadPlain::~fReadPlain() +{ + this->closeFile(); +} + +bool fReadPlain::isOpen() +{ + return m_cFile.is_open(); +} + +bool fReadPlain::isEoF() +{ + if(this->isOpen()) { + return m_cFile.eof(); + } else { + return false; + } +} + +bool fReadPlain::fileExists(std::string fName) const +{ + std::ifstream testFile; + testFile.open(fName.c_str(),std::ios::binary | std::ios::in); + + bool isThere = testFile.good(); + + if(isThere) testFile.close(); + + return isThere; +} + +void fReadPlain::openFile(std::string fName) +{ + if(this->isOpen()) this->closeFile(); + + m_cFile.clear(); + m_cFile.open(fName.c_str(),std::ios::binary | std::ios::in); +} + +void fReadPlain::closeFile() +{ + m_cFile.close(); +} + +void fReadPlain::readData(char *buffer, unsigned int sizeBytes) +{ + if (sizeBytes==0) return; + + if(!m_cFile.is_open()) { + std::stringstream mystream; + mystream << "an attempt to read from a file that is not open. " + <<"fReadPlain::readData called to read " + <<sizeBytes<<" bytes."; + std::string err = mystream.str(); + EventStorage::ReadingIssue ci(ERS_HERE, err.c_str()); + ers::warning(ci); + return; + } + + if(m_cFile.eof()) { + std::stringstream mystream; + mystream << "error reading data from disk. " + <<"fReadPlain called to read " + <<sizeBytes<<" bytes and finds EOF."; + std::string err = mystream.str(); + EventStorage::ReadingIssue ci(ERS_HERE, err.c_str()); + ers::warning(ci); + return; + } + + if(m_cFile.bad()) { + std::stringstream mystream; + mystream << "error reading data from disk. " + <<"fReadPlain called to read " + <<sizeBytes<<" bytes and finds that the bad flag is set."; + std::string err = mystream.str(); + EventStorage::ReadingIssue ci(ERS_HERE, err.c_str()); + ers::warning(ci); + return; + } + + m_cFile.read(buffer,sizeBytes); + + if(m_cFile.bad()) { + std::stringstream mystream; + mystream << "error reading data from disk. " + <<"fReadPlain finds the file in bad state after trying to read " + <<sizeBytes<<" bytes."; + std::string err = mystream.str(); + EventStorage::ReadingIssue ci(ERS_HERE, err.c_str()); + ers::warning(ci); + } else if(m_cFile.eof()) { + std::stringstream mystream; + mystream << "error reading data from disk. " + <<"fReadPlain finds EOF after trying to read " + <<sizeBytes<<" bytes."; + std::string err = mystream.str(); + EventStorage::ReadingIssue ci(ERS_HERE, err.c_str()); + ers::warning(ci); + } +} + +int64_t fReadPlain::getPosition() +{ + if(this->isOpen()) { + std::streampos pos=m_cFile.tellg(); + return pos; + } + return -1; +} + +void fReadPlain::setPosition(int64_t p) +{ + if(this->isOpen()) { + std::streampos pos=p; + m_cFile.seekg(pos); + } +} + +void fReadPlain::setPositionFromEnd(int64_t p) +{ + if(this->isOpen()) { + m_cFile.seekg(p,std::ios::end); + } +} + +fRead * fReadPlain::newReader() const +{ + fReadPlain * nfr = new fReadPlain(); + return (fRead *)nfr; +} + +extern "C" { + fRead *fReadFactory() + { + fReadPlain * nfr = new fReadPlain(); + return (fRead *)nfr; + } +} diff --git a/Event/FaserEventStorage/src/fReadPlain.h b/Event/FaserEventStorage/src/fReadPlain.h new file mode 100644 index 0000000000000000000000000000000000000000..3fe6738d4f867b0e15b6327b018dc93dcf7fc939 --- /dev/null +++ b/Event/FaserEventStorage/src/fReadPlain.h @@ -0,0 +1,35 @@ + +#ifndef FREADPLAIN_H +#define FREADPLAIN_H + +#include <fstream> +#include <string> + +#include "FaserEventStorage/fRead.h" + +class fReadPlain : public fRead +//class fReadPlain +{ + public: + fReadPlain(); + ~fReadPlain(); + + bool isOpen(); + bool isEoF(); + bool fileExists(std::string fName) const; + void openFile(std::string fName); + void closeFile(); + void readData(char *buffer, unsigned int sizeBytes); + int64_t getPosition(); + void setPosition(int64_t p); + void setPositionFromEnd(int64_t p); + fRead * newReader() const; + + private: + std::ifstream m_cFile; // current file +}; + +// fRead *fReadFactory(); + +#endif + diff --git a/Event/FaserEventStorage/src/loadfRead.cxx b/Event/FaserEventStorage/src/loadfRead.cxx new file mode 100644 index 0000000000000000000000000000000000000000..0404e7385d766594d22dc3bc3e634f13e372d8db --- /dev/null +++ b/Event/FaserEventStorage/src/loadfRead.cxx @@ -0,0 +1,40 @@ +#include <dlfcn.h> +#include "ers/ers.h" + +#include "FaserEventStorage/fRead.h" +#include "FaserEventStorage/loadfRead.h" + +fRead * loadfRead(std::string libName){ + + ERS_DEBUG(2,"loadfRead called with library name "<<libName); + + ::dlerror(); + + libName += ".so"; + libName = "lib" + libName; + + void * lib = ::dlopen(libName.c_str(), RTLD_NOW | RTLD_GLOBAL); + + if (!lib || ::dlerror() ) { + ERS_DEBUG(1,"Cannot load library"); + return NULL; + } + + ERS_DEBUG(2,"Library OK, now find the symbol."); + + ::dlerror(); + + // fun is defined to be: + // a pointer to a function which takes no arguments "()" + // and returns fRead* (e.g., look in fReadPlain fReadFactory) + typedef fRead* (*fun)(); + fun sym = (fun)::dlsym(lib, "fReadFactory"); + + if (!sym || ::dlerror()) { + ERS_DEBUG(1,"No symbol"); + return NULL; + } + ERS_DEBUG(2,"Symbol is OK, now get the reader."); + + return sym(); // this returns an "fRead*" +} diff --git a/Event/FaserEventStorage/src/pickFaserDataReader.cxx b/Event/FaserEventStorage/src/pickFaserDataReader.cxx new file mode 100644 index 0000000000000000000000000000000000000000..e800e22aa88fe4358dfa4562d051747a12677769 --- /dev/null +++ b/Event/FaserEventStorage/src/pickFaserDataReader.cxx @@ -0,0 +1,132 @@ +#include "ers/ers.h" +#include "FaserEventStorage/fRead.h" +#include "FaserEventStorage/loadfRead.h" +#include "FaserEventStorage/pickFaserDataReader.h" +#include "FaserEventStorage/EventStorageIssues.h" +#include "DataReaderController.h" + +DataReader * pickFaserDataReader(std::string fileName) { + + ERS_DEBUG(1,"pickFaserDataReader(file) with file name "<<fileName); + + std::vector<std::string> fReadLibs; + fReadLibs.push_back("fReadPlain"); // Just use plain + + /* + // Control plugins libraries via file name prefixes. + // Take the prefixes away from the name, in most cases anyway. + if(fileName.find("rfio:")==0) { + fileName.erase(0,std::string("rfio:").size()); + fReadLibs.push_back("fReadCastor"); + } else if(fileName.find("dcache:")==0) { + fileName.erase(0,std::string("dcache:").size()); + fReadLibs.push_back("fReaddCache"); + } else if(fileName.find("dcap:")==0) { + // Leave the prefix in the file name in this case. + fReadLibs.push_back("fReaddCache"); + } else if(fileName.find("root:")==0) { + // Leave the prefix in the file name in this case. + fReadLibs.push_back("fReadXRootD"); + } else if(fileName.find("https:")==0) { + // Leave the prefix in the file name in this case. + fReadLibs.push_back("fReadDavix"); + } else if(fileName.find("davs:")==0) { + // Leave the prefix in the file name in this case. + fReadLibs.push_back("fReadDavix"); + } else if(fileName.find("disk:")==0) { + fileName.erase(0,std::string("disk:").size()); + fReadLibs.push_back("fReadPlain"); + } else { // by defaul all will be tried + fReadLibs.push_back("fReadPlain"); + fReadLibs.push_back("fReadCastor"); + fReadLibs.push_back("fReadXRootD"); + fReadLibs.push_back("fReadDavix"); + fReadLibs.push_back("fReaddCache"); + } + */ + ERS_DEBUG(2,"After parsing the file name is "<<fileName); + ERS_DEBUG(2,"Number of fRead plugins to try is "<<fReadLibs.size()); + + std::vector<std::string>::iterator fReadLib=fReadLibs.begin(); + fRead *pfR = NULL; + + std::vector<std::string> libsNotLoaded; + std::vector<std::string> libsNoSuccess; + libsNotLoaded.clear(); libsNoSuccess.clear(); + + for(fReadLib=fReadLibs.begin(); fReadLib!=fReadLibs.end(); ++fReadLib) { + ERS_DEBUG(2,"Try to with lib "<<(*fReadLib)); + + pfR = loadfRead(*fReadLib); + if (!pfR) { + ERS_DEBUG(2,"No fRead"); + libsNotLoaded.push_back(*fReadLib); + continue; + } + ERS_DEBUG(2,"fRead* OK. Try to open the data file "<<fileName); + + pfR->openFile(fileName); + + ERS_DEBUG(2,"Is the file open? "<<pfR->isOpen()); + if(!pfR->isOpen()) { + ERS_DEBUG(2,"Can not open file "<<fileName<<" with library "<<(*fReadLib)); + libsNoSuccess.push_back(*fReadLib); + delete pfR; + pfR=NULL; + continue; + } else { + break; + } + } + + if(pfR==NULL || !pfR->isOpen()) { + if(libsNoSuccess.size()>0) { + std::string libList=""; + std::vector<std::string>::iterator it; + for(it = libsNoSuccess.begin(); it != libsNoSuccess.end(); ++it) { + libList += *it + " "; + } + //ERS_ERROR("Can not open file "<<fileName + //<<"\nThe following libraries were tried: "<<libList); + std::stringstream mystream; + mystream << "can not open file "<<fileName + <<"\nThe following libraries were tried: "<<libList; + std::string err = mystream.str(); + ReadingIssue ci(ERS_HERE, err.c_str()); + ers::error(ci); + } + if(libsNotLoaded.size()>0) { + std::string libList=""; + std::vector<std::string>::iterator it; + for(it = libsNotLoaded.begin(); it != libsNotLoaded.end(); ++it) { +libList += *it + " "; + } + //ERS_WARNING("Can not load libraries: "<<libList); + std::string err = "can not load libraries: " + libList; + ReadingIssue ci(ERS_HERE, err.c_str()); + ers::warning(ci); + } + + return NULL; + } + + // We have a working fRead and the file is accessible. + + ERS_DEBUG(1,"The file is accessible. Go through file format now."); + + pfR->closeFile(); + + DataReader * pDR = NULL; + try{ + pDR = new DataReaderController(pfR,fileName); + }catch(FaserEventStorage::ES_WrongFileFormat &ex){ + ReadingIssue ci(ERS_HERE,"file format not valid for EventStorage.", ex); + ers::warning(ci); + return NULL; + } + + ERS_DEBUG(1,"File format is OK."); + + return pDR; +} + diff --git a/faser-common b/faser-common new file mode 160000 index 0000000000000000000000000000000000000000..d526df399f57bafedb86111851d63d98f90adddf --- /dev/null +++ b/faser-common @@ -0,0 +1 @@ +Subproject commit d526df399f57bafedb86111851d63d98f90adddf