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