/// <summary> /// Evaluates the spatial frequency and temporal frequency resolved reflectance /// calculating the Fourier transform of the NURBS curve R(t) at the /// required spatial frequency for the specified optical properties. /// The computed FT is analitycal or discrete according to the boolean value 'analyticIntegration'. /// </summary> /// <param name="ops">optical properties</param> /// <param name="fxs">spatial frequency</param> /// <param name="fts">temporal frequancy</param> /// <returns>spatial frequency and temporal frequancy resolved reflectance</returns> public override IEnumerable <Complex> ROfFxAndFt(IEnumerable <OpticalProperties> ops, IEnumerable <double> fxs, IEnumerable <double> fts) { bool analyticIntegration = false; double fx_ref; Complex transformedValue; foreach (var op in ops) { if (analyticIntegration) { foreach (var fx in fxs) { fx_ref = fx * _opReference.Musp / op.Musp; double exponentialterm = op.Mua * v * _opReference.Musp / op.Musp; if (fx_ref <= _sfdGenerator.SpaceValues.MaxValue) { foreach (var ft in fts) { transformedValue = _sfdGenerator.EvaluateNurbsCurveFourierTransform(fx_ref, exponentialterm, ft * _opReference.Musp / op.Musp); yield return(Math.PI * transformedValue); } } else { foreach (var ft in fts) { yield return(new Complex(0.0, 0.0)); } } } } else { var time = _sfdGenerator.TimeKnotSpanPolynomialCoefficients.Select(span => span.GetKnotSpanMidTime()); var deltaT = _sfdGenerator.TimeKnotSpanPolynomialCoefficients.Select(span => span.GetKnotSpanDeltaT()); foreach (var fx in fxs) { fx_ref = fx * op.Musp / _opReference.Musp; if (fx_ref <= _sfdGenerator.SpaceValues.MaxValue) { var ROfT = ROfFxAndTime(op.AsEnumerable(), fx_ref.AsEnumerable(), time); foreach (var ft in fts) { yield return(LinearDiscreteFourierTransform.GetFourierTransform(time.ToArray(), ROfT.ToArray(), deltaT.ToArray(), ft * _opReference.Musp / op.Musp)); } } else { foreach (var ft in fts) { yield return(new Complex(0.0, 0.0)); } } } } } }
/// <summary> /// Evaluates the temporal frequency and space resolved reflectance at a source /// detector separation rho for a modulation frequency ft,for the specified /// optical properties. It calculates the Fourier transform of the NURBS /// curve R(t) at the required source detector separation. /// The used FT is analitycal or discrete according to the boolean value 'analyticIntegration'. /// </summary> /// <param name="ops">optical properties</param> /// <param name="rhos">source detector separation</param> /// <param name="fts">modulation frequency</param> /// <returns>reflectance intensity</returns> public override IEnumerable <Complex> ROfRhoAndFt(IEnumerable <OpticalProperties> ops, IEnumerable <double> rhos, IEnumerable <double> fts) { bool analyticIntegration = false; double rho_ref; foreach (var op in ops) { if (analyticIntegration) { foreach (var rho in rhos) { double exponentialTerm = op.Mua * v * _opReference.Musp / op.Musp; rho_ref = rho * op.Musp / _opReference.Musp; if (rho_ref <= _rdGenerator.SpaceValues.MaxValue) { foreach (var ft in fts) { yield return(GetScalingFactor(op, 2) * _rdGenerator.EvaluateNurbsCurveFourierTransform(rho_ref, exponentialTerm, ft * _opReference.Musp / op.Musp)); } } else { foreach (var ft in fts) { yield return(new Complex(0.0, 0.0)); } } } } else { //var time = _rdGenerator.NativeTimes; var time = _rdGenerator.NativeTimes.ToArray(); for (int i = 0; i < time.Length; i++) { time[i] = time[i] * _opReference.Musp / op.Musp; } var deltaT = GetDeltaT(time); foreach (var rho in rhos) { if (rho * _opReference.Musp / op.Musp <= _rdGenerator.SpaceValues.MaxValue) { var ROfT = ROfRhoAndTime(op.AsEnumerable(), rho.AsEnumerable(), time); foreach (var ft in fts) { yield return(LinearDiscreteFourierTransform.GetFourierTransform(time.ToArray(), ROfT.ToArray(), deltaT.ToArray(), ft)); } } else { foreach (var ft in fts) { yield return(new Complex(0.0, 0.0)); } } } } } }