24 #include "G4VSolid.hh"
25 #include "G4LogicalVolumeStore.hh"
26 #include "G4TouchableHistory.hh"
27 #include "G4VPhysicalVolume.hh"
28 #include "G4AffineTransform.hh"
35 #define DEBUG_G4_VOLUMES
37 using namespace CLHEP;
42 const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
44 #ifdef DEBUG_G4_VOLUMES
45 for (G4LogicalVolumeStore::const_iterator volume = lvs->begin(); volume != lvs->end(); ++volume)
46 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: G4 registered volumes " << (*volume)->GetName()
50 for (G4LogicalVolumeStore::const_iterator volume = lvs->begin(); volume != lvs->end(); ++volume) {
58 static inline const G4AffineTransform&
GetTransform(
const G4TouchableHistory* touchable,
int depth) {
59 return touchable->GetHistory()->GetTransform(touchable->GetHistory()->GetDepth() -
depth);
69 int depth = touchable->GetHistoryDepth();
71 const G4VPhysicalVolume* volume = touchable->GetVolume(
level);
72 if (volume->GetLogicalVolume()->GetSensitiveDetector() !=
nullptr) {
73 return std::make_tuple(volume,
level);
76 return std::tuple<const G4VPhysicalVolume*, int>(
nullptr, 0);
82 m_selectedNames =
config.getParameter<std::vector<std::string> >(
"SelectedVolumes");
83 m_primaryTracks =
config.getParameter<
bool>(
"PrimaryTracksOnly");
85 m_hgcalzfront =
config.getParameter<
double>(
"hgcalzfront");
87 m_track_volume =
nullptr;
89 produces<std::vector<MaterialAccountingTrack> >();
90 output_file_ =
new TFile(
"radLen_vs_eta_fromProducer.root",
"RECREATE");
92 radLen_vs_eta_ =
new TProfile(
"radLen",
"radLen", 250., -5., 5., 0, 10.);
96 if (
std::find(m_selectedNames.begin(), m_selectedNames.end(),
"HGCal") != m_selectedNames.end()) {
101 if (
std::find(m_selectedNames.begin(), m_selectedNames.end(),
"HFNose") != m_selectedNames.end()) {
105 outVolumeZpositionTxt.open(m_txtOutFile.c_str(),
std::ios::out);
114 radLen_vs_eta_->Write();
115 output_file_->Close();
120 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: List of the selected volumes: " << std::endl;
121 for (std::vector<std::string>::const_iterator volume_name = m_selectedNames.begin();
122 volume_name != m_selectedNames.end();
124 const G4LogicalVolume* volume =
GetVolume(*volume_name);
126 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: " << *volume_name << std::endl;
127 m_selectedVolumes.push_back(volume);
130 std::cerr <<
"TrackingMaterialProducer::update(const BeginOfJob*): WARNING: selected volume \"" << *volume_name
131 <<
"\" not found in geometry " << std::endl;
138 m_tracks =
new std::vector<MaterialAccountingTrack>();
144 m_track_volume =
nullptr;
147 G4Track*
track = const_cast<G4Track*>((*
event)());
148 if (m_primaryTracks and
track->GetParentID() != 0) {
149 track->SetTrackStatus(fStopAndKill);
159 if (
isHGCal &&
track->GetTrackStatus() != fStopAndKill && fabs(
track->GetMomentum().eta()) > outerHGCalEta &&
160 fabs(
track->GetMomentum().eta()) < innerHGCalEta) {
161 if (
track->GetMomentum().eta() > 0.) {
162 outVolumeZpositionTxt <<
"StainlessSteel " << m_hgcalzfront <<
" " << 0 <<
" " << 0 <<
" " << 0 <<
" " << 0
164 }
else if (
track->GetMomentum().eta() <= 0.) {
165 outVolumeZpositionTxt <<
"StainlessSteel " << -m_hgcalzfront <<
" " << 0 <<
" " << 0 <<
" " << 0 <<
" " << 0
174 if (
isHFNose &&
track->GetTrackStatus() != fStopAndKill && fabs(
track->GetMomentum().eta()) > outerHFnoseEta &&
175 fabs(
track->GetMomentum().eta()) < innerHFnoseEta) {
176 if (
track->GetMomentum().eta() > 0.) {
177 outVolumeZpositionTxt <<
"Polyethylene " << m_hgcalzfront <<
" " << 0 <<
" " << 0 <<
" " << 0 <<
" " << 0
179 }
else if (
track->GetMomentum().eta() <= 0.) {
180 outVolumeZpositionTxt <<
"Polyethylene " << -m_hgcalzfront <<
" " << 0 <<
" " << 0 <<
" " << 0 <<
" " << 0
187 for (
int d = touchable->GetHistoryDepth() - 1;
d >= 0; --
d) {
188 if (
std::find(m_selectedNames.begin(), m_selectedNames.end(), touchable->GetVolume(
d)->GetName()) !=
189 m_selectedNames.end())
197 const G4TouchableHistory* touchable = static_cast<const G4TouchableHistory*>(
step->GetTrack()->GetTouchable());
198 if (not isSelectedFast(touchable)) {
199 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer:\t[...] skipping "
200 << touchable->GetVolume()->GetName() << std::endl;
205 const G4Material* material = touchable->GetVolume()->GetLogicalVolume()->GetMaterial();
206 double length =
step->GetStepLength() / cm;
207 double X0 = material->GetRadlen() / cm;
208 double Ne = material->GetElectronDensity() * cm3;
209 double Xi = Ne / 6.0221415e23 * 0.307075 / 2;
210 double radiationLengths = length /
X0;
214 G4ThreeVector globalPosPre =
step->GetPreStepPoint()->GetPosition();
215 G4ThreeVector globalPosPost =
step->GetPostStepPoint()->GetPosition();
216 GlobalPoint globalPositionIn(globalPosPre.x() / cm, globalPosPre.y() / cm, globalPosPre.z() / cm);
217 GlobalPoint globalPositionOut(globalPosPost.x() / cm, globalPosPost.y() / cm, globalPosPost.z() / cm);
219 G4StepPoint* prePoint =
step->GetPreStepPoint();
220 G4StepPoint* postPoint =
step->GetPostStepPoint();
221 const CLHEP::Hep3Vector& postPos = postPoint->GetPosition();
227 if (postPoint->GetStepStatus() == fGeomBoundary && fabs(postPoint->GetMomentum().eta()) > outerHGCalEta &&
228 fabs(postPoint->GetMomentum().eta()) < innerHGCalEta) {
233 outVolumeZpositionTxt << prePoint->GetMaterial()->GetName() <<
" " << postPos.
z() <<
" "
234 << postPoint->GetMomentum().eta() <<
" "
235 <<
sqrt(postPos.x() * postPos.x() + postPos.y() * postPos.y()) <<
" " << 0 <<
" " << 0
239 if (postPoint->GetStepStatus() == fGeomBoundary && fabs(postPoint->GetMomentum().eta()) > outerHFnoseEta &&
240 fabs(postPoint->GetMomentum().eta()) < innerHFnoseEta) {
241 outVolumeZpositionTxt << prePoint->GetMaterial()->GetName() <<
" " << postPos.z() <<
" "
242 << postPoint->GetMomentum().eta() <<
" "
243 <<
sqrt(postPos.x() * postPos.x() + postPos.y() * postPos.y()) <<
" " << 0 <<
" " << 0
250 bool enter_sensitive =
false;
251 bool leave_sensitive =
false;
252 double cosThetaPre = 0.0;
253 double cosThetaPost = 0.0;
255 const G4VPhysicalVolume* sensitive =
nullptr;
259 const G4VSolid& solid = *touchable->GetSolid(
level);
261 G4ThreeVector
pos =
transform.Inverse().TransformPoint(G4ThreeVector(0., 0., 0.));
264 G4ThreeVector localPosPre =
transform.TransformPoint(globalPosPre);
265 EInside statusPre = solid.Inside(localPosPre);
266 if (statusPre == kSurface) {
267 enter_sensitive =
true;
268 G4ThreeVector globalDirPre =
step->GetPreStepPoint()->GetMomentumDirection();
269 G4ThreeVector localDirPre =
transform.TransformAxis(globalDirPre);
270 G4ThreeVector normalPre = solid.SurfaceNormal(localPosPre);
271 cosThetaPre = normalPre.cosTheta(-localDirPre);
274 G4ThreeVector localPosPost =
transform.TransformPoint(globalPosPost);
275 EInside statusPost = solid.Inside(localPosPost);
276 if (statusPost == kSurface) {
277 leave_sensitive =
true;
278 G4ThreeVector globalDirPost =
step->GetPostStepPoint()->GetMomentumDirection();
279 G4ThreeVector localDirPost =
transform.TransformAxis(globalDirPost);
280 G4ThreeVector normalPost = solid.SurfaceNormal(localPosPost);
281 cosThetaPost = normalPost.cosTheta(localDirPost);
286 if (enter_sensitive) {
287 if (m_track_volume !=
nullptr) {
288 edm::LogWarning(
"TrackingMaterialProducer") <<
"Entering volume " << sensitive <<
" while inside volume "
289 << m_track_volume <<
". Something is inconsistent";
292 m_track_volume = sensitive;
293 m_track.enterDetector(
position, cosThetaPre);
296 if (leave_sensitive) {
297 if (m_track_volume != sensitive) {
298 edm::LogWarning(
"TrackingMaterialProducer") <<
"Leaving volume " << sensitive <<
" while inside volume "
299 << m_track_volume <<
". Something is inconsistent";
302 m_track.leaveDetector(cosThetaPost);
303 m_track_volume =
nullptr;
306 LogInfo(
"TrackingMaterialProducer") <<
"Track was near sensitive volume " << sensitive->GetName() << std::endl;
308 LogInfo(
"TrackingMaterialProducer") <<
"Track was near non-sensitive volume " << touchable->GetVolume()->GetName()
310 LogInfo(
"TrackingMaterialProducer") <<
"Step length: " << length <<
" cm\n"
311 <<
"globalPreStep(r,z): (" << globalPositionIn.perp() <<
", "
312 << globalPositionIn.z() <<
") cm\n"
313 <<
"globalPostStep(r,z): (" << globalPositionOut.perp() <<
", "
314 << globalPositionOut.z() <<
") cm\n"
315 <<
"position(r,z): (" <<
position.perp() <<
", " <<
position.z() <<
") cm\n"
316 <<
"Radiation lengths: " << radiationLengths <<
" \t\t(X0: " <<
X0
318 <<
"Energy loss: " <<
energyLoss <<
" MeV \t(Xi: " << Xi
320 <<
"Track was " << (enter_sensitive ?
"entering " :
"in none ")
321 <<
"sensitive volume\n"
322 <<
"Track was " << (leave_sensitive ?
"leaving " :
"in none ")
323 <<
"sensitive volume\n";
328 const G4Track*
track = (*event)();
329 if (m_primaryTracks and
track->GetParentID() != 0)
332 radLen_vs_eta_->Fill(
track->GetMomentum().eta(), m_track.summary().radiationLengths());
333 m_tracks->push_back(m_track);
336 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: this track took " << m_track.steps().size()
337 <<
" steps, and passed through " << m_track.detectors().size()
338 <<
" sensitive detectors" << std::endl;
339 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: track length: " << m_track.summary().length()
340 <<
" cm" << std::endl;
341 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: radiation lengths: "
342 << m_track.summary().radiationLengths() << std::endl;
343 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: energy loss: "
344 << m_track.summary().energyLoss() <<
" MeV" << std::endl;
350 std::unique_ptr<std::vector<MaterialAccountingTrack> >
tracks(m_tracks);
357 for (
size_t i = 0;
i < m_selectedVolumes.size(); ++
i)
358 if (m_selectedVolumes[
i]->IsAncestor(touchable->GetVolume())
or
359 m_selectedVolumes[
i] == touchable->GetVolume()->GetLogicalVolume())