From 94a2bd6fcf7c18dfb81cfd677e270dad23f738e4 Mon Sep 17 00:00:00 2001 From: Markus Frank <markus.frank@cern.ch> Date: Wed, 2 Jul 2014 12:20:13 +0000 Subject: [PATCH] Add LCIO conversions --- DDG4/examples/CLICSidSimu.py | 9 +- DDG4/include/DDG4/Geant4Context.h | 19 +++-- DDG4/include/DDG4/Geant4HitCollection.h | 2 + DDG4/lcio/Geant4Output2LCIO.cpp | 18 +--- DDG4/lcio/LCIOConversions.cpp | 108 ++++++++++++++++++++++-- DDG4/src/Geant4HitCollection.cpp | 5 ++ 6 files changed, 128 insertions(+), 33 deletions(-) diff --git a/DDG4/examples/CLICSidSimu.py b/DDG4/examples/CLICSidSimu.py index 712bb471d..30b71fa38 100644 --- a/DDG4/examples/CLICSidSimu.py +++ b/DDG4/examples/CLICSidSimu.py @@ -78,10 +78,11 @@ def run(): evt_root.enableUI() kernel.eventAction().add(evt_root) - #evt_lcio = DDG4.EventAction(kernel,'Geant4Output2LCIO/LcioOutput') - #evt_lcio.Output = "simple_lcio" - #evt_lcio.enableUI() - #kernel.eventAction().add(evt_lcio) + evt_lcio = DDG4.EventAction(kernel,'Geant4Output2LCIO/LcioOutput') + evt_lcio.Control = True + evt_lcio.Output = "CLICSiD_"+time.strftime("%Y-%m-%d_%H-%M")+".lcio" + evt_lcio.enableUI() + kernel.eventAction().add(evt_lcio) gen = DDG4.GeneratorAction(kernel,"Geant4TestGeneratorAction/Generate") kernel.generatorAction().add(gen) diff --git a/DDG4/include/DDG4/Geant4Context.h b/DDG4/include/DDG4/Geant4Context.h index 20fce51dd..355a69fbb 100644 --- a/DDG4/include/DDG4/Geant4Context.h +++ b/DDG4/include/DDG4/Geant4Context.h @@ -77,8 +77,9 @@ namespace DD4hep { Geant4Run(const G4Run* run); /// Default destructor virtual ~Geant4Run(); - /// Access the G4Run directly + /// Access the G4Run directly: Automatic type conversion operator const G4Run&() const { return *m_run; } + /// Access the G4Event directly: Explicit G4Run accessor const G4Run& run() const { return *m_run; } /// Add an extension object to the detector element /** Note: @@ -90,7 +91,8 @@ namespace DD4hep { } /// Add user extension object. Ownership is transferred! template <typename T> T* addExtension(T* ptr, bool take_ownership=true) { - return (T*)ObjectExtensions::addExtension(ptr,typeid(T),take_ownership ? _delete<T> : 0); + destruct_t dt = ObjectExtensions::_delete<T>; + return (T*)ObjectExtensions::addExtension(ptr,typeid(T),take_ownership ? dt : 0); } /// Access to type safe extension object. Exception is thrown if the object is invalid template <typename T> T* extension(bool alert=true) { @@ -122,9 +124,11 @@ namespace DD4hep { Geant4Event(const G4Event* run); /// Default destructor virtual ~Geant4Event(); - /// Access the G4Event directly - operator const G4Event&() const { return *m_event; } - const G4Event& event() const { return *m_event; } + /// Access the G4Event directly: Automatic type conversion + operator const G4Event&() const { return *m_event; } + /// Access the G4Event directly: Explicit G4Event accessor + const G4Event& event() const { return *m_event; } + /// Add an extension object to the detector element /** Note: * To add an extension, which should NOT be deleted, @@ -134,8 +138,9 @@ namespace DD4hep { return ObjectExtensions::addExtension(ptr,info,dtor); } /// Add user extension object. Ownership is transferred and object deleted at the end of the event. - template <typename T> T* addExtension(T* ptr, bool take_ownership=true) { - return (T*)ObjectExtensions::addExtension(ptr,typeid(T),take_ownership ? _delete<T> : 0); + template <typename T> T* addExtension(T* ptr, bool take_ownership=true) { + destruct_t dt = ObjectExtensions::_delete<T>; + return (T*)ObjectExtensions::addExtension(ptr,typeid(T),take_ownership ? dt : 0); } /// Access to type safe extension object. Exception is thrown if the object is invalid template <typename T> T* extension(bool alert=true) { diff --git a/DDG4/include/DDG4/Geant4HitCollection.h b/DDG4/include/DDG4/Geant4HitCollection.h index 5f8b0a728..69fb9255e 100644 --- a/DDG4/include/DDG4/Geant4HitCollection.h +++ b/DDG4/include/DDG4/Geant4HitCollection.h @@ -220,6 +220,8 @@ namespace DD4hep { const ComponentCast& type() const; /// Type information of the vector type for extracting data const ComponentCast& vector_type() const; + /// Clear the collection (Deletes all valid references to real hits) + virtual void clear(); /// Access individual hits virtual G4VHit* GetHit(size_t which) const { return (G4VHit*) &m_hits.at(which); diff --git a/DDG4/lcio/Geant4Output2LCIO.cpp b/DDG4/lcio/Geant4Output2LCIO.cpp index 51b791c3e..f5f6f9024 100644 --- a/DDG4/lcio/Geant4Output2LCIO.cpp +++ b/DDG4/lcio/Geant4Output2LCIO.cpp @@ -93,16 +93,13 @@ namespace DD4hep { #include "IMPL/LCRunHeaderImpl.h" #include "IMPL/LCCollectionVec.h" - using namespace DD4hep::Simulation; using namespace DD4hep; using namespace std; - #include "DDG4/Factories.h" DECLARE_GEANT4ACTION(Geant4Output2LCIO) - /// Standard constructor Geant4Output2LCIO::Geant4Output2LCIO(Geant4Context* ctxt, const string& nam) : Geant4OutputAction(ctxt,nam), m_volMgr(), m_file(0), m_runNo(0) @@ -112,14 +109,14 @@ Geant4Output2LCIO::Geant4Output2LCIO(Geant4Context* ctxt, const string& nam) /// Default destructor Geant4Output2LCIO::~Geant4Output2LCIO() { - InstanceCount::decrement(this); if ( m_file ) { m_file->close(); deletePtr(m_file); } + InstanceCount::decrement(this); } -// Callback to store the Geant4 run information +/// Callback to store the Geant4 run information void Geant4Output2LCIO::beginRun(const G4Run* ) { if ( 0 == m_file && !m_output.empty() ) { m_file = lcio::LCFactory::getInstance()->createLCWriter(); @@ -153,25 +150,17 @@ void Geant4Output2LCIO::saveRun(const G4Run* run) { void Geant4Output2LCIO::begin(const G4Event* event){ - lcio::LCEventImpl* e = new lcio::LCEventImpl; - //fg: fixme: should be this call (deleting the pointer in the end) but that does not compile ... // context()->event().addExtension<lcio::LCEventImpl>( e ); - - context()->event().addExtension<lcio::LCEventImpl>( e ); + context()->event().addExtension(e); //context()->event().addExtension( e , typeid( lcio::LCEventImpl ), 0); - // std::cout << " ########### Geant4Output2LCIO::begin add new LCIO event event context " << std::endl ; } - /// Callback to store the Geant4 event void Geant4Output2LCIO::saveEvent(OutputContext<G4Event>& ctxt) { - // lcio::LCEventImpl* e = new lcio::LCEventImpl; - // ctxt.userData = e; lcio::LCEventImpl* e = context()->event().extension<lcio::LCEventImpl>(); - e->setRunNumber(m_runNo); e->setEventNumber(ctxt.context->GetEventID()); e->setDetectorName(context()->lcdd().header().name()); @@ -187,7 +176,6 @@ void Geant4Output2LCIO::saveCollection(OutputContext<G4Event>& ctxt, G4VHitsColl typedef pair<Geometry::VolumeManager,G4VHitsCollection*> _A; typedef Geant4Conversion<lcio::LCCollectionVec,_A> _C; const _C& cnv = _C::converter(typeid(Geant4HitCollection)); - //lcio::LCEventImpl* evt = ctxt.data<lcio::LCEventImpl>(); lcio::LCEventImpl* evt = context()->event().extension<lcio::LCEventImpl>(); lcio::LCCollectionVec* col = cnv(_A(m_volMgr,collection)); evt->addCollection(col,hc_nam); diff --git a/DDG4/lcio/LCIOConversions.cpp b/DDG4/lcio/LCIOConversions.cpp index fefaf5f34..44cb83edd 100644 --- a/DDG4/lcio/LCIOConversions.cpp +++ b/DDG4/lcio/LCIOConversions.cpp @@ -34,9 +34,15 @@ namespace DD4hep { typedef Geometry::VolumeManager VolMgr; + /// Data conversion interface calling lower level explicit convetrers + /** + * @author M.Frank + * @version 1.0 + */ template <> lcio::LCCollectionVec* - Geant4DataConversion<lcio::LCCollectionVec,pair<VolMgr,G4VHitsCollection*>,Geant4HitCollection>:: - operator()(const arg_t& args) const { + Geant4DataConversion<lcio::LCCollectionVec, + pair<VolMgr,G4VHitsCollection*>, + Geant4HitCollection>::operator()(const arg_t& args) const { G4VHitsCollection* c = args.second; Geant4HitCollection* coll = dynamic_cast<Geant4HitCollection*>(c); if ( coll ) { @@ -49,8 +55,20 @@ namespace DD4hep { "Cannot save the collection entries of:"+c->GetName()); } + /// Data conversion interface creating lcio::SimTrackerHitImpl from SimpleTracker::Hit structures + /** + * This converter is to be used, when the sensitive detectors create fill collections + * of type Geant4HitCollection with objects of type **SimpleTracker::Hit**. + * The original objects are untouched and are automatically when the hosting + * Geant4HitCollection object is released. + * + * @author M.Frank + * @version 1.0 + */ template <> lcio::LCCollectionVec* - Geant4DataConversion<lcio::LCCollectionVec,pair<VolMgr,Geant4HitCollection*>,SimpleTracker::Hit>::operator()(const arg_t& args) const + Geant4DataConversion<lcio::LCCollectionVec, + pair<VolMgr,Geant4HitCollection*>, + SimpleTracker::Hit>::operator()(const arg_t& args) const { Geant4HitCollection* coll = args.second; size_t nhits = coll->GetSize(); @@ -74,8 +92,20 @@ namespace DD4hep { return col; } + /// Data conversion interface creating lcio::SimCalorimeterHitImpl from SimpleCalorimeter::Hit structures + /** + * This converter is to be used, when the sensitive detectors create fill collections + * of type Geant4HitCollection with objects of type **SimpleCalorimeter::Hit**. + * The original objects are untouched and are automatically when the hosting + * Geant4HitCollection object is released. + * + * @author M.Frank + * @version 1.0 + */ template <> lcio::LCCollectionVec* - Geant4DataConversion<lcio::LCCollectionVec,pair<VolMgr,Geant4HitCollection*>,SimpleCalorimeter::Hit>::operator()(const arg_t& args) const + Geant4DataConversion<lcio::LCCollectionVec, + pair<VolMgr,Geant4HitCollection*>, + SimpleCalorimeter::Hit>::operator()(const arg_t& args) const { Geant4HitCollection* coll = args.second; size_t nhits = coll->GetSize(); @@ -97,14 +127,78 @@ namespace DD4hep { return col; } + /// Data conversion interface moving lcio::SimTrackerHitImpl objects from a Geant4HitCollection to a LCCollectionVec + /** + * This converter is to be used, when the sensitive detectors create fill collections + * of type Geant4HitCollection with objects of type **lcio::SimTrackerHitImpl**. + * The ownership of the original Geant4HitCollection is released and moved to + * the newly created lcio::LCCollectionVec container. + * Finally the original hits collection is cleared. + * + * Note: This conversion is INTRUSIVE and CLEARS the original collection! + * + * @author M.Frank + * @version 1.0 + */ + template <> lcio::LCCollectionVec* + Geant4DataConversion<lcio::LCCollectionVec, + pair<VolMgr,Geant4HitCollection*>, + lcio::SimTrackerHitImpl>::operator()(const arg_t& args) const + { + Geant4HitCollection* coll = args.second; + lcio::LCCollectionVec* lc_coll = new lcio::LCCollectionVec(lcio::LCIO::SIMTRACKERHIT); + for(size_t i=0, nhits = coll->GetSize(); i<nhits; ++i) { + Geant4HitWrapper& wrap = coll->hit(i); + lcio::SimTrackerHitImpl* lc_hit = wrap; + wrap.release(); // Now we have ownership! + lc_coll->addElement(lc_hit); + } + coll->clear(); + return lc_coll; + } + + /// Data conversion interface moving lcio::SimCalorimeterHitImpl objects from a Geant4HitCollection to a LCCollectionVec + /** + * This converter is to be used, when the sensitive detectors create fill collections + * of type Geant4HitCollection with objects of type **lcio::SimCalorimeterHitImpl**. + * The ownership of the original Geant4HitCollection is released and moved to + * the newly created lcio::LCCollectionVec container. + * Finally the original hits collection is cleared. + * + * Note: This conversion is INTRUSIVE and CLEARS the original collection! + * + * @author M.Frank + * @version 1.0 + */ + template <> lcio::LCCollectionVec* + Geant4DataConversion<lcio::LCCollectionVec, + pair<VolMgr,Geant4HitCollection*>, + lcio::SimCalorimeterHitImpl>::operator()(const arg_t& args) const + { + Geant4HitCollection* coll = args.second; + lcio::LCCollectionVec* lc_coll = new lcio::LCCollectionVec(lcio::LCIO::SIMTRACKERHIT); + for(size_t i=0, nhits = coll->GetSize(); i<nhits; ++i) { + Geant4HitWrapper& wrap = coll->hit(i); + lcio::SimCalorimeterHitImpl* lc_hit = wrap; + wrap.release(); // Now we have ownership! + lc_coll->addElement(lc_hit); + } + coll->clear(); + return lc_coll; + } + typedef pair<VolMgr,G4VHitsCollection*> _AA1; + typedef pair<VolMgr,Geant4HitCollection*> _AA2; template class Geant4Conversion<lcio::LCCollectionVec,_AA1>; DECLARE_GEANT4_HITCONVERTER(lcio::LCCollectionVec,_AA1,Geant4HitCollection) - typedef pair<VolMgr,Geant4HitCollection*> _AA2; + template class Geant4Conversion<lcio::LCCollectionVec,_AA2>; + // Hit converters for simple Geant4Data objects DECLARE_GEANT4_HITCONVERTER(lcio::LCCollectionVec,_AA2,SimpleTracker::Hit) - typedef pair<VolMgr,Geant4HitCollection*> _AA3; - DECLARE_GEANT4_HITCONVERTER(lcio::LCCollectionVec,_AA3,SimpleCalorimeter::Hit) + DECLARE_GEANT4_HITCONVERTER(lcio::LCCollectionVec,_AA2,SimpleCalorimeter::Hit) + // Hit converters for standard LCIO objects + DECLARE_GEANT4_HITCONVERTER(lcio::LCCollectionVec,_AA2,lcio::SimTrackerHitImpl) + DECLARE_GEANT4_HITCONVERTER(lcio::LCCollectionVec,_AA2,lcio::SimCalorimeterHitImpl) } // End namespace Simulation } // End namespace DD4hep diff --git a/DDG4/src/Geant4HitCollection.cpp b/DDG4/src/Geant4HitCollection.cpp index 3d805840c..b1a1b4604 100644 --- a/DDG4/src/Geant4HitCollection.cpp +++ b/DDG4/src/Geant4HitCollection.cpp @@ -90,6 +90,11 @@ void Geant4HitCollection::newInstance() { InstanceCount::increment(this); } +/// Clear the collection (Deletes all valid references to real hits) +void Geant4HitCollection::clear() { + m_hits.clear(); +} + /// Find hit in a collection by comparison of attributes void* Geant4HitCollection::findHit(const Compare& cmp) const { void* p = 0; -- GitLab