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;
        }
Example #2
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));
        }
Example #3
0
        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;
            }
        }