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(); } }
/// <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(); } }
/// <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); }
/// <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; }
/// <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; }
/// <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; }
/// <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) { }
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; }
/// <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; }
/// <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(); }
/// <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; }
/// <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; }
/// <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) { }
/// <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; }
/// <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; }
/// <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); }