24 #include "G4VSolid.hh" 25 #include "G4LogicalVolumeStore.hh" 26 #include "G4TouchableHistory.hh" 27 #include "G4VPhysicalVolume.hh" 28 #include "G4AffineTransform.hh" 30 #include <DD4hep/Filter.h> 37 #define DEBUG_G4_VOLUMES 39 using namespace CLHEP;
44 const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
46 #ifdef DEBUG_G4_VOLUMES 47 for (G4LogicalVolumeStore::const_iterator volume = lvs->begin(); volume != lvs->end(); ++volume)
48 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: G4 registered volumes " << (*volume)->GetName()
52 for (G4LogicalVolumeStore::const_iterator volume = lvs->begin(); volume != lvs->end(); ++volume) {
53 if ((
const std::string)(dd4hep::dd::noNamespace((*volume)->GetName())) ==
name)
60 static inline const G4AffineTransform&
GetTransform(
const G4TouchableHistory* touchable,
int depth) {
61 return touchable->GetHistory()->GetTransform(touchable->GetHistory()->GetDepth() -
depth);
71 int depth = touchable->GetHistoryDepth();
73 const G4VPhysicalVolume* volume = touchable->GetVolume(
level);
74 if (volume->GetLogicalVolume()->GetSensitiveDetector() !=
nullptr) {
75 return std::make_tuple(volume,
level);
78 return std::tuple<const G4VPhysicalVolume*, int>(
nullptr, 0);
84 m_selectedNames =
config.getParameter<std::vector<std::string> >(
"SelectedVolumes");
85 m_primaryTracks =
config.getParameter<
bool>(
"PrimaryTracksOnly");
87 m_hgcalzfront =
config.getParameter<
double>(
"hgcalzfront");
89 m_track_volume =
nullptr;
91 produces<std::vector<MaterialAccountingTrack> >();
92 output_file_ =
new TFile(
"radLen_vs_eta_fromProducer.root",
"RECREATE");
94 radLen_vs_eta_ =
new TProfile(
"radLen",
"radLen", 250., -5., 5., 0, 10.);
99 if (
std::find(m_selectedNames.begin(), m_selectedNames.end(),
"HGCal") != m_selectedNames.end()) {
104 if (
std::find(m_selectedNames.begin(), m_selectedNames.end(),
"HFNose") != m_selectedNames.end()) {
108 outVolumeZpositionTxt.open(m_txtOutFile.c_str(),
std::ios::out);
117 radLen_vs_eta_->Write();
118 output_file_->Close();
123 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: List of the selected volumes: " << std::endl;
124 for (std::vector<std::string>::const_iterator volume_name = m_selectedNames.begin();
125 volume_name != m_selectedNames.end();
127 const G4LogicalVolume* volume =
GetVolume(*volume_name);
129 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: " << *volume_name << std::endl;
130 m_selectedVolumes.push_back(volume);
133 std::cerr <<
"TrackingMaterialProducer::update(const BeginOfJob*): WARNING: selected volume \"" << *volume_name
134 <<
"\" not found in geometry " << std::endl;
141 m_tracks =
new std::vector<MaterialAccountingTrack>();
147 m_track_volume =
nullptr;
150 G4Track*
track =
const_cast<G4Track*
>((*event)());
151 if (m_primaryTracks and
track->GetParentID() != 0) {
152 track->SetTrackStatus(fStopAndKill);
167 if (
isHGCal &&
track->GetTrackStatus() != fStopAndKill && fabs(
track->GetMomentum().eta()) > outerHGCalEta &&
168 fabs(
track->GetMomentum().eta()) < innerHGCalEta) {
169 if (
track->GetMomentum().eta() > 0.) {
170 outVolumeZpositionTxt <<
"Air " << m_hgcalzfront <<
" " << 0 <<
" " << 0 <<
" " << 0 <<
" " << 0 << std::endl;
171 }
else if (
track->GetMomentum().eta() <= 0.) {
172 outVolumeZpositionTxt <<
"Air " << -m_hgcalzfront <<
" " << 0 <<
" " << 0 <<
" " << 0 <<
" " << 0 << std::endl;
180 if (
isHFNose &&
track->GetTrackStatus() != fStopAndKill && fabs(
track->GetMomentum().eta()) > outerHFnoseEta &&
181 fabs(
track->GetMomentum().eta()) < innerHFnoseEta) {
182 if (
track->GetMomentum().eta() > 0.) {
183 outVolumeZpositionTxt <<
"Polyethylene " << m_hgcalzfront <<
" " << 0 <<
" " << 0 <<
" " << 0 <<
" " << 0
185 }
else if (
track->GetMomentum().eta() <= 0.) {
186 outVolumeZpositionTxt <<
"Polyethylene " << -m_hgcalzfront <<
" " << 0 <<
" " << 0 <<
" " << 0 <<
" " << 0
193 for (
int d = touchable->GetHistoryDepth() - 1;
d >= 0; --
d) {
195 m_selectedNames.end(),
196 (
std::string)(dd4hep::dd::noNamespace(touchable->GetVolume(
d)->GetName()))) != m_selectedNames.end())
204 const G4TouchableHistory* touchable =
static_cast<const G4TouchableHistory*
>(
step->GetTrack()->GetTouchable());
205 if (not isSelectedFast(touchable)) {
206 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer:\t[...] skipping " 207 << touchable->GetVolume()->GetName() << std::endl;
212 const G4Material* material = touchable->GetVolume()->GetLogicalVolume()->GetMaterial();
213 double length =
step->GetStepLength() / cm;
214 double X0 = material->GetRadlen() / cm;
215 double Ne = material->GetElectronDensity() * cm3;
216 double Xi = Ne / 6.0221415e23 * 0.307075 / 2;
217 double radiationLengths = length /
X0;
221 G4ThreeVector globalPosPre =
step->GetPreStepPoint()->GetPosition();
222 G4ThreeVector globalPosPost =
step->GetPostStepPoint()->GetPosition();
223 GlobalPoint globalPositionIn(globalPosPre.x() / cm, globalPosPre.y() / cm, globalPosPre.z() / cm);
224 GlobalPoint globalPositionOut(globalPosPost.x() / cm, globalPosPost.y() / cm, globalPosPost.z() / cm);
226 G4StepPoint* prePoint =
step->GetPreStepPoint();
227 G4StepPoint* postPoint =
step->GetPostStepPoint();
228 const CLHEP::Hep3Vector& postPos = postPoint->GetPosition();
234 if (postPoint->GetStepStatus() == fGeomBoundary && fabs(postPoint->GetMomentum().eta()) > outerHGCalEta &&
235 fabs(postPoint->GetMomentum().eta()) < innerHGCalEta) {
240 outVolumeZpositionTxt << prePoint->GetMaterial()->GetName() <<
" " << postPos.
z() <<
" " 241 << postPoint->GetMomentum().eta() <<
" " 242 <<
sqrt(postPos.x() * postPos.x() + postPos.y() * postPos.y()) <<
" " << 0 <<
" " << 0
246 if (postPoint->GetStepStatus() == fGeomBoundary && fabs(postPoint->GetMomentum().eta()) > outerHFnoseEta &&
247 fabs(postPoint->GetMomentum().eta()) < innerHFnoseEta) {
248 outVolumeZpositionTxt << prePoint->GetMaterial()->GetName() <<
" " << postPos.z() <<
" " 249 << postPoint->GetMomentum().eta() <<
" " 250 <<
sqrt(postPos.x() * postPos.x() + postPos.y() * postPos.y()) <<
" " << 0 <<
" " << 0
257 bool enter_sensitive =
false;
258 bool leave_sensitive =
false;
259 double cosThetaPre = 0.0;
260 double cosThetaPost = 0.0;
262 const G4VPhysicalVolume* sensitive =
nullptr;
266 const G4VSolid& solid = *touchable->GetSolid(
level);
268 G4ThreeVector
pos =
transform.Inverse().TransformPoint(G4ThreeVector(0., 0., 0.));
271 G4ThreeVector localPosPre =
transform.TransformPoint(globalPosPre);
272 EInside statusPre = solid.Inside(localPosPre);
273 if (statusPre == kSurface) {
274 enter_sensitive =
true;
275 G4ThreeVector globalDirPre =
step->GetPreStepPoint()->GetMomentumDirection();
276 G4ThreeVector localDirPre =
transform.TransformAxis(globalDirPre);
277 G4ThreeVector normalPre = solid.SurfaceNormal(localPosPre);
278 cosThetaPre = normalPre.cosTheta(-localDirPre);
281 G4ThreeVector localPosPost =
transform.TransformPoint(globalPosPost);
282 EInside statusPost = solid.Inside(localPosPost);
283 if (statusPost == kSurface) {
284 leave_sensitive =
true;
285 G4ThreeVector globalDirPost =
step->GetPostStepPoint()->GetMomentumDirection();
286 G4ThreeVector localDirPost =
transform.TransformAxis(globalDirPost);
287 G4ThreeVector normalPost = solid.SurfaceNormal(localPosPost);
288 cosThetaPost = normalPost.cosTheta(localDirPost);
293 if (enter_sensitive) {
294 if (m_track_volume !=
nullptr) {
295 edm::LogWarning(
"TrackingMaterialProducer") <<
"Entering volume " << sensitive <<
" while inside volume " 296 << m_track_volume <<
". Something is inconsistent";
299 m_track_volume = sensitive;
300 m_track.enterDetector(
position, cosThetaPre);
303 if (leave_sensitive) {
304 if (m_track_volume != sensitive) {
305 edm::LogWarning(
"TrackingMaterialProducer") <<
"Leaving volume " << sensitive <<
" while inside volume " 306 << m_track_volume <<
". Something is inconsistent";
309 m_track.leaveDetector(cosThetaPost);
310 m_track_volume =
nullptr;
313 LogInfo(
"TrackingMaterialProducer") <<
"Track was near sensitive volume " << sensitive->GetName() << std::endl;
315 LogInfo(
"TrackingMaterialProducer") <<
"Track was near non-sensitive volume " << touchable->GetVolume()->GetName()
317 LogInfo(
"TrackingMaterialProducer") <<
"Step length: " << length <<
" cm\n" 318 <<
"globalPreStep(r,z): (" << globalPositionIn.perp() <<
", " 319 << globalPositionIn.z() <<
") cm\n" 320 <<
"globalPostStep(r,z): (" << globalPositionOut.perp() <<
", " 321 << globalPositionOut.z() <<
") cm\n" 322 <<
"position(r,z): (" <<
position.perp() <<
", " <<
position.z() <<
") cm\n" 323 <<
"Radiation lengths: " << radiationLengths <<
" \t\t(X0: " <<
X0 325 <<
"Energy loss: " <<
energyLoss <<
" MeV \t(Xi: " << Xi
327 <<
"Track was " << (enter_sensitive ?
"entering " :
"in none ")
328 <<
"sensitive volume\n" 329 <<
"Track was " << (leave_sensitive ?
"leaving " :
"in none ")
330 <<
"sensitive volume\n";
335 const G4Track*
track = (*event)();
336 if (m_primaryTracks and
track->GetParentID() != 0)
339 radLen_vs_eta_->Fill(
track->GetMomentum().eta(), m_track.summary().radiationLengths());
340 m_tracks->push_back(m_track);
343 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: this track took " << m_track.steps().size()
344 <<
" steps, and passed through " << m_track.detectors().size()
345 <<
" sensitive detectors" << std::endl;
346 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: track length: " << m_track.summary().length()
347 <<
" cm" << std::endl;
348 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: radiation lengths: " 349 << m_track.summary().radiationLengths() << std::endl;
350 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: energy loss: " 351 << m_track.summary().energyLoss() <<
" MeV" << std::endl;
357 std::unique_ptr<std::vector<MaterialAccountingTrack> >
tracks(m_tracks);
364 for (
size_t i = 0;
i < m_selectedVolumes.size(); ++
i)
365 if (m_selectedVolumes[
i]->IsAncestor(touchable->GetVolume())
or 366 m_selectedVolumes[
i] == touchable->GetVolume()->GetLogicalVolume())
#define DEFINE_SIMWATCHER(type)
T getParameter(std::string const &) const
Global3DPoint GlobalPoint
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
TrackingMaterialProducer(const edm::ParameterSet &)
static const G4AffineTransform & GetTransform(const G4TouchableHistory *touchable, int depth)
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
~TrackingMaterialProducer() override
Log< level::Info, false > LogInfo
static const G4LogicalVolume * GetVolume(const std::string &name)
static int position[264][3]
Log< level::Warning, false > LogWarning
void produce(edm::Event &, const edm::EventSetup &) override
void update(const BeginOfJob *) override
This routine will be called when the appropriate signal arrives.
bool isSelected(const G4VTouchable *touch)
bool isSelectedFast(const G4TouchableHistory *touch)
std::tuple< const G4VPhysicalVolume *, int > GetSensitiveVolume(const G4VTouchable *touchable)