=================
Electrophysiology
=================

The purpose of the :mod:`electrophysiology` component is to store metadata about
electrodes and how they are used in electrophysiology experiments.

This component depends on the :mod:`helmholtz.equipment` and
:mod:`helmholtz.chemistry` components.

We distinguish between the physical electrode and the way it is used (configuration).
Physical electrodes are represented by subclasses of :class:`helmholtz.equipment.Equipment`
and electrode configurations by subclasses of :class:`helmholtz.equipment.DeviceConfiguration`.


Electrodes
----------

All electrodes have attributes :attr:`material`, :attr:`external_diameter` and
:attr:`impedance`, e.g.::

    >>> from helmholtz.equipment.models import Material
    >>> from helmholtz.units.fields import PhysicalQuantity as Q
    >>> from helmholtz.electrophysiology.models import SolidElectrode, PatchElectrode
    >>> tungsten = Material(name="tungsten")
    >>> tungsten.save()
    >>> selectrode = SolidElectrode(material=tungsten, external_diameter=Q(0.125, "mm"),
    ...                            impedance=Q(2, u"MΩ"))
    >>> selectrode.save()

(the :class:`Material` entry can also contain the supplier of the material, if you wish).

Hollow electrodes (:class:`SharpElectrode` and :class:`PatchElectrode`) also have
an :attr:`internal_diameter` attribute::

    >>> borosilicate = Material(name="borosilicate glass")
    >>> borosilicate.save()
    >>> pelectrode = PatchElectrode(material=borosilicate, external_diameter=Q(1.65, "mm"),
    ...                             internal_diameter=Q(0.75, "mm"))
    >>> pelectrode.save()
    
.. NOTE: I don't think impedance makes much sense for hollow electrodes, since
..       their impedance depends on the solution with which they're filled,
..       which is stored in the ElectrodeConfiguration class.


Electrode configurations
------------------------

An electrode configuration is usually associated with one position of the
electrode within the preparation. If the pipette solution is changed, or the
resistance changes due to movement, this creates a new configuration.

In the following example, we assume that the :class:`helmholtz.chemistry.Solution`
object ``pipette_solution`` already exists (see the :doc:`chemistry`
component for details of how to create this).

::

    >>> from helmholtz.electrophysiology.models import PatchElectrodeConfiguration
    >>> electrode_conf = PatchElectrodeConfiguration(resistance=Q(12, u"MΩ"),
    ...                                              solution=pipette_solution,
    ...                                              seal_resistance=Q(1.3, u"GΩ"),
    ...                                              contact_configuration="WC",
    ...                                              filtering="4-pole Bessel, 10 kHz")
    >>> electrode_conf.save()

:attr:`contact_configuration` must have one of the values "CA" (cell attached),
"WC" (whole cell), "PP" (perforated patch), "IO" (inside out), "OO" (outside in),
or "L" (loose). The full configuration name may be obtained with the
:meth:`get_contact_configuration_display()`, e.g.:

    >>> electrode_conf.get_contact_configuration_display()
    u'whole cell'
    >>> electrode_conf.contact_configuration
    'WC'


Reference
---------

.. automodule:: helmholtz.electrophysiology.models

.. autoclass:: DiscElectrode
   :members:
   
.. autoclass:: SolidElectrode
   :members:
   
.. autoclass:: SharpElectrode
   :members:
   
.. autoclass:: PatchElectrode
   :members:
   
.. autoclass:: MultiElectrode
   :members:

.. autoclass:: EEG
   :members:
   
.. autoclass:: EKG
   :members:
   
.. autoclass:: DiscElectrodeConfiguration
   :members:
   
.. autoclass:: SolidElectrodeConfiguration
   :members:
   
.. autoclass:: SharpElectrodeConfiguration
   :members:
   
.. autoclass:: PatchElectrodeConfiguration
   :members:

.. autoclass:: ElectricalSignal
   :members:

.. autoclass:: ElectricalChannel
   :members:

.. autoclass:: RecordingPoint
   :members:
