6 #include <boost/tuple/tuple.hpp>
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 LogDebug(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: G4 registered volumes "
47 << (*volume)->GetName() << std::endl;
50 for (G4LogicalVolumeStore::const_iterator volume = lvs->begin(); volume != lvs->end(); ++volume) {
61 return touchable->GetHistory()->GetTransform( touchable->GetHistory()->GetDepth() -
depth );
72 int depth = touchable->GetHistoryDepth();
74 const G4VPhysicalVolume* volume = touchable->GetVolume(
level);
75 if (volume->GetLogicalVolume()->GetSensitiveDetector() != 0) {
76 return boost::make_tuple(volume,
level);
79 return boost::tuple<const G4VPhysicalVolume*, int>(0, 0);
86 m_selectedNames = config.
getParameter< std::vector<std::string> >(
"SelectedVolumes");
87 m_primaryTracks = config.
getParameter<
bool>(
"PrimaryTracksOnly");
90 produces< std::vector<MaterialAccountingTrack> >();
102 LogDebug(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: List of the selected volumes: " << std::endl;
103 for (std::vector<std::string>::const_iterator volume_name = m_selectedNames.begin();
104 volume_name != m_selectedNames.end(); ++volume_name) {
105 const G4LogicalVolume* volume =
GetVolume(*volume_name);
107 LogDebug(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: " << *volume_name << std::endl;
108 m_selectedVolumes.push_back( volume );
111 std::cerr <<
"TrackingMaterialProducer::update(const BeginOfJob*): WARNING: selected volume \"" << *volume_name <<
"\" not found in geometry " << std::endl;
120 m_tracks =
new std::vector<MaterialAccountingTrack>();
130 G4Track* track =
const_cast<G4Track*
>((*event)());
131 if (m_primaryTracks and track->GetParentID() != 0) {
132 track->SetTrackStatus(fStopAndKill);
140 const G4TouchableHistory* touchable = (G4TouchableHistory*)(step->GetTrack()->GetTouchable());
141 if (not isSelected( touchable )) {
142 LogDebug(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer:\t[...] skipping "
143 << touchable->GetVolume()->GetName() << std::endl;
148 const G4Material* material = touchable->GetVolume()->GetLogicalVolume()->GetMaterial();
149 double length = step->GetStepLength() / cm;
150 double X0 = material->GetRadlen() / cm;
151 double Ne = material->GetElectronDensity() * cm3;
152 double Xi = Ne / 6.0221415e23 * 0.307075 / 2;
153 double radiationLengths = length /
X0;
154 double energyLoss = length * Xi / 1000.;
157 G4ThreeVector globalPosPre = step->GetPreStepPoint()->GetPosition();
158 G4ThreeVector globalPosPost = step->GetPostStepPoint()->GetPosition();
159 GlobalPoint globalPositionIn( globalPosPre.x() / cm, globalPosPre.y() / cm, globalPosPre.z() / cm );
160 GlobalPoint globalPositionOut( globalPosPost.x() / cm, globalPosPost.y() / cm, globalPosPost.z() / cm );
163 bool enter_sensitive =
false;
164 bool leave_sensitive =
false;
165 double cosThetaPre = 0.0;
166 double cosThetaPost = 0.0;
168 const G4VPhysicalVolume* sensitive = 0;
172 const G4VSolid & solid = *touchable->GetSolid( level );
174 G4ThreeVector pos = transform.Inverse().TransformPoint( G4ThreeVector( 0., 0., 0. ) );
175 position =
GlobalPoint( pos.x() / cm, pos.y() / cm, pos.z() / cm );
177 G4ThreeVector localPosPre = transform.TransformPoint( globalPosPre );
178 EInside statusPre = solid.Inside( localPosPre );
179 if (statusPre == kSurface) {
180 enter_sensitive =
true;
181 G4ThreeVector globalDirPre = step->GetPreStepPoint()->GetMomentumDirection();
182 G4ThreeVector localDirPre = transform.TransformAxis( globalDirPre );
183 G4ThreeVector normalPre = solid.SurfaceNormal( localPosPre );
184 cosThetaPre = normalPre.cosTheta( -localDirPre );
187 G4ThreeVector localPosPost = transform.TransformPoint( globalPosPost );
188 EInside statusPost = solid.Inside( localPosPost );
189 if (statusPost == kSurface) {
190 leave_sensitive =
true;
191 G4ThreeVector globalDirPost = step->GetPostStepPoint()->GetMomentumDirection();
192 G4ThreeVector localDirPost = transform.TransformAxis( globalDirPost );
193 G4ThreeVector normalPost = solid.SurfaceNormal( localPosPost );
194 cosThetaPost = normalPost.cosTheta( localDirPost );
200 m_track.enterDetector( sensitive, position, cosThetaPre );
201 m_track.step(
MaterialAccountingStep( length, radiationLengths, energyLoss, globalPositionIn, globalPositionOut ));
203 m_track.leaveDetector( sensitive, cosThetaPost );
206 LogDebug(
"TrackingMaterialProducer") <<
"Track was near sensitive volume "
207 << sensitive->GetName() << std::endl;
209 LogDebug(
"TrackingMaterialProducer") <<
"Track was near non-sensitive volume "
210 << touchable->GetVolume()->GetName() << std::endl;
211 LogDebug(
"TrackingMaterialProducer") <<
"Step length: "
212 << length <<
" cm" << std::endl;
213 LogDebug(
"TrackingMaterialProducer") <<
"Radiation lengths: "
214 << radiationLengths <<
" \t\t(X0: "
215 << X0 <<
" cm)" << std::endl;
216 LogDebug(
"TrackingMaterialProducer") <<
"Energy loss: "
217 << energyLoss <<
" MeV \t(Xi: "
218 << Xi <<
" MeV/cm)" << std::endl;
219 LogDebug(
"TrackingMaterialProducer") <<
"Track was " << (enter_sensitive ?
"entering " :
"in none ")
220 <<
"sensitive volume" << std::endl;
221 LogDebug(
"TrackingMaterialProducer") <<
"Track was " << (leave_sensitive ?
"leaving " :
"in none ")
222 <<
"sensitive volume" << std::endl;
230 const G4Track * track = (*event)();
231 if (m_primaryTracks and track->GetParentID() != 0)
234 m_tracks->push_back(m_track);
237 LogDebug(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: this track took "
238 << m_track.steps().size()
239 <<
" steps, and passed through "
240 << m_track.detectors().size()
241 <<
" sensitive detectors" << std::endl;
242 LogDebug(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: track length: "
243 << m_track.summary().length()
244 <<
" cm" << std::endl;
245 LogDebug(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: radiation lengths: "
246 << m_track.summary().radiationLengths() << std::endl;
247 LogDebug(
"TrackingMaterialProducer") <<
"TrackingMaterialProducer: energy loss: "
248 << m_track.summary().energyLoss()
249 <<
" MeV" << std::endl;
256 std::auto_ptr<std::vector<MaterialAccountingTrack> >
tracks( m_tracks );
257 iEvent.
put( tracks );
264 for (
size_t i = 0;
i < m_selectedVolumes.size(); ++
i)
265 if (m_selectedVolumes[
i]->IsAncestor( touchable->GetVolume() )
266 or m_selectedVolumes[
i] == touchable->GetVolume()->GetLogicalVolume())
T getParameter(std::string const &) const
#define DEFINE_SIMWATCHER(type)
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::EventIDconst &, edm::Timestampconst & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
void produce(edm::Event &, const edm::EventSetup &)
Global3DPoint GlobalPoint
TrackingMaterialProducer(const edm::ParameterSet &)
static const G4AffineTransform & GetTransform(const G4TouchableHistory *touchable, int depth)
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
boost::tuple< const G4VPhysicalVolume *, int > GetSensitiveVolume(const G4VTouchable *touchable)
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
static const G4LogicalVolume * GetVolume(const std::string &name)
virtual ~TrackingMaterialProducer()
void update(const BeginOfJob *)
This routine will be called when the appropriate signal arrives.
static int position[264][3]
bool isSelected(const G4VTouchable *touch)