def test_raise_messages(): e = "Expecting a `Simulator` object, found" with pytest.raises(ValueError, match=f".*{e}.*"): sf.make_LMFIT_params(12, 21) e = "Expecting a list of `SignalProcessor` objects." with pytest.raises(ValueError, match=f".*{e}.*"): sf.make_LMFIT_params(Simulator(spin_systems=[SpinSystem()]), 21)
def on_submit_signal_processor_button(): existing_data, method_index = setup() existing_process_data = existing_data["signal_processors"] n_dims = len(existing_data["methods"][method_index]["spectral_dimensions"]) processor_dict = generate_signal_processor_dict(n_dims) existing_process_data[method_index] = processor_dict print("submit process_data", existing_process_data) # refresh lmfit parameters for signal processor processor sim, pd, _ = parse(existing_data) processors = [ sp.SignalProcessor.parse_dict_with_units(mth_proc) for mth_proc in existing_process_data ] params = make_LMFIT_params(sim, processors, include={"rotor_frequency"}) existing_data["params"] = params.dumps() existing_data["trigger"] = {"simulation": True, "method_index": False} out = { "alert": ["", False], "mrsim": [existing_data, no_update], "children": [no_update] * 3, "mrsim_config": [no_update] * 4, "processor": [no_update], } return expand_output(out)
def test_6_coupled(): sim = Simulator() spin_system = {"sites": [H, C], "couplings": [CH], "abundance": "100%"} system_object = SpinSystem.parse_dict_with_units(spin_system) sim.spin_systems += [system_object] post_sim = sp.SignalProcessor(operations=op_list) params = sf.make_LMFIT_params(sim, post_sim) valuesdict_system = { "sys_0_site_0_isotropic_chemical_shift": 10, "sys_0_site_0_shielding_symmetric_zeta": 5, "sys_0_site_0_shielding_symmetric_eta": 0.1, "sys_0_site_0_shielding_symmetric_alpha": 3.12, "sys_0_site_0_shielding_symmetric_gamma": 0.341, "sys_0_site_1_isotropic_chemical_shift": -10, "sys_0_site_1_shielding_symmetric_zeta": 15, "sys_0_site_1_shielding_symmetric_eta": 0.2, "sys_0_site_1_shielding_symmetric_beta": 4.12, "sys_0_coupling_0_isotropic_j": 10, "sys_0_coupling_0_j_symmetric_zeta": 60, "sys_0_coupling_0_j_symmetric_eta": 0.4, "sys_0_abundance": 100, } valuedict_proc = { "SP_0_operation_1_Exponential_FWHM": 100, "SP_0_operation_3_Scale_factor": 10, } assert params.valuesdict() == { **valuesdict_system, **valuedict_proc, }, "Parameter creation failed" params = sf.make_LMFIT_params(sim) assert params.valuesdict( ) == valuesdict_system, "Parameter creation failed" # alias params = sf.make_LMFIT_parameters(sim) assert params.valuesdict( ) == valuesdict_system, "Parameter creation failed"
def add_params(mrsim_data): """Adds updated params to mrsim_data""" if mrsim_data is None: return no_update if mrsim_data["spin_systems"] is None or len( mrsim_data["spin_systems"]) == 0: return no_update if mrsim_data["methods"] is None or len(mrsim_data["methods"]) == 0: return no_update sim, processor, _ = parse(mrsim_data) params_obj = make_LMFIT_params(sim, processor, include={"rotor_frequency"}) mrsim_data["params"] = params_obj.dumps() return mrsim_data
def test_array(): sim.run() dataset = processor.apply_operations(sim.methods[0].simulation) data_sum = 0 for dv in dataset.y: data_sum += dv.components[0] params = sf.make_LMFIT_params(sim, processor) a = sf.LMFIT_min_function(params, sim, processor) np.testing.assert_almost_equal(-a, data_sum, decimal=8) dat = sf.add_csdm_dvs(dataset.real) fits = sf.bestfit(sim, processor) assert sf.add_csdm_dvs(fits[0]) == dat res = sf.residuals(sim, processor) assert res[0] == -dat
def compare_result(params, valuesdict_system, sim): valuesdict_proc = { "SP_0_operation_1_Exponential_FWHM": 100, "SP_0_operation_3_Scale_factor": 10, } assert params.valuesdict() == { **valuesdict_system, **valuesdict_proc, }, "Parameter creation failed" params = sf.make_LMFIT_params(sim) assert params.valuesdict( ) == valuesdict_system, "Parameter creation failed" # alias params = sf.make_LMFIT_parameters(sim) assert params.valuesdict( ) == valuesdict_system, "Parameter creation failed"
def test_6_coupled(): sim = Simulator() spin_system = {"sites": [H, C], "couplings": [CH], "abundance": "100%"} system_object = SpinSystem.parse_dict_with_units(spin_system) sim.spin_systems += [system_object] post_sim = sp.SignalProcessor(operations=op_list) params = sf.make_LMFIT_params(sim, post_sim) valuesdict_system = { "sys_0_site_0_isotropic_chemical_shift": 10, "sys_0_site_0_shielding_symmetric_zeta": 5, "sys_0_site_0_shielding_symmetric_eta": 0.1, "sys_0_site_0_shielding_symmetric_alpha": 3.12, "sys_0_site_0_shielding_symmetric_gamma": 0.341, "sys_0_site_1_isotropic_chemical_shift": -10, "sys_0_site_1_shielding_symmetric_zeta": 15, "sys_0_site_1_shielding_symmetric_eta": 0.2, "sys_0_site_1_shielding_symmetric_beta": 4.12, "sys_0_coupling_0_isotropic_j": 10, "sys_0_coupling_0_j_symmetric_zeta": 60, "sys_0_coupling_0_j_symmetric_eta": 0.4, "sys_0_abundance": 100, } compare_result(params, valuesdict_system, sim)
def test_5_multi_spin_systems(): sim = Simulator() spin_system1 = {"sites": [H], "abundance": "100%"} system_object1 = SpinSystem.parse_dict_with_units(spin_system1) spin_system2 = {"sites": [C], "abundance": "60%"} system_object2 = SpinSystem.parse_dict_with_units(spin_system2) sim.spin_systems += [system_object1, system_object2] post_sim = sp.SignalProcessor(operations=op_list) params = sf.make_LMFIT_params(sim, post_sim) valuesdict_system = { "sys_0_site_0_isotropic_chemical_shift": 10, "sys_0_site_0_shielding_symmetric_zeta": 5, "sys_0_site_0_shielding_symmetric_eta": 0.1, "sys_0_site_0_shielding_symmetric_alpha": 3.12, "sys_0_site_0_shielding_symmetric_gamma": 0.341, "sys_0_abundance": 62.5, "sys_1_site_0_isotropic_chemical_shift": -10, "sys_1_site_0_shielding_symmetric_zeta": 15, "sys_1_site_0_shielding_symmetric_eta": 0.2, "sys_1_site_0_shielding_symmetric_beta": 4.12, "sys_1_abundance": 37.5, } compare_result(params, valuesdict_system, sim)
"r", alpha=0.75, linewidth=1, label="guess spectrum") ax.set_xlim(100, -100) plt.grid() plt.legend() plt.tight_layout() plt.show() # %% # Least-squares minimization with LMFIT # ------------------------------------- # Use the :func:`~mrsimulator.utils.spectral_fitting.make_LMFIT_params` for a quick # setup of the fitting parameters. params = sf.make_LMFIT_params(sim, processor) params.pop("sys_0_abundance") print(params.pretty_print(columns=["value", "min", "max", "vary", "expr"])) # %% # **Solve the minimizer using LMFIT** minner = Minimizer(sf.LMFIT_min_function, params, fcn_args=(sim, processor, sigma)) result = minner.minimize() result # %% # The best fit solution # --------------------- best_fit = sf.bestfit(sim, processor)[0].real
# ------------------------------------- # # Once you have a fitting model, you need to create the list of parameters to use in the # least-squares minimization. For this, you may use the # `Parameters <https://lmfit.github.io/lmfit-py/parameters.html>`_ class from *LMFIT*, # as described in the previous example. # Here, we make use of a utility function, # :func:`~mrsimulator.utils.spectral_fitting.make_LMFIT_params`, to simplifies the # LMFIT parameters generation process. By default, the function only creates parameters # from the SpinSystem and SignalProcessor objects. Often, in spectrum with sidebands, # spinning speed may not be accurately known; and is, therefore, included as a fitting # parameter. To include a keyword from the method object, use the *include* argument # of the function, as follows, # # **Step 6:** Create a list of parameters. params = sf.make_LMFIT_params(sim, processor, include={"rotor_frequency"}) # %% # The `make_LMFIT_params` parses the instances of the ``Simulator`` and the # ``PostSimulator`` objects for parameters and returns a LMFIT `Parameters` object. # # **Customize the Parameters:** # You may customize the parameters list, ``params``, as desired. Here, we remove the # abundance parameter. params.pop("sys_0_abundance") print(params.pretty_print(columns=["value", "min", "max", "vary", "expr"])) # %% # **Step 7:** Perform the least-squares minimization. For the user's convenience, we # also provide a utility function, # :func:`~mrsimulator.utils.spectral_fitting.LMFIT_min_function`, for evaluating the