Skip to content
This repository was archived by the owner on Feb 21, 2022. It is now read-only.
This repository was archived by the owner on Feb 21, 2022. It is now read-only.

Add citations tracker for elements #61

@wence-

Description

@wence-

Upstream in Firedrake we hook in to the PETSc citations mechanism so that someone can run a simulation and add the PETSc option -citations to show.

It would be nice if FIAT registered citations for all its elements (and possibly the fiat-related paper describing their implementation if required) so that people can know what to cite.

We don't want a hard PETSc dependency in FIAT, so how about something like this (see also some discussion in FInAT/FInAT#71), which a downstream consumer can hook up to PETSc (or otherwise just use).

class Citations(dict):
    """Entry point to citations management.

    This object may be used to record Bibtex citation
    information and then register that a particular citation is
    relevant for a particular computation.

    Example usage::

        from FIAT.citations import registry
    
        registry["key"] = "bibtex-entry-for-my-funky-method"

        ...

        if using_funky_method:
            registry.register("key")

        ...

        registry.bibtex(filename)
    """
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._registered = set()

    def __setitem__(self, key, entry):
        """Add a paper to the database of possible citations.

        :arg key: The key to use.
        :arg entry: The bibtex entry.
        """
        if key in self and entry != self[key]:
            raise ValueError("Adding duplicate key with different entry.")
        super().__setitem__(key, entry)

    def register(self, key):
        """Register that a paper has been used in this computation.

        :arg key: The key of the relevant citation.

        :raises KeyError: if no such citation is found in the database.

        Papers to be cited can be added using :meth:`add`.

        .. note::

           The intended use is that :meth:`register` should be called
           only when the referenced functionality is actually being
           used.
        """
        cite = self.get(key, None)
        if cite is None:
            raise KeyError(f"Did not find a citation for '{key}', did you forget to add it?")
        self._registered.add(key)

    def bibtex(self):
        """Produce bibtex of currently registered citations.

        :returns: String."""
        return "\n".join(self[key] for key in sorted(self._registered))
            

registry = Citations()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions