private double _thetaConvOrDiv; //convergence:positive, divergence:negative, collimated:zero;

        /// <summary>
        /// Returns an instance of directional (diverging/converging/collimated) Rectangular Source with specified length and width,
        /// source profile (Flat/Gaussian), polar and azimuthal angle range, new source axis direction, translation, and  inward normal ray rotation
        /// </summary>
        /// <param name="thetaConvOrDiv">Covergence or Divergance Angle {= 0, for a collimated beam}</param>
        /// <param name="rectLengthX">The length of the Rectangular Source</param>
        /// <param name="rectWidthY">The width of the Rectangular Source</param>
        /// <param name="sourceProfile">Source Profile {Flat / Gaussian}</param>
        /// <param name="newDirectionOfPrincipalSourceAxis">New source axis direction</param>
        /// <param name="translationFromOrigin">New source location</param>
        /// <param name="beamRotationFromInwardNormal">Polar Azimuthal Rotational Angle of inward Normal</param>
        /// <param name="initialTissueRegionIndex">Initial tissue region index</param>
        public DirectionalRectangularSource(
            double thetaConvOrDiv,
            double rectLengthX,
            double rectWidthY,
            ISourceProfile sourceProfile,
            Direction newDirectionOfPrincipalSourceAxis = null,
            Position translationFromOrigin = null,
            PolarAzimuthalAngles beamRotationFromInwardNormal = null,
            int initialTissueRegionIndex = 0)
            : base(
                rectLengthX,
                rectWidthY,
                sourceProfile,
                newDirectionOfPrincipalSourceAxis,
                translationFromOrigin,
                beamRotationFromInwardNormal,
                initialTissueRegionIndex)
        {
            _thetaConvOrDiv = thetaConvOrDiv;
            if (newDirectionOfPrincipalSourceAxis == null)
            {
                newDirectionOfPrincipalSourceAxis = SourceDefaults.DefaultDirectionOfPrincipalSourceAxis.Clone();
            }
            if (translationFromOrigin == null)
            {
                translationFromOrigin = SourceDefaults.DefaultPosition.Clone();
            }
            if (beamRotationFromInwardNormal == null)
            {
                beamRotationFromInwardNormal = SourceDefaults.DefaultBeamRoationFromInwardNormal.Clone();
            }
        }
Beispiel #2
0
        /// <summary>
        /// Read text data file that has input and output data
        /// </summary>
        public void read_data()
        {
            string testpara = "../../../../matlab/test/monte_carlo/source_test_data_generation/UnitTests_LineSources.txt";

            if (File.Exists(testpara))
            {
                using (TextReader reader = File.OpenText(testpara))
                {
                    string   text = reader.ReadToEnd();
                    string[] bits = text.Split('\t');
                    for (int i = 0; i < 54; i++)
                    {
                        _tp[i] = double.Parse(bits[i]);
                    }
                    reader.Close();
                }
            }
            _position    = new Position(_tp[0], _tp[1], _tp[2]);
            _direction   = new Direction(_tp[3], _tp[4], _tp[5]);
            _translation = new Position(_tp[6], _tp[7], _tp[8]);
            _angPair     = new PolarAzimuthalAngles(_tp[9], _tp[10]);
            _polRange    = new DoubleRange(_tp[11], _tp[12]);
            _aziRange    = new DoubleRange(_tp[13], _tp[14]);
            _lengthX     = _tp[15];
            _bdFWHM      = _tp[16];
            _polarAngle  = _tp[17];
        }
        /// <summary>
        /// Implements Get next photon
        /// </summary>
        /// <param name="tissue">tissue</param>
        /// <returns>photon</returns>
        public Photon GetNextPhoton(ITissue tissue)
        {
            // sample angular distribution
            Direction finalDirection = SourceToolbox.GetDirectionForGivenPolarAzimuthalAngleRangeRandom(_polarAngleRangeToDefineSphericalSurface, _azimuthalAngleRangeToDefineSphericalSurface, Rng);

            //Source starts from anywhere in the sphere
            Position finalPosition = GetFinalPositionFromProfileType(finalDirection, _radius, Rng);

            //Lambertian distribution (uniform hemispherical distribution)
            PolarAzimuthalAngles polarAzimuthalPair = SourceToolbox.GetPolarAzimuthalPairForGivenAngleRangeRandom(
                SourceDefaults.DefaultHalfPolarAngleRange.Clone(),
                SourceDefaults.DefaultAzimuthalAngleRange.Clone(),
                Rng);

            //Avoid updating the finalDirection during following rotation
            Position dummyPosition = finalPosition;

            //Rotate polar azimutahl angle by polarAzimuthalPair vector
            SourceToolbox.UpdateDirectionPositionAfterRotatingByGivenAnglePair(polarAzimuthalPair, ref finalDirection, ref dummyPosition);

            //Find the relevent polar and azimuthal pair for the direction
            PolarAzimuthalAngles _rotationalAnglesOfPrincipalSourceAxis = SourceToolbox.GetPolarAzimuthalPairFromDirection(_newDirectionOfPrincipalSourceAxis);

            //Translation and source rotation
            SourceToolbox.UpdateDirectionPositionAfterGivenFlags(
                ref finalPosition,
                ref finalDirection,
                _rotationalAnglesOfPrincipalSourceAxis,
                _translationFromOrigin,
                _rotationAndTranslationFlags);

            var photon = new Photon(finalPosition, finalDirection, 1.0, tissue, _initialTissueRegionIndex, Rng);

            return(photon);
        }
 /// <summary>
 /// Returns an instance of Custom Rectangular Source with specified length and width, source profile (Flat/Gaussian),
 /// polar and azimuthal angle range, translation, inward normal rotation, and source axis rotation
 /// </summary>
 /// <param name="rectLengthX">The length of the Rectangular Source</param>
 /// <param name="rectWidthY">The width of the Rectangular Source</param>
 /// <param name="sourceProfile">Source Profile {Flat / Gaussian}</param>
 /// <param name="polarAngleEmissionRange">Polar angle emission range</param>
 /// <param name="azimuthalAngleEmissionRange">Azimuthal angle emission range</param>
 /// <param name="newDirectionOfPrincipalSourceAxis">New source axis direction</param>
 /// <param name="translationFromOrigin">New source location</param>
 /// <param name="beamRotationFromInwardNormal">Polar Azimuthal Rotational Angle of inward Normal</param>
 /// <param name="initialTissueRegionIndex">Initial tissue region index</param>
 public CustomRectangularSource(
     double rectLengthX,
     double rectWidthY,
     ISourceProfile sourceProfile,
     DoubleRange polarAngleEmissionRange,
     DoubleRange azimuthalAngleEmissionRange,
     Direction newDirectionOfPrincipalSourceAxis = null,
     Position translationFromOrigin = null,
     PolarAzimuthalAngles beamRotationFromInwardNormal = null,
     int initialTissueRegionIndex = 0)
     : base(
         rectLengthX,
         rectWidthY,
         sourceProfile,
         newDirectionOfPrincipalSourceAxis,
         translationFromOrigin,
         beamRotationFromInwardNormal,
         initialTissueRegionIndex)
 {
     _polarAngleEmissionRange     = polarAngleEmissionRange.Clone();
     _azimuthalAngleEmissionRange = azimuthalAngleEmissionRange.Clone();
     if (newDirectionOfPrincipalSourceAxis == null)
     {
         newDirectionOfPrincipalSourceAxis = SourceDefaults.DefaultDirectionOfPrincipalSourceAxis.Clone();
     }
     if (translationFromOrigin == null)
     {
         translationFromOrigin = SourceDefaults.DefaultPosition.Clone();
     }
     if (beamRotationFromInwardNormal == null)
     {
         beamRotationFromInwardNormal = SourceDefaults.DefaultBeamRoationFromInwardNormal.Clone();
     }
 }
