.. _effects:

EFFECTS
###########

A required :term:`verbatim` section that defines |fes| and |res| for use in mixed effects models. The |effects| section defines a level structure, which dictates the number of instances of the |fx| and |rx| effect variables. 

For example, |fx| variables representing |fes| are usually declared at the |pop| level, so there is only one value of each |fx|. Whereas |rx| variables representing |res| are usually declared at the |id_level| level, so each individual has a sample from each |re|. It is also possible to define further sub levels below the |id_level| level, for example within individual occasions which have there own |rx| variables, see :ref:`inter_occasion_variation`.

The |effects| section is required by the following scripts:- 

* :ref:`tut_script`
* :ref:`gen_script`
* :ref:`fit_script`
* :ref:`mtut_script`
* :ref:`mgen_script`
* :ref:`mfit_script`
* :ref:`msim_script`

|ie| Any script that defines a mixed effect model. Note that a :ref:`tut_script` or :ref:`mtut_script` has two separate |effects| sections named |gen_effects| and |fit_effects|. 

.. _example_two_level_effects_fit:

EFFECTS with two levels from a fit_script
===============================================

The example below is used in :ref:`builtin_fit_example`.

.. literalinclude:: 
    /_autogen/quick_start/builtin_fit_example/fit_sections/EFFECTS.pyml
    :language: pyml

The example above defines two levels:-

* |pop| - single value of each |fx| variable over whole population
* |id_level| - one value per individual for each |rx| variable

This example defines 5 mean |fe| parameters |ie| |fx_main_builtin|, a 5x5 covariance matrix |fx_isv_mat_builtin|, a proportional noise variable :pyml:`f[PNOISE]` and a 5 element vector |rx_vec_builtin| of |res| defined for each individual. 

Every variable declared at the |pop| level has **one** shared value over the whole population. 
The |id_level| level creates a single instance of each |rx| distribution for each 'ID' field present in the |data_file|. This is similar to the **factor** concept in |r|. The structure of the mixed effects is a tree, see :numref:`fig_two_level_tree`.

.. _fig_two_level_tree:

.. figure:: /handwritten/popy_guide/hierarchy_diagrams/two_level_tree.*
    :width: 80%
    :align: center
    
    |effects| structure with **two** levels

Here the number of |rx| values is dependent on the number of individuals in the |data_file|.
    
.. _example_three_level_effects_fit:

EFFECTS with three levels from a fit_script
===================================================
    
It is possible to add a further level as follows:-
        
.. literalinclude:: EFFECTS_three_levels_fit.pyml
    :language: pyml
    
The example above defines three levels:-

* |pop| - single value of each |fx| variable
* |id_level| - one value per individual for each |rx| variable
* |iov| - one value per iov per individual for each |rx| variable
    
The |iov| level creates an extra level of |rx_iov_vec_builtin| variables. If there are say 2 different values of :pyml:`c[IOV]` in the |data_file| (|ie| two occasions) then each individual has a 5 element vector |rx_vec_builtin| at the |id_level| level and additionally two 5 element vectors |rx_iov_vec_builtin| (one for each occasion) at the |iov| level.
    
The structure of the mixed effects is now as show in :numref:`fig_three_level_tree`.

.. _fig_three_level_tree:

.. figure:: /handwritten/popy_guide/hierarchy_diagrams/three_level_tree.*
    :width: 80%
    :align: center
    
    |effects| structure with **three** levels
    
For more information on this topic see :ref:`inter_occasion_variation`.
    
.. _example_two_level_effects_gen:

EFFECTS with two levels from a gen_script
===============================================

The example below is used in :ref:`builtin_gen_example`.

.. literalinclude:: 
    /_autogen/quick_start/builtin_gen_example/gen_sections/EFFECTS.pyml
    :language: pyml

The example above defines two levels and is similar to the :ref:`example_two_level_effects_fit` section. The :ref:`fit_script` defines |fx| and |rx| variables. Additionally this :ref:`gen_script` version defines |cx| variables and additionally |tdose| and |tobs| variables that define the dosing and |obs| rows of the generated |data_file|.  

In the |pop| section:-

.. code-block:: pyml

    POP: |
        c[AMT] = 100.0
    
This syntax creates a |camt| field in the |data_file| which is constant over **all** rows. In the |id_level| section:-

.. code-block:: pyml

    ID: |
        c[ID] = sequential(50)
            
This syntax creates a |cid| field in the |data_file| which has values of [1,50]. |ie| 50 individuals. Also in the |id_level| sections these |tx| variables are declared:-
            
.. code-block:: pyml

    ID: |
        t[DOSE] = 2.0
        t[OBS] ~ unif(1.0, 50.0; 5)

The |tdose| creates a dose row at time 2.0 for all individuals. The |tobs| line creates 5 |obs| rows at random time points in the range [1,50.0].
    
.. _example_three_level_effects_gen:

