public override double StationaryFluence(double rho, double z, DiffusionParameters dp) { var sqDiamOver8 = BeamDiameter * BeamDiameter / 8; var hprime = -1 / (2 * dp.A * dp.D); // = -1/dp.zb var lambda = 3 * dp.musTilde * (dp.mutr + dp.gTilde * dp.mutTilde); double expVar3 = Math.Exp(-dp.mutTilde * z); var rhoInternal = Math.Abs(rho); if (rhoInternal <= 0) { rhoInternal = 1e-9; } double fluence = 0.0; for (int i = 0; i < hankelPoints.Length; i++) { double scaledHankelPoint = hankelPoints[i] / rhoInternal; double scaledHankelPointSq = scaledHankelPoint * scaledHankelPoint; double sqrtArg = Math.Sqrt(scaledHankelPointSq + dp.mueff * dp.mueff); double expVar1 = Math.Exp(-sqDiamOver8 / 4 * scaledHankelPointSq) * scaledHankelPoint; double expVar2 = Math.Exp(-sqrtArg * z); double denom1 = 2 * (scaledHankelPointSq + dp.mueff * dp.mueff - dp.mutTilde * dp.mutTilde); double phi1 = 3 / 2 * dp.gTilde * dp.musTilde * expVar2 / (hprime - sqrtArg); double phi2 = lambda * (dp.mutTilde - hprime) * expVar2 / (denom1 * (hprime - sqrtArg)); double phi3 = lambda * expVar3 / denom1; fluence += (phi1 + phi2 + phi3) * sqDiamOver8 * expVar1 * hankelWeights[i]; } //fluence /= rhoInternal; // scale back... diffuse component only... return(fluence / rhoInternal + Math.Exp(-rhoInternal * rhoInternal / sqDiamOver8) * Math.Exp(-dp.mutTilde * z)); //diffuse plus collimated }
/// <summary> /// Evaulation of the temporally resolved radial reflectance using the distribution of /// source-image point sources. /// </summary> /// <param name="dp">DiffusionParamters object</param> /// <param name="rho">radial location</param> /// <param name="t">time</param> /// <param name="fr1">Fresnel Moment 1</param> /// <param name="fr2">Fresnel Moment 2</param> /// <returns>reflectance</returns> public override double TemporalReflectance(DiffusionParameters dp, double rho, double t, double fr1, double fr2) { return(GetBackwardHemisphereIntegralDiffuseReflectance( TemporalFluence(dp, rho, 0.0, t), TemporalFlux(dp, rho, 0.0, t), fr1, fr2)); }
/// <summary> /// Evaluates the temporal frequency radially resolved reflectance using the distribution of /// the source-image point source configuration. /// </summary> /// <param name="dp">DiffusionParameters object</param> /// <param name="rho">radial location</param> /// <param name="k">wavevector</param> /// <param name="fr1">Fresnel Moment 1</param> /// <param name="fr2">Fresnel Moment 2</param> /// <returns></returns> public override Complex TemporalFrequencyReflectance(DiffusionParameters dp, double rho, Complex k, double fr1, double fr2) { var dpLocalReal = DiffusionParameters.Copy(dp); var dpLocalImag = DiffusionParameters.Copy(dp); Func <DiffusionParameters, double, Complex, double, Complex> kernelFunc = (dpLocal, r, kLocal, zp) => { dpLocal.zp = zp; return (_pointSourceForwardSolver.TemporalFrequencyReflectance( dpLocal, r, kLocal, fr1, fr2)); }; return ((CalculatorToolbox.EvaluateDistributedExponentialLineSourceIntegral( zp => kernelFunc(dpLocalReal, rho, k, zp).Real, dp.mutTilde) + Complex.ImaginaryOne * CalculatorToolbox.EvaluateDistributedExponentialLineSourceIntegral( zp => kernelFunc(dpLocalImag, rho, k, zp).Imaginary, dp.mutTilde) ) * dp.musTilde); }
public static double TemporalPointSourceGreensFunctionZFlux( DiffusionParameters dp, double r, double zr, double t) { return(0.5 / Math.Pow(4.0 * Math.PI * dp.D * dp.cn, 1.5) / Math.Pow(t, 2.5) * Math.Exp(-dp.mua * dp.cn * t) * zr * Math.Exp(-r * r / (4.0 * dp.D * dp.cn * t))); }
public static double SteadyStateGaussianBeamSurfaceFluence(DiffusionParameters dp, double diam, double rho) { var sqDiamOver8 = diam * diam / 8; var hprime = -1 / (2 * dp.A * dp.D); var lambda = 3 * dp.musTilde * (dp.mutr + dp.gTilde * dp.mutTilde); if (rho <= 0) { rho = 1e-9; } double fluence = 0.0; for (int i = 0; i < hankelPoints.Length; i++) { double scaledHankelPoint = hankelPoints[i] / rho; double scaledHankelPointSq = scaledHankelPoint * scaledHankelPoint; double sqrtArg = Math.Sqrt(scaledHankelPointSq + dp.mueff * dp.mueff); double exp1mod = Math.Exp(-sqDiamOver8 / 4 * scaledHankelPointSq) * scaledHankelPoint; double denom1 = 2 * (scaledHankelPointSq + dp.mueff * dp.mueff - dp.mutTilde * dp.mutTilde); double phi1 = 3 / 2 * dp.gTilde * dp.musTilde * sqDiamOver8 * exp1mod / (hprime - sqrtArg); double phi2 = lambda * sqDiamOver8 * exp1mod * (dp.mutTilde - hprime) / (denom1 * (hprime - sqrtArg)); double phi3 = lambda * sqDiamOver8 * exp1mod / denom1; fluence += (phi1 + phi2 + phi3) * hankelWeights[i]; } return(fluence / rho); // scale back... }
/// <summary> /// Infinite media diffusion Green's functions for space and time for an /// origin of r = 0 and t = 0. /// </summary> /// <param name="dp">diffusion parameters object</param> /// <param name="r">radial location</param> /// <param name="t">time</param> /// <returns>evaluation of the Green's function</returns> public static double TemporalPointSourceGreensFunction( DiffusionParameters dp, double r, double t) { var tempVar = 4.0 * dp.D * dp.cn * t; return(dp.cn * Math.Exp(-dp.mua * dp.cn * t) / Math.Pow(Math.PI * tempVar, 1.5) * Math.Exp(-r * r / tempVar)); }
/// <summary> /// Evaluation of the radially resolved stationary reflectance for the distribution of point sources in /// the source-image configuration. /// </summary> /// <param name="dp">DiffusionParameters object</param> /// <param name="rho">radial position</param> /// <param name="fr1">Fresnel Reflection Moment 1</param> /// <param name="fr2">Fresnel Reflection Moment 2</param> /// <returns>reflectance</returns> public override double StationaryReflectance( DiffusionParameters dp, double rho, double fr1, double fr2) { return(GetBackwardHemisphereIntegralDiffuseReflectance( StationaryFluence(rho, 0.0, dp), StationaryFlux(rho, 0.0, dp), fr1, fr2)); }
/// <summary> /// Evaluate the temporally-radially resolved fluence using the point source-image configuration /// </summary> /// <param name="dp">DiffusionParameters object</param> /// <param name="rho">radial location</param> /// <param name="z">depth location</param> /// <param name="t">time</param> /// <returns>fluence</returns> public override double TemporalFluence( DiffusionParameters dp, double rho, double z, double t) { return(DiffusionGreensFunctions.TemporalPointSourceImageGreensFunction(dp, CalculatorToolbox.GetRadius(rho, z - dp.zp), CalculatorToolbox.GetRadius(rho, z + dp.zp + 2 * dp.zb), t)); }
/// <summary> /// Infinte media diffusion Green's function for space and temporal frequency /// </summary> /// <param name="dp">diffusion parameters object</param> /// <param name="r">radial location</param> /// <param name="k"></param> /// <returns></returns> public static Complex TemporalFrequencyPointSourceGreensFunction( DiffusionParameters dp, double r, Complex k) { return(Math.Exp(-k.Real * r) / r * ( Math.Cos(k.Imaginary * r) - Complex.ImaginaryOne * Math.Sin(k.Imaginary * r) ) / (4.0 * Math.PI * dp.D)); }
public override Complex TemporalFrequencyReflectance( DiffusionParameters dp, double rho, Complex k, double fr1, double fr2) { return(GetBackwardHemisphereIntegralDiffuseReflectance( TemporalFrequencyFluence(dp, rho, 0.0, k), TemporalFrequencyZFlux(dp, rho, 0.0, k), fr1, fr2)); }
public override Complex TemporalFrequencyFluence(DiffusionParameters dp, double rho, double z, Complex k) { return(DiffusionGreensFunctions.TemporalFrequencyPointSourceImageGreensFunction(dp, CalculatorToolbox.GetRadius(rho, z - dp.zp), CalculatorToolbox.GetRadius(rho, z + dp.zp + 2 * dp.zb), k)); }
/// <summary> /// Evaluation of the reflectance according to Carp et al. FILL IN (2004). /// </summary> /// <param name="dp">DiffusionParameters object</param> /// <param name="rho">radial location</param> /// <param name="fr1">First Fresnel Reflection Moment, not applied here</param> /// <param name="fr2">Second Fresnel Reflection Moment, not applied here</param> /// <returns></returns> public override double StationaryReflectance(DiffusionParameters dp, double rho, double fr1, double fr2) { var normFactor = 8 / (Math.PI * BeamDiameter * BeamDiameter) / (2 * dp.A); //var surfaceFluence = //return normFactor * surfaceFluence; return(normFactor * SteadyStateGaussianBeamSurfaceFluence(dp, BeamDiameter, rho)); }
/// <summary> /// Evaluate the time-independent, one dimensional spatial frequency, depth resolved /// fluence. /// </summary> /// <param name="dp">DiffusionParameters object</param> /// <param name="fx">spatial frequency</param> /// <param name="z">depth</param> /// <returns>fluence</returns> public static double StationaryOneDimensionalSpatialFrequencyFluence( DiffusionParameters dp, double fx, double z) { var mueffPrime = Math.Sqrt(dp.mueff * dp.mueff + 4.0 * Math.PI * Math.PI * fx * fx); return(dp.musTilde / dp.D / (mueffPrime * mueffPrime - dp.mutTilde * dp.mutTilde) * ( Math.Exp(-dp.mutTilde * z) - (1.0 + dp.mutTilde * dp.zb) / (1.0 + mueffPrime * dp.zb) * Math.Exp(-mueffPrime * z))); }
/// <summary> /// Evaluate the stationary radially resolved z-flux with the point source-image /// configuration /// </summary> /// <param name="rho">radial location</param> /// <param name="z">depth location</param> /// <param name="dp">DiffusionParamters object</param> /// <returns></returns> public double StationaryFlux(double rho, double z, DiffusionParameters dp) { var zSource = z - dp.zp; var zImage = z + dp.zp + 2 * dp.zb; return (DiffusionGreensFunctions.StationaryPointSourceImageGreensFunctionZFlux(dp, CalculatorToolbox.GetRadius(rho, zSource), zSource, CalculatorToolbox.GetRadius(rho, zImage), zImage)); }
/// <summary> /// Evaluates the depth resolved diffuse spatial frequency flux in the z-direction. /// </summary> /// <param name="dp">DiffusionParameters object</param> /// <param name="fx">spatial frequency</param> /// <param name="z">depth</param> /// <returns>z-flux</returns> public static double StationaryOneDimensionalSpatialFrequencyZFlux( DiffusionParameters dp, double fx, double z) { var mueffPrime = Math.Sqrt(dp.mueff * dp.mueff + 4.0 * Math.PI * Math.PI * fx * fx); // need to check that this is the "real" flux and not the assumed negative value... return(dp.musTilde / (mueffPrime * mueffPrime - dp.mutTilde * dp.mutTilde) * (dp.mutTilde * Math.Exp(-dp.mutTilde * z) - mueffPrime * (1.0 + dp.mutTilde * dp.zb) / (1.0 + mueffPrime * dp.zb) * Math.Exp(-mueffPrime * z))); }
/// <summary> /// Evaluate the temporally-radially resolved z-flux using the point source-image configuration /// </summary> /// <param name="dp">DiffusionParameters object</param> /// <param name="rho">radial location</param> /// <param name="z">depth location</param> /// <param name="t">time</param> /// <returns></returns> public double TemporalFlux( DiffusionParameters dp, double rho, double z, double t) { var zSource = z - dp.zp; var zImage = z + dp.zp + 2 * dp.zb; return(DiffusionGreensFunctions.TemporalPointSourceImageGreensFunctionZFlux(dp, CalculatorToolbox.GetRadius(rho, zSource), zSource, CalculatorToolbox.GetRadius(rho, zImage), zImage, t)); }
public Complex TemporalFrequencyZFlux( DiffusionParameters dp, double rho, double z, Complex k) { var zSource = z - dp.zp; var zImage = z + dp.zp + 2 * dp.zb; return(DiffusionGreensFunctions.TemporalFrequencyPointSourceImageGreensFunctionZFlux(dp, CalculatorToolbox.GetRadius(rho, zSource), zSource, CalculatorToolbox.GetRadius(rho, zImage), zImage, k)); }
private static DiffusionParameters[] GetDiffusionParameters(IOpticalPropertyRegion[] regions) { var diffusionParameters = new DiffusionParameters[regions.Length]; for (int i = 0; i < regions.Length; i++) { diffusionParameters[i] = DiffusionParameters.Create( new OpticalProperties(regions[i].RegionOP.Mua, regions[i].RegionOP.Musp, regions[i].RegionOP.G, regions[i].RegionOP.N), ForwardModel.SDA); } return(diffusionParameters); }
private double StationaryFlux(double rho, double z, DiffusionParameters dp) { var dpLocal = DiffusionParameters.Copy(dp); return(CalculatorToolbox.EvaluateDistributedExponentialLineSourceIntegral( zp => { dpLocal.zp = zp; return _pointSourceForwardSolver.StationaryFlux(rho, z, dpLocal); }, dp.mutTilde) * dp.musTilde); }
/// <summary> /// Vectorized ROfFx. Solves SDA using Cuccia et al JBO, March/April 2009 /// </summary> /// <param name="ops">set of optical properties of the medium</param> /// <param name="fxs">spatial frequencies (1/mm)</param> /// <returns></returns> public override IEnumerable <double> ROfFx( IEnumerable <OpticalProperties> ops, IEnumerable <double> fxs) { foreach (var op in ops) { DiffusionParameters dp = DiffusionParameters.Create(op, this.ForwardModel); foreach (var fx in fxs) { yield return(SFDDiffusionForwardSolver.StationaryOneDimensionalSpatialFrequencyFluence( dp, fx, 0.0) / 2 / dp.A); // this is not the true mathematical derivation given the source condition! but is the WIDELY used in the lit } } }
/// <summary> /// Evaluation of the temporally and radially resolved fluence rate using the distribution of /// source-image point sources. /// </summary> /// <param name="dp">DiffusionParameters object</param> /// <param name="rho">radial location</param> /// <param name="z">depth location</param> /// <param name="t">time</param> /// <returns>fluence rate</returns> public override double TemporalFluence( DiffusionParameters dp, double rho, double z, double t) { var dpLocal = DiffusionParameters.Copy(dp); return(CalculatorToolbox.EvaluateDistributedExponentialLineSourceIntegral( zp => { dpLocal.zp = zp; return _pointSourceForwardSolver.TemporalFluence(dpLocal, rho, z, t); }, dp.mutTilde) * dp.musTilde); }
public override IEnumerable <double> ROfRho( IEnumerable <OpticalProperties> ops, IEnumerable <double> rhos) { foreach (var op in ops) { DiffusionParameters dp = DiffusionParameters.Create(op, this.ForwardModel); var fr1 = CalculatorToolbox.GetCubicFresnelReflectionMomentOfOrder1(op.N); var fr2 = CalculatorToolbox.GetCubicFresnelReflectionMomentOfOrder2(op.N); foreach (var rho in rhos) { yield return(StationaryReflectance(dp, rho, fr1, fr2)); } } }
public override IEnumerable <double> FluenceOfRhoAndZ( IEnumerable <OpticalProperties> ops, IEnumerable <double> rhos, IEnumerable <double> zs) { foreach (var op in ops) { DiffusionParameters dp = DiffusionParameters.Create(op, this.ForwardModel); foreach (var rho in rhos) { foreach (var z in zs) { yield return(StationaryFluence(rho, z, dp)); } } } }
public override IEnumerable <double> FluenceOfFxAndZ( IEnumerable <OpticalProperties> ops, IEnumerable <double> fxs, IEnumerable <double> zs) { foreach (var op in ops) { DiffusionParameters dp = DiffusionParameters.Create(op, this.ForwardModel); foreach (var fx in fxs) { foreach (var z in zs) { yield return(SFDDiffusionForwardSolver.StationaryOneDimensionalSpatialFrequencyFluence( dp, fx, z)); } } } }
public override IEnumerable <Complex> ROfRhoAndFt(IEnumerable <OpticalProperties> ops, IEnumerable <double> rhos, IEnumerable <double> fts) { foreach (var op in ops) { DiffusionParameters dp = DiffusionParameters.Create(op, this.ForwardModel); var fr1 = CalculatorToolbox.GetCubicFresnelReflectionMomentOfOrder1(op.N); var fr2 = CalculatorToolbox.GetCubicFresnelReflectionMomentOfOrder2(op.N); foreach (var rho in rhos) { foreach (var ft in fts) { Complex k = ((op.Mua * dp.cn + Complex.ImaginaryOne * ft * 2 * Math.PI) / (dp.cn * dp.D)).SquareRoot(); yield return(TemporalFrequencyReflectance(dp, rho, k, fr1, fr2)); } } } }
public override IEnumerable <double> FluenceOfRhoAndZAndTime( IEnumerable <OpticalProperties> ops, IEnumerable <double> rhos, IEnumerable <double> zs, IEnumerable <double> ts) { foreach (var op in ops) { DiffusionParameters dp = DiffusionParameters.Create(op, this.ForwardModel); foreach (var rho in rhos) { foreach (var z in zs) { foreach (var t in ts) { yield return(TemporalFluence(dp, rho, z, t)); } } } } }
public override IEnumerable <Complex> FluenceOfRhoAndZAndFt( IEnumerable <OpticalProperties> ops, IEnumerable <double> rhos, IEnumerable <double> zs, IEnumerable <double> fts) { foreach (var op in ops) { DiffusionParameters dp = DiffusionParameters.Create(op, this.ForwardModel); foreach (var rho in rhos) { foreach (var z in zs) { foreach (var ft in fts) { Complex k = ((op.Mua * dp.cn + Complex.ImaginaryOne * ft * 2 * Math.PI) / (dp.cn * dp.D)).SquareRoot(); yield return(TemporalFrequencyFluence(dp, rho, z, k).Magnitude); } } } } }
public override IEnumerable <double> FluenceOfFxAndZAndTime( IEnumerable <OpticalProperties> ops, IEnumerable <double> fxs, IEnumerable <double> zs, IEnumerable <double> ts) { foreach (var op in ops) { DiffusionParameters dp = DiffusionParameters.Create(op, this.ForwardModel); foreach (var fx in fxs) { foreach (var z in zs) { foreach (var t in ts) { yield return (HankelTransform.DigitalFilterOfOrderZero( fx, rho => TemporalFluence(dp, rho, z, t))); } } } } }
/// <summary> /// Evaluate the stationary radially resolved fluence with the point source-image /// configuration /// </summary> /// <param name="rho">radial location</param> /// <param name="z">depth location</param> /// <param name="dp">DiffusionParameters object</param> /// <returns>fluence</returns> public override double StationaryFluence(double rho, double z, DiffusionParameters dp) { return(DiffusionGreensFunctions.StationaryPointSourceImageGreensFunction(dp, CalculatorToolbox.GetRadius(rho, z - dp.zp), CalculatorToolbox.GetRadius(rho, z + dp.zp + 2 * dp.zb))); }
public override Complex TemporalFrequencyFluence(DiffusionParameters dp, double rho, double z, Complex k) { throw new NotImplementedException(); }