Skip to content
Closed
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
Empty file added doc/source/check_duplicates.py
Empty file.
33 changes: 33 additions & 0 deletions doc/source/check_duplicates.py python check_duplicates.py
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't include the helper scripts.

This is clearly a one-off script. If we were to include it, people would think it's well tested.

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import os
import re

# Step 1: All .rst file paths collect karo
rst_files = []
for root, dirs, files in os.walk("."):
for file in files:
if file.endswith(".rst"):
rst_files.append(os.path.join(root, file))

# Step 2: label regex se labels dhundo
label_pattern = re.compile(r'^\s*\.\.\s+_([^:]+):')
labels = {}

for file_path in rst_files:
with open(file_path, 'r', encoding='utf-8') as f:
for i, line in enumerate(f, start=1):
match = label_pattern.match(line)
if match:
label = match.group(1)
labels.setdefault(label, []).append((file_path, i))

# ✅ Step 3: Duplicate check aur print
duplicates = {k: v for k, v in labels.items() if len(v) > 1}

if not duplicates:
print("✅ कोई duplicate label नहीं मिला — सब कुछ सही है!")
else:
for label, occurrences in duplicates.items():
print(f"Label: {label}")
for file, line_num in occurrences:
print(f" → {file} — Line {line_num}")
print()
4 changes: 2 additions & 2 deletions doc/source/examples/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,5 @@ each notebook on `Binder`_.
:alt: Binder
:target: https://mybinder.org/v2/gh/MDAnalysis/binder-env-userguide/main?urlpath=git-pull%3Frepo%3Dhttps%253A%252F%252Fgithub.com%252FMDAnalysis%252FUserGuide%26urlpath%3Dtree%252FUserGuide%252Fdoc%252Fsource%252Fexamples%26branch%3Dmaster

.. _Binder: https://mybinder.org/v2/gh/MDAnalysis/binder-env-userguide/main?urlpath=git-pull%3Frepo%3Dhttps%253A%252F%252Fgithub.com%252FMDAnalysis%252FUserGuide%26urlpath%3Dtree%252FUserGuide%252Fdoc%252Fsource%252Fexamples%26branch%3Dmaster
.. _GitHub: https://github.com/MDAnalysis/UserGuide/tree/develop/doc/source/examples
.. _Binder-ref: https://mybinder.org/v2/gh/MDAnalysis/binder-env-userguide/main?urlpath=git-pull%3Frepo%3Dhttps%253A%252F%252Fgithub.com%252FMDAnalysis%252FUserGuide%26urlpath%3Dtree%252FUserGuide%252Fdoc%252Fsource%252Fexamples%26branch%3Dmaster
.. _GitHub-ref: https://github.com/MDAnalysis/UserGuide/tree/develop/doc/source/examples
4 changes: 2 additions & 2 deletions doc/source/formats/reference/tpr.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.. -*- coding: utf-8 -*-
.. _TPR-format:
.. _TPR-format-ref:

====================================
TPR (GROMACS run topology files)
Expand Down Expand Up @@ -94,7 +94,7 @@ Bonded interactions available in Gromacs are described in the
`Gromacs manual`_. The following ones are used to build the topology (see
`Issue 463`_):

.. _Gromacs: http://www.gromacs.org
.. _Gromacs-ref: http://www.gromacs.org
.. _`Gromacs manual`: http://manual.gromacs.org/current/reference-manual/index.html
.. _TPR file: http://manual.gromacs.org/current/reference-manual/file-formats.html#tpr
.. _`Issue Tracker`: https://github.com/MDAnalysis/mdanalysis/issues
Expand Down
2 changes: 1 addition & 1 deletion doc/source/formats/selection_exporters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ Reading in selections
Currently, MDAnalysis doesn't support reading in atom selections. However, there are other tools that can read files from other programs, such as `GromacsWrapper`_.

.. _CHARMM: http://www.charmm.org
.. _Gromacs: http://www.gromacs.org
.. _Gromacs-ref: http://www.gromacs.org
.. _VMD: http://www.ks.uiuc.edu/Research/vmd/
.. _PyMol: http://www.pymol.org
.. _Jmol: http://wiki.jmol.org/
Expand Down
91 changes: 24 additions & 67 deletions doc/source/scripts/gen_topologyparser_attrs.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env python

"""
Generate three tables:
- connectivityattrs.txt: A table of supported formats for bonds, angles, dihedrals, impropers
Expand All @@ -7,26 +8,22 @@

This script imports the testsuite, which tests these.
"""

from collections import defaultdict
from typing import Any

import base
from base import TableWriter
from core import DESCRIPTIONS, NON_CORE_ATTRS
from MDAnalysis.topology.base import TopologyReaderBase
from MDAnalysis.topology.base import TopologyReaderBase
from MDAnalysisTests.topology.base import mandatory_attrs
from MDAnalysisTests.topology.test_crd import TestCRDParser
from MDAnalysisTests.topology.test_dlpoly import (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this rewritten?

TestDLPConfigParser,
TestDLPHistoryParser,
)
from MDAnalysisTests.topology.test_dms import TestDMSParser
from MDAnalysisTests.topology.test_dlpoly import TestDLPConfigParser, TestDLPHistoryParser
from MDAnalysisTests.topology.test_fhiaims import TestFHIAIMS
from MDAnalysisTests.topology.test_gms import GMSBase
from MDAnalysisTests.topology.test_gro import TestGROParser
from MDAnalysisTests.topology.test_gsd import TestGSDParser
from MDAnalysisTests.topology.test_hoomdxml import TestHoomdXMLParser
from MDAnalysisTests.topology.test_lammpsdata import LammpsBase, TestDumpParser
from MDAnalysisTests.topology.test_mmtf import TestMMTFParser
from MDAnalysisTests.topology.test_mol2 import TestMOL2Base
from MDAnalysisTests.topology.test_pdb import TestPDBParser
Expand All @@ -39,17 +36,16 @@
from MDAnalysisTests.topology.test_xpdb import TestXPDBParser
from MDAnalysisTests.topology.test_xyz import XYZBase

