public PlotViewModel(int plotViewId = 0) { _plotViewId = plotViewId; _MinYValue = 1E-9; _MaxYValue = 1.0; _MinXValue = 1E-9; _MaxXValue = 1.0; _AutoScaleX = true; _AutoScaleY = true; RealLabels = new List <string>(); ImagLabels = new List <string>(); PhaseLabels = new List <string>(); AmplitudeLabels = new List <string>();; Labels = new List <string>(); PlotTitles = new List <string>(); DataSeriesCollection = new List <DataPointCollection>(); PlotSeriesCollection = new PlotPointCollection(); //IsComplexPlot = false; PlotModel = new PlotModel { Title = "", LegendPlacement = LegendPlacement.Outside }; PlotType = ReflectancePlotType.ForwardSolver; _HoldOn = true; _HideKey = false; _ShowInPlotView = true; _ShowAxes = false; _showComplexPlotToggle = false; XAxisSpacingOptionVM = new OptionViewModel <ScalingType>("XAxisSpacing_" + _plotViewId, false); XAxisSpacingOptionVM.PropertyChanged += (sender, args) => UpdatePlotSeries(); YAxisSpacingOptionVM = new OptionViewModel <ScalingType>("YAxisSpacing_" + _plotViewId, false); YAxisSpacingOptionVM.PropertyChanged += (sender, args) => UpdatePlotSeries(); PlotToggleTypeOptionVM = new OptionViewModel <PlotToggleType>("ToggleType_" + _plotViewId, false); PlotToggleTypeOptionVM.PropertyChanged += (sender, args) => UpdatePlotSeries(); PlotNormalizationTypeOptionVM = new OptionViewModel <PlotNormalizationType>("NormalizationType_" + _plotViewId, false); PlotNormalizationTypeOptionVM.PropertyChanged += (sender, args) => UpdatePlotSeries(); CustomPlotLabel = ""; Commands.Plot_PlotValues.Executed += Plot_Executed; Commands.Plot_SetAxesLabels.Executed += Plot_SetAxesLabels_Executed; ClearPlotCommand = new RelayCommand(() => Plot_Cleared(null, null)); ClearPlotSingleCommand = new RelayCommand(() => Plot_ClearedSingle(null, null)); ExportDataToTextCommand = new RelayCommand(() => Plot_ExportDataToText_Executed(null, null)); DuplicateWindowCommand = new RelayCommand(() => Plot_DuplicateWindow_Executed(null, null)); }
private void UpdateOptions() { switch (SelectedValue) { case FluenceSolutionDomainType.FluenceOfRhoAndZ: IndependentVariableAxisOptionVM = new OptionViewModel <IndependentVariableAxis>("IndependentAxis", false, new[] { IndependentVariableAxis.Rho }); FluenceOfRhoAndZOption.IsSelected = true; //added to force the radio button when it is changed programatically break; case FluenceSolutionDomainType.FluenceOfFxAndZ: IndependentVariableAxisOptionVM = new OptionViewModel <IndependentVariableAxis>("IndependentAxis", false, new[] { IndependentVariableAxis.Fx }); break; case FluenceSolutionDomainType.FluenceOfRhoAndZAndTime: IndependentVariableAxisOptionVM = new OptionViewModel <IndependentVariableAxis>("IndependentAxis", false, new[] { IndependentVariableAxis.Rho, IndependentVariableAxis.Time }); break; case FluenceSolutionDomainType.FluenceOfFxAndZAndTime: IndependentVariableAxisOptionVM = new OptionViewModel <IndependentVariableAxis>("IndependentAxis", false, new[] { IndependentVariableAxis.Fx, IndependentVariableAxis.Time }); break; case FluenceSolutionDomainType.FluenceOfRhoAndZAndFt: IndependentVariableAxisOptionVM = new OptionViewModel <IndependentVariableAxis>("IndependentAxis", false, new[] { IndependentVariableAxis.Rho, IndependentVariableAxis.Ft }); break; case FluenceSolutionDomainType.FluenceOfFxAndZAndFt: IndependentVariableAxisOptionVM = new OptionViewModel <IndependentVariableAxis>("IndependentAxis", false, new[] { IndependentVariableAxis.Fx, IndependentVariableAxis.Ft }); break; default: throw new NotImplementedException("SelectedValue"); } // create a new callback based on the new viewmodel IndependentVariableAxisOptionVM.PropertyChanged += (s, a) => UpdateAxes(); UpdateAxes(); //The independent axis should not be visible, this panel already has modulation frequency ShowIndependentAxisChoice = (ShowIndependentAxisChoice && ((SelectedValue != FluenceSolutionDomainType.FluenceOfRhoAndZAndFt) && (SelectedValue != FluenceSolutionDomainType.FluenceOfRhoAndZAndTime))); }
public SimulationOptionsViewModel(SimulationOptions options) { _simulationOptions = options; // use the property to invoke the appropriate change notification #if WHITELIST _absorptionWeightingTypeVM = new OptionViewModel <AbsorptionWeightingType>("Absorption Weighting Type:", false, _simulationOptions.AbsorptionWeightingType, WhiteList.AbsorptionWeightingTypes); _randomNumberGeneratorTypeVM = new OptionViewModel <RandomNumberGeneratorType>("Random Number Generator Type:", false, _simulationOptions.RandomNumberGeneratorType, WhiteList.RandomNumberGeneratorTypes); _phaseFunctionTypeVM = new OptionViewModel <PhaseFunctionType>("Phase Function Type:", false, _simulationOptions.PhaseFunctionType, WhiteList.PhaseFunctionTypes); #else _absorptionWeightingTypeVM = new OptionViewModel <AbsorptionWeightingType>("Absorption Weighting Type:", false, _simulationOptions.AbsorptionWeightingType); _randomNumberGeneratorTypeVM = new OptionViewModel <RandomNumberGeneratorType>("Random Number Generator:", false, _simulationOptions.RandomNumberGeneratorType); _phaseFunctionTypeVM = new OptionViewModel <PhaseFunctionType>("Phase Function Type:", false, _simulationOptions.PhaseFunctionType); #endif _absorptionWeightingTypeVM.PropertyChanged += (sender, args) => _simulationOptions.AbsorptionWeightingType = _absorptionWeightingTypeVM.SelectedValue; _randomNumberGeneratorTypeVM.PropertyChanged += (sender, args) => _simulationOptions.RandomNumberGeneratorType = _randomNumberGeneratorTypeVM.SelectedValue; _phaseFunctionTypeVM.PropertyChanged += (sender, args) => _simulationOptions.PhaseFunctionType = _phaseFunctionTypeVM.SelectedValue; }
public MeshViewModel() { MinValue = 1E-9; MaxValue = 50.0; AutoScale = false; ScalingTypeOptionVM = new OptionViewModel <ScalingType>("Scaling Type:", false); ScalingTypeOptionVM.PropertyChanged += (sender, args) => UpdateImages(); ColormapTypeOptionVM = new OptionViewModel <ColormapType>("Colormap Type:"); _colormap = new Colormap(ColormapTypeOptionVM.SelectedValue); ColormapTypeOptionVM.PropertyChanged += (sender, args) => { _colormap = new Colormap(ColormapTypeOptionVM.SelectedValue); UpdateImages(); }; ExportDataCommand = new RelayCommand(() => ExportData_Executed(null, null)); Commands.Mesh_PlotMap.Executed += Mesh_PlotMap_Executed; }
public SimulationInputViewModel(SimulationInput input) { _simulationInput = input; // use the property to invoke the appropriate change notification _simulationOptionsVM = new SimulationOptionsViewModel(_simulationInput.Options); #if WHITELIST TissueTypeVM = new OptionViewModel <string>("Tissue Type:", true, _simulationInput.TissueInput.TissueType, WhiteList.TissueTypes); #else TissueTypeVM = new OptionViewModel <string>("Tissue Type:", true, _simulationInput.TissueInput.TissueType, new[] { "MultiLayer", "SingleEllipsoid", }); #endif _tissueTypeVM.PropertyChanged += (sender, args) => { switch (_tissueTypeVM.SelectedValue) { case "MultiLayer": _simulationInput.TissueInput = new MultiLayerTissueInput(); break; case "SingleEllipsoid": _simulationInput.TissueInput = new SingleEllipsoidTissueInput(); break; default: throw new ArgumentOutOfRangeException(); } UpdateTissueTypeVM(_simulationInput.TissueInput.TissueType); }; UpdateTissueInputVM(_simulationInput.TissueInput); }
public MapViewModel(int MapViewId = 0) { _mapViewId = MapViewId; MinValue = 1E-9; MaxValue = 1.0; AutoScale = false; ScalingTypeOptionVM = new OptionViewModel <ScalingType>(StringLookup.GetLocalizedString("Label_ScalingType") + _mapViewId, false); ScalingTypeOptionVM.PropertyChanged += (sender, args) => UpdateImages(); ColormapTypeOptionVM = new OptionViewModel <ColormapType>(StringLookup.GetLocalizedString("Label_ColormapType")); ColormapTypeOptionVM.PropertyChanged += (sender, args) => { _colormap = new Colormap(ColormapTypeOptionVM.SelectedValue); UpdateImages(); }; _colormap = new Colormap(ColormapTypeOptionVM.SelectedValue); Commands.Maps_PlotMap.Executed += Maps_PlotMap_Executed; ExportDataToTextCommand = new RelayCommand(() => Maps_ExportDataToText_Executed(null, null)); DuplicateWindowCommand = new RelayCommand(() => Map_DuplicateWindow_Executed(null, null)); }
public FluenceSolverViewModel() { RhoRangeVM = new RangeViewModel(new DoubleRange(0.1, 19.9, 300), "mm", IndependentVariableAxis.Rho, ""); ZRangeVM = new RangeViewModel(new DoubleRange(0.1, 19.9, 300), "mm", IndependentVariableAxis.Z, ""); SourceDetectorSeparation = 10.0; TimeModulationFrequency = 0.1; _tissueInputVM = new OpticalPropertyViewModel(); // right now, we're doing manual databinding to the selected item. need to enable databinding // confused, though - do we need to use strings? or, how to make generics work with dependency properties? ForwardSolverTypeOptionVM = new OptionViewModel <ForwardSolverType>( "Forward Model:", false, new[] { ForwardSolverType.DistributedPointSourceSDA, ForwardSolverType.PointSourceSDA, ForwardSolverType.DistributedGaussianSourceSDA, ForwardSolverType.TwoLayerSDA }); // explicitly enabling these for the workshop; FluenceSolutionDomainTypeOptionVM = new FluenceSolutionDomainOptionViewModel("Fluence Solution Domain", FluenceSolutionDomainType.FluenceOfRhoAndZ); FluenceSolutionDomainTypeOptionVM.IsFluenceOfRhoAndZAndTimeEnabled = false; FluenceSolutionDomainTypeOptionVM.IsFluenceOfRhoAndZAndFtEnabled = true; AbsorbedEnergySolutionDomainTypeOptionVM = new FluenceSolutionDomainOptionViewModel("Absorbed Energy Solution Domain", FluenceSolutionDomainType.FluenceOfRhoAndZ); AbsorbedEnergySolutionDomainTypeOptionVM.IsFluenceOfRhoAndZAndTimeEnabled = false; AbsorbedEnergySolutionDomainTypeOptionVM.IsFluenceOfRhoAndZAndFtEnabled = true; PhotonHittingDensitySolutionDomainTypeOptionVM = new FluenceSolutionDomainOptionViewModel("PHD Solution Domain", FluenceSolutionDomainType.FluenceOfRhoAndZ); PhotonHittingDensitySolutionDomainTypeOptionVM.IsFluenceOfRhoAndZAndTimeEnabled = false; PhotonHittingDensitySolutionDomainTypeOptionVM.IsFluenceOfRhoAndZAndFtEnabled = true; PropertyChangedEventHandler updateSolutionDomain = (sender, args) => { if (args.PropertyName == "IndependentAxisType") { RhoRangeVM = ((FluenceSolutionDomainOptionViewModel)sender).IndependentAxesVMs[0].AxisRangeVM; } // todo: must this fire on ANY property, or is there a specific one we can listen to, as above? this.OnPropertyChanged("IsTimeFrequencyDomain"); }; FluenceSolutionDomainTypeOptionVM.PropertyChanged += updateSolutionDomain; AbsorbedEnergySolutionDomainTypeOptionVM.PropertyChanged += updateSolutionDomain; PhotonHittingDensitySolutionDomainTypeOptionVM.PropertyChanged += updateSolutionDomain; MapTypeOptionVM = new OptionViewModel <MapType>( "Map Type", new[] { MapType.Fluence, MapType.AbsorbedEnergy, MapType.PhotonHittingDensity }); MapTypeOptionVM.PropertyChanged += (sender, args) => { if (args.PropertyName == "SelectedValues") { OnPropertyChanged("IsFluence"); OnPropertyChanged("IsAbsorbedEnergy"); OnPropertyChanged("IsPhotonHittingDensity"); OnPropertyChanged("IsTimeFrequencyDomain"); UpdateAvailableOptions(); } }; ForwardSolverTypeOptionVM.PropertyChanged += (sender, args) => { OnPropertyChanged("ForwardSolver"); OnPropertyChanged("IsGaussianForwardModel"); OnPropertyChanged("IsMultiRegion"); OnPropertyChanged("IsSemiInfinite"); TissueInputVM = GetTissueInputVM(IsMultiRegion ? "MultiLayer" : "SemiInfinite"); UpdateAvailableOptions(); OnPropertyChanged("IsTimeFrequencyDomain"); }; ExecuteFluenceSolverCommand = new RelayCommand(() => ExecuteFluenceSolver_Executed(null, null)); }
public SpectralMappingViewModel() { #if WHITELIST ScatteringTypeVM = new OptionViewModel <ScatteringType>("Scatterer Type", true, WhiteList.ScatteringTypes); #else ScatteringTypeVM = new OptionViewModel <ScatteringType>("Scatterer Type", true); #endif ScatteringTypeVM.PropertyChanged += (sender, args) => { if (args.PropertyName == "SelectedValue" && SelectedTissue != null)//SelectedTissue.ScattererType != ScatteringTypeVM.SelectedValue) { SelectedTissue.Scatterer = SolverFactory.GetScattererType(ScatteringTypeVM.SelectedValue); var bindableScatterer = SelectedTissue.Scatterer as INotifyPropertyChanged; if (bindableScatterer != null) { bindableScatterer.PropertyChanged += (s, a) => UpdateOpticalProperties(); } //LM - Temporary Fix to reset the tissue type after a new scatterer is created if (SelectedTissue.ScattererType == ScatteringType.PowerLaw) { PowerLawScatterer myScatterer = (PowerLawScatterer)SelectedTissue.Scatterer; myScatterer.SetTissueType(SelectedTissue.TissueType); } ScatteringTypeName = SelectedTissue.Scatterer.GetType().FullName; } OnPropertyChanged("Scatterer"); UpdateOpticalProperties(); }; WavelengthRangeVM = new RangeViewModel(new DoubleRange(650.0, 1000.0, 36), "nm", IndependentVariableAxis.Wavelength, "Wavelength Range"); Tissues = new List <Tissue> { new Tissue(TissueType.Skin), new Tissue(TissueType.BrainWhiteMatter), new Tissue(TissueType.BrainGrayMatter), new Tissue(TissueType.BreastPreMenopause), new Tissue(TissueType.BreastPostMenopause), new Tissue(TissueType.Liver), new Tissue(TissueType.IntralipidPhantom), //new Tissue(TissueType.PolystyreneSpherePhantom), new Tissue(TissueType.Custom) }; BloodConcentrationVM = new BloodConcentrationViewModel(); #region DC notes 1 // DC NOTES on how to propagate the correct hemoglobin instances into BloodConcentrationVM: // Upon setting SelectedTissue (below), we internally update the BloodConcentrationVM hemoglobin references // This is the simplest solution, but maybe violates SOC...(see SelectedTissue property for details) // A second alternative way would be to override AfterPropertyChanged (see AfterPropertyChanged method below) #endregion BloodConcentrationVM.PropertyChanged += (sender, args) => UpdateOpticalProperties(); SelectedTissue = Tissues.First(); ScatteringTypeVM.SelectedValue = SelectedTissue.ScattererType; // forces update to all bindings established in hanlder for ScatteringTypeVM.PropertyChanged above ScatteringTypeName = SelectedTissue.GetType().FullName; OpticalProperties = new OpticalProperties(0.01, 1, 0.8, 1.4); Wavelength = 650; PlotMuaSpectrumCommand = new RelayCommand(PlotMuaSpectrum_Executed); PlotMuspSpectrumCommand = new RelayCommand(PlotMuspSpectrum_Executed); Commands.SD_SetWavelength.Executed += (snder, args) => // updates when solution domain is involved in spectral feedback { // Wavelength = (double) args.Parameter; // this will ping-pong back to FS (stack overflow), so repeating setter logic here: _wavelength = (double)args.Parameter; UpdateOpticalProperties(); // Commands.Spec_UpdateWavelength.Execute(_wavelength); (don't do this) this.OnPropertyChanged("Wavelength"); }; }
public InverseSolverViewModel() { _showOpticalProperties = true; _useSpectralPanelData = false; _allRangeVMs = new[] { new RangeViewModel { Title = Resources.Strings.IndependentVariableAxis_Rho } }; SolutionDomainTypeOptionVM = new SolutionDomainOptionViewModel("Solution Domain", SolutionDomainType.ROfRho); SolutionDomainTypeOptionVM.EnableMultiAxis = false; SolutionDomainTypeOptionVM.AllowMultiAxis = false; Action<double> updateSolutionDomainWithWavelength = wv => { var wvAxis = SolutionDomainTypeOptionVM.ConstantAxesVMs.FirstOrDefault(axis => axis.AxisType == IndependentVariableAxis.Wavelength); if (wvAxis != null) { wvAxis.AxisValue = wv; } }; SolutionDomainTypeOptionVM.PropertyChanged += (sender, args) => { if (args.PropertyName == "UseSpectralInputs") { UseSpectralPanelData = SolutionDomainTypeOptionVM.UseSpectralInputs; } if (args.PropertyName == "IndependentAxesVMs") { var useSpectralPanelDataAndNotNull = UseSpectralPanelData && SolverDemoViewModel.Current != null && SolverDemoViewModel.Current.SpectralMappingVM != null; AllRangeVMs = (from i in Enumerable.Range(0, SolutionDomainTypeOptionVM.IndependentVariableAxisOptionVM.SelectedValues.Length) orderby i descending // descending so that wavelength takes highest priority, then time/time frequency, then space/spatial frequency select useSpectralPanelDataAndNotNull && SolutionDomainTypeOptionVM.IndependentVariableAxisOptionVM.SelectedValues[i] == IndependentVariableAxis.Wavelength ? SolverDemoViewModel.Current.SpectralMappingVM.WavelengthRangeVM // bind to same instance, not a copy : SolutionDomainTypeOptionVM.IndependentAxesVMs[i].AxisRangeVM).ToArray(); // if the independent axis is wavelength, then hide optical properties (because they come from spectral panel) ShowOpticalProperties = !_allRangeVMs.Any(value => value.AxisType == IndependentVariableAxis.Wavelength); // update solution domain wavelength constant if applicable if (useSpectralPanelDataAndNotNull && SolutionDomainTypeOptionVM.ConstantAxesVMs.Any(axis => axis.AxisType == IndependentVariableAxis.Wavelength)) { updateSolutionDomainWithWavelength(SolverDemoViewModel.Current.SpectralMappingVM.Wavelength); } } }; #if WHITELIST MeasuredForwardSolverTypeOptionVM = new OptionViewModel<ForwardSolverType>( "Forward Model Engine",false, WhiteList.InverseForwardSolverTypes); #else MeasuredForwardSolverTypeOptionVM = new OptionViewModel<ForwardSolverType>( "Forward Model Engine",false); #endif #if WHITELIST InverseForwardSolverTypeOptionVM = new OptionViewModel<ForwardSolverType>("Inverse Model Engine",false, WhiteList.InverseForwardSolverTypes); #else InverseForwardSolverTypeOptionVM = new OptionViewModel<ForwardSolverType>("Inverse Model Engine", false); #endif InverseForwardSolverTypeOptionVM.PropertyChanged += (sender, args) => OnPropertyChanged("InverseForwardSolver"); OptimizerTypeOptionVM = new OptionViewModel<OptimizerType>("Optimizer Type", true); OptimizerTypeOptionVM.PropertyChanged += (sender, args) => OnPropertyChanged("Optimizer"); InverseFitTypeOptionVM = new OptionViewModel<InverseFitType>("Optimization Parameters", true); MeasuredOpticalPropertyVM = new OpticalPropertyViewModel() { Title = "" }; InitialGuessOpticalPropertyVM = new OpticalPropertyViewModel() { Title = "" }; ResultOpticalPropertyVM = new OpticalPropertyViewModel() { Title = "" }; SimulateMeasuredDataCommand = new RelayCommand(() => SimulateMeasuredDataCommand_Executed(null, null)); CalculateInitialGuessCommand = new RelayCommand(() => CalculateInitialGuessCommand_Executed(null, null)); SolveInverseCommand = new RelayCommand(() => SolveInverseCommand_Executed(null, null)); Commands.Spec_UpdateWavelength.Executed += (sender, args) => { //need to get the value from the checkbox in case UseSpectralPanelData has not yet been updated if (SolutionDomainTypeOptionVM != null) { UseSpectralPanelData = SolutionDomainTypeOptionVM.UseSpectralInputs; } if (UseSpectralPanelData && SolverDemoViewModel.Current != null && SolverDemoViewModel.Current.SpectralMappingVM != null) { updateSolutionDomainWithWavelength(SolverDemoViewModel.Current.SpectralMappingVM.Wavelength); } }; Commands.Spec_UpdateOpticalProperties.Executed += (sender, args) => { //need to get the value from the checkbox in case UseSpectralPanelData has not yet been updated if (SolutionDomainTypeOptionVM != null) { UseSpectralPanelData = SolutionDomainTypeOptionVM.UseSpectralInputs; } if (UseSpectralPanelData && SolverDemoViewModel.Current != null && SolverDemoViewModel.Current.SpectralMappingVM != null) { //if (IsMultiRegion && MultiRegionTissueVM != null) //{ // MultiRegionTissueVM.RegionsVM.ForEach(region => // ((dynamic)region).OpticalPropertyVM.SetOpticalProperties( // SolverDemoViewModel.Current.SpectralMappingVM.OpticalProperties)); //} //else if (MeasuredOpticalPropertyVM != null) { MeasuredOpticalPropertyVM.SetOpticalProperties(SolverDemoViewModel.Current.SpectralMappingVM.OpticalProperties); } } }; }
public ForwardSolverViewModel() { _showOpticalProperties = true; _useSpectralPanelData = false; _allRangeVMs = new[] { new RangeViewModel { Title = Resources.Strings.IndependentVariableAxis_Rho } }; #if WHITELIST ForwardSolverTypeOptionVM = new OptionViewModel <ForwardSolverType>("Forward Model", false, WhiteList.ForwardSolverTypes); #else ForwardSolverTypeOptionVM = new OptionViewModel <ForwardSolverType>("Forward Model", false); #endif SolutionDomainTypeOptionVM = new SolutionDomainOptionViewModel("Solution Domain", SolutionDomainType.ROfRho); ForwardAnalysisTypeOptionVM = new OptionViewModel <ForwardAnalysisType>("Model/Analysis Output", true); ForwardSolverTypeOptionVM.PropertyChanged += (sender, args) => { OnPropertyChanged("IsGaussianForwardModel"); OnPropertyChanged("ForwardSolver"); OnPropertyChanged("IsMultiRegion"); OnPropertyChanged("IsSemiInfinite"); TissueInputVM = GetTissueInputVM(IsMultiRegion ? "MultiLayer" : "SemiInfinite"); if (SolutionDomainTypeOptionVM != null) { if (ForwardSolverTypeOptionVM.SelectedValue == ForwardSolverType.TwoLayerSDA) { SolutionDomainTypeOptionVM.AllowMultiAxis = false; SolutionDomainTypeOptionVM.UseSpectralInputs = false; } SolutionDomainTypeOptionVM.EnableMultiAxis = ForwardSolverTypeOptionVM.SelectedValue != ForwardSolverType.TwoLayerSDA; SolutionDomainTypeOptionVM.EnableSpectralPanelInputs = ForwardSolverTypeOptionVM.SelectedValue != ForwardSolverType.TwoLayerSDA; } if (ForwardAnalysisTypeOptionVM != null) { if (ForwardSolverTypeOptionVM.SelectedValue == ForwardSolverType.TwoLayerSDA) { ForwardAnalysisTypeOptionVM.Options[ForwardAnalysisType.R].IsSelected = true; } ForwardAnalysisTypeOptionVM.Options[ForwardAnalysisType.dRdMua].IsEnabled = ForwardSolverTypeOptionVM.SelectedValue != ForwardSolverType.TwoLayerSDA; ForwardAnalysisTypeOptionVM.Options[ForwardAnalysisType.dRdMusp].IsEnabled = ForwardSolverTypeOptionVM.SelectedValue != ForwardSolverType.TwoLayerSDA; ForwardAnalysisTypeOptionVM.Options[ForwardAnalysisType.dRdG].IsEnabled = ForwardSolverTypeOptionVM.SelectedValue != ForwardSolverType.TwoLayerSDA; ForwardAnalysisTypeOptionVM.Options[ForwardAnalysisType.dRdN].IsEnabled = ForwardSolverTypeOptionVM.SelectedValue != ForwardSolverType.TwoLayerSDA; } }; ForwardSolverTypeOptionVM.SelectedValue = ForwardSolverType.PointSourceSDA; // force the model choice here? Action <double> updateSolutionDomainWithWavelength = wv => { var wvAxis = SolutionDomainTypeOptionVM.ConstantAxesVMs.FirstOrDefault(axis => axis.AxisType == IndependentVariableAxis.Wavelength); if (wvAxis != null) { wvAxis.AxisValue = wv; } }; SolutionDomainTypeOptionVM.PropertyChanged += (sender, args) => { if (args.PropertyName == "UseSpectralInputs") { UseSpectralPanelData = SolutionDomainTypeOptionVM.UseSpectralInputs; } if (args.PropertyName == "IndependentAxesVMs") { var useSpectralPanelDataAndNotNull = SolutionDomainTypeOptionVM.UseSpectralInputs && SolverDemoViewModel.Current != null && SolverDemoViewModel.Current.SpectralMappingVM != null; AllRangeVMs = (from i in Enumerable.Range(0, SolutionDomainTypeOptionVM.IndependentVariableAxisOptionVM.SelectedValues.Length) orderby i descending // descending so that wavelength takes highest priority, then time/time frequency, then space/spatial frequency select useSpectralPanelDataAndNotNull&& SolutionDomainTypeOptionVM.IndependentVariableAxisOptionVM.SelectedValues[i] == IndependentVariableAxis.Wavelength ? SolverDemoViewModel.Current.SpectralMappingVM.WavelengthRangeVM // bind to same instance, not a copy : SolutionDomainTypeOptionVM.IndependentAxesVMs[i].AxisRangeVM).ToArray(); // if the independent axis is wavelength, then hide optical properties (because they come from spectral panel) ShowOpticalProperties = !_allRangeVMs.Any(value => value.AxisType == IndependentVariableAxis.Wavelength); // update solution domain wavelength constant if applicable if (useSpectralPanelDataAndNotNull && SolutionDomainTypeOptionVM.ConstantAxesVMs.Any(axis => axis.AxisType == IndependentVariableAxis.Wavelength)) { updateSolutionDomainWithWavelength(SolverDemoViewModel.Current.SpectralMappingVM.Wavelength); } } }; ExecuteForwardSolverCommand = new RelayCommand(() => ExecuteForwardSolver_Executed(null, null)); Commands.Spec_UpdateWavelength.Executed += (sender, args) => { //need to get the value from the checkbox in case UseSpectralPanelData has not yet been updated if (SolutionDomainTypeOptionVM != null) { UseSpectralPanelData = SolutionDomainTypeOptionVM.UseSpectralInputs; } if (UseSpectralPanelData && SolverDemoViewModel.Current != null && SolverDemoViewModel.Current.SpectralMappingVM != null) { updateSolutionDomainWithWavelength(SolverDemoViewModel.Current.SpectralMappingVM.Wavelength); } }; Commands.Spec_UpdateOpticalProperties.Executed += (sender, args) => { //need to get the value from the checkbox in case UseSpectralPanelData has not yet been updated if (SolutionDomainTypeOptionVM != null) { UseSpectralPanelData = SolutionDomainTypeOptionVM.UseSpectralInputs; } if (UseSpectralPanelData && SolverDemoViewModel.Current != null && SolverDemoViewModel.Current.SpectralMappingVM != null) { if (IsMultiRegion && MultiRegionTissueVM != null) { MultiRegionTissueVM.RegionsVM.ForEach(region => ((dynamic)region).OpticalPropertyVM.SetOpticalProperties( SolverDemoViewModel.Current.SpectralMappingVM.OpticalProperties)); } else if (OpticalPropertyVM != null) { OpticalPropertyVM.SetOpticalProperties(SolverDemoViewModel.Current.SpectralMappingVM.OpticalProperties); } } }; }