Beispiel #5
0
        /// <summary>
        /// Implements Get next photon
        /// </summary>
        /// <param name="tissue">tissue</param>
        /// <returns>photon</returns>
        public Photon GetNextPhoton(ITissue tissue)
        {
            //Source starts at the origin
            Position finalPosition = SourceDefaults.DefaultPosition.Clone();

            // sample angular distribution
            Direction finalDirection = SourceToolbox.GetDirectionForGivenPolarAzimuthalAngleRangeRandom(
                _polarAngleEmissionRange,
                _azimuthalAngleEmissionRange,
                Rng);

            //Find the relevent polar and azimuthal pair for the direction
            _rotationalAnglesOfPrincipalSourceAxis = SourceToolbox.GetPolarAzimuthalPairFromDirection(_direction);

            //Rotation and translation
            SourceToolbox.UpdateDirectionPositionAfterGivenFlags(
                ref finalPosition,
                ref finalDirection,
                _rotationalAnglesOfPrincipalSourceAxis,
                _pointLocation,
                _rotationAndTranslationFlags);

            var photon = new Photon(finalPosition, finalDirection, 1.0, tissue, _initialTissueRegionIndex, Rng);

            return(photon);
        }
Beispiel #6
0
        /// <summary>
        /// Defines LineSourceBase class
        /// </summary>
        /// <param name="lineLength">The length of the line source</param>
        /// <param name="sourceProfile">Source profile type</param>
        /// <param name="newDirectionOfPrincipalSourceAxis">New source axis direction</param>
        /// <param name="translationFromOrigin">New source location</param>
        /// <param name="beamRotationFromInwardNormal">Beam rotation from inward normal</param>
        /// <param name="initialTissueRegionIndex">Initial tissue region index</param>
        protected LineSourceBase(
            double lineLength,
            ISourceProfile sourceProfile,
            Direction newDirectionOfPrincipalSourceAxis,
            Position translationFromOrigin,
            PolarAzimuthalAngles beamRotationFromInwardNormal,
            int initialTissueRegionIndex)
        {
            if (newDirectionOfPrincipalSourceAxis == null)
            {
                newDirectionOfPrincipalSourceAxis = SourceDefaults.DefaultDirectionOfPrincipalSourceAxis.Clone();
            }
            if (translationFromOrigin == null)
            {
                translationFromOrigin = SourceDefaults.DefaultPosition.Clone();
            }
            if (beamRotationFromInwardNormal == null)
            {
                beamRotationFromInwardNormal = SourceDefaults.DefaultBeamRoationFromInwardNormal.Clone();
            }

            _rotationAndTranslationFlags = new SourceFlags(
                newDirectionOfPrincipalSourceAxis != SourceDefaults.DefaultDirectionOfPrincipalSourceAxis.Clone(),
                translationFromOrigin != SourceDefaults.DefaultPosition.Clone(),
                beamRotationFromInwardNormal != SourceDefaults.DefaultBeamRoationFromInwardNormal.Clone());

            _lineLength    = lineLength;
            _sourceProfile = sourceProfile;
            _newDirectionOfPrincipalSourceAxis = newDirectionOfPrincipalSourceAxis.Clone();
            _translationFromOrigin             = translationFromOrigin.Clone();
            _beamRotationFromInwardNormal      = beamRotationFromInwardNormal.Clone();
            _initialTissueRegionIndex          = initialTissueRegionIndex;
        }
Beispiel #7
0
        /// <summary>
        /// Implements Get next photon
        /// </summary>
        /// <param name="tissue">tissue</param>
        /// <returns>photon</returns>
        public Photon GetNextPhoton(ITissue tissue)
        {
            double curved = 2 * Math.PI * _fiberRadius * _fiberHeightZ * _curvedSurfaceEfficiency;
            double bottom = Math.PI * _fiberRadius * _fiberRadius * _bottomSurfaceEfficiency;

            Direction finalDirection = SourceToolbox.GetDirectionForGivenPolarAzimuthalAngleRangeRandom(
                        SourceDefaults.DefaultHalfPolarAngleRange.Clone(),
                        SourceDefaults.DefaultAzimuthalAngleRange.Clone(),
                        Rng);
            Position finalPosition = SourceDefaults.DefaultPosition.Clone();

            if (_fiberRadius > 0.0)
            {   
                if (Rng.NextDouble() > bottom / (curved + bottom))   //Consider 
                {   /* Curved surface */
                    // To utilize the final direction given above, we can assume a tube 
                    // parallel to the y-axis. We can rotate it about the x-axis by pi/2 
                    // to compute the new direction.
                    SourceToolbox.UpdateDirectionAfterRotatingAroundXAxis(-0.5 * Math.PI, finalDirection);

                    //Sample tube perimeter first to compute x and y coordinates
                    finalPosition = SourceToolbox.GetPositionAtCirclePerimeter(finalPosition,
                        _fiberRadius, 
                        Rng);

                    //Sample tube height to compute z coordinate
                    finalPosition.Z = _fiberHeightZ * (Rng.NextDouble() - 0.5);
                }
                else
                {   /* Bottom Surface */
                    //Shift finalPosition by _fiberHeightZ / 2
                    finalPosition = new Position(0.0, 0.0, _fiberHeightZ * 0.5);

                    //Sample the bottom face to find  x, y coordinates of the emission
                    finalPosition = SourceToolbox.GetPositionInACircleRandomFlat(finalPosition,
                        0.0,
                        _fiberRadius,
                        Rng);                    
                }
            }
 
            //Find the relevent polar and azimuthal pair for the direction
            PolarAzimuthalAngles _rotationalAnglesOfPrincipalSourceAxis = SourceToolbox.GetPolarAzimuthalPairFromDirection(_newDirectionOfPrincipalSourceAxis);
            
            //Translation and source rotation
            SourceToolbox.UpdateDirectionPositionAfterGivenFlags(
                ref finalPosition,
                ref finalDirection,
                _rotationalAnglesOfPrincipalSourceAxis,
                _translationFromOrigin,                
                _rotationAndTranslationFlags);

            var photon = new Photon(finalPosition, finalDirection, 1.0, tissue, _initialTissueRegionIndex, Rng);

            return photon;
        }
