Source code for arviz_base.citations
"""How to cite ArviZ and its methods."""
import os
import re
[docs]
def citations(methods=None, filepath=None, format_type="bibtex"):
"""
List citations for ArviZ and the methods implemented in ArviZ.
Parameters
----------
methods : Callable or list of callable, optional
Methods implemented in ArviZ from which to retrieve citations.
filepath : str, optional
Specifies the location to save the file with the citations.
If ``None``, the result is returned as a string.
format_type : str
Specifies in which format the references will be displayed.
Currently, only "bibtex" is supported.
Examples
--------
>>> from arviz_base import citations
>>> from arviz_stats import rhat
>>> citations(methods=[rhat]) # Returns how to cite ArviZ and rhat
>>> citations() # Returns how to cite ArviZ
"""
method_citations = [{"doi": "10.21105/joss.XXXXX"}]
if methods is not None:
if isinstance(methods, str):
raise TypeError("you should pass an ArviZ function or list of functions.")
if not isinstance(methods, list | tuple):
methods = [methods]
for method in methods:
_extract_ids_per_entry(method_citations, method.__doc__)
if format_type == "bibtex":
header = _get_header(methods)
citation_text = _find_bibtex_entries(header, method_citations)
if filepath:
with open(filepath, "w") as fw:
fw.write(citation_text)
else:
return citation_text
else:
raise ValueError("Invalid value for format_type. Use 'bibtex'.")
def _extract_ids_per_entry(data, text):
entries = re.split(r"\n\s*\.\. \[\d+\] ", text.strip())
doi_pattern = re.compile(r"https?://doi\.org/(\S+)", re.IGNORECASE)
url_pattern = re.compile(r"https?://(?!doi\.org)(\S+)", re.IGNORECASE)
for entry in entries:
doi_match = doi_pattern.search(entry)
if doi_match:
doi = doi_match.group(1).rstrip(".")
data.append({"doi": doi})
else:
urls = [url.rstrip(".") for url in url_pattern.findall(entry)]
if urls:
data.append({"urls": urls})
return data
def _find_bibtex_entries(header, data):
ref_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "references.bib")
with open(ref_path, encoding="utf-8") as fr:
bibtex_text = fr.read()
entries = re.split(r"\n(?=@)", bibtex_text)
doi_field_pattern = re.compile(r'doi\s*=\s*[{"]([^}"]+)[}"]', re.IGNORECASE)
url_field_pattern = re.compile(r'url\s*=\s*[{"]([^}"]+)[}"]', re.IGNORECASE)
references = [header]
for identifier in data:
found_entry = ""
for entry in entries:
bib_dois = doi_field_pattern.findall(entry)
bib_urls = url_field_pattern.findall(entry)
if "doi" in identifier and any(identifier["doi"] in doi for doi in bib_dois):
found_entry = entry.strip()
break
if "urls" in identifier and any(
any(url in b_url or b_url in url for b_url in bib_urls)
for url in identifier["urls"]
):
found_entry = entry.strip()
break
if found_entry:
if found_entry not in references:
references.append(found_entry)
return "\n\n".join(references)
def _get_header(methods=None):
references = "Bibtex format citations for ArviZ paper\n"
if methods is not None:
methods_str = ", ".join([method.__name__ for method in methods])
references = references.strip() + f", and\nfor the following methods: {methods_str}"
return references