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