Beispiel #8
0
 /// <summary>
 /// Initializes a new instance of IsotropicLineSourceInput class
 /// </summary>
 /// <param name="lineLength">The length of the line source</param>
 /// <param name="sourceProfile">Source Profile {Flat / Gaussian}</param>
 /// <param name="newDirectionOfPrincipalSourceAxis">New source axis direction</param>
 /// <param name="translationFromOrigin">New source location</param>
 /// <param name="beamRotationFromInwardNormal">beam rotation angle</param>
 /// <param name="initialTissueRegionIndex">Initial tissue region index</param>
 public IsotropicLineSourceInput(
     double lineLength,
     ISourceProfile sourceProfile,
     Direction newDirectionOfPrincipalSourceAxis,
     Position translationFromOrigin,
     PolarAzimuthalAngles beamRotationFromInwardNormal,
     int initialTissueRegionIndex)
 {
     SourceType    = "IsotropicLine";
     LineLength    = lineLength;
     SourceProfile = sourceProfile;
     NewDirectionOfPrincipalSourceAxis = newDirectionOfPrincipalSourceAxis;
     TranslationFromOrigin             = translationFromOrigin;
     BeamRotationFromInwardNormal      = beamRotationFromInwardNormal;
     InitialTissueRegionIndex          = initialTissueRegionIndex;
 }
Beispiel #9
0
 /// <summary>
 /// Returns an instance of isotropicLineSource with line length, source profile, direction, position,
 /// inward normal beam rotation and initial tissue region index.
 /// </summary>
 /// <param name="lineLength">The length of the line source</param>
 /// <param name="sourceProfile">Source Profile {Flat / Gaussian}</param>
 /// <param name="newDirectionOfPrincipalSourceAxis">New source axis direction</param>
 /// <param name="translationFromOrigin">New source location</param>
 /// <param name="beamRotationFromInwardNormal">Ray rotation from inward normal</param>
 /// <param name="initialTissueRegionIndex">Initial tissue region index</param>
 public IsotropicLineSource(
     double lineLength,
     ISourceProfile sourceProfile,
     Direction newDirectionOfPrincipalSourceAxis = null,
     Position translationFromOrigin = null,
     PolarAzimuthalAngles beamRotationFromInwardNormal = null,
     int initialTissueRegionIndex = 0)
     : base(
         lineLength,
         sourceProfile,
         newDirectionOfPrincipalSourceAxis,
         translationFromOrigin,
         beamRotationFromInwardNormal,
         initialTissueRegionIndex)
 {
 }
Beispiel #10
0
        private double _thetaConvOrDiv;   //convergence:positive, divergence:negative  collimated:zero

        /// <summary>
        /// Initializes a new instance of the DirectionalLineSource class
        /// </summary>
        /// <param name="thetaConvOrDiv">Covergence or Divergance Angle {= 0, for a collimated beam}</param>
        /// <param name="lineLength">The length of the line source</param>
        /// <param name="beamDiameterFWHM">Beam diameter FWHM (-1 for flat beam)</param>
        /// <param name="newDirectionOfPrincipalSourceAxis">New source axis direction</param>
        /// <param name="translationFromOrigin">New source location</param>
        /// <param name="beamRotationFromInwardNormal">Ray rotation from inward normal</param>
        /// <param name="initialTissueRegionIndex">Initial tissue region index</param>
        public DirectionalLineSource(
            double thetaConvOrDiv,
            double lineLength,
            double beamDiameterFWHM,
            Direction newDirectionOfPrincipalSourceAxis = null,
            Position translationFromOrigin = null,
            PolarAzimuthalAngles beamRotationFromInwardNormal = null,
            int initialTissueRegionIndex = 0)
            : base(
                lineLength,
                beamDiameterFWHM,
                newDirectionOfPrincipalSourceAxis,
                translationFromOrigin,
                beamRotationFromInwardNormal,
                initialTissueRegionIndex)
        {
            _thetaConvOrDiv = thetaConvOrDiv;
        }
Beispiel #11
0
 /// <summary>
 /// Initializes a new instance of the DirectionalLineSourceInput class
 /// </summary>
 /// <param name="thetaConvOrDiv">Covergence or Divergance Angle {= 0, for a collimated beam} {= 0, for a collimated beam}</param>
 /// <param name="lineLength">The length of the line source</param>
 /// <param name="beamDiameterFWHM">Beam diameter FWHM (-1 for flat beam)</param>
 /// <param name="newDirectionOfPrincipalSourceAxis">New source axis direction</param>
 /// <param name="translationFromOrigin">New source location</param>
 /// <param name="beamRotationFromInwardNormal">beam rotation angle</param>
 /// <param name="initialTissueRegionIndex">Initial tissue region index</param>
 public DirectionalLineSourceInput(
     double thetaConvOrDiv,
     double lineLength,
     double beamDiameterFWHM,
     Direction newDirectionOfPrincipalSourceAxis,
     Position translationFromOrigin,
     PolarAzimuthalAngles beamRotationFromInwardNormal,
     int initialTissueRegionIndex)
 {
     SourceType       = "DirectionalLine";
     ThetaConvOrDiv   = thetaConvOrDiv;
     LineLength       = lineLength;
     BeamDiameterFWHM = beamDiameterFWHM;
     NewDirectionOfPrincipalSourceAxis = newDirectionOfPrincipalSourceAxis;
     TranslationFromOrigin             = translationFromOrigin;
     BeamRotationFromInwardNormal      = beamRotationFromInwardNormal;
     InitialTissueRegionIndex          = initialTissueRegionIndex;
 }
 /// <summary>
 /// Initializes a new instance of DirectionalEllipticalSourceInput class
 /// </summary>
 /// <param name="thetaConvOrDiv">Covergence or Divergance Angle {= 0, for a collimated beam}</param>
 /// <param name="aParameter">"a" parameter of the ellipse source</param>
 /// <param name="bParameter">"b" parameter of the ellipse source</param>
 /// <param name="sourceProfile">Source Profile {Flat / Gaussian}</param>
 /// <param name="newDirectionOfPrincipalSourceAxis">New source axis direction</param>
 /// <param name="translationFromOrigin">New source location</param>
 /// <param name="beamRotationFromInwardNormal">beam rotation angle</param>
 /// <param name="initialTissueRegionIndex">Initial tissue region index</param>
 public DirectionalEllipticalSourceInput(
     double thetaConvOrDiv,
     double aParameter,
     double bParameter,
     ISourceProfile sourceProfile,
     Direction newDirectionOfPrincipalSourceAxis,
     Position translationFromOrigin,
     PolarAzimuthalAngles beamRotationFromInwardNormal,
     int initialTissueRegionIndex)
 {
     SourceType     = "DirectionalElliptical";
     ThetaConvOrDiv = thetaConvOrDiv;
     AParameter     = aParameter;
     BParameter     = bParameter;
     SourceProfile  = sourceProfile;
     NewDirectionOfPrincipalSourceAxis = newDirectionOfPrincipalSourceAxis;
     TranslationFromOrigin             = translationFromOrigin;
     BeamRotationFromInwardNormal      = beamRotationFromInwardNormal;
     InitialTissueRegionIndex          = initialTissueRegionIndex;
 }
