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 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)); }
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; } }