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");
86 produces<std::vector<MaterialAccountingTrack> >();
87 output_file_ =
new TFile(
"radLen_vs_eta_fromProducer.root",
"RECREATE");
89 radLen_vs_eta_ =
new TProfile(
"radLen",
"radLen", 250., -5., 5., 0, 10.);
97 radLen_vs_eta_->Write();
98 output_file_->Close();
103 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: List of the selected volumes: " << std::endl;
104 for (std::vector<std::string>::const_iterator volume_name = m_selectedNames.begin();
105 volume_name != m_selectedNames.end();
107 const G4LogicalVolume* volume =
GetVolume(*volume_name);
109 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: " << *volume_name << std::endl;
110 m_selectedVolumes.push_back(volume);
113 std::cerr <<
"TrackingMaterialProducer::update(const BeginOfJob*): WARNING: selected volume \"" << *volume_name
114 <<
"\" not found in geometry " << std::endl;
121 m_tracks =
new std::vector<MaterialAccountingTrack>();
129 G4Track*
track =
const_cast<G4Track*
>((*event)());
130 if (m_primaryTracks and track->GetParentID() != 0) {
131 track->SetTrackStatus(fStopAndKill);
136 for (
int d = touchable->GetHistoryDepth() - 1;
d >= 0; --
d) {
137 if (
std::find(m_selectedNames.begin(), m_selectedNames.end(), touchable->GetVolume(
d)->GetName()) !=
138 m_selectedNames.end())
146 const G4TouchableHistory* touchable =
static_cast<const G4TouchableHistory*
>(step->GetTrack()->GetTouchable());
147 if (not isSelectedFast(touchable)) {
148 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer:\t[...] skipping " 149 << touchable->GetVolume()->GetName() << std::endl;
154 const G4Material* material = touchable->GetVolume()->GetLogicalVolume()->GetMaterial();
155 double length = step->GetStepLength() / cm;
156 double X0 = material->GetRadlen() / cm;
157 double Ne = material->GetElectronDensity() * cm3;
158 double Xi = Ne / 6.0221415e23 * 0.307075 / 2;
159 double radiationLengths = length /
X0;
160 double energyLoss = length * Xi / 1000.;
163 G4ThreeVector globalPosPre = step->GetPreStepPoint()->GetPosition();
164 G4ThreeVector globalPosPost = step->GetPostStepPoint()->GetPosition();
165 GlobalPoint globalPositionIn(globalPosPre.x() / cm, globalPosPre.y() / cm, globalPosPre.z() / cm);
166 GlobalPoint globalPositionOut(globalPosPost.x() / cm, globalPosPost.y() / cm, globalPosPost.z() / cm);
169 bool enter_sensitive =
false;
170 bool leave_sensitive =
false;
171 double cosThetaPre = 0.0;
172 double cosThetaPost = 0.0;
174 const G4VPhysicalVolume* sensitive =
nullptr;
178 const G4VSolid& solid = *touchable->GetSolid(level);
180 G4ThreeVector
pos = transform.Inverse().TransformPoint(G4ThreeVector(0., 0., 0.));
181 position =
GlobalPoint(pos.x() / cm, pos.y() / cm, pos.z() / cm);
183 G4ThreeVector localPosPre = transform.TransformPoint(globalPosPre);
184 EInside statusPre = solid.Inside(localPosPre);
185 if (statusPre == kSurface) {
186 enter_sensitive =
true;
187 G4ThreeVector globalDirPre = step->GetPreStepPoint()->GetMomentumDirection();
188 G4ThreeVector localDirPre = transform.TransformAxis(globalDirPre);
189 G4ThreeVector normalPre = solid.SurfaceNormal(localPosPre);
190 cosThetaPre = normalPre.cosTheta(-localDirPre);
193 G4ThreeVector localPosPost = transform.TransformPoint(globalPosPost);
194 EInside statusPost = solid.Inside(localPosPost);
195 if (statusPost == kSurface) {
196 leave_sensitive =
true;
197 G4ThreeVector globalDirPost = step->GetPostStepPoint()->GetMomentumDirection();
198 G4ThreeVector localDirPost = transform.TransformAxis(globalDirPost);
199 G4ThreeVector normalPost = solid.SurfaceNormal(localPosPost);
200 cosThetaPost = normalPost.cosTheta(localDirPost);
206 m_track.enterDetector(sensitive, position, cosThetaPre);
207 m_track.step(
MaterialAccountingStep(length, radiationLengths, energyLoss, globalPositionIn, globalPositionOut));
209 m_track.leaveDetector(sensitive, cosThetaPost);
212 LogInfo(
"TrackingMaterialProducer") <<
"Track was near sensitive volume " << sensitive->GetName() << std::endl;
214 LogInfo(
"TrackingMaterialProducer") <<
"Track was near non-sensitive volume " << touchable->GetVolume()->GetName()
216 LogInfo(
"TrackingMaterialProducer") <<
"Step length: " << length <<
" cm\n" 217 <<
"globalPreStep(r,z): (" << globalPositionIn.perp() <<
", " 218 << globalPositionIn.z() <<
") cm\n" 219 <<
"globalPostStep(r,z): (" << globalPositionOut.perp() <<
", " 220 << globalPositionOut.z() <<
") cm\n" 221 <<
"position(r,z): (" << position.
perp() <<
", " << position.
z() <<
") cm\n" 222 <<
"Radiation lengths: " << radiationLengths <<
" \t\t(X0: " << X0
224 <<
"Energy loss: " << energyLoss <<
" MeV \t(Xi: " << Xi
226 <<
"Track was " << (enter_sensitive ?
"entering " :
"in none ")
227 <<
"sensitive volume\n" 228 <<
"Track was " << (leave_sensitive ?
"leaving " :
"in none ")
229 <<
"sensitive volume\n";
234 const G4Track*
track = (*event)();
235 if (m_primaryTracks and track->GetParentID() != 0)
238 radLen_vs_eta_->Fill(track->GetMomentum().eta(), m_track.summary().radiationLengths());
239 m_tracks->push_back(m_track);
242 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: this track took " << m_track.steps().size()
243 <<
" steps, and passed through " << m_track.detectors().size()
244 <<
" sensitive detectors" << std::endl;
245 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: track length: " << m_track.summary().length()
246 <<
" cm" << std::endl;
247 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: radiation lengths: " 248 << m_track.summary().radiationLengths() << std::endl;
249 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: energy loss: " 250 << m_track.summary().energyLoss() <<
" MeV" << std::endl;
256 std::unique_ptr<std::vector<MaterialAccountingTrack> >
tracks(m_tracks);
263 for (
size_t i = 0;
i < m_selectedVolumes.size(); ++
i)
264 if (m_selectedVolumes[
i]->IsAncestor(touchable->GetVolume())
or 265 m_selectedVolumes[
i] == touchable->GetVolume()->GetLogicalVolume())
T getParameter(std::string const &) const
#define DEFINE_SIMWATCHER(type)
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
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
static const G4LogicalVolume * GetVolume(const std::string &name)
static int position[264][3]
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)