Write a human-friendly Markdown summary of per-fluid 3D molecule-viewer status to *out_path*. Buckets are populated by FluidGenerator.write() as it runs, so call this *after* the per-fluid generation loop. If *cache_dir* is given (the directory containing the SDF cache and ``m
(out_path, cache_dir=None)
| 373 | |
| 374 | |
| 375 | def write_geometry_status_report(out_path, cache_dir=None): |
| 376 | """ |
| 377 | Write a human-friendly Markdown summary of per-fluid 3D molecule-viewer |
| 378 | status to *out_path*. Buckets are populated by FluidGenerator.write() as |
| 379 | it runs, so call this *after* the per-fluid generation loop. |
| 380 | |
| 381 | If *cache_dir* is given (the directory containing the SDF cache and |
| 382 | ``manifest.json``), the report also includes a PubChem cache freshness |
| 383 | section. |
| 384 | """ |
| 385 | s = GEOMETRY_STATUS |
| 386 | total = sum(len(s[k]) for k in ('has_3d', 'has_2d_only', 'pubchem_missing', 'no_inchikey')) |
| 387 | lines = [ |
| 388 | '# Molecule geometry status', |
| 389 | '', |
| 390 | ('Generated by `Web/scripts/fluid_properties.PurePseudoPure.py` from ' |
| 391 | '`fetch_pubchem_sdf()` outcomes. Buckets are mutually exclusive and ' |
| 392 | 'cover every fluid in `CoolProp.__fluids__`.'), |
| 393 | '', |
| 394 | f'- **Total fluids:** {total}', |
| 395 | f'- **3D conformer:** {len(s["has_3d"])}', |
| 396 | f'- **2D fallback only:** {len(s["has_2d_only"])}', |
| 397 | f'- **No PubChem record:** {len(s["pubchem_missing"])}', |
| 398 | f'- **No valid InChIKey** (pseudo-pures, ortho/para variants): {len(s["no_inchikey"])}', |
| 399 | '', |
| 400 | '## 2D fallback only', |
| 401 | '', |
| 402 | 'PubChem returned a 2D structure but no 3D conformer.', |
| 403 | '', |
| 404 | ] |
| 405 | if s['has_2d_only']: |
| 406 | lines += [f'- {name}' for name in sorted(s['has_2d_only'])] |
| 407 | else: |
| 408 | lines.append('_(none)_') |
| 409 | lines += ['', '## No PubChem record', '', |
| 410 | 'PubChem returned 404 for both 3D and 2D requests.', ''] |
| 411 | if s['pubchem_missing']: |
| 412 | lines += [f'- {name} — `{key}`' for name, key in sorted(s['pubchem_missing'])] |
| 413 | else: |
| 414 | lines.append('_(none)_') |
| 415 | lines += ['', '## No valid InChIKey', '', |
| 416 | ('These fluids have `INCHIKEY = "N/A"` (or empty) and are skipped ' |
| 417 | 'before any PubChem lookup. Typical cases: pseudo-pure mixtures ' |
| 418 | '(R407C, R410A, SES36, …) and ortho/para hydrogen variants.'), |
| 419 | ''] |
| 420 | if s['no_inchikey']: |
| 421 | lines += [f'- {name}' for name in sorted(s['no_inchikey'])] |
| 422 | else: |
| 423 | lines.append('_(none)_') |
| 424 | lines += ['', '## 3D conformer (success)', ''] |
| 425 | if s['has_3d']: |
| 426 | lines += [f'- {name}' for name in sorted(s['has_3d'])] |
| 427 | else: |
| 428 | lines.append('_(none)_') |
| 429 | lines.append('') |
| 430 | |
| 431 | has_stale = False |
| 432 | if cache_dir is not None: |
no test coverage detected