PARSER_TESTS = (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't rewrite code that you don't need to touch.

# Removed TestDumpParser (it does not exist)
PARSER_TESTS = [
TestCRDParser,
TestDLPHistoryParser,
TestDLPConfigParser,
TestDMSParser,
TestFHIAIMS,
GMSBase,
TestGROParser,
TestGSDParser,
TestHoomdXMLParser,
LammpsBase,
TestMMTFParser,
TestMOL2Base,
TestPDBParser,
Expand All @@ -61,16 +57,13 @@
TestTXYZParser,
TestXPDBParser,
XYZBase,
TestDumpParser,
)

]

def create_parser_attributes() -> dict[Any, tuple[set[str], set[str]]]:
parser_attrs = {}
for test_parser_class in PARSER_TESTS:
expected = set(test_parser_class.expected_attrs) - set(mandatory_attrs)
guessed = set(test_parser_class.guessed_attrs)
# clunky hack for PDB
if test_parser_class is TestPDBParser:
expected.add("elements")
parser_attrs[test_parser_class.parser] = (expected, guessed)
Expand All @@ -88,46 +81,27 @@ def _keys(parser: TopologyReaderBase) -> tuple[str, str]:
key = label = f
return (key, label)

def _description(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't rewrite code that you don't need to touch.

(applies to many more lines)

parser: TopologyReaderBase,
expected: set[str],
guessed: set[str],
key_label: tuple[str, str],
) -> str:
key, label = key_label
def _description(parser, expected, guessed, key_label):
key, _ = key_label
return DESCRIPTIONS[key]

def _format(
parser: TopologyReaderBase,
expected: set[str],
guessed: set[str],
key_label: tuple[str, str],
) -> str:
def _format(parser, expected, guessed, key_label):
key, label = key_label
return base.sphinx_ref(txt=label, label=key, suffix="-format")

def _attributes_read(
parser: TopologyReaderBase,
expected: set[str],
guessed: set[str],
key_label: tuple[str, str],
) -> str:
def _attributes_read(parser, expected, guessed, key_label):
vals = sorted(expected - guessed)
return ", ".join(vals)

def _attributes_guessed(
parser: TopologyReaderBase,
expected: set[str],
guessed: set[str],
key_label: tuple[str, str],
) -> str:
def _attributes_guessed(parser, expected, guessed, key_label):
return ", ".join(sorted(guessed))

parser_attrs = create_parser_attributes()
input_items = [
[parser, expected, guessed, _keys(parser=parser)]
for parser, (expected, guessed) in parser_attrs.items()
]

self.table_writer = TableWriter(
filename="formats/topology_parsers.txt",
include_table="Table of supported topology parsers and the attributes read",
Expand All @@ -147,37 +121,25 @@ def _attributes_guessed(
def get_format_attrs(topology_parsers: TopologyParsers) -> dict[str, set[str]]:
attrs = defaultdict(set)
writer = topology_parsers.table_writer
assert writer.input_items
for format, (_, expected, guessed, _) in zip(
writer.fields["Format"],
writer.input_items,
):
for format, (_, expected, guessed, _) in zip(writer.fields["Format"], writer.input_items):
for attribute in expected | guessed:
attrs[attribute].add(format)
return attrs


class TopologyAttrs:
def __init__(self, attrs: dict[str, set[str]]) -> None:
def _atom(name: str, singular: str, description: str) -> str:
return singular

def _atomgroup(name: str, singular: str, description: str) -> str:
return name

def _description(name: str, singular: str, description: str) -> str:
return description

def _supported_formats(
name: str, singular: str, description: str
) -> str:
return ", ".join(sorted(attrs[name]))
def _atom(name, singular, description): return singular
def _atomgroup(name, singular, description): return name
def _description(name, singular, description): return description
def _supported_formats(name, singular, description): return ", ".join(sorted(attrs[name]))

input_items = sorted(
[x, *y]
for x, y in NON_CORE_ATTRS.items()
if x not in set(mandatory_attrs)
)

self.table_writer = TableWriter(
filename="generated/topology/topologyattrs.txt",
lines=[],
Expand All @@ -194,14 +156,9 @@ def _supported_formats(

class ConnectivityAttrs:
def __init__(self, attrs: dict[str, set[str]]) -> None:
def _atom(name: str) -> str:
return name

def _atomgroup(name: str) -> str:
return name

def _supported_formats(name: str) -> str:
return ", ".join(sorted(attrs[name]))
def _atom(name): return name
def _atomgroup(name): return name
def _supported_formats(name): return ", ".join(sorted(attrs[name]))

input_items = [("bonds",), ("angles",), ("dihedrals",), ("impropers",)]

Expand All @@ -218,12 +175,12 @@ def _supported_formats(name: str) -> str:
self.table_writer.generate_lines_and_write_table()


def main() -> None:
def main():
top = TopologyParsers()
topology_attrs = get_format_attrs(top)
TopologyAttrs(topology_attrs)
ConnectivityAttrs(topology_attrs)


if __name__ == "__main__":
main()
main()