Beispiel #13
0
 /// <summary>
 /// Initializes a new instance of the CustomLineSource class
 /// </summary>
 /// <param name="lineLength">The length of the line source</param>
 /// <param name="beamDiameterFWHM">Beam diameter FWHM (-1 for flat beam)</param>
 /// <param name="polarAngleEmissionRange">Polar angle emission range</param>
 /// <param name="azimuthalAngleEmissionRange">Azimuthal angle emission range</param>
 /// <param name="newDirectionOfPrincipalSourceAxis">New source axis direction</param>
 /// <param name="translationFromOrigin">New source location</param>
 /// <param name="beamRotationFromInwardNormal">Beam rotation from inward normal</param>
 /// <param name="initialTissueRegionIndex">Initial tissue region index</param>
 public CustomLineSource(
     double lineLength,
     double beamDiameterFWHM,
     DoubleRange polarAngleEmissionRange,
     DoubleRange azimuthalAngleEmissionRange,
     Direction newDirectionOfPrincipalSourceAxis = null,
     Position translationFromOrigin = null,
     PolarAzimuthalAngles beamRotationFromInwardNormal = null,
     int initialTissueRegionIndex = 0)
     : base(
         lineLength,
         beamDiameterFWHM,
         newDirectionOfPrincipalSourceAxis,
         translationFromOrigin,
         beamRotationFromInwardNormal,
         initialTissueRegionIndex)
 {
     _polarAngleEmissionRange     = polarAngleEmissionRange.Clone();
     _azimuthalAngleEmissionRange = azimuthalAngleEmissionRange.Clone();
 }
Beispiel #14
0
 /// <summary>
 /// Initializes a new instance of DirectionalCircularSourceInput class
 /// </summary>
 /// <param name="thetaConvOrDiv">Convergence(negative angle in radians) or Divergence (positive angle in radians) angle {= 0, for a collimated beam}</param>
 /// <param name="outerRadius">The outer radius of the circular source</param>
 /// <param name="innerRadius">The inner radius of the circular source</param>
 /// <param name="beamDiameterFWHM">Beam diameter FWHM (-1 for flat beam)</param>
 /// <param name="newDirectionOfPrincipalSourceAxis">New source axis direction</param>
 /// <param name="translationFromOrigin">New source location</param>
 /// <param name="beamRotationFromInwardNormal">beam rotation angle</param>
 /// <param name="initialTissueRegionIndex">Initial tissue region index</param>
 public DirectionalCircularSourceInput(
     double thetaConvOrDiv,
     double outerRadius,
     double innerRadius,
     double beamDiameterFWHM,
     Direction newDirectionOfPrincipalSourceAxis,
     Position translationFromOrigin,
     PolarAzimuthalAngles beamRotationFromInwardNormal,
     int initialTissueRegionIndex)
 {
     SourceType       = "DirectionalCircular";
     ThetaConvOrDiv   = thetaConvOrDiv;
     OuterRadius      = outerRadius;
     InnerRadius      = innerRadius;
     BeamDiameterFWHM = beamDiameterFWHM;
     NewDirectionOfPrincipalSourceAxis = newDirectionOfPrincipalSourceAxis;
     TranslationFromOrigin             = translationFromOrigin;
     BeamRotationFromInwardNormal      = beamRotationFromInwardNormal;
     InitialTissueRegionIndex          = initialTissueRegionIndex;
 }
 /// <summary>
 /// Initializes a new instance of the DirectionalRectangularSourceInput class
 /// </summary>
 /// <param name="thetaConvOrDiv">Covergence or Divergance Angle {= 0, for a collimated beam}</param>
 /// <param name="rectLengthX">The length of the Rectangular Source</param>
 /// <param name="rectWidthY">The width of the Rectangular Source</param>
 /// <param name="sourceProfile">Source Profile {Flat / Gaussian}</param>
 /// <param name="newDirectionOfPrincipalSourceAxis">New source axis direction</param>
 /// <param name="translationFromOrigin">New source location</param>
 /// <param name="beamRotationFromInwardNormal">beam rotation angle</param>
 /// <param name="initialTissueRegionIndex">Initial tissue region index</param>
 public DirectionalRectangularSourceInput(
     double thetaConvOrDiv,
     double rectLengthX,
     double rectWidthY,
     ISourceProfile sourceProfile,
     Direction newDirectionOfPrincipalSourceAxis,
     Position translationFromOrigin,
     PolarAzimuthalAngles beamRotationFromInwardNormal,
     int initialTissueRegionIndex)
 {
     SourceType     = "DirectionalRectangular";
     ThetaConvOrDiv = thetaConvOrDiv;
     RectLengthX    = rectLengthX;
     RectWidthY     = rectWidthY;
     SourceProfile  = sourceProfile;
     NewDirectionOfPrincipalSourceAxis = newDirectionOfPrincipalSourceAxis;
     TranslationFromOrigin             = translationFromOrigin;
     BeamRotationFromInwardNormal      = beamRotationFromInwardNormal;
     InitialTissueRegionIndex          = initialTissueRegionIndex;
 }
