Skip to content

Commit

Permalink
Merge pull request #124 from spjuhel/develop
Browse files Browse the repository at this point in the history
JOSS Version 1
  • Loading branch information
spjuhel authored Jun 8, 2024
2 parents 32d2ada + f649c33 commit fccfebb
Show file tree
Hide file tree
Showing 19 changed files with 214 additions and 177 deletions.
1 change: 1 addition & 0 deletions .github/workflows/static_html_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ jobs:
# which you find below to build all documents
git fetch --tags
cd docs
poetry run ipython kernel install --name "boario" --user
poetry run python ./source/build_docs.py
- name: Setup Pages
uses: actions/configure-pages@v5
Expand Down
43 changes: 34 additions & 9 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,17 @@ hesitate to contact the author when using the model !
What is BoARIO ?
=================

BoARIO, is a python implementation project of the Adaptative Regional Input Output (ARIO) model [`Hallegatte 2013`_].
BoARIO, is a python implementation project of the Adaptative Regional Input Output (ARIO) model [`Hal13`_].

Its objectives are to give an accessible and inter-operable implementation of ARIO, as well as tools to visualize and analyze simulation outputs and to
evaluate the effects of many parameters of the model.

This implementation would not have been possible without the `Pymrio`_ module and amazing work of [`Stadler 2021`_] !
This implementation would not have been possible without the `Pymrio`_ module and amazing work of [`Sta21`_].

It is still an ongoing project (in parallel of a PhD project).
It is still an ongoing project (in parallel with a PhD project).

.. _`Stadler 2021`: https://openresearchsoftware.metajnl.com/articles/10.5334/jors.251/
.. _`Hallegatte 2013`: https://doi.org/10.1111/j.1539-6924.2008.01046.x
.. _`Sta21`: https://openresearchsoftware.metajnl.com/articles/10.5334/jors.251/
.. _`Hal13`: https://doi.org/10.1111/j.1539-6924.2008.01046.x
.. _`Pymrio`: https://pymrio.readthedocs.io/en/latest/intro.html

You can find most academic literature using ARIO or related models `here <https://spjuhel.github.io/BoARIO/boario-references.html>`_
Expand All @@ -63,15 +63,37 @@ What is ARIO ?

ARIO stands for Adaptive Regional Input-Output. It is an hybrid input-output / agent-based economic model,
designed to compute indirect costs from economic shocks. Its first version dates back to 2008 and has originally
been developed to assess the indirect costs of natural disasters (Hallegatte 2008).
been developed to assess the indirect costs of natural disasters [`Hal08`_].

In ARIO, the economy is modelled as a set of economic sectors and a set of regions.
Each economic sector produces its generic product and draws inputs from an inventory.
Each sector answers to a total demand consisting of a final demand (household consumption,
public spending and private investments) of all regions (local demand and exports) and
intermediate demand (through inputs inventory resupply). An initial equilibrium state of
the economy is built based on multi-regional input-output tables (MRIO tables).
the economy is built based on multi-regional input-output tables (MRIOTs).

For a more detailed description, please refer to the `Mathematical documentation`_ of the model.

Multi-Regional Input-Output tables
-------------------------------------

Multi-Regional Input-Output tables (MRIOTs) are comprehensive economic data sets
that capture inter-regional trade flows, production activities, and consumption
patterns across different regions or countries. These tables provide a detailed
breakdown of the flows of goods and services between industries within each
region and between regions themselves. MRIOTs are constructed through a
combination of national or regional input-output tables, international trade
data, and other relevant economic statistics. By integrating data from multiple
regions, MRIOTs enable the analysis of global supply chains, international trade
dependencies, and the estimation of economic impacts across regions. However,
they also come with limitations, such as data inconsistencies across regions,
assumptions about trade patterns and production technologies, and the challenge
of ensuring coherence and accuracy in the aggregation of data from various
sources.

.. _`Mathematical documentation`: https://spjuhel.github.io/BoARIO/boario-math.html

.. _`Hal08`: https://doi.org/10.1111/risa.12090

Where to get BoARIO ?
==========================
Expand All @@ -98,18 +120,21 @@ How does BoARIO work?

In a nutshell, BoARIO takes the following inputs :

