{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Selecting Fitting Parameters" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As the number of fitting parameters increases it may be necessary to only refine a subset of the parameters. In MDMC this can be done in two ways:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Fixing a Parameter\n", "\n", "`Parameter` objects can be fixed. This can either be set when they are initialised (created) or changed for an existing `Parameter`. By default, an initialised `Parameter` is **not** fixed." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from MDMC.MD.parameters import Parameter\n", "charge = Parameter(value=0.5, name='charge', fixed=True, unit='e')\n", "\n", "# Trying to set the value of a fixed Parameter will result in a warning...\n", "charge.value = 12" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# ... and the value will remain unchanged\n", "print(charge.value)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Existing Parameters can also be fixed\n", "sigma = Parameter(1.0, name='sigma', unit='Ang')\n", "print('Is sigma fixed: {}'.format(sigma.fixed))\n", "sigma.fixed = True\n", "print('Is sigma fixed: {}'.format(sigma.fixed))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Passing a subset of Parameters to Control\n", "\n", "Only parameters that are passed to `Control` (as `fit_parameters`) will be refined. While it is simplest to pass all parameters in a `Universe` to `Control`, it is also possible to filter out a subset. To demonstrate this, a universe filled with SPCE water molecules is read from [Building a Universe](building-a-universe.ipynb)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `%%capture` and `%run` commands below simply executes the [Building a Universe](building-a-universe.ipynb) notebook and captures the variables into this notebook. They are only valid if they are executed in the same folder as the [Building a Universe](building-a-universe.ipynb) notebook. Otherwise, please copy the last section of [Building a Universe](building-a-universe.ipynb) to set the same state." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%capture\n", "# Run Building a universe notebook and hide output\n", "%run \"building-a-universe.ipynb\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are 8 parameters in the universe:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(universe.parameters)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So while all 8 parameters can be passed when initiliasing `Control`, they can also be filtered. `Parameters` objects have a number of convenience methods to assist with this:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "parameters = universe.parameters\n", "help(parameters)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For example, if only the charge parameters should be refined, `parameters` could be filtered by name:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "charges = parameters.filter_name('charge')\n", "print(charges)\n", "\n", "# charges is a Parameters object\n", "print('\\nThe class of charges is: {}'.format(type(charges)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As each filter returns a `Parameters` object, filters can be chained together. For example, to find the potential strengths of all bonds:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "bond_potential_strengths = parameters.filter_name('potential_strength').filter_interaction('Bond')\n", "print(bond_potential_strengths)\n", "\n", "# These operations are commutative\n", "print('\\nThe order these methods are'\n", " ' applied does not matter: {}'.format(bond_potential_strengths\n", " == parameters.filter_interaction('Bond').filter_name('potential_strength')))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It is also possible to filter parameters based on the properties of the atoms to which they apply. For instance, we can filter the SPCE parameters so that only parameters of interactions on H atoms are shown:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "H_parameters = parameters.filter_atom_attribute('name', 'H')\n", "print(H_parameters)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally there is also a more flexible method (`Parameters.filter`) which can be used in conjunction with any function to filter the parameters:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def is_length(parameter):\n", " if parameter.unit == 'Ang':\n", " return True\n", " else:\n", " return False\n", "length_parameters = parameters.filter(is_length)\n", "print(length_parameters)\n", "\n", "# For those more familiar with Python, this can also be done using a lambda\n", "lambda_length_parameters = parameters.filter(lambda x: x.unit == 'Ang')\n", "print('\\nThe same filter can be achieved using lambdas: {}'.format(lambda_length_parameters == length_parameters))" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.6" } }, "nbformat": 4, "nbformat_minor": 2 }