Beispiel #16
0
 /// <summary>
 /// Initializes a new instance of CustomLineSourceInput class
 /// </summary>
 /// <param name="lineLength">The length of the line source</param>
 /// <param name="beamDiameterFWHM">Beam diameter FWHM (-1 for flat beam)</param>
 /// <param name="polarAngleEmissionRange">Polar angle range</param>
 /// <param name="azimuthalAngleEmissionRange">Azimuthal angle range</param>
 /// <param name="newDirectionOfPrincipalSourceAxis">New source axis direction</param>
 /// <param name="translationFromOrigin">New source location</param>
 /// <param name="beamRotationFromInwardNormal">beam rotation angle</param>
 /// <param name="initialTissueRegionIndex">Initial tissue region index</param>
 public CustomLineSourceInput(
     double lineLength,
     double beamDiameterFWHM,
     DoubleRange polarAngleEmissionRange,
     DoubleRange azimuthalAngleEmissionRange,
     Direction newDirectionOfPrincipalSourceAxis,
     Position translationFromOrigin,
     PolarAzimuthalAngles beamRotationFromInwardNormal,
     int initialTissueRegionIndex)
 {
     SourceType                        = "CustomLine";
     LineLength                        = lineLength;
     BeamDiameterFWHM                  = beamDiameterFWHM;
     PolarAngleEmissionRange           = polarAngleEmissionRange;
     AzimuthalAngleEmissionRange       = azimuthalAngleEmissionRange;
     NewDirectionOfPrincipalSourceAxis = newDirectionOfPrincipalSourceAxis;
     TranslationFromOrigin             = translationFromOrigin;
     BeamRotationFromInwardNormal      = beamRotationFromInwardNormal;
     InitialTissueRegionIndex          = initialTissueRegionIndex;
 }
        /// <summary>
        /// Implements Get next photon
        /// </summary>
        /// <param name="tissue">tissue</param>
        /// <returns>photon</returns>
        public Photon GetNextPhoton(ITissue tissue)
        {
            //sample angular distribution
            Direction finalDirection = SourceToolbox.GetDirectionForGivenPolarAzimuthalAngleRangeRandom(
                SourceDefaults.DefaultHalfPolarAngleRange.Clone(),
                SourceDefaults.DefaultAzimuthalAngleRange.Clone(),
                Rng);

            //Translate the photon to _tubeRadius length below the origin. Ring lies on yz plane.
            Position finalPosition = new Position(0.0, 0.0, _tubeRadius);

            //Sample a ring that emits photons outside.
            SourceToolbox.UpdateDirectionPositionAfterRotatingAroundXAxis(
                2.0 * Math.PI * Rng.NextDouble(),
                ref finalDirection,
                ref finalPosition);

            //Ring lies on xy plane. z= 0;
            SourceToolbox.UpdateDirectionPositionAfterRotatingAroundYAxis(
                0.5 * Math.PI,
                ref finalDirection,
                ref finalPosition);

            //Sample tube height
            finalPosition.Z = _tubeHeightZ * (2.0 * Rng.NextDouble() - 1.0);

            //Find the relevent polar and azimuthal pair for the direction
            PolarAzimuthalAngles _rotationalAnglesOfPrincipalSourceAxis = SourceToolbox.GetPolarAzimuthalPairFromDirection(_newDirectionOfPrincipalSourceAxis);

            //Translation and source rotation
            SourceToolbox.UpdateDirectionPositionAfterGivenFlags(
                ref finalPosition,
                ref finalDirection,
                _rotationalAnglesOfPrincipalSourceAxis,
                _translationFromOrigin,
                _rotationAndTranslationFlags);

            var photon = new Photon(finalPosition, finalDirection, tissue, _initialTissueRegionIndex, Rng);

            return(photon);
        }
        /// <summary>
        /// Implements Get next photon
        /// </summary>
        /// <param name="tissue">tissue</param>
        /// <returns>photon</returns>
        public Photon GetNextPhoton(ITissue tissue)
        {
            //sample angular distribution
            Direction finalDirection = SourceToolbox.GetDirectionForGivenPolarAzimuthalAngleRangeRandom(
                SourceDefaults.DefaultHalfPolarAngleRange.Clone(),
                SourceDefaults.DefaultAzimuthalAngleRange.Clone(),
                Rng);
            Position finalPosition = SourceDefaults.DefaultPosition.Clone();

            if (_tubeRadius > 0.0)
            {
                // To utilize the final direction given above, we can assume a tube
                // parallel to the y-axis. We can rotate it about the x-axis by pi/2
                // to compute the new direction.
                SourceToolbox.UpdateDirectionAfterRotatingAroundXAxis(0.5 * Math.PI, finalDirection);

                //Sample tube perimeter first to compute x and y coordinates
                finalPosition = SourceToolbox.GetPositionAtCirclePerimeter(finalPosition,
                                                                           _tubeRadius,
                                                                           Rng);

                //Sample tube height to compute z coordinate
                finalPosition.Z = _tubeHeightZ * (Rng.NextDouble() - 0.5);
            }

            //Find the relevent polar and azimuthal pair for the direction
            PolarAzimuthalAngles _rotationalAnglesOfPrincipalSourceAxis = SourceToolbox.GetPolarAzimuthalPairFromDirection(_newDirectionOfPrincipalSourceAxis);

            //Translation and source rotation
            SourceToolbox.UpdateDirectionPositionAfterGivenFlags(
                ref finalPosition,
                ref finalDirection,
                _rotationalAnglesOfPrincipalSourceAxis,
                _translationFromOrigin,
                _rotationAndTranslationFlags);

            var photon = new Photon(finalPosition, finalDirection, 1.0, tissue, _initialTissueRegionIndex, Rng);

            return(photon);
        }
        /// <summary>
        /// Read text data file that has input and output data
        /// </summary>
        public void read_data()
        {
            string testpara = "../../../../matlab/test/monte_carlo/source_test_data_generation/UnitTests_SourceToolbox.txt";

            if (File.Exists(testpara))
            {
                using (TextReader reader = File.OpenText(testpara))
                {
                    string   text = reader.ReadToEnd();
                    string[] bits = text.Split('\t');
                    for (int i = 0; i < 140; i++)
                    {
                        _tp[i] = double.Parse(bits[i]);
                    }
                    reader.Close();
                }
            }

            _position    = new Position(_tp[0], _tp[1], _tp[2]);
            _direction   = new Direction(_tp[3], _tp[4], _tp[5]);
            _translation = new Position(_tp[6], _tp[7], _tp[8]);
            _angPair     = new PolarAzimuthalAngles(_tp[9], _tp[10]);
            _polRange    = new DoubleRange(_tp[11], _tp[12]);
            _aziRange    = new DoubleRange(_tp[13], _tp[14]);
            _angRot      = new ThreeAxisRotation(_tp[15], _tp[16], _tp[17]);
            _flags       = new SourceFlags(true, true, true);
            _aParameter  = _tp[18];
            _bParameter  = _tp[19];
            _cParameter  = _tp[20];
            _lengthX     = _tp[21];
            _widthY      = _tp[22];
            _heightZ     = _tp[23];
            _innerRadius = _tp[24];
            _outerRadius = _tp[25];
            _bdFWHM      = _tp[26];
            _limitL      = _tp[27];
            _limitU      = _tp[28];
            _factor      = _tp[29];
            _polarAngle  = _tp[30];
        }
 /// <summary>
 /// Initializes a new instance of CustomRectangularSourceInput class
 /// </summary>
 /// <param name="rectLengthX">The length of the Rectangular Source</param>
 /// <param name="rectWidthY">The width of the Rectangular Source</param>
 /// <param name="sourceProfile">Source Profile {Flat / Gaussian}</param>
 /// <param name="polarAngleEmissionRange">Polar angle range</param>
 /// <param name="azimuthalAngleEmissionRange">Azimuthal angle range</param>
 /// <param name="newDirectionOfPrincipalSourceAxis">New source axis direction</param>
 /// <param name="translationFromOrigin">New source location</param>
 /// <param name="beamRotationFromInwardNormal">beam rotation angle</param>
 /// <param name="initialTissueRegionIndex">Initial tissue region index</param>
 public CustomRectangularSourceInput(
     double rectLengthX,
     double rectWidthY,
     ISourceProfile sourceProfile,
     DoubleRange polarAngleEmissionRange,
     DoubleRange azimuthalAngleEmissionRange,
     Direction newDirectionOfPrincipalSourceAxis,
     Position translationFromOrigin,
     PolarAzimuthalAngles beamRotationFromInwardNormal,
     int initialTissueRegionIndex)
 {
     SourceType                        = "CustomRectangular";
     RectLengthX                       = rectLengthX;
     RectWidthY                        = rectWidthY;
     SourceProfile                     = sourceProfile;
     PolarAngleEmissionRange           = polarAngleEmissionRange;
     AzimuthalAngleEmissionRange       = azimuthalAngleEmissionRange;
     NewDirectionOfPrincipalSourceAxis = newDirectionOfPrincipalSourceAxis;
     TranslationFromOrigin             = translationFromOrigin;
     BeamRotationFromInwardNormal      = beamRotationFromInwardNormal;
     InitialTissueRegionIndex          = initialTissueRegionIndex;
 }