EFFECTS with three levels from a gen_script
===================================================
    
It is possible to add a further level to the :ref:`gen_script` EFFECTS as follows:-
        
.. literalinclude:: EFFECTS_three_levels_gen.pyml
    :language: pyml
    
The obvious difference between :ref:`example_two_level_effects_gen` and the three level version above is the addition of the third section:-

.. code-block:: pyml

    IOV: |
        c[IOV] = sequential(2)
        t[DOSE] = 2.0
        t[OBS] ~ unif(1.0, 50.0; 5)
        # t[OBS] = range(1.0, 50.0; 5)
        r[KA_iov, CL_iov, V1_iov, Q_iov, V2_iov] ~ mnorm( 
            [0,0,0,0,0], 
            f[KA_iov, CL_iov, V2_iov, Q_iov, V3_iov] 
        )

This denotes an |iov| level with two occasions for each individual. Note that this line creates two occasions:-

.. code-block:: pyml

    IOV: |
        c[IOV] = sequential(2)
            
|ie| rows with :pyml:`c[IOV]` taking the values [1,2] are created. Within each occasion the |tdose| and |tobs| create a dosing row and 5 observation rows. Note it is necessary to move the |tx| variables from the |id_level| level to the |iov| level. In a :ref:`gen_script` it usually makes sense to place the |tx| variables at the lowest level.


.. _combining_effects_in_tut:

Combining EFFECTS in a tut_script
===================================

A :ref:`tut_script` combines a :ref:`gen_script` and a :ref:`fit_script`, so has to encode both a generating |effects| section and a fitting |effects| section.

.. _gen_effects:

GEN_EFFECTS
------------

The generating EFFECTS section in a :ref:`tut_script` is called GEN_EFFECTS. This section is transcribed into the EFFECTS section in the **child** :ref:`gen_script`.

The GEN_EFFECTS can contain |fx|, |rx|, |tx| and |cx| variable definitions in each level.

.. _fit_effects:

FIT_EFFECTS
------------

The fitting EFFECTS section in a :ref:`tut_script` is called FIT_EFFECTS. This section is transcribed into the EFFECTS section in the **child** :ref:`fit_script`.

The FIT_EFFECTS section can contain |fx| and |rx| variable definitions in each level. 

.. _example_two_level_effects_tut:

EFFECTS with two levels from a tut_script
===============================================

The examples below are used in :ref:`builtin_tut_example`.

.. literalinclude:: 
    /_autogen/quick_start/builtin_tut_example/tut_sections/GEN_EFFECTS.pyml
    :language: pyml

.. literalinclude:: 
    /_autogen/quick_start/builtin_tut_example/tut_sections/FIT_EFFECTS.pyml
    :language: pyml

The :ref:`tut_script` combines the :ref:`gen_script` and :ref:`fit_script` levels. 
    
.. _example_three_level_effects_tut:

EFFECTS with three levels from a tut_script
==================================================

It is possible to add the third level to a :ref:`tut_script` as follows:-

.. literalinclude:: EFFECTS_three_levels_tut.pyml
    :language: pyml

This is similar to the :ref:`example_three_level_effects_fit` and :ref:`example_three_level_effects_gen` examples. The :ref:`tut_script` copies GEN_EFFECTS into :ref:`gen_script` EFFECTS and FIT_EFFECTS into :ref:`fit_script` EFFECTS.
 
 
Rules for each EFFECTS level
=======================================

Each individual level of the |effects| is a :term:`verbatim` section, as follows:-

.. code-block:: pyml

    EFFECTS:
        <level_name>: |

However the level section is limited in what expressions it can accept. For example it is |not| pseudo |python| code, unlike the |preprocess|, |model_params| or |derivatives| sections, which act more like |python| functions.

Generally only declarative expressions of the type:-

.. code-block:: pyml

    x[VAR] = <some definition>
    
Or

.. code-block:: pyml

    x[VAR] ~ <some definition>

Are allowed. You cannot use :python:`if` statements for example. And all effect levels are declarative and unordered. |ie| the order of the statements in a single effects level makes no difference to the mixed effect model.

The variables you are allowed to declare on the |lhs| depends on which type of script you are running:-

* In a :ref:`fit_script` you are allowed to declare |fx| and |rx| only. 
* In a :ref:`gen_script` you are allowed to declare |fx|, |rx|, |cx| and |tx| 
* All variables must have a unique name, |ie| no duplicate |cx| or |fx| or |rx|
* If a variable is on the |rhs| of an expression it **must** be defined in a level **above** the current level

You can |not| use |mx|, |dx|, |px| etc variables in |effects|.

Like all :term:`verbatim` sections it is possible to introduce syntax errors by writing malformed code in |effects|. Any errors will be brought to the users attention when |popy| attempts to interpret the verbatim sections and form a tree structure to manage the |fe| and |re| variables.
 