From 422162377e0ea4a41c6fa7c76c5463f724e67ce3 Mon Sep 17 00:00:00 2001
From: Markus Frank <markus.frank@cern.ch>
Date: Thu, 3 Jul 2014 18:52:15 +0000
Subject: [PATCH] Improve event data handling

---
 DDEve/DDEve/DDG4Support.C              | 46 +++++++++---------
 DDEve/include/DDEve/DDEveEventData.h   | 67 ++++++++++++++++++++++++++
 DDEve/include/DDEve/DDG4EventHandler.h | 23 ++-------
 DDEve/include/DDEve/EventHandler.h     | 49 +++++++++++--------
 DDEve/include/DDEve/SimulationHit.h    | 56 ---------------------
 DDEve/src/DDG4EventHandler.cpp         | 51 ++++++++++++--------
 DDEve/src/Display.cpp                  | 57 +++++++++++++---------
 DDEve/src/EventControl.cpp             | 14 +++---
 DDEve/src/EventHandler.cpp             | 61 +----------------------
 9 files changed, 200 insertions(+), 224 deletions(-)
 create mode 100644 DDEve/include/DDEve/DDEveEventData.h
 delete mode 100644 DDEve/include/DDEve/SimulationHit.h

diff --git a/DDEve/DDEve/DDG4Support.C b/DDEve/DDEve/DDG4Support.C
index c81aff05a..a9292b6c5 100644
--- a/DDEve/DDEve/DDG4Support.C
+++ b/DDEve/DDEve/DDG4Support.C
@@ -19,7 +19,7 @@ namespace DD4hep { namespace Geometry {
 class G4Step;
 class G4StepPoint;
 #include "DDG4/Geant4Data.h"
-#include "DDEve/SimulationHit.h"
+#include "DDEve/DDEveEventData.h"
 
 
 #ifdef __DD4HEP_DDEVE_EXCLUSIVE__
@@ -86,36 +86,38 @@ namespace DD4hep {
 #pragma link C++ class DD4hep::Simulation::SimpleCalorimeter+;
 #pragma link C++ class DD4hep::Simulation::SimpleCalorimeter::Hit+;
 #pragma link C++ class std::vector<DD4hep::Simulation::SimpleCalorimeter::Hit*>+;
-
 #else
+
 using namespace std;
 using namespace DD4hep;
 using namespace DD4hep::Simulation;
-
-static void* _convertHitCollection(const char* source)  {
-  typedef DD4hep::DDEve::SimulationHit SimulationHit;
-  const std::vector<SimpleHit*>* c = (std::vector<SimpleHit*>*)source;
-  std::vector<SimulationHit>* pv = new std::vector<SimulationHit>();
-  if ( source && c->size() > 0 )   {
-    for(std::vector<SimpleHit*>::const_iterator k=c->begin(); k!=c->end(); ++k)   {
-      SimpleTracker::Hit* trh = dynamic_cast<SimpleTracker::Hit*>(*k);
-      if ( trh )   {
-	pv->push_back(SimulationHit(trh->position, trh->energyDeposit));
-	continue;
-      }
-      SimpleCalorimeter::Hit* cah = dynamic_cast<SimpleCalorimeter::Hit*>(*k);
-      if ( cah )   {
-	pv->push_back(SimulationHit(cah->position, cah->energyDeposit));
-	continue;
-      }
-    }
+template <typename T> static T* _fill(SimpleHit* ptr, DDEveHit* target)   {
+  T* s = dynamic_cast<T*>(ptr);
+  if ( s )   {
+    Geometry::Position* p = &s->position;
+    target->x = p->X();
+    target->y = p->Y();
+    target->z = p->Z();
+    target->deposit = s->energyDeposit;
   }
-  return pv;
+  return s;
+}
+
+static void* _convertHitFunc(void* source, DDEveHit* target)  {
+  void* result;
+  SimpleHit* hit = (SimpleHit*)source;
+  if ((result=_fill<SimpleTracker::Hit>(hit,target))) return result;
+  if ((result=_fill<SimpleCalorimeter::Hit>(hit,target))) return result;
+  return 0;
+}
+
+static void* _convertHit(const char*)  {
+  return (void*)_convertHitFunc;
 }
 
 #include "DD4hep/Factories.h"
 using namespace DD4hep::Geometry;
-DECLARE_CONSTRUCTOR(DDEve_DDG4CollectionAccess,_convertHitCollection)
+DECLARE_CONSTRUCTOR(DDEve_DDG4HitAccess,_convertHit)
 #endif
 #endif
 
diff --git a/DDEve/include/DDEve/DDEveEventData.h b/DDEve/include/DDEve/DDEveEventData.h
new file mode 100644
index 000000000..6a6b5b76a
--- /dev/null
+++ b/DDEve/include/DDEve/DDEveEventData.h
@@ -0,0 +1,67 @@
+// $Id: LCDD.h 1117 2014-04-25 08:07:22Z markus.frank@cern.ch $
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+#ifndef DD4HEP_DDEVE_DDEVEHIT_H
+#define DD4HEP_DDEVE_DDEVEHIT_H
+
+// C/C++ include files
+#include <vector>
+
+/*
+ *   DD4hep namespace declaration
+ */
+namespace DD4hep {
+
+  /// DDEve event classes: Basic hit
+  /** 
+   * @author  M.Frank
+   * @version 1.0
+   */
+  class DDEveHit   {
+  public:
+    /// Hit position
+    float x,y,z; 
+    /// Energy deposit
+    float deposit;
+    /// Default constructor
+    DDEveHit();
+    /// Initializing constructor
+    DDEveHit(float xx, float yy, float zz, float d);
+    /// Copy constructor
+    DDEveHit(const DDEveHit& c);
+    /// Default destructor
+    ~DDEveHit();
+    /// Assignment operator
+    DDEveHit& operator=(const DDEveHit& c);
+  };
+  typedef std::vector<DDEveHit> DDEveHits;
+
+  /// Default constructor
+  inline DDEveHit::DDEveHit() : x(0.0), y(0.0), z(0.0), deposit(0.0) {}
+  /// Initializing constructor
+  inline DDEveHit::DDEveHit(float xx, float yy, float zz, float d) : x(xx), y(yy), z(zz), deposit(d) {}
+  /// Copy constructor
+  inline DDEveHit::DDEveHit(const DDEveHit& c) : x(c.x), y(c.y), z(c.z), deposit(c.deposit) {}
+  /// Default destructor
+  inline DDEveHit::~DDEveHit()  {}
+  /// Assignment operator
+  inline DDEveHit& DDEveHit::operator=(const DDEveHit& c)  {
+    if ( this != &c )  {
+      x = c.x;
+      y = c.y;
+      z = c.z;
+      deposit = c.deposit;
+    }
+    return *this;
+  }
+
+} /* End namespace DD4hep   */
+
+
+#endif /* DD4HEP_DDEVE_DDEVEHIT_H */
+
diff --git a/DDEve/include/DDEve/DDG4EventHandler.h b/DDEve/include/DDEve/DDG4EventHandler.h
index a10eb7675..6d50541dc 100644
--- a/DDEve/include/DDEve/DDG4EventHandler.h
+++ b/DDEve/include/DDEve/DDG4EventHandler.h
@@ -26,9 +26,6 @@ class TBranch;
  */
 namespace DD4hep {
 
-  // Forward declarations
-  namespace Simulation { class SimpleHit; }
-
   /** @class DDG4EventHandler  DDG4EventHandler.h DDEve/DDG4EventHandler.h
    *
    * @author  M.Frank
@@ -36,47 +33,37 @@ namespace DD4hep {
    */
   class DDG4EventHandler : public EventHandler  {
   public:
-    typedef Simulation::SimpleHit Hit;
     typedef std::map<std::string,std::pair<TBranch*,void*> > Branches;
+    typedef void* (*HitAccessor_t)(void*, DDEveHit*);
   protected:
     /// Reference to data file
     std::pair<TFile*,TTree*> m_file;
     /// Branch map
     Branches m_branches;
-    /// Data collection map
-    Data     m_data;
     /// File entry number
     Long64_t m_entry;
-
+    /// 
+    HitAccessor_t m_simhitConverter;
   public:
     /// Standard constructor
     DDG4EventHandler();
     /// Default destructor
     virtual ~DDG4EventHandler();
 
-    const Branches& branches()  const   {  return m_branches; }
-    /// Access the map of simulation data collections
-    virtual const Data& data()  const { return m_data;  }
-    /// Check if a data file is connected to the handler
-    virtual bool hasFile() const;
     /// Access the number of events on the current input data source (-1 if no data source connected)
     virtual long numEvents() const;
     /// Access the data source name
     std::string datasourceName() const;
-
+    /// Call functor on hit collection
+    virtual size_t collectionLoop(const std::string& collection, DDEveHitActor& actor);
     /// Open new data file
     virtual bool Open(const std::string& file_name);
-
     /// User overloadable function: Load the next event
     virtual bool NextEvent();
     /// User overloadable function: Load the previous event
     virtual bool PreviousEvent();
     /// Goto a specified event in the file
     virtual bool GotoEvent(long event_number);
-
-    /// Fill eta-phi histogram from a hit collection
-    virtual size_t FillEtaPhiHistogram(const std::string& collection, TH2F* histogram);
-
     /// Load the specified event
     Int_t ReadEvent(Long64_t n);
 
diff --git a/DDEve/include/DDEve/EventHandler.h b/DDEve/include/DDEve/EventHandler.h
index e15dc7ba0..5ca60736b 100644
--- a/DDEve/include/DDEve/EventHandler.h
+++ b/DDEve/include/DDEve/EventHandler.h
@@ -10,6 +10,7 @@
 #define DD4HEP_DDEVE_EVENTHANDLER_H
 
 // Framework include files
+#include "DDEve/DDEveEventData.h"
 #include "TClass.h"
 class TH2F;
 
@@ -26,50 +27,61 @@ class TH2F;
 namespace DD4hep {
 
   class EventConsumer;
+  /// Event data actor base class. Used to extract data from concrete classes.
+  /** 
+   * @author  M.Frank
+   * @version 1.0
+   */
+  struct DDEveHitActor  {
+    virtual ~DDEveHitActor() {}
+    virtual void operator()(const DDEveHit&) = 0;
+    virtual void setSize(size_t /* num_elements */) {}
+  };
 
-  /** @class EventHandler  EventHandler.h DDEve/EventHandler.h
-   *
+  /// Event handler base class. Interface to all DDEve I/O actions
+  /** 
    * @author  M.Frank
    * @version 1.0
    */
   class EventHandler   {
   public:
-    typedef std::pair<const char*,std::vector<void*>* > Collection;
-    typedef std::map<std::string,std::vector<Collection> > Data;
+    /// Collection definition: name, size
+    typedef std::pair<const char*,size_t> Collection;
+    /// Types collection: collections are grouped by type (class name)
+    typedef std::map<std::string,std::vector<Collection> > TypedEventCollections;
+    /// Subscriber set
     typedef std::set<EventConsumer*> Subscriptions;
 
-    typedef std::pair<const std::type_info*,std::string> DataID;
-    typedef void (*fcn)(void*);
-    typedef std::pair<fcn,void*> DataHolder;
-    typedef std::map<DataID, DataHolder> EventCollections;
   protected:
+    /// Data collection map
+    TypedEventCollections m_data;
     /// Data subscriptions (unordered)
     Subscriptions m_subscriptions;
-    EventCollections m_collections;
+    /// Flag to indicate that a file is opened
+    bool m_hasFile;
+    /// Flag to indicate that an event is loaded
     bool m_hasEvent;
   public:
     /// Standard constructor
     EventHandler();
     /// Default destructor
     virtual ~EventHandler();
-
-    template <typename T> std::vector<const T*> GetHits(const std::string& collection);
     /// Access the map of simulation data collections
-    virtual const Data& data()  const = 0;
-    /// Check if a data file is connected to the handler
-    virtual bool hasFile() const = 0;
+    virtual const TypedEventCollections& data()  const   { return m_data;      }
+    /// Check if an event is present in memory
     virtual bool hasEvent() const  { return m_hasEvent; }
+    /// Check if a data file is connected to the handler
+    virtual bool hasFile() const   { return m_hasFile;  }
     /// Access the number of events on the current input data source (-1 if no data source connected)
     virtual long numEvents() const = 0;
     /// Access the data source name
     virtual std::string datasourceName() const = 0;
-
+    /// Loop over collection and extract data
+    virtual size_t collectionLoop(const std::string& collection, DDEveHitActor& actor) = 0;
     /// Clear all event related data caches
     virtual void ClearCache();
-
     /// Open a new event data file
     virtual bool Open(const std::string& file_name) = 0;
-
     /// Load the next event
     virtual bool NextEvent() = 0;
     /// User overloadable function: Load the previous event
@@ -82,9 +94,6 @@ namespace DD4hep {
     /// Unsubscribe from notification of new data present
     virtual void Unsubscribe(EventConsumer* display);
 
-    /// Fill eta-phi histogram from a hit collection
-    virtual size_t FillEtaPhiHistogram(const std::string& collection, TH2F* histogram)  = 0;
-
 #ifndef __CINT__
     /// Notfy all subscribers
     virtual void NotifySubscribers(void (EventConsumer::*pmf)(EventHandler*));
diff --git a/DDEve/include/DDEve/SimulationHit.h b/DDEve/include/DDEve/SimulationHit.h
deleted file mode 100644
index 12ce2b3f6..000000000
--- a/DDEve/include/DDEve/SimulationHit.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// $Id: LCDD.h 1117 2014-04-25 08:07:22Z markus.frank@cern.ch $
-//====================================================================
-//  AIDA Detector description implementation for LCD
-//--------------------------------------------------------------------
-//
-//  Author     : M.Frank
-//
-//====================================================================
-#ifndef DD4HEP_DDEVE_SIMULATIONHIT_H
-#define DD4HEP_DDEVE_SIMULATIONHIT_H
-
-#ifndef __DD4HEP_DDEVE_EXCLUSIVE__
-// Framework include files
-#include "DD4hep/Objects.h"
-#endif
-
-// C/C++ include files
-#include <vector>
-
-/*
- *   DD4hep namespace declaration
- */
-namespace DD4hep {
-  namespace DDEve  {
-
-    class SimulationHit   {
-    public:
-      typedef Geometry::Position Position;
-      Position position;
-      float deposit;
-      SimulationHit();
-      SimulationHit(const Position& p, float d);
-      SimulationHit(const SimulationHit& c);
-      ~SimulationHit();
-      SimulationHit& operator=(const SimulationHit& c);
-    };
-    typedef std::vector<SimulationHit> SimulationHits;
-
-    inline SimulationHit::SimulationHit() : deposit(0.0) {}
-    inline SimulationHit::SimulationHit(const Position& p, float d) : position(p), deposit(d) {}
-    inline SimulationHit::SimulationHit(const SimulationHit& c) : position(c.position), deposit(c.deposit) {}
-    inline SimulationHit::~SimulationHit()  {}
-    inline SimulationHit& SimulationHit::operator=(const SimulationHit& c)  {
-      if ( this != &c )  {
-	position = c.position;
-	deposit = c.deposit;
-      }
-      return *this;
-    }
-
-  }
-} /* End namespace DD4hep   */
-
-
-#endif /* DD4HEP_DDEVE_SIMULATIONHIT_H */
-
diff --git a/DDEve/src/DDG4EventHandler.cpp b/DDEve/src/DDG4EventHandler.cpp
index 634dfa664..c19d423f6 100644
--- a/DDEve/src/DDG4EventHandler.cpp
+++ b/DDEve/src/DDG4EventHandler.cpp
@@ -9,9 +9,9 @@
 
 // Framework include files
 #include "DDEve/DDG4EventHandler.h"
-#include "DDEve/SimulationHit.h"
 #include "DD4hep/Printout.h"
 #include "DD4hep/Objects.h"
+#include "DD4hep/Factories.h"
 
 #include "TH2.h"
 #include "TFile.h"
@@ -29,9 +29,21 @@ using namespace std;
 using namespace DD4hep;
 
 ClassImp(DDG4EventHandler)
+namespace {
+  union FCN  {
+    FCN(void* p) { ptr = p; }
+    DDG4EventHandler::HitAccessor_t func;
+    void* ptr;
+  };
+}
 
 /// Standard constructor
 DDG4EventHandler::DDG4EventHandler() : EventHandler(), m_file(0,0), m_entry(-1) {
+  void* ptr = ROOT::Reflex::PluginService::Create<void*>("DDEve_DDG4HitAccess",(const char*)"");
+  if ( 0 == ptr )   {
+    throw runtime_error("FATAL: Failed to access function pointer from factory DDEve_DDG4HitAccess");
+  }
+  m_simhitConverter = FCN(ptr).func;
 }
 
 /// Default destructor
@@ -46,7 +58,7 @@ DDG4EventHandler::~DDG4EventHandler()   {
 
 /// Load the next event
 bool DDG4EventHandler::NextEvent()   {
-  ReadEvent(++m_entry) > 0;
+  return ReadEvent(++m_entry) > 0;
 }
 
 /// Load the previous event
@@ -59,11 +71,6 @@ bool DDG4EventHandler::GotoEvent(long event_number)   {
   return ReadEvent(m_entry = event_number) > 0;
 }
 
-/// Check if a data file is connected to the handler
-bool DDG4EventHandler::hasFile() const  {
-  return 0 != m_file.first && 0 != m_file.second;
-}
-
 /// Access the number of events on the current input data source (-1 if no data source connected)
 long DDG4EventHandler::numEvents() const   {
   if ( hasFile() )  {
@@ -80,18 +87,22 @@ std::string DDG4EventHandler::datasourceName() const   {
   return "UNKNOWN";
 }
 
-/// Fill eta-phi histogram from a hit collection
-size_t DDG4EventHandler::FillEtaPhiHistogram(const std::string& collection, TH2F* histogram)  {
-  typedef DD4hep::DDEve::SimulationHit Hit;
-  typedef std::vector<const Hit*> _P;
-  if ( hasEvent() )  {
-    _P pv = GetHits<Hit>(collection.c_str());
-    for(_P::const_iterator i=pv.begin(); i!=pv.end(); ++i)   {
-      const Geometry::Position& pos = (*i)->position;
-      float deposit = (*i)->deposit;
-      histogram->Fill(pos.Eta(),pos.Phi(),deposit);
+/// Call functor on hit collection
+size_t DDG4EventHandler::collectionLoop(const std::string& collection, DDEveHitActor& actor)   {
+  typedef std::vector<void*> _P;
+  Branches::const_iterator i = m_branches.find(collection);
+  if ( i != m_branches.end() )   {
+    const _P* data = (_P*)(*i).second.second;
+    if ( data )  {
+      DDEveHit hit;
+      actor.setSize(data->size());
+      for(_P::const_iterator i=data->begin(); i!=data->end(); ++i)   {
+	if ( (*m_simhitConverter)(*i,&hit) )    {
+	  actor(hit);
+	}
+      }
+      return data->size();
     }
-    return pv.size();
   }
   return 0;
 }
@@ -118,7 +129,7 @@ Int_t DDG4EventHandler::ReadEvent(Long64_t event_number)   {
 	for(Branches::const_iterator i=m_branches.begin(); i != m_branches.end(); ++i)  {
 	  TBranch* b = (*i).second.first;
 	  std::vector<void*>* data = *(std::vector<void*>**)b->GetAddress();
-	  m_data[b->GetClassName()].push_back(make_pair(b->GetName(),data));
+	  m_data[b->GetClassName()].push_back(make_pair(b->GetName(),data->size()));
 	}
 	m_hasEvent = true;
 	NotifySubscribers(&EventConsumer::OnNewEvent);
@@ -143,6 +154,7 @@ Int_t DDG4EventHandler::ReadEvent(Long64_t event_number)   {
 bool DDG4EventHandler::Open(const std::string& name)   {
   string err;
   if ( m_file.first ) m_file.first->Close();
+  m_hasFile = false;
   m_hasEvent = false;
   try {
     char buff[PATH_MAX];
@@ -167,6 +179,7 @@ bool DDG4EventHandler::Open(const std::string& name)   {
 	  if ( !b ) continue;
 	  b->SetAddress(&m_branches[b->GetName()].second);
 	}
+	m_hasFile = true;
 	NotifySubscribers(&EventConsumer::OnFileOpen);
 	return true;
       }
diff --git a/DDEve/src/Display.cpp b/DDEve/src/Display.cpp
index 25fde02c4..66f1e9c01 100644
--- a/DDEve/src/Display.cpp
+++ b/DDEve/src/Display.cpp
@@ -18,7 +18,7 @@
 #include "DDEve/EvePgonSetProjectedContextMenu.h"
 #include "DDEve/DDG4EventHandler.h"
 #include "DDEve/Utilities.h"
-#include "DDEve/SimulationHit.h"
+#include "DDEve/DDEveEventData.h"
 
 #include "DD4hep/LCDD.h"
 #include "DD4hep/LCDDData.h"
@@ -71,6 +71,22 @@ namespace DD4hep {
       //display->LoadXML("file:../DD4hep/examples/CLICSiD/compact/DDEve.xml");
     }
   }
+
+  struct PointsetCreator : public DDEveHitActor  {
+    TEvePointSet* points;
+    int count;
+    PointsetCreator(TEvePointSet* ps) : points(ps), count(0) {}
+    virtual void operator()(const DDEveHit& hit)  
+    {     points->SetPoint(count++, hit.x/10e0, hit.y/10e0, hit.z/10e0);    }
+  };
+  struct EtaPhiHistogramActor : public DDEveHitActor  {
+    TH2F* histogram;
+    EtaPhiHistogramActor(TH2F* h) : DDEveHitActor(), histogram(h) {}
+    virtual void operator()(const DDEveHit& hit)   {
+      const Geometry::Position pos(hit.x/10e0,hit.y/10e0,hit.z/10e0);
+      histogram->Fill(pos.Eta(),pos.Phi(),hit.deposit);
+    }
+  };
 }
 
 Display::CalodataContext::CalodataContext() 
@@ -241,7 +257,8 @@ Display::CalodataContext& Display::GetCaloHistogram(const std::string& nam)   {
 	ctx.calo3D->SetAutoRange(kTRUE);
 	ctx.calo3D->SetMaxTowerH(10);
 	ImportGeo(ctx.calo3D);
-	eventHandler().FillEtaPhiHistogram(hits.c_str(),h);
+	EtaPhiHistogramActor actor(h);
+	eventHandler().collectionLoop(hits,actor);
 	ctx.eveHist->DataChanged();
       }
       else   {
@@ -412,29 +429,22 @@ TFile* Display::Open(const char* name) const   {
 
 /// Consumer event data
 void Display::OnNewEvent(EventHandler* handler )   {
-  typedef DD4hep::DDEve::SimulationHit Hit;
-  typedef EventHandler::Data Data;
-  typedef EventHandler::Collection Collection;
-  const Data& event = handler->data();
+  typedef EventHandler::TypedEventCollections Types;
+  typedef std::vector<EventHandler::Collection> Collections;
+  const Types& types = handler->data();
 
   printout(ERROR,"EventHandler","+++ Display new event.....");
   GetEve().DestroyElements();
-  for(Data::const_iterator i=event.begin(); i!=event.end(); ++i)  {
-    for(std::vector<Collection>::const_iterator j=(*i).second.begin(); j!=(*i).second.end(); ++j)   {
-      const std::vector<void*>* c = (*j).second;
-      if ( c->size() > 0 )   {
-	typedef std::vector<const Hit*> _P;
-	string coll_name = (*j).first;
-	_P pv = handler->GetHits<Hit>(coll_name);
-	if ( pv.size() > 0 )   {
-	  cout << coll_name << ": Got " << pv.size() << " positions." << endl;
-	  TEvePointSet* ps = new TEvePointSet(coll_name.c_str(),pv.size());
-	  for(int m=0; m < int(pv.size()); ++m)  {
-	    const Position& p = pv.at(m)->position;
-	    ps->SetPoint(m, p.X()/10, p.Y()/10, p.Z()/10);
-	  }
-	  ImportEvent(ps);
-	}
+  for(Types::const_iterator i=types.begin(); i!=types.end(); ++i)  {
+    const Collections& colls = (*i).second;
+    for(Collections::const_iterator j=colls.begin(); j!=colls.end(); ++j)   {
+      size_t len = (*j).second;
+      if ( len > 0 )   {
+	TEvePointSet* ps = new TEvePointSet((*j).first,len);
+	ps->SetMarkerSize(0.2);
+	PointsetCreator cr(ps);
+	handler->collectionLoop((*j).first, cr);
+	ImportEvent(ps);
       }
     }
   }
@@ -445,7 +455,8 @@ void Display::OnNewEvent(EventHandler* handler )   {
   for(Calodata::iterator i = m_calodata.begin(); i != m_calodata.end(); ++i)  {
     CalodataContext& ctx = (*i).second;
     TH2F* h = ctx.eveHist->GetHist(0);
-    long n = eventHandler().FillEtaPhiHistogram(ctx.config.hits,h);
+    EtaPhiHistogramActor actor(h);
+    size_t n = eventHandler().collectionLoop(ctx.config.hits, actor);
     ctx.eveHist->DataChanged();
     printout(INFO,"FillEtaPhiHistogram","+++ %s: Filled %ld hits from %s....",
 	     ctx.calo3D->GetName(), n, ctx.config.hits.c_str());
diff --git a/DDEve/src/EventControl.cpp b/DDEve/src/EventControl.cpp
index 3b00319bc..8f42b3bb0 100644
--- a/DDEve/src/EventControl.cpp
+++ b/DDEve/src/EventControl.cpp
@@ -102,13 +102,14 @@ void EventControl::OnFileOpen(EventHandler* handler)  {
 
 /// Consumer event data
 void EventControl::OnNewEvent(EventHandler* handler)   {
-  typedef EventHandler::Data Data;
-  typedef EventHandler::Collection Collection;
-  const Data& event = handler->data();
+  typedef EventHandler::TypedEventCollections Types;
+  typedef std::vector<EventHandler::Collection> Collections;
+  const Types& types = handler->data();
   size_t cnt = 1;
   m_lines[0].second.first->SetText("Hit collection name");
   m_lines[0].second.second->SetText("No.Hits");
-  for(Data::const_iterator i=event.begin(); i!=event.end() && cnt+1<m_lines.size(); ++i)  {
+  for(Types::const_iterator i=types.begin(); i!=types.end() && cnt+1<m_lines.size(); ++i)  {
+    const Collections& colls = (*i).second;
     Line line = m_lines[cnt++];
     string cl = (*i).first.substr((*i).first.find("Simple"));
     cl = cl.substr(0,cl.find('*'));
@@ -116,10 +117,9 @@ void EventControl::OnNewEvent(EventHandler* handler)   {
     line.second.second->SetTextColor(kRed);
     line.second.first->SetText(("Coll.Type: "+cl).c_str());
     line.second.second->SetText("");
-    for(std::vector<Collection>::const_iterator j=(*i).second.begin(); j!=(*i).second.end() && cnt+1<m_lines.size(); ++j)   {
+    for(Collections::const_iterator j=colls.begin(); j!=colls.end() && cnt+1<m_lines.size(); ++j)   {
       char text[132];
-      const vector<void*>* coll_data = (*j).second;
-      ::snprintf(text,sizeof(text),"%ld",long(coll_data->size()));
+      ::snprintf(text,sizeof(text),"%ld",long((*j).second));
       line = m_lines[cnt++];
       line.second.first->SetText((*j).first);
       line.second.second->SetText(text);
diff --git a/DDEve/src/EventHandler.cpp b/DDEve/src/EventHandler.cpp
index 3121df9f4..cc2da6495 100644
--- a/DDEve/src/EventHandler.cpp
+++ b/DDEve/src/EventHandler.cpp
@@ -9,63 +9,14 @@
 
 // Framework include files
 #include "DDEve/EventHandler.h"
-#include "DDEve/SimulationHit.h"
-#include "DD4hep/Printout.h"
-#include "DD4hep/Factories.h"
 
-// C/C++ include files
-#include <stdexcept>
-
-using namespace std;
 using namespace DD4hep;
-using DD4hep::DDEve::SimulationHit;
 
 ClassImp(EventHandler)
-
-
-namespace DD4hep {
-  template <typename T> vector<const T*> EventHandler::GetHits(const string& collection)  {
-    vector<T*> data;
-    return data;
-  }
-  template<> vector<const SimulationHit*> EventHandler::GetHits(const string& collection);
-}
-template <typename T> static void _delete(void* p)  { T* t = (T*)p; deletePtr(t); }
-
-template <typename T, typename Q> void fill_result(const T& src, Q& result)   {
-  result.reserve(src.size());
-  for(typename T::const_iterator i=src.begin(); i!=src.end(); ++i)
-    result.push_back(&(*i));
-}
-
-template<> vector<const SimulationHit*> EventHandler::GetHits(const string& collection)  {
-  typedef std::vector<const SimulationHit*> PTR_TYPE;
-  typedef std::vector<SimulationHit> TYPE;
-  PTR_TYPE result;
-  EventCollections::key_type key = make_pair(&typeid(TYPE),collection);
-  EventCollections::const_iterator ic = m_collections.find(key);
-  if ( ic != m_collections.end() )   {
-    const TYPE* source = (const TYPE*)((*ic).second.second);
-    fill_result<TYPE,PTR_TYPE>(*source, result);
-    return result;
-  }
-  const Data& event = data();
-  for(Data::const_iterator i=event.begin(); i!=event.end(); ++i)  {
-    for(std::vector<Collection>::const_iterator j=(*i).second.begin(); j!=(*i).second.end(); ++j)   {
-      if ( (*j).first == collection )  {
-	const std::vector<void*>* c = (*j).second;
-	TYPE* pv = (TYPE*)ROOT::Reflex::PluginService::Create<void*>("DDEve_DDG4CollectionAccess",(const char*)c);
-	m_collections[key] = make_pair(_delete<TYPE>,pv);
-	fill_result<TYPE,PTR_TYPE>(*pv, result);
-	return result;
-      }
-    }
-  }
-  return result;
-}
+ClassImp(EventConsumer)
 
 /// Standard constructor
-EventHandler::EventHandler() : m_hasEvent(false) {
+EventHandler::EventHandler() : m_hasFile(false), m_hasEvent(false) {
 }
 
 /// Default destructor
@@ -76,11 +27,6 @@ EventHandler::~EventHandler()   {
 
 /// Clear all event related data caches
 void EventHandler::ClearCache()     {
-  for(EventCollections::const_iterator ic = m_collections.begin(); ic != m_collections.end(); ++ic)   {
-    void (*fcn)(void*) = (*ic).second.first;
-    (*fcn)((*ic).second.second);
-  }
-  m_collections.clear();
 }
 
 /// Notfy all subscribers
@@ -100,9 +46,6 @@ void EventHandler::Unsubscribe(EventConsumer* consumer)  {
   if ( i != m_subscriptions.end() ) m_subscriptions.erase(i);
 }
 
-
-ClassImp(EventConsumer)
-
 /// Standard constructor
 EventConsumer::EventConsumer()  {
 }
-- 
GitLab