Beispiel #21
0
        /// <summary>
        /// Defines CircularSourceBase class
        /// </summary>
        /// <param name="innerRadius">The inner radius of the circular source</param>
        /// <param name="outerRadius">The outer radius of the circular source</param>
        /// <param name="sourceProfile">Source Profile {Flat / Gaussian}</param>
        /// <param name="newDirectionOfPrincipalSourceAxis">New source axis direction</param>
        /// <param name="translationFromOrigin">New source location</param>
        /// <param name="beamRotationFromInwardNormal">Polar Azimuthal Rotational Angle of inward Normal</param>
        /// <param name="initialTissueRegionIndex">Initial tissue region index</param>
        protected CircularSourceBase(
            double outerRadius,
            double innerRadius,
            ISourceProfile sourceProfile,
            Direction newDirectionOfPrincipalSourceAxis,
            Position translationFromOrigin,
            PolarAzimuthalAngles beamRotationFromInwardNormal,
            int initialTissueRegionIndex)
        {
            _rotationAndTranslationFlags = new SourceFlags(
                newDirectionOfPrincipalSourceAxis != SourceDefaults.DefaultDirectionOfPrincipalSourceAxis.Clone(),
                translationFromOrigin != SourceDefaults.DefaultPosition.Clone(),
                beamRotationFromInwardNormal != SourceDefaults.DefaultBeamRoationFromInwardNormal.Clone());

            _outerRadius   = outerRadius;
            _innerRadius   = innerRadius;
            _sourceProfile = sourceProfile;
            _newDirectionOfPrincipalSourceAxis = newDirectionOfPrincipalSourceAxis.Clone();
            _translationFromOrigin             = translationFromOrigin.Clone();
            _beamRotationFromInwardNormal      = beamRotationFromInwardNormal.Clone();
            _initialTissueRegionIndex          = initialTissueRegionIndex;
        }
        /// <summary>
        /// Defines RectangularSourceBase class
        /// </summary>
        /// <param name="rectLengthX">The length of the Rectangular Source</param>
        /// <param name="rectWidthY">The width of the Rectangular Source</param>
        /// <param name="sourceProfile">Source Profile {Flat / Gaussian}</param>
        /// <param name="newDirectionOfPrincipalSourceAxis">New source axis direction</param>
        /// <param name="translationFromOrigin">New source location</param>
        /// <param name="beamRotationFromInwardNormal">Polar Azimuthal Rotational Angle of inward Normal</param>
        /// <param name="initialTissueRegionIndex">Initial tissue region index</param>
        protected RectangularSourceBase(
            double rectLengthX,
            double rectWidthY,
            ISourceProfile sourceProfile,
            Direction newDirectionOfPrincipalSourceAxis,
            Position translationFromOrigin,
            PolarAzimuthalAngles beamRotationFromInwardNormal,
            int initialTissueRegionIndex)
        {
            _rotationAndTranslationFlags = new SourceFlags(
                newDirectionOfPrincipalSourceAxis != SourceDefaults.DefaultDirectionOfPrincipalSourceAxis.Clone(),
                translationFromOrigin != SourceDefaults.DefaultPosition.Clone(),
                beamRotationFromInwardNormal != SourceDefaults.DefaultBeamRoationFromInwardNormal.Clone());

            _rectLengthX   = rectLengthX;
            _rectWidthY    = rectWidthY;
            _sourceProfile = sourceProfile;
            _newDirectionOfPrincipalSourceAxis = newDirectionOfPrincipalSourceAxis.Clone();
            _translationFromOrigin             = translationFromOrigin.Clone();
            _beamRotationFromInwardNormal      = beamRotationFromInwardNormal.Clone();
            _initialTissueRegionIndex          = initialTissueRegionIndex;
        }
 /// <summary>
 /// Defines DirectionalArbitrarySurfaceSource
 /// </summary>
 /// <param name="thetaConvOrDiv"></param>
 /// <param name="sourceLengthX">The length of the arbitrary (image-based) Source</param>
 /// <param name="sourceWidthY">The width of the arbitrary (image-based) Source</param>
 /// <param name="image"></param>
 /// <param name="pixelLengthX">pixel length X</param>
 /// <param name="pixelWidthY">pixel length Y</param>
 /// <param name="newDirectionOfPrincipalSourceAxis">New source axis direction</param>
 /// <param name="translationFromOrigin">New source location</param>
 /// <param name="beamRotationFromInwardNormal">Polar Azimuthal Rotational Angle of inward Normal</param>
 /// <param name="initialTissueRegionIndex">Initial tissue region index</param>
 protected DirectionalArbitrarySurfaceSource(
     double thetaConvOrDiv,
     double sourceLengthX,
     double sourceWidthY,
     double[] image,
     int pixelLengthX,
     int pixelWidthY,
     Direction newDirectionOfPrincipalSourceAxis,
     Position translationFromOrigin,
     PolarAzimuthalAngles beamRotationFromInwardNormal,
     int initialTissueRegionIndex)
     : base(
         thetaConvOrDiv,
         sourceLengthX,
         sourceWidthY,
         new ArbitrarySourceProfile(image, pixelWidthY, pixelLengthX),
         newDirectionOfPrincipalSourceAxis,
         translationFromOrigin,
         beamRotationFromInwardNormal,
         initialTissueRegionIndex)
 {
 }
Beispiel #24
0
 /// <summary>
 /// Initializes a new instance of CustomCircularSourceInput class
 /// </summary>
 /// <param name="outerRadius">The outer radius of the circular source</param>
 /// <param name="innerRadius">The inner radius of the circular source</param>
 /// <param name="beamDiameterFWHM">Beam diameter FWHM (-1 for flat beam)</param>
 /// <param name="polarAngleEmissionRange">Polar angle range</param>
 /// <param name="azimuthalAngleEmissionRange">Azimuthal angle range</param>
 /// <param name="newDirectionOfPrincipalSourceAxis">New source axis direction</param>
 /// <param name="translationFromOrigin">New source location</param>
 /// <param name="beamRotationFromInwardNormal">Beam rotation from inward normal</param>
 /// <param name="initialTissueRegionIndex">Initial tissue region index</param>
 public CustomCircularSourceInput(
     double outerRadius,
     double innerRadius,
     double beamDiameterFWHM,
     DoubleRange polarAngleEmissionRange,
     DoubleRange azimuthalAngleEmissionRange,
     Direction newDirectionOfPrincipalSourceAxis,
     Position translationFromOrigin,
     PolarAzimuthalAngles beamRotationFromInwardNormal,
     int initialTissueRegionIndex)
 {
     SourceType                        = "CustomCircular";
     OuterRadius                       = outerRadius;
     InnerRadius                       = innerRadius;
     BeamDiameterFWHM                  = beamDiameterFWHM;
     PolarAngleEmissionRange           = polarAngleEmissionRange;
     AzimuthalAngleEmissionRange       = azimuthalAngleEmissionRange;
     NewDirectionOfPrincipalSourceAxis = newDirectionOfPrincipalSourceAxis;
     TranslationFromOrigin             = translationFromOrigin;
     BeamRotationFromInwardNormal      = beamRotationFromInwardNormal;
     InitialTissueRegionIndex          = initialTissueRegionIndex;
 }
