Click or drag to resize

Wizard Example

Below, an example implementation of a RelaxISPlugin_Wizard is shown.

The function of the plugin is chosen for illustrative purposes.

Requirements
  • Reference to the RelaxIS_SDK.dll

  • .NET Framework 4.7.2 target (class library)

  • Recommended: Development environment with compiler e.g. RelaxIS SDK Code Editor, Microsoft Visual Studio

Demonstrates

This examples illustrates the implementation of a Wizard plugin.

The Wizard selects between two different types of models for two different types of spectra based on their data aspect ratio.

It is an interactive wizard that also presets options to the user.

Example
C#
// <copyright file="MyWizard.cs" company="rhd instruments GmbH and Co. KG">
// Copyright (c) rhd instruments GmbH and Co. KG. All rights reserved.
// Licensed under the MIT No Attribution (MIT-0) license. See section 'License' in the 'SDK Examples / Tutorials' topic for full license information.
// </copyright>

namespace RelaxIS_SDK_Examples.Plugins
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using RelaxIS_SDK.Common;
    using RelaxIS_SDK.Plugins;
    using RelaxIS_SDK.Wizard;
    using RelaxIS_SDK.Wizard.WizardOptionResults;
    using RelaxIS_SDK.Wizard.WizardOptions;

    /***
     * The Wizard plugins are used to implement models for the Wizard Fit function in RelaxIS.
     * A wizard can either be interactive or non-interactive. In the former case, the wizard
     * can specify a set of options that are shows as userinterface to the user. The option values
     * are later handed over to a function that generates a fit setup for a spectrum.
     * The fit setup is the model, transfer function, weight mode and parameter values. Using this,
     * RelaxIS then moves the spectrum to the respective model and performs a single fit.
     * Alternatively it can also run an Auto Fit, if no initial parameters can be determined algorithmically.
     */

    /// <summary>
    /// Defines an example <see cref="RelaxISPlugin_Wizard"/> class.
    /// </summary>
    public class MyWizard
        : RelaxISPlugin_Wizard
    {
        /***
         * First, implement the default plugin properties Name and Description that describe the plugin.
         * This is mainly used for display purposes.
         */

        /// <inheritdoc/>
        public override string Name
        {
            get { return "MyWizard"; }
        }

        /// <inheritdoc/>
        public override string Description
        {
            get { return "Implements a wizard that selects one of two possible models for fitting either wide or high spectra."; }
        }

        /// <inheritdoc/>
        public override string Title
        {
            get
            {
                return "My Wizard Plugin";
            }
        }

        /***
         * Define if the wizard is interactive. If so, it can not be used from the WCF Link interface.
         */

        /// <inheritdoc/>
        public override bool IsInteractive
        {
            get
            {
                return true;
            }
        }

        /***
         * Get a list of options to display to the user. Various types of options are available in the
         * RelaxIS_SDK.Wizard.WizardOptions namespace. Each will be displayed as a certain control, e.g.
         * checkboxes or similar.
         * The user can change these controls. The values are then retrieved from the controls and passed
         * on to the RetrieveFitSetup function.
         * Note that the name property of each option is used to refer to it in the OptionValues dictionary
         * in the RetrieveFitSetup function.
         */

        /// <inheritdoc/>
        public override List<WizardOptionBase> GetOptions(ImpedanceSpectrum InputSpectrum)
        {
            // Define options to show to the user on the interface
            var mcoWide = new MultipleChoiceOption("wide", "Which model to use if the spectrum is a wide one?", 1);
            mcoWide.PossibleAnswers.Add("R-(R)(P)-(R)(P)");
            mcoWide.PossibleAnswers.Add("R-(RWs)(P)");
            mcoWide.DefaultValue = "R-(R)(P)-(R)(P)";

            var mcoHigh = new MultipleChoiceOption("high", "Which model to use if the spectrum is a high one?", 2);
            mcoHigh.PossibleAnswers.Add("RP");
            mcoHigh.PossibleAnswers.Add("RWo");
            mcoHigh.DefaultValue = "RP";

            var res = new List<WizardOptionBase>
            {
                new LabelOption("lblTitle", "Welcome to this example wizard!", 0),
                mcoWide,
                mcoHigh,
                new CheckboxOption("useL", "Add an inductivity to the models?", 3),
            };
            return res;
        }

        /***
         * This function returns a WizardResult object that contains all information for RelaxIS to evaluate the given spectrum.
         * The result contains a transfer function, weight mode, and most importantly a model and parameter values. That means
         * that you can inspect the spectrum and decide on a spectrum-by-spectrum basis which model should be used to fit it.
         * In this example, the aspect ratio of the spectrum sorts it into either high or wide spectra and selects a model accordingly.
         * It is helpful to implement custom functions to determine start parameters for the model from the actual spectrum. This allows
         * RelaxIS to perform a fast single fit. However, if that is unfeasible, the UseAutoFit property of the result can be set to true.
         * Then RelaxIS will perform a slower Auto Fit instead.
         */

        /// <inheritdoc/>
        public override WizardResult RetrieveFitSetup(ImpedanceSpectrum InputSpectrum, Dictionary<string, OptionResultBase> OptionValues)
        {
            // Get the option results. Here this is which model to use in either the wide or high case.
            var modelWide = OptionValues["wide"].ToMultipleChoiceOptionResult();
            var modelHigh = OptionValues["high"].ToMultipleChoiceOptionResult();
            var useL = OptionValues["useL"].ToCheckboxOptionResult();

            // Determine spectrum aspect ratio, select model
            var specWidth = Math.Abs(InputSpectrum.Data.Max(d => d.Impedance.Real) - InputSpectrum.Data.Min(d => d.Impedance.Real));
            var specHeight = Math.Abs(InputSpectrum.Data.Max(d => d.Impedance.Imaginary) - InputSpectrum.Data.Min(d => d.Impedance.Imaginary));
            string model;
            if (specWidth > specHeight)
            {
                model = modelWide.Value;
            }
            else
            {
                model = modelHigh.Value;
            }

            if (useL.Value)
            {
                model = "I-" + model;
            }

            // Here, just use an auto fit. It would also be possible to setup exact start parameters
            // for the chosen model based on the spectrum for a quicker fit.
            var res = new WizardResult()
            {
                AbortFit = false,
                UseAutoFit = true,
                Circuit = model,
                TransferFunction = "Impedance",
                LowerFrequencyLimit = InputSpectrum.Data.Min(d => d.Impedance.Frequency),
                UpperFrequencyLimit = InputSpectrum.Data.Max(d => d.Impedance.Frequency),
                UseDefaultLimitsForAutofit = true,
                WeightMode = "Proportional Weighting",
            };

            /*
                Instead of settings UseDefaultLimitsForAutofit = true, you can set it to false
                and specify custom lower and upper limits for the auto fit:
                res.UseDefaultLimitsForAutofit = false;
                res.ParameterLowerLimits = new List<double>() { 1e-15, 1e-15, 0 };
                res.ParameterUpperLimits = new List<double>() { 1e10, 1e-1, 100000.0 };
             */

            /*
                Using the autofit, no parameter setup needs to be performed.
                Alternatively you could set UseAutoFit = false and specify the initial parameter directly:
                res.ParameterValues = new List<double>() { 10.0, 1e-5, 25.0 };
            */

            return res;
        }

        /***
         * If required, this function can calculate and return further evaluation results for the spectrum given the fit result.
         * These are then shown to the user after the fit is complete.
         */

        /// <inheritdoc/>
        public override FurtherEvaluationResult GetFurtherEvaluation(ImpedanceSpectrum InputSpectrum, Dictionary<string, OptionResultBase> OptionValues, WizardFitResults FitResults)
        {
            return null;
        }
    }
}
See Also