DD4hep  1.28.0
Detector Description Toolkit for High Energy Physics
LCIOConversions.cpp
Go to the documentation of this file.
1 //==========================================================================
2 // AIDA Detector description implementation
3 //--------------------------------------------------------------------------
4 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
5 // All rights reserved.
6 //
7 // For the licensing terms see $DD4hepINSTALL/LICENSE.
8 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
9 //
10 // Author : M.Frank
11 //
12 //==========================================================================
13 
14 // Framework include files
15 #define DDG4_MAKE_INSTANTIATIONS
17 #include "DD4hep/Printout.h"
21 #include "DDG4/Geant4Context.h"
22 #include "DDG4/Geant4Primary.h"
23 #include "DDG4/Geant4Data.h"
24 
25 // LCIO includes
26 #include "lcio.h"
27 #include "IMPL/LCCollectionVec.h"
28 //
29 #include "IMPL/LCEventImpl.h"
30 #include "IMPL/ClusterImpl.h"
31 #include "IMPL/SimTrackerHitImpl.h"
32 #include "IMPL/SimCalorimeterHitImpl.h"
33 #include "IMPL/MCParticleImpl.h"
34 //
35 #include "UTIL/Operators.h"
36 #include "UTIL/ILDConf.h"
37 
38 #include "CLHEP/Units/SystemOfUnits.h"
39 
40 using namespace std;
41 using namespace lcio ;
42 //==================================================================================
43 //
44 // SimCalorimeterHit:
45 // ------------------
46 // LCIO::CHBIT_STEP If detailed mode set | YES if detailed
47 // LCIO::CHBIT_LONG: Position is stored | YES
48 // LCIO::CHBIT_ID1: CellID1 is stored | YES
49 //
50 //
51 // SimTrackerHit:
52 // --------------
53 // LCIO::THBIT_ID1: CellID1 is stored (TrackerHit) | YES
54 // LCIO::THBIT_MOMENTUM: Momentum is stored | YES if detailed
55 //
56 //==================================================================================
57 
58 /*
59  * dd4hep namespace declaration
60  */
61 namespace dd4hep {
62 
63  /*
64  * Simulation namespace declaration
65  */
66  namespace sim {
67 
70 
72 
76  template <> lcio::LCCollectionVec*
77  Geant4DataConversion<lcio::LCCollectionVec,
78  pair<const Geant4Context*,G4VHitsCollection*>,
79  Geant4HitCollection>::operator()(const arg_t& args) const {
80  G4VHitsCollection* c = args.second;
81  Geant4HitCollection* coll = dynamic_cast<Geant4HitCollection*>(c);
82  if ( coll ) {
83  typedef pair<arg_t::first_type,Geant4HitCollection*> _A;
85  const _C& cnv= _C::converter(coll->type().type());
86  return cnv(_A(args.first,coll));
87  }
88  throw unrelated_type_error(typeid(Geant4HitCollection),typeid(*c),
89  "Cannot save the collection entries of:"+c->GetName());
90  }
91 
93 
102  template <> lcio::LCCollectionVec*
103  Geant4DataConversion<lcio::LCCollectionVec,
104  pair<const Geant4Context*,Geant4HitCollection*>,
105  Geant4Tracker::Hit>::operator()(const arg_t& args) const {
106 
107  Geant4HitCollection* coll = args.second;
108  string hc_nam = coll->GetName();
109  Geant4Sensitive* sd = coll->sensitive();
110  size_t nhits = coll->GetSize();
111  string dsc = encoding(sd->sensitiveDetector());
112  Geant4ParticleMap* pm = args.first->event().extension<Geant4ParticleMap>();
113  lcio::LCEventImpl* lc_evt = args.first->event().extension<lcio::LCEventImpl>();
114  EVENT::LCCollection* lc_part = lc_evt->getCollection(lcio::LCIO::MCPARTICLE);
115  lcio::LCCollectionVec* lc_coll = nullptr;
116  bool isNewCollection = false;
117  try {
118  lc_coll = static_cast<lcio::LCCollectionVec*>(lc_evt->getCollection(hc_nam));
119  } catch (lcio::DataNotAvailableException &e) {
120  lc_coll = new lcio::LCCollectionVec(lcio::LCIO::SIMTRACKERHIT);
121  isNewCollection = true;
122  }
123  UTIL::CellIDEncoder<SimTrackerHit> decoder(dsc,lc_coll);
124  int hit_creation_mode = sd->hitCreationMode();
125 
126  if ( hit_creation_mode == Geant4Sensitive::DETAILED_MODE )
127  lc_coll->setFlag(UTIL::make_bitset32(LCIO::THBIT_MOMENTUM,LCIO::THBIT_ID1));
128  else
129  lc_coll->setFlag(LCIO::THBIT_ID1);
130 
131  lc_coll->reserve(nhits + lc_coll->getNumberOfElements());
132  for(size_t i=0; i<nhits; ++i) {
133  const Geant4Tracker::Hit* hit = coll->hit(i);
134  const Geant4Tracker::Hit::Contribution& t = hit->truth;
135  int trackID = pm->particleID(t.trackID);
136  EVENT::MCParticle* lc_mcp = (EVENT::MCParticle*)lc_part->getElementAt(trackID);
137  double pos[3] = {hit->position.x()/CLHEP::mm, hit->position.y()/CLHEP::mm, hit->position.z()/CLHEP::mm};
138  lcio::SimTrackerHitImpl* lc_hit = new lcio::SimTrackerHitImpl;
139  lc_hit->setCellID0((hit->cellID >> 0 ) & 0xFFFFFFFF);
140  lc_hit->setCellID1((hit->cellID >> sizeof(int)*8) & 0xFFFFFFFF);
141  lc_hit->setEDep(hit->energyDeposit/CLHEP::GeV);
142  lc_hit->setPathLength(hit->length/CLHEP::mm);
143  lc_hit->setTime(hit->truth.time/CLHEP::ns);
144  lc_hit->setMCParticle(lc_mcp);
145  lc_hit->setPosition(pos);
146  lc_hit->setMomentum(hit->momentum.x()/CLHEP::GeV,hit->momentum.y()/CLHEP::GeV,hit->momentum.z()/CLHEP::GeV);
147 
148 #if LCIO_VERSION_GE( 2, 8 )
149  auto particleIt = pm->particles().find(trackID);
150  if( ( particleIt != pm->particles().end()) ){
151  // if the original track ID of the particle is not the same as the
152  // original track ID of the hit it was produced by an MCParticle that
153  // is no longer stored
154  lc_hit->setProducedBySecondary( (particleIt->second->originalG4ID != t.trackID) );
155  }
156 #endif
157  lc_coll->addElement(lc_hit);
158  }
159 
160  if(isNewCollection) {
161  lc_evt->addCollection(lc_coll, hc_nam);
162  }
163  return lc_coll;
164  }
165 
167 
176  template <> lcio::LCCollectionVec*
177  Geant4DataConversion<lcio::LCCollectionVec,
178  pair<const Geant4Context*,Geant4HitCollection*>,
179  Geant4Calorimeter::Hit>::operator()(const arg_t& args) const {
180  typedef Geant4HitData::Contributions Contributions;
181  Geant4HitCollection* coll = args.second;
182  string hc_nam = coll->GetName();
183  Geant4Sensitive* sd = coll->sensitive();
184  size_t nhits = coll->GetSize();
185  string dsc = encoding(sd->sensitiveDetector());
186  Geant4ParticleMap* pm = args.first->event().extension<Geant4ParticleMap>();
187  lcio::LCEventImpl* lc_evt = args.first->event().extension<lcio::LCEventImpl>();
188  EVENT::LCCollection* lc_parts = lc_evt->getCollection(lcio::LCIO::MCPARTICLE);
189  lcio::LCCollectionVec* lc_coll = nullptr;
190  bool isNewCollection = false;
191  try {
192  lc_coll = static_cast<lcio::LCCollectionVec*>(lc_evt->getCollection(hc_nam));
193  } catch (lcio::DataNotAvailableException &e) {
194  lc_coll = new lcio::LCCollectionVec(lcio::LCIO::SIMCALORIMETERHIT);
195  isNewCollection = true;
196  }
197  UTIL::CellIDEncoder<SimCalorimeterHit> decoder(dsc,lc_coll);
198  int hit_creation_mode = sd->hitCreationMode();
199 
200  if ( hit_creation_mode == Geant4Sensitive::DETAILED_MODE )
201  lc_coll->setFlag(UTIL::make_bitset32(LCIO::CHBIT_LONG,LCIO::CHBIT_STEP,LCIO::CHBIT_ID1));
202  else
203  lc_coll->setFlag(UTIL::make_bitset32(LCIO::CHBIT_LONG,LCIO::CHBIT_ID1));
204 
205  lc_coll->reserve(nhits + lc_coll->getNumberOfElements());
206  if ( sd->hasProperty("HitCreationMode") ) {
207  hit_creation_mode = sd->property("HitCreationMode").value<int>();
208  }
209  for(size_t i=0; i<nhits; ++i) {
210  const Geant4Calorimeter::Hit* hit = coll->hit(i);
211  float pos[3] = {float(hit->position.x()/CLHEP::mm), float(hit->position.y()/CLHEP::mm), float(hit->position.z()/CLHEP::mm)};
212  lcio::SimCalorimeterHitImpl* lc_hit = new lcio::SimCalorimeterHitImpl;
213  lc_hit->setCellID0((hit->cellID >> 0 ) & 0xFFFFFFFF);
214  lc_hit->setCellID1((hit->cellID >> sizeof(int)*8) & 0xFFFFFFFF); // ????
215  lc_hit->setPosition(pos);
217  lc_coll->addElement(lc_hit);
219  for(Contributions::const_iterator j=hit->truth.begin(); j!=hit->truth.end(); ++j) {
220  const Geant4HitData::Contribution& c = *j;
221  int trackID = pm->particleID(c.trackID);
222  EVENT::MCParticle* lc_mcp = (EVENT::MCParticle*)lc_parts->getElementAt(trackID);
223  if ( hit_creation_mode == Geant4Sensitive::DETAILED_MODE ) {
224  float contrib_pos[] = {float(c.x/CLHEP::mm), float(c.y/CLHEP::mm), float(c.z/CLHEP::mm)};
225 #if LCIO_VERSION_GE( 2, 11 )
226  lc_hit->addMCParticleContribution(lc_mcp, c.deposit/CLHEP::GeV, c.time/CLHEP::ns, c.length/CLHEP::mm, c.pdgID, contrib_pos);
227 #else
228  lc_hit->addMCParticleContribution(lc_mcp, c.deposit/CLHEP::GeV, c.time/CLHEP::ns, c.pdgID, contrib_pos);
229 #endif
230  }
231  else {
232  lc_hit->addMCParticleContribution(lc_mcp, c.deposit/CLHEP::GeV, c.time/CLHEP::ns);
233  }
234  }
235  }
236  if(isNewCollection) {
237  lc_evt->addCollection(lc_coll, hc_nam);
238  }
239  return lc_coll;
240  }
241 
242  template <typename T>
243  lcio::LCCollectionVec* moveEntries(Geant4HitCollection* coll,
244  lcio::LCCollectionVec* lc_coll)
245  {
246  size_t nhits = coll->GetSize();
247  lc_coll->reserve(nhits);
248  for(size_t i=0; i<nhits; ++i) {
249  Geant4HitWrapper& wrap = coll->hit(i);
250  T* lc_hit = wrap;
251  wrap.release(); // Now we have ownership!
252  lc_coll->addElement(lc_hit);
253  }
254  coll->clear(); // Since the collection now only contains NULL pointers, better clear it!
255  return lc_coll;
256  }
257 
259 
271  template <> lcio::LCCollectionVec*
272  Geant4DataConversion<lcio::LCCollectionVec,
273  pair<const Geant4Context*,Geant4HitCollection*>,
274  lcio::SimTrackerHitImpl>::operator()(const arg_t& args) const
275  {
276  Geant4Sensitive* sd = args.second->sensitive();
277  string dsc = encoding(sd->sensitiveDetector());
278  output_t* lc = new lcio::LCCollectionVec(lcio::LCIO::SIMTRACKERHIT);
279  int hit_creation_mode = sd->hitCreationMode();
280 
281  if ( hit_creation_mode == Geant4Sensitive::DETAILED_MODE )
282  lc->setFlag(UTIL::make_bitset32(LCIO::CHBIT_LONG,LCIO::CHBIT_STEP,LCIO::CHBIT_ID1));
283  else
284  lc->setFlag(UTIL::make_bitset32(LCIO::CHBIT_LONG,LCIO::CHBIT_ID1));
285  UTIL::CellIDEncoder<SimTrackerHit> decoder(dsc,lc);
286  return moveEntries<lcio::SimTrackerHitImpl>(args.second,lc);
287  }
288 
290 
302  template <> lcio::LCCollectionVec*
303  Geant4DataConversion<lcio::LCCollectionVec,
304  pair<const Geant4Context*,Geant4HitCollection*>,
305  lcio::SimCalorimeterHitImpl>::operator()(const arg_t& args) const
306  {
307  Geant4Sensitive* sd = args.second->sensitive();
308  //string dsc = encoding(args.second->sensitive()->sensitiveDetector());
309  output_t* lc = new lcio::LCCollectionVec(lcio::LCIO::SIMCALORIMETERHIT);
310  int hit_creation_mode = sd->hitCreationMode();
311 
312  if ( hit_creation_mode == Geant4Sensitive::DETAILED_MODE )
313  lc->setFlag(UTIL::make_bitset32(LCIO::CHBIT_LONG,LCIO::CHBIT_STEP,LCIO::CHBIT_ID1));
314  else
315  lc->setFlag(UTIL::make_bitset32(LCIO::CHBIT_LONG,LCIO::CHBIT_ID1));
316  return moveEntries<tag_t>(args.second,lc);
317  }
318 
320 
325  template <> lcio::LCCollectionVec*
326  Geant4DataConversion<lcio::LCCollectionVec,
327  pair<const Geant4Context*,Geant4HitCollection*>,
328  lcio::ClusterImpl>::operator()(const arg_t& args) const
329  {
330  output_t* lc = new lcio::LCCollectionVec(lcio::LCIO::CLUSTER);
331  return moveEntries<tag_t>(args.second,lc);
332  }
333 
334  typedef pair<const Geant4Context*,G4VHitsCollection*> RAW_CONVERSION_ARGS;
335  typedef pair<const Geant4Context*,Geant4HitCollection*> CONVERSION_ARGS;
337  DECLARE_GEANT4_HITCONVERTER(lcio::LCCollectionVec,RAW_CONVERSION_ARGS,Geant4HitCollection)
338 
340  // Hit converters for simple Geant4Data objects
341  DECLARE_GEANT4_HITCONVERTER(lcio::LCCollectionVec,CONVERSION_ARGS,Geant4Tracker::Hit)
342  DECLARE_GEANT4_HITCONVERTER(lcio::LCCollectionVec,CONVERSION_ARGS,Geant4Calorimeter::Hit)
343  // Hit converters for standard LCIO objects
344  DECLARE_GEANT4_HITCONVERTER(lcio::LCCollectionVec,CONVERSION_ARGS,lcio::SimTrackerHitImpl)
345  DECLARE_GEANT4_HITCONVERTER(lcio::LCCollectionVec,CONVERSION_ARGS,lcio::SimCalorimeterHitImpl)
346  DECLARE_GEANT4_HITCONVERTER(lcio::LCCollectionVec,CONVERSION_ARGS,lcio::ClusterImpl)
347  } // End namespace sim
348 } // End namespace dd4hep
349 
350 
351 
Geant4DataConversion.h
dd4hep::sim::moveEntries
lcio::LCCollectionVec * moveEntries(Geant4HitCollection *coll, lcio::LCCollectionVec *lc_coll)
Definition: LCIOConversions.cpp:243
Geant4HitCollection.h
dd4hep::sim::Geant4Conversion
Data conversion class.
Definition: Geant4DataConversion.h:54
dd4hep::sim::Geant4HitCollection::clear
virtual void clear()
Clear the collection (Deletes all valid references to real hits)
Definition: Geant4HitCollection.cpp:102
Detector.h
_C
DetElement::Children _C
Definition: GeometryWalk.cpp:64
dd4hep::sim::Geant4HitWrapper::release
void * release()
Pointer/Object release.
Definition: Geant4HitCollection.cpp:60
dd4hep::sim::Geant4ParticleMap::particles
const ParticleMap & particles() const
Access the particle map.
Definition: Geant4Particle.h:361
Geant4SensDetAction.h
dd4hep::sim::Geant4HitCollection
Generic hit container class using Geant4HitWrapper objects.
Definition: Geant4HitCollection.h:201
dd4hep::sim::VolMgr
VolumeManager VolMgr
Definition: LCIOConversions.cpp:68
dd4hep::sim::Geant4HitCollection::hit
Geant4HitWrapper & hit(size_t which)
Access the hit wrapper.
Definition: Geant4HitCollection.h:325
G4VHitsCollection
Class of the Geant4 toolkit. See http://www-geant4.kek.jp/Reference.
Definition: Geant4Classes.h:47
Geant4Data.h
dd4hep::sim::Geant4ParticleMap
Data structure to map particles produced during the generation and the simulation.
Definition: Geant4Particle.h:337
dd4hep::sim::Geant4HitWrapper
Generic wrapper class for hit structures created in Geant4 sensitive detectors.
Definition: Geant4HitCollection.h:50
dd4hep::sim::Geant4HitCollection::sensitive
Geant4Sensitive * sensitive() const
Access the sensitive detector.
Definition: Geant4HitCollection.h:313
dd4hep::VolumeManager
Class to support the retrieval of detector elements and volumes given a valid identifier.
Definition: VolumeManager.h:135
dd4hep::sim::Geant4Tracker::Hit
DDG4 tracker hit class used by the generic DDG4 tracker sensitive detector.
Definition: Geant4Data.h:263
dd4hep::sim::CONVERSION_ARGS
pair< const Geant4Context *, Geant4HitCollection * > CONVERSION_ARGS
Definition: LCIOConversions.cpp:335
dd4hep::sim::Geant4Sensitive::sensitiveDetector
SensitiveDetector sensitiveDetector() const
Access the dd4hep sensitive detector.
Definition: Geant4SensDetAction.h:198
dd4hep::sim::Geant4Calorimeter::Hit
DDG4 calorimeter hit class used by the generic DDG4 calorimeter sensitive detector.
Definition: Geant4Data.h:323
dd4hep::sim::IDDescriptor
IDDescriptor IDDescriptor
Definition: LCIOConversions.cpp:69
dd4hep::sim::Geant4HitCollection::type
const ComponentCast & type() const
Type information of the object stored.
Definition: Geant4HitCollection.cpp:87
dd4hep::sim::Geant4ParticleMap::particleID
int particleID(int track, bool throw_if_not_found=true) const
Access the equivalent track id (shortcut to the usage of TrackEquivalents)
Definition: Geant4Particle.cpp:541
std
Definition: Plugins.h:30
dd4hep::sim::Geant4Sensitive::hitCreationMode
int hitCreationMode() const
Property access to the hit creation mode.
Definition: Geant4SensDetAction.h:173
Geant4Primary.h
dd4hep
Namespace for the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:28
dd4hep::sim::Geant4Sensitive
The base class for Geant4 sensitive detector actions implemented by users.
Definition: Geant4SensDetAction.h:121
Printout.h
Geant4Context.h
dd4hep::sim::Geant4HitCollection::GetSize
virtual size_t GetSize() const
Access the collection size.
Definition: Geant4HitCollection.h:321
dd4hep::sim::RAW_CONVERSION_ARGS
pair< const Geant4Context *, G4VHitsCollection * > RAW_CONVERSION_ARGS
Definition: LCIOConversions.cpp:334