Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions .github/scripts/json_to_nef.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/usr/bin/env python3
"""Convert specification/v1_2_under_review/namespaces.json to namespaces.nef."""

import json
import pynmrstar
from pathlib import Path

REPO_ROOT = Path(__file__).resolve().parents[2]
VERSION = (REPO_ROOT / "specification" / "current_version").read_text().strip()
JSON_PATH = REPO_ROOT / "specification" / VERSION / "namespaces.json"
NEF_PATH = REPO_ROOT / "specification" / VERSION / "namespaces.nef"


def main():
entries = json.loads(JSON_PATH.read_text(encoding="utf-8"))

entry = pynmrstar.Entry.from_scratch("nef_namespaces_registry")

sf = pynmrstar.Saveframe.from_scratch("nns_namespaces", tag_prefix="nns_namespaces")
sf.add_tag("sf_category", "nns_namespaces")
sf.add_tag("sf_framecode", "nns_namespaces")

loop = pynmrstar.Loop.from_scratch(category="nns_namespaces_namespace")
for col in ("id", "name", "description", "url", "dictionary_url"):
loop.add_tag(col)

for item in entries:
raw_url = item.get("url") or item.get("urls") or "."
url = (raw_url[0] if isinstance(raw_url, list) else raw_url) or "."
dict_url = item.get("dict_url") or "."
loop.add_data([
item.get("id", "."),
item.get("name", "."),
item.get("description", "."),
url,
dict_url,
])

sf.add_loop(loop)
entry.add_saveframe(sf)

NEF_PATH.write_text(str(entry), encoding="utf-8")
print(f"Written {len(entries)} namespaces to {NEF_PATH}")


if __name__ == "__main__":
main()
34 changes: 34 additions & 0 deletions .github/workflows/generate-namespaces-nef.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Generate namespaces.nef

on:
push:
paths:
- 'specification/*/namespaces.json'
- 'specification/current_version'
workflow_dispatch:

jobs:
generate:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Install pynmrstar
run: pip install pynmrstar

- name: Convert JSON to NEF
run: python .github/scripts/json_to_nef.py

- name: Commit if changed
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add specification/v1_2_under_review/namespaces.nef
git diff --staged --quiet || git commit -m "chore: regenerate namespaces.nef from namespaces.json"
git push
32 changes: 32 additions & 0 deletions .github/workflows/update-current-symlink.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Update current symlink

on:
push:
paths:
- 'specification/current_version'
workflow_dispatch:

jobs:
update-symlink:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4

- name: Update current symlink
run: |
VERSION=$(cat specification/current_version | tr -d '[:space:]')
if [ ! -d "specification/$VERSION" ]; then
echo "Error: specification/$VERSION does not exist"
exit 1
fi
cd specification
rm -f current
ln -s "$VERSION" current
cd ..
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add specification/current
git diff --staged --quiet || git commit -m "chore: update current symlink to $VERSION"
git push
177 changes: 177 additions & 0 deletions namespaces.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NEF Namespaces Registry</title>
<style>
/* Base Styles */
body {
font-family: system-ui, -apple-system, sans-serif;
padding: 2rem;
background: #f9fafb;
color: #1f2937;
max-width: 1200px;
margin: auto;
line-height: 1.5;
}

