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 = segmentation.position(cell);
48 if (!segmentation.cellsSpanVolumes()) {
49 global = h.localToGlobal(pos);
59 VolumeID volID = segmentation.volumeID(cell);
61 VolumeManagerContext* vc = vman.lookupContext(volID);
63 global = vc->localToWorld(
Position(pos)) / dd4hep::mm;
65 hit =
new Hit(global);
69 sd.
printM2(
"%s> CREATE hit with deposit:%e MeV Pos:%8.2f %8.2f %8.2f %s [%s]",
70 sd.
c_name(),contrib.deposit,pos.X,pos.Y,pos.Z,handler.path().c_str(),
71 coll.GetName().c_str());
72 if ( 0 == hit->cellID ) {
74 sd.
except(
"+++ Invalid CELL ID for hit!");
77 hit->truth.emplace_back(contrib);
78 hit->energyDeposit += contrib.deposit;
103 G4TouchableHistory* ) {
110 G4TouchableHistory* ) {
129 m_collectionID = declareReadoutFilteredCollection<Geant4Tracker::Hit>();
139 auto contrib = Hit::extractContribution(step);
141 double hit_deposit = h.
deposit();
142 Hit* hit =
new Hit(contrib, hit_momentum, hit_deposit);
144 hit->cellID = cellID(step);
145 if ( 0 == hit->cellID ) {
146 hit->cellID = volumeID(step);
147 except(
"+++ Invalid CELL ID for hit!");
149 collection(m_collectionID)->add(hit);
151 print(
"Hit with deposit:%f Pos:%f %f %f ID=%016X",
152 hit->energyDeposit,hit->position.X(),hit->position.Y(),hit->position.Z(),(
void*)hit->cellID);
154 print(
" Geant4 path:%s",handler.
path().c_str());
161 G4TouchableHistory* )
165 auto contrib = Hit::extractContribution(spot);
169 if ( 0 == hit->cellID ) {
171 except(
"+++ Invalid CELL ID for hit!");
173 collection(m_collectionID)->add(hit);
175 print(
"Hit with deposit:%f Pos:%f %f %f ID=%016X",
176 hit->energyDeposit,hit->position.X(),hit->position.Y(),hit->position.Z(),(
void*)hit->cellID);
178 print(
" Geant4 path:%s",handler.
path().c_str());
202 m_collectionID = declareReadoutFilteredCollection<Geant4Tracker::Hit>();
212 auto contrib = Hit::extractContribution(step);
214 double hit_deposit = contrib.deposit;
215 Hit* hit =
new Hit(contrib, hit_momentum, hit_deposit);
217 if (h.
trackDef() == G4OpticalPhoton::OpticalPhotonDefinition()) {
218 step->GetTrack()->SetTrackStatus(fStopAndKill);
220 hit->cellID = cellID(step);
221 if ( 0 == hit->cellID ) {
222 hit->cellID = volumeID( step ) ;
223 except(
"+++ Invalid CELL ID for hit!");
225 collection(m_collectionID)->add(hit);
227 print(
"Hit with deposit:%f Pos:%f %f %f ID=%016X",
228 hit->energyDeposit,hit->position.X(),hit->position.Y(),hit->position.Z(),(
void*)hit->cellID);
230 print(
" Geant4 path:%s",handler.
path().c_str());
237 G4TouchableHistory* )
241 auto contrib = Hit::extractContribution(spot);
242 Hit* hit =
new Hit(contrib, h.
momentum(), contrib.deposit);
245 if ( 0 == hit->cellID ) {
247 except(
"+++ Invalid CELL ID for hit!");
249 collection(m_collectionID)->add(hit);
251 print(
"Hit with deposit:%f Pos:%f %f %f ID=%016X",
252 hit->energyDeposit,hit->position.X(),hit->position.Y(),hit->position.Z(),(
void*)hit->cellID);
254 print(
" Geant4 path:%s",handler.
path().c_str());
274 m_collectionID = declareReadoutFilteredCollection<Geant4Calorimeter::Hit>();
282 HitContribution contrib = Hit::extractContribution(step);
288 }
catch(std::runtime_error &e) {
289 std::stringstream out;
290 out << std::setprecision(20) << std::scientific;
291 out <<
"ERROR: " << e.what() << std::endl;
293 <<
"Pre (" << std::setw(24) << step->GetPreStepPoint()->GetPosition() <<
") "
294 <<
"Post (" << std::setw(24) << step->GetPostStepPoint()->GetPosition() <<
") "
297 <<
" Pre (" <<std::setw(24) << step->GetPreStepPoint() ->GetMomentum() <<
") "
298 <<
" Post (" <<std::setw(24) << step->GetPostStepPoint()->GetMomentum() <<
") "
300 std::cout << out.str();
304 handleCalorimeterHit(cell, contrib, *coll, h, *
this, m_segmentation);
311 G4TouchableHistory* )
315 HitContribution contrib = Hit::extractContribution(spot);
321 }
catch(std::runtime_error &e) {
322 std::stringstream out;
323 out << std::setprecision(20) << std::scientific;
324 out <<
"ERROR: " << e.what() << std::endl;
325 out <<
"Position: (" << std::setw(24) << h.
avgPositionG4() <<
") " << std::endl;
326 out <<
"Momentum: (" << std::setw(24) << h.
momentumG4() <<
") " << std::endl;
327 std::cout << out.str();
330 handleCalorimeterHit(cell, contrib, *coll, h, *
this, m_segmentation);
358 m_collectionID = declareReadoutFilteredCollection<Geant4Calorimeter::Hit>();
363 G4Track * track = step->GetTrack();
365 if( track->GetDefinition() != G4OpticalPhoton::OpticalPhotonDefinition() ) {
368 else if ( track->GetCreatorProcess()->G4VProcess::GetProcessName() !=
"Cerenkov") {
369 track->SetTrackStatus(fStopAndKill);
376 HitContribution contrib = Hit::extractContribution(step);
381 hit->cellID = volumeID(step);
383 if ( 0 == hit->cellID ) {
384 hit->cellID = volumeID(step);
385 except(
"+++ Invalid CELL ID for hit!");
388 hit->energyDeposit += contrib.deposit;
389 hit->truth.emplace_back(contrib);
390 track->SetTrackStatus(fStopAndKill);
399 G4TouchableHistory* )
403 const G4Track* track = h.
track;
404 if( track->GetDefinition() != G4OpticalPhoton::OpticalPhotonDefinition() ) {
407 else if ( track->GetCreatorProcess()->G4VProcess::GetProcessName() !=
"Cerenkov") {
412 HitContribution contrib = Hit::extractContribution(spot);
419 if ( 0 == hit->cellID ) {
421 except(
"+++ Invalid CELL ID for hit!");
424 hit->energyDeposit += contrib.deposit;
425 hit->truth.emplace_back(contrib);
454 m_collectionID = declareReadoutFilteredCollection<Geant4Calorimeter::Hit>();
461 HitContribution contrib = Hit::extractContribution(step,
true);
466 }
catch(std::runtime_error &e) {
467 std::stringstream out;
468 out << std::setprecision(20) << std::scientific;
469 out <<
"ERROR: " << e.what() << std::endl;
471 <<
"Pre (" << std::setw(24) << step->GetPreStepPoint()->GetPosition() <<
") "
472 <<
"Post (" << std::setw(24) << step->GetPostStepPoint()->GetPosition() <<
") "
475 <<
" Pre (" <<std::setw(24) << step->GetPreStepPoint() ->GetMomentum() <<
") "
476 <<
" Post (" <<std::setw(24) << step->GetPostStepPoint()->GetMomentum() <<
") "
478 std::cout << out.str();
481 handleCalorimeterHit(cell, contrib, *coll, h, *
this, m_segmentation);
489 G4TouchableHistory* )
493 HitContribution contrib = Hit::extractContribution(spot);
499 }
catch(std::runtime_error &e) {
500 std::stringstream out;
501 out << std::setprecision(20) << std::scientific;
502 out <<
"ERROR: " << e.what() << std::endl;
503 out <<
"Position: (" << std::setw(24) << h.
avgPositionG4() <<
") " << std::endl;
504 out <<
"Momentum: (" << std::setw(24) << h.
momentumG4() <<
") " << std::endl;
505 std::cout << out.str();
508 handleCalorimeterHit(cell, contrib, *coll, h, *
this, m_segmentation);
562 void start(
const G4Step* step,
const G4StepPoint* point) {
565 firstSpotVolume = step->GetPreStepPoint()->GetTouchableHandle()->GetVolume();
626 depo, time, path_len, pos, mom);
628 collection->
add(hit);
629 sensitive->
printM2(
"+++ TrackID:%6d [%s] CREATE hit combination with %2d deposit(s):"
630 " %e MeV Pos:%8.2f %8.2f %8.2f",
632 pos.X()/CLHEP::mm,pos.Y()/CLHEP::mm,pos.Z()/CLHEP::mm);
638 G4bool
process(
const G4Step* step, G4TouchableHistory* ) {
656 if ( prePV != postPV ) {
657 void* postSD = h.
sd(h.
post);
660 void* preSD = h.
sd(h.
pre);
661 if ( preSD == postSD ) {
666 else if ( h.
track->GetTrackStatus() == fStopAndKill ) {
689 void* postSD = h.
sd();
692 void* preSD = prePV ? prePV->GetLogicalVolume()->GetSensitiveDetector() :
nullptr;
693 if ( preSD == postSD ) {
698 else if ( h.
track->GetTrackStatus() == fStopAndKill ) {
722 m_userData.e_cut = m_sensitive.energyCutoff();
723 m_userData.sensitive =
this;
728 m_collectionID = declareReadoutFilteredCollection<Geant4Tracker::Hit>();
739 return m_userData.process(step, history);
745 G4TouchableHistory* history) {
746 return m_userData.process(spot, history);