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;
43 const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
45 #ifdef DEBUG_G4_VOLUMES 46 for (G4LogicalVolumeStore::const_iterator volume = lvs->begin(); volume != lvs->end(); ++volume)
47 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: G4 registered volumes " 48 << (*volume)->GetName() << std::endl;
51 for (G4LogicalVolumeStore::const_iterator volume = lvs->begin(); volume != lvs->end(); ++volume) {
62 return touchable->GetHistory()->GetTransform( touchable->GetHistory()->GetDepth() -
depth );
73 int depth = touchable->GetHistoryDepth();
75 const G4VPhysicalVolume* volume = touchable->GetVolume(
level);
76 if (volume->GetLogicalVolume()->GetSensitiveDetector() !=
nullptr) {
77 return std::make_tuple(volume,
level);
80 return std::tuple<const G4VPhysicalVolume*, int>(
nullptr, 0);
87 m_selectedNames = config.
getParameter< std::vector<std::string> >(
"SelectedVolumes");
88 m_primaryTracks = config.
getParameter<
bool>(
"PrimaryTracksOnly");
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.);
105 radLen_vs_eta_->Write();
106 output_file_->Close();
112 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: List of the selected volumes: " << std::endl;
113 for (std::vector<std::string>::const_iterator volume_name = m_selectedNames.begin();
114 volume_name != m_selectedNames.end(); ++volume_name) {
115 const G4LogicalVolume* volume =
GetVolume(*volume_name);
117 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: " << *volume_name << std::endl;
118 m_selectedVolumes.push_back( volume );
121 std::cerr <<
"TrackingMaterialProducer::update(const BeginOfJob*): WARNING: selected volume \"" << *volume_name <<
"\" not found in geometry " << std::endl;
130 m_tracks =
new std::vector<MaterialAccountingTrack>();
140 G4Track*
track =
const_cast<G4Track*
>((*event)());
141 if (m_primaryTracks and track->GetParentID() != 0) {
142 track->SetTrackStatus(fStopAndKill);
147 for (
int d = touchable->GetHistoryDepth() -1;
d >=0; --
d) {
150 m_selectedNames.begin(),
151 m_selectedNames.end(),
152 touchable->GetVolume(
d)->GetName())
153 != m_selectedNames.end())
162 const G4TouchableHistory* touchable = (G4TouchableHistory*)(step->GetTrack()->GetTouchable());
163 if (not isSelectedFast( touchable )) {
164 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer:\t[...] skipping " 165 << touchable->GetVolume()->GetName() << std::endl;
170 const G4Material* material = touchable->GetVolume()->GetLogicalVolume()->GetMaterial();
171 double length = step->GetStepLength() / cm;
172 double X0 = material->GetRadlen() / cm;
173 double Ne = material->GetElectronDensity() * cm3;
174 double Xi = Ne / 6.0221415e23 * 0.307075 / 2;
175 double radiationLengths = length /
X0;
176 double energyLoss = length * Xi / 1000.;
179 G4ThreeVector globalPosPre = step->GetPreStepPoint()->GetPosition();
180 G4ThreeVector globalPosPost = step->GetPostStepPoint()->GetPosition();
181 GlobalPoint globalPositionIn( globalPosPre.x() / cm, globalPosPre.y() / cm, globalPosPre.z() / cm );
182 GlobalPoint globalPositionOut( globalPosPost.x() / cm, globalPosPost.y() / cm, globalPosPost.z() / cm );
185 bool enter_sensitive =
false;
186 bool leave_sensitive =
false;
187 double cosThetaPre = 0.0;
188 double cosThetaPost = 0.0;
190 const G4VPhysicalVolume* sensitive =
nullptr;
194 const G4VSolid & solid = *touchable->GetSolid( level );
196 G4ThreeVector
pos = transform.Inverse().TransformPoint( G4ThreeVector( 0., 0., 0. ) );
197 position =
GlobalPoint( pos.x() / cm, pos.y() / cm, pos.z() / cm );
199 G4ThreeVector localPosPre = transform.TransformPoint( globalPosPre );
200 EInside statusPre = solid.Inside( localPosPre );
201 if (statusPre == kSurface) {
202 enter_sensitive =
true;
203 G4ThreeVector globalDirPre = step->GetPreStepPoint()->GetMomentumDirection();
204 G4ThreeVector localDirPre = transform.TransformAxis( globalDirPre );
205 G4ThreeVector normalPre = solid.SurfaceNormal( localPosPre );
206 cosThetaPre = normalPre.cosTheta( -localDirPre );
209 G4ThreeVector localPosPost = transform.TransformPoint( globalPosPost );
210 EInside statusPost = solid.Inside( localPosPost );
211 if (statusPost == kSurface) {
212 leave_sensitive =
true;
213 G4ThreeVector globalDirPost = step->GetPostStepPoint()->GetMomentumDirection();
214 G4ThreeVector localDirPost = transform.TransformAxis( globalDirPost );
215 G4ThreeVector normalPost = solid.SurfaceNormal( localPosPost );
216 cosThetaPost = normalPost.cosTheta( localDirPost );
222 m_track.enterDetector( sensitive, position, cosThetaPre );
223 m_track.step(
MaterialAccountingStep( length, radiationLengths, energyLoss, globalPositionIn, globalPositionOut ));
225 m_track.leaveDetector( sensitive, cosThetaPost );
228 LogInfo(
"TrackingMaterialProducer") <<
"Track was near sensitive volume " 229 << sensitive->GetName() << std::endl;
231 LogInfo(
"TrackingMaterialProducer") <<
"Track was near non-sensitive volume " 232 << touchable->GetVolume()->GetName() << std::endl;
233 LogInfo(
"TrackingMaterialProducer") <<
"Step length: " 235 <<
"globalPreStep(r,z): (" << globalPositionIn.perp()
236 <<
", " << globalPositionIn.z() <<
") cm\n" 237 <<
"globalPostStep(r,z): (" << globalPositionOut.perp()
238 <<
", " << globalPositionOut.z() <<
") cm\n" 239 <<
"position(r,z): (" 241 <<
", " << position.
z() <<
") cm\n" 242 <<
"Radiation lengths: " 243 << radiationLengths <<
" \t\t(X0: " 246 << energyLoss <<
" MeV \t(Xi: " 247 << Xi <<
" MeV/cm)\n" 248 <<
"Track was " << (enter_sensitive ?
"entering " :
"in none ")
249 <<
"sensitive volume\n" 250 <<
"Track was " << (leave_sensitive ?
"leaving " :
"in none ")
251 <<
"sensitive volume\n";
259 const G4Track *
track = (*event)();
260 if (m_primaryTracks and track->GetParentID() != 0)
263 radLen_vs_eta_->Fill(track->GetMomentum().eta(), m_track.summary().radiationLengths());
264 m_tracks->push_back(m_track);
267 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: this track took " 268 << m_track.steps().size()
269 <<
" steps, and passed through " 270 << m_track.detectors().size()
271 <<
" sensitive detectors" << std::endl;
272 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: track length: " 273 << m_track.summary().length()
274 <<
" cm" << std::endl;
275 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: radiation lengths: " 276 << m_track.summary().radiationLengths() << std::endl;
277 LogInfo(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: energy loss: " 278 << m_track.summary().energyLoss()
279 <<
" MeV" << std::endl;
286 std::unique_ptr<std::vector<MaterialAccountingTrack> >
tracks( m_tracks );
294 for (
size_t i = 0;
i < m_selectedVolumes.size(); ++
i)
295 if (m_selectedVolumes[
i]->IsAncestor( touchable->GetVolume() )
296 or 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)