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 VolumeManager vman = vman_glob.subdetector(sd.
id());
67 VolumeManagerContext* vc = vman.lookupContext(volID);
69 pos = segmentation.position(cell);
70 global = vc->localToWorld(
Position(pos)) / dd4hep::mm;
72 hit =
new Hit(global);
76 sd.
printM2(
"%s> CREATE hit with deposit:%e MeV Pos:%8.2f %8.2f %8.2f %s [%s]",
77 sd.
c_name(),contrib.deposit,pos.X,pos.Y,pos.Z,handler.path().c_str(),
78 coll.GetName().c_str());
79 if ( 0 == hit->cellID ) {
81 sd.
except(
"+++ Invalid CELL ID for hit!");
84 hit->truth.emplace_back(contrib);
85 hit->energyDeposit += contrib.deposit;
110 G4TouchableHistory* ) {
117 G4TouchableHistory* ) {
136 m_collectionID = declareReadoutFilteredCollection<Geant4Tracker::Hit>();
146 auto contrib = Hit::extractContribution(step);
148 double hit_deposit = h.
deposit();
149 Hit* hit =
new Hit(contrib, hit_momentum, hit_deposit);
151 hit->cellID = cellID(step);
152 if ( 0 == hit->cellID ) {
153 hit->cellID = volumeID(step);
154 except(
"+++ Invalid CELL ID for hit!");
156 collection(m_collectionID)->add(hit);
158 print(
"Hit with deposit:%f Pos:%f %f %f ID=%016X",
159 hit->energyDeposit,hit->position.X(),hit->position.Y(),hit->position.Z(),(
void*)hit->cellID);
161 print(
" Geant4 path:%s",handler.
path().c_str());
168 G4TouchableHistory* )
172 auto contrib = Hit::extractContribution(spot);
176 if ( 0 == hit->cellID ) {
178 except(
"+++ Invalid CELL ID for hit!");
180 collection(m_collectionID)->add(hit);
182 print(
"Hit with deposit:%f Pos:%f %f %f ID=%016X",
183 hit->energyDeposit,hit->position.X(),hit->position.Y(),hit->position.Z(),(
void*)hit->cellID);
185 print(
" Geant4 path:%s",handler.
path().c_str());
209 m_collectionID = declareReadoutFilteredCollection<Geant4Tracker::Hit>();
219 auto contrib = Hit::extractContribution(step);
221 double hit_deposit = contrib.deposit;
222 Hit* hit =
new Hit(contrib, hit_momentum, hit_deposit);
224 if (h.
trackDef() == G4OpticalPhoton::OpticalPhotonDefinition()) {
225 step->GetTrack()->SetTrackStatus(fStopAndKill);
227 hit->cellID = cellID(step);
228 if ( 0 == hit->cellID ) {
229 hit->cellID = volumeID( step ) ;
230 except(
"+++ Invalid CELL ID for hit!");
232 collection(m_collectionID)->add(hit);
234 print(
"Hit with deposit:%f Pos:%f %f %f ID=%016X",
235 hit->energyDeposit,hit->position.X(),hit->position.Y(),hit->position.Z(),(
void*)hit->cellID);
237 print(
" Geant4 path:%s",handler.
path().c_str());
244 G4TouchableHistory* )
248 auto contrib = Hit::extractContribution(spot);
249 Hit* hit =
new Hit(contrib, h.
momentum(), contrib.deposit);
252 if ( 0 == hit->cellID ) {
254 except(
"+++ Invalid CELL ID for hit!");
256 collection(m_collectionID)->add(hit);
258 print(
"Hit with deposit:%f Pos:%f %f %f ID=%016X",
259 hit->energyDeposit,hit->position.X(),hit->position.Y(),hit->position.Z(),(
void*)hit->cellID);
261 print(
" Geant4 path:%s",handler.
path().c_str());
281 m_collectionID = declareReadoutFilteredCollection<Geant4Calorimeter::Hit>();
289 HitContribution contrib = Hit::extractContribution(step);
295 }
catch(std::runtime_error &e) {
296 std::stringstream out;
297 out << std::setprecision(20) << std::scientific;
298 out <<
"ERROR: " << e.what() << std::endl;
300 <<
"Pre (" << std::setw(24) << step->GetPreStepPoint()->GetPosition() <<
") "
301 <<
"Post (" << std::setw(24) << step->GetPostStepPoint()->GetPosition() <<
") "
304 <<
" Pre (" <<std::setw(24) << step->GetPreStepPoint() ->GetMomentum() <<
") "
305 <<
" Post (" <<std::setw(24) << step->GetPostStepPoint()->GetMomentum() <<
") "
307 std::cout << out.str();
311 handleCalorimeterHit(cell, contrib, *coll, h, *
this, m_segmentation);
318 G4TouchableHistory* )
322 HitContribution contrib = Hit::extractContribution(spot);
328 }
catch(std::runtime_error &e) {
329 std::stringstream out;
330 out << std::setprecision(20) << std::scientific;
331 out <<
"ERROR: " << e.what() << std::endl;
332 out <<
"Position: (" << std::setw(24) << h.
avgPositionG4() <<
") " << std::endl;
333 out <<
"Momentum: (" << std::setw(24) << h.
momentumG4() <<
") " << std::endl;
334 std::cout << out.str();
337 handleCalorimeterHit(cell, contrib, *coll, h, *
this, m_segmentation);
365 m_collectionID = declareReadoutFilteredCollection<Geant4Calorimeter::Hit>();
370 G4Track * track = step->GetTrack();
372 if( track->GetDefinition() != G4OpticalPhoton::OpticalPhotonDefinition() ) {
375 else if ( track->GetCreatorProcess()->G4VProcess::GetProcessName() !=
"Cerenkov") {
376 track->SetTrackStatus(fStopAndKill);
383 HitContribution contrib = Hit::extractContribution(step);
388 hit->cellID = volumeID(step);
390 if ( 0 == hit->cellID ) {
391 hit->cellID = volumeID(step);
392 except(
"+++ Invalid CELL ID for hit!");
395 hit->energyDeposit += contrib.deposit;
396 hit->truth.emplace_back(contrib);
397 track->SetTrackStatus(fStopAndKill);
406 G4TouchableHistory* )
410 const G4Track* track = h.
track;
411 if( track->GetDefinition() != G4OpticalPhoton::OpticalPhotonDefinition() ) {
414 else if ( track->GetCreatorProcess()->G4VProcess::GetProcessName() !=
"Cerenkov") {
419 HitContribution contrib = Hit::extractContribution(spot);
426 if ( 0 == hit->cellID ) {
428 except(
"+++ Invalid CELL ID for hit!");
431 hit->energyDeposit += contrib.deposit;
432 hit->truth.emplace_back(contrib);
461 m_collectionID = declareReadoutFilteredCollection<Geant4Calorimeter::Hit>();
468 HitContribution contrib = Hit::extractContribution(step,
true);
473 }
catch(std::runtime_error &e) {
474 std::stringstream out;
475 out << std::setprecision(20) << std::scientific;
476 out <<
"ERROR: " << e.what() << std::endl;
478 <<
"Pre (" << std::setw(24) << step->GetPreStepPoint()->GetPosition() <<
") "
479 <<
"Post (" << std::setw(24) << step->GetPostStepPoint()->GetPosition() <<
") "
482 <<
" Pre (" <<std::setw(24) << step->GetPreStepPoint() ->GetMomentum() <<
") "
483 <<
" Post (" <<std::setw(24) << step->GetPostStepPoint()->GetMomentum() <<
") "
485 std::cout << out.str();
488 handleCalorimeterHit(cell, contrib, *coll, h, *
this, m_segmentation);
496 G4TouchableHistory* )
500 HitContribution contrib = Hit::extractContribution(spot);
506 }
catch(std::runtime_error &e) {
507 std::stringstream out;
508 out << std::setprecision(20) << std::scientific;
509 out <<
"ERROR: " << e.what() << std::endl;
510 out <<
"Position: (" << std::setw(24) << h.
avgPositionG4() <<
") " << std::endl;
511 out <<
"Momentum: (" << std::setw(24) << h.
momentumG4() <<
") " << std::endl;
512 std::cout << out.str();
515 handleCalorimeterHit(cell, contrib, *coll, h, *
this, m_segmentation);
569 void start(
const G4Step* step,
const G4StepPoint* point) {
572 firstSpotVolume = step->GetPreStepPoint()->GetTouchableHandle()->GetVolume();
633 depo, time, path_len, pos, mom);
635 collection->
add(hit);
636 sensitive->
printM2(
"+++ TrackID:%6d [%s] CREATE hit combination with %2d deposit(s):"
637 " %e MeV Pos:%8.2f %8.2f %8.2f",
639 pos.X()/CLHEP::mm,pos.Y()/CLHEP::mm,pos.Z()/CLHEP::mm);
645 G4bool
process(
const G4Step* step, G4TouchableHistory* ) {
663 if ( prePV != postPV ) {
664 void* postSD = h.
sd(h.
post);
667 void* preSD = h.
sd(h.
pre);
668 if ( preSD == postSD ) {
673 else if ( h.
track->GetTrackStatus() == fStopAndKill ) {
696 void* postSD = h.
sd();
699 void* preSD = prePV ? prePV->GetLogicalVolume()->GetSensitiveDetector() :
nullptr;
700 if ( preSD == postSD ) {
705 else if ( h.
track->GetTrackStatus() == fStopAndKill ) {
729 m_userData.e_cut = m_sensitive.energyCutoff();
730 m_userData.sensitive =
this;
735 m_collectionID = declareReadoutFilteredCollection<Geant4Tracker::Hit>();
746 return m_userData.process(step, history);
752 G4TouchableHistory* history) {
753 return m_userData.process(spot, history);