Skip to content

Commit 7c69f1d

Browse files
authored
Merge pull request #2862 from agriyakhetarpal/issue-1182-tag-citations
Issue 1182 verbose outputs and tagging PyBaMM citations
2 parents 2c32902 + a460035 commit 7c69f1d

File tree

3 files changed

+126
-7
lines changed

3 files changed

+126
-7
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
# Features
44

5+
- Added verbose logging to `pybamm.print_citations()` and citation tags for the `pybamm.Citations` class so that users can now see where the citations were registered when running simulations ([#2862](https://github.com/pybamm-team/PyBaMM/pull/2862))
56
- PyBaMM is now natively supported on Apple silicon chips (`M1/M2`) ([#2435](https://github.com/pybamm-team/PyBaMM/pull/2435))
67
- PyBaMM is now supported on Python `3.10` and `3.11` ([#2435](https://github.com/pybamm-team/PyBaMM/pull/2435))
78
- Updated to casadi 3.6, which required some changes to the casadi integrator. ([#2859](https://github.com/pybamm-team/PyBaMM/pull/2859))

pybamm/citations.py

Lines changed: 85 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import os
88
import warnings
99
import pybtex
10+
from inspect import stack
1011
from pybtex.database import parse_file, parse_string, Entry
1112
from pybtex.scanner import PybtexError
1213

@@ -35,6 +36,9 @@ def __init__(self):
3536
# Dict mapping citations keys to BibTex entries
3637
self._all_citations: dict[str, str] = dict()
3738

39+
# Dict mapping citation tags for use when registering citations
40+
self._citation_tags = dict()
41+
3842
# store citation error
3943
self._citation_err_msg = None
4044

@@ -48,10 +52,21 @@ def _reset(self):
4852
"""Reset citations to default only (only for testing purposes)"""
4953
# Initialize empty papers to cite
5054
self._papers_to_cite = set()
55+
# Initialize empty citation tags
56+
self._citation_tags = dict()
5157
# Register the PyBaMM paper and the numpy paper
5258
self.register("Sulzer2021")
5359
self.register("Harris2020")
5460

61+
def _caller_name():
62+
"""
63+
Returns the qualified name of classes that call :meth:`register` internally.
64+
This is used for tagging citations but only for verbose output
65+
"""
66+
# Attributed to https://stackoverflow.com/a/17065634
67+
caller_name = stack()[2][0].f_locals["self"].__class__.__qualname__
68+
return caller_name
69+
5570
def read_citations(self):
5671
"""Reads the citations in `pybamm.CITATIONS.txt`. Other works can be cited
5772
by passing a BibTeX citation to :meth:`register`.
@@ -78,6 +93,14 @@ def _add_citation(self, key, entry):
7893
# Add to database
7994
self._all_citations[key] = new_citation
8095

96+
def _add_citation_tag(self, key, entry):
97+
"""Adds a tag for a citation key which represents the name of the class that
98+
called :meth:`register`"""
99+
100+
# Add a citation tag to the citation_tags ordered dictionary with
101+
# the key being the citation itself and the value being the name of the class
102+
self._citation_tags[key] = entry
103+
81104
@property
82105
def _cited(self):
83106
"""Return a list of the BibTeX entries that have been cited"""
@@ -101,6 +124,14 @@ def register(self, key):
101124
# Check if citation is a known key
102125
if key in self._all_citations:
103126
self._papers_to_cite.add(key)
127+
# Add citation tags for the key
128+
# This is used for verbose output
129+
try:
130+
caller = Citations._caller_name()
131+
self._add_citation_tag(key, entry=caller)
132+
# Don't add citation tags if the citation is registered manually
133+
except KeyError: # pragma: no cover
134+
pass
104135
return
105136

106137
# Try to parse the citation using pybtex
@@ -119,14 +150,54 @@ def register(self, key):
119150
# Unable to parse / unknown key
120151
raise KeyError(f"Not a bibtex citation or known citation: {key}")
121152

122-
def print(self, filename=None, output_format="text"):
123-
"""Print all citations that were used for running simulations.
153+
def tag_citations(self): # pragma: no cover
154+
"""Prints the citations tags for the citations that have been registered
155+
(non-manually). This is used for verbose output when printing citations
156+
such that it can be seen which citations were registered by PyBaMM classes.
157+
158+
To use, either call :meth:`tag_citations` after calling :meth:`register`
159+
for all citations, or enable verbose output with :meth:`print_citations`
160+
or :meth:`print`.
161+
162+
.. note::
163+
If a citation is registered manually, it will not be tagged.
164+
165+
Examples
166+
--------
167+
.. code-block:: python
168+
:linenos:
169+
170+
pybamm.citations.register("Doyle1993")
171+
pybamm.citations.print() or pybamm.print_citations()
172+
173+
will print the following:
174+
175+
.. code-block::
176+
177+
Citations registered:
178+
Sulzer2021 was cited due to the use of
179+
pybamm.models.full_battery_models.lithium_ion.dfn
180+
181+
"""
182+
if self._citation_tags:
183+
print("\n Citations registered: \n")
184+
for key, entry in self._citation_tags.items():
185+
print(f"{key} was cited due to the use of {entry}")
186+
187+
def print(self, filename=None, output_format="text", verbose=False):
188+
"""Print all citations that were used for running simulations. The verbose
189+
option is provided to print the citation tags for the citations that have
190+
been registered non-manually. This is available only upon printing
191+
to the terminal.
124192
125193
Parameters
126194
----------
127195
filename : str, optional
128-
Filename to which to print citations. If None, citations are printed to the
129-
terminal.
196+
Filename to which to print citations. If None, citations are printed
197+
to the terminal.
198+
verbose: bool, optional
199+
If True, prints the citation tags for the citations that have been
200+
registered
130201
"""
131202
if output_format == "text":
132203
citations = pybtex.format_from_strings(
@@ -142,12 +213,14 @@ def print(self, filename=None, output_format="text"):
142213

143214
if filename is None:
144215
print(citations)
216+
if verbose:
217+
self.tag_citations() # pragma: no cover
145218
else:
146219
with open(filename, "w") as f:
147220
f.write(citations)
148221

149222

150-
def print_citations(filename=None, output_format="text"):
223+
def print_citations(filename=None, output_format="text", verbose=False):
151224
"""See :meth:`Citations.print`"""
152225
if citations._citation_err_msg is not None:
153226
raise ImportError(
@@ -159,7 +232,13 @@ def print_citations(filename=None, output_format="text"):
159232
f"{citations._citation_err_msg}"
160233
)
161234
else:
162-
pybamm.citations.print(filename, output_format)
235+
if verbose: # pragma: no cover
236+
warnings.warn(
237+
"Verbose output is not available for printing to files, only to the terminal" # noqa: E501
238+
)
239+
pybamm.citations.print(filename, output_format, verbose=True)
240+
else:
241+
pybamm.citations.print(filename, output_format)
163242

164243

165244
citations = Citations()

0 commit comments

Comments
 (0)