Skip to content

Commit

Permalink
Add sphinxbibtex and function to get references from methods (#651)
Browse files Browse the repository at this point in the history
* Introduce sphinx-bibtex
Add function to generate citations.

* Add sphinxcontrib-bibtex to env docs

* Fix broken citation

* Add citation test in ipynb

* Add file_path to save the file
  • Loading branch information
rohanbabbar04 authored Feb 24, 2025
1 parent d7ed83a commit 1e15418
Show file tree
Hide file tree
Showing 11 changed files with 162 additions and 11 deletions.
4 changes: 4 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"sphinx_tabs.tabs",
"sphinx_design",
"jupyter_sphinx",
"sphinxcontrib.bibtex"
]

# -- Extension configuration -------------------------------------------------
Expand Down Expand Up @@ -143,6 +144,9 @@
# Output file base name for HTML help builder.
htmlhelp_basename = "prelizdoc"

# -- For Bibtex files ---------------------------------------------

bibtex_bibfiles = ['../preliz/internal/reference.bib']

# -- Options for LaTeX output ------------------------------------------------

Expand Down
1 change: 1 addition & 0 deletions environment-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ dependencies:
- sphinx>=4
- sphinx-copybutton
- sphinx-tabs
- sphinxcontrib-bibtex
- jupyter-sphinx
- pymc>=5.16.0
- bambi>=0.13.0
1 change: 1 addition & 0 deletions preliz/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from preliz.unidimensional import *
from preliz.multidimensional import *
from preliz.internal.rcparams import rc_context, rcParams
from preliz.internal.citations import citations


__version__ = "0.15.0"
Expand Down
53 changes: 53 additions & 0 deletions preliz/internal/citations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import os
import re


def citations(methods=None, filepath=None, format_type="bibtex"):
"""
Generate references associated with the methods.
Parameters
----------
methods : A list of preliz methods
Displays references for the specified methods or classes.
Defaults to ``None``, which shows PreliZ's references.
filepath : str or a file-like object
Specifies the location to save the file.
If ``None``, the result is returned as a string.
format_type : str
Specifies in which type the references will be displayed.
Currently, only "bibtex" is supported.
Defaults to ``bibtex``.
"""
if methods is None:
keys = {"PreliZ", "Icazatti2023"}
else:
keys = set()
for method in methods:
matches = set(re.findall(r":(?:cite|footcite):[tp]:`(.*?)`", method.__doc__))
keys.update(matches)
ref_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "reference.bib")
with open(ref_path, encoding="utf-8") as fr:
content = fr.read()

if format_type == "bibtex":
cite_text = _citation_bibtex(content, keys)
if filepath:
with open(filepath, "w") as fw:
fw.write(cite_text)
else:
return cite_text
else:
raise ValueError("Invalid value for format_type. Use 'bibtex'.")


