=========================
 Contributing to IOSACal
=========================


Overview
--------

IOSACal is written in Python_ 3, and it makes heavy use of the NumPy_ library
for the internal management of calibration curves and calibrated samples.
Calibration curves, radiocarbon dates and calibrated curves are handled
internally as ``ndarray`` objects. ``ndarray`` objects are matrices that can be
easily manipulated through slicing, flipping, summing and other typical
operations.

Generation of plots is done through Matplotlib_, another Python
library built on top of NumPy. Matplotlib can natively read
``ndarray`` objects and plot them in a graphical form. Far from being
just a set of plotting functions, Matplotlib allows the drawing of
complex plots like those created by IOSACal.

Development happens in a public git repository at Codeberg_, the free
home for free projects. The default branch name is *main*.

.. _Python: http://www.python.org/
.. _NumPy: http://numpy.scipy.org/
.. _Matplotlib: http://www.matplotlib.org/
.. _Codeberg: https://codeberg.org/steko/iosacal

Codebase structure
------------------

The ``iosacal`` directory in the root of the Git repository is a
Python package that contains the following source code files:

* ``__init__.py`` is first of all there to declare that this directory
  is a Python package. It also imports three objects (*R*, *combine*
  and *iplot*) so that they can be imported directly from the root
  package with ``from iosacal import R`` - that is enough to calibrate
  a date when using a Python interpreter. And it contains the current
  version that is propagated to other parts of the program.
* ``cli.py`` contains the command line app, based on Click_
* ``core.py`` contains the main classes to instantiate calibration
  curves and radiocarbon determinations, and functions that work
  directly on them like ``combine``
* ``hpd.py`` contains functions to compute Highest Posterior Density
  and helper classes to format the resulting confidence intervals
* ``plot.py`` contains two large functions based on Matplotlib that
  are respectively dedicated to plotting a single date or multiple
  ("stacked") dates. The small ``iplot`` function is useful for usage
  with Jupyter notebooks
* ``spd.py`` contains functions and classes for working with Sum of
  Probability Distributions of calibrated dates
* ``text.py`` contains one function to format calibration results for
  output to a terminal or a Markdown document
* the ``data`` subdirectory contains the calibration curves in the
  standard ``.14c`` format.

Tests are in a separate directory called ``tests`` in the root of the
Git repository. Each file corresponds to one of the modules listed
above and has the name prefixed with ``test_``, such as
``test_core.py``.

Documentation is in the ``docs`` directory and is a collection of
files in reStructured Text format, for use with Sphinx. There is also
a file called ``.readthedocs.yml`` in the root of the Git repository,
that contains some settings for Read the Docs, the service that
publishes the formatted documentation you are probably reading right
now. If you're contributing changes to the source code, please always
check that the documentation is updated and include relevant changes
to the documentation as well.

.. _Click: https://click.palletsprojects.com/

Contributing
------------

Contributing to IOSACal can be done by suggesting improvements or
pointing out bugs and limitations of the program. This kind of
contribution works by opening a new *issue* at
https://codeberg.org/steko/iosacal/issues . Please always open a new
issue to let other contributors know that you're working on a specific
problem.

Code contributions are based on *pull requests*, as is common in
modern open source software. You will need Git to clone the repository
on your development machine.

However, if you're not familiar with Git or you don't want to open an
account specifically for contributing, you can send the modified files
by email or attach them to the issue.

Coding guidelines
-----------------

The maintainer prefers to use black_ with the default settings to
format source code.

.. _black: https://black.readthedocs.io/en/stable/

Interpolation
-------------

The *IntCal09* and *IntCal13* calibration curves have a varying
resolution. For example, in *IntCal09* data spacing changes from 5
years for the range from 0 to 11.2 to cal kBP, 10 yrs for 11.2–15 cal
kBP, 20 yrs for 15–25 cal kBP, 50 yrs for 25–40 cal kBP, and 100 yrs
for 40–50 cal kBP [REI2009]_. Other curves follow a similar pattern.

This means that the output intervals would follow these limitations. IOSACal
uses the `interp` function of *NumPy* to perform linear interpolation of the
calibration curves and obtain more fine-grained results, particularly concerning
probability intervals.

.. [REI2009] Reimer PJ, Baillie MGL, Bard E, Bayliss A, Beck JW, Blackwell PG,
   Bronk Ramsey C, Buck CE, Burr GS, Edwards RL, Friedrich M, Grootes PM,
   Guilderson TP, Hajdas I, Heaton TJ, Hogg AG, Hughen KA, Kaiser KF, Kromer B,
   McCormac FG, Manning SW, Reimer RW, Richards DA, Southon JR, Talamo S,
   Turney CSM, van der Plicht J, Weyhenmeyer CE. 2009. IntCal09 and Marine09
   radiocarbon age calibration curves, 0–50,000 years cal BP. Radiocarbon
   51(4):1111–50.
