BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSAuxiliaryNavigator.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2023.
4
5This file is part of BDSIM.
6
7BDSIM is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published
9by the Free Software Foundation version 3 of the License.
10
11BDSIM is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
18*/
19#include "BDSAuxiliaryNavigator.hh"
20#include "BDSDebug.hh"
21#include "BDSStep.hh"
22#include "BDSUtilities.hh"
23
24#include "G4Navigator.hh"
25#include "G4Step.hh"
26#include "G4StepPoint.hh"
27#include "G4StepStatus.hh"
28#include "G4ThreeVector.hh"
29
30G4Navigator* BDSAuxiliaryNavigator::auxNavigator = new G4Navigator();
31G4Navigator* BDSAuxiliaryNavigator::auxNavigatorCL = new G4Navigator();
32G4Navigator* BDSAuxiliaryNavigator::auxNavigatorCLB = new G4Navigator();
34G4VPhysicalVolume* BDSAuxiliaryNavigator::worldPV = nullptr;
35G4VPhysicalVolume* BDSAuxiliaryNavigator::curvilinearWorldPV = nullptr;
36G4VPhysicalVolume* BDSAuxiliaryNavigator::curvilinearBridgeWorldPV = nullptr;
37
38BDSAuxiliaryNavigator::BDSAuxiliaryNavigator():
39 globalToLocal(G4AffineTransform()),
40 localToGlobal(G4AffineTransform()),
41 globalToLocalCL(G4AffineTransform()),
42 localToGlobalCL(G4AffineTransform()),
43 bridgeVolumeWasUsed(false),
44 volumeMargin(0.1*CLHEP::mm)
45{
46 numberOfInstances++;
47}
48
49BDSAuxiliaryNavigator::~BDSAuxiliaryNavigator()
50{
51 // Only delete static navigator objects when last instance is deleted
52 if (numberOfInstances == 1)
53 {
54 delete auxNavigator; auxNavigator = nullptr;
55 delete auxNavigatorCL; auxNavigatorCL = nullptr;
56 delete auxNavigatorCLB; auxNavigatorCLB = nullptr;
57 }
59}
60
61void BDSAuxiliaryNavigator::ResetNavigatorStates()
62{
63 auxNavigator->ResetStackAndState();
64 auxNavigatorCL->ResetStackAndState();
65 auxNavigatorCLB->ResetStackAndState();
66}
67
68G4VPhysicalVolume* BDSAuxiliaryNavigator::LocateGlobalPointAndSetup(const G4ThreeVector& point,
69 const G4ThreeVector* direction,
70 const G4bool pRelativeSearch,
71 const G4bool ignoreDirection,
72 G4bool useCurvilinear) const
73{
74 bridgeVolumeWasUsed = false; // reset flag
75 G4Navigator* nav = Navigator(useCurvilinear);
76 auto selectedVol = nav->LocateGlobalPointAndSetup(point, direction,
77 pRelativeSearch, ignoreDirection);
78
79#ifdef BDSDEBUGNAV
80 G4cout << "Point lookup " << selectedVol->GetName() << G4endl;
81#endif
82
83 // check if we accidentally fell between the gaps and found the world volume
84 if (useCurvilinear && selectedVol == curvilinearWorldPV)
85 {// try the bridge world next
86#ifdef BDSDEBUGNAV
87 G4cout << "Trying bridge world" << G4endl;
88#endif
89 bridgeVolumeWasUsed = true;
90 selectedVol = auxNavigatorCLB->LocateGlobalPointAndSetup(point, direction,
91 pRelativeSearch, ignoreDirection);
92 // if we find a non-world volume, then good. if we find the world volume even
93 // of the bridge world, it must really lie outside the curvilinear volumes
94 // eitherway, we return that volume.
95#ifdef BDSDEBUGNAV
96 G4cout << "Found " << selectedVol->GetName() << G4endl;
97#endif
98 return selectedVol;
99 }
100 else if (selectedVol == worldPV)
101 {// try searching a little further along the step
102 if (!direction) // no direction, so can't search
103 {return selectedVol;}
104 G4ThreeVector globalDirUnit = direction->unit();
105 G4ThreeVector newPosition = point + volumeMargin*globalDirUnit;
106 selectedVol = nav->LocateGlobalPointAndSetup(newPosition, direction,
107 pRelativeSearch, ignoreDirection);
108#ifdef BDSDEBUGNAV
109 G4cout << __METHOD_NAME__ << "New selected volume is: " << selectedVol->GetName() << G4endl;
110#endif
111 return selectedVol;
112 }
113 else
114 {return selectedVol;}
115}
116
117G4VPhysicalVolume* BDSAuxiliaryNavigator::LocateGlobalPointAndSetup(G4Step const* const step,
118 G4bool useCurvilinear) const
119{ // const pointer to const G4Step
120 // 'pos' = post but has same length as pre so code looks better
121 G4StepPoint* preStepPoint = step->GetPreStepPoint();
122 G4StepPoint* posStepPoint = step->GetPostStepPoint();
123
124 // average the points - the mid point should always lie inside the volume given
125 // the way G4 does tracking.
126 G4ThreeVector prePosition = preStepPoint->GetPosition();
127 G4ThreeVector postPosition = posStepPoint->GetPosition();
128 G4ThreeVector position = (postPosition + prePosition)/2.0;
129 G4ThreeVector globalDirUnit = (postPosition - prePosition).unit();
130
131 G4Navigator* nav = Navigator(useCurvilinear); // select navigator
132 G4VPhysicalVolume* selectedVol = nav->LocateGlobalPointAndSetup(position, &globalDirUnit);
133 bridgeVolumeWasUsed = false; // reset flag
134#ifdef BDSDEBUGNAV
135 G4cout << __METHOD_NAME__ << selectedVol->GetName() << G4endl;
136#endif
137 // check if we accidentally fell between the gaps and found the world volume
138 if (useCurvilinear && selectedVol == curvilinearWorldPV)
139 {// try the bridge world next
140#ifdef BDSDEBUGNAV
141 G4cout << "Trying bridge world" << G4endl;
142#endif
143 bridgeVolumeWasUsed = true;
144 selectedVol = auxNavigatorCLB->LocateGlobalPointAndSetup(position, &globalDirUnit);
145 // if we find a non-world volume, then good. if we find the world volume even
146 // of the bridge world, it must really lie outside the curvilinear volumes
147 // eitherway, we return that volume.
148#ifdef BDSDEBUGNAV
149 G4cout << "Found " << selectedVol->GetName() << G4endl;
150#endif
151 return selectedVol;
152 }
153 else if (selectedVol == worldPV)
154 {// try searching a little further along the step from the pre-step point
155 G4ThreeVector newPosition = position + volumeMargin*globalDirUnit;
156 selectedVol = nav->LocateGlobalPointAndSetup(position, &globalDirUnit);
157#ifdef BDSDEBUGNAV
158 G4cout << __METHOD_NAME__ << "New selected volume is: " << selectedVol->GetName() << G4endl;
159#endif
160 return selectedVol;
161 }
162 else
163 {return selectedVol;}
164}
165
167 G4bool useCurvilinear) const
168{
169 auto selectedVol = LocateGlobalPointAndSetup(step, useCurvilinear);
170
171#ifdef BDSDEBUGNAV
172 G4cout << __METHOD_NAME__ << selectedVol->GetName() << G4endl;
173#endif
174
175 useCurvilinear ? InitialiseTransform(false, true) : InitialiseTransform(true, false);
176
177 G4ThreeVector pre = GlobalToLocal(useCurvilinear).TransformPoint(step->GetPreStepPoint()->GetPosition());
178 G4ThreeVector pos = GlobalToLocal(useCurvilinear).TransformPoint(step->GetPostStepPoint()->GetPosition());
179 return BDSStep(pre, pos, selectedVol);
180}
181
182BDSStep BDSAuxiliaryNavigator::ConvertToLocal(const G4ThreeVector& globalPosition,
183 const G4ThreeVector& globalDirection,
184 const G4double stepLength,
185 const G4bool useCurvilinear,
186 const G4double marginLength) const
187{
188 G4ThreeVector point = globalPosition;
189 // protect against boundary problems - use step length to sample into volume
190 // however, sometimes the step length is stupidly long and the mid point may
191 // lie outside the volume. Geant does this to evaluate the maximum length it
192 // could take before breaking the tracking accuracy / bending limits even
193 // though it clearly may leave the volume. Invoke a bit of knowledge about the
194 // scale of the problem and sample only 1mm along.
195 G4ThreeVector globalDirUnit = globalDirection.unit();
196 if (stepLength > 1*CLHEP::mm) // too long - may go outside typical geometry length
197 {point += globalDirUnit * marginLength;}
198 else if (stepLength > 0) // must be a shorter length, obey it
199 {point += globalDirUnit * (stepLength * 0.5);}
200 // else pass: point = globalPosition
201
202 auto selectedVol = LocateGlobalPointAndSetup(point,
203 &globalDirection,
204 true, // relative search
205 false, // don't ignore direction, ie use it
206 useCurvilinear);
207#ifdef BDSDEBUGNAV
208 G4cout << __METHOD_NAME__ << selectedVol->GetName() << G4endl;
209#endif
210
211 useCurvilinear ? InitialiseTransform(false, true) : InitialiseTransform(true, false);
212 const G4AffineTransform& aff = GlobalToLocal(useCurvilinear);
213 G4ThreeVector localPos = aff.TransformPoint(globalPosition);
214 G4ThreeVector localDir = aff.TransformAxis(globalDirection);
215 return BDSStep(localPos, localDir, selectedVol);
216}
217
218G4ThreeVector BDSAuxiliaryNavigator::ConvertToLocal(const G4double globalPosition[3],
219 const G4bool useCurvilinear) const
220{
221 G4ThreeVector globalPositionV(globalPosition[0], globalPosition[1], globalPosition[2]);
222 return ConvertToLocal(globalPositionV, useCurvilinear);
223}
224
225G4ThreeVector BDSAuxiliaryNavigator::ConvertToLocal(const G4ThreeVector& globalPosition,
226 const G4bool useCurvilinear) const
227{
228 InitialiseTransform(globalPosition);
229 return GlobalToLocal(useCurvilinear).TransformPoint(globalPosition);
230}
231
232G4ThreeVector BDSAuxiliaryNavigator::ConvertToLocalNoSetup(const G4ThreeVector& globalPosition,
233 G4bool useCurvilinear) const
234{
235 return GlobalToLocal(useCurvilinear).TransformPoint(globalPosition);
236}
237
238G4ThreeVector BDSAuxiliaryNavigator::ConvertAxisToLocal(const G4ThreeVector& globalAxis,
239 const G4bool useCurvilinear) const
240{
241 return GlobalToLocal(useCurvilinear).TransformAxis(globalAxis);
242}
243
244G4ThreeVector BDSAuxiliaryNavigator::ConvertAxisToLocal(const G4double globalPosition[3],
245 const G4double globalAxis[3],
246 const G4bool useCurvilinear) const
247{
248 G4ThreeVector globalPositionV(globalPosition[0], globalPosition[1], globalPosition[2]);
249 G4ThreeVector globalAxisV(globalAxis[0], globalAxis[1], globalAxis[2]);
250 return ConvertAxisToLocal(globalPositionV, globalAxisV, useCurvilinear);
251}
252
253G4ThreeVector BDSAuxiliaryNavigator::ConvertAxisToLocal(const G4ThreeVector& globalPosition,
254 const G4ThreeVector& globalAxis,
255 const G4bool useCurvilinear) const
256{
257 InitialiseTransform(globalPosition);
258 return GlobalToLocal(useCurvilinear).TransformAxis(globalAxis);
259}
260
261G4ThreeVector BDSAuxiliaryNavigator::ConvertAxisToGlobal(const G4ThreeVector& localAxis,
262 const G4bool useCurvilinear) const
263{return LocalToGlobal(useCurvilinear).TransformAxis(localAxis);}
264
265std::pair<G4ThreeVector, G4ThreeVector> BDSAuxiliaryNavigator::ConvertAxisToGlobal(const std::pair<G4ThreeVector, G4ThreeVector>& localAxis,
266 const G4bool useCurvilinear) const
267{
268 const G4AffineTransform& lToG = LocalToGlobal(useCurvilinear);
269 G4ThreeVector globalB = lToG.TransformAxis(localAxis.first);
270 G4ThreeVector globalE = lToG.TransformAxis(localAxis.second);
271 return std::make_pair(globalB, globalE);
272}
273
274G4ThreeVector BDSAuxiliaryNavigator::ConvertToGlobal(const G4ThreeVector& localPosition,
275 const G4bool useCurvilinear) const
276{return LocalToGlobal(useCurvilinear).TransformPoint(localPosition);}
277
278G4ThreeVector BDSAuxiliaryNavigator::ConvertAxisToGlobal(const G4ThreeVector& globalPosition,
279 const G4ThreeVector& localAxis,
280 const G4bool useCurvilinear) const
281{
282 InitialiseTransform(globalPosition);
283 return LocalToGlobal(useCurvilinear).TransformAxis(localAxis);
284}
285
286BDSStep BDSAuxiliaryNavigator::ConvertToGlobalStep(const G4ThreeVector& localPosition,
287 const G4ThreeVector& localDirection,
288 const G4bool useCurvilinear) const
289{
290 const G4AffineTransform& aff = LocalToGlobal(useCurvilinear);
291 G4ThreeVector globalPos = aff.TransformPoint(localPosition);
292 G4ThreeVector globalDir = aff.TransformAxis(localDirection);
293 return BDSStep(globalPos, globalDir);
294}
295
296G4ThreeVector BDSAuxiliaryNavigator::ConvertToGlobal(const G4ThreeVector& globalPosition,
297 const G4ThreeVector& localPosition,
298 const G4bool useCurvilinear) const
299{
300 InitialiseTransform(globalPosition);
301 return LocalToGlobal(useCurvilinear).TransformPoint(localPosition);
302}
303
304BDSStep BDSAuxiliaryNavigator::GlobalToCurvilinear(const G4ThreeVector& position,
305 const G4ThreeVector& unitMomentum,
306 const G4double h,
307 const G4bool useCurvilinearWorld)
308{
309 return ConvertToLocal(position, unitMomentum, h, useCurvilinearWorld);
310}
311
313 const G4ThreeVector& unitField,
314 const G4double angle,
315 const G4ThreeVector& position,
316 const G4ThreeVector& unitMomentum,
317 const G4double h,
318 const G4bool useCurvilinearWorld,
319 const G4double FCof,
320 const G4double tilt)
321{
322 G4double radiusOfCurvature = fieldArcLength / angle;
323 G4double radiusAtChord = radiusOfCurvature * std::cos(angle*0.5);
324
325 BDSStep local = ConvertToLocal(position, unitMomentum, h, useCurvilinearWorld);
326
327 if (BDS::IsFinite(tilt))
328 {local = local.rotateZ(-tilt);}
329
330 // Test on finite angle here. If the angle is 0, there is no need for a further transform.
331 if (!BDS::IsFinite(angle))
332 {return local;}
333
334 G4ThreeVector localPos = local.PreStepPoint();
335 G4ThreeVector localMom = local.PostStepPoint();
336 G4double localZ = localPos.z();
337
338 // Here we always assume the field is along local unit Y.
339 //G4ThreeVector localUnitF = ConvertAxisToLocal(unitField, useCurvilinearWorld);
340 G4ThreeVector localUnitF = unitField;
341
342 // only find angle between particle and radiusAtChord in x-z plane,
343 // conversion to CL shouldn't affect y co-ordinate but finite y co-ord would affect angle
344 // generalise to 3D - take projection of local position (in frame of solid) onto plane
345 // defined by the unit field vector as a normal on the origin. We take the projection
346 // onto the normal of the plane (here the field field unit vector in local solid coordinates)
347 // - the 'rejection', and then take the point - that projection to get the projection on the plane.
348 //G4ThreeVector localPosProjOnBendPlane = localPos - localPos.project(localUnitF);
349 // we want a vector pointing from the origin of the solid to the point of bending.
350 // the direction of the bending radius is given by the cross product of the field
351 // (unit) with local unit Z - giving a unit direction. Multiplied by radius length.
352 //G4ThreeVector arcCentre = unitField.cross(G4ThreeVector(0,0,1))*-radiusAtChord;
353 //G4ThreeVector partVectToCentre = arcCentre - localPosProjOnBendPlane;
354 //G4double partToCentreDist = partVectToCentre.mag();
355
356 // only find angle between particle and radiusAtChord in x-z plane,
357 // conversion to CL shouldn't affect y co-ordinate but finite y co-ord would affect angle
358 G4ThreeVector localXZPos = G4ThreeVector(localPos.x(), 0, localPos.z());
359 G4ThreeVector arcCentre = G4ThreeVector(-1*radiusAtChord,0,0);
360 G4ThreeVector partVectToCentre = arcCentre - localXZPos;
361 G4double partToCentreDist = partVectToCentre.mag();
362
363 // angle along reference path, from -angle/2 to +angle/2
364 G4double theta = std::acos(partVectToCentre.dot(arcCentre) / (arcCentre.mag() * partToCentreDist));
365
366 // theta should be negative for first 'half' of dipole
367 if (localZ < 0)
368 {theta *= -1;}
369
370 // vector from origin to CL arc centre depends on sign of dipole angle
371 G4double sign = (angle < 0)? -1:1;
372
373 G4double CLXOffset = sign*partToCentreDist - radiusOfCurvature;
374 G4double distAlongS = theta * sign * radiusOfCurvature;
375
376 // normalise momentum rotation to sign particle charge
377 G4double chargeSign = 0;
378 chargeSign = (FCof < 0)? -1: 1;
379
380 G4double rotationAngle = theta*chargeSign;
381
382 G4ThreeVector localMomCL = localMom.rotate(rotationAngle, localUnitF);
383 G4ThreeVector localPosCL = G4ThreeVector(CLXOffset, localPos.y(), distAlongS);
384
385 return BDSStep(localPosCL, localMomCL);
386}
387
388BDSStep BDSAuxiliaryNavigator::CurvilinearToGlobal(const G4ThreeVector& localPosition,
389 const G4ThreeVector& localMomentum,
390 const G4bool useCurvilinearWorld)
391{
392 return ConvertToGlobalStep(localPosition, localMomentum, useCurvilinearWorld);
393}
394
395BDSStep BDSAuxiliaryNavigator::CurvilinearToGlobal(const G4double fieldArcLength,
396 const G4ThreeVector& unitField,
397 const G4double angle,
398 const G4ThreeVector& CLPositionIn,
399 const G4ThreeVector& CLMomentumIn,
400 const G4bool useCurvilinearWorld,
401 const G4double FCof,
402 const G4double tilt)
403{
404 G4double radiusOfCurvature = fieldArcLength / angle;
405 G4double radiusAtChord = radiusOfCurvature * std::cos(angle*0.5);
406
407 // copy inputs so they can be rotated if tilted
408 G4ThreeVector CLPosition = CLPositionIn;
409 G4ThreeVector CLMomentum = CLMomentumIn;
410
411 // Test on finite angle here. If the angle is 0, return convert to global transform.
412 if (!BDS::IsFinite(angle))
413 {
414 if (BDS::IsFinite(tilt))
415 {
416 CLPosition = CLPosition.rotateZ(tilt);
417 CLMomentum = CLMomentum.rotateZ(tilt);
418 }
419 return ConvertToGlobalStep(CLPosition, CLMomentum, useCurvilinearWorld);
420 }
421
422 G4double sign = (angle < 0)? 1:-1;
423 //G4ThreeVector localUnitF = ConvertAxisToLocal(unitField, useCurvilinearWorld);
424 G4ThreeVector localUnitF = unitField;
425 G4ThreeVector arcCentre = G4ThreeVector(sign*radiusAtChord,0,0);
426
427 G4double theta = CLPosition.z() / radiusOfCurvature;
428
429 G4double partToCentreDist = CLPosition.x() + radiusOfCurvature;
430 G4double localZ = partToCentreDist * std::sin(theta);
431 G4double localX = (partToCentreDist * std::cos(theta)) - radiusAtChord;
432
433 // normalise momentum rotation to sign of particle charge
434 G4double chargeSign = 0;
435 chargeSign = (FCof < 0)? -1: 1;
436
437 // rotation angle should be negative for second 'half' of dipole
438 G4double rotationAngle = std::abs(theta)*chargeSign;
439 if (localZ > 0)
440 {rotationAngle *= -1;}
441
442 G4ThreeVector localPosition = G4ThreeVector(localX, CLPosition.y(), localZ);
443 G4ThreeVector localMomentum = G4ThreeVector(CLMomentum).rotate(rotationAngle, localUnitF);;
444
445 if (BDS::IsFinite(tilt))
446 {
447 localPosition = localPosition.rotateZ(tilt);
448 localMomentum = localMomentum.rotateZ(tilt);
449 }
450
451 return ConvertToGlobalStep(localPosition, localMomentum, useCurvilinearWorld);
452}
453
454G4Navigator* BDSAuxiliaryNavigator::Navigator(G4bool curvilinear) const
455{
456 // condition ? case true : case false
457 return curvilinear ? auxNavigatorCL : auxNavigator;
458}
459
460const G4AffineTransform& BDSAuxiliaryNavigator::GlobalToLocal(G4bool curvilinear) const
461{
462 return curvilinear ? globalToLocalCL : globalToLocal;
463}
464
465const G4AffineTransform& BDSAuxiliaryNavigator::LocalToGlobal(G4bool curvilinear) const
466{
467 return curvilinear ? localToGlobalCL : localToGlobal;
468}
469
470void BDSAuxiliaryNavigator::InitialiseTransform(const G4bool massWorld,
471 const G4bool curvilinearWorld) const
472{
473 if (massWorld)
474 {
475 globalToLocal = auxNavigator->GetGlobalToLocalTransform();
476 localToGlobal = auxNavigator->GetLocalToGlobalTransform();
477 }
478 if (curvilinearWorld)
479 {
480 if (bridgeVolumeWasUsed)
481 {
482 globalToLocalCL = auxNavigatorCLB->GetGlobalToLocalTransform();
483 localToGlobalCL = auxNavigatorCLB->GetLocalToGlobalTransform();
484 }
485 else
486 {
487 globalToLocalCL = auxNavigatorCL->GetGlobalToLocalTransform();
488 localToGlobalCL = auxNavigatorCL->GetLocalToGlobalTransform();
489 }
490 }
491}
492
493void BDSAuxiliaryNavigator::InitialiseTransform(const G4ThreeVector& globalPosition) const
494{
495 auxNavigator->LocateGlobalPointAndSetup(globalPosition);
496 auxNavigatorCL->LocateGlobalPointAndSetup(globalPosition);
497 globalToLocal = auxNavigator->GetGlobalToLocalTransform();
498 localToGlobal = auxNavigator->GetLocalToGlobalTransform();
499 globalToLocalCL = auxNavigatorCL->GetGlobalToLocalTransform();
500 localToGlobalCL = auxNavigatorCL->GetLocalToGlobalTransform();
501}
502
503void BDSAuxiliaryNavigator::InitialiseTransform(const G4ThreeVector &globalPosition,
504 const G4ThreeVector &globalMomentum,
505 const G4double stepLength)
506{
507 G4ThreeVector endPoint = globalPosition + globalMomentum.unit()*stepLength;
508 G4ThreeVector midPoint = (endPoint + globalPosition) / 2;
509 InitialiseTransform(midPoint);
510}
G4ThreeVector ConvertToGlobal(const G4ThreeVector &localPosition, const G4bool useCurvilinear=true) const
static G4VPhysicalVolume * curvilinearBridgeWorldPV
Cache of world PV to test if we're getting the wrong volume for the transform.
G4VPhysicalVolume * LocateGlobalPointAndSetup(const G4ThreeVector &point, const G4ThreeVector *direction=nullptr, const G4bool pRelativeSearch=true, const G4bool ignoreDirection=true, G4bool useCurvilinear=true) const
A wrapper for the underlying static navigator instance located within this class.
BDSStep GlobalToCurvilinear(const G4double fieldArcLength, const G4ThreeVector &unitField, const G4double angle, const G4ThreeVector &position, const G4ThreeVector &unitMomentum, const G4double h, const G4bool useCurvilinearWorld, const G4double FCof, const G4double tilt=0)
G4Navigator * Navigator(G4bool curvilinear) const
Utility function to select appropriate navigator.
static G4VPhysicalVolume * worldPV
Cache of world PV to test if we're getting the wrong volume for the transform.
G4ThreeVector ConvertAxisToLocal(const G4ThreeVector &globalAxis, const G4bool useCurvilinear=true) const
BDSStep ConvertToGlobalStep(const G4ThreeVector &localPosition, const G4ThreeVector &localDirection, const G4bool useCurvilinear=true) const
static G4Navigator * auxNavigator
G4ThreeVector ConvertToLocalNoSetup(const G4ThreeVector &globalPosition, const G4bool useCurvilinear=true) const
Similar to above function but does NOT initialise the transforms.
G4ThreeVector ConvertAxisToGlobal(const G4ThreeVector &localAxis, const G4bool useCurvilinear=true) const
static G4Navigator * auxNavigatorCLB
static G4Navigator * auxNavigatorCL
const G4AffineTransform & LocalToGlobal(G4bool curvilinear) const
Utility function to select appropriate transform.
static G4VPhysicalVolume * curvilinearWorldPV
Cache of world PV to test if we're getting the wrong volume for the transform.
BDSStep ConvertToLocal(G4Step const *const step, G4bool useCurvilinear=true) const
const G4AffineTransform & GlobalToLocal(G4bool curvilinear) const
Utility function to select appropriate transform.
A simple class to represent the positions of a step.
Definition: BDSStep.hh:33
G4ThreeVector PostStepPoint() const
Accessor.
Definition: BDSStep.hh:43
BDSStep rotateZ(const G4double &angle)
Mirror function to G4ThreeVector::rotateZ(). Returns copy that's rotated.
Definition: BDSStep.cc:39
G4ThreeVector PreStepPoint() const
Accessor.
Definition: BDSStep.hh:42
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())