예제 #1
0
        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 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 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
            });
        }
예제 #5
0
 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;
     }
 }
예제 #6
0
 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 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
            };
        }
예제 #8
0
        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();
                        }
                    }
                }
            }
        }
예제 #9
0
        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 string GetPlotData(SolutionDomainPlotParameters plotParameters)
        {
            try
            {
                var inverseSolver = plotParameters.InverseSolverType;
                var igparms       = GetParametersInOrder(
                    GetInitialGuessOpticalProperties(plotParameters.OpticalProperties),
                    plotParameters.XAxis.AsEnumerable().ToArray(),
                    plotParameters.SolutionDomain.ToString(),
                    plotParameters.IndependentAxes.Label,
                    plotParameters.IndependentAxes.Value);
                object[] igparmsConvert = igparms.Values.ToArray();
                // get measured data from inverse solver analysis component
                var measuredPoints = plotParameters.MeasuredData;
                var meas           = measuredPoints.Select(p => p.Last()).ToArray(); // get y value
                var lbs            = new double[] { 0, 0, 0, 0 };
                var ubs            = new double[]
                {
                    double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity
                };
                double[] fit = ComputationFactory.SolveInverse(
                    plotParameters.InverseSolverType,
                    plotParameters.OptimizerType,
                    plotParameters.SolutionDomain,
                    meas,
                    meas, // set standard deviation to measured to match WPF
                    plotParameters.OptimizationParameters,
                    igparmsConvert,
                    lbs,
                    ubs);
                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;
            }

            // this needs further development when add in wavelength refer to WPF code
            object GetInitialGuessOpticalProperties(OpticalProperties igops)
            {
                return(new[] { igops });
            }

            // the following needs to change when Wavelength is added into independent variable list
            IDictionary <IndependentVariableAxis, object> GetParametersInOrder(
                object opticalProperties, double[] xs, string sd, string independentAxis, double independentValue)
            {
                // make list of independent vars with independent first then constant
                var    listIndepVars = new List <IndependentVariableAxis>();
                string isConstant    = "";

                if (sd == "ROfRho")
                {
                    listIndepVars.Add(IndependentVariableAxis.Rho);
                }
                else if (sd == "ROfRhoAndTime")
                {
                    listIndepVars.Add(IndependentVariableAxis.Rho);
                    listIndepVars.Add(IndependentVariableAxis.Time);
                    if (independentAxis == "t")
                    {
                        isConstant = "t";
                    }
                    else
                    {
                        isConstant = "rho";
                    }
                }
                else if (sd == "ROfRhoAndFt")
                {
                    listIndepVars.Add(IndependentVariableAxis.Ft);
                    listIndepVars.Add(IndependentVariableAxis.Rho);
                    if (independentAxis == "ft")
                    {
                        isConstant = "ft";
                    }
                    else
                    {
                        isConstant = "rho";
                    }
                }
                else if (sd == "ROfFx")
                {
                    listIndepVars.Add(IndependentVariableAxis.Fx);
                }
                else if (sd == "ROfFxAndTime")
                {
                    listIndepVars.Add(IndependentVariableAxis.Time);
                    listIndepVars.Add(IndependentVariableAxis.Fx);
                    if (independentAxis == "t")
                    {
                        isConstant = "t";
                    }
                    else
                    {
                        isConstant = "fx";
                    }
                }
                else if (sd == "ROfFxAndFt")
                {
                    listIndepVars.Add(IndependentVariableAxis.Ft);
                    listIndepVars.Add(IndependentVariableAxis.Fx);
                    if (independentAxis == "ft")
                    {
                        isConstant = "ft";
                    }
                    else
                    {
                        isConstant = "fx";
                    }
                }

                // get all parameters in order
                var allParameters =
                    from iva in listIndepVars
                    where iva != IndependentVariableAxis.Wavelength
                    orderby GetParameterOrder(iva)
                    select new KeyValuePair <IndependentVariableAxis, object>(iva,
                                                                              GetParameterValues(iva, isConstant, independentValue, xs));

                // OPs are always first in the list
                return
                    (new KeyValuePair <IndependentVariableAxis, object>(IndependentVariableAxis.Wavelength,
                                                                        opticalProperties)
                     .AsEnumerable()
                     .Concat(allParameters).ToDictionary());
            }

            int GetParameterOrder(IndependentVariableAxis axis)
            {
                switch (axis)
                {
                case IndependentVariableAxis.Wavelength:
                    return(0);

                case IndependentVariableAxis.Rho:
                    return(1);

                case IndependentVariableAxis.Fx:
                    return(1);

                case IndependentVariableAxis.Time:
                    return(2);

                case IndependentVariableAxis.Ft:
                    return(2);

                case IndependentVariableAxis.Z:
                    return(3);

                default:
                    throw new InvalidEnumArgumentException("There is no Enum of this type");
                }
            }

            // this has commented out code that might come into play when we add wavelength as axis
            double[] GetParameterValues(IndependentVariableAxis axis, string isConstant, double independentValue,
                                        double[] xs)
            {
                if (((axis == IndependentVariableAxis.Rho) && (isConstant == "rho")) ||
                    ((axis == IndependentVariableAxis.Time) && (isConstant == "t")) ||
                    ((axis == IndependentVariableAxis.Fx) && (isConstant == "fx")) ||
                    ((axis == IndependentVariableAxis.Ft) && (isConstant == "ft")))
                {
                    return(new[] { independentValue });
                }
                else
                {
                    if (axis != IndependentVariableAxis.Time)
                    {
                        return(xs.ToArray());
                    }
                    else
                    {
                        return(xs.ToArray());
                    }
                }
                //{
                //    var positionIndex = 0; //hard-coded for now
                //    switch (positionIndex)
                //    {
                //        case 0:
                //        default:
                //            return new[] {independentValue};
                //case 1:
                //return new[] { SolutionDomainTypeOptionVM.ConstantAxesVMs[1].AxisValue };
                //case 2:
                //    return new[] { SolutionDomainTypeOptionVM.ConstantAxisThreeValue };
                //}
                //}
                //else
                //{
                //    //var numAxes = axis.Count();
                //    var numAxes = 1;
                //    var positionIndex = 0; //hard-coded for now
                //    //var positionIndex = SolutionDomainTypeOptionVM.IndependentVariableAxisOptionVM.SelectedValues.IndexOf(axis);
                //    switch (numAxes)
                //    {
                //        case 1:
                //        default:
                //            //return AllRangeVMs[0].Values.ToArray();
                //            return xs.ToArray();
                //case 2:
                //    switch (positionIndex)
                //    {
                //        case 0:
                //        default:
                //            return AllRangeVMs[1].Values.ToArray();
                //        case 1:
                //            return AllRangeVMs[0].Values.ToArray();
                //    }
                //case 3:
                //    switch (positionIndex)
                //    {
                //        case 0:
                //        default:
                //            return AllRangeVMs[2].Values.ToArray();
                //        case 1:
                //            return AllRangeVMs[1].Values.ToArray();
                //        case 2:
                //            return AllRangeVMs[0].Values.ToArray();
                //    }
                //}
                //}
            }
        }