- an IO table (such as EXIOBASE3 or EORA26) in the form of an ``pymrio.IOSystem`` object, using the `Pymrio`_ python package.
- a (possibly Environmentally Extended) Multi-Regional IO table (such as `EXIOBASE 3`_ or `EORA26`_) in the form of an ``pymrio.IOSystem`` object, using the `Pymrio`_ python package. Please reference the `Pymrio documentation <https://github.com/IndEcol/pymrio>`_ for details on methods available to pymrio objects.

- multiple parameters which govern the simulation,

- event(s) description(s), which are used as the perturbation to analyse during the simulation

And produce the following outputs:
And produces the following outputs:

- the step by step, sector by sector, region by region evolution of most of the variables involved in the simulation (`production`, `demand`, `stocks`, ...)

- aggregated indicators for the whole simulation (`shortages duration`, `aggregated impacts`, ...)

.. _`EXIOBASE 3`: https://www.exiobase.eu/
.. _`EORA26`: https://worldmrio.com/eora26/

Example of use
=================

Expand Down
61 changes: 51 additions & 10 deletions boario/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,58 @@
__version__ = importlib.metadata.version("boario")
__author__ = "sjuhel <[email protected]>"

# __minimum_python_version__ = "3.8"

# Create a logger object.
logger = logging.getLogger(__name__)
logger.addHandler(logging.NullHandler())

DEBUGFORMATTER = logging.Formatter(
fmt="%(asctime)s [%(levelname)s] - [%(filename)s > %(funcName)s() > %(lineno)s] - %(message)s",
fmt="%(asctime)s - boario - [%(levelname)s] - [%(filename)s > %(funcName)s() > %(lineno)s] - %(message)s",
datefmt="%H:%M:%S",
)

"""Debug file formatter."""

INFOFORMATTER = logging.Formatter(
fmt="%(asctime)s [%(levelname)s] - %(message)s",
fmt="%(asctime)s - boario - [%(levelname)s] - %(message)s",
datefmt="%H:%M:%S",
)
"""Info file formatter."""


# Create a logger object.
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

# Console logger
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
ch.setFormatter(INFOFORMATTER)

# Avoid adding multiple handlers in case of repeated imports
if not logger.handlers:
logger.addHandler(ch)


# Functions to activate/deactivate logging
def deactivate_logging():
"""Deactivate logging for the package."""
logger.disabled = True


def activate_logging():
"""Activate logging for the package."""
logger.disabled = False


# Functions to disable/enable console logging
def disable_console_logging():
"""Disable console logging for the package."""
logger.info(
"Disabling logging. You can reenable it with `boario.enable_console_logging()`"
)
logger.removeHandler(ch)


def enable_console_logging():
"""Enable console logging for the package."""
if ch not in logger.handlers:
logger.addHandler(ch)


try:
import pygit2
Expand All @@ -55,12 +91,17 @@
logger.info("You are using boario from branch %s", __git_branch__)
except pygit2.GitError:
logger.info(
"Could not find git branch, this is normal if you installed boario from pip."
"Could not find git branch, this is normal if you installed boario from pip/conda."
)
except ModuleNotFoundError:
logger.info("Unable to tell git branch as pygit2 was not found.")


logger.info(
"Loaded boario module. You can disable logging in console with `boario.disable_console_logging()`."
)


