From 46504b93db4071d1cd3503c82811ac6136fe4373 Mon Sep 17 00:00:00 2001 From: Tristan Stevens Date: Fri, 16 Oct 2026 14:04:04 +0200 Subject: [PATCH] add citation section to website --- .github/workflows/pages.yml | 4 ++ CITATION.bib | 59 ++++++++++++++++++++++++++++ README.md | 6 +++ site/README.md | 8 ++++ site/build.py | 77 +++++++++++++++++++++++++++++++++++++ site/index.html | 27 ++++++++++++- 6 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 CITATION.bib diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 9cd5710..829d4e3 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -8,6 +8,8 @@ on: - "plots/open_h_rf_datasets.py" - "scripts/authors.csv" - "scripts/compile_authors.py" + - "CITATION.bib" + - "README.md" - ".github/workflows/pages.yml" pull_request: branches: [main] @@ -16,6 +18,8 @@ on: - "plots/open_h_rf_datasets.py" - "scripts/authors.csv" - "scripts/compile_authors.py" + - "CITATION.bib" + - "README.md" - ".github/workflows/pages.yml" workflow_dispatch: diff --git a/CITATION.bib b/CITATION.bib new file mode 100644 index 0000000..ceec7bd --- /dev/null +++ b/CITATION.bib @@ -0,0 +1,59 @@ +@misc{stevens2026openhrf, + title = {{Open-H-RF}: A Large-Scale Ultrasound Raw Channel Dataset Initiative}, + author = {T. S. W. Stevens and S. W. Penninga and W. L. van Nierop and O. Nolan and F. Duelmer and + B. N. Frey and B. Federici and V. van Hal and L. D. van Harten and H. de Hoop and + R. Lopata and B. Luijten and M. van Sambeek and V. van der Schaft and H.-M. Schwab and + M. F. Azampour and N. Navab and R. Ali and A. Andrzejek and J. Baek and B. Boitnott and + T. Brevett and H. Hashemi and D. Hyun and J. H. Park and A. V. Telichko and + C. Thomas and L. Zhuang and Y. Aklilu and H. Arora and J. Barker and A. K. Mackanic and + P. McDowall and L. McHugh and I. Pirozzi and S. Simon-Trench and A. M. Bronstein and + O. Senouf and S. Vedula and D. Zadok and H. Rivaz and M. Sharifzadeh and S. Chen and + G. P. Luke and S. Wang and Yujia Wu and J. Verde and R. G{\"o}bl and O. Zettinig and + E. Boctor and Yixuan Wu and H.-M. Bae and M.-G. Kim and Y.-M. Kim and H. Lee and + S.-H. Oh and P. Pinto and M. Berrada-Sounni and M. Carley and R. J. Fedewa and + S. Gavin and N. Goldsmith and R. Kassayan and C. Low and R. Mehranfar and + G. Bardoscia and M. Boccardo and A. Botter and M. Carbonaro and G. L. Cerone and + E. Cesti and K. Meiburger and S. Seoni and F. Truscello and B. J. Raiteri and + L. Caron and M. Gasse and N. Ghigo and O. Gulenko and A. Leconte and S. A. Lee and + A. Malescot and E. Martineau and J. Por{\'e}e and J. Provost and G. Ramos-Palacios and + B. Rauby and R. L. Rungta and A. F. Sadikot and A. Wu and P. Xing and A. Chavignon and + C. Ferlay and V. Hingot and M. Reberol and A. Waelbroeck and H.-S. Kwon and + J. Bucholz and I. Guracar and R. Loftman and C. Williams and T. Grutman and + T. Ilovitsh and T. A. Aleef and P. B. Chen and W. Chen and Y. Chen and M. Frew and + M. Honarvar and Y. C. Lee and Z. Li and H. Moradi and R. Rohling and S. E. Salcudean and + Z. Wu and Q. Zeng and P. C. Cattin and S. El Hadramy and N. Bottenus and A. S. Perez and + S. Feng and Y. Feng and P. Jin and Y. Lin and O. Ostras and G. Pinton and + F. Santibanez and M. Sode and B. Turkbey and H. Wang and B. J. Wood and L. Zhang and + S. Luo and J. Wiskin and A. Austeng and Y. Karabiyik and S. P. N{\"a}sholm and + O. M. H. Rindal and D. Bustamante and M. Mehrmohammadi and H. Raeis and A. Hameddine and + G. Lajoinie and H. de Roo and M. Versluis and R. Zorgdrager and J. S. Au and + A. J. Y. Chee and J. Cohen and T. Gu and J. Y.-H. Hsu and S. Ling and M. Mourtzakis and + H. Nahas and P. de la Torre and D. Xiao and A. C. H. Yu and E. Zafiris and + P. Jarosik and P. Karwat and Z. Klimonda and M. Lewandowski and B. Byram and C. Khan and + Z. Marshall and Y.-C. Pan and S. Liu and T. Sultan and C. Hoerig and J. Mamou and + D. Auerbach and Y. C. Eldar and A. Wegerhoff and G. S. Fischer and S. Katayose and + X. Ma and R. Murakami and Y. Tang and R. Tsumura and Y. Wang and H. K. Zhang and + M. Azizian and S. Huver and J. J. Dahl and R. J. G. van Sloun and W. Simson}, + year = {2026}, + eprint = {2610.13616}, + archivePrefix = {arXiv}, + primaryClass = {eess.SP}, + doi = {10.48550/arXiv.2610.13616}, + url = {https://arxiv.org/abs/2610.13616} +} + +@article{stevens2026zea, + title = {{zea}: A Toolbox for Cognitive Ultrasound Imaging}, + author = {Stevens, Tristan S. W. and van Nierop, Wessel L. and Luijten, Ben and + van de Schaft, Vincent and Nolan, Ois{\'i}n and Federici, Beatrice and + van Harten, Louis D. and Penninga, Simon W. and Schueler, Noortje I. P. and + van Sloun, Ruud J. G.}, + journal = {Journal of Open Source Software}, + publisher = {The Open Journal}, + year = {2026}, + volume = {11}, + number = {121}, + pages = {9881}, + doi = {10.21105/joss.09881}, + url = {https://doi.org/10.21105/joss.09881} +} diff --git a/README.md b/README.md index 7828758..5e752fe 100644 --- a/README.md +++ b/README.md @@ -170,8 +170,11 @@ Set the matching `KERAS_BACKEND` (`jax`, `torch`, or `tensorflow`) before runnin ## Citation + + If you use Open-H-RF in your research, please cite the [Open-H-RF paper](https://arxiv.org/abs/2610.13616): + ```bibtex @misc{stevens2026openhrf, title = {{Open-H-RF}: A Large-Scale Ultrasound Raw Channel Dataset Initiative}, @@ -217,9 +220,11 @@ If you use Open-H-RF in your research, please cite the [Open-H-RF paper](https:/ url = {https://arxiv.org/abs/2610.13616} } ``` + If you use [`zea`](https://github.com/tue-bmd/zea) to access or process the data, please also cite the [`zea` paper](https://doi.org/10.21105/joss.09881): + ```bibtex @article{stevens2026zea, title = {{zea}: A Toolbox for Cognitive Ultrasound Imaging}, @@ -237,6 +242,7 @@ If you use [`zea`](https://github.com/tue-bmd/zea) to access or process the data url = {https://doi.org/10.21105/joss.09881} } ``` + If you use a specific sub-dataset, please also check whether it has its own citation. Open the [dataset explorer](https://open-h.github.io/Open-H-RF/#explorer), click the dataset's card and see its Citation section. diff --git a/site/README.md b/site/README.md index 3a57c44..703787f 100644 --- a/site/README.md +++ b/site/README.md @@ -124,6 +124,14 @@ port 8000 (all interfaces). `--check` only validates `catalog.yaml`. details: the card's BibTeX, else an entry written from the citation it suggests. A `% dataset:` line names the dataset (or collection) the entries below it are for. The build warns about a card that asks to be cited and has no entry. +- `CITATION.bib` (at the repository root): the BibTeX for citing Open-H-RF and zea, the one + place to change it. The build writes each entry into the page where `index.html` has + ``, and fails unless the README's `` blocks match + it. After editing it, copy it into the README: + + ```bash + uv run python site/build.py --readme + ``` - `metadata_fixes.md`: where the site corrects the metadata on the Hub (probe names, probe types, transmit schemes, institutions), and the fix at the source for each. - `assets/img/examples*` (the banner: the paper's collages as webp, and the tile frames the diff --git a/site/build.py b/site/build.py index d824fd7..e7b67c6 100644 --- a/site/build.py +++ b/site/build.py @@ -20,12 +20,18 @@ institution, as ``site/institution_filters.csv`` names it. That file also lists the institutions datasets are from that are no author's affiliation. +The BibTeX for citing Open-H-RF and zea is ``CITATION.bib``, at the repository root. The +build writes each entry into the page where ``index.html`` has ````, +and fails unless the README has the same entries between its ```` and +```` lines; ``--readme`` copies them there. + ``update.py`` refreshes the ``site/hub/`` files and then runs this. The build itself needs only PyYAML, and no network. Usage (from the repository root):: uv run python site/build.py # build into site/_site uv run python site/build.py --serve # build, then serve on port 8000 uv run python site/build.py --check # only validate catalog.yaml + uv run python site/build.py --readme # copy CITATION.bib into README.md """ from __future__ import annotations @@ -56,6 +62,10 @@ AUTHOR_WEBSITES = SITE / "author_websites.csv" INSTITUTION_FILTERS = SITE / "institution_filters.csv" CITATIONS = SITE / "citation_suggestions.bib" +CITE = SITE.parent / "CITATION.bib" +README = SITE.parent / "README.md" +# Where index.html and the README take an entry of CITATION.bib. +BIBTEX_MARK = re.compile(r"") # Where index.html takes the author list. AUTHORS_MARK = "" @@ -264,6 +274,60 @@ def latex(text: str) -> str: return text +def cite_entries() -> dict[str, str]: + """The entries of CITATION.bib by key.""" + entries = re.split(r"^(?=@)", CITE.read_text(encoding="utf-8"), flags=re.M)[1:] + return {re.match(r"@\w+\{([^,]+),", e)[1]: e.strip() for e in entries} + + +def cite_html(page: str) -> str: + """The page with each ```` replaced by that entry, to copy.""" + entries = cite_entries() + + def block(m: re.Match) -> str: + if m[1] not in entries: + raise SystemExit(f"index.html asks for {m[1]!r}, which is not in {CITE.name}") + return ( + '
' + f"
{highlight_bibtex(entries[m[1]])}
" + ) + + return BIBTEX_MARK.sub(block, page) + + +# The entry type, the field names and the values, coloured as site.js colours its snippets. +BIBTEX_TOKENS = re.compile( + r"(?P^@\w+)|(?P\b\w+(?= = ))|(?P(?<= = )\{.*?\}(?=,?\n))", + re.M | re.S, +) + + +def highlight_bibtex(entry: str) -> str: + """A BibTeX entry as HTML, with the site's ``tok-`` classes on its tokens.""" + parts, end = [], 0 + for m in BIBTEX_TOKENS.finditer(entry + "\n"): + token = html.escape(m[0]) + parts += [ + html.escape(entry[end : m.start()]), + f'{token}', + ] + end = m.end() + return "".join(parts) + html.escape(entry[end:]) + + +def readme_with_citations() -> str: + """README.md with each ```` block set to that entry.""" + entries = cite_entries() + text = README.read_text(encoding="utf-8") + + def block(m: re.Match) -> str: + if m[2] not in entries: + raise SystemExit(f"{README.name} asks for {m[2]!r}, which is not in {CITE.name}") + return f"{m[1]}```bibtex\n{entries[m[2]]}\n```\n" + + return re.sub(r"(\n).*?", block, text, flags=re.S) + + def validate(catalog: dict) -> list[str]: """Problems with catalog.yaml: overrides outside the vocabulary, bad match patterns.""" problems = [] @@ -520,6 +584,11 @@ def build(out: Path) -> dict: raise SystemExit(f"index.html has no {AUTHORS_MARK} for the author list") institutions = {i for r in records for i in r["institutions"]} page = page.replace(AUTHORS_MARK, authors_html(institutions)) + page = cite_html(page) + if readme_with_citations() != README.read_text(encoding="utf-8"): + raise SystemExit( + f"{README.name} cites differently from {CITE.name}; run site/build.py --readme" + ) (out / "index.html").write_text(page, encoding="utf-8") shutil.copytree(SITE / "assets", out / "assets") shutil.copytree(HUB / "images", out / "images") @@ -584,6 +653,9 @@ def main() -> None: parser.add_argument("--out", type=Path, default=SITE / "_site", help="output directory") parser.add_argument("--check", action="store_true", help="validate catalog.yaml and exit") parser.add_argument("--serve", action="store_true", help="serve the build afterwards") + parser.add_argument( + "--readme", action="store_true", help="copy CITATION.bib into README.md and exit" + ) parser.add_argument("--port", type=int, default=8000) args = parser.parse_args() @@ -592,6 +664,11 @@ def main() -> None: print("\n".join(problems) or "catalog.yaml is valid") raise SystemExit(1 if problems else 0) + if args.readme: + README.write_text(readme_with_citations(), encoding="utf-8") + print(f"Copied {CITE.name} into {README.name}") + return + index = build(args.out.resolve()) print(f"Built {index['dataset_count']} datasets into {args.out}") if args.serve: diff --git a/site/index.html b/site/index.html index 64e2fbb..e983b37 100644 --- a/site/index.html +++ b/site/index.html @@ -334,13 +334,38 @@

Get the data

+
+

Citation

+
+

+ If you use Open-H-RF in your research, please cite the + Open-H-RF paper: +

+
+ +
+

+ If you use zea to access or + process the data, please also cite the + zea paper: +

+
+ +

+ If you use a specific dataset, please also check whether it has its own citation: open the + dataset explorer, click on a specific contribution and see its Citation section. +

+
+
+ +

Contributing institutions

    -
    +

    Steering committee