public void VerifyROfRhoMonteCarloMeasuredNoNoiseMonteCarloModel() { var independentValues = new double[] { 1, 2, 3, 4, 5, 6 }; // rho [mm] var actualProperties = new OpticalProperties(mua: 0.01, musp: 1.0, g: 0.8, n: 1.4); var initialGuess = new OpticalProperties(mua: 0.02, musp: 1.2, g: 0.8, n: 1.4); var simulatedMeasured = ComputationFactory.ComputeReflectance( ForwardSolverType.MonteCarlo, SolutionDomainType.ROfRho, ForwardAnalysisType.R, new object[] { new[] { actualProperties }, independentValues }); var standardDeviation = simulatedMeasured; double[] fit = ComputationFactory.SolveInverse( ForwardSolverType.MonteCarlo, OptimizerType.MPFitLevenbergMarquardt, SolutionDomainType.ROfRho, simulatedMeasured, standardDeviation, InverseFitType.MuaMusp, new object[] { new[] { initialGuess }, independentValues }); var convergedMua = fit[0]; var convergedMusp = fit[1]; Assert.Less(Math.Abs(convergedMua - 0.01), 1e-6); Assert.Less(Math.Abs(convergedMusp - 1.0), 1e-6); }
public void VerifyROfRhoMonteCarloMeasuredNoNoiseSDAModel() { var independentValues = new double[] { 10, 11, 12, 13, 14, 15 }; // rho [mm] var actualProperties = new OpticalProperties(mua: 0.01, musp: 1.0, g: 0.8, n: 1.4); var initialGuess = new OpticalProperties(mua: 0.02, musp: 1.2, g: 0.8, n: 1.4); var lowerBounds = new double[] { 0, 0, 0, 0 }; var upperBounds = new double[] { double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity }; var simulatedMeasured = ComputationFactory.ComputeReflectance( ForwardSolverType.MonteCarlo, SolutionDomainType.ROfRho, ForwardAnalysisType.R, new object[] { new[] { actualProperties }, independentValues }); var standardDeviation = simulatedMeasured; double[] fit = ComputationFactory.SolveInverse( ForwardSolverType.DistributedPointSourceSDA, OptimizerType.MPFitLevenbergMarquardt, SolutionDomainType.ROfRho, simulatedMeasured, standardDeviation, InverseFitType.MuaMusp, new object[] { new[] { initialGuess }, independentValues }, lowerBounds, upperBounds); var convergedMua = fit[0]; var convergedMusp = fit[1]; Assert.Less(Math.Abs(convergedMua - 0.01), 0.002); Assert.Less(Math.Abs(convergedMusp - 1.0), 0.11); }
public void GetVectorizedIndependentVariableQueryNew_can_be_called_using_enum_inputs() { var test = ComputationFactory.ComputeReflectance( ForwardSolverType.MonteCarlo, SolutionDomainType.ROfRho, ForwardAnalysisType.R, new object[] { new[] { new OpticalProperties(0.01, 1, 0.8, 1.4) }, new double[] { 1, 2, 3 } }); }
public void validate_ROfRhoAndTime_With_Wavelength() { // used values for tissue=liver var scatterer = new PowerLawScatterer(0.84, 0.55); var hbAbsorber = new ChromophoreAbsorber(ChromophoreType.Hb, 66); var hbo2Absorber = new ChromophoreAbsorber(ChromophoreType.HbO2, 124); var fatAbsorber = new ChromophoreAbsorber(ChromophoreType.Fat, 0.02); var waterAbsorber = new ChromophoreAbsorber(ChromophoreType.H2O, 0.87); var n = 1.4; var wvs = new double[] { 650, 700 }; var rhos = new double[] { 0.5, 1.625 }; var times = new double[] { 0.05, 0.10 }; var tissue = new Tissue( new IChromophoreAbsorber[] { hbAbsorber, hbo2Absorber, fatAbsorber, waterAbsorber }, scatterer, "test_tissue", n); var ops = wvs.Select(wv => tissue.GetOpticalProperties(wv)).ToArray(); var rVsWavelength = ComputationFactory.ComputeReflectance( new PointSourceSDAForwardSolver(), SolutionDomainType.ROfRhoAndTime, ForwardAnalysisType.R, new object[] { ops, rhos, times }); // return from ROfRhoAndTime is new double[ops.Length * rhos.Length * ts.Length]; // order is: (ops0,rhos0,ts0), (ops0,rhos0,ts1)...(ops0,rhos0,tsnt-1) // (ops0,rhos1,ts0), (ops0,rhos1,ts1)...(ops0,rhos1,tsnt-1) // ... // (ops0,rhosnr-1,ts0),.................(ops0,rhosnr-1,tsnt-1) // ... repeat above with ops1... // [0] -> ops0=650, rho0=0.5, ts0=0.05 Assert.IsTrue(Math.Abs(rVsWavelength[0] - 0.044606) < 0.000001); // API match // [1] -> ops0=650, rho0=0.5, ts1=0.10 Assert.IsTrue(Math.Abs(rVsWavelength[1] - 0.005555) < 0.000001); // [2] -> ops0=650, rho1=1.635, ts0=0.05 Assert.IsTrue(Math.Abs(rVsWavelength[2] - 0.036900) < 0.000001); // API match // [3] -> ops0=650, rho1=1.635, ts1=0.10 Assert.IsTrue(Math.Abs(rVsWavelength[3] - 0.005053) < 0.000001); // [4] -> ops1=700, rho0=0.5, ts0=0.05 Assert.IsTrue(Math.Abs(rVsWavelength[4] - 0.057894) < 0.000001); // API match // [5] -> ops1=700, rho0=0.5, ts1=0.10 Assert.IsTrue(Math.Abs(rVsWavelength[5] - 0.010309) < 0.000001); // [6] -> ops1=700, rho1=1.635, ts0=0.05 Assert.IsTrue(Math.Abs(rVsWavelength[6] - 0.048493) < 0.000001); // API match // [7] -> ops1=700, rho1=1.635, ts1=0.10 Assert.IsTrue(Math.Abs(rVsWavelength[7] - 0.009434) < 0.000001); }
public void validate_ROfFxAndTime_With_Wavelength() { // used values for tissue=liver var scatterer = new PowerLawScatterer(0.84, 0.55); var hbAbsorber = new ChromophoreAbsorber(ChromophoreType.Hb, 66); var hbo2Absorber = new ChromophoreAbsorber(ChromophoreType.HbO2, 124); var fatAbsorber = new ChromophoreAbsorber(ChromophoreType.Fat, 0.02); var waterAbsorber = new ChromophoreAbsorber(ChromophoreType.H2O, 0.87); var n = 1.4; var wvs = new double[] { 650, 700 }; var fxs = new double[] { 0.0, 0.5 }; var times = new double[] { 0.05, 0.10 }; var tissue = new Tissue( new IChromophoreAbsorber[] { hbAbsorber, hbo2Absorber, fatAbsorber, waterAbsorber }, scatterer, "test_tissue", n); var ops = wvs.Select(wv => tissue.GetOpticalProperties(wv)).ToArray(); var rVsWavelength = ComputationFactory.ComputeReflectance( new DistributedPointSourceSDAForwardSolver(), SolutionDomainType.ROfFxAndTime, ForwardAnalysisType.R, new object[] { ops, fxs, times }); // return from ROfFxAndTime is new double[ops.Length * fxs.Length * ts.Length]; // order is: (ops0,fxs0,ts0), (ops0,fxs0,ts1)...(ops0,fxs0,tsnt-1) // (ops0,fxs1,ts0), (ops0,fxs1,ts1)...(ops0,fxs1,tsnt-1) // ... // (ops0,fxsnf-1,ts0),................(ops0,fxsnf-1,tsnt-1) // ... repeat above with ops1... // [0] -> ops0=650, fx0=0.0, ts0=0.05 Assert.IsTrue(Math.Abs(rVsWavelength[0] - 1.558702) < 0.000001); // [1] -> ops0=650, fx0=0.0, ts1=0.10 Assert.IsTrue(Math.Abs(rVsWavelength[1] - 0.391871) < 0.000001); // [2] -> ops0=650, fx1=0.5, ts0=0.05 Assert.IsTrue(Math.Abs(rVsWavelength[2] - 5.023055e-12) < 0.000001e-12); // [3] -> ops0=650, fx1=0.5, ts1=0.10 Assert.IsTrue(Math.Abs(rVsWavelength[3] - 1.032586e-13) < 0.000001e-13); // [4] -> ops1=700, fx0=0.0, ts0=0.05 Assert.IsTrue(Math.Abs(rVsWavelength[4] - 2.218329) < 0.000001); // [5] -> ops1=700, fx1=0.5, ts1=0.10 Assert.IsTrue(Math.Abs(rVsWavelength[5] - 0.797200) < 0.000001); // [6] -> ops1=700, fx0=0.0, ts0=0.05 Assert.IsTrue(Math.Abs(rVsWavelength[6] - 1.347053e-12) < 0.000001e-12); // [7] -> ops1=700, fx1=0.5, ts1=0.10 Assert.IsTrue(Math.Abs(rVsWavelength[7] - 2.052883e-13) < 0.000001e-13); }
public InverseSolutionResult SolveInverse() { var lowerBounds = new double[] { 0, 0, 0, 0 }; var upperBounds = new double[] { double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity }; var measuredOpticalProperties = GetMeasuredOpticalProperties(); var measuredDataValues = GetSimulatedMeasuredData(); var dependentValues = measuredDataValues.ToArray(); var initGuessOpticalProperties = GetInitialGuessOpticalProperties(); var initGuessParameters = GetParametersInOrder(initGuessOpticalProperties); // replace unconstrained L-M optimization with constrained version // this solves problem of when distributed source solution produces neg OPs during inversion //var fit = ComputationFactory.SolveInverse( // InverseForwardSolverTypeOptionVM.SelectedValue, // OptimizerTypeOptionVM.SelectedValue, // SolutionDomainTypeOptionVM.SelectedValue, // dependentValues, // dependentValues, // set standard deviation, sd, to measured (works w/ or w/o noise) // InverseFitTypeOptionVM.SelectedValue, // initGuessParameters.Values.ToArray()); var fit = ComputationFactory.SolveInverse( InverseForwardSolverTypeOptionVM.SelectedValue, OptimizerTypeOptionVM.SelectedValue, SolutionDomainTypeOptionVM.SelectedValue, dependentValues, dependentValues, // set standard deviation, sd, to measured (works w/ or w/o noise) InverseFitTypeOptionVM.SelectedValue, initGuessParameters.Values.ToArray(), lowerBounds, upperBounds); var fitOpticalProperties = ComputationFactory.UnFlattenOpticalProperties(fit); var fitParameters = GetParametersInOrder(fitOpticalProperties); var resultDataValues = ComputationFactory.ComputeReflectance( InverseForwardSolverTypeOptionVM.SelectedValue, SolutionDomainTypeOptionVM.SelectedValue, ForwardAnalysisType.R, fitParameters.Values.ToArray()); var resultDataPoints = GetDataPoints(resultDataValues); return(new InverseSolutionResult { FitDataPoints = resultDataPoints, MeasuredOpticalProperties = (OpticalProperties[])measuredOpticalProperties, // todo: currently only supports homog OPs GuessOpticalProperties = (OpticalProperties[])initGuessOpticalProperties, // todo: currently only supports homog OPss FitOpticalProperties = fitOpticalProperties }); }
public double[] CalculateInitialGuess() { var opticalProperties = GetInitialGuessOpticalProperties(); var parameters = GetParametersInOrder(opticalProperties); return ComputationFactory.ComputeReflectance( InverseForwardSolverTypeOptionVM.SelectedValue, SolutionDomainTypeOptionVM.SelectedValue, ForwardAnalysisType.R, parameters.Values.ToArray()); }
public void validate_ComputeReflectance_can_be_called_using_IForwardSolver() { var reflectance = ComputationFactory.ComputeReflectance( new NurbsForwardSolver(), SolutionDomainType.ROfFx, ForwardAnalysisType.dRdMua, new object[] { new [] { new OpticalProperties(0.01, 1, 0.8, 1.4) }, new double[] { 1, 2, 3 } }); Assert.IsTrue(Math.Abs(reflectance[0] + 0.005571) < 0.000001); }
private double[] GetSimulatedMeasuredData() { var opticalProperties = GetMeasuredOpticalProperties(); var parameters = GetParametersInOrder(opticalProperties); var measuredData = ComputationFactory.ComputeReflectance( MeasuredForwardSolverTypeOptionVM.SelectedValue, SolutionDomainTypeOptionVM.SelectedValue, ForwardAnalysisType.R, parameters.Values.ToArray()); return measuredData.AddNoise(PercentNoise); }
public IDataPoint[][] ExecuteForwardSolver() { var opticalProperties = GetOpticalProperties(); var parameters = GetParametersInOrder(opticalProperties); var reflectance = ComputationFactory.ComputeReflectance( ForwardSolverTypeOptionVM.SelectedValue, SolutionDomainTypeOptionVM.SelectedValue, ForwardAnalysisTypeOptionVM.SelectedValue, parameters.Values.ToArray()); return(GetDataPoints(reflectance)); }
public void validate_ComputeReflectance_can_be_called_using_enum_forward_solver() { var reflectance = ComputationFactory.ComputeReflectance( ForwardSolverType.MonteCarlo, SolutionDomainType.ROfRho, ForwardAnalysisType.R, new object[] { // could have array of OPs, one set for each tissue region new[] { new OpticalProperties(0.01, 1, 0.8, 1.4) }, new double[] { 1, 2, 3 } }); Assert.IsTrue(Math.Abs(reflectance[0] - 0.021093) < 0.000001); }
public InverseSolutionResult SolveInverse() { var measuredOpticalProperties = GetMeasuredOpticalProperties(); var measuredDataValues = GetSimulatedMeasuredData(); var dependentValues = measuredDataValues.ToArray(); var initGuessOpticalProperties = GetInitialGuessOpticalProperties(); var initGuessParameters = GetParametersInOrder(initGuessOpticalProperties); double[] fit = ComputationFactory.SolveInverse( InverseForwardSolverTypeOptionVM.SelectedValue, OptimizerTypeOptionVM.SelectedValue, SolutionDomainTypeOptionVM.SelectedValue, dependentValues, dependentValues, // set standard deviation, sd, to measured (works w/ or w/o noise) InverseFitTypeOptionVM.SelectedValue, initGuessParameters.Values.ToArray()); var fitOpticalProperties = ComputationFactory.UnFlattenOpticalProperties(fit); var fitParameters = GetParametersInOrder(fitOpticalProperties); var resultDataValues = ComputationFactory.ComputeReflectance( InverseForwardSolverTypeOptionVM.SelectedValue, SolutionDomainTypeOptionVM.SelectedValue, ForwardAnalysisType.R, fitParameters.Values.ToArray()); var resultDataPoints = GetDataPoints(resultDataValues); return new InverseSolutionResult { FitDataPoints = resultDataPoints, MeasuredOpticalProperties = (OpticalProperties[])measuredOpticalProperties, // todo: currently only supports homog OPs GuessOpticalProperties = (OpticalProperties[])initGuessOpticalProperties, // todo: currently only supports homog OPss FitOpticalProperties = fitOpticalProperties }; }
public void validate_ROfFxAndFt_With_Wavelength() { // used values for tissue=liver var scatterer = new PowerLawScatterer(0.84, 0.55); var hbAbsorber = new ChromophoreAbsorber(ChromophoreType.Hb, 66); var hbo2Absorber = new ChromophoreAbsorber(ChromophoreType.HbO2, 124); var fatAbsorber = new ChromophoreAbsorber(ChromophoreType.Fat, 0.02); var waterAbsorber = new ChromophoreAbsorber(ChromophoreType.H2O, 0.87); var n = 1.4; var wvs = new double[] { 650, 700 }; var fxs = new double[] { 0.0, 0.5 }; var fts = new double[] { 0.0, 0.50 }; var tissue = new Tissue( new IChromophoreAbsorber[] { hbAbsorber, hbo2Absorber, fatAbsorber, waterAbsorber }, scatterer, "test_tissue", n); var ops = wvs.Select(wv => tissue.GetOpticalProperties(wv)).ToArray(); var rVsWavelength = ComputationFactory.ComputeReflectance( new DistributedPointSourceSDAForwardSolver(), SolutionDomainType.ROfFxAndFt, ForwardAnalysisType.R, new object[] { ops, fxs, fts }); // return from ROfFxAndFt is new double[ops.Length * fxs.Length * fts.Length]; // order is: (ops0,fxs0,fts0)real, (ops0,fxs0,ts1)real...(ops0,fxs0,ftsnt-1)real // (ops0,fxs1,fts0)real, (ops0,fxs1,ts1)real...(ops0,fxs1,ftsnt-1)real // ... // (ops0,fxsnf-1,fts0)real,.................(ops0,fxsnf-1,ftsnt-1)real // ... repeat above with imag, then with ops1... // [0] -> ops0=650, fx0=0.0, fts0=0.0 real Assert.IsTrue(Math.Abs(rVsWavelength[0] - 1.890007) < 0.000001); // API match // [1] -> ops0=650, fx0=0.0, fts1=0.5 real Assert.IsTrue(Math.Abs(rVsWavelength[1] - 1.888160) < 0.000001); // [2] -> ops0=650, fx1=0.5, fts0=0.0 real Assert.IsTrue(Math.Abs(rVsWavelength[2] - 0.562537) < 0.000001); // API match // [3] -> ops0=650, fx1=0.5, fts1=0.5 real Assert.IsTrue(Math.Abs(rVsWavelength[3] - 0.562543) < 0.000001); // [4] -> ops1=700, fx0=0.0, fts0=0.0 real Assert.IsTrue(Math.Abs(rVsWavelength[4] - 2.118427) < 0.000001); // API match // [5] -> ops1=700, fx0=0.0, fts1=0.5 real Assert.IsTrue(Math.Abs(rVsWavelength[5] - 2.113377) < 0.000001); // [6] -> ops1=700, fx1=0.5, fts0=0.0 real Assert.IsTrue(Math.Abs(rVsWavelength[6] - 0.543539) < 0.000001); // API match // [7] -> ops1=700, fx1=0.5, fts1=0.5 real Assert.IsTrue(Math.Abs(rVsWavelength[7] - 0.543546) < 0.000001); // [8] -> ops0=650, fx0=0.0, fts0=0.0 imag Assert.IsTrue(Math.Abs(rVsWavelength[8] - 0.0) < 0.000001); // API match // [9] -> ops0=650, fx0=0.0, fts1=0.5 imag Assert.IsTrue(Math.Abs(rVsWavelength[9] + 0.045122) < 0.000001); // [10] -> ops0=650, fx1=0.5, fts0=0.0 imag Assert.IsTrue(Math.Abs(rVsWavelength[10] - 0.0) < 0.000001); // API match // [11] -> ops0=650, fx1=0.5, fts1=0.5 imag Assert.IsTrue(Math.Abs(rVsWavelength[11] + 0.000799) < 0.000001); // [12] -> ops1=700, fx0=0.0, fts0=0.0 imag Assert.IsTrue(Math.Abs(rVsWavelength[12] - 0.0) < 0.000001); // API match // [13] -> ops1=700, fx0=0.0, fts1=0.5 imag Assert.IsTrue(Math.Abs(rVsWavelength[13] + 0.071758) < 0.000001); // [14] -> ops1=700, fx1=0.5, fts0=0.0 imag Assert.IsTrue(Math.Abs(rVsWavelength[14] - 0.0) < 0.000001); // API match // [15] -> ops1=700, fx1=0.5, fts1=0.5 imag Assert.IsTrue(Math.Abs(rVsWavelength[15] + 0.000651) < 0.000001); }
public void validate_ROfRhoAndFt_With_Wavelength() { // used values for tissue=liver var scatterer = new PowerLawScatterer(0.84, 0.55); var hbAbsorber = new ChromophoreAbsorber(ChromophoreType.Hb, 66); var hbo2Absorber = new ChromophoreAbsorber(ChromophoreType.HbO2, 124); var fatAbsorber = new ChromophoreAbsorber(ChromophoreType.Fat, 0.02); var waterAbsorber = new ChromophoreAbsorber(ChromophoreType.H2O, 0.87); var n = 1.4; var wvs = new double[] { 650, 700 }; var rhos = new double[] { 0.5, 1.625 }; var fts = new double[] { 0.0, 0.50 }; var tissue = new Tissue( new IChromophoreAbsorber[] { hbAbsorber, hbo2Absorber, fatAbsorber, waterAbsorber }, scatterer, "test_tissue", n); var ops = wvs.Select(wv => tissue.GetOpticalProperties(wv)).ToArray(); var rVsWavelength = ComputationFactory.ComputeReflectance( new PointSourceSDAForwardSolver(), SolutionDomainType.ROfRhoAndFt, ForwardAnalysisType.R, new object[] { ops, rhos, fts }); // return from ROfRhoAndFt is new double[ops.Length * rhos.Length * fts.Length]; // order is: (ops0,rhos0,fts0)real, (ops0,rhos0,fts1)real...(ops0,rhos0,ftsnt-1)real // (ops0,rhos1,fts0)real, (ops0,rhos1,fts1)real...(ops0,rhos1,ftsnt-1)real // ... // (ops0,rhosnr-1,fts0)real,.................(ops0,rhosnr-1,ftsnt-1)real // ... repeat above with imag, then next ops1... // [0] -> ops0=650, rho0=0.5, fts0=0.0 real Assert.IsTrue(Math.Abs(rVsWavelength[0] - 0.037575) < 0.000001); // [1] -> ops0=650, rho0=0.5, fts1=0.5 real Assert.IsTrue(Math.Abs(rVsWavelength[1] - 0.037511) < 0.000001); // [2] -> ops0=650, rho1=1.635, fts0=0.0 real Assert.IsTrue(Math.Abs(rVsWavelength[2] - 0.009306) < 0.000001); // [3] -> ops0=650, rho1=1.635, fts1=0.5 real Assert.IsTrue(Math.Abs(rVsWavelength[3] - 0.009255) < 0.000001); // [4] -> ops1=700, rho0=0.5, fts0=0.0 real Assert.IsTrue(Math.Abs(rVsWavelength[4] - 0.036425) < 0.000001); // [5] -> ops1=700, rho0=0.5, fts1=0.5 real Assert.IsTrue(Math.Abs(rVsWavelength[5] - 0.036310) < 0.000001); // [6] -> ops1=700, rho1=1.635, fts0=0.0 real Assert.IsTrue(Math.Abs(rVsWavelength[6] - 0.010657) < 0.000001); // [7] -> ops1=700, rho1=1.635, fts1=0.5 real Assert.IsTrue(Math.Abs(rVsWavelength[7] - 0.010558) < 0.000001); // [8] -> ops0=650, rho0=0.5, fts0=0.0 imag Assert.IsTrue(Math.Abs(rVsWavelength[8] - 0.0) < 0.000001); // [9] -> ops0=650, rho0=0.5, fts1=0.5 imag Assert.IsTrue(Math.Abs(rVsWavelength[9] + 0.001200) < 0.000001); // [10] -> ops0=650, rho1=1.635, fts0=0.0 imag Assert.IsTrue(Math.Abs(rVsWavelength[10] - 0.0) < 0.000001); // [11] -> ops1=650, rho1=1.635, fts1=0.5 imag Assert.IsTrue(Math.Abs(rVsWavelength[11] + 0.000674) < 0.000001); // [12] -> ops1=700, rho0=0.5, fts0=0.0 Assert.IsTrue(Math.Abs(rVsWavelength[12] - 0.0) < 0.000001); // [13] -> ops1=700, rho0=0.5, fts1=0.5 imag Assert.IsTrue(Math.Abs(rVsWavelength[13] + 0.001446) < 0.000001); // [14] -> ops1=700, rho1=1.635, fts0=0.0 real Assert.IsTrue(Math.Abs(rVsWavelength[14] - 0.0) < 0.000001); // [15] -> ops1=700, rho1=1.635, fts1=0.5 imag Assert.IsTrue(Math.Abs(rVsWavelength[15] + 0.000929) < 0.000001); }
public string Plot(IPlotParameters plotParameters) { var parameters = (SolutionDomainPlotParameters)plotParameters; var fs = parameters.ForwardSolverType; var op = parameters.OpticalProperties; var independentValue = parameters.IndependentAxes.Value; var independentValues = parameters.XAxis.AsEnumerable().ToArray(); try { Plots plot; var parametersInOrder = _parameterTools.GetParametersInOrder( _parameterTools.GetOpticalPropertiesObject(parameters.OpticalProperties), plotParameters.XAxis.AsEnumerable().ToArray(), parameters.SolutionDomain, parameters.IndependentAxes.Label, parameters.IndependentAxes.Value); var parametersInOrderObject = parametersInOrder.Values.ToArray(); var reflectance = parameters.NoiseValue > 0 ? ComputationFactory.ComputeReflectance(fs, parameters.SolutionDomain, parameters.ModelAnalysis, parametersInOrderObject).AddNoise(parameters.NoiseValue) : ComputationFactory.ComputeReflectance(fs, parameters.SolutionDomain, parameters.ModelAnalysis, parametersInOrderObject); var isComplex = ComputationFactory.IsComplexSolver(parameters.SolutionDomain); var hasIndependentAxis = parameters.SolutionDomain != SolutionDomainType.ROfFx && parameters.SolutionDomain != SolutionDomainType.ROfRho; if (!isComplex) { var xyPoints = independentValues.Zip(reflectance, (x, y) => new Point(x, y)); var plotData = new PlotData { Data = xyPoints, Label = parameters.SolutionDomain.ToString() }; plot = new Plots { Id = hasIndependentAxis ? $"{parameters.SolutionDomain.ToString()}Fixed{parameters.IndependentAxes.Label}" : $"{parameters.SolutionDomain.ToString()}", PlotList = new List <PlotDataJson>() }; plot.PlotList.Add(new PlotDataJson { Data = plotData.Data.Select(item => new List <double> { item.X, item.Y }).ToList(), Label = hasIndependentAxis ? $"{fs} μa={op.Mua} μs'={op.Musp} {parameters.IndependentAxes.Label}={parameters.IndependentAxes.Value}" : $"{fs} μa={op.Mua} μs'={op.Musp}" }); } else { var offset = reflectance.Length / 2; IEnumerable <ComplexPoint> xyPointsComplex = independentValues.Zip(reflectance, (x, y) => new ComplexPoint(x, new Complex(y, reflectance[Array.IndexOf(reflectance, y) + offset]))).ToArray(); var xyPointsReal = xyPointsComplex.Select(item => new Point(item.X, item.Y.Real)); var xyPointsImaginary = xyPointsComplex.Select(item => new Point(item.X, item.Y.Imaginary)); var plotDataReal = new PlotData { Data = xyPointsReal, Label = parameters.SolutionDomain.ToString() }; var plotDataImaginary = new PlotData { Data = xyPointsImaginary, Label = parameters.SolutionDomain.ToString() }; plot = new Plots { Id = $"{parameters.SolutionDomain.ToString()}Fixed{parameters.IndependentAxes.Label}", PlotList = new List <PlotDataJson>() }; plot.PlotList.Add(new PlotDataJson { Data = plotDataReal.Data.Select(item => new List <double> { item.X, item.Y }).ToList(), Label = $"{fs} μa={op.Mua} μs'={op.Musp} {parameters.IndependentAxes.Label}={independentValue}(real)" }); plot.PlotList.Add(new PlotDataJson { Data = plotDataImaginary.Data.Select(item => new List <double> { item.X, item.Y }).ToList(), Label = $"{fs} μa={op.Mua} μs'={op.Musp} {parameters.IndependentAxes.Label}={independentValue}(imag)" }); } var msg = JsonConvert.SerializeObject(plot); return(msg); } catch (Exception e) { _logger.LogError("An error occurred: {Message}", e.Message); throw; } }