The ``fit`` Subscript
=======================

Having simulated some data to which we can fit our model, the :ref:`fit_script`
is run in order to estimate the "best fit" fixed effects (and random effects)
for the simulated dataset.

``fit`` Inputs
-----------------

As in the ``gen`` script, a |method_options| block contains a ``py_module`` 
entry that defines the action to take (``fit`` in this case).

A new |file_paths| section includes an ``input_data_file`` entry that points
to the data file (``my_pkpd_model_gen.pyml_output/generated_data/cx_obs_params.csv``)
that defines the study and the individuals taking part in it.

.. literalinclude:: 
    /case-studies/quick_start/builtin_tut_example/fit_sections/FILE_PATHS.pyml
    :language: pyml

Because the properties of the population and study are entirely 
contained in the input data, a ``fit`` script need only consider what
fixed effects and random effects to estimate, so the parent ``tut`` script's 
|fit_effects| that is copied to the ``fit`` script's |effects| block
does not include covariates (|cx|) or times (|tx|):

.. literalinclude:: 
    /case-studies/quick_start/builtin_tut_example/fit_sections/EFFECTS.pyml
    :language: pyml

Furthermore, because fixed effects are unknown but allowed to vary
they are given a *distribution* of values (usually to limit their range) 
and an initial value to begin the estimation process:

.. code-block:: pyml

    f[X] ~ <distribution> <initial value>

For example,

.. code-block:: pyml

    f[X] ~ unif(0.0, +inf) 1.0

defines a uniformly distributed variable that must take a value in the range
(0, +infinity) - |ie| a positive value - and that has an initial value of 1.0. 
Because this range is a common one in |pkpd| modelling, 
|popy| provides a convenient shortcut, ``~ P``:

.. code-block:: pyml

    f[X] ~ P 1.0
   
where the 'P' is short for 'positive'.

Random effects definitions are identical to those in the ``gen`` script.

In total there are 271 parameters to estimate: 

* six univariate parameters
* one symmetric covariance matrix with 15 degrees of freedom
* five random effects for each of the 50 individuals in the population

|model_params|, |derivatives| and |predictions| define the mathematical model
as before, and the |ode_solver| section sets the parameters of the solver that
integrates derivatives into amounts.

|output_scripts| defines the subscripts we want to run after completing 
the model fitting, which in this case are ``sim``, ``msim`` and ``fitsum``.
As with ``gen``, ``sim`` simulates smooth curves at dense time points for the 
model with estimated (rather than true) values of the parameters, 
and ``fitsum`` creates a HTML report of the fitting process.

``msim`` is a different subscript that, given population fixed effects, will
generate many new populations whose statistics can be used to evaluate the 
goodness of fit via a Visual Predictive Check (VPC).

The other section - also new to the ``fit`` script - is the ``FIT_METHODS``
section that defines the fitting method (|eg| FOCE, JOE or ND) and its 
parameters (|eg| tolerances or number of iterations). These parameters control 
how well and how quickly a fitting algorithm will converge on a final estimate
and will be discussed in greater depth later in this book.

.. literalinclude:: 
    /case-studies/quick_start/builtin_tut_example/fit_sections/FIT_METHODS.pyml
    :language: pyml
    

``fit`` Outputs
-----------------

Running this ``fit`` script (either manually or as part of this ``tut``
tutorial), will attempt to minimize iteratively an error function 
(known as the Objective Function, OBJV) over a number of steps such that
the model parameters generate a better prediction of the data at every step.
The Objective Function is defined in such a way that it is minimized when
the *likelihood* (the probability of the data given the model) is maximized,
and when OBJV stops decreasing the fit is said to have *converged* 
(:numref:`table_obj_vs_time_builtin_fit_example`).

.. _table_obj_vs_time_builtin_fit_example:

.. csv-table:: Objective values vs iteration number and time
    :file: ../../case-studies/quick_start/builtin_tut_example/builtin_tut_example_fit.pyml_output/OBJV_vs_time.csv
    
Because the data to which we are fitting with our model 
was created by simulating observations *with the same model*, 
we should expect a good model fit to the data.
(Some differences in estimated parameter values should, however, be expected
because the observations are noisy and imperfect [Sheiner1980]_.)

When OBJV has converged to a locally minimal value (a "local minimum")
then the corresponding values of the fixed effects and random effects 
are returned as the "best" estimates of those variables:

.. literalinclude:: /case-studies/quick_start/builtin_tut_example/final_fx_params.txt
    :language: pyml

After running ``fit`` followed by ``sim`` followed by ``grph``
we can see a smooth predicted time series of drug concentration 
for every individual, overlaid with the input observations
(:numref:`table_pred_vs_target_plots_builtin`)

.. _table_pred_vs_target_plots_builtin:

.. list-table:: Model predictions vs original data points for first three individuals 
    :class: image_table
    
    * - .. thumbnail:: /case-studies/quick_start/builtin_tut_example/images/fit_sim_grph_outputs/indOBS_vs_TIME/000001.*
      - .. thumbnail:: /case-studies/quick_start/builtin_tut_example/images/fit_sim_grph_outputs/indOBS_vs_TIME/000002.*
      - .. thumbnail:: /case-studies/quick_start/builtin_tut_example/images/fit_sim_grph_outputs/indOBS_vs_TIME/000003.* 

where a dashed blue line represents the noiseless model predictions 
given the *initial* |fx| parameters and sampled |rx| values for each individual, 
a solid blue line represents the predicted curve for the *final* values, and  
solid blue dots represent the simulated, noisy observations 
(|cdvcen| in ``synthetic_data.csv``).

These graphs show that |popy| has adjusted the |fx| and |rx| parameters
such that the |pk| curves more closely match the input data 
and therefore maximise the likelihood of the data being generated from this model.
