/// <summary> /// Extrapolates the linear decay of the log of the tail of the curve and integrates /// analitically from tMax to infinity to evaluate the steady state signal /// </summary> /// <param name="generator">NurbsGenerator</param> /// <param name="space_ref">spatial coordiante</param> /// <param name="op">optical Properties</param> /// <returns>Integral value of the curve extrapolated outside the time range</returns> private double ExtrapolateIntegralValueOutOfRange(INurbs generator, double space_ref, OpticalProperties op) { double area; double deltaT = 0.01;//ns double scalingFactor = GetScalingFactor(op, 3); double lR2 = Math.Log10(generator.ComputeSurfacePoint(generator.TimeValues.MaxValue, space_ref)); double lR1 = Math.Log10(generator.ComputeSurfacePoint(generator.TimeValues.MaxValue - deltaT, space_ref)); double slope = (lR2 - lR1) / (deltaT); double intercept = -slope * generator.TimeValues.MaxValue + lR1; area = -Math.Pow(10.0, intercept + slope * generator.TimeValues.MaxValue) * Math.Exp(-op.Mua * v * generator.TimeValues.MaxValue) / (slope - op.Mua); return(area); }
/// <summary> /// Returns the reflectance at spatial frequency, fx, and time, t, scaling the /// reference fx-time resolved reflectance. /// If a point of the reference reflectance outside the time/spatial frequancy range /// of the surface is required, the value is extrapolated using the first derivative /// along the time/spatial frequency dimension. /// If the required point is outside both ranges a linear combination of the /// two derivatives is used. /// </summary> /// <param name="ops">optical properties</param> /// <param name="fxs">spatial frequency</param> /// <param name="ts">time</param> /// <returns>spatial frequency and time resolved reflectance</returns> public override IEnumerable <double> ROfFxAndTime(IEnumerable <OpticalProperties> ops, IEnumerable <double> fxs, IEnumerable <double> ts) { double scalingFactor; double fx_ref; double t_ref; double scaledValue; foreach (var op in ops) { scalingFactor = GetScalingFactor(op, 1); foreach (var fx in fxs) { fx_ref = fx * _opReference.Musp / op.Musp; foreach (var t in ts) { t_ref = t * op.Musp / _opReference.Musp; if (fx_ref > _sfdGenerator.SpaceValues.MaxValue || t_ref > _sfdGenerator.TimeValues.MaxValue) { yield return(0.0); } else { scaledValue = _sfdGenerator.ComputeSurfacePoint(t_ref, fx_ref); scaledValue = CheckIfValidOutput(scaledValue); yield return(scalingFactor * scaledValue * Math.Exp(-op.Mua * v * t)); } } } } }
/// <summary> /// Returns the reflectance at radial distance rho and time t scaling the /// reference rho-time resolved reflectance. /// The returned value is forced to zero if the time t is smaller then the /// minimal time of flight required to reach a detector at a distance rho. /// If a point of the reference reflectance outside the time range of the /// surface is required, the value is extrapolated using the linear /// approximation of the logarithm of R for two points placed at the end of /// the time range [Tmax - 0.1ns, Tmax]. /// If the required point is outside the radial range a linear extarpolation /// is used, based on the value of R at [0.95*RhoMax, RhoMax]. /// If the required point is outside both ranges a linear combination of the /// two extrapolations is adopted. /// </summary> /// <param name="ops">optical properties</param> /// <param name="rhos">source detector separation</param> /// <param name="ts">time</param> /// <returns>space and time resolved reflectance at rho and t</returns> public override IEnumerable <double> ROfRhoAndTime(IEnumerable <OpticalProperties> ops, IEnumerable <double> rhos, IEnumerable <double> ts) { double scalingFactor; double rho_ref; double t_ref; double scaledValue; foreach (var op in ops) { scalingFactor = GetScalingFactor(op, 3); foreach (var rho in rhos) { rho_ref = rho * op.Musp / _opReference.Musp; foreach (var t in ts) { t_ref = t * op.Musp / _opReference.Musp; if (t_ref < _rdGenerator.GetMinimumValidTime(rho_ref)) { scaledValue = 0.0; } else { scaledValue = _rdGenerator.ComputeSurfacePoint(t_ref, rho_ref); } if ((rho_ref > _rdGenerator.SpaceValues.MaxValue || t_ref > _rdGenerator.TimeValues.MaxValue) && t_ref > _rdGenerator.GetMinimumValidTime(rho_ref)) { scaledValue = _rdGenerator.ComputePointOutOfSurface(t_ref, rho_ref, scaledValue); } scaledValue = CheckIfValidOutput(scaledValue); yield return(scalingFactor * scaledValue * Math.Exp(-op.Mua * v * t)); } } } }