From b76a2ab25546d9e6a785788e544fd36c3501af2f Mon Sep 17 00:00:00 2001 From: Cao Guangjie <gjcao@lxslc614.ihep.ac.cn> Date: Tue, 17 Sep 2019 20:48:50 +0800 Subject: [PATCH] Convertor from LCIO to Plcio & LCIO Data Service --- Examples/CMakeLists.txt | 9 +- Examples/options/LCIO_read.py | 43 +++++ Examples/src/PlcioTest/PlcioReadAlg.cpp | 20 +- Examples/src/PlcioTest/PlcioReadAlg.h | 4 +- FWCore/CMakeLists.txt | 6 +- FWCore/FWCore/LCIODataSvc.h | 102 ++++++++++ FWCore/src/components/LCIO2Plcio.cpp | 238 ++++++++++++++++++++++++ FWCore/src/components/LCIO2Plcio.h | 76 ++++++++ FWCore/src/components/LCIODataSvc.cpp | 180 ++++++++++++++++++ FWCore/src/components/LCIOInput.cpp | 52 ++++++ FWCore/src/components/LCIOInput.h | 43 +++++ 11 files changed, 754 insertions(+), 19 deletions(-) create mode 100644 Examples/options/LCIO_read.py create mode 100644 FWCore/FWCore/LCIODataSvc.h create mode 100644 FWCore/src/components/LCIO2Plcio.cpp create mode 100644 FWCore/src/components/LCIO2Plcio.h create mode 100644 FWCore/src/components/LCIODataSvc.cpp create mode 100644 FWCore/src/components/LCIOInput.cpp create mode 100644 FWCore/src/components/LCIOInput.h diff --git a/Examples/CMakeLists.txt b/Examples/CMakeLists.txt index 7db41df7..f9f4c9d9 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 00000000..0a3a9428 --- /dev/null +++ b/Examples/options/LCIO_read.py @@ -0,0 +1,43 @@ +#!/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") + +from Configurables import LCIOInput +lcioinput = LCIOInput("LCIOReader", collections=[ + "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/src/PlcioTest/PlcioReadAlg.cpp b/Examples/src/PlcioTest/PlcioReadAlg.cpp index 5921731c..59d420dd 100644 --- a/Examples/src/PlcioTest/PlcioReadAlg.cpp +++ b/Examples/src/PlcioTest/PlcioReadAlg.cpp @@ -1,5 +1,4 @@ #include "PlcioReadAlg.h" -#include "plcio/EventHeaderCollection.h" #include "plcio/MCParticleCollection.h" DECLARE_COMPONENT(PlcioReadAlg) @@ -7,8 +6,7 @@ DECLARE_COMPONENT(PlcioReadAlg) PlcioReadAlg::PlcioReadAlg(const std::string& name, ISvcLocator* svcLoc) : GaudiAlgorithm(name, svcLoc) { - declareProperty("HeaderCol", m_headerCol); - declareProperty("InputCol", m_mcParCol, "MCParticle collection (input)"); + declareProperty("MCParticleCol", m_hdl, "MCParticle collection (input)"); } StatusCode PlcioReadAlg::initialize() @@ -20,21 +18,19 @@ StatusCode PlcioReadAlg::initialize() StatusCode PlcioReadAlg::execute() { debug() << "begin execute PlcioReadAlg" << endmsg; + auto mcCol = m_hdl.get(); - auto headers = m_headerCol.get(); - auto header = headers->at(0); - auto mcCol = m_mcParCol.get(); - - info() << "Run " << header.getRunNumber() << " Event " << header.getEventNumber() << " { "; +// debug() << "testing loop..." <<endmsg; for ( auto p : *mcCol ) { - info() << p.getObjectID().index << " : ["; + debug() << p.getObjectID().index << " : ["; for ( auto it = p.daughters_begin(), end = p.daughters_end(); it != end; ++it ) { - info() << " " << it->getObjectID().index; + debug() << " " << it->getObjectID().index; } - info() << " ]; "; + debug() << " ]; "; } - info() << "}" << endmsg; + debug() << endmsg; +// debug() << "end execute PlcioReadAlg" << endmsg; return StatusCode::SUCCESS; } diff --git a/Examples/src/PlcioTest/PlcioReadAlg.h b/Examples/src/PlcioTest/PlcioReadAlg.h index 5b9ec815..07d0eae4 100644 --- a/Examples/src/PlcioTest/PlcioReadAlg.h +++ b/Examples/src/PlcioTest/PlcioReadAlg.h @@ -5,7 +5,6 @@ #include "GaudiAlg/GaudiAlgorithm.h" namespace plcio { - class EventHeaderCollection; class MCParticleCollection; } @@ -23,8 +22,7 @@ class PlcioReadAlg : public GaudiAlgorithm private : - DataHandle<plcio::EventHeaderCollection> m_headerCol{"EventHeaderCol", Gaudi::DataHandle::Reader, this}; - DataHandle<plcio::MCParticleCollection> m_mcParCol{"MCParticleCol", Gaudi::DataHandle::Reader, this}; + DataHandle<plcio::MCParticleCollection> m_hdl{"MCParticle", Gaudi::DataHandle::Reader, this}; }; diff --git a/FWCore/CMakeLists.txt b/FWCore/CMakeLists.txt index 0540c5e3..3cc5478b 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 00000000..9627a8b7 --- /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 00000000..ac853eaa --- /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 00000000..799f864e --- /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 00000000..b5ed5235 --- /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 00000000..c6a81070 --- /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 00000000..f8492279 --- /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 -- GitLab