h1 { font-size: 1.75rem; margin-bottom: 0.5rem; color: #111827; }

.source-notice {
margin-bottom: 2rem; padding: 14px; background: #f3f4f6;
border-left: 4px solid #374151; color: #374151; font-size: 0.95rem;
}

.raw-data-link { font-weight: 700; color: #2563eb; text-decoration: underline; }

/* Table Styling - Uniform Font Size */
table {
width: 100%; border-collapse: collapse; background: white;
border-radius: 8px; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
table-layout: fixed;
font-size: 0.95rem; /* Unified base size for the whole table */
}

th, td {
padding: 14px 16px; text-align: left;
border-bottom: 1px solid #e5e7eb; vertical-align: top;
word-wrap: break-word;
}

th {
background: #f3f4f6;
font-size: 0.8rem;
text-transform: uppercase;
color: #6b7280;
font-weight: 600;
}

/* Standardizing Program Names and Codes */
code {
background: #e5e7eb;
padding: 3px 6px;
border-radius: 4px;
font-family: ui-monospace, monospace;
font-size: 0.9rem; /* Matches the table text size */
color: #1f2937;
}

strong { font-size: 0.95rem; color: #111827; }

/* Standardizing Links */
.link-container a {
display: block;
color: #2563eb;
text-decoration: none;
font-size: 0.9rem; /* Normalized with the table */
margin-bottom: 8px;
word-break: break-all;
line-height: 1.4;
}
.link-container a:hover { text-decoration: underline; }

/* Standardizing Comments (No Dotted Line) */
.comment-row td {
background-color: #fcfcfc;
padding: 8px 16px 20px 16px;
border-bottom: 2px solid #e5e7eb;
}

.comment-box {
font-style: italic;
font-size: 0.9rem; /* Consistent with the rest of the table */
color: #4b5563;
line-height: 1.5;
}

.error-msg { color: #dc2626; padding: 40px; text-align: center; font-weight: bold; }
</style>
</head>
<body>

<h1>NEF Namespace Registry</h1>

<div class="source-notice">
The raw data for this table can be found at:
<a id="data-link" href="#" class="raw-data-link" target="_blank"></a>.
To register your own namespace raise an issue at <a href="https://github.com/NMRExchangeFormat/NEF/issues" class="raw-data-link" target="_blank">this repository</a> requesting one.
</div>

<table id="registry-table">
<thead>
<tr>
<th style="width: 12%">Namespace</th>
<th style="width: 18%">Name</th>
<th style="width: 25%">Description</th>
<th style="width: 25%">Resources</th>
<th style="width: 20%">Dictionary</th>
</tr>
</thead>
<tbody id="table-body">
<tr><td colspan="5" style="text-align:center; padding: 40px;">Initializing registry...</td></tr>
</tbody>
</table>

<script>
async function loadRegistry() {
const tbody = document.getElementById('table-body');

try {
const version = await fetch('./specification/current_version')
.then(r => { if (!r.ok) throw new Error(`HTTP ${r.status}`); return r.text(); })
.then(t => t.trim());

const jsonPath = `./specification/${version}/namespaces.json`;
const dataLink = document.getElementById('data-link');
dataLink.href = jsonPath;
dataLink.textContent = jsonPath.replace('./', '');

const response = await fetch(jsonPath);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();

tbody.innerHTML = data.map(item => {
// First URL only
const raw = item.url || item.urls || '';
const url = Array.isArray(raw) ? raw[0] : raw;
const urlHtml = url
? `<a href="${url}" target="_blank" rel="noopener">${url}</a>`
: '—';

// Dictionary URL
const dictUrl = item.dict_url || '';
const dictHtml = dictUrl
? `<a href="${dictUrl}" target="_blank" rel="noopener">${dictUrl}</a>`
: '—';

// Comment row spanning all columns
const note = item.comment || item.comments || "";
const commentRow = note ? `
<tr class="comment-row">
<td colspan="5">
<div class="comment-box">${note}</div>
</td>
</tr>` : '';

return `
<tr>
<td><code>${item.id || ''}</code></td>
<td><strong>${item.name || ''}</strong></td>
<td>${item.description || ''}</td>
<td class="link-container">${urlHtml}</td>
<td class="link-container">${dictHtml}</td>
</tr>
${commentRow}
`;
}).join('');

} catch (err) {
tbody.innerHTML = `<tr><td colspan="5" class="error-msg">Error: ${err.message}</td></tr>`;
}
}

loadRegistry();
</script>
</body>
</html>
1 change: 1 addition & 0 deletions specification/current
1 change: 1 addition & 0 deletions specification/current_version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v1_1
21 changes: 21 additions & 0 deletions specification/v1_1/namespaces.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[
{ "id": "nef", "name": "NEF Standard", "description": "Data Exchange", "url": "https://github.com/NMRExchangeFormat/NEF",
"dict_url": "https://github.com/NMRExchangeFormat/NEF/blob/master/specification/v1_1/mmcif_nef_v1_1.dic"},
{ "id": "nefpls", "name": "NEF Pipelines", "description": "Format transcoding and NEF manipulation", "url": "https://github.com/varioustoxins/NEF-Pipelines" },

{ "id": "amber", "name": "Amber", "description": "Structure modelling and refinement", "url": "https://ambermd.org" },
{ "id": "aria", "name": "Aria", "description": "Structure calculation", "url": "https://aria.pasteur.fr" },
{ "id": "ccpn", "name": "CcpNmr Analysis", "description": "NMR spectra processing and data analysis", "url": "https://ccpn.ac.uk" },
{ "id": "csrosetta", "name": "CS-Rosetta", "description": "Structure calculation", "url": "https://web.archive.org/web/20240421045134/https://csrosetta.chemistry.ucsc.edu/",
"comment": "the original version by the Bax group is still available at https://spin.niddk.nih.gov/bax/software/CSROSETTA/, the archive on the wayback machine at \"https://web.archive.org/web/20240421045134/https://csrosetta.chemistry.ucsc.edu/most probably contains the most complete reference"
},
{ "id": "cyana", "name": "Cyana", "description": "Structure calculation", "url": "http://www.cyana.org" },
{ "id": "meld", "name": "MELD", "description": "Structure modelling and refinement", "url": "https://meldmd.org" },
{ "id": "NMRFx", "name": "NMRFx", "description": "Structure calculation", "url": "https://nmrfx.org" },
{ "id": "pdbstat", "name": "PDBStat", "description": "NMR data validation", "url": "https://github.rpi.edu/RPIBioinformatics/PDBStat_public" },
{ "id": "unio", "name": "Unio NMR", "description": "Structure calculation", "url": "https://unio-nmr.fr" },
{ "id": "unres", "name": "Unres", "description": "Structure modelling and refinement", "url": "http://www.unres.pl" },
{ "id": "pdbx", "name": "wwPDB/BMRB", "description": "Database", "url": "https://www.wwpdb.org" },
{ "id": "XplorNIH", "name": "Xplor-NIH", "description": "Structure calculation and refinement", "url": "https://nmr.cit.nih.gov/xplor-nih/" },
{ "id": "yasara", "name": "Yasara", "description": "Structure refinement", "url": "http://www.yasara.org" }
]
32 changes: 32 additions & 0 deletions specification/v1_1/namespaces.nef
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
data_nef_namespaces_registry

save_nns_namespaces
_nns_namespaces.sf_category nns_namespaces
_nns_namespaces.sf_framecode nns_namespaces

loop_
_nns_namespaces_namespace.id
_nns_namespaces_namespace.name
_nns_namespaces_namespace.description
_nns_namespaces_namespace.url
_nns_namespaces_namespace.dictionary_url

nef 'NEF Standard' 'Data Exchange' https://github.com/NMRExchangeFormat/NEF https://github.com/NMRExchangeFormat/NEF/blob/master/specification/v1_1/mmcif_nef_v1_1.dic
nefpls 'NEF Pipelines' 'Format transcoding and NEF manipulation' https://github.com/varioustoxins/NEF-Pipelines .
amber Amber 'Structure modelling and refinement' https://ambermd.org .
aria Aria 'Structure calculation' https://aria.pasteur.fr .
ccpn 'CcpNmr Analysis' 'NMR spectra processing and data analysis' https://ccpn.ac.uk .
csrosetta CS-Rosetta 'Structure calculation' https://web.archive.org/web/20240421045134/https://csrosetta.chemistry.ucsc.edu/ .
cyana Cyana 'Structure calculation' http://www.cyana.org .
meld MELD 'Structure modelling and refinement' https://meldmd.org .
NMRFx NMRFx 'Structure calculation' https://nmrfx.org .
pdbstat PDBStat 'NMR data validation' https://github.rpi.edu/RPIBioinformatics/PDBStat_public .
unio 'Unio NMR' 'Structure calculation' https://unio-nmr.fr .
unres Unres 'Structure modelling and refinement' http://www.unres.pl .
pdbx wwPDB/BMRB Database https://www.wwpdb.org .
XplorNIH Xplor-NIH 'Structure calculation and refinement' https://nmr.cit.nih.gov/xplor-nih/ .
yasara Yasara 'Structure refinement' http://www.yasara.org .

stop_

save_