Skip to content

Commit e1f002b

Browse files
authored
Merge pull request #55 from LinkedEarth/pangaea-publications
Improve PANGAEA Publication Extraction Logic
2 parents 4b0254b + 27f2951 commit e1f002b

4 files changed

Lines changed: 301 additions & 89 deletions

File tree

‎pyleotups/core/PangaeaDataset.py‎

Lines changed: 107 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -540,21 +540,118 @@ def get_publications(
540540
verbose: bool = False,
541541
):
542542
"""
543-
Retrieve publication information in BibTeX and DataFrame format.
543+
Retrieve publication information for all registered PANGAEA studies.
544+
545+
This method aggregates publication metadata across all studies currently
546+
registered in the dataset. It returns both a structured pandas DataFrame
547+
and a BibTeX-compatible ``pybtex.database.BibliographyData`` object.
548+
549+
Publication extraction is performed at the study level via the internal
550+
``PangaeaStudy._extract_publications()`` method, and results are combined
551+
across studies.
552+
553+
Publication Sources
554+
-------------------
555+
Publications are collected from three metadata sources within each
556+
``PanDataSet`` object:
557+
558+
1. **Dataset Citation (Primary Source)**
559+
- Extracted directly from ``PanDataSet.citation``.
560+
- No external API calls are made for this source.
561+
- The citation string is treated as authoritative dataset metadata.
562+
- Parsed minimally into:
563+
- ``Title`` → full citation string
564+
- ``Year`` → extracted using regex
565+
- Other structured fields (authors, journal, etc.) may be unavailable.
566+
- Assigned:
567+
``Type = "citation"``
568+
569+
2. **Supplementary Publications**
570+
- Extracted from ``PanDataSet.supplement_to["uri"]``.
571+
- Represents the publication to which the dataset is a supplement.
572+
- If the URI contains a valid DOI, metadata is fetched via Crossref.
573+
- Assigned:
574+
``Type = "supplement to"``
575+
576+
3. **Related Publications**
577+
- Extracted from ``PanDataSet.relations``.
578+
- Each relation is expected to have:
579+
``{"id", "title", "uri", "type"}``
580+
- Only relations with DOI-containing URIs are processed.
581+
- Metadata is fetched via Crossref.
582+
- Assigned:
583+
``Type = relation["type"]``
584+
585+
Crossref Integration
586+
--------------------
587+
For supplement and relation publications, metadata is retrieved using
588+
``doi2bib.crossref.get_bib()`` and parsed via ``bibtexparser``.
589+
590+
The helper method ``_fetch_publication_from_doi()``:
591+
- Normalizes DOI strings
592+
- Retrieves BibTeX from Crossref
593+
- Parses BibTeX into structured fields
594+
- Converts entries into:
595+
- Row dictionaries for DataFrame output
596+
- ``pybtex.database.Entry`` objects for BibTeX export
597+
598+
Dataset citations are intentionally excluded from Crossref resolution
599+
to avoid inconsistencies and API failures.
600+
601+
Deduplication
602+
-------------
603+
Duplicate DOIs across citation, supplement, and relations are removed
604+
within each study using a DOI-based uniqueness check.
605+
606+
Returns
607+
-------
608+
tuple
609+
A tuple containing:
610+
611+
- ``BibliographyData`` :
612+
A pybtex bibliography object containing all publication entries,
613+
suitable for BibTeX export.
614+
615+
- ``pandas.DataFrame`` :
616+
Tabular representation of publications with columns:
617+
618+
- ``Author`` : str or None
619+
- ``Title`` : str
620+
- ``Journal`` : str or None
621+
- ``Year`` : str or None
622+
- ``Volume`` : str or None
623+
- ``Number`` : str or None
624+
- ``Pages`` : str or None
625+
- ``Type`` : str
626+
One of {"citation", "supplement to", relation type}
627+
- ``DOI`` : str or None
628+
- ``URL`` : str or None
544629
545630
Parameters
546631
----------
547-
save : bool, default=False
548-
If True, save BibTeX file.
632+
save : bool, optional, default=False
633+
If True, saves the BibTeX output to disk.
634+
549635
path : str or None, optional
550-
Output path.
551-
verbose : bool, default=False
552-
Print BibTeX content.
636+
Output file path or directory. If a directory is provided, a timestamped
637+
filename is generated.
553638
554-
Returns
555-
-------
556-
tuple
557-
(BibliographyData, pandas.DataFrame)
639+
verbose : bool, optional, default=False
640+
If True, prints the BibTeX content to stdout.
641+
642+
Notes
643+
-----
644+
- The dataset citation is always included, even if supplement or relation
645+
publications are present.
646+
- Crossref lookups are only performed for supplement and relation DOIs.
647+
- Some fields may be missing depending on metadata availability.
648+
- BibTeX entry keys are auto-generated and guaranteed to be unique
649+
within the returned bibliography.
650+
651+
See Also
652+
--------
653+
PangaeaStudy._extract_publications : Study-level publication extraction logic
654+
_fetch_publication_from_doi : DOI-based metadata retrieval helper
558655
"""
559656
all_rows = []
560657
all_entries = {}

‎pyleotups/tests/test_PangaeaDataset.py‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,14 +243,27 @@ def test_get_funding(self, mock_panquery, mock_requests):
243243
assert isinstance(df_funding, pd.DataFrame)
244244

245245

246+
@patch("doi2bib.crossref.get_bib")
246247
@patch("pangaeapy.pandataset.requests.get", side_effect=mock_requests_get)
247248
@patch("pyleotups.core.PangaeaDataset.PanQuery")
248-
def test_get_publications(self, mock_panquery, mock_requests):
249+
def test_get_publications(self, mock_panquery, mock_requests, mock_crossref):
249250

250251
mock_panquery.return_value.result = [
251252
{"URI": "10.1594/PANGAEA.830586"}
252253
]
253254

255+
mock_crossref.return_value = (
256+
200,
257+
"""
258+
@article{test,
259+
author = {Smith, John},
260+
title = {Test Paper},
261+
journal = {Nature},
262+
year = {2020}
263+
}
264+
"""
265+
)
266+
254267
ds = PangaeaDataset()
255268
ds.search_studies(search_text="test")
256269

0 commit comments

Comments
 (0)