Newer
Older
// $Id: Geant4Converter.cpp 603 2013-06-13 21:15:14Z markus.frank $
//====================================================================
// AIDA Detector description implementation for LCD
//--------------------------------------------------------------------
//
// Author : M.Frank
//
//====================================================================
// Framework include files
#define DDG4_MAKE_INSTANTIATIONS
#include "DD4hep/LCDD.h"
#include "DDG4/Geant4HitCollection.h"
#include "DDG4/Geant4DataConversion.h"
#include "DDG4/Geant4Data.h"
// LCIO includes
#include "IMPL/LCCollectionVec.h"
//
#include "IMPL/ClusterImpl.h"
#include "IMPL/SimTrackerHitImpl.h"
#include "IMPL/SimCalorimeterHitImpl.h"
#include "IMPL/MCParticleImpl.h"
//
#include "UTIL/Operators.h"
#include "UTIL/ILDConf.h"
using namespace std;
/*
* DD4hep namespace declaration
*/
namespace DD4hep {
/*
* Simulation namespace declaration
*/
namespace Simulation {
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 {
G4VHitsCollection* c = args.second;
Geant4HitCollection* coll = dynamic_cast<Geant4HitCollection*>(c);
if ( coll ) {
typedef pair<arg_t::first_type,Geant4HitCollection*> _A;
typedef Geant4Conversion<output_t,_A> _C;
const _C& cnv= _C::converter(coll->type().type);
return cnv(_A(args.first,coll));
}
throw unrelated_type_error(typeid(Geant4HitCollection),typeid(*c),
"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*>,
Markus Frank
committed
SimpleTracker::Hit>::operator()(const arg_t& args) const {
Geant4HitCollection* coll = args.second;
size_t nhits = coll->GetSize();
lcio::LCCollectionVec* lc_coll = new lcio::LCCollectionVec(lcio::LCIO::SIMTRACKERHIT);
lc_coll->reserve(nhits);
Markus Frank
committed
if ( nhits > 0 ) {
SimpleHit* hit = coll->hit(0);
string dsc = encoding(args.first, hit->cellID);
UTIL::CellIDEncoder<SimTrackerHit> decoder(dsc,lc_coll);
for(size_t i=0; i<nhits; ++i) {
const SimpleTracker::Hit* g4_hit = coll->hit(i);
double pos[3] = {g4_hit->position.x(), g4_hit->position.y(), g4_hit->position.z()};
lcio::SimTrackerHitImpl* lc_hit = new lcio::SimTrackerHitImpl;
lc_hit->setCellID0( (g4_hit->cellID >> 0 ) & 0xFFFFFFFF);
lc_hit->setCellID1( (g4_hit->cellID >> sizeof( int ) ) & 0xFFFFFFFF);
lc_hit->setPosition(pos);
lc_hit->setEDep(g4_hit->energyDeposit);
lc_hit->setTime(g4_hit->truth.time);
lc_hit->setMomentum( g4_hit->momentum.x(), g4_hit->momentum.y() , g4_hit->momentum.z() );
lc_hit->setPathLength( g4_hit->length);
lc_coll->addElement(lc_hit);
}
/// 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*>,
Markus Frank
committed
SimpleCalorimeter::Hit>::operator()(const arg_t& args) const {
Geant4HitCollection* coll = args.second;
size_t nhits = coll->GetSize();
lcio::LCCollectionVec* lc_coll = new lcio::LCCollectionVec(lcio::LCIO::SIMCALORIMETERHIT);
lc_coll->setFlag(UTIL::make_bitset32(LCIO::CHBIT_LONG,LCIO::CHBIT_STEP,LCIO::CHBIT_ID1));
Markus Frank
committed
if ( nhits > 0 ) {
SimpleHit* hit = coll->hit(0);
string dsc = encoding(args.first, hit->cellID);
UTIL::CellIDEncoder<SimCalorimeterHit> decoder(dsc,lc_coll);
for(size_t i=0; i<nhits; ++i) {
const SimpleCalorimeter::Hit* g4_hit = coll->hit(i);
float pos[3] = {g4_hit->position.x(), g4_hit->position.y(), g4_hit->position.z()};
lcio::SimCalorimeterHitImpl* lc_hit = new lcio::SimCalorimeterHitImpl;
lc_hit->setCellID0( ( g4_hit->cellID >> 0 ) & 0xFFFFFFFF );
lc_hit->setCellID1( ( g4_hit->cellID >> sizeof( int ) ) & 0xFFFFFFFF );
lc_hit->setPosition(pos);
lc_hit->setEnergy( g4_hit->energyDeposit );
lc_coll->addElement(lc_hit);
}
template <typename T> lcio::LCCollectionVec* moveEntries(Geant4HitCollection* coll, lcio::LCCollectionVec* lc_coll) {
size_t nhits = coll->GetSize();
lc_coll->reserve(nhits);
for(size_t i=0; i<nhits; ++i) {
Geant4HitWrapper& wrap = coll->hit(i);
T* lc_hit = wrap;
wrap.release(); // Now we have ownership!
lc_coll->addElement(lc_hit);
}
coll->clear(); // Since the collection now only contains NULL pointers, better clear it!
return lc_coll;
}
/// 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::SimTrackerHitImpl* hit = coll->hit(0);
long long int id1 = hit->getCellID1(), id0=hit->getCellID0();
long long int cellID = (((id1<<32)&0xFFFFFFFF00000000)|(id0&0xFFFFFFFF));
string dsc = encoding(args.first, cellID);
lcio::LCCollectionVec* lc_coll = new lcio::LCCollectionVec(lcio::LCIO::SIMTRACKERHIT);
UTIL::CellIDEncoder<SimTrackerHit> decoder(dsc,lc_coll);
return moveEntries<lcio::SimTrackerHitImpl>(args.second,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::SimCalorimeterHitImpl* hit = coll->hit(0);
output_t* lc = new lcio::LCCollectionVec(lcio::LCIO::SIMCALORIMETERHIT);
long long int id1 = hit->getCellID1(), id0=hit->getCellID0();
long long int cellID = (((id1<<32)&0xFFFFFFFF00000000)|(id0&0xFFFFFFFF));
string dsc = encoding(args.first, cellID);
UTIL::CellIDEncoder<SimCalorimeterHit> decoder(dsc,lc);
lc->setFlag(UTIL::make_bitset32(LCIO::CHBIT_LONG,LCIO::CHBIT_STEP,LCIO::CHBIT_ID1));
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
return moveEntries<tag_t>(args.second,lc);
}
/// Data conversion interface moving lcio::ClusterImpl objects from a Geant4HitCollection to a LCCollectionVec
/** Same comments apply as for the data mover for lcio::SimCalorimeterHitImpl and lcio::SimTrackerHitImpl
*
* @author M.Frank
* @version 1.0
*/
template <> lcio::LCCollectionVec*
Geant4DataConversion<lcio::LCCollectionVec,
pair<VolMgr,Geant4HitCollection*>,
lcio::ClusterImpl>::operator()(const arg_t& args) const
{
output_t* lc = new lcio::LCCollectionVec(lcio::LCIO::CLUSTER);
return moveEntries<tag_t>(args.second,lc);
}
/// Data conversion interface moving lcio::MCParticleImpl objects from a Geant4HitCollection to a LCCollectionVec
/** Same comments apply as for the data mover for lcio::SimCalorimeterHitImpl and lcio::SimTrackerHitImpl
*
* @author M.Frank
* @version 1.0
*/
template <> lcio::LCCollectionVec*
Geant4DataConversion<lcio::LCCollectionVec,
pair<VolMgr,Geant4HitCollection*>,
lcio::MCParticleImpl>::operator()(const arg_t& args) const
{
output_t* lc = new lcio::LCCollectionVec(lcio::LCIO::MCPARTICLE);
return moveEntries<tag_t>(args.second,lc);
typedef pair<VolMgr,G4VHitsCollection*> RAW_CONVERSION_ARGS;
typedef pair<VolMgr,Geant4HitCollection*> CONVERSION_ARGS;
template class Geant4Conversion<lcio::LCCollectionVec,RAW_CONVERSION_ARGS>;
DECLARE_GEANT4_HITCONVERTER(lcio::LCCollectionVec,RAW_CONVERSION_ARGS,Geant4HitCollection)
template class Geant4Conversion<lcio::LCCollectionVec,CONVERSION_ARGS>;
DECLARE_GEANT4_HITCONVERTER(lcio::LCCollectionVec,CONVERSION_ARGS,SimpleTracker::Hit)
DECLARE_GEANT4_HITCONVERTER(lcio::LCCollectionVec,CONVERSION_ARGS,SimpleCalorimeter::Hit)
DECLARE_GEANT4_HITCONVERTER(lcio::LCCollectionVec,CONVERSION_ARGS,lcio::SimTrackerHitImpl)
DECLARE_GEANT4_HITCONVERTER(lcio::LCCollectionVec,CONVERSION_ARGS,lcio::SimCalorimeterHitImpl)
DECLARE_GEANT4_HITCONVERTER(lcio::LCCollectionVec,CONVERSION_ARGS,lcio::ClusterImpl)
DECLARE_GEANT4_HITCONVERTER(lcio::LCCollectionVec,CONVERSION_ARGS,lcio::MCParticleImpl)
} // End namespace Simulation
} // End namespace DD4hep