def _citation_bibtex(content, keys):
"""Extract and return references in BibTeX format."""
extracted_refs = []
for key in keys:
match = re.search(rf"(@\w+\{{\s*{key}\s*,.*?\n\}})", content, re.DOTALL)
extracted_refs.append(match.group(1))
return "\n".join(extracted_refs)
74 changes: 74 additions & 0 deletions preliz/internal/reference.bib
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
@software{PreliZ,
author = {Icazatti, Alejandro and
Babbar, Rohan and
Abril-Pla, Oriol and
Klami, Arto and
Martin, Osvaldo A},
title = {PreliZ: A tool-box for prior elicitation},
month = jan,
year = 2025,
publisher = {Zenodo},
version = {0.15.0},
doi = {10.5281/zenodo.14619053},
url = {https://doi.org/10.5281/zenodo.14619053},
swhid = {swh:1:dir:755ff7ec1b224eb9473d5f58ef1c76bf10c2e807;
origin=https://doi.org/10.5281/zenodo.8368035;
visit=swh:1:snp:ce9432267312af4e0473c1987e3c1a54bb05de23;
anchor=swh:1:rel:9284f4998394356b01ad93de1caa5b11a4c07e3c;
path=arviz-devs-preliz-f2bb948}
}

@article{Icazatti2023,
author = {Icazatti, Alejandro and Abril-Pla, Oriol and Klami, Arto and Martin, Osvaldo A},
doi = {10.21105/joss.05499},
journal = {Journal of Open Source Software},
month = sep,
number = {89},
pages = {5499},
title = {{PreliZ: A tool-box for prior elicitation}},
url = {https://joss.theoj.org/papers/10.21105/joss.05499},
volume = {8},
year = {2023}
}

@article{Morris2014,
title = {A web-based tool for eliciting probability distributions from experts},
journal = {Environmental Modelling & Software},
volume = {52},
pages = {1-4},
year = {2014},
issn = {1364-8152},
doi = {https://doi.org/10.1016/j.envsoft.2013.10.010},
url = {https://www.sciencedirect.com/science/article/pii/S1364815213002533},
author = {David E. Morris and Jeremy E. Oakley and John A. Crowe},
keywords = {Bayesian prior distribution, Expert judgement, Subjective probability, Web-based elicitation},
abstract = {We present a web-based probability distribution elicitation tool: The MATCH Uncertainty Elicitation Tool. The Tool is designed to help elicit probability distributions about uncertain model parameters from experts, in situations where suitable data is either unavailable or sparse. The Tool is free to use, and offers five different techniques for eliciting univariate probability distributions. A key feature of the Tool is that users can log in from different sites and view and interact with the same graphical displays, so that expert elicitation sessions can be conducted remotely (in conjunction with tele- or videoconferencing). This will make probability elicitation easier in situations where it is difficult to interview experts in person. Even when conducting elicitation remotely, interviewers will be able to follow good elicitation practice, advise the experts, and provide instantaneous feedback and assistance.}
}

@Article{Michael2017,
AUTHOR = {Evans, Michael and Guttman, Irwin and Li, Peiying},
TITLE = {Prior Elicitation, Assessment and Inference with a Dirichlet Prior},
JOURNAL = {Entropy},
VOLUME = {19},
YEAR = {2017},
NUMBER = {10},
ARTICLE-NUMBER = {564},
URL = {https://www.mdpi.com/1099-4300/19/10/564},
ISSN = {1099-4300},
ABSTRACT = {Methods are developed for eliciting a Dirichlet prior based upon stating bounds on the individual probabilities that hold with high prior probability. This approach to selecting a prior is applied to a contingency table problem where it is demonstrated how to assess the prior with respect to the bias it induces as well as how to check for prior-data conflict. It is shown that the assessment of a hypothesis via relative belief can easily take into account what it means for the falsity of the hypothesis to correspond to a difference of practical importance and provide evidence in favor of a hypothesis.},
DOI = {10.3390/e19100564}
}

@article{Burnham2004,
author = {Kenneth P. Burnham and David R. Anderson},
title = {Multimodel Inference: Understanding AIC and BIC in Model Selection},
journal = {Sociological Methods \& Research},
volume = {33},
number = {2},
pages = {261--304},
year = {2004},
doi = {10.1177/0049124104268644},
url = {https://doi.org/10.1177/0049124104268644},
eprint = {https://doi.org/10.1177/0049124104268644},
abstract = {The model selection literature has been generally poor at reflecting the deep foundations of the Akaike information criterion (AIC) and at making appropriate comparisons to the Bayesian information criterion (BIC). There is a clear philosophy, a sound criterion based in information theory, and a rigorous statistical foundation for AIC. AIC can be justified as Bayesian using a “savvy” prior on models that is a function of sample size and the number of model parameters. Furthermore, BIC can be derived as a non-Bayesian result. Therefore, arguments about using AIC versus BIC for model selection cannot be from a Bayes versus frequentist perspective. The philosophical context of what is assumed about reality, approximating models, and the intent of model-based inference should determine whether AIC or BIC is used. Various facets of such multimodel inference are presented here, particularly methods of model averaging.}
}
7 changes: 5 additions & 2 deletions preliz/multidimensional/dirichlet_mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ def dirichlet_mode(mode, mass=None, bound=0.01, plot=None, plot_kwargs=None, ax=
Elicitate a Dirichlet distribution with a given mode and mass.
Computes a Dirichlet distribution where the marginals have the specified mode
and mass and their masses lie within the range mode ± bound.
and mass and their masses lie within the range mode ± bound
(Adapted from :footcite:t:`Michael2017`).
Parameters
----------
Expand All @@ -37,7 +38,9 @@ def dirichlet_mode(mode, mass=None, bound=0.01, plot=None, plot_kwargs=None, ax=
References
----------
Adapted from Evans et al. (2017) see https://doi.org/10.3390/e19100564
.. footbibliography::
"""
if mass is None:
mass = rcParams["stats.ci_prob"]
Expand Down
11 changes: 11 additions & 0 deletions preliz/tests/test_citation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import pytest

import preliz as pz


@pytest.mark.parametrize(
"methods, filepath, format_type",
[(None, None, "bibtex"), ([pz.Roulette, pz.dirichlet_mode], None, "bibtex")],
)
def test_citations(methods, filepath, format_type):
pz.citations(methods, filepath, format_type)
8 changes: 7 additions & 1 deletion preliz/unidimensional/mle.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def mle(
Find the maximum likelihood distribution given a list of distributions and one sample.
AIC with a correction for small sample sizes is used to compare the fits.
See https://doi.org/10.1177/0049124104268
(See :footcite:t:`Burnham2004`)
Parameters
----------
Expand All @@ -43,6 +43,12 @@ def mle(
-------
idx : array with the indexes to sort ``distributions`` from best to worst match
axes : matplotlib axes
References
----------
.. footbibliography::
"""
for dist in distributions:
valid_distribution(dist)
Expand Down
7 changes: 4 additions & 3 deletions preliz/unidimensional/quartile_int.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

class QuartileInt:
"""
Prior elicitation for 1D distributions from quartiles.
Prior elicitation for 1D distributions from quartiles (See :footcite:t:`Morris2014`).
Parameters
----------
Expand All @@ -42,8 +42,9 @@ class QuartileInt:
References
----------
* Morris D.E. et al. (2014) see https://doi.org/10.1016/j.envsoft.2013.10.010
* See quartile mode http://optics.eee.nottingham.ac.uk/match/uncertainty.php
.. footbibliography::
"""

def __init__(self, q1=1, q2=2, q3=3, dist_names=None, figsize=None):
Expand Down
6 changes: 1 addition & 5 deletions preliz/unidimensional/roulette.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

class Roulette:
"""
Prior elicitation for 1D distribution using the roulette method.
Prior elicitation for 1D distribution using the roulette method (See :footcite:t:`Morris2014`).
Draw 1D distributions using a grid as input.
Expand Down Expand Up @@ -53,10 +53,6 @@ class Roulette:
- inputs: A tuple with the x values, the empirical pdf, the total
chips, the x_min, the x_max, the number of rows, and the number of columns.
References
----------
* Morris D.E. et al. (2014) see https://doi.org/10.1016/j.envsoft.2013.10.010
* See roulette mode http://optics.eee.nottingham.ac.uk/match/uncertainty.php
"""

def __init__(
Expand Down
1 change: 1 addition & 0 deletions requirements-docs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ jupyter-sphinx
ipympl
pymc
bambi
sphinxcontrib-bibtex

0 comments on commit 1e15418

Please sign in to comment.