Beispiel #25
0
 /// <summary>
 /// Initializes a new instance of CustomEllipticalSourceInput class
 /// </summary>
 /// <param name="aParameter">"a" parameter of the ellipse source</param>
 /// <param name="bParameter">"b" parameter of the ellipse source</param>
 /// <param name="sourceProfile">Source Profile {Flat / Gaussian}</param>
 /// <param name="polarAngleEmissionRange">Polar angle range</param>
 /// <param name="azimuthalAngleEmissionRange">Azimuthal angle range</param>
 /// <param name="newDirectionOfPrincipalSourceAxis">New source axis direction</param>
 /// <param name="translationFromOrigin">New source location</param>
 /// <param name="beamRotationFromInwardNormal">beam rotation angle</param>
 /// <param name="initialTissueRegionIndex">Initial tissue region index</param>
 public CustomEllipticalSourceInput(
     double aParameter,
     double bParameter,
     ISourceProfile sourceProfile,
     DoubleRange polarAngleEmissionRange,
     DoubleRange azimuthalAngleEmissionRange,
     Direction newDirectionOfPrincipalSourceAxis,
     Position translationFromOrigin,
     PolarAzimuthalAngles beamRotationFromInwardNormal,
     int initialTissueRegionIndex)
 {
     SourceType                        = "CustomElliptical";
     AParameter                        = aParameter;
     BParameter                        = bParameter;
     SourceProfile                     = sourceProfile;
     PolarAngleEmissionRange           = polarAngleEmissionRange;
     AzimuthalAngleEmissionRange       = azimuthalAngleEmissionRange;
     NewDirectionOfPrincipalSourceAxis = newDirectionOfPrincipalSourceAxis;
     TranslationFromOrigin             = translationFromOrigin;
     BeamRotationFromInwardNormal      = beamRotationFromInwardNormal;
     InitialTissueRegionIndex          = initialTissueRegionIndex;
 }
