diff --git a/Examples/CMakeLists.txt b/Examples/CMakeLists.txt index 7db41df710f98228150f5d40ba0decdc44c71c5d..f9f4c9d92f6f09025b391d2fb50a756371fe8006 100644 --- a/Examples/CMakeLists.txt +++ b/Examples/CMakeLists.txt @@ -3,6 +3,7 @@ gaudi_subdir(Examples v0r0) find_package(podio REQUIRED) find_package(plcio REQUIRED) +find_package(LCIO REQUIRED) set(Examples_srcs src/HelloWorld/*.cpp @@ -17,8 +18,8 @@ gaudi_install_headers(Examples) # Modules gaudi_add_module(Examples ${Examples_srcs} - INCLUDE_DIRS GaudiKernel FWCore ${plcio_INCLUDE_DIRS} ${podio_INCLUDE_DIRS} - LINK_LIBRARIES GaudiKernel FWCore ${podio_LIBRARIES} $ENV{PLCIO}/lib/libplcio.so + INCLUDE_DIRS GaudiKernel FWCore ${plcio_INCLUDE_DIRS} ${podio_INCLUDE_DIRS} ${LCIO_INCLUDE_DIRS} + LINK_LIBRARIES GaudiKernel FWCore ${podio_LIBRARIES} ${LCIO_LIBRARIES} $ENV{PLCIO}/lib/libplcio.so ) # Unit tests @@ -33,3 +34,7 @@ gaudi_add_test(PlcioWriteAlg gaudi_add_test(PlcioReadAlg FRAMEWORK options/plcio_read.py) + +gaudi_add_test(LCIOReadAlg + FRAMEWORK options/LCIO_read.py) + diff --git a/Examples/options/LCIO_read.py b/Examples/options/LCIO_read.py new file mode 100644 index 0000000000000000000000000000000000000000..372754e269fd92a66bd47f1c6e51038f211c2ac1 --- /dev/null +++ b/Examples/options/LCIO_read.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python + +from Gaudi.Configuration import * + +from Configurables import LCIODataSvc +dsvc = LCIODataSvc("EventDataSvc", input="/cefs/data/FullSim/CEPC240/CEPC_v4/higgs/E240.Pe2e2h_bb.e0.p0.whizard195/e2e2h_bb.e0.p0.00001_000000_sim.slcio") + +from Configurables import PlcioReadAlg +alg = PlcioReadAlg("PlcioReadAlg") +alg.InputCol.Path = "MCParticle" +alg.HeaderCol.Path = "EventHeader" + +from Configurables import LCIOInput +lcioinput = LCIOInput("LCIOReader", collections=[ + "EventHeader", + "MCParticle", + "COILCollection", + "EcalBarrelSiliconCollection", + "EcalBarrelSiliconPreShowerCollection", + "EcalEndcapRingCollection", + "EcalEndcapRingPreShowerCollection", + "EcalEndcapSiliconCollection", + "EcalEndcapSiliconPreShowerCollection", + "FTD_PIXELCollection", + "FTD_STRIPCollection", + "HcalBarrelCollection", + "HcalEndCapRingsCollection", + "HcalEndCapsCollection", + "LumiCalCollection", + "MuonBarrelCollection", + "MuonEndCapCollection", + "SETCollection", + "SITCollection", + "TPCCollection", + "TPCSpacePointCollection", + "VXDCollection" + ]) + +# ApplicationMgr +from Configurables import ApplicationMgr +ApplicationMgr( TopAlg = [lcioinput, alg], + EvtSel = 'NONE', + EvtMax = 10, + ExtSvc = [dsvc], + OutputLevel=DEBUG +) diff --git a/Examples/options/plcio_write.py b/Examples/options/plcio_write.py index e2619218625bf9d1f7e4835e47ba1a22f5defac0..0096c2df8cbcdf2ec6137ce9705ef05bf9d951f8 100644 --- a/Examples/options/plcio_write.py +++ b/Examples/options/plcio_write.py @@ -7,7 +7,7 @@ dsvc = CEPCDataSvc("EventDataSvc") from Configurables import PlcioWriteAlg alg = PlcioWriteAlg("PlcioWriteAlg") -alg.OutputCol.Path = "MCParticleCol" +alg.OutputCol.Path = "MCParticle" from Configurables import PodioOutput out = PodioOutput("out") diff --git a/FWCore/CMakeLists.txt b/FWCore/CMakeLists.txt index 0540c5e3bbfb41d38892b323246015148e13ad55..3cc5478bb80f00bc90fa56717ebb8331131dab3e 100644 --- a/FWCore/CMakeLists.txt +++ b/FWCore/CMakeLists.txt @@ -4,6 +4,8 @@ gaudi_subdir(FWCore v0r1) find_package(podio REQUIRED) +find_package(plcio REQUIRED) +find_package(LCIO REQUIRED) find_package(ROOT COMPONENTS RIO Tree) # this declaration will not be needed in the future @@ -13,8 +15,8 @@ gaudi_install_python_modules() gaudi_add_library(FWCore src/*.cpp - INCLUDE_DIRS ${podio_INCLUDE_DIRS} ROOT - LINK_LIBRARIES GaudiAlgLib GaudiKernel ${podio_LIBRARIES} ROOT + INCLUDE_DIRS ${podio_INCLUDE_DIRS} ${LCIO_INCLUDE_DIRS} ${plcio_INCLUDE_DIRS} ROOT + LINK_LIBRARIES GaudiAlgLib GaudiKernel ${podio_LIBRARIES} ${LCIO_LIBRARIES} ${plcio_LIBRARIES} ROOT PUBLIC_HEADERS FWCore) gaudi_add_module(FWCorePlugins diff --git a/FWCore/FWCore/LCIODataSvc.h b/FWCore/FWCore/LCIODataSvc.h new file mode 100644 index 0000000000000000000000000000000000000000..9627a8b73462d52360908899cac5aacc39757a56 --- /dev/null +++ b/FWCore/FWCore/LCIODataSvc.h @@ -0,0 +1,102 @@ +#ifndef FWCORE_LCIODATASVC_H +#define FWCORE_LCIODATASVC_H + +#include "GaudiKernel/DataSvc.h" +#include "GaudiKernel/IConversionSvc.h" +// LCIO +#include "podio/CollectionBase.h" +#include "podio/CollectionIDTable.h" +#include "podio/EventStore.h" +#include "podio/ROOTReader.h" + +#include "IO/LCReader.h" +#include "EVENT/LCCollection.h" +#include "EVENT/MCParticle.h" +#include "plcio/MCParticleCollection.h" +#include "plcio/MCParticle.h" +#include "plcio/EventHeaderCollection.h" + +#include "src/components/LCIO2Plcio.h" +#include <utility> +// Forward declarations + +/** @class LCIOEvtSvc EvtDataSvc.h + * + * An EvtDataSvc for LCIO classes + * + * @author B. Hegner + */ +class LCIODataSvc : public DataSvc { +public: + + friend class SvcFactory<LCIODataSvc>; + + typedef std::vector<std::pair<std::string, podio::CollectionBase*>> CollRegistry; + + virtual StatusCode initialize(); + virtual StatusCode reinitialize(); + virtual StatusCode finalize(); + virtual StatusCode clearStore(); + + /// Standard Constructor + LCIODataSvc(const std::string& name, ISvcLocator* svc); + + /// Standard Destructor + virtual ~LCIODataSvc(); + + // Use DataSvc functionality except where we override + using DataSvc::registerObject; + /// Overriding standard behaviour of evt service + /// Register object with the data store. + virtual StatusCode registerObject(const std::string& fullPath, DataObject* pObject) final; + + StatusCode readCollection(const std::string& collectionName, int collectionID); + + virtual const CollRegistry& getCollections() const { return m_collections; } + virtual const CollRegistry& getReadCollections() const { return m_readCollections; } + virtual podio::CollectionIDTable* getCollectionIDs() { return m_collectionIDs; } + + /// Set the collection IDs (if reading a file) + void setCollectionIDs(podio::CollectionIDTable* collectionIds); + /// Resets caches of reader and event store, increases event counter + void endOfRead(); + + + TTree* eventDataTree() {return m_eventDataTree;} + +private: + + EVENT::LCEvent* evt = nullptr; + // eventDataTree + TTree* m_eventDataTree; + /// LCIO reader for ROOT files + IO::LCReader* m_reader; + /// LCIO reader for ROOT files + plcio::EventHeaderCollection* pl_evtcol; + /// podio::ROOTReader m_reader; + /// LCIO EventStore, used to initialise collections + /// podio::EventStore m_provider; + /// Counter of the event number + int m_eventNum{0}; + /// Number of events in the file / to process + int m_eventMax{-1}; + + + SmartIF<IConversionSvc> m_cnvSvc; + + // special members for podio handling + std::vector<std::pair<std::string, podio::CollectionBase*>> m_collections; + std::vector<std::pair<std::string, podio::CollectionBase*>> m_readCollections; + podio::CollectionIDTable* m_collectionIDs; + +protected: +// bool exist_MCP = false; + LCIO2Plcio cvtor; +// EVENT::LCCollection* mcpcol_lc; +// plcio::MCParticleCollection* mcpcol_pl; + + /// ROOT file name the input is read from. Set by option filename + std::vector<std::string> m_filenames; + std::string m_filename; +}; +#endif // CORE_LCIODATASVC_H diff --git a/FWCore/src/components/LCIO2Plcio.cpp b/FWCore/src/components/LCIO2Plcio.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ac853eaaa2f0c4ace3a84ef82fa8a45ea549ffca --- /dev/null +++ b/FWCore/src/components/LCIO2Plcio.cpp @@ -0,0 +1,238 @@ +#include "LCIO2Plcio.h" + +#include "lcio.h" +#include "EVENT/LCCollection.h" +#include "plcio/MCParticle.h" +#include "plcio/MCParticleConst.h" +#include "plcio/MCParticleCollection.h" +#include "plcio/LCRunHeader.h" +#include "plcio/LCRunHeaderCollection.h" +#include "EVENT/MCParticle.h" + +typedef std::vector<EVENT::MCParticle*> MCParticleVec ; + +//std::map<std::string, fptr> LCIO2Plcio::map_cvt; +CollectionsMap LCIO2Plcio::map_cols; + +void lp_info(std::string s){ + printf("[LCIO2Plcio]:\t\t%s.\n", &s[0]); +} + +LCIO2Plcio::LCIO2Plcio(){ + map_cvt.insert(std::make_pair<std::string, fptr>("MCParticle", Convertor_MCParticle)); + map_cvt.insert(std::make_pair<std::string, fptr>("LCRunHeader", Convertor_LCRunHeader)); + map_cvt.insert(std::make_pair<std::string, fptr>("SimTrackerHit", Convertor_SimTrackerHit)); + map_cvt.insert(std::make_pair<std::string, fptr>("SimCalorimeterHit", Convertor_SimCalorimeterHit)); +} +LCIO2Plcio::LCIO2Plcio(EVENT::LCCollection* collection){ + LCIO2Plcio(); +} + +podio::CollectionBase* LCIO2Plcio::Convertor_LCRunHeader(EVENT::LCCollection* lc_col){ + plcio::LCRunHeaderCollection* pl_col = new plcio::LCRunHeaderCollection(); +// plcio::LCRunHeader pl_rh = (plcio::LCRunHeader) pl_col->create(); + return pl_col; +} + +void LCIO2Plcio::void_Core_MCParticle(EVENT::MCParticle* lc_mcp, plcio::MCParticle& pl_mcp){ + + pl_mcp.setPDG( lc_mcp->getPDG() ); + pl_mcp.setGeneratorStatus( lc_mcp->getGeneratorStatus() ); + pl_mcp.setSimulatorStatus( lc_mcp->getSimulatorStatus() ); + pl_mcp.setCharge( lc_mcp->getCharge() ); + pl_mcp.setTime( lc_mcp->getTime() ); + pl_mcp.setMass( lc_mcp->getMass() ); + pl_mcp.setStopped( lc_mcp->isStopped() ); + pl_mcp.setOverlay( lc_mcp->isOverlay() ); + pl_mcp.setBackscatter( lc_mcp->isBackscatter() ); + pl_mcp.setDecayedInTracker( lc_mcp->isDecayedInTracker() ); + pl_mcp.setDecayedInCalorimeter( lc_mcp->isDecayedInCalorimeter() ); + pl_mcp.setCreatedInSimulation( lc_mcp->isCreatedInSimulation() ); + pl_mcp.setVertexIsNotEndpointOfParent( lc_mcp->vertexIsNotEndpointOfParent() ); + pl_mcp.setHasLeftDetector( lc_mcp->hasLeftDetector() ); + + pl_mcp.setSpin( plcio::FloatThree( lc_mcp->getSpin() ) ); + pl_mcp.setColorFlow( plcio::IntTwo( lc_mcp->getColorFlow() ) ); + pl_mcp.setVertex( plcio::DoubleThree( lc_mcp->getVertex())); + pl_mcp.setEndpoint( plcio::DoubleThree( lc_mcp->getEndpoint() ) ); + + // send float ptr as parameter to FloatThree. + float plcio_m[3]; + const double* lcio_m = lc_mcp->getMomentum(); + plcio_m[0] = lcio_m[0]; + plcio_m[1] = lcio_m[1]; + plcio_m[2] = lcio_m[2]; + pl_mcp.setMomentum( plcio::FloatThree( plcio_m ) ); + + lcio_m = lc_mcp->getMomentumAtEndpoint(); + plcio_m[0] = lcio_m[0]; + plcio_m[1] = lcio_m[1]; + plcio_m[2] = lcio_m[2]; + pl_mcp.setMomentumAtEndpoint( plcio::FloatThree( plcio_m ) ); +} + +podio::CollectionBase* LCIO2Plcio::Convertor_MCParticle(EVENT::LCCollection* lc_col){ + return Core_MCParticle(lc_col); +} + +plcio::MCParticleCollection* LCIO2Plcio::Core_MCParticle(EVENT::LCCollection* lc_col){ + plcio::MCParticleCollection* pl_col = new plcio::MCParticleCollection(); + + // Convert basic info from LCIO to plcio; + for( unsigned i=0,N=lc_col->getNumberOfElements() ; i< N ; ++i){ + EVENT::MCParticle* lc_mcp = (EVENT::MCParticle*) lc_col->getElementAt(i) ; + plcio::MCParticle pl_mcp = (plcio::MCParticle) pl_col->create(); + + void_Core_MCParticle(lc_mcp, pl_mcp); + // dealing each of 'Parents' of lcio::MCParticle ; + const MCParticleVec& veclc = lc_mcp->getParents(); + for(unsigned j=0; j<veclc.size(); j++){ + EVENT::MCParticle* vlcreg = veclc[j]; + for(unsigned k=0; k<i; ++k){ + if(((EVENT::MCParticle*) lc_col->getElementAt(k)) == vlcreg){ + // A loop for plcio's MCParticleCollection to recover plcio's relationship; + plcio::MCParticle plprt = pl_col->at(k); + pl_mcp.addParent(plprt); + plprt.addDaughter(pl_mcp); + } + } + } + } + return pl_col; +} + +//void LCIO2Plcio::setPlcioMCParticleCollection(plcio::MCParticleCollection* pl_col){ +// hitcol_pl = pl_col; +//} + +//void LCIO2Plcio::setLCIOMCParticleCollection(EVENT::LCCollection* lc_col){ +// hitcol_lc = lc_col; +//} + + +podio::CollectionBase* LCIO2Plcio::Convertor_SimTrackerHit(EVENT::LCCollection* lc_col){ + plcio::SimTrackerHitCollection* pl_col = new plcio::SimTrackerHitCollection(); + + for( unsigned i=0,N=lc_col->getNumberOfElements() ; i< N ; ++i){ + EVENT::SimTrackerHit* lc_sth = (EVENT::SimTrackerHit*) lc_col->getElementAt(i) ; + plcio::SimTrackerHit pl_sth = (plcio::SimTrackerHit) pl_col->create(); + + pl_sth.setCellID0( lc_sth->getCellID0() ); + pl_sth.setCellID1( lc_sth->getCellID1() ); + pl_sth.setEDep( lc_sth->getEDep() ); + pl_sth.setTime( lc_sth->getTime() ); + pl_sth.setPathLength( lc_sth->getPathLength() ); + pl_sth.setQuality( lc_sth->getQuality() ); + pl_sth.setPosition( lc_sth->getPosition() ); + pl_sth.setMomentum( lc_sth->getMomentum() ); + pl_sth.setOverlay( lc_sth->isOverlay() ); + pl_sth.setProducedBySecondary( lc_sth->isProducedBySecondary() ); + + // Looping the LCIO::MCParticleCollection to pick Particle for Hits; + CollectionsVec vec_mcp; + vec_mcp = map_cols["MCParticle"]; + EVENT::LCCollection* hitcol_lc = (EVENT::LCCollection*) vec_mcp[0].first; + plcio::MCParticleCollection* hitcol_pl = (plcio::MCParticleCollection*) vec_mcp[0].second; + + int index = -1; + // search corresponding MCParticleCollection*; + EVENT::MCParticle* mcptr_reg = lc_sth->getMCParticle(); + for( unsigned j=0, M=hitcol_lc->getNumberOfElements(); j<M; ++j){ + EVENT::MCParticle* mcpin_lc = (EVENT::MCParticle*) hitcol_lc->getElementAt(j); + if( mcpin_lc == mcptr_reg ){ + index = j; + } + } +// if( index != -1) lp_info("Cedar: Convertor SimTrackerHit Success."); + bool is_empty = false; + if( index == -1){ + if(mcptr_reg == nullptr) is_empty = true; +// lp_info("Convertor SimTrackerHit Problem."); +// printf("LCCollection size: %d\n", hitcol_lc->getNumberOfElements()); +// printf("MCParticleCollection size: %d\n", hitcol_pl->size()); +// printf("Index: %d\n", index); + } + if( is_empty == false ) + pl_sth.setMCParticle( hitcol_pl->at(index) ); + + } + return pl_col; +} + +podio::CollectionBase* LCIO2Plcio::Convertor_SimCalorimeterHit(EVENT::LCCollection* lc_col){ + plcio::SimCalorimeterHitCollection* pl_col = new plcio::SimCalorimeterHitCollection(); + + for( unsigned i=0,N=lc_col->getNumberOfElements() ; i< N ; ++i){ + EVENT::SimCalorimeterHit* lc_sch = (EVENT::SimCalorimeterHit*) lc_col->getElementAt(i); + plcio::SimCalorimeterHit pl_sch = (plcio::SimCalorimeterHit) pl_col->create(); + + pl_sch.setCellID0( lc_sch->getCellID0() ); + pl_sch.setCellID1( lc_sch->getCellID1() ); + pl_sch.setEnergy( lc_sch->getEnergy() ); + + float plcio_p[3]; + const float* lcio_p = lc_sch->getPosition(); + plcio_p[0] = lcio_p[0]; + plcio_p[1] = lcio_p[1]; + plcio_p[2] = lcio_p[2]; + pl_sch.setPosition( plcio::FloatThree( plcio_p ) ); + + // converting from lc_sch to pl_sch on the contribution variables; + for( unsigned j=0, N=lc_sch->getNMCContributions(); j<N; j++){ + plcio_p[0] = lc_sch->getStepPosition(j)[0]; + plcio_p[1] = lc_sch->getStepPosition(j)[1]; + plcio_p[2] = lc_sch->getStepPosition(j)[2]; + + plcio::ConstCaloHitContribution tmp( + lc_sch->getPDGCont(j), lc_sch->getEnergyCont(j), + lc_sch->getTimeCont(j), plcio::FloatThree(plcio_p) + ); + pl_sch.addContribution( tmp ); + } + } + + return pl_col; +} + +bool LCIO2Plcio::isReady(const std::string& TypeName){ + if( TypeName == "SimTrackerHit" ){ + std::vector<std::string>::iterator it = find( + vec_Types.begin(), vec_Types.end(), "MCParticle" + ); + if( it != vec_Types.end() ) + return true; + } + return false; +} + +podio::CollectionBase* LCIO2Plcio::Convertor_getPlcio(EVENT::LCCollection* lc_col){ + + podio::CollectionBase* collection(nullptr); + TypeName = lc_col->getTypeName(); + +// lp_info("Converting "+TypeName); + bool ready = true; + if( !ready ){ + lp_info("Not ready yet."); + lp_info("Please put MCParticle firstly in the python file, Please"); + return nullptr; + } + + fptr fp; + if( map_cvt.find(TypeName) == map_cvt.end()){ + lp_info("unrecognized "+TypeName); + }else{ + fp = *map_cvt[TypeName]; + } + + fp = *map_cvt[TypeName]; + collection = fp(lc_col); + +// maintain map<TypeName, CollVec>; + map_cols[TypeName].push_back( + std::pair<EVENT::LCCollection*, podio::CollectionBase*>(lc_col, collection) + ); + +// lp_info("done."); + return collection; +} diff --git a/FWCore/src/components/LCIO2Plcio.h b/FWCore/src/components/LCIO2Plcio.h new file mode 100644 index 0000000000000000000000000000000000000000..799f864ecadd85f810cd839f178411e46dd33b45 --- /dev/null +++ b/FWCore/src/components/LCIO2Plcio.h @@ -0,0 +1,76 @@ +#ifndef FWCORE_CONVERTOR_H +#define FWCORE_CONVERTOR_H + +// LCIO + +#include <map> +#include <iostream> +#include <string> +#include "lcio.h" +// #include "IO/LCReader.h" +// #include "EVENT/LCCollection.h" +#include "EVENT/MCParticle.h" +#include "EVENT/SimTrackerHit.h" +#include "EVENT/SimCalorimeterHit.h" +#include "plcio/SimTrackerHit.h" +#include "plcio/SimTrackerHitCollection.h" +#include "plcio/SimCalorimeterHit.h" +#include "plcio/SimCalorimeterHitCollection.h" +#include "plcio/MCParticle.h" +#include "plcio/MCParticleCollection.h" + +#include <utility> +// Forward declarations + +/** @class LCIO2Plcio LCIO2Plcio.h + * + * An LCIO2Plcio for Converting from LCCollection to plcio collection; + * + * @author jhZou, gjCao + */ + +// typedef plcio::MCParticleCollection* (*fptr) (EVENT::LCCollection*); +typedef podio::CollectionBase* (*fptr) (EVENT::LCCollection*); +typedef std::vector<std::pair<EVENT::LCCollection*, podio::CollectionBase*>> CollectionsVec; +typedef std::map<std::string, CollectionsVec> CollectionsMap; + +class LCIO2Plcio{ +public: + + /// Standard Constructor + LCIO2Plcio(); + LCIO2Plcio(EVENT::LCCollection*); + + /// Standard Destructor + virtual ~LCIO2Plcio(){} + + void test(){ printf("MYTESTFUC\n"); } + void clear(){ map_cols.clear(); }; + +// plcio::MCParticleCollection* Convertor_getPlcio(EVENT::LCCollection*); + podio::CollectionBase* Convertor_getPlcio(EVENT::LCCollection*); + static podio::CollectionBase* Convertor_MCParticle(EVENT::LCCollection*); + static podio::CollectionBase* Convertor_LCRunHeader(EVENT::LCCollection*); + static podio::CollectionBase* Convertor_SimTrackerHit(EVENT::LCCollection*); + static podio::CollectionBase* Convertor_SimCalorimeterHit(EVENT::LCCollection*); + + static void void_Core_MCParticle(EVENT::MCParticle*, plcio::MCParticle&); + static plcio::MCParticleCollection* Core_MCParticle(EVENT::LCCollection*); + + bool isReady(const std::string&); + void setPlcioMCParticleCollection(plcio::MCParticleCollection*); + void setLCIOMCParticleCollection(EVENT::LCCollection*); + +private: + std::string TypeName; + // maintain a log vec about data read; + std::vector<std::string> vec_Types; + + // maintain a map from keyword to function pointer. + std::map<std::string, fptr> map_cvt; + static CollectionsMap map_cols; + +// plcio::MCParticleCollection* hitcol_pl; +// EVENT::LCCollection* hitcol_lc; +}; +#endif // CORE_CONVERTOR_H diff --git a/FWCore/src/components/LCIODataSvc.cpp b/FWCore/src/components/LCIODataSvc.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b5ed5235cd29424451d5d4514fcf83cb9df13fa2 --- /dev/null +++ b/FWCore/src/components/LCIODataSvc.cpp @@ -0,0 +1,180 @@ +#include "FWCore/LCIODataSvc.h" +#include "LCIO2Plcio.h" +#include "GaudiKernel/IConversionSvc.h" +#include "GaudiKernel/IEventProcessor.h" +#include "GaudiKernel/ISvcLocator.h" + +#include "IOIMPL/LCFactory.h" +#include "FWCore/DataWrapper.h" +#include "lcio.h" +#include "plcio/MCParticleCollection.h" +#include "plcio/MCParticle.h" +#include "plcio/EventHeaderCollection.h" +#include "EVENT/MCParticle.h" + +#include "TTree.h" + +typedef std::vector<lcio::MCParticle*> MCParticleVec ; + +DECLARE_SERVICE_FACTORY(LCIODataSvc) +/// Service initialisation +StatusCode LCIODataSvc::initialize() { + // Nothing to do: just call base class initialisation + StatusCode status = DataSvc::initialize(); + ISvcLocator* svc_loc = serviceLocator(); + + // Attach data loader facility + m_cnvSvc = svc_loc->service("EventPersistencySvc"); + status = setDataLoader(m_cnvSvc); + + m_reader = IOIMPL::LCFactory::getInstance()->createLCReader(); + + if (m_filename != "") { + m_filenames.push_back(m_filename); + } + + if (m_filenames.size() > 0) { + if (m_filenames[0] != "") { + m_reader->open(m_filenames); + m_eventMax = m_reader->getNumberOfEvents(); + } + } + return status; +} +/// Service reinitialisation +StatusCode LCIODataSvc::reinitialize() { + // Do nothing for this service + return StatusCode::SUCCESS; +} +/// Service finalization +StatusCode LCIODataSvc::finalize() { + m_cnvSvc = 0; // release + DataSvc::finalize().ignore(); + return StatusCode::SUCCESS; +} + +StatusCode LCIODataSvc::clearStore() { + for (auto& collNamePair : m_collections) { + if (collNamePair.second != nullptr) { + collNamePair.second->clear(); + } + } + for (auto& collNamePair : m_readCollections) { + if (collNamePair.second != nullptr) { + collNamePair.second->clear(); + } + } + DataSvc::clearStore().ignore(); + m_collections.clear(); + m_readCollections.clear(); + return StatusCode::SUCCESS; +} + +void LCIODataSvc::endOfRead() { + if (m_eventMax != -1) { + // m_provider.clearCaches(); + // m_reader.endOfEvent(); + if (m_eventNum++ > m_eventMax) { + info() << "Reached end of file with event " << m_eventMax << endmsg; + IEventProcessor* eventProcessor; + service("ApplicationMgr", eventProcessor); + eventProcessor->stopRun(); + } + } + evt = nullptr; +} + +void LCIODataSvc::setCollectionIDs(podio::CollectionIDTable* collectionIds) { + if (m_collectionIDs != nullptr) { + delete m_collectionIDs; + } + m_collectionIDs = collectionIds; +} + +/// Standard Constructor +LCIODataSvc::LCIODataSvc(const std::string& name, ISvcLocator* svc) + : DataSvc(name, svc), m_collectionIDs(new podio::CollectionIDTable()) { + + m_eventDataTree = new TTree("events", "Events tree"); + declareProperty("inputs", m_filenames = {}, "Names of the files to read"); + declareProperty("input", m_filename = "", "Name of the file to read"); + + } + +/// Standard Destructor +LCIODataSvc::~LCIODataSvc() {} + + +StatusCode LCIODataSvc::readCollection(const std::string& collName, int collectionID) { + podio::CollectionBase* collection(nullptr); + + if( evt == nullptr ){ + evt = m_reader->readNextEvent(); + cvtor.clear(); + + // basicly set EventHeader; + pl_evtcol = new plcio::EventHeaderCollection(); + plcio::EventHeader evt_header; + evt_header = (plcio::EventHeader) pl_evtcol->create(); + evt_header.setEventNumber( evt->getEventNumber() ); + evt_header.setRunNumber( evt->getRunNumber() ); + evt_header.setTimeStamp( evt->getTimeStamp() ); + evt_header.setDetectorName( evt->getDetectorName() ); + + // wrap event header collection into Data service; + auto wrapper = new DataWrapper<podio::CollectionBase>; + int id = m_collectionIDs->add("EventHeader"); + pl_evtcol->setID(id); + wrapper->setData(pl_evtcol); + m_readCollections.emplace_back(std::make_pair("EventHeader", pl_evtcol)); + + DataSvc::registerObject("EventHeader", wrapper); + } + + debug() << "reading collection name: " << collName << "." << endmsg; + EVENT::LCCollection* lc_col; + std::vector<std::string> vec_colns = *evt->getCollectionNames(); + std::vector<std::string>::iterator it = find(vec_colns.begin(), vec_colns.end(), collName); + if( it != vec_colns.end() ){ + lc_col = evt->getCollection(collName); + } + else return StatusCode::SUCCESS; +// debug() << "Got collection: " << collName << "." << endmsg; + + std::string TypeName = lc_col->getTypeName(); +// if( !exist_MCP && (TypeName == "MCParticle") ) exist_MCP = true; +// if( TypeName == "MCParticle" ){ +// if( !exist_MCP ) exist_MCP = true; +// mcpcol_pl = LCIO2Plcio::Core_MCParticle(lc_col); +// LCIO2Plcio::setLCIOMCParticleCollection(mcpcol_lc); +// LCIO2Plcio::setPlcioMCParticleCollection(mcpcol_pl); +// } + collection = cvtor.Convertor_getPlcio( lc_col ); + pl_evtcol->at(0)->addCollectionName(collName); + pl_evtcol->at(0)->addCollectionType(TypeName); + + auto wrapper = new DataWrapper<podio::CollectionBase>; + int id = m_collectionIDs->add(collName); + collection->setID(id); + wrapper->setData(collection); + m_readCollections.emplace_back(std::make_pair(collName, collection)); + +// info() << "readCollection completed." << endmsg; + + return DataSvc::registerObject(collName, wrapper); +} + +StatusCode LCIODataSvc::registerObject(const std::string& fullPath, DataObject* pObject) { + DataWrapperBase* wrapper = dynamic_cast<DataWrapperBase*>(pObject); + if (wrapper != nullptr) { + podio::CollectionBase* coll = wrapper->collectionBase(); + if (coll != nullptr) { + size_t pos = fullPath.find_last_of("/"); + std::string shortPath(fullPath.substr(pos + 1, fullPath.length())); + int id = m_collectionIDs->add(shortPath); + coll->setID(id); + m_collections.emplace_back(std::make_pair(shortPath, coll)); + } + } + return DataSvc::registerObject(fullPath, pObject); +} diff --git a/FWCore/src/components/LCIOInput.cpp b/FWCore/src/components/LCIOInput.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c6a810708e26c94a8eb1677cb23b27f85e9620ce --- /dev/null +++ b/FWCore/src/components/LCIOInput.cpp @@ -0,0 +1,52 @@ +#include "LCIOInput.h" + +#include "TFile.h" +#include "TROOT.h" + +#include "FWCore/DataWrapper.h" +#include "FWCore/LCIODataSvc.h" + +DECLARE_COMPONENT(LCIOInput) + +LCIOInput::LCIOInput(const std::string& name, ISvcLocator* svcLoc) : GaudiAlgorithm(name, svcLoc) {} + +StatusCode LCIOInput::initialize() { + if (GaudiAlgorithm::initialize().isFailure()) return StatusCode::FAILURE; + + // check whether we have the LCIOEvtSvc active + m_LCIODataSvc = dynamic_cast<LCIODataSvc*>(evtSvc().get()); + if (nullptr == m_LCIODataSvc) return StatusCode::FAILURE; + + auto idTable = m_LCIODataSvc->getCollectionIDs(); + for (auto& name : m_collectionNames) { + debug() << "Finding collection " << name << " in collection registry." << endmsg; +/* + if (!idTable->present(name)) { + error() << "Requested product " << name << " not found." << endmsg; + return StatusCode::FAILURE; + } +*/ + m_collectionIDs.push_back(idTable->add(name)); + } + return StatusCode::SUCCESS; +} + +StatusCode LCIOInput::execute() { + size_t cntr = 0; + // Re-create the collections from ROOT file + for (auto& id : m_collectionIDs) { + const std::string& collName = m_collectionNames.value().at(cntr++); + debug() << "Registering collection to read " << collName << " with id " << id << endmsg; + if (m_LCIODataSvc->readCollection(collName, id).isFailure()) { + return StatusCode::FAILURE; + } + } + // Tell data service that we are done with requested collections + m_LCIODataSvc->endOfRead(); + return StatusCode::SUCCESS; +} + +StatusCode LCIOInput::finalize() { + if (GaudiAlgorithm::finalize().isFailure()) return StatusCode::FAILURE; + return StatusCode::SUCCESS; +} diff --git a/FWCore/src/components/LCIOInput.h b/FWCore/src/components/LCIOInput.h new file mode 100644 index 0000000000000000000000000000000000000000..f84922797e085677dcbd2759f433006b5c53cc0e --- /dev/null +++ b/FWCore/src/components/LCIOInput.h @@ -0,0 +1,43 @@ +#ifndef FWCORE_LCIOINPUT_H +#define FWCORE_LCIOINPUT_H +// Gaaudi +#include "GaudiAlg/GaudiAlgorithm.h" + +// STL +#include <string> +#include <vector> + +// forward declarations +// from FWCore: +class LCIODataSvc; + +/** @class LCIOInput FWCore/components/LCIOInput.h LCIOInput.h + * + * Class that allows to read ROOT files written with LCIOInput + * + * @author J. Lingemann + */ + +class LCIOInput : public GaudiAlgorithm { + friend class AlgFactory<LCIOInput>; + +public: + /// Constructor. + LCIOInput(const std::string& name, ISvcLocator* svcLoc); + /// Initialization of LCIOInput. Acquires the data service, opens root file and creates trees. + virtual StatusCode initialize(); + /// Execute. Re-creates collections that are specified to be read and sets references. + virtual StatusCode execute(); + /// Finalize. Closes ROOT file. + virtual StatusCode finalize(); + +private: + /// Name of collections to read. Set by option collections (this is temporary) + Gaudi::Property<std::vector<std::string>> m_collectionNames{this, "collections", {}, "Places of collections to read"}; + /// Collection IDs (retrieved with CollectionIDTable from ROOT file, using collection names) + std::vector<int> m_collectionIDs; + /// Data service: needed to register objects and get collection IDs. Just an observing pointer. + LCIODataSvc* m_LCIODataSvc; +}; + +#endif