Skip to content
Snippets Groups Projects
Geant4HitCollection.cpp 4.79 KiB
Newer Older
Markus Frank's avatar
Markus Frank committed
// $Id: $
//==========================================================================
//  AIDA Detector description implementation for LCD
//--------------------------------------------------------------------------
Markus Frank's avatar
Markus Frank committed
// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
// For the licensing terms see $DD4hepINSTALL/LICENSE.
// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
// Author     : M.Frank
//
//==========================================================================

// Framework include files
#include "DD4hep/InstanceCount.h"
#include "DDG4/Geant4HitCollection.h"
#include "DDG4/Geant4Data.h"
#include "G4Allocator.hh"

using namespace DD4hep;
using namespace DD4hep::Simulation;

G4ThreadLocal G4Allocator<Geant4HitWrapper>* HitWrapperAllocator = 0;
Geant4HitWrapper::InvalidHit::~InvalidHit() {
/// Initializing Constructor
Geant4HitWrapper::HitManipulator::HitManipulator(const ComponentCast& c, const ComponentCast& v)
  InstanceCount::increment(this);
/// Default destructor
Geant4HitWrapper::HitManipulator::~HitManipulator() {
  InstanceCount::decrement(this);
}

/// Default destructor
Geant4HitWrapper::~Geant4HitWrapper() {
  if (m_data.first && m_data.second) {
    (*m_data.second->cast.destroy)(m_data.first);
    m_data.first = 0;
  }
}

/// Geant4 required object allocator
void* Geant4HitWrapper::operator new(size_t) {
  if ( HitWrapperAllocator )
    return HitWrapperAllocator->MallocSingle();
  HitWrapperAllocator = new G4Allocator<Geant4HitWrapper>;
  return HitWrapperAllocator->MallocSingle();
}

/// Geat4 required object destroyer
void Geant4HitWrapper::operator delete(void *p) {
  HitWrapperAllocator->FreeSingle((Geant4HitWrapper*) p);
}

/// Pointer/Object release
void* Geant4HitWrapper::release() {
  void* p = m_data.first;
  m_data.first = 0;
  m_data.second = manipulator<InvalidHit>();
  return p;
}

/// Pointer/Object release
Geant4HitWrapper::Wrapper Geant4HitWrapper::releaseData() {
  Wrapper w = m_data;
  m_data.first = 0;
  m_data.second = manipulator<InvalidHit>();
  return w;
}

Markus Frank's avatar
Markus Frank committed
/// Default destructor
Geant4HitCollection::Compare::~Compare()  {
}

/// Default destructor
Geant4HitCollection::~Geant4HitCollection() {
  m_hits.clear();
  InstanceCount::decrement(this);
}

/// Type information of the object stored
const ComponentCast& Geant4HitCollection::type() const {
  return m_manipulator->cast;
}

/// Type information of the vector type for extracting data
const ComponentCast& Geant4HitCollection::vector_type() const {
  return m_manipulator->vec_type;
}

/// Notification to increase the instance counter
void Geant4HitCollection::newInstance() {
  InstanceCount::increment(this);
}

Markus Frank's avatar
Markus Frank committed
/// Clear the collection (Deletes all valid references to real hits)
void Geant4HitCollection::clear()   {
  m_lastHit = ULONG_MAX;
Markus Frank's avatar
Markus Frank committed
  m_hits.clear();
}

/// Find hit in a collection by comparison of attributes
void* Geant4HitCollection::findHit(const Compare& cmp)  {
  void* p = 0;
  WrappedHits::const_iterator i = m_hits.begin();
  if ( m_flags.bits.repeatedLookup && m_lastHit < m_hits.size() )  {
    if ( (p = cmp(*(i+m_lastHit))) != 0 ) return p;
  }
  for (size_t cnt=0; i != m_hits.end(); ++i, ++cnt)   {
    if ((p = cmp(*i)) != 0)  {
      m_lastHit = cnt;
/// Release all hits from the Geant4 container and pass ownership to the caller
void Geant4HitCollection::releaseData(const ComponentCast& cast, std::vector<void*>* result) {
  for (size_t j = 0, n = m_hits.size(); j < n; ++j) {
    Geant4HitWrapper& w = m_hits.at(j);
    Manip* m = w.manip();
    if (&cast == &m->cast)
      result->push_back(w.release());
    else
      result->push_back(m->cast.apply_downCast(cast, w.release()));
  m_lastHit = ULONG_MAX;
}

/// Release all hits from the Geant4 container. Ownership stays with the container
void Geant4HitCollection::getData(const ComponentCast& cast, std::vector<void*>* result) {
  for (size_t j = 0, n = m_hits.size(); j < n; ++j) {
    Geant4HitWrapper& w = m_hits.at(j);
    Manip* m = w.manip();
    if (&cast == &m->cast)
      result->push_back(w.data());
    else
      result->push_back(m->cast.apply_downCast(cast, w.data()));
  }
}

/// Release all hits from the Geant4 container and pass ownership to the caller
void Geant4HitCollection::releaseHitsUnchecked(std::vector<void*>& result) {
  for (size_t j = 0, n = m_hits.size(); j < n; ++j) {
    Geant4HitWrapper& w = m_hits.at(j);
    result.push_back(w.release());
  }
  m_lastHit = ULONG_MAX;
}

/// Release all hits from the Geant4 container. Ownership stays with the container
void Geant4HitCollection::getHitsUnchecked(std::vector<void*>& result) {
  for (size_t j = 0, n = m_hits.size(); j < n; ++j) {
    Geant4HitWrapper& w = m_hits.at(j);
    result.push_back(w.data());
  }
  m_lastHit = ULONG_MAX;