Beispiel #26
0
        /// <summary>
        /// Defines EllipticalSourceBase class
        /// </summary>
        /// <param name="aParameter">"a" parameter of the ellipse source</param>
        /// <param name="bParameter">"b" parameter of the ellipse source</param>
        /// <param name="sourceProfile">Source Profile {Flat / Gaussian}</param>
        /// <param name="newDirectionOfPrincipalSourceAxis">New source axis direction</param>
        /// <param name="translationFromOrigin">New source location</param>
        /// <param name="beamRotationFromInwardNormal">Polar Azimuthal Rotational Angle of inward Normal</param>
        /// <param name="initialTissueRegionIndex">Initial tissue region index</param>
        protected EllipticalSourceBase(
            double aParameter,
            double bParameter,
            ISourceProfile sourceProfile,
            Direction newDirectionOfPrincipalSourceAxis,
            Position translationFromOrigin,
            PolarAzimuthalAngles beamRotationFromInwardNormal,
            int initialTissueRegionIndex)
        {
            _rotationAndTranslationFlags = new SourceFlags(
                newDirectionOfPrincipalSourceAxis != SourceDefaults.DefaultDirectionOfPrincipalSourceAxis.Clone(),
                translationFromOrigin != SourceDefaults.DefaultPosition.Clone(),
                beamRotationFromInwardNormal != SourceDefaults.DefaultBeamRoationFromInwardNormal.Clone());

            _aParameter    = aParameter;
            _bParameter    = bParameter;
            _sourceProfile = sourceProfile;
            _newDirectionOfPrincipalSourceAxis = newDirectionOfPrincipalSourceAxis.Clone();
            _translationFromOrigin             = translationFromOrigin.Clone();
            _beamRotationFromInwardNormal      = beamRotationFromInwardNormal.Clone();
            _initialTissueRegionIndex          = initialTissueRegionIndex;
        }
        /// <summary>
        /// Implements Get next photon
        /// </summary>
        /// <param name="tissue">tissue</param>
        /// <returns>photon</returns>
        public Photon GetNextPhoton(ITissue tissue)
        {
            //Source starts from anywhere in the ellipsoid
            Position finalPosition = GetFinalPositionFromProfileType(_sourceProfile, _aParameter, _bParameter, _cParameter, Rng);

            // sample angular distribution
            Direction finalDirection = GetFinalDirection();

            //Find the relevent polar and azimuthal pair for the direction
            PolarAzimuthalAngles _rotationalAnglesOfPrincipalSourceAxis = SourceToolbox.GetPolarAzimuthalPairFromDirection(_newDirectionOfPrincipalSourceAxis);

            //Rotation and translation
            SourceToolbox.UpdateDirectionPositionAfterGivenFlags(
                ref finalPosition,
                ref finalDirection,
                _rotationalAnglesOfPrincipalSourceAxis,
                _translationFromOrigin,
                _rotationAndTranslationFlags);

            var photon = new Photon(finalPosition, finalDirection, 1.0, tissue, _initialTissueRegionIndex, Rng);

            return(photon);
        }
        /// <summary>
        /// Implements Get next photon
        /// </summary>
        /// <param name="tissue">tissue</param>
        /// <returns>photon</returns>
        public Photon GetNextPhoton(ITissue tissue)
        {
            //Source starts from anywhere in the cuboid
            Position finalPosition = GetFinalPosition(_beamDiameterFWHM, _cubeLengthX, _cubeWidthY, _cubeHeightZ, Rng);

            // sample angular distribution
            Direction finalDirection = GetFinalDirection();

            //Find the relevent polar and azimuthal pair for the direction
            PolarAzimuthalAngles _rotationalAnglesOfPrincipalSourceAxis = SourceToolbox.GetPolarAzimuthalPairFromDirection(_newDirectionOfPrincipalSourceAxis);

            //Rotation and translation
            SourceToolbox.UpdateDirectionPositionAfterGivenFlags(
                ref finalPosition,
                ref finalDirection,
                _rotationalAnglesOfPrincipalSourceAxis,
                _translationFromOrigin,
                _rotationAndTranslationFlags);

            var photon = new Photon(finalPosition, finalDirection, tissue, _initialTissueRegionIndex, Rng);

            return(photon);
        }
        /// <summary>
        /// Implements Get next photon
        /// </summary>
        /// <param name="tissue">tissue</param>
        /// <returns>photon</returns>
        public Photon GetNextPhoton(ITissue tissue)
        {
            //Sample emitting side
            String cSide = SelectEmittingSurface(
                _cubeLengthX,
                _cubeWidthY,
                _cubeHeightZ,
                Rng);

            //sample angular distribution
            Direction finalDirection = SourceToolbox.GetDirectionForGivenPolarAzimuthalAngleRangeRandom(
                _polarAngleEmissionRange,
                SourceDefaults.DefaultAzimuthalAngleRange.Clone(),
                Rng);

            Position tempPosition  = null;
            Position finalPosition = null;

            switch (cSide)
            {
            case "xpos":
                tempPosition    = GetFinalPosition(_beamDiameterFWHM, _cubeHeightZ, _cubeWidthY, Rng);
                finalPosition.X = 0.5 * _cubeLengthX;
                finalPosition.Y = tempPosition.Y;
                finalPosition.Z = tempPosition.X;
                finalDirection  = SourceToolbox.UpdateDirectionAfterRotatingAroundXAxis(0.5 * Math.PI, finalDirection);
                break;

            case "xneg":
                tempPosition    = GetFinalPosition(_beamDiameterFWHM, _cubeHeightZ, _cubeWidthY, Rng);
                finalPosition.X = -0.5 * _cubeLengthX;
                finalPosition.Y = tempPosition.Y;
                finalPosition.Z = tempPosition.X;
                finalDirection  = SourceToolbox.UpdateDirectionAfterRotatingAroundXAxis(-0.5 * Math.PI, finalDirection);
                break;

            case "ypos":
                tempPosition    = GetFinalPosition(_beamDiameterFWHM, _cubeLengthX, _cubeHeightZ, Rng);
                finalPosition.X = tempPosition.X;
                finalPosition.Y = 0.5 * _cubeWidthY;
                finalPosition.Z = tempPosition.Y;
                finalDirection  = SourceToolbox.UpdateDirectionAfterRotatingAroundYAxis(0.5 * Math.PI, finalDirection);
                break;

            case "yneg":
                tempPosition    = GetFinalPosition(_beamDiameterFWHM, _cubeLengthX, _cubeHeightZ, Rng);
                finalPosition.X = tempPosition.X;
                finalPosition.Y = -0.5 * _cubeWidthY;
                finalPosition.Z = tempPosition.Y;
                finalDirection  = SourceToolbox.UpdateDirectionAfterRotatingAroundYAxis(-0.5 * Math.PI, finalDirection);
                break;

            case "zpos":
                tempPosition    = GetFinalPosition(_beamDiameterFWHM, _cubeLengthX, _cubeWidthY, Rng);
                finalPosition.X = tempPosition.X;
                finalPosition.Y = tempPosition.Y;
                finalPosition.Z = 0.5 * _cubeHeightZ;
                break;

            case "zneg":
                tempPosition    = GetFinalPosition(_beamDiameterFWHM, _cubeLengthX, _cubeWidthY, Rng);
                finalPosition.X = tempPosition.X;
                finalPosition.Y = tempPosition.Y;
                finalPosition.Z = -0.5 * _cubeHeightZ;
                //reverse signs
                finalDirection.Uz = -finalDirection.Uz;
                break;
            }

            //Find the relevent polar and azimuthal pair for the direction
            PolarAzimuthalAngles _rotationalAnglesOfPrincipalSourceAxis = SourceToolbox.GetPolarAzimuthalPairFromDirection(_newDirectionOfPrincipalSourceAxis);

            //Translation and source rotation
            SourceToolbox.UpdateDirectionPositionAfterGivenFlags(
                ref finalPosition,
                ref finalDirection,
                _rotationalAnglesOfPrincipalSourceAxis,
                _translationFromOrigin,
                _rotationAndTranslationFlags);

            var photon = new Photon(finalPosition, finalDirection, tissue, _initialTissueRegionIndex, Rng);

            return(photon);
        }
        /// <summary>
        /// Implements Get next photon
        /// </summary>
        /// <param name="tissue">tissue</param>
        /// <returns>photon</returns>
        public Photon GetNextPhoton(ITissue tissue)
        {
            double curved = 2 * Math.PI * _fiberRadius * _fiberHeightZ * _curvedSurfaceEfficiency;
            double bottom = Math.PI * _fiberRadius * _fiberRadius * _bottomSurfaceEfficiency;

            Direction finalDirection;
            Position  finalPosition;

            if (_fiberRadius > 0.0)
            {
                if (Rng.NextDouble() > bottom / (curved + bottom))
                {
                    //sample angular distribution
                    finalDirection = SourceToolbox.GetDirectionForGivenPolarAzimuthalAngleRangeRandom(
                        SourceDefaults.DefaultHalfPolarAngleRange.Clone(),
                        SourceDefaults.DefaultAzimuthalAngleRange.Clone(),
                        Rng);

                    //Translate the photon to _tubeRadius length below the origin. Ring lies on yz plane.
                    finalPosition = new Position(0.0, 0.0, _fiberRadius);

                    //Sample a ring that emits photons outside.
                    SourceToolbox.UpdateDirectionPositionAfterRotatingAroundXAxis(
                        2.0 * Math.PI * Rng.NextDouble(),
                        ref finalDirection,
                        ref finalPosition);

                    //Ring lies on xy plane. z= 0;
                    SourceToolbox.UpdateDirectionPositionAfterRotatingAroundYAxis(
                        0.5 * Math.PI,
                        ref finalDirection,
                        ref finalPosition);

                    //Sample tube height
                    finalPosition.Z = _fiberHeightZ * (2.0 * Rng.NextDouble() - 1.0);
                }
                else
                {
                    finalPosition = SourceToolbox.GetPositionInACircleRandomFlat(
                        SourceDefaults.DefaultPosition.Clone(),
                        0.0,
                        _fiberRadius,
                        Rng);

                    finalDirection = SourceToolbox.GetDirectionForGivenPolarAzimuthalAngleRangeRandom(
                        SourceDefaults.DefaultHalfPolarAngleRange.Clone(),
                        SourceDefaults.DefaultAzimuthalAngleRange.Clone(),
                        Rng);
                }
            }
            else
            {
                finalPosition = SourceToolbox.GetPositionInALineRandomFlat(
                    SourceDefaults.DefaultPosition.Clone(),
                    _fiberHeightZ,
                    Rng);

                finalDirection = SourceToolbox.GetDirectionForGivenPolarAzimuthalAngleRangeRandom(
                    SourceDefaults.DefaultFullPolarAngleRange.Clone(),
                    SourceDefaults.DefaultAzimuthalAngleRange.Clone(),
                    Rng);

                //Rotate 90degrees around y axis
                SourceToolbox.UpdateDirectionPositionAfterRotatingAroundYAxis(
                    0.5 * Math.PI,
                    ref finalDirection,
                    ref finalPosition);
            }


            //Find the relevent polar and azimuthal pair for the direction
            PolarAzimuthalAngles _rotationalAnglesOfPrincipalSourceAxis = SourceToolbox.GetPolarAzimuthalPairFromDirection(_newDirectionOfPrincipalSourceAxis);

            //Translation and source rotation
            SourceToolbox.UpdateDirectionPositionAfterGivenFlags(
                ref finalPosition,
                ref finalDirection,
                _rotationalAnglesOfPrincipalSourceAxis,
                _translationFromOrigin,
                _rotationAndTranslationFlags);

            var photon = new Photon(finalPosition, finalDirection, tissue, _initialTissueRegionIndex, Rng);

            return(photon);
        }