public void validate_SolveInverse_can_be_called_using_IForwardSolver_IOptimizer_and_bounds() { object[] initialGuessOPsAndXAxis = new object[] { new [] { new OpticalProperties(0.01, 1.0, 0.8, 1.4) }, new double[] { 1, 2, 3 } }; double[] measuredData = new double[] { 4, 5, 6 }; double[] lowerBounds = new double[] { 0, 0, 0, 0 }; // one for each OP even if not optimized double[] upperBounds = new double[] { double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity }; var solution = ComputationFactory.SolveInverse( new PointSourceSDAForwardSolver(), new MPFitLevenbergMarquardtOptimizer(), SolutionDomainType.ROfRho, measuredData, measuredData, InverseFitType.MuaMusp, initialGuessOPsAndXAxis, lowerBounds, upperBounds ); // solution is a double array with converged solution OPs Assert.IsTrue(Math.Abs(solution[1] - 3.75530) < 0.00001); }
public void validate_GetAbsorbedEnergy_can_be_called_for_homogeneous_complex_fluence_solutions() { double mua = 0.1; IEnumerable <Complex> absorbedEnergy = ComputationFactory.GetAbsorbedEnergy(complexFluence, mua); Assert.IsTrue(Math.Abs(absorbedEnergy.First().Real - 0.018829) < 0.000001); }
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); }
private IDataPoint[][] GetDataPoints(double[] reflectance) { var plotIsVsWavelength = _allRangeVMs.Any(vm => vm.AxisType == IndependentVariableAxis.Wavelength); var isComplexPlot = ComputationFactory.IsComplexSolver(SolutionDomainTypeOptionVM.SelectedValue); var primaryIdependentValues = _allRangeVMs.First().Values.ToArray(); var numPointsPerCurve = primaryIdependentValues.Length; var numForwardValues = isComplexPlot ? reflectance.Length / 2 : reflectance.Length; // complex reported as all reals, then all imaginaries var numCurves = numForwardValues / numPointsPerCurve; var points = new IDataPoint[numCurves][]; Func<int, int, IDataPoint> getReflectanceAtIndex = (i, j) => { // man, this is getting hacky... var index = plotIsVsWavelength ? i * numCurves + j : j * numPointsPerCurve + i; return isComplexPlot ? (IDataPoint) new ComplexDataPoint(primaryIdependentValues[i], new Complex(reflectance[index], reflectance[index + numForwardValues])) : (IDataPoint)new DoubleDataPoint(primaryIdependentValues[i], reflectance[index]); }; for (int j = 0; j < numCurves; j++) { points[j] = new IDataPoint[numPointsPerCurve]; for (int i = 0; i < numPointsPerCurve; i++) { points[j][i] = getReflectanceAtIndex(i, j); } } return points; }
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 void validate_GetAbsorbedEnergy_can_be_called_for_heterogeneous_real_fluence_solutions() { // use real Fluence as fluence for two layer tissue which is a 4x3 and // define muas so that top 2 rows have one value, bottom have different value (matrix is column major) double[] muas = new double[12] { 0.1, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.2 }; IEnumerable <double> absorbedEnergy = ComputationFactory.GetAbsorbedEnergy(realFluence.AsEnumerable(), muas.AsEnumerable()); Assert.IsTrue(Math.Abs(absorbedEnergy.First() - 0.018829) < 0.000001); }
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); }
public void validate_GetPHD_can_be_called_using_enum_forward_solver() { double sourceDetectorSeparation = 3; double[] phd = ComputationFactory.GetPHD( ForwardSolverType.PointSourceSDA, realFluence, sourceDetectorSeparation, new[] { new OpticalProperties(0.01, 1.0, 0.8, 1.4) }, xAxis, zAxis); // solution is linearized PHD, column major Assert.IsTrue(Math.Abs(phd[0] - 0.010336) < 0.000001); }
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)); }
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 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); }
private async Task InitializeFields(IEnumerable <SkillNode> skillNodes) { _gameData.PassiveNodes = skillNodes; var computationFactory = new ComputationFactory(GameData); var calculator = computationFactory.CreateCalculator(); _builderFactories = await computationFactory.CreateBuilderFactoriesAsync(); _parser = await computationFactory.CreateParserAsync(); _schedulers = new ComputationSchedulerProvider(); _observables = new ComputationObservables(_parser); _calculator = new ObservableCalculator(calculator, _schedulers.CalculationThread); }
public void validate_ComputeFluenceComplex_can_be_called_using_IForwardSolver_and_single_optical_properties() { double[] xAxis = new double[] { 1, 2, 3 }; double[] zAxis = new double[] { 1, 2, 3, 4 }; double[][] independentValues = new double[][] { xAxis, zAxis }; var fluence = ComputationFactory.ComputeFluenceComplex( new PointSourceSDAForwardSolver(), FluenceSolutionDomainType.FluenceOfRhoAndZAndFt, new IndependentVariableAxis[] { IndependentVariableAxis.Rho, IndependentVariableAxis.Z }, independentValues, new OpticalProperties(0.01, 1, 0.8, 1.4), // single OPs new double[] { 0 } ); // fluence is linearized to be [0-3]=>(x=1,z=1,2,3,4), [4-7]=>(x=2,z=1,2,3,4), [8-11]=>(x=3,z=1,2,3,4) Assert.IsTrue(Math.Abs(fluence[0].Real - 0.188294) < 0.000001); }
public void validate_GetPHD_can_be_called_using_IForwardSolver_and_temporal_modulation_frequency() { double sourceDetectorSeparation = 3; double modulationFrequency = 0; var phd = ComputationFactory.GetPHD( new PointSourceSDAForwardSolver(), complexFluence, sourceDetectorSeparation, modulationFrequency, new[] { new OpticalProperties(0.01, 1.0, 0.8, 1.4) }, xAxis, zAxis ); // solution is linearized PHD, column major Assert.IsTrue(Math.Abs(phd[0] - 0.010336) < 0.000001); }
public string GetPlotData(SolutionDomainPlotParameters plotParameters) { try { var inverseSolver = plotParameters.InverseSolverType; var initialGuessParams = _parameterTools.GetParametersInOrder( _parameterTools.GetOpticalPropertiesObject(plotParameters.OpticalProperties), plotParameters.XAxis.AsEnumerable().ToArray(), plotParameters.SolutionDomain, plotParameters.IndependentAxes.Label, plotParameters.IndependentAxes.Value); var initialGuessParamsConvert = initialGuessParams.Values.ToArray(); // get measured data from inverse solver analysis component var measuredPoints = plotParameters.MeasuredData; var dependentValues = measuredPoints.Select(p => p.Last()).ToArray(); // get y value var lowerBounds = new double[] { 0, 0, 0, 0 }; var upperBounds = new [] { double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity }; var fit = ComputationFactory.SolveInverse( plotParameters.InverseSolverType, plotParameters.OptimizerType, plotParameters.SolutionDomain, dependentValues, dependentValues, // set standard deviation to measured to match WPF plotParameters.OptimizationParameters, initialGuessParamsConvert, lowerBounds, upperBounds); var fitops = ComputationFactory.UnFlattenOpticalProperties(fit); //var fitparms = // GetParametersInOrder(fitops, independentValues, sd, independentAxis, independentAxisValue); plotParameters.ForwardSolverType = inverseSolver; plotParameters.OpticalProperties = fitops[0]; // not sure [0] is always going to work here plotParameters.NoiseValue = 0; var msg = _plotFactory.GetPlot(PlotType.SolutionDomain, plotParameters); return(msg); } catch (Exception e) { _logger.LogError("An error occurred: {Message}", e.Message); throw; } }
public void validate_ComputeFluence_can_be_called_using_IForwardSolver_and_optical_property_array() { double[] xAxis = new double[] { 1, 2, 3 }; double[] zAxis = new double[] { 1, 2, 3, 4 }; double[][] independentValues = new double[][] { xAxis, zAxis }; var fluence = ComputationFactory.ComputeFluence( new PointSourceSDAForwardSolver(), FluenceSolutionDomainType.FluenceOfRhoAndZ, new IndependentVariableAxis[] { IndependentVariableAxis.Rho, IndependentVariableAxis.Z }, independentValues, // could have array of OPs, one set for each tissue region new OpticalProperties[] { new OpticalProperties(0.01, 1, 0.8, 1.4) }, new double[] { 0 } ); // fluence is linearized to be [0-3]=>(x=1,z=1,2,3,4), [4-7]=>(x=2,z=1,2,3,4), [8-11]=>(x=3,z=1,2,3,4) Assert.IsTrue(Math.Abs(fluence[0] - 0.188294) < 0.000001); }
public void validate_SolveInverse_can_be_called_using_IForwardSolver_and_IOptimizer() { object[] initialGuessOPsAndXAxis = new object[] { new [] { new OpticalProperties(0.01, 1.0, 0.8, 1.4) }, new double[] { 1, 2, 3 } }; double[] measuredData = new double[] { 4, 5, 6 }; double[] solution = ComputationFactory.SolveInverse( new PointSourceSDAForwardSolver(), new MPFitLevenbergMarquardtOptimizer(), SolutionDomainType.ROfRho, measuredData, measuredData, InverseFitType.MuaMusp, initialGuessOPsAndXAxis ); // solution is a double array with converged solution OPs Assert.IsTrue(Math.Abs(solution[1] - 3.75515) < 0.00001); }
public void validate_ComputeFluenceComplex_can_be_called_using_enum_forward_solver_and_IOpticalPropertyRegion_array() { double[] xAxis = new double[] { 1, 2, 3 }; double[] zAxis = new double[] { 1, 2, 3, 4 }; double[][] independentValues = new double[][] { xAxis, zAxis }; Complex[] fluence = ComputationFactory.ComputeFluenceComplex( ForwardSolverType.PointSourceSDA, FluenceSolutionDomainType.FluenceOfRhoAndZAndFt, new IndependentVariableAxis[] { IndependentVariableAxis.Rho, IndependentVariableAxis.Z }, independentValues, new IOpticalPropertyRegion[] { new LayerTissueRegion( new DoubleRange(0, 10, 10), new OpticalProperties(0.01, 1.0, 0.8, 1.4) ) }, new double[] { 0 } ); // fluence is linearized to be [0-3]=>(x=1,z=1,2,3,4), [4-7]=>(x=2,z=1,2,3,4), [8-11]=>(x=3,z=1,2,3,4) Assert.IsTrue(Math.Abs(fluence[0].Real - 0.188294) < 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 Setup() { // need to generate fluence to send into GetPHD xAxis = new double[] { 1, 2, 3 }; zAxis = new double[] { 1, 2, 3, 4 }; double[][] independentValues = new double[][] { xAxis, zAxis }; realFluence = ComputationFactory.ComputeFluence( ForwardSolverType.PointSourceSDA, FluenceSolutionDomainType.FluenceOfRhoAndZ, new IndependentVariableAxis[] { IndependentVariableAxis.Rho, IndependentVariableAxis.Z }, independentValues, // could have array of OPs, one set for each tissue region new OpticalProperties[] { new OpticalProperties(0.01, 1, 0.8, 1.4) }, new double[] { 0 } ); complexFluence = ComputationFactory.ComputeFluenceComplex( ForwardSolverType.PointSourceSDA, FluenceSolutionDomainType.FluenceOfRhoAndZAndFt, new IndependentVariableAxis[] { IndependentVariableAxis.Rho, IndependentVariableAxis.Z }, independentValues, new OpticalProperties(0.01, 1, 0.8, 1.4), // single OPs new double[] { 0 } ); }
public MapData ExecuteForwardSolver() // todo: simplify method calls to ComputationFactory, as with Forward/InverseSolver(s) { var opticalProperties = GetOpticalProperties(); // could be OpticalProperties[] or IOpticalPropertyRegion[][] //double[] rhos = RhoRangeVM.Values.Reverse().Concat(RhoRangeVM.Values).ToArray(); double[] rhos = RhoRangeVM.Values.Reverse().Select(rho => - rho).Concat(RhoRangeVM.Values).ToArray(); double[] zs = ZRangeVM.Values.ToArray(); double[][] independentValues = new[] { rhos, zs }; var sd = GetSelectedSolutionDomain(); // todo: too much thinking at the VM layer? double[] constantValues = new double[0]; if (ComputationFactory.IsSolverWithConstantValues(sd.SelectedValue)) { switch (sd.SelectedValue) { case FluenceSolutionDomainType.FluenceOfRhoAndZAndFt: constantValues = new[] { TimeModulationFrequency }; break; default: constantValues = new[] { sd.ConstantAxesVMs[0].AxisValue }; break; } } IndependentVariableAxis[] independentAxes = GetIndependentVariableAxesInOrder( sd.IndependentVariableAxisOptionVM.SelectedValue, IndependentVariableAxis.Z); double[] results = null; if (ComputationFactory.IsComplexSolver(sd.SelectedValue)) { Complex[] fluence; if (IsMultiRegion) { fluence = ComputationFactory.ComputeFluenceComplex( ForwardSolverTypeOptionVM.SelectedValue, sd.SelectedValue, independentAxes, independentValues, ((IOpticalPropertyRegion[][])opticalProperties)[0], constantValues); } else { fluence = ComputationFactory.ComputeFluenceComplex( ForwardSolverTypeOptionVM.SelectedValue, sd.SelectedValue, independentAxes, independentValues, ((OpticalProperties[])opticalProperties)[0], constantValues); } switch (MapTypeOptionVM.SelectedValue) { case MapType.Fluence: results = fluence.Select(f => f.Magnitude).ToArray(); break; case MapType.AbsorbedEnergy: results = ComputationFactory.GetAbsorbedEnergy(fluence, ((OpticalProperties[])opticalProperties)[0].Mua).Select(a => a.Magnitude).ToArray(); // todo: is this correct?? DC 12/08/12 break; case MapType.PhotonHittingDensity: switch (PhotonHittingDensitySolutionDomainTypeOptionVM.SelectedValue) { case FluenceSolutionDomainType.FluenceOfRhoAndZAndFt: results = ComputationFactory.GetPHD( ForwardSolverTypeOptionVM.SelectedValue, fluence.ToArray(), SourceDetectorSeparation, TimeModulationFrequency, (OpticalProperties[])opticalProperties, independentValues[0], independentValues[1]).ToArray(); break; case FluenceSolutionDomainType.FluenceOfFxAndZAndFt: break; default: throw new ArgumentOutOfRangeException("FluenceSolutionDomainType"); } break; default: throw new ArgumentOutOfRangeException("MapType"); } } else { double[] fluence; if (IsMultiRegion) { fluence = ComputationFactory.ComputeFluence( ForwardSolverTypeOptionVM.SelectedValue, sd.SelectedValue, independentAxes, independentValues, ((IOpticalPropertyRegion[][])opticalProperties)[0], constantValues).ToArray(); } else { fluence = ComputationFactory.ComputeFluence( ForwardSolverTypeOptionVM.SelectedValue, sd.SelectedValue, independentAxes, independentValues, (OpticalProperties[])opticalProperties, constantValues).ToArray(); } switch (MapTypeOptionVM.SelectedValue) { case MapType.Fluence: results = fluence; break; case MapType.AbsorbedEnergy: if (IsMultiRegion) { if (ForwardSolver is TwoLayerSDAForwardSolver) { var regions = ((MultiRegionTissueViewModel)TissueInputVM).GetTissueInput().Regions .Select(region => (ILayerOpticalPropertyRegion)region).ToArray(); var muas = getRhoZMuaArrayFromLayerRegions(regions, rhos, zs); results = ComputationFactory.GetAbsorbedEnergy(fluence, muas).ToArray(); } else { return(null); } } else { // Note: the line below was originally overwriting the multi-region results. I think this was a bug (DJC 7/11/14) results = ComputationFactory.GetAbsorbedEnergy(fluence, ((OpticalProperties[])opticalProperties)[0].Mua).ToArray(); } break; case MapType.PhotonHittingDensity: switch (PhotonHittingDensitySolutionDomainTypeOptionVM.SelectedValue) { case FluenceSolutionDomainType.FluenceOfRhoAndZ: if (IsMultiRegion) { var nop = (IOpticalPropertyRegion[][])opticalProperties; results = ComputationFactory.GetPHD( ForwardSolverTypeOptionVM.SelectedValue, fluence, SourceDetectorSeparation, (from LayerTissueRegion tissue in nop[0] select tissue.RegionOP).ToArray(), independentValues[0], independentValues[1]).ToArray(); } else { results = ComputationFactory.GetPHD( ForwardSolverTypeOptionVM.SelectedValue, fluence, SourceDetectorSeparation, (OpticalProperties[])opticalProperties, independentValues[0], independentValues[1]).ToArray(); } break; case FluenceSolutionDomainType.FluenceOfFxAndZ: break; case FluenceSolutionDomainType.FluenceOfRhoAndZAndTime: break; case FluenceSolutionDomainType.FluenceOfFxAndZAndTime: break; default: throw new ArgumentOutOfRangeException("PhotonHittingDensitySolutionDomainTypeOptionVM.SelectedValue"); } break; default: throw new ArgumentOutOfRangeException("MapTypeOptionVM.SelectedValue"); } } // flip the array (since it goes over zs and then rhos, while map wants rhos and then zs double[] destinationArray = new double[results.Length]; long index = 0; for (int rhoi = 0; rhoi < rhos.Length; rhoi++) { for (int zi = 0; zi < zs.Length; zi++) { destinationArray[rhoi + rhos.Length * zi] = results[index++]; } } var dRho = 1D; var dZ = 1D; var dRhos = Enumerable.Select(rhos, rho => 2 * Math.PI * Math.Abs(rho) * dRho).ToArray(); var dZs = Enumerable.Select(zs, z => dZ).ToArray(); //var twoRhos = Enumerable.Concat(rhos.Reverse(), rhos).ToArray(); //var twoDRhos = Enumerable.Concat(dRhos.Reverse(), dRhos).ToArray(); return(new MapData(destinationArray, rhos, zs, dRhos, dZs)); }
private static void ReportInverseSolverROfRhoAndTime(double dt, double riseMarker, double tailMarker, string stDevMode, InverseFitType IFT, string projectName, string inputPath, ForwardSolverType[] forwardSolverTypes, OptimizerType[] optimizerTypes, IEnumerable <OpticalProperties> guessOps, IEnumerable <OpticalProperties> realOps, double[] rhos, double noisePercentage, bool stepByStep) { Console.WriteLine("#############################################"); Console.WriteLine("##### REPORT INVERSE SOLVER: ROfRhoAndT #####"); Console.WriteLine("#############################################"); //path definition string spaceDomainFolder = "Real"; string timeDomainFolder = "TimeDomain"; string noiseFolder = "noise" + noisePercentage.ToString(); string problemFolder = "dt" + (dt * 1000).ToString() + "markers" + riseMarker.ToString() + tailMarker.ToString(); problemFolder = problemFolder.Replace(".", "p"); foreach (var fST in forwardSolverTypes) { //initialize forward solver Console.WriteLine("Forward Solver Type: {0}", fST.ToString()); foreach (var oT in optimizerTypes) { Console.WriteLine("Optimizer Type: {0}", oT.ToString()); foreach (var rho in rhos) { string rhoFolder = rho.ToString(); Console.WriteLine("================================================="); Console.WriteLine("SOURCE DETECTOR SEPARETION: R = {0} mm", rhoFolder); if (stepByStep) { Console.WriteLine("Press enter to continue"); } Console.WriteLine("================================================="); if (stepByStep) { Console.ReadLine(); } rhoFolder = rhoFolder.Replace(".", "p"); rhoFolder = "rho" + rhoFolder; double[] constantVals = { rho }; foreach (var rOp in realOps) { //output double bestMua = 0.0; double meanMua = 0.0; double guessBestMua = 0.0; double bestMusp = 0.0; double meanMusp = 0.0; double guessBestMusp = 0.0; double bestChiSquared = 10000000000000.0; //initialize very large to avoid if first double meanChiSquared = 0.0; DateTime start = new DateTime(); //processing start time DateTime end = new DateTime(); //processing finish time double elapsedSeconds; //processing time //set filename based on real optical properties var filename = "musp" + rOp.Musp.ToString() + "mua" + rOp.Mua.ToString(); filename = filename.Replace(".", "p"); Console.WriteLine("Looking for file {0}", filename); if (File.Exists(inputPath + spaceDomainFolder + "/" + timeDomainFolder + "/" + problemFolder + "/" + rhoFolder + "/" + filename + "Range")) { Console.WriteLine("The file has been found for rho = {0} mm.", rho); //read binary files var timeRange = (double[])FileIO.ReadArrayFromBinaryInResources <double> ("Resources/" + spaceDomainFolder + "/" + timeDomainFolder + "/" + problemFolder + "/" + rhoFolder + "/" + filename + "Range", projectName, 2); int numberOfPoints = Convert.ToInt32((timeRange[1] - timeRange[0]) / dt) + 1; var T = new DoubleRange(timeRange[0], timeRange[1], numberOfPoints).AsEnumerable().ToArray(); var R = (double[])FileIO.ReadArrayFromBinaryInResources <double> ("Resources/" + spaceDomainFolder + "/" + timeDomainFolder + "/" + problemFolder + "/" + rhoFolder + "/" + filename + "R", projectName, numberOfPoints); var S = GetStandardDeviationValues("Resources/" + spaceDomainFolder + "/" + timeDomainFolder + "/" + problemFolder + "/" + rhoFolder + "/" + filename + "S", projectName, stDevMode, numberOfPoints, R.ToArray()); // add noise if (noisePercentage != 0.0) { R = R.AddNoise(noisePercentage); } start = DateTime.Now; int convergedCounter = 0; foreach (var gOp in guessOps) { bool converged; if (IFT == InverseFitType.Mua) { gOp.Musp = rOp.Musp; } if (IFT == InverseFitType.Musp) { gOp.Mua = rOp.Mua; } //solve inverse problem double[] fit = ComputationFactory.SolveInverse(fST, oT, SolutionDomainType.ROfRhoAndTime, R, S, IFT, new object[] { new[] { gOp }, constantVals, T }); if (fit[0] != 0 && fit[1] != 0) { converged = true; } else { converged = false; } if (converged) { OpticalProperties fOp = new OpticalProperties(fit[0], fit[1], gOp.G, gOp.N); //calculate chi squared and change best values if it improved double chiSquared = EvaluateChiSquared(R.ToArray(), SolverFactory.GetForwardSolver(fST).ROfRhoAndTime(fOp.AsEnumerable(), rho.AsEnumerable(), T).ToArray(), S.ToArray()); if (chiSquared < bestChiSquared) { guessBestMua = gOp.Mua; bestMua = fit[0]; guessBestMusp = gOp.Musp; bestMusp = fit[1]; bestChiSquared = chiSquared; } meanMua += fit[0]; meanMusp += fit[1]; meanChiSquared += chiSquared; convergedCounter += 1; } } end = DateTime.Now; meanMua /= convergedCounter; meanMusp /= convergedCounter; meanChiSquared /= convergedCounter; elapsedSeconds = (end - start).TotalSeconds; MakeDirectoryIfNonExistent(new string[] { spaceDomainFolder, timeDomainFolder, noiseFolder, problemFolder, fST.ToString(), oT.ToString(), IFT.ToString(), rhoFolder }); //write results to array double[] inverseProblemValues = FillInverseSolverValuesArray(bestMua, meanMua, guessBestMua, bestMusp, meanMusp, guessBestMusp, bestChiSquared, meanChiSquared, elapsedSeconds, numberOfPoints); // write array to binary LocalWriteArrayToBinary(inverseProblemValues, @"Output/" + spaceDomainFolder + "/" + timeDomainFolder + "/" + noiseFolder + "/" + problemFolder + "/" + fST.ToString() + "/" + oT.ToString() + "/" + IFT.ToString() + "/" + rhoFolder + "/" + filename, FileMode.Create); Console.WriteLine("Real MUA = {0} - best MUA = {1} - mean MUA = {2}", rOp.Mua, bestMua, meanMua); Console.WriteLine("Real MUSp = {0} - best MUSp = {1} - mean MUSp = {2}", rOp.Musp, bestMusp, meanMusp); if (stepByStep) { Console.ReadLine(); } } else { Console.WriteLine("The file has not been found."); } Console.Clear(); } } } } }
private static void ReportInverseSolverROfRho(double drho, double[] rhoRange, InverseFitType IFT, string projectName, string inputPath, ForwardSolverType[] forwardSolverTypes, OptimizerType[] optimizerTypes, IEnumerable <OpticalProperties> guessOps, IEnumerable <OpticalProperties> realOps, int ratioDetectors, double noisePercentage, bool stepByStep) { Console.WriteLine("#############################################"); Console.WriteLine("####### REPORT INVERSE SOLVER: ROfRho #######"); Console.WriteLine("#############################################"); //path definition string spaceDomainFolder = "Real"; string timeDomainFolder = "SteadyState"; string problemFolder = "drho" + drho.ToString() + "/" + "ratioD" + ratioDetectors.ToString() + "/" + "noise" + noisePercentage.ToString() + "/" + rhoRange[0].ToString() + "_" + rhoRange[1].ToString(); problemFolder = problemFolder.Replace(".", "p"); //rhos based on range int numberOfPoints = Convert.ToInt32((rhoRange[1] - rhoRange[0]) / drho) + 1; var rhos = new DoubleRange(rhoRange[0], rhoRange[1], numberOfPoints).AsEnumerable().ToArray(); double[] R = new double[numberOfPoints]; double[] S = new double[numberOfPoints]; //based on range evaluate the index of first and last points to use int firstInd = Convert.ToInt32((rhoRange[0] + drho / 2.0) / drho) - 1; int lastInd = Convert.ToInt32((rhoRange[1] + drho / 2) / drho) - 1; //execute foreach (var fST in forwardSolverTypes) { Console.WriteLine("Forward Solver Type: {0}", fST.ToString()); foreach (var oT in optimizerTypes) { Console.WriteLine("Optimizer Type: {0}", oT.ToString()); if (stepByStep) { Console.WriteLine("Press enter to continue"); } Console.WriteLine("================================================="); if (stepByStep) { Console.ReadLine(); } foreach (var rOp in realOps) { //output double bestMua = 0.0; double meanMua = 0.0; double guessBestMua = 0.0; double bestMusp = 0.0; double meanMusp = 0.0; double guessBestMusp = 0.0; double bestChiSquared = 10000000000000.0; //initialize very large to avoid if first double meanChiSquared = 0.0; DateTime start = new DateTime(); //processing start time DateTime end = new DateTime(); //processing finish time double elapsedSeconds; //processing time //set filename based on real optical properties var filename = "musp" + rOp.Musp.ToString() + "mua" + rOp.Mua.ToString(); filename = filename.Replace(".", "p"); Console.WriteLine("Looking for file {0}", filename); if (File.Exists(inputPath + spaceDomainFolder + "/" + timeDomainFolder + "/" + filename + "R")) { Console.WriteLine("The file has been found"); //read binary files var Rtot = (IEnumerable <double>)FileIO.ReadArrayFromBinaryInResources <double> ("Resources/" + spaceDomainFolder + "/" + timeDomainFolder + "/" + filename + "R", projectName, 88); var Stot = (IEnumerable <double>)FileIO.ReadArrayFromBinaryInResources <double> ("Resources/" + spaceDomainFolder + "/" + timeDomainFolder + "/" + filename + "S", projectName, 88); // extract points within range for (int i = firstInd; i <= lastInd; i++) { R[i - firstInd] = Rtot.ToArray()[i]; S[i - firstInd] = Stot.ToArray()[i]; } // reduce number of measurements var mrhos = FilterArray(rhos, ratioDetectors); var mR = FilterArray(R, ratioDetectors); var mS = FilterArray(S, ratioDetectors); // add noise if (noisePercentage != 0.0) { mR.AddNoise(noisePercentage); } start = DateTime.Now; int covergedCounter = 0; foreach (var gOp in guessOps) { bool converged; //if fitting only one parameter change the guess to the true value if (IFT == InverseFitType.Mua) { gOp.Musp = rOp.Musp; } if (IFT == InverseFitType.Musp) { gOp.Mua = rOp.Mua; } //solve inverse problem double[] fit = ComputationFactory.SolveInverse(fST, oT, SolutionDomainType.ROfRho, mR, mS, IFT, new object[] { new[] { gOp }, mrhos }); if (fit[0] != 0 && fit[1] != 0) { converged = true; } else { converged = false; } // fitted op if (converged) { OpticalProperties fOp = new OpticalProperties(fit[0], fit[1], gOp.G, gOp.N); //calculate chi squared and change values if it improved double chiSquared = EvaluateChiSquared(mR, SolverFactory.GetForwardSolver(fST).ROfRho(fOp.AsEnumerable(), mrhos).ToArray(), mS); if (chiSquared < bestChiSquared) { guessBestMua = gOp.Mua; bestMua = fit[0]; guessBestMusp = gOp.Musp; bestMusp = fit[1]; bestChiSquared = chiSquared; } meanMua += fit[0]; meanMusp += fit[1]; meanChiSquared += chiSquared; covergedCounter += 1; } } end = DateTime.Now; meanMua /= covergedCounter; meanMusp /= covergedCounter; meanChiSquared /= covergedCounter; elapsedSeconds = (end - start).TotalSeconds; MakeDirectoryIfNonExistent(new string[] { spaceDomainFolder, timeDomainFolder, problemFolder, fST.ToString(), oT.ToString(), IFT.ToString() }); //write results to array double[] inverseProblemValues = FillInverseSolverValuesArray(bestMua, meanMua, guessBestMua, bestMusp, meanMusp, guessBestMusp, bestChiSquared, meanChiSquared, elapsedSeconds, mR.Count()); // write array to binary LocalWriteArrayToBinary(inverseProblemValues, @"Output/" + spaceDomainFolder + "/" + timeDomainFolder + "/" + problemFolder + "/" + fST.ToString() + "/" + oT.ToString() + "/" + IFT.ToString() + "/" + filename, FileMode.Create); Console.WriteLine("Real MUA = {0} - best MUA = {1} - mean MUA = {2}", rOp.Mua, bestMua, meanMua); Console.WriteLine("Real MUSp = {0} - best MUSp = {1} - mean MUSp = {2}", rOp.Musp, bestMusp, meanMusp); if (stepByStep) { Console.ReadLine(); } } else { Console.WriteLine("The file has not been found."); } Console.Clear(); } } } }
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 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); }