15 #include <DDG4/Geant4SensDetAction.inl>
18 #include <G4OpticalPhoton.hh>
19 #include <G4VProcess.hh>
29 struct Geant4VoidSensitive {};
32 template <
class HANDLER>
33 void handleCalorimeterHit (
VolumeID cell,
34 const HitContribution& contrib,
38 const Segmentation& segmentation)
43 DDSegmentation::Vector3D pos;
47 pos = h.avgPosition();
48 global = h.localToGlobal(pos);
50 else if( !segmentation.cellsSpanVolumes() ) {
53 pos = segmentation.position(cell);
54 global = h.localToGlobal(pos);
64 VolumeID volID = segmentation.volumeID(cell);
66 VolumeManagerContext* vc = vman.lookupContext(volID);
68 pos = segmentation.position(cell);
69 global = vc->localToWorld(
Position(pos)) / dd4hep::mm;
71 hit =
new Hit(global);
75 sd.
printM2(
"%s> CREATE hit with deposit:%e MeV Pos:%8.2f %8.2f %8.2f %s [%s]",
76 sd.
c_name(),contrib.deposit,pos.X,pos.Y,pos.Z,handler.path().c_str(),
77 coll.GetName().c_str());
78 if ( 0 == hit->cellID ) {
80 sd.
except(
"+++ Invalid CELL ID for hit!");
83 hit->truth.emplace_back(contrib);
84 hit->energyDeposit += contrib.deposit;
109 G4TouchableHistory* ) {
116 G4TouchableHistory* ) {
135 m_collectionID = declareReadoutFilteredCollection<Geant4Tracker::Hit>();
145 auto contrib = Hit::extractContribution(step);
147 double hit_deposit = h.
deposit();
148 Hit* hit =
new Hit(contrib, hit_momentum, hit_deposit);
150 hit->cellID = cellID(step);
151 if ( 0 == hit->cellID ) {
152 hit->cellID = volumeID(step);
153 except(
"+++ Invalid CELL ID for hit!");
155 collection(m_collectionID)->add(hit);
157 print(
"Hit with deposit:%f Pos:%f %f %f ID=%016X",
158 hit->energyDeposit,hit->position.X(),hit->position.Y(),hit->position.Z(),(
void*)hit->cellID);
160 print(
" Geant4 path:%s",handler.
path().c_str());
167 G4TouchableHistory* )
171 auto contrib = Hit::extractContribution(spot);
175 if ( 0 == hit->cellID ) {
177 except(
"+++ Invalid CELL ID for hit!");
179 collection(m_collectionID)->add(hit);
181 print(
"Hit with deposit:%f Pos:%f %f %f ID=%016X",
182 hit->energyDeposit,hit->position.X(),hit->position.Y(),hit->position.Z(),(
void*)hit->cellID);
184 print(
" Geant4 path:%s",handler.
path().c_str());
208 m_collectionID = declareReadoutFilteredCollection<Geant4Tracker::Hit>();
218 auto contrib = Hit::extractContribution(step);
220 double hit_deposit = contrib.deposit;
221 Hit* hit =
new Hit(contrib, hit_momentum, hit_deposit);
223 if (h.
trackDef() == G4OpticalPhoton::OpticalPhotonDefinition()) {
224 step->GetTrack()->SetTrackStatus(fStopAndKill);
226 hit->cellID = cellID(step);
227 if ( 0 == hit->cellID ) {
228 hit->cellID = volumeID( step ) ;
229 except(
"+++ Invalid CELL ID for hit!");
231 collection(m_collectionID)->add(hit);
233 print(
"Hit with deposit:%f Pos:%f %f %f ID=%016X",
234 hit->energyDeposit,hit->position.X(),hit->position.Y(),hit->position.Z(),(
void*)hit->cellID);
236 print(
" Geant4 path:%s",handler.
path().c_str());
243 G4TouchableHistory* )
247 auto contrib = Hit::extractContribution(spot);
248 Hit* hit =
new Hit(contrib, h.
momentum(), contrib.deposit);
251 if ( 0 == hit->cellID ) {
253 except(
"+++ Invalid CELL ID for hit!");
255 collection(m_collectionID)->add(hit);
257 print(
"Hit with deposit:%f Pos:%f %f %f ID=%016X",
258 hit->energyDeposit,hit->position.X(),hit->position.Y(),hit->position.Z(),(
void*)hit->cellID);
260 print(
" Geant4 path:%s",handler.
path().c_str());
280 m_collectionID = declareReadoutFilteredCollection<Geant4Calorimeter::Hit>();
288 HitContribution contrib = Hit::extractContribution(step);
294 }
catch(std::runtime_error &e) {
295 std::stringstream out;
296 out << std::setprecision(20) << std::scientific;
297 out <<
"ERROR: " << e.what() << std::endl;
299 <<
"Pre (" << std::setw(24) << step->GetPreStepPoint()->GetPosition() <<
") "
300 <<
"Post (" << std::setw(24) << step->GetPostStepPoint()->GetPosition() <<
") "
303 <<
" Pre (" <<std::setw(24) << step->GetPreStepPoint() ->GetMomentum() <<
") "
304 <<
" Post (" <<std::setw(24) << step->GetPostStepPoint()->GetMomentum() <<
") "
306 std::cout << out.str();
310 handleCalorimeterHit(cell, contrib, *coll, h, *
this, m_segmentation);
317 G4TouchableHistory* )
321 HitContribution contrib = Hit::extractContribution(spot);
327 }
catch(std::runtime_error &e) {
328 std::stringstream out;
329 out << std::setprecision(20) << std::scientific;
330 out <<
"ERROR: " << e.what() << std::endl;
331 out <<
"Position: (" << std::setw(24) << h.
avgPositionG4() <<
") " << std::endl;
332 out <<
"Momentum: (" << std::setw(24) << h.
momentumG4() <<
") " << std::endl;
333 std::cout << out.str();
336 handleCalorimeterHit(cell, contrib, *coll, h, *
this, m_segmentation);
364 m_collectionID = declareReadoutFilteredCollection<Geant4Calorimeter::Hit>();
369 G4Track * track = step->GetTrack();
371 if( track->GetDefinition() != G4OpticalPhoton::OpticalPhotonDefinition() ) {
374 else if ( track->GetCreatorProcess()->G4VProcess::GetProcessName() !=
"Cerenkov") {
375 track->SetTrackStatus(fStopAndKill);
382 HitContribution contrib = Hit::extractContribution(step);
387 hit->cellID = volumeID(step);
389 if ( 0 == hit->cellID ) {
390 hit->cellID = volumeID(step);
391 except(
"+++ Invalid CELL ID for hit!");
394 hit->energyDeposit += contrib.deposit;
395 hit->truth.emplace_back(contrib);
396 track->SetTrackStatus(fStopAndKill);
405 G4TouchableHistory* )
409 const G4Track* track = h.
track;
410 if( track->GetDefinition() != G4OpticalPhoton::OpticalPhotonDefinition() ) {
413 else if ( track->GetCreatorProcess()->G4VProcess::GetProcessName() !=
"Cerenkov") {
418 HitContribution contrib = Hit::extractContribution(spot);
425 if ( 0 == hit->cellID ) {
427 except(
"+++ Invalid CELL ID for hit!");
430 hit->energyDeposit += contrib.deposit;
431 hit->truth.emplace_back(contrib);
460 m_collectionID = declareReadoutFilteredCollection<Geant4Calorimeter::Hit>();
467 HitContribution contrib = Hit::extractContribution(step,
true);
472 }
catch(std::runtime_error &e) {
473 std::stringstream out;
474 out << std::setprecision(20) << std::scientific;
475 out <<
"ERROR: " << e.what() << std::endl;
477 <<
"Pre (" << std::setw(24) << step->GetPreStepPoint()->GetPosition() <<
") "
478 <<
"Post (" << std::setw(24) << step->GetPostStepPoint()->GetPosition() <<
") "
481 <<
" Pre (" <<std::setw(24) << step->GetPreStepPoint() ->GetMomentum() <<
") "
482 <<
" Post (" <<std::setw(24) << step->GetPostStepPoint()->GetMomentum() <<
") "
484 std::cout << out.str();
487 handleCalorimeterHit(cell, contrib, *coll, h, *
this, m_segmentation);
495 G4TouchableHistory* )
499 HitContribution contrib = Hit::extractContribution(spot);
505 }
catch(std::runtime_error &e) {
506 std::stringstream out;
507 out << std::setprecision(20) << std::scientific;
508 out <<
"ERROR: " << e.what() << std::endl;
509 out <<
"Position: (" << std::setw(24) << h.
avgPositionG4() <<
") " << std::endl;
510 out <<
"Momentum: (" << std::setw(24) << h.
momentumG4() <<
") " << std::endl;
511 std::cout << out.str();
514 handleCalorimeterHit(cell, contrib, *coll, h, *
this, m_segmentation);
568 void start(
const G4Step* step,
const G4StepPoint* point) {
571 firstSpotVolume = step->GetPreStepPoint()->GetTouchableHandle()->GetVolume();
632 depo, time, path_len, pos, mom);
634 collection->
add(hit);
635 sensitive->
printM2(
"+++ TrackID:%6d [%s] CREATE hit combination with %2d deposit(s):"
636 " %e MeV Pos:%8.2f %8.2f %8.2f",
638 pos.X()/CLHEP::mm,pos.Y()/CLHEP::mm,pos.Z()/CLHEP::mm);
644 G4bool
process(
const G4Step* step, G4TouchableHistory* ) {
662 if ( prePV != postPV ) {
663 void* postSD = h.
sd(h.
post);
666 void* preSD = h.
sd(h.
pre);
667 if ( preSD == postSD ) {
672 else if ( h.
track->GetTrackStatus() == fStopAndKill ) {
695 void* postSD = h.
sd();
698 void* preSD = prePV ? prePV->GetLogicalVolume()->GetSensitiveDetector() :
nullptr;
699 if ( preSD == postSD ) {
704 else if ( h.
track->GetTrackStatus() == fStopAndKill ) {
728 m_userData.e_cut = m_sensitive.energyCutoff();
729 m_userData.sensitive =
this;
734 m_collectionID = declareReadoutFilteredCollection<Geant4Tracker::Hit>();
745 return m_userData.process(step, history);
751 G4TouchableHistory* history) {
752 return m_userData.process(spot, history);