@lru_cache(10)
def warn_once(logger, msg: str):
logger.warning(msg)
Expand Down
5 changes: 4 additions & 1 deletion boario/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -494,8 +494,11 @@ def from_scalar_regions_sectors(
Event
An Event object or one of its subclass.
"""
if not isinstance(impact, (int, float)):
raise ValueError("Impact is not scalar.")

if impact <= 0:
raise ValueError("Impact is null")
raise ValueError("Impact is null.")

if isinstance(regions, str):
regions = [regions]
Expand Down
2 changes: 1 addition & 1 deletion boario/model_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -895,7 +895,7 @@ def production_cap(self) -> npt.NDArray:
production_cap = production_cap * self.overprod
if (production_cap < 0).any():
raise ValueError(
"Production capacity was found negative for at least on industry"
"Production capacity was found negative for at least on industry. It may be caused by an impact being to important for a sector."
)
return production_cap

Expand Down
14 changes: 9 additions & 5 deletions boario/simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,13 +303,14 @@ def __init__(
"n_temporal_units_by_step": self.model.n_temporal_units_by_step,
"year_to_temporal_unit_factor": self.model.iotable_year_to_temporal_unit_factor,
"inventory_restoration_tau": (
list(self.model.restoration_tau)
list(np.reciprocal(self.model.restoration_tau))
if isinstance(self.model, ARIOPsiModel)
else None
),
"alpha_base": self.model.overprod_base,
"alpha_max": self.model.overprod_max,
"alpha_tau": self.model.overprod_tau,
"alpha_tau": self.model.overprod_tau
* self.model.iotable_year_to_temporal_unit_factor,
"rebuild_tau": self.model.rebuild_tau,
}
"""dict: A dictionary saving the parameters the simulation was run with."""
Expand Down Expand Up @@ -416,7 +417,7 @@ def loop(self, progress: bool = True):
self.model.write_index(self.results_storage / "jsons" / "indexes.json")

self.params_dict["n_temporal_units_simulated"] = self.n_temporal_units_simulated
self.has_crashed = self.has_crashed
self.params_dict["has_crashed"] = self.has_crashed

if self._save_params:
with (
Expand All @@ -432,7 +433,10 @@ def loop(self, progress: bool = True):
indent=4,
cls=CustomNumpyEncoder,
)
logger.info("Loop complete")
if self.has_crashed:
logger.info("Loop crashed before completion.")
else:
logger.info("Loop complete")

def next_step(
self,
Expand Down Expand Up @@ -551,7 +555,7 @@ def next_step(
):
self._write_rebuild_prod()
except RuntimeError:
logger.exception("An exception happened:")
logger.exception("An exception happened: ")
self.model.matrix_stock.dump(
self.results_storage / "matrix_stock_dump.pkl"
)
Expand Down
7 changes: 6 additions & 1 deletion docs/source/_static/switcher.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
[
{
"name": "latest",
"version": "v0.5.9",
"version": "v0.5.10",
"url": "https://spjuhel.github.io/BoARIO/",
"preferred": true
},
{
"name": "v0.5.9",
"version": "v0.5.9",
"url": "https://spjuhel.github.io/BoARIO/v0.5.9/en"
},
{
"name": "v0.5.8",
"version": "v0.5.8",
Expand Down
12 changes: 6 additions & 6 deletions docs/source/boario-math.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ Model description

Background and overview
=======================

Adaptive Regional Input-Output (ARIO) is an I-O model, designed to compute indirect
costs from exogenous shocks. Its first version dates back to 2008 and has originally
been developed to assess the indirect costs of natural disasters (Hallegatte 2008).
been developed to assess the indirect costs of natural disasters :cite:`2008:hallegatte`.
In this paper we present BoARIO, a generic python implementation, similar to the one
described in (Hallegatte 2014) with some additions (e.g. inspired by Guan et al. 2020).
described in :cite:`2013:hallegatte` with some additions (e.g. inspired by :cite:`2020:guan`).

The economy is modelled as a set of economic sectors and a set of regions.
In the following, we call an industry a specific (sector, region) couple.
Expand All @@ -23,11 +23,11 @@ An initial equilibrium state of the economy is built based on multi-regional
input-output tables (MRIO tables). Apart from parameters specific to the MRIOT
region-sector typology, BoARIO supposedly handles any MRIOT in the same manner.

Multiple kinds of shocks can be implemented:
Multiple kinds of shocks can be implemented:

* On the production capacity directly (one or multiple industries are arbitrarily
forced to produce less)
* On the productive capital (one or multiple industries arbitrarily
* On the productive capital (one or multiple industries arbitrarily
lose some part of their factors of production and are thus forced to both
produce less and to build back their capital stock).
* On the households (households of affected regions lose some part of their goods and
Expand All @@ -45,7 +45,7 @@ industries adjust their production and orders based on both demand and their inv
Direct economic impact consists in the valuation of the initial exogenous shock,
while total economic impact includes also indirect costs consequent to the propagation.

Total economic impact can be measured in two ways:
Total economic impact can be measured in two ways:

* Final demand not met, i.e. goods that households couldn’t buy due to rationing.
* Relative production change, i.e. diminished or increased production of industries relative to their initial production.
Expand Down
2 changes: 2 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@
napoleon_use_param = False
napoleon_use_ivar = False

nbsphinx_kernel_name = "boario"

# automatically generate api references
autosummary_generate = ["boario-api-reference.rst"]

Expand Down
Loading

0 comments on commit fccfebb

Please sign in to comment.