Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4TrajectoryDrawerUtils.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27// Jane Tinslay, John Allison, Joseph Perl November 2005
28//
30
31#include "G4AttValue.hh"
32#include "G4Colour.hh"
33#include "G4Polyline.hh"
34#include "G4Polymarker.hh"
35#include "G4UIcommand.hh"
36#include "G4VTrajectory.hh"
37#include "G4VTrajectoryPoint.hh"
39#include "G4VVisManager.hh"
40#include "G4VisAttributes.hh"
41#include "G4VisTrajContext.hh"
42#include "G4VModel.hh"
44
45#include <utility>
46
47#define G4warn G4cout
48
50{
51
57
59 G4Polyline& trajectoryLine, G4Polymarker& auxiliaryPoints,
60 G4Polymarker& stepPoints,
61 std::vector<G4double>& trajectoryLineTimes,
62 std::vector<G4double>& auxiliaryPointTimes,
63 std::vector<G4double>& stepPointTimes)
64{
65 TimesValidity validity = InvalidTimes;
66 if (context.GetTimeSliceInterval()) validity = ValidTimes;
67
68 // Memory for last trajectory point position for auxiliary point
69 // time interpolation algorithm. There are no auxiliary points
70 // for the first trajectory point, so its initial value is
71 // immaterial.
72 G4ThreeVector lastTrajectoryPointPosition;
73
74 // Keep positions. Don't store unless first or different.
75 std::vector<G4ThreeVector> positions;
76
77 for (G4int iPoint = 0; iPoint < traj.GetPointEntries(); iPoint++) {
78 G4VTrajectoryPoint* aTrajectoryPoint = traj.GetPoint(iPoint);
79 const G4ThreeVector& trajectoryPointPosition = aTrajectoryPoint->GetPosition();
80
81 // Only store if first or if different
82 if (positions.size() == 0 || trajectoryPointPosition != positions[positions.size() - 1]) {
83 // Pre- and Post-Point times from the trajectory point...
84 G4double trajectoryPointPreTime = -std::numeric_limits<double>::max();
85 G4double trajectoryPointPostTime = std::numeric_limits<double>::max();
86
87 if (context.GetTimeSliceInterval() && validity == ValidTimes) {
88
89 const auto richTrajectoryPoint = dynamic_cast<G4RichTrajectoryPoint*>(aTrajectoryPoint);
90 if (richTrajectoryPoint) {
91 trajectoryPointPreTime = richTrajectoryPoint->GetPreStepPointGlobalTime();
92 trajectoryPointPostTime = richTrajectoryPoint->GetPostStepPointGlobalTime();
93 if (trajectoryPointPostTime > 1000000. * context.GetTimeSliceInterval()) {
94 static G4bool warnedTimeExceeded = false;
95 if (!warnedTimeExceeded) {
96 G4Exception("G4TrajectoryUtils::GetPointsAndTimes", "modeling0128", JustWarning,
97 "Trajectory point times exceed limit (>1000000 time slice)."
98 "\nNormal trajectory will be drawn.");
99 warnedTimeExceeded = true;
100 }
101 validity = InvalidTimes;
102 }
103 } else {
104 static G4bool warnedNoAttValues = false;
105 if (!warnedNoAttValues) {
106 G4Exception("G4TrajectoryUtils::GetPointsAndTimes", "modeling0127", JustWarning,
107 "Trajectory point times not found. Use G4RichTrajectory:"
108 "\n /vis/scene/add/trajectories rich");
109 warnedNoAttValues = true;
110 }
111 validity = InvalidTimes;
112 }
113 }
114
115 const std::vector<G4ThreeVector>* auxiliaries = aTrajectoryPoint->GetAuxiliaryPoints();
116 if (0 != auxiliaries) {
117 for (size_t iAux = 0; iAux < auxiliaries->size(); ++iAux) {
118 const G4ThreeVector& auxPointPosition = (*auxiliaries)[iAux];
119 if (positions.size() == 0 || auxPointPosition != positions[positions.size() - 1]) {
120 // Only store if first or if different
121 positions.push_back(trajectoryPointPosition);
122 trajectoryLine.push_back(auxPointPosition);
123 auxiliaryPoints.push_back(auxPointPosition);
124 if (validity == ValidTimes) {
125 // Interpolate time for auxiliary points...
126 G4double s1 = (auxPointPosition - lastTrajectoryPointPosition).mag();
127 G4double s2 = (trajectoryPointPosition - auxPointPosition).mag();
128 G4double t = trajectoryPointPreTime
129 + (trajectoryPointPostTime - trajectoryPointPreTime) * (s1 / (s1 + s2));
130 trajectoryLineTimes.push_back(t);
131 auxiliaryPointTimes.push_back(t);
132 }
133 }
134 }
135 }
136
137 positions.push_back(trajectoryPointPosition);
138 trajectoryLine.push_back(trajectoryPointPosition);
139 stepPoints.push_back(trajectoryPointPosition);
140 if (validity == ValidTimes) {
141 trajectoryLineTimes.push_back(trajectoryPointPostTime);
142 stepPointTimes.push_back(trajectoryPointPostTime);
143 }
144 lastTrajectoryPointPosition = trajectoryPointPosition;
145 }
146 }
147 return validity;
148}
149
150static void SliceLine(G4double timeIncrement, G4Polyline& trajectoryLine,
151 std::vector<G4double>& trajectoryLineTimes)
152{
153 // Assumes valid arguments from GetPoints and GetTimes.
154
155 G4Polyline newTrajectoryLine;
156 std::vector<G4double> newTrajectoryLineTimes;
157
158 newTrajectoryLine.push_back(trajectoryLine[0]);
159 newTrajectoryLineTimes.push_back(trajectoryLineTimes[0]);
160 size_t lineSize = trajectoryLine.size();
161 if (lineSize > 1) {
162 for (size_t i = 1; i < trajectoryLine.size(); ++i) {
163 G4double deltaT = trajectoryLineTimes[i] - trajectoryLineTimes[i - 1];
164 if (deltaT > 0.) {
165 G4double practicalTimeIncrement = std::max(timeIncrement, deltaT / 100.);
166 for (G4double t = (int(trajectoryLineTimes[i - 1] / practicalTimeIncrement) + 1)
167 * practicalTimeIncrement;
168 t <= trajectoryLineTimes[i]; t += practicalTimeIncrement)
169 {
170 G4ThreeVector pos = trajectoryLine[i - 1]
171 + (trajectoryLine[i] - trajectoryLine[i - 1])
172 * ((t - trajectoryLineTimes[i - 1]) / deltaT);
173 newTrajectoryLine.push_back(pos);
174 newTrajectoryLineTimes.push_back(t);
175 }
176 }
177 newTrajectoryLine.push_back(trajectoryLine[i]);
178 newTrajectoryLineTimes.push_back(trajectoryLineTimes[i]);
179 }
180 }
181
182 trajectoryLine = std::move(newTrajectoryLine);
183 trajectoryLineTimes = std::move(newTrajectoryLineTimes);
184}
185
186static void DrawWithoutTime(const G4VisTrajContext& myContext, G4Polyline& trajectoryLine,
187 G4Polymarker& auxiliaryPoints, G4Polymarker& stepPoints)
188{
189 // Draw without time slice information
190
191 G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance();
192 if (0 == pVVisManager) return;
193
194 if (myContext.GetDrawLine() && myContext.GetLineVisible()) {
195 G4VisAttributes trajectoryLineAttribs(myContext.GetLineColour());
196 trajectoryLineAttribs.SetLineWidth(myContext.GetLineWidth());
197 trajectoryLine.SetVisAttributes(&trajectoryLineAttribs);
198
199 pVVisManager->Draw(trajectoryLine);
200 }
201
202 if (myContext.GetDrawAuxPts() && myContext.GetAuxPtsVisible() && (auxiliaryPoints.size() > 0)) {
203 auxiliaryPoints.SetMarkerType(myContext.GetAuxPtsType());
204 auxiliaryPoints.SetSize(myContext.GetAuxPtsSizeType(), myContext.GetAuxPtsSize());
205 auxiliaryPoints.SetFillStyle(myContext.GetAuxPtsFillStyle());
206
207 G4VisAttributes auxiliaryPointsAttribs(myContext.GetAuxPtsColour());
208 auxiliaryPoints.SetVisAttributes(&auxiliaryPointsAttribs);
209
210 pVVisManager->Draw(auxiliaryPoints);
211 }
212
213 if (myContext.GetDrawStepPts() && myContext.GetStepPtsVisible() && (stepPoints.size() > 0)) {
214 stepPoints.SetMarkerType(myContext.GetStepPtsType());
215 stepPoints.SetSize(myContext.GetStepPtsSizeType(), myContext.GetStepPtsSize());
216 stepPoints.SetFillStyle(myContext.GetStepPtsFillStyle());
217
218 G4VisAttributes stepPointsAttribs(myContext.GetStepPtsColour());
219 stepPoints.SetVisAttributes(&stepPointsAttribs);
220
221 pVVisManager->Draw(stepPoints);
222 }
223}
224
225static void DrawWithTime(const G4VisTrajContext& myContext, G4Polyline& trajectoryLine,
226 G4Polymarker& auxiliaryPoints, G4Polymarker& stepPoints,
227 std::vector<G4double>& trajectoryLineTimes,
228 std::vector<G4double>& auxiliaryPointTimes,
229 std::vector<G4double>& stepPointTimes)
230{
231 // Draw with time slice information
232
233 G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance();
234 if (0 == pVVisManager) return;
235
236 const auto& timeParameters = G4VModel::GetCurrentModelingParameters()->GetTimeParameters();
237 const auto& viewerStartTime = timeParameters.fStartTime;
238 const auto& viewerEndTime = timeParameters.fEndTime;
239 const auto& viewerFadeFactor = timeParameters.fFadeFactor;
240
241 if (myContext.GetDrawLine() && myContext.GetLineVisible()) {
242 G4VisAttributes trajectoryLineAttribs(myContext.GetLineColour());
243 trajectoryLineAttribs.SetLineWidth(myContext.GetLineWidth());
244
245 for (size_t i = 1; i < trajectoryLine.size(); ++i) {
246 const auto& sliceStartTime = trajectoryLineTimes[i - 1];
247 const auto& sliceEndTime = trajectoryLineTimes[i];
248 if (sliceStartTime >= viewerStartTime && sliceEndTime <= viewerEndTime) {
249 G4Polyline slice;
250 slice.push_back(trajectoryLine[i - 1]);
251 slice.push_back(trajectoryLine[i]);
252 trajectoryLineAttribs.SetStartTime(trajectoryLineTimes[i - 1]);
253 trajectoryLineAttribs.SetEndTime(trajectoryLineTimes[i]);
254 if (viewerStartTime >= 0.) {
255 auto opacityMultiplier = 1. - viewerFadeFactor
256 * (viewerEndTime - trajectoryLineTimes[i]) / (viewerEndTime - viewerStartTime);
257 auto colour = myContext.GetLineColour();
258 colour.SetAlpha(opacityMultiplier * colour.GetAlpha());
259 trajectoryLineAttribs.SetColour(colour);
260 }
261 slice.SetVisAttributes(&trajectoryLineAttribs);
262 pVVisManager->Draw(slice);
263 }
264 }
265 }
266
267 if (myContext.GetDrawAuxPts() && myContext.GetAuxPtsVisible() && (auxiliaryPoints.size() > 0)) {
268 G4VisAttributes auxiliaryPointsAttribs(myContext.GetAuxPtsColour());
269
270 for (size_t i = 0; i < auxiliaryPoints.size(); ++i) {
271 const auto& auxStartTime = auxiliaryPointTimes[i];
272 const auto& auxEndTime = auxiliaryPointTimes[i];
273 if (auxStartTime >= viewerStartTime && auxEndTime <= viewerEndTime) {
274 G4Polymarker point;
275 point.push_back(auxiliaryPoints[i]);
276 point.SetMarkerType(myContext.GetAuxPtsType());
277 point.SetSize(myContext.GetAuxPtsSizeType(), myContext.GetAuxPtsSize());
278 point.SetFillStyle(myContext.GetAuxPtsFillStyle());
279 auxiliaryPointsAttribs.SetStartTime(auxiliaryPointTimes[i]);
280 auxiliaryPointsAttribs.SetEndTime(auxiliaryPointTimes[i]);
281 if (viewerStartTime >= 0.) {
282 auto opacityMultiplier = 1. - viewerFadeFactor
283 * (viewerEndTime - auxiliaryPointTimes[i] ) / (viewerEndTime - viewerStartTime);
284 auto colour = myContext.GetAuxPtsColour();
285 colour.SetAlpha(opacityMultiplier * colour.GetAlpha());
286 auxiliaryPointsAttribs.SetColour(colour);
287 }
288 point.SetVisAttributes(&auxiliaryPointsAttribs);
289 pVVisManager->Draw(point);
290 }
291 }
292 }
293
294 if (myContext.GetDrawStepPts() && myContext.GetStepPtsVisible() && (stepPoints.size() > 0)) {
295 G4VisAttributes stepPointsAttribs(myContext.GetStepPtsColour());
296
297 for (size_t i = 0; i < stepPoints.size(); ++i) {
298 const auto& pointStartTime = stepPointTimes[i];
299 const auto& pointEndTime = stepPointTimes[i];
300 if (pointStartTime >= viewerStartTime && pointEndTime <= viewerEndTime) {
301 G4Polymarker point;
302 point.push_back(stepPoints[i]);
303 point.SetMarkerType(myContext.GetStepPtsType());
304 point.SetSize(myContext.GetStepPtsSizeType(), myContext.GetStepPtsSize());
305 point.SetFillStyle(myContext.GetStepPtsFillStyle());
306 stepPointsAttribs.SetStartTime(stepPointTimes[i]);
307 stepPointsAttribs.SetEndTime(stepPointTimes[i]);
308 if (viewerStartTime >= 0.) {
309 auto opacityMultiplier = 1. - viewerFadeFactor
310 * (viewerEndTime - stepPointTimes[i]) / (viewerEndTime - viewerStartTime);
311 auto colour = myContext.GetStepPtsColour();
312 colour.SetAlpha(opacityMultiplier * colour.GetAlpha());
313 stepPointsAttribs.SetColour(colour);
314 }
315 point.SetVisAttributes(&stepPointsAttribs);
316 pVVisManager->Draw(point);
317 }
318 }
319 }
320}
321
322void DrawLineAndPoints(const G4VTrajectory& traj, const G4VisTrajContext& context)
323{
324 // Return if don't need to do anything
325 if (!context.GetDrawLine() && !context.GetDrawAuxPts() && !context.GetDrawStepPts()) return;
326
327 // Get points and times (times are returned only if time-slicing
328 // is requested).
329 G4Polyline trajectoryLine;
330 G4Polymarker stepPoints;
331 G4Polymarker auxiliaryPoints;
332 std::vector<G4double> trajectoryLineTimes;
333 std::vector<G4double> stepPointTimes;
334 std::vector<G4double> auxiliaryPointTimes;
335
336 TimesValidity validity =
337 GetPointsAndTimes(traj, context, trajectoryLine, auxiliaryPoints, stepPoints,
338 trajectoryLineTimes, auxiliaryPointTimes, stepPointTimes);
339
340 if (validity == ValidTimes) {
341 SliceLine(context.GetTimeSliceInterval(), trajectoryLine, trajectoryLineTimes);
342
343 DrawWithTime(context, trajectoryLine, auxiliaryPoints, stepPoints, trajectoryLineTimes,
344 auxiliaryPointTimes, stepPointTimes);
345 }
346 else {
347 DrawWithoutTime(context, trajectoryLine, auxiliaryPoints, stepPoints);
348 }
349}
350} // namespace G4TrajectoryDrawerUtils
@ JustWarning
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
void SetAlpha(G4double)
Definition G4Colour.cc:53
const TimeParameters & GetTimeParameters() const
void SetMarkerType(MarkerType)
void SetSize(SizeType, G4double)
Definition G4VMarker.cc:86
void SetFillStyle(FillStyle)
static const G4ModelingParameters * GetCurrentModelingParameters()
Definition G4VModel.cc:49
virtual const std::vector< G4ThreeVector > * GetAuxiliaryPoints() const
virtual const G4ThreeVector GetPosition() const =0
virtual G4VTrajectoryPoint * GetPoint(G4int i) const =0
virtual G4int GetPointEntries() const =0
static G4VVisManager * GetConcreteInstance()
virtual void Draw(const G4Circle &, const G4Transform3D &objectTransformation=G4Transform3D())=0
G4bool GetDrawAuxPts() const
G4Colour GetStepPtsColour() const
G4double GetLineWidth() const
G4double GetStepPtsSize() const
G4bool GetLineVisible() const
G4double GetTimeSliceInterval() const
G4bool GetDrawLine() const
G4VMarker::SizeType GetStepPtsSizeType() const
G4Polymarker::MarkerType GetAuxPtsType() const
G4double GetAuxPtsSize() const
G4VMarker::SizeType GetAuxPtsSizeType() const
G4Colour GetAuxPtsColour() const
G4VMarker::FillStyle GetStepPtsFillStyle() const
G4VMarker::FillStyle GetAuxPtsFillStyle() const
G4bool GetAuxPtsVisible() const
G4bool GetStepPtsVisible() const
G4Colour GetLineColour() const
G4Polymarker::MarkerType GetStepPtsType() const
G4bool GetDrawStepPts() const
void SetVisAttributes(const G4VisAttributes *)
Definition G4Visible.cc:108
TimesValidity GetPointsAndTimes(const G4VTrajectory &traj, const G4VisTrajContext &context, G4Polyline &trajectoryLine, G4Polymarker &auxiliaryPoints, G4Polymarker &stepPoints, std::vector< G4double > &trajectoryLineTimes, std::vector< G4double > &auxiliaryPointTimes, std::vector< G4double > &stepPointTimes)
void DrawLineAndPoints(const G4VTrajectory &traj, const G4VisTrajContext &)