Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/dna/management/include/G4ITNavigator1.hh

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /processes/electromagnetic/dna/management/include/G4ITNavigator1.hh (Version 11.3.0) and /processes/electromagnetic/dna/management/include/G4ITNavigator1.hh (Version 10.0.p2)


  1 //                                                  1 
  2 // *******************************************    
  3 // * License and Disclaimer                       
  4 // *                                              
  5 // * The  Geant4 software  is  copyright of th    
  6 // * the Geant4 Collaboration.  It is provided    
  7 // * conditions of the Geant4 Software License    
  8 // * LICENSE and available at  http://cern.ch/    
  9 // * include a list of copyright holders.         
 10 // *                                              
 11 // * Neither the authors of this software syst    
 12 // * institutes,nor the agencies providing fin    
 13 // * work  make  any representation or  warran    
 14 // * regarding  this  software system or assum    
 15 // * use.  Please see the license in the file     
 16 // * for the full disclaimer and the limitatio    
 17 // *                                              
 18 // * This  code  implementation is the result     
 19 // * technical work of the GEANT4 collaboratio    
 20 // * By using,  copying,  modifying or  distri    
 21 // * any work based  on the software)  you  ag    
 22 // * use  in  resulting  scientific  publicati    
 23 // * acceptance of all terms of the Geant4 Sof    
 24 // *******************************************    
 25 //                                                
 26 //                                                
 27 // Original author: Paul Kent, July 95/96         
 28 //                                                
 29 /// \brief { Class description:                   
 30 ///                                               
 31 /// G4ITNavigator1 is a duplicate version of G    
 32 /// initially written by Paul Kent and colleag    
 33 /// The only difference resides in the way the    
 34 ///                                               
 35 /// A class for use by the tracking management    
 36 /// dynamic tracking time information such as     
 37 /// or to find the physical volume containing     
 38 /// reference system. The navigator maintains     
 39 /// other information to optimise the tracking    
 40 //                                                
 41 // Contact : Mathieu Karamitros (kara (AT) cen    
 42 //                                                
 43 // WARNING : This class is released as a proto    
 44 // It might strongly evolve or even disapear i    
 45 //                                                
 46 // We would be very happy hearing from you, se    
 47 //                                                
 48 // History:                                       
 49 // - Created.                                     
 50 // - Zero step protections                        
 51 // - Added check mode                             
 52 // - Made Navigator Abstract                      
 53 // - G4ITNavigator1 created                       
 54 // *******************************************    
 55                                                   
 56 #ifndef G4ITNAVIGATOR_HH                          
 57 #define G4ITNAVIGATOR_HH                          
 58                                                   
 59 #include "geomdefs.hh"                            
 60                                                   
 61 #include "G4ThreeVector.hh"                       
 62 #include "G4AffineTransform.hh"                   
 63 #include "G4RotationMatrix.hh"                    
 64                                                   
 65 #include "G4LogicalVolume.hh"             // U    
 66 #include "G4TouchableHandle.hh"           //      
 67                                                   
 68 #include "G4NavigationHistory.hh"                 
 69 #include "G4NormalNavigation.hh"                  
 70 #include "G4VoxelNavigation.hh"                   
 71 #include "G4ParameterisedNavigation.hh"           
 72 #include "G4ReplicaNavigation.hh"                 
 73 #include "G4RegularNavigation.hh"                 
 74                                                   
 75 #include <iostream>                               
 76                                                   
 77 class G4VPhysicalVolume;                          
 78                                                   
 79                                                   
 80 struct G4ITNavigatorState_Lock1                   
 81 {                                                 
 82     virtual ~G4ITNavigatorState_Lock1()= defau    
 83 protected:                                        
 84     G4ITNavigatorState_Lock1(){}                  
 85 };                                                
 86                                                   
 87 class G4ITNavigator1                              
 88 {                                                 
 89 public:                                           
 90   static const G4int fMaxNav = 8;   // rename     
 91                                                   
 92   public:  // with description                    
 93                                                   
 94   friend std::ostream& operator << (std::ostre    
 95                                                   
 96   G4ITNavigator1();                               
 97     // Constructor - initialisers and setup.      
 98                                                   
 99   virtual ~G4ITNavigator1();                      
100     // Destructor. No actions.                    
101                                                   
102   G4ITNavigator1(const G4ITNavigator1&) = dele    
103   G4ITNavigator1& operator=(const G4ITNavigato    
104                                                   
105   // !>                                           
106     G4ITNavigatorState_Lock1* GetNavigatorStat    
107     void SetNavigatorState(G4ITNavigatorState_    
108     void NewNavigatorState();                     
109   // <!                                           
110                                                   
111   virtual G4double ComputeStep(const G4ThreeVe    
112                                const G4ThreeVe    
113                                const G4double     
114                                      G4double     
115     // Calculate the distance to the next boun    
116     // along the specified NORMALISED vector d    
117     // from the specified point in the global     
118     // system. LocateGlobalPointAndSetup or Lo    
119     // must have been called with the same glo    
120     // The isotropic distance to the nearest b    
121     // calculated (usually an underestimate).     
122     // proposed Step length is used to avoid i    
123     // calculations: if it can be determined t    
124     // boundary is >pCurrentProposedStepLength    
125     // is returned together with the computed     
126     // distance. Geometry must be closed.         
127                                                   
128   G4double CheckNextStep(const G4ThreeVector &    
129                          const G4ThreeVector &    
130                          const G4double pCurre    
131                                G4double &pNewS    
132     // Same as above, but do not disturb the s    
133                                                   
134   virtual                                         
135   G4VPhysicalVolume* ResetHierarchyAndLocate(c    
136                                              c    
137                                              c    
138                                                   
139     // Resets the geometrical hierarchy and se    
140     // in the hierarchy containing the point i    
141     // The direction is used to check if a vol    
142     // The search begin is the geometrical hie    
143     // last located point, or the endpoint of     
144     // SetGeometricallyLimitedStep() has been     
145     //                                            
146     // Important Note: In order to call this t    
147                                                   
148   virtual                                         
149   G4VPhysicalVolume* LocateGlobalPointAndSetup    
150                                              c    
151                                              c    
152                                              c    
153     // Search the geometrical hierarchy for th    
154     // containing the point in the global coor    
155     //  i) If pRelativeSearch=false it makes u    
156     //     information. Returns the physical v    
157     //     with all previous mothers correctly    
158     // ii) If pRelativeSearch is set to true,     
159     //     geometrical hierarchy at the locati    
160     //     or the endpoint of the previous Ste    
161     //     has been called immediately before.    
162     // The direction is used (to check if a vo    
163     //   - the argument ignoreDirection is fal    
164     //   - the Navigator has determined that i    
165     //     more volumes.  (This is state infor    
166     //                                            
167     // Important Note: In order to call this t    
168                                                   
169   virtual                                         
170   void LocateGlobalPointWithinVolume(const G4T    
171     // Notify the Navigator that a track has m    
172     // 'position', that is known to be within     
173     // No check is performed to ensure that it    
174     // This method can be called instead of Lo    
175     // the caller is certain that the new glob    
176     // same volume as the previous position.      
177     // only if the point is within safety.        
178                                                   
179   inline void LocateGlobalPointAndUpdateToucha    
180                 const G4ThreeVector&       pos    
181                 const G4ThreeVector&       dir    
182                       G4TouchableHandle&   old    
183                 const G4bool               Rel    
184     // First, search the geometrical hierarchy    
185     // LocateGlobalPointAndSetup(). Then use t    
186     // navigation history to update the toucha    
187                                                   
188   inline void LocateGlobalPointAndUpdateToucha    
189                 const G4ThreeVector&       pos    
190                 const G4ThreeVector&       dir    
191                       G4VTouchable*        tou    
192                 const G4bool               Rel    
193     // First, search the geometrical hierarchy    
194     // LocateGlobalPointAndSetup(). Then use t    
195     // navigation history to update the toucha    
196                                                   
197   inline void LocateGlobalPointAndUpdateToucha    
198                 const G4ThreeVector&       pos    
199                       G4VTouchable*        tou    
200                 const G4bool               Rel    
201     // Same as the method above but missing di    
202                                                   
203   inline void SetGeometricallyLimitedStep();      
204     // Inform the navigator that the previous     
205     // by the geometry was taken in its entire    
206                                                   
207   virtual G4double ComputeSafety(const G4Three    
208                                  const G4doubl    
209                                  const G4bool     
210     // Calculate the isotropic distance to the    
211     // specified point in the global coordinat    
212     // The globalpoint utilised must be within    
213     // The value returned is usually an undere    
214     // The proposed maximum length is used to     
215     //  calculations.  The geometry must be cl    
216     // To ensure minimum side effects from the    
217     //  must be true.                             
218                                                   
219   inline G4VPhysicalVolume* GetWorldVolume() c    
220     // Return the current  world (`topmost') v    
221                                                   
222   inline void SetWorldVolume(G4VPhysicalVolume    
223     // Set the world (`topmost') volume. This     
224     // origin (0,0,0) and unrotated.              
225                                                   
226   inline G4TouchableHistory* CreateTouchableHi    
227   inline G4TouchableHistory* CreateTouchableHi    
228     // `Touchable' creation methods: caller ha    
229                                                   
230   virtual G4TouchableHandle CreateTouchableHis    
231     // Returns a reference counted handle to a    
232                                                   
233   virtual G4ThreeVector GetLocalExitNormal(G4b    
234   virtual G4ThreeVector GetLocalExitNormalAndC    
235                                                   
236   virtual G4ThreeVector GetGlobalExitNormal(co    
237                                                   
238     // Return Exit Surface Normal and validity    
239     // Can only be called if the Navigator's l    
240     // volume geometrical boundary.               
241     // It returns the Normal to the surface po    
242     // was left behind and/or into the volume     
243     // Convention:                                
244     //   The *local* normal is in the coordina    
245     // Restriction:                               
246     //   Normals are not available for replica    
247     // These methods takes full care about how    
248     // but if the surfaces are not convex it w    
249                                                   
250   inline G4int GetVerboseLevel() const;           
251   inline void  SetVerboseLevel(G4int level);      
252     // Get/Set Verbose(ness) level.               
253     // [if level>0 && G4VERBOSE, printout can     
254                                                   
255   inline G4bool IsActive() const;                 
256     // Verify if the navigator is active.         
257   inline void  Activate(G4bool flag);             
258     // Activate/inactivate the navigator.         
259                                                   
260   inline G4bool EnteredDaughterVolume() const;    
261     // The purpose of this function is to info    
262     // entering a daughter volume while exitin    
263     // This method returns                        
264     // - True only in case 1) above, that is w    
265     //   the track to arrive at a boundary of     
266     // - False in cases 2), 3) and 4), i.e. in    
267     // This function is not guaranteed to work    
268     // was not called when it should have been    
269   inline G4bool ExitedMotherVolume() const;       
270     // Verify if the step has exited the mothe    
271                                                   
272   inline void   CheckMode(G4bool mode);           
273     // Run navigation in "check-mode", therefo    
274     // verifications and more strict correctne    
275     // Is effective only with G4VERBOSE set.      
276   inline G4bool IsCheckModeActive() const;        
277   inline void   SetPushVerbosity(G4bool mode);    
278     // Set/unset verbosity for pushed tracks (    
279                                                   
280   void PrintState() const;                        
281     // Print the internal state of the Navigat    
282     // The level of detail is according to the    
283                                                   
284   inline const G4AffineTransform& GetGlobalToL    
285   inline const G4AffineTransform  GetLocalToGl    
286     // Obtain the transformations Global/Local    
287     // Clients of these methods must copy the     
288                                                   
289   G4AffineTransform GetMotherToDaughterTransfo    
290                                                   
291                                                   
292     // Obtain mother to daughter transformatio    
293                                                   
294   inline void ResetStackAndState();               
295     // Reset stack and minimum or navigator st    
296     // as needed by LocalGlobalPointAndSetup.     
297     // [Does not perform clears, resizes, or r    
298                                                   
299   inline G4int SeverityOfZeroStepping( G4int*     
300     // Report on severity of error and number     
301     // in case Navigator is stuck and is retur    
302     // Values: 1 (small problem),  5 (correcti    
303     //         9 (ready to abandon), 10 (aband    
304                                                   
305   void SetSavedState();                           
306     // ( fValidExitNormal, fExitNormal, fExiti    
307     //   fBlockedPhysicalVolume, fBlockedRepli    
308   void RestoreSavedState();                       
309     // Copy aspects of the state, to enable a     
310     //  call to ComputeStep                       
311                                                   
312   inline G4ThreeVector GetCurrentLocalCoordina    
313     // Return the local coordinate of the poin    
314     // of its containing volume that was found    
315     // The local coordinate of the last locate    
316                                                   
317   inline G4ThreeVector NetTranslation() const;    
318   inline G4RotationMatrix NetRotation() const;    
319     // Compute+return the local->global transl    
320                                                   
321   inline void EnableBestSafety( G4bool value=     
322     // Enable best-possible evaluation of isot    
323                                                   
324   virtual void ResetState();                      
325     // Utility method to reset the navigator s    
326                                                   
327  protected:  // with description                  
328                                                   
329   inline G4ThreeVector ComputeLocalPoint(const    
330     // Return position vector in local coordin    
331     // vector in world coordinate system.         
332                                                   
333   inline G4ThreeVector ComputeLocalAxis(const     
334     // Return the local direction of the speci    
335     // system of the volume that was found by     
336     // The Local Coordinates of point in world    
337                                                   
338   inline EVolume VolumeType(const G4VPhysicalV    
339     // Characterise `type' of volume - normal/    
340                                                   
341   inline EVolume CharacteriseDaughters(const G    
342     // Characterise daughter of logical volume    
343                                                   
344   inline G4int GetDaughtersRegularStructureId(    
345     // Get regular structure ID of first daugh    
346                                                   
347   virtual void SetupHierarchy();                  
348     // Renavigate & reset hierarchy described     
349     // o Reset volumes                            
350     // o Recompute transforms and/or solids of    
351     //   volumes.                                 
352                                                   
353  private:                                         
354                                                   
355   void ComputeStepLog(const G4ThreeVector& pGl    
356                             G4double moveLenSq    
357     // Log and checks for steps larger than th    
358                                                   
359  protected:  // without description               
360                                                   
361   G4double kCarTolerance;                         
362     // Geometrical tolerance for surface thick    
363                                                   
364   //                                              
365   // BEGIN State information                      
366   //                                              
367                                                   
368   G4NavigationHistory fHistory;                   
369     // Transformation and history of the curre    
370     // through the geometrical hierarchy.         
371                                                   
372   G4bool fEnteredDaughter;                        
373     // A memory of whether in this Step a daug    
374     // (set in Compute & Locate).                 
375     //  After Compute: it expects to enter a d    
376     //  After Locate:  it has entered a daught    
377                                                   
378   G4bool fExitedMother;                           
379     // A similar memory whether the Step exite    
380     // completely, not entering daughter.         
381                                                   
382   G4bool fWasLimitedByGeometry{false};            
383     // Set true if last Step was limited by ge    
384                                                   
385   G4ThreeVector fStepEndPoint;                    
386     // Endpoint of last ComputeStep               
387     // can be used for optimisation (e.g. when    
388   G4ThreeVector fLastStepEndPointLocal;           
389     // Position of the end-point of the last c    
390     // in last Local coordinates.                 
391                                                   
392   G4int  fVerbose{0};                             
393     // Verbose(ness) level  [if > 0, printout     
394                                                   
395  private:                                         
396                                                   
397   G4bool fActive;                                 
398     // States if the navigator is activated or    
399                                                   
400   G4bool fLastTriedStepComputation;               
401     // Whether ComputeStep was called since th    
402     // Uses: - distinguish parts of state whic    
403     //         to ComputeStep or one of the Lo    
404     //       - avoid two consecutive calls to     
405                                                   
406   G4bool fEntering,fExiting;                      
407     // Entering/Exiting volumes blocking/setup    
408     // o If exiting                               
409     //      volume ptr & replica number (set &    
410     //      used for blocking on redescent of     
411     // o If entering                              
412     //      volume ptr & replica number (set b    
413     //      Locate..()) of volume for `automat    
414                                                   
415   G4VPhysicalVolume *fBlockedPhysicalVolume;      
416   G4int fBlockedReplicaNo;                        
417                                                   
418   G4ThreeVector fLastLocatedPointLocal;           
419     // Position of the last located point rela    
420   G4bool fLocatedOutsideWorld;                    
421     // Whether the last call to Locate methods    
422                                                   
423   G4bool fValidExitNormal;    // Set true if h    
424   G4ThreeVector fExitNormal;  // Leaving volum    
425                               // volume contai    
426                               // volume's coor    
427   G4ThreeVector fGrandMotherExitNormal;  // Le    
428                                          // ow    
429   G4bool  fChangedGrandMotherRefFrame;   // Wh    
430                                                   
431   G4ThreeVector fExitNormalGlobalFrame;  // Le    
432                                          // gl    
433   G4bool  fCalculatedExitNormal;  // Has it be    
434                                   // the last     
435                                   // Covers bo    
436                                                   
437   // Count zero steps - as one or two can occu    
438   //                    a boundary or at an ed    
439   //                  - several are likely a p    
440   //                    description or in the     
441   //                                              
442   G4bool fLastStepWasZero;                        
443     // Whether the last ComputeStep moved Zero    
444                                                   
445   G4bool fLocatedOnEdge;                          
446     // Whether the Navigator has detected an e    
447   G4int fNumberZeroSteps;                         
448     // Number of preceding moves that were Zer    
449   G4int fActionThreshold_NoZeroSteps;             
450     // After this many failed/zero steps, act     
451   G4int fAbandonThreshold_NoZeroSteps;            
452     // After this many failed/zero steps, aban    
453                                                   
454   G4ThreeVector  fPreviousSftOrigin;              
455   G4double       fPreviousSafety;                 
456     // Memory of last safety origin & value. U    
457     // that origin of current Step is in the s    
458     // last relocation                            
459                                                   
460   //                                              
461   // END State information                        
462   //                                              
463                                                   
464   // Save key state information (NOT the navig    
465   //                                              
466   struct G4SaveNavigatorState : public G4ITNav    
467   {                                               
468      G4SaveNavigatorState();                      
469      ~G4SaveNavigatorState() override= default    
470      G4ThreeVector sExitNormal;                   
471      G4bool sValidExitNormal;                     
472      G4bool sEntering, sExiting;                  
473      G4VPhysicalVolume* spBlockedPhysicalVolum    
474      G4int sBlockedReplicaNo;                     
475      G4int sLastStepWasZero;                      
476                                                   
477      // !>                                        
478      G4bool sLocatedOnEdge;                       
479      G4bool sWasLimitedByGeometry;                
480      G4bool sPushed;                              
481      G4int  sNumberZeroSteps;                     
482      // <!                                        
483                                                   
484      //  Potentially relevant                     
485      //                                           
486      G4bool sLocatedOutsideWorld;                 
487      G4ThreeVector sLastLocatedPointLocal;        
488      G4bool sEnteredDaughter, sExitedMother;      
489      G4ThreeVector  sPreviousSftOrigin;           
490      G4double       sPreviousSafety;              
491   } ;                                             
492                                                   
493   G4SaveNavigatorState* fpSaveState;              
494                                                   
495                                                   
496   // Tracking Invariants                          
497   //                                              
498   G4VPhysicalVolume  *fTopPhysical{nullptr};      
499     // A link to the topmost physical volume i    
500     // Must be positioned at the origin and un    
501                                                   
502   // Utility information                          
503   //                                              
504   G4bool fCheck{false};                           
505     // Check-mode flag  [if true, more strict     
506   G4bool fPushed{false}, fWarnPush{true};         
507     // Push flags  [if true, means a stuck par    
508                                                   
509   // Helpers/Utility classes                      
510   //                                              
511   G4NormalNavigation  fnormalNav;                 
512   G4VoxelNavigation fvoxelNav;                    
513   G4ParameterisedNavigation fparamNav;            
514   G4ReplicaNavigation freplicaNav;                
515   G4RegularNavigation fregularNav;                
516   G4VoxelSafety       *fpVoxelSafety;             
517 };                                                
518                                                   
519 #include "G4ITNavigator1.icc"                     
520                                                   
521 #endif                                            
522                                                   
523                                                   
524 // NOTES:                                         
525 //                                                
526 // The following methods provide detailed info    
527 // arrived at a geometrical boundary.  They di    
528 // causes that can result in the track leaving    
529 //                                                
530 // Four cases are possible:                       
531 //                                                
532 // 1) The particle has reached a boundary of a    
533 //     (this could cause the relocation to ent    
534 //     or a potential granddaughter or further    
535 //                                                
536 // 2) The particle has reached a boundary of t    
537 //     volume, exiting into a mother (regardle    
538 //     at which it is located in the tree):       
539 //                                                
540 // 3) The particle has reached a boundary of t    
541 //     volume, exiting into a volume which is     
542 //     parental hierarchy:                        
543 //                                                
544 // 4) The particle is not on a boundary betwee    
545 //     the function returns an exception, and     
546 //     reccomended to compare the G4touchables    
547 //     to the preStepPoint and postStepPoint t    
548 //                                                
549 //   G4bool        EnteredDaughterVolume()        
550 //   G4bool        IsExitNormalValid()            
551 //   G4ThreeVector GetLocalExitNormal()           
552 //                                                
553 // The expected usefulness of these methods is    
554 // determine how to compute the surface normal    
555 // possibilities are to obtain the normal from    
556 //                                                
557 //   i) the solid associated with the volume o    
558 //      This is valid for cases 2 and 3.          
559 //      (Note that the initial point is genera    
560 //   or                                           
561 //                                                
562 //  ii) the solid of the final point, ie of th    
563 //      This is valid for case 1.                 
564 //      (Note that the final point is generall    
565 //                                                
566 // This way the caller can always get a valid     
567 // the solid for which it is computed, that ca    
568 // discretion.                                    
569