diff --git a/DDG4/edm4hep/Geant4Output2EDM4hep.cpp b/DDG4/edm4hep/Geant4Output2EDM4hep.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0eab1aa9df88cf41b61f5381a279bc417cd6e46e
--- /dev/null
+++ b/DDG4/edm4hep/Geant4Output2EDM4hep.cpp
@@ -0,0 +1,589 @@
+//==========================================================================
+//  AIDA Detector description implementation 
+//--------------------------------------------------------------------------
+// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+// All rights reserved.
+//
+// For the licensing terms see $DD4hepINSTALL/LICENSE.
+// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+//
+// Author     : F.Gaede, DESY
+//
+//==========================================================================
+
+#ifndef DD4HEP_DDG4_GEANT4OUTPUT2EDM4hep_H
+#define DD4HEP_DDG4_GEANT4OUTPUT2EDM4hep_H
+
+//  Framework include files
+#include "DD4hep/Detector.h"
+#include "DD4hep/VolumeManager.h"
+#include "DDG4/Geant4HitCollection.h"
+#include "DDG4/Geant4OutputAction.h"
+#include "DDG4/Geant4SensDetAction.h"
+#include "DDG4/EventParameters.h"
+
+// Geant4 headers
+#include "G4Threading.hh"
+#include "G4AutoLock.hh"
+#include <G4Version.hh>
+#include <G4SystemOfUnits.hh>
+
+// edm4hep include files
+#include "edm4hep/EventHeaderCollection.h"
+#include "edm4hep/MCParticleCollection.h"
+#include "edm4hep/SimTrackerHitCollection.h"
+#include "edm4hep/CaloHitContributionCollection.h"
+#include "edm4hep/SimCalorimeterHitCollection.h"
+#include "podio/EventStore.h"
+#include "podio/ROOTWriter.h"
+
+#include <typeinfo>
+#include <iostream>
+#include <ctime>
+
+
+/// Namespace for the AIDA detector description toolkit
+namespace dd4hep {
+
+  class ComponentCast;
+
+  /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
+  namespace sim {
+
+    template <class T=podio::EventStore> void EventParameters::extractParameters(T& event){
+      auto& lcparameters = event.getEventMetaData();
+
+      for(auto const& ival: this->intParameters()) {
+        lcparameters.setValues(ival.first, ival.second);
+      }
+      for(auto const& ival: this->fltParameters()) {
+        lcparameters.setValues(ival.first, ival.second);
+      }
+      for(auto const& ival: this->strParameters()) {
+        lcparameters.setValues(ival.first, ival.second);
+      }
+    }
+
+    class  Geant4ParticleMap;
+
+    /// Base class to output Geant4 event data to EDM4hep
+    /**
+     *  \author  F.Gaede
+     *  \version 1.0
+     *  \ingroup DD4HEP_SIMULATION
+     */
+    class Geant4Output2EDM4hep : public Geant4OutputAction  {
+    protected:
+      podio::EventStore*  m_store;
+      podio::ROOTWriter*  m_file;
+      int              m_runNo;
+      int              m_runNumberOffset;
+      int              m_eventNumberOffset;
+      std::map< std::string, std::string > m_runHeader;
+      std::map< std::string, std::string > m_eventParametersInt;
+      std::map< std::string, std::string > m_eventParametersFloat;
+      std::map< std::string, std::string > m_eventParametersString;
+      bool m_FirstEvent =  true  ;
+
+      /// create the podio collections for the particles and hits
+      void createCollections(OutputContext<G4Event>& ctxt) ;
+      /// Data conversion interface for MC particles to EDM4hep format
+      void saveParticles(Geant4ParticleMap* particles);
+    public:
+      /// Standard constructor
+      Geant4Output2EDM4hep(Geant4Context* ctxt, const std::string& nam);
+      /// Default destructor
+      virtual ~Geant4Output2EDM4hep();
+      /// Callback to store the Geant4 run information
+      virtual void beginRun(const G4Run* run);
+      /// Callback to store the Geant4 run information
+      virtual void endRun(const G4Run* run);
+
+      /// Callback to store the Geant4 run information
+      virtual void saveRun(const G4Run* run);
+      /// Callback to store the Geant4 event
+      virtual void saveEvent( OutputContext<G4Event>& ctxt);
+      /// Callback to store each Geant4 hit collection
+      virtual void saveCollection( OutputContext<G4Event>& ctxt, G4VHitsCollection* collection);
+      /// Commit data at end of filling procedure
+      virtual void commit( OutputContext<G4Event>& ctxt);
+
+      /// begin-of-event callback - creates EDM4hep event and adds it to the event context
+      virtual void begin(const G4Event* event);
+    protected:
+      /// Fill event parameters in EDM4hep event
+      template <typename T>
+      void saveEventParameters(const std::map<std::string, std::string >& parameters);
+    };
+    
+    /// Fill event parameters in EDM4hep event
+    template <typename T>
+    inline void Geant4Output2EDM4hep::saveEventParameters(const std::map<std::string, std::string >& parameters)  {
+      for(std::map<std::string, std::string >::const_iterator iter = parameters.begin(), endIter = parameters.end() ; iter != endIter ; ++iter)  {
+        T parameter;
+        std::istringstream iss(iter->second);
+        if ( (iss >> parameter).fail() )  {
+          printout(FATAL,"saveEventParameters","+++ Event parameter %s: FAILED to convert to type :%s",iter->first.c_str(),typeid(T).name());
+          continue;
+        }
+	auto& evtMD = m_store->getEventMetaData();
+	evtMD.setValue(iter->first,parameter);
+      }
+    }
+
+    /// Fill event parameters in EDM4hep event - std::string specialization
+    template <>
+    inline void Geant4Output2EDM4hep::saveEventParameters<std::string>(const std::map<std::string, std::string >& parameters)  {
+      for(std::map<std::string, std::string >::const_iterator iter = parameters.begin(), endIter = parameters.end() ; iter != endIter ; ++iter)  {
+	auto& evtMD = m_store->getEventMetaData();
+	evtMD.setValue(iter->first,iter->second);
+      }
+    }
+
+  }    // End namespace sim
+}      // End namespace dd4hep
+#endif // DD4HEP_DDG4_GEANT4OUTPUT2EDM4hep_H
+
+//==========================================================================
+//  AIDA Detector description implementation 
+//--------------------------------------------------------------------------
+// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+// All rights reserved.
+//
+// For the licensing terms see $DD4hepINSTALL/LICENSE.
+// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+//
+// Author     : F.Gaede, DESY
+//
+//==========================================================================
+
+// Framework include files
+#include "DD4hep/InstanceCount.h"
+#include "DD4hep/Detector.h"
+#include "DDG4/Geant4HitCollection.h"
+#include "DDG4/Geant4DataConversion.h"
+#include "DDG4/Geant4Context.h"
+#include "DDG4/Geant4Particle.h"
+#include "DDG4/Geant4Data.h"
+#include "DDG4/Geant4Action.h"
+
+//#include "DDG4/Geant4Output2EDM4hep.h"
+#include "G4ParticleDefinition.hh"
+#include "G4VProcess.hh"
+#include "G4Event.hh"
+#include "G4Run.hh"
+
+
+using namespace dd4hep::sim;
+using namespace dd4hep;
+using namespace std;
+namespace {
+  G4Mutex action_mutex=G4MUTEX_INITIALIZER;
+}
+
+#include "DDG4/Factories.h"
+DECLARE_GEANT4ACTION(Geant4Output2EDM4hep)
+
+/// Standard constructor
+Geant4Output2EDM4hep::Geant4Output2EDM4hep(Geant4Context* ctxt, const string& nam)
+: Geant4OutputAction(ctxt,nam), m_store(0), m_file(0), m_runNo(0), m_runNumberOffset(0), m_eventNumberOffset(0)
+{
+  declareProperty("RunHeader", m_runHeader);
+  declareProperty("EventParametersInt",    m_eventParametersInt);
+  declareProperty("EventParametersFloat",  m_eventParametersFloat);
+  declareProperty("EventParametersString", m_eventParametersString);
+  declareProperty("RunNumberOffset", m_runNumberOffset);
+  declareProperty("EventNumberOffset", m_eventNumberOffset);
+  printout( INFO, "Geant4Output2EDM4hep" ," instantiated ..." ) ;
+  InstanceCount::increment(this);
+}
+
+/// Default destructor
+Geant4Output2EDM4hep::~Geant4Output2EDM4hep()  {
+  G4AutoLock protection_lock(&action_mutex);
+  if ( m_file )  {
+    m_file->finish();
+    detail::deletePtr(m_file);
+  }
+  if (nullptr != m_store) {
+    delete m_store;
+  }
+  InstanceCount::decrement(this);
+}
+
+// Callback to store the Geant4 run information
+void Geant4Output2EDM4hep::beginRun(const G4Run* run)  {
+  G4AutoLock protection_lock(&action_mutex);
+  if ( 0 == m_file && !m_output.empty() )   {
+    m_store = new podio::EventStore ;
+    m_file = new podio::ROOTWriter(m_output, m_store);
+
+    printout( INFO, "Geant4Output2EDM4hep" ," opened %s for output", m_output.c_str() ) ;
+  }
+  
+  saveRun(run);
+}
+
+/// Callback to store the Geant4 run information
+void Geant4Output2EDM4hep::endRun(const G4Run* /*run*/)  {
+  // saveRun(run);
+}
+
+/// Commit data at end of filling procedure
+void Geant4Output2EDM4hep::commit( OutputContext<G4Event>& /* ctxt */)   {
+  if ( m_file )   {
+    G4AutoLock protection_lock(&action_mutex);
+    m_file->writeEvent();
+    m_store->clearCollections();
+    return;
+  }
+  except("+++ Failed to write output file. [Stream is not open]");
+}
+
+/// Callback to store the Geant4 run information
+void Geant4Output2EDM4hep::saveRun(const G4Run* /*run*/)  {
+  //G4AutoLock protection_lock(&action_mutex);
+
+  printout( WARNING, "Geant4Output2EDM4hep" ,"saveRun(): RunHeader not implemented in EDM4hep, nothing written ..." ) ;
+
+  // --- write an edm4hep::RunHeader ---------
+  //FIXME: need a suitable Runheader object in EDM4hep
+
+//  edm4hep::LCRunHeaderImpl* rh =  new edm4hep::LCRunHeaderImpl;
+//  for (std::map< std::string, std::string >::iterator it = m_runHeader.begin(); it != m_runHeader.end(); ++it) {
+//    rh->parameters().setValue( it->first, it->second );
+//  }
+//  m_runNo = m_runNumberOffset > 0 ? m_runNumberOffset + run->GetRunID() : run->GetRunID();
+//  rh->parameters().setValue("GEANT4Version", G4Version);
+//  rh->parameters().setValue("DD4HEPVersion", versionString());
+//  rh->setRunNumber(m_runNo);
+//  rh->setDetectorName(context()->detectorDescription().header().name());
+//  m_file->writeRunHeader(rh);
+}
+
+void Geant4Output2EDM4hep::begin(const G4Event* /* event */)  {
+}
+
+/// Data conversion interface for MC particles to EDM4hep format
+void Geant4Output2EDM4hep::saveParticles(Geant4ParticleMap* particles)    {
+  typedef detail::ReferenceBitMask<const int> PropertyMask;
+  typedef Geant4ParticleMap::ParticleMap ParticleMap;
+  const ParticleMap& pm = particles->particleMap;
+  size_t nparts = pm.size();
+  edm4hep::MCParticleCollection* mcpc =
+    const_cast<edm4hep::MCParticleCollection*>(
+      &m_store->get<edm4hep::MCParticleCollection>("MCParticles"));
+
+  if ( nparts > 0 )  {
+    size_t cnt = 0;
+    map<int,int> p_ids;
+    vector<const Geant4Particle*> p_part(pm.size(),0);
+    vector<edm4hep::MCParticle> p_edm4hep(pm.size());
+    // First create the particles
+    for(ParticleMap::const_iterator i=pm.begin(); i!=pm.end();++i, ++cnt)   {
+      int id = (*i).first;
+      const Geant4ParticleHandle p = (*i).second;
+      PropertyMask mask(p->status);
+      //      std::cout << " ********** mcp status : 0x" << std::hex << p->status << ", mask.isSet(G4PARTICLE_GEN_STABLE) x" << std::dec << mask.isSet(G4PARTICLE_GEN_STABLE)  <<std::endl ;
+      const G4ParticleDefinition* def = p.definition();
+      edm4hep::MCParticle mcp = edm4hep::MCParticle();
+      mcp.setPDG(p->pdgID);
+
+      float ps_fa[3] = {float(p->psx/CLHEP::GeV),float(p->psy/CLHEP::GeV),float(p->psz/CLHEP::GeV)};
+      mcp.setMomentum( ps_fa );
+
+      float pe_fa[3] = {float(p->pex/CLHEP::GeV),float(p->pey/CLHEP::GeV),float(p->pez/CLHEP::GeV)};
+      mcp.setMomentumAtEndpoint( pe_fa );
+
+      double vs_fa[3] = { p->vsx/CLHEP::mm, p->vsy/CLHEP::mm, p->vsz/CLHEP::mm } ;
+      mcp.setVertex( vs_fa );
+
+      double ve_fa[3] = { p->vex/CLHEP::mm, p->vey/CLHEP::mm, p->vez/CLHEP::mm } ;
+      mcp.setEndpoint( ve_fa );
+
+      mcp.setTime(p->time/CLHEP::ns);
+      mcp.setMass(p->mass/CLHEP::GeV);
+      mcp.setCharge(def ? def->GetPDGCharge() : 0); // Charge(e+) = 1 !
+
+      // Set generator status
+      mcp.setGeneratorStatus(0);
+      if( p->genStatus ) {
+        mcp.setGeneratorStatus( p->genStatus ) ;
+      } else {
+        if ( mask.isSet(G4PARTICLE_GEN_STABLE) )             mcp.setGeneratorStatus(1);
+        else if ( mask.isSet(G4PARTICLE_GEN_DECAYED) )       mcp.setGeneratorStatus(2);
+        else if ( mask.isSet(G4PARTICLE_GEN_DOCUMENTATION) ) mcp.setGeneratorStatus(3);
+        else if ( mask.isSet(G4PARTICLE_GEN_BEAM) )          mcp.setGeneratorStatus(4);
+        else if ( mask.isSet(G4PARTICLE_GEN_OTHER) )         mcp.setGeneratorStatus(9);
+      }
+
+      // Set simulation status
+      mcp.setCreatedInSimulation(         mask.isSet(G4PARTICLE_SIM_CREATED) );
+      mcp.setBackscatter(                 mask.isSet(G4PARTICLE_SIM_BACKSCATTER) );
+      mcp.setVertexIsNotEndpointOfParent( mask.isSet(G4PARTICLE_SIM_PARENT_RADIATED) );
+      mcp.setDecayedInTracker(            mask.isSet(G4PARTICLE_SIM_DECAY_TRACKER) );
+      mcp.setDecayedInCalorimeter(        mask.isSet(G4PARTICLE_SIM_DECAY_CALO) );
+      mcp.setHasLeftDetector(             mask.isSet(G4PARTICLE_SIM_LEFT_DETECTOR) );
+      mcp.setStopped(                     mask.isSet(G4PARTICLE_SIM_STOPPED) );
+      mcp.setOverlay(                     false );
+
+      //fg: if simstatus !=0 we have to set the generator status to 0:
+      if( mcp.isCreatedInSimulation() )
+        mcp.setGeneratorStatus( 0 )  ;
+
+      mcp.setSpin(p->spin);
+      mcp.setColorFlow(p->colorFlow);
+
+      mcpc->push_back(mcp);
+      p_ids[id] = cnt;
+      p_part[cnt] = p;
+      p_edm4hep[cnt] = mcp;
+    }
+
+    // Now establish parent-daughter relationships
+    for(size_t i=0, n=p_ids.size(); i<n; ++i)   {
+      map<int,int>::iterator k;
+      const Geant4Particle* p = p_part[i];
+      edm4hep::MCParticle q = p_edm4hep[i];
+      const Geant4Particle::Particles& dau = p->daughters;
+      for(Geant4Particle::Particles::const_iterator j=dau.begin(); j!=dau.end(); ++j)  {
+        int idau = *j;
+        if ( (k=p_ids.find(idau)) == p_ids.end() )  {  // Error!!!
+          printout(FATAL,"Geant4Conversion","+++ Particle %d: FAILED to find daughter with ID:%d",p->id,idau);
+          continue;
+        }
+        int iqdau = (*k).second;
+        edm4hep::MCParticle qdau = p_edm4hep[iqdau];
+        qdau.addToParents(q);
+      }
+      const Geant4Particle::Particles& par = p->parents;
+      for(Geant4Particle::Particles::const_iterator j=par.begin(); j!=par.end(); ++j)  {
+        int ipar = *j; // A parent ID iof -1 means NO parent, because a base of 0 is perfectly leagal!
+        if ( ipar>=0 && (k=p_ids.find(ipar)) == p_ids.end() )  {  // Error!!!
+          printout(FATAL,"Geant4Conversion","+++ Particle %d: FAILED to find parent with ID:%d",p->id,ipar);
+          continue;
+        }
+        int iqpar = (*k).second;
+        edm4hep::MCParticle qpar = p_edm4hep[iqpar];
+        q.addToParents(qpar);
+      }
+    }
+  }
+}
+
+/// Callback to store the Geant4 event
+void Geant4Output2EDM4hep::saveEvent(OutputContext<G4Event>& ctxt)  {
+
+  if( m_FirstEvent ){
+    createCollections( ctxt ) ;
+    m_FirstEvent = false ;
+  }
+
+  EventParameters* parameters = context()->event().extension<EventParameters>(false);
+  int runNumber(0), eventNumber(0);
+  const int eventNumberOffset(m_eventNumberOffset > 0 ? m_eventNumberOffset : 0);
+  const int runNumberOffset(m_runNumberOffset > 0 ? m_runNumberOffset : 0);
+  // Get event number, run number and parameters from extension ...
+  if ( parameters ) {
+    runNumber = parameters->runNumber() + runNumberOffset;
+    eventNumber = parameters->eventNumber() + eventNumberOffset;
+    parameters->extractParameters(*m_store);
+  } else { // ... or from DD4hep framework
+    runNumber = m_runNo + runNumberOffset;
+    eventNumber = ctxt.context->GetEventID() + eventNumberOffset;
+  }
+  printout(INFO,"Geant4Output2EDM4hep","+++ Saving EDM4hep event %d run %d.", eventNumber, runNumber);
+
+  // this does not compile as create() is we only get a const ref - need to review PODIO EventStore API
+  // auto& evtHCol = m_store->get<edm4hep::EventHeaderCollection>("EventHeader") ;
+  // auto evtHdr = evtHCol.create() ;
+  auto* evtHCol = const_cast<edm4hep::EventHeaderCollection*>(&m_store->get<edm4hep::EventHeaderCollection>("EventHeader") );
+  auto evtHdr = evtHCol->create() ;
+
+  evtHdr.setRunNumber(runNumber);
+  evtHdr.setEventNumber(eventNumber);
+//not implemented in EDM4hep ?  evtHdr.setDetectorName(context()->detectorDescription().header().name());
+  evtHdr.setTimeStamp( std::time(nullptr) ) ;
+
+  saveEventParameters<int>(m_eventParametersInt);
+  saveEventParameters<float>(m_eventParametersFloat);
+  saveEventParameters<std::string>(m_eventParametersString);
+
+  Geant4ParticleMap* part_map = context()->event().extension<Geant4ParticleMap>(false);
+  if ( part_map )   {
+    print("+++ Saving %d EDM4hep particles....",int(part_map->particleMap.size()));
+    if ( part_map->particleMap.size() > 0 )  {
+      saveParticles(part_map);
+    }
+  }
+}
+
+/// Callback to store each Geant4 hit collection
+void Geant4Output2EDM4hep::saveCollection(OutputContext<G4Event>& /*ctxt*/, G4VHitsCollection* collection)  {
+
+  size_t nhits = collection->GetSize();
+  std::string colName = collection->GetName();
+
+  printout(DEBUG,"Geant4Output2EDM4hep","+++ Saving EDM4hep collection %s with %d entries.",
+     colName.c_str(),int(nhits));
+
+  Geant4HitCollection* coll = dynamic_cast<Geant4HitCollection*>(collection);
+  if( coll == nullptr ){
+    printout(ERROR, "Geant4Output2EDM4hep" , " no Geant4HitCollection:  %s ", colName.c_str() );
+    return ;
+  }
+
+  Geant4ParticleMap* pm = context()->event().extension<Geant4ParticleMap>(false);
+
+  edm4hep::MCParticleCollection* mcpc =
+    const_cast<edm4hep::MCParticleCollection*>(
+      &m_store->get<edm4hep::MCParticleCollection>("MCParticles"));
+
+  //-------------------------------------------------------------------
+  if( typeid( Geant4Tracker::Hit ) == coll->type().type  ){
+
+    edm4hep::SimTrackerHitCollection* sthc =
+      const_cast<edm4hep::SimTrackerHitCollection*>(&m_store->get<edm4hep::SimTrackerHitCollection>(colName));
+
+    for(unsigned i=0 ; i < nhits ; ++i){
+      auto sth = sthc->create() ;
+
+      const Geant4Tracker::Hit* hit = coll->hit(i);
+      const Geant4Tracker::Hit::Contribution& t = hit->truth;
+      int trackID = pm->particleID(t.trackID);
+
+      auto mcp = mcpc->at(trackID);
+
+      sth.setCellID( hit->cellID ) ;
+      sth.setEDep(hit->energyDeposit/CLHEP::GeV);
+      sth.setPathLength(hit->length/CLHEP::mm);
+      sth.setTime(hit->truth.time/CLHEP::ns);
+      sth.setMCParticle(mcp);
+      sth.setPosition({hit->position.x()/CLHEP::mm,
+           hit->position.y()/CLHEP::mm,
+           hit->position.z()/CLHEP::mm});
+      sth.setMomentum(edm4hep::Vector3f(hit->momentum.x()/CLHEP::GeV,
+          hit->momentum.y()/CLHEP::GeV,
+          hit->momentum.z()/CLHEP::GeV ));
+
+      auto particleIt = pm->particles().find(trackID);
+      if( ( particleIt != pm->particles().end()) ){
+        // if the original track ID of the particle is not the same as the
+        // original track ID of the hit it was produced by an MCParticle that
+        // is no longer stored
+        sth.setProducedBySecondary( (particleIt->second->originalG4ID != t.trackID) );
+      }
+    }
+  //-------------------------------------------------------------------
+  }
+  else if( typeid( Geant4Calorimeter::Hit ) == coll->type().type ){
+
+    Geant4Sensitive*       sd      = coll->sensitive();
+    int hit_creation_mode = sd->hitCreationMode();
+
+    edm4hep::SimCalorimeterHitCollection* sCaloHitColl =
+      const_cast<edm4hep::SimCalorimeterHitCollection*>(
+  &m_store->get<edm4hep::SimCalorimeterHitCollection>(colName));
+
+    colName += "Contributions"  ;
+
+    edm4hep::CaloHitContributionCollection* sCaloHitContColl =
+      const_cast<edm4hep::CaloHitContributionCollection*>(
+  &m_store->get<edm4hep::CaloHitContributionCollection>(colName));
+
+
+    for(unsigned i=0 ; i < nhits ; ++i){
+      auto sch = sCaloHitColl->create() ;
+
+      const Geant4Calorimeter::Hit* hit = coll->hit(i);
+
+      sch.setCellID( hit->cellID );
+      sch.setPosition({
+           float(hit->position.x()/CLHEP::mm),
+           float(hit->position.y()/CLHEP::mm),
+           float(hit->position.z()/CLHEP::mm)});
+      sch.setEnergy( hit->energyDeposit );
+
+      // now add the individual step contributions
+      for(Geant4HitData::Contributions::const_iterator ci=hit->truth.begin();
+        ci!=hit->truth.end(); ++ci){
+
+        auto sCaloHitCont = sCaloHitContColl->create();
+        sch.addToContributions( sCaloHitCont );
+
+        const Geant4HitData::Contribution& c = *ci;
+        int trackID = pm->particleID(c.trackID);
+        auto mcp = mcpc->at(trackID);
+
+        sCaloHitCont.setEnergy( c.deposit/CLHEP::GeV );
+        sCaloHitCont.setTime( c.time/CLHEP::ns );
+        sCaloHitCont.setParticle( mcp );
+
+        if ( hit_creation_mode == Geant4Sensitive::DETAILED_MODE )     {
+          sCaloHitCont.setPDG( c.pdgID );
+          sCaloHitCont.setStepPosition( edm4hep::Vector3f(
+            c.x/CLHEP::mm,
+            c.y/CLHEP::mm, 
+            c.z/CLHEP::mm) );
+        }
+      }
+    }
+  //-------------------------------------------------------------------
+  } else {
+
+    printout(ERROR, "Geant4Output2EDM4hep" , " unknown type in Geant4HitCollection  %s ",
+       coll->type().type.name() );
+  }
+}
+
+
+void Geant4Output2EDM4hep::createCollections(OutputContext<G4Event>& ctxt){
+
+  m_store->create<edm4hep::MCParticleCollection>("MCParticles");
+  m_file->registerForWrite("MCParticles");
+  printout(DEBUG,"Geant4Output2EDM4hep","+++ created collection MCParticles" );
+
+  m_store->create<edm4hep::EventHeaderCollection>("EventHeader") ;
+  m_file->registerForWrite("EventHeader");
+  printout(DEBUG,"Geant4Output2EDM4hep","+++ created collection EventHeader" );
+
+
+  const G4Event* evt = ctxt.context ;
+  G4HCofThisEvent* hce = evt->GetHCofThisEvent();
+  int nCol = hce->GetNumberOfCollections();
+
+  for (int i = 0; i < nCol; ++i) {
+    G4VHitsCollection* hc = hce->GetHC(i);
+    std::string colName =  hc->GetName() ;
+    Geant4HitCollection* coll = dynamic_cast<Geant4HitCollection*>(hc);
+    if( coll == nullptr ){
+      printout(WARNING, "Geant4Output2EDM4hep" , " no Geant4HitCollection:  %s ", colName.c_str() );
+      continue ;
+    }
+
+    if( typeid( Geant4Tracker::Hit ) == coll->type().type  ){
+
+      m_store->create<edm4hep::SimTrackerHitCollection>(colName);
+      m_file->registerForWrite(colName);
+      printout(DEBUG,"Geant4Output2EDM4hep","+++ created collection %s",colName.c_str() );
+    }
+    else if( typeid( Geant4Calorimeter::Hit ) == coll->type().type ){
+
+      m_store->create<edm4hep::SimCalorimeterHitCollection>(colName);
+      m_file->registerForWrite(colName);
+      printout(DEBUG,"Geant4Output2EDM4hep","+++ created collection %s",colName.c_str() );
+
+      colName += "Contributions"  ;
+      m_store->create<edm4hep::CaloHitContributionCollection>(colName);
+      m_file->registerForWrite(colName);
+      printout(DEBUG,"Geant4Output2EDM4hep","+++ created collection %s",colName.c_str() );
+
+    } else {
+
+      printout(WARNING, "Geant4Output2EDM4hep" ,
+         " unknown type in Geant4HitCollection  %s ", coll->type().type.name() );
+    }
+  }
+
+
+}