pdbe-mmcif-validator 0.1.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pdbe-mmcif-validator might be problematic. Click here for more details.

@@ -0,0 +1,400 @@
1
+ Metadata-Version: 2.4
2
+ Name: pdbe-mmcif-validator
3
+ Version: 0.1.6
4
+ Summary: Validate mmCIF/CIF files against the PDBx/mmCIF dictionary or any CIF dictionary
5
+ Author-email: Deborah Harrus <deborah@ebi.ac.uk>
6
+ Maintainer: Protein Data Bank in Europe (PDBe), EMBL-EBI
7
+ License: MIT
8
+ Project-URL: Homepage, https://github.com/PDBeurope/mmcif-validator
9
+ Project-URL: Documentation, https://github.com/PDBeurope/mmcif-validator/blob/main/vscode-extension/python-script/README.md
10
+ Project-URL: Repository, https://github.com/PDBeurope/mmcif-validator
11
+ Keywords: mmcif,cif,pdb,validation,pdbe,structural-biology
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.7
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Topic :: Scientific/Engineering :: Chemistry
24
+ Requires-Python: >=3.7
25
+ Description-Content-Type: text/markdown
26
+ Provides-Extra: dev
27
+
28
+ # PDBe mmCIF Validator - Python Script
29
+
30
+ **Version 0.1.6**
31
+
32
+ A standalone Python script to validate mmCIF/CIF files against the PDBx/mmCIF dictionary or any CIF dictionary.
33
+
34
+ ## Features
35
+
36
+ - ✅ Validates mmCIF/CIF files against any CIF dictionary schema
37
+ - ✅ Checks for missing mandatory items (only for categories present in file)
38
+ - ✅ Validates item values against enumerations
39
+ - ✅ **Data type validation** - Automatically validates types with regex patterns from dictionary (email, phone, orcid_id, pdb_id, fax, etc.) plus hardcoded validations for dates, integers, floats, booleans
40
+ - ✅ **Range validation** - Distinguishes between strictly allowed boundary conditions (errors) and advisory boundary conditions (warnings)
41
+ - ✅ **Parent/child category relationship validation** - Ensures parent categories exist when child categories are present
42
+ - ✅ **Foreign key integrity validation** - Ensures referenced data exists in parent items
43
+ - ✅ **Composite key validation** - Validates that combinations of multiple child items together match corresponding combinations in parent categories
44
+ - ✅ **Operation expression validation** - Parses and validates complex operation expressions like `(1-60)`, `(1,2,5)`, `(X0)(1-5,11-15)`
45
+ - ✅ **Duplicate category and item detection** - Reports when a category or item is duplicated (in loop or frame format)
46
+ - ✅ Supports local dictionary files or downloading from URL (works with PDBx/mmCIF dictionary or any CIF dictionary format)
47
+ - ✅ **Enhanced JSON output** - Includes precise character positions and column indices for programmatic error handling
48
+ - ✅ **Exit codes** - Returns 0 for success, 1 for errors (useful for CI/CD integration)
49
+
50
+ ## Installation
51
+
52
+ ### Prerequisites
53
+
54
+ - Python 3.7 or higher (uses only Python standard library, no pip packages required)
55
+ - Internet connection (optional) - Only needed if downloading dictionary from URL. Can use local dictionary file for offline use.
56
+ - CIF dictionary file (optional) - Defaults to PDBx/mmCIF dictionary from URL, but can use any CIF dictionary format
57
+
58
+ ## Usage
59
+
60
+ ### Basic Usage
61
+
62
+ ```bash
63
+ # Dictionary source can be a file path or URL (auto-detected)
64
+ # Works with PDBx/mmCIF dictionary or any CIF dictionary format
65
+ python validate_mmcif.py <dictionary.dic or URL> <mmcif_file.cif>
66
+ ```
67
+
68
+ ### Using Local Dictionary File
69
+
70
+ ```bash
71
+ # Use PDBx/mmCIF dictionary
72
+ python validate_mmcif.py mmcif_pdbx_v5_next.dic 6qvt.cif
73
+
74
+ # Or use any CIF dictionary file
75
+ python validate_mmcif.py path/to/your/cif_dictionary.dic your_file.cif
76
+ ```
77
+
78
+ ### Using Dictionary from URL
79
+
80
+ ```bash
81
+ # Using --url option (explicit) - defaults to PDBx/mmCIF dictionary
82
+ python validate_mmcif.py --url http://mmcif.pdb.org/dictionaries/ascii/mmcif_pdbx.dic 6qvt.cif
83
+
84
+ # Or use any CIF dictionary URL
85
+ python validate_mmcif.py --url https://example.com/path/to/your/dictionary.dic 6qvt.cif
86
+
87
+ # Or as positional argument (auto-detects URL)
88
+ python validate_mmcif.py http://mmcif.pdb.org/dictionaries/ascii/mmcif_pdbx.dic 6qvt.cif
89
+ ```
90
+
91
+ ### Explicit Options
92
+
93
+ ```bash
94
+ # Use local file
95
+ python validate_mmcif.py --file mmcif_pdbx_v5_next.dic 6qvt.cif
96
+
97
+ # Use URL
98
+ python validate_mmcif.py --url http://mmcif.pdb.org/dictionaries/ascii/mmcif_pdbx.dic 6qvt.cif
99
+ ```
100
+
101
+ ### Help
102
+
103
+ ```bash
104
+ python validate_mmcif.py --help
105
+ ```
106
+
107
+ ## Library usage
108
+
109
+ You can use the validator as a Python library (e.g. in prerelease pipelines or other tools) by importing and calling the same logic the CLI uses. The library raises exceptions instead of exiting, so callers can handle errors.
110
+
111
+ ### Install
112
+
113
+ From the project (e.g. after cloning or from a wheel):
114
+
115
+ ```bash
116
+ pip install -e /path/to/mmcif-validator/vscode-extension/python-script
117
+ # or from that directory:
118
+ pip install -e .
119
+ ```
120
+
121
+ Or install from PyPI (when published):
122
+
123
+ ```bash
124
+ pip install pdbe-mmcif-validator
125
+ ```
126
+
127
+ When installed via pip, a `validate-mmcif` console script is also available:
128
+
129
+ ```bash
130
+ validate-mmcif --file mmcif_pdbx_v5_next.dic file.cif
131
+ validate-mmcif --help
132
+ ```
133
+
134
+ ### Basic usage
135
+
136
+ ```python
137
+ from pathlib import Path
138
+ from validate_mmcif import validate, ValidatorFactory, ValidationError
139
+ from validate_mmcif import DictionaryNotFoundError, CifNotFoundError, DownloadError
140
+
141
+ # Option 1: top-level function (recommended)
142
+ try:
143
+ errors = validate(Path("mmcif_pdbx_v5_next.dic"), Path("file.cif"))
144
+ for err in errors:
145
+ print(err.line, err.item, err.message, err.severity)
146
+ if not errors:
147
+ print("Validation passed.")
148
+ except DictionaryNotFoundError as e:
149
+ print("Dictionary not found:", e)
150
+ except CifNotFoundError as e:
151
+ print("mmCIF file not found:", e)
152
+ except DownloadError as e:
153
+ print("Download failed:", e)
154
+
155
+ # Option 2: factory (same behaviour)
156
+ errors = ValidatorFactory.validate(Path("dict.dic"), Path("file.cif"))
157
+ ```
158
+
159
+ ### Using a dictionary from a URL
160
+
161
+ Download the dictionary first, then validate:
162
+
163
+ ```python
164
+ from pathlib import Path
165
+ from validate_mmcif import validate, download_dictionary, DownloadError
166
+
167
+ try:
168
+ dict_path = download_dictionary("http://mmcif.pdb.org/dictionaries/ascii/mmcif_pdbx.dic")
169
+ errors = validate(dict_path, Path("file.cif"))
170
+ # ... use errors ...
171
+ finally:
172
+ if dict_path.exists():
173
+ dict_path.unlink() # clean up temp file
174
+ except DownloadError as e:
175
+ print("Download failed:", e)
176
+ ```
177
+
178
+ ### Integrating with your logging
179
+
180
+ The module uses the standard `logging` logger `validate_mmcif`. Configure logging so library messages go to your logs:
181
+
182
+ ```python
183
+ import logging
184
+ logging.basicConfig(level=logging.DEBUG)
185
+ # or attach to your app's logger:
186
+ logging.getLogger("validate_mmcif").setLevel(logging.INFO)
187
+ ```
188
+
189
+ ### Exceptions
190
+
191
+ | Exception | When it is raised |
192
+ |-----------|-------------------|
193
+ | `DictionaryNotFoundError` | The dictionary path does not exist. |
194
+ | `CifNotFoundError` | The mmCIF file path does not exist. |
195
+ | `DownloadError` | Downloading the dictionary from a URL failed. |
196
+
197
+ All of these inherit from `MmCIFValidatorError`, so you can catch that for any validator error.
198
+
199
+ ### Return value
200
+
201
+ `validate()` and `ValidatorFactory.validate()` return a list of `ValidationError` dataclass instances with:
202
+
203
+ - `line`, `item`, `message`, `severity` (`"error"` or `"warning"`)
204
+ - `column`, `start_char`, `end_char` (optional, for positioning)
205
+
206
+ ## Output
207
+
208
+ The script outputs:
209
+ - Validation errors and warnings with line numbers
210
+ - JSON output for programmatic use
211
+ - Exit code 0 for success, 1 for errors
212
+
213
+ Example output:
214
+ ```
215
+ Parsing dictionary: mmcif_pdbx.dic
216
+ Loaded 6652 items from dictionary
217
+ Parsing mmCIF file: model.cif
218
+ Found 1124 items in mmCIF file
219
+ Validating...
220
+
221
+ Found 4 validation issue(s):
222
+
223
+ ERROR: Line 36, Item '_pdbx_database_status.recvd_initial_deposition_date'
224
+ Value '20250601' does not match expected type 'yyyy-mm-dd'
225
+
226
+ ERROR: Line 1643, Item '_pdbx_struct_assembly_gen.oper_expression'
227
+ Operation expression '1' references operation ID '1' which does not exist in '_pdbx_struct_oper_list.id'
228
+
229
+ WARNING: Line 1011, Item '_refine.ls_R_factor_obs'
230
+ Out of advisory range: Value '0.350' is above advisory maximum '0.300'
231
+
232
+ ERROR: Line 1020, Item '_refine.ls_R_factor_obs'
233
+ Value '1.250' is above maximum allowed value '1.000'
234
+ ```
235
+
236
+ ### JSON Output Format
237
+
238
+ The script outputs JSON at the end with the following structure:
239
+
240
+ ```json
241
+ {
242
+ "errors": [
243
+ {
244
+ "line": 1238,
245
+ "item": "_refine_ls_shell.number_reflns_R_free",
246
+ "message": "Out of advisory range: Value '0' is below minimum advised value '1'",
247
+ "severity": "warning",
248
+ "column": 5,
249
+ "start_char": 43,
250
+ "end_char": 44
251
+ }
252
+ ]
253
+ }
254
+ ```
255
+
256
+ **Fields:**
257
+ - `line`: Line number (1-based) where the error occurs
258
+ - `item`: The item name (e.g., `_refine_ls_shell.number_reflns_R_free`)
259
+ - `message`: Human-readable error message
260
+ - `severity`: Either `"error"` or `"warning"`
261
+ - `column`: Global column index (0-based) within the row (for loop data) or `null` for non-loop items
262
+ - `start_char`: Character start position (0-based) within the line for precise highlighting, or `null` if not available
263
+ - `end_char`: Character end position (0-based) within the line for precise highlighting, or `null` if not available
264
+
265
+ The `start_char` and `end_char` fields enable precise highlighting of the exact problematic value, even when the same value appears multiple times on a line.
266
+
267
+ ## Validation Checks
268
+
269
+ The validator performs the following checks:
270
+
271
+ 1. **Item Definition**: Verifies that items used in the mmCIF file are defined in the dictionary
272
+ 2. **Mandatory Items**: Checks that all mandatory items are present (only for categories that exist in the file)
273
+ 3. **Enumeration Values**: Validates that item values match allowed enumerations (reported as errors)
274
+ - Handles enumerations with only `_item_enumeration.value` (no detail field)
275
+ - Handles enumerations with both `value` and `detail` fields
276
+ 4. **Data Type Validation**: Validates that values match their expected data types:
277
+ - **Regex patterns from dictionary** - Automatically validates any type code that has a regex pattern defined in `_item_type_list.construct` (e.g., `email`, `phone`, `orcid_id`, `pdb_id`, `fax`, etc.)
278
+ - **Hardcoded validations** for common types:
279
+ - Date formats: `yyyy-mm-dd`, `yyyy-mm-dd:hh:mm`, `yyyy-mm-dd:hh:mm-flex`
280
+ - Numeric types: `int`, `positive_int`, `float`, `float-range`
281
+ - Boolean type: `boolean`
282
+ 5. **Range Validation**: Checks that numeric values fall within specified minimum/maximum ranges
283
+ - **Strictly Allowed Boundary Conditions** (`_item_range`): Violations are reported as **errors**
284
+ - **Advisory Boundary Conditions** (`_pdbx_item_range`): Violations are reported as **warnings** with "Out of advisory range:" prefix
285
+ 6. **Parent/Child Category Validation**:
286
+ - Verifies that when a child category is present, its parent category is also present
287
+ - Example: If `entity_src_nat` (child) is present, `entity` (parent) must also be present
288
+ 7. **Foreign Key Integrity**: Validates that foreign key values in child items exist in their parent items
289
+ - Example: `_entity_src_nat.entity_id` values must exist in `_entity.id`
290
+ 8. **Composite Key Validation**: Validates that combinations of multiple child items together match corresponding combinations in parent categories
291
+ - Example: In `pdbx_entity_poly_domain`, the combination of `begin_mon_id` + `begin_seq_num` must match a row in `entity_poly_seq` where `mon_id` + `num` appear together as a pair
292
+ - Validates relationships where multiple items form a composite foreign key (identified by `link_group_id` in the dictionary)
293
+ - **Special handling for label/auth field combinations**: Categories like `struct_conn`, `pdbx_struct_conn_angle`, `geom_*`, `atom_site_anisotrop`, and others have composite keys that include both label and auth fields. The validator intelligently handles these by:
294
+ - First attempting validation using label fields (if complete)
295
+ - Falling back to auth fields when label fields are incomplete (e.g., when `label_seq_id` is missing)
296
+ - Using `label_atom_id` when `auth_atom_id` is not present in the file
297
+ - This ensures atoms referenced in these categories are properly validated against `atom_site` even when some fields are missing
298
+ 9. **Operation Expression Validation**: Validates `oper_expression` values that reference operation IDs
299
+ - Parses complex operation expressions: `(1)`, `(1,2,5)`, `(1-4)`, `(1,2)(3,4)`, `(X0)(1-5,11-15)`
300
+ - Validates that all referenced operation IDs exist in `_pdbx_struct_oper_list.id`
301
+ - Example: If `oper_expression` is `(1-60)`, validates that operation IDs 1 through 60 all exist
302
+ 10. **Category-aware validation**: Only checks mandatory items for categories that are actually present in the mmCIF file
303
+ 11. **First data block only**: By default, only validates the first data block in files containing multiple data blocks (each starting with `data_`)
304
+
305
+ ## Error vs Warning Severity
306
+
307
+ The validator reports issues with different severity levels:
308
+
309
+ ### Errors (Red Underline)
310
+ These are violations of mandatory constraints that must be fixed:
311
+
312
+ - **Missing Mandatory Items**: Required items that are missing from categories present in the file
313
+ - **Enumeration Violations**: Values that don't match the controlled vocabulary/enumeration list
314
+ - **Data Type Mismatches**: Values that don't match their expected data type (e.g., invalid date format, non-numeric value for integer type)
315
+ - **Strictly Allowed Range Violations** (`_item_range`): Values outside the strictly allowed boundary conditions
316
+ - **Parent Category Missing**: Child categories present but their required parent categories are missing
317
+ - **Foreign Key Integrity Violations**: Foreign key values that don't exist in their parent items
318
+ - **Composite Key Violations**: Combinations of multiple child items that don't match corresponding combinations in parent categories (including label/auth field combinations)
319
+ - **Invalid Operation Expression References**: Operation expressions referencing operation IDs that don't exist
320
+
321
+ ### Warnings (Yellow Underline)
322
+ These are advisory issues that may indicate problems but are not strictly required:
323
+
324
+ - **Undefined Items**: Items used in the mmCIF file that are not defined in the dictionary (only for items not starting with `_`)
325
+ - **Advisory Range Violations** (`_pdbx_item_range`): Values outside the advisory boundary conditions (but within allowed range)
326
+
327
+ ## Command-Line Options
328
+
329
+ - `--file, -f`: Path to local dictionary file (.dic)
330
+ - `--url, -u`: URL to download dictionary from
331
+ - Positional arguments: Dictionary source (auto-detects file path or URL) and mmCIF file
332
+
333
+ ## Examples
334
+
335
+ ```bash
336
+ # Validate with local dictionary
337
+ python validate_mmcif.py mmcif_pdbx_v5_next.dic 6qvt.cif
338
+
339
+ # Validate with online dictionary
340
+ python validate_mmcif.py --url http://mmcif.pdb.org/dictionaries/ascii/mmcif_pdbx.dic 6qvt.cif
341
+
342
+ # Output to file
343
+ python validate_mmcif.py mmcif_pdbx_v5_next.dic 6qvt.cif > validation_results.txt
344
+ ```
345
+
346
+ ## Troubleshooting
347
+
348
+ ### Dictionary file not found
349
+ - Check that the file path is correct
350
+ - Use absolute paths if relative paths don't work
351
+ - Or use the `--url` option to download from the internet
352
+
353
+ ### Validation script errors
354
+ - Ensure Python 3.7+ is installed: `python --version`
355
+ - Check file paths are correct
356
+ - Verify dictionary file format is correct
357
+ - For large files, validation may take time. When using the VSCode extension, the validation timeout is configurable in settings (default 60 seconds, max 600); increase `mmcifValidator.validationTimeoutSeconds` if you see "Validation timed out".
358
+
359
+ ### Python not found
360
+ - Make sure Python is in your PATH
361
+ - Or use the full path to your Python executable, e.g. `python3 validate_mmcif.py ...` or on Windows `C:\Python39\python.exe validate_mmcif.py ...`
362
+
363
+ ## Limitations
364
+
365
+ - Dictionary parsing is simplified and may not handle all dictionary features
366
+ - Large dictionary files may take time to parse
367
+ - Some advanced validation rules may not be implemented yet
368
+ - **Note**: Some "missing mandatory item" errors may be false positives. In the mmCIF dictionary, items are often mandatory only when their parent category is present. The current implementation checks mandatory items only for categories that exist in the file, which should reduce false positives.
369
+ - **Note**: Some foreign key validation errors may be false positives if relationships are optional or conditional. The validator checks all defined parent/child relationships from `_pdbx_item_linked_group_list`.
370
+ - **Note**: For categories with both label and auth fields (like `struct_conn`), the validator will attempt to validate using label fields first, then fall back to auth fields if label fields are incomplete. This ensures proper validation even when some fields are missing (e.g., when `label_seq_id` is "." for non-polymer entities).
371
+ - Data type validation uses regex patterns from the dictionary when available. Types like `email`, `phone`, `orcid_id`, `pdb_id`, etc. are automatically validated if they have regex patterns defined in `_item_type_list.construct`. Types without regex patterns fall back to hardcoded validation (dates, int, positive_int, float, float-range, boolean) or are accepted without format validation.
372
+
373
+ ## Implemented Features
374
+
375
+ The validator currently implements comprehensive validation including:
376
+
377
+ - [x] **Data type validation** - Validates int, float, date, etc., plus automatic validation of any type with regex pattern in dictionary (email, phone, orcid_id, pdb_id, fax, etc.)
378
+ - [x] **Range validation** - Checks min/max values from dictionary constraints
379
+ - [x] **Parent/child category validation** - Validates category hierarchies
380
+ - [x] **Foreign key integrity validation** - Ensures referenced data exists
381
+ - [x] **Composite key validation** - Validates that combinations of multiple child items match corresponding combinations in parent categories
382
+ - [x] **Label/auth field composite key handling** - Special validation for categories with both label and auth fields (struct_conn, geom_*, etc.) that intelligently falls back between label and auth fields when some values are missing
383
+ - [x] **Operation expression validation** - Parses and validates complex `oper_expression` values
384
+ - [x] **Regular expression validation** - Automatically extracts and uses regex patterns from dictionary for type validation
385
+ - [x] **Conditional relationship validation** - Entity type-based validation for polymer/non-polymer relationships
386
+ - [x] **Loop structure parsing** - Parses and validates loop structures in mmCIF files
387
+ - [x] **Category key extraction** - Extracts and uses category keys from dictionary definitions
388
+
389
+ ## License
390
+
391
+ MIT
392
+
393
+ ## Author
394
+
395
+ Deborah Harrus, Protein Data Bank in Europe (PDBe), EMBL-EBI
396
+
397
+ ## Related
398
+
399
+ This script is part of the [PDBe mmCIF Validator](https://github.com/PDBeurope/mmcif-validator) project, which also includes a Visual Studio Code extension for real-time validation.
400
+