Skip to content

chore: release v1.4.0 - #157

Merged
galjos merged 7 commits into
mainfrom
dev
Jul 22, 2026
Merged

chore: release v1.4.0#157
galjos merged 7 commits into
mainfrom
dev

Conversation

@galjos

@galjos galjos commented Jul 22, 2026

Copy link
Copy Markdown
Member

Summary

  • release PQAnalysis v1.4.0
  • add optimizer, vibrational, MSD, VACF, spectrum, and momentum analysis APIs
  • include RDF, QMCFC continuation, documentation, and release workflow fixes

Release

Tag v1.4.0 after this PR merges and all checks pass.

galjos added 6 commits July 7, 2026 09:49
- remove unsupported `display_version` sphinx_rtd_theme option
- set html_baseurl so sphinx-sitemap can build sitemap.xml
- include inputFile in a hidden user guide toctree
- drop obsolete code/modules.rst (not regenerated under better-apidoc --no-toc)
- fix malformed bullet lists in AtomicSystem and Selection docstrings
* feat: add vibrational analysis workflow

* test: cover vibrational analysis workflow

* test: compare vibrations against ASE

* style: format ASE vibration test
…cy C) (#153)

* feat: add msd, vacf, spectrum and momentum analyses

Port the remaining thh_tools analyses into PQAnalysis:

- analysis/msd: multiple-time-origin mean square displacement with
  periodic-image unwrapping (triclinic-capable) and an Einstein-relation
  self-diffusion fit; `msd` CLI. Matches the legacy Diffcalc estimator
  (parity <= 2e-7 against the recompiled binary).
- analysis/vacf: sliding-time-origin velocity autocorrelation with an
  optional charge-flux mode (static charges or a charge trajectory) and
  a windowed cosine-transform power spectrum in cm^-1 reproducing the
  legacy freqcalc/fluxfreqcalc/ft pipeline (parity <= 3e-6); optional
  fft-based estimator; `vacf` CLI.
- analysis/spectrum_broadening: Gaussian (optionally Lorentzian)
  line broadening of stick spectra; `build_spectrum` CLI (byte-level
  parity with the legacy gawk implementation).
- analysis/momentum: per-frame total linear momentum norm as a
  center-of-mass drift diagnostic; `check_momentum` CLI. The single
  precision parsing noise floor is documented.

All modules follow the rdf/vibrational conventions (input file readers
with documented keys, BaseWriter outputs, logging, runtime type
checking) and are registered in the pqanalysis main CLI, the console
script entry points and the user guide. Legacy-generated reference
data is checked in under tests/data; pytest-benchmark suites live in
benchmarks/analysis.

* perf: outperform legacy C analysis tools

Make the trajectory-bound analyses faster than the recompiled -O2
legacy binaries end to end, with bit-identical outputs:

- add RawTrajectoryReader: a streaming fast path yielding raw
  coordinate arrays and cached Cell objects without per-frame
  AtomicSystem construction, plus a single-pass block-scan frame
  counter (replaces two readlines passes)
- add Cython kernels for the msd and vacf sliding-origin accumulation
  (with identical-signature numpy fallbacks following the
  process_lines pattern), including a lockstep charge trajectory
  parser for the flux mode
- import scipy lazily (analysis import time 0.70 s -> 0.15 s)

Benchmarks (20k frames x 100 atoms, median of 3, wall clock incl.
startup, vs -O2 rebuilds of the legacy tools):
msd 1.08 s vs diffcalc 1.62 s; vacf 1.22 s vs freqcalc 1.51 s;
charge flux 1.23 s vs fluxfreqcalc 2.05 s; vacf+spectrum 1.23 s vs
freqcalc+ft 1.69 s; build_spectrum 0.24 s vs gawk 1.21 s. Outputs
match the previous implementation bitwise and legacy references to
print precision; kernel-vs-fallback equivalence is test-pinned.

* perf: parse trajectories from byte slabs

Replace the per-line parse path of the raw fast-path readers with a
Cython slab parser: frames are scanned from 8 MB byte chunks with
memchr, the atom-name token is skipped without decoding and the
numeric fields are converted with strtof/strtod directly on the
buffer. The float32 values stay bitwise identical to the previous
sscanf-based parsing (verified per frame over the full benchmark
trajectories and over adversarial rounding-boundary literals,
including subnormals and NaN payloads). A pure-python implementation
with the identical contract remains as fallback, and the charge
trajectory reader shares the same machinery.

Raw streaming of a 74 MB trajectory drops from 0.70 s to 0.16 s.
End-to-end against the fastest legacy builds (-O3/-ffast-math/-flto
where beneficial, 20k frames x 100 atoms): msd 0.54 s vs 1.55 s
(2.9x), vacf 0.65 s vs 1.49 s (2.3x), charge flux 0.66 s vs 2.03 s
(3.1x), vacf+spectrum 0.67 s vs 1.67 s (2.5x).

* chore: stop tracking generated cython artifacts

The compiled extensions produce per-platform .so files and generated
.c sources that should not live in version control (following the
existing process_lines.pyx precedent, whose .c/.so are untracked).
Remove the committed msd/vacf kernel and slab-parser artifacts and add
ignore rules; only the .pyx sources stay tracked.

* perf: vectorize rdf and speed up momentum

Bring the remaining trajectory analyses up to the msd/vacf fast path
and add a compiled histogram kernel for the pair-distance loop:

- analysis/rdf: add a Cython distance-histogram kernel (with a numpy
  fallback) and route the plain g(r) case through the raw streaming
  reader. The five output arrays stay bitwise identical to the
  previous implementation; the residue-exclusion and in-memory paths
  are untouched. End to end on 20k frames x 100 atoms this drops rdf
  from 34.4 s to 0.78 s, edging past the fastest legacy C build
  (0.83 s).
- analysis/momentum: read velocity trajectories through the raw fast
  path (2.46 s -> 0.59 s, bit-identical norms).
- add tqdm progress bars (config-gated) to the vacf and momentum run
  loops, matching rdf/msd; give vacf a class-level default window size.

Also aligns the newer modules with the rdf house style (relative
exception imports, module docstrings, CLI headings) and adds the
_slab_parser source to the sdist manifest.

* test: reach full line coverage for the new analyses

Add tests covering the remaining branches of the msd, vacf, momentum,
spectrum_broadening and raw-reader modules: the warning exception
types, the non-positive time_step and negative start guards, the
non-fast-path trajectory-reader branches (extended xyz velocity and
charge inputs), the charge-trajectory length and shape errors, the
zero origin-norm case, and the byte-slab parser edge cases (missing
trailing newline, blank-line skipping, truncated frames, invalid box
counts, empty qmcfc frames). The compiled-extension import fallbacks
are exercised without disturbing the shared modules. Line coverage of
the added source is now 100%.
@github-actions

Copy link
Copy Markdown
Contributor

PYLINT REPORT

Your code has been rated at 9.76/10

Full report

Raw metrics

type number % previous difference
code 13031 42.96 NC NC
docstring 12355 40.73 NC NC
comment 455 1.50 NC NC
empty 4494 14.81 NC NC

Duplication

now previous difference
nb duplicated lines 0 NC NC
percent duplicated lines 0.000 NC NC

Messages by category

type number previous difference
convention 8 NC NC
refactor 126 NC NC
warning 19 NC NC
error 5 NC NC

% errors / warnings by module

module error warning refactor convention
PQAnalysis.type_checking 40.00 0.00 0.00 0.00
PQAnalysis.atomic_system.atomic_system 20.00 10.53 7.14 0.00
PQAnalysis.analysis.vibrational.vibrational_analysis 20.00 0.00 7.94 0.00
PQAnalysis 20.00 0.00 0.00 0.00
PQAnalysis.analysis.vacf._vacf_kernel_py 0.00 10.53 1.59 0.00
PQAnalysis.topology.init 0.00 10.53 0.00 0.00
PQAnalysis.tools.traj_to_com_traj 0.00 10.53 0.00 0.00
PQAnalysis.io.traj_file._process_lines_py 0.00 10.53 0.00 0.00
PQAnalysis.io.moldescriptor_reader 0.00 10.53 0.00 0.00
PQAnalysis.tools.add_molecule 0.00 5.26 4.76 0.00
PQAnalysis.analysis.rdf._rdf_kernel_py 0.00 5.26 2.38 0.00
PQAnalysis.analysis.msd._msd_kernel_py 0.00 5.26 2.38 0.00
PQAnalysis.io.conversion_api 0.00 5.26 1.59 0.00
PQAnalysis.version 0.00 5.26 0.00 0.00
PQAnalysis.utils.custom_logging 0.00 5.26 0.00 0.00
PQAnalysis.io.write_api 0.00 5.26 0.00 0.00
PQAnalysis.cli.init 0.00 0.00 11.11 0.00
PQAnalysis.analysis.rdf.rdf 0.00 0.00 6.35 12.50
PQAnalysis.analysis.msd.msd 0.00 0.00 6.35 0.00
PQAnalysis.io.nep.nep_writer 0.00 0.00 5.56 12.50
PQAnalysis.analysis.vacf.vacf 0.00 0.00 4.76 0.00
PQAnalysis.analysis.vacf.spectrum 0.00 0.00 3.97 0.00
PQAnalysis.io.traj_file.trajectory_reader 0.00 0.00 3.17 0.00
PQAnalysis.topology.bonded_topology.dihedral 0.00 0.00 2.38 0.00
PQAnalysis.io.traj_file._slab_parser_py 0.00 0.00 2.38 0.00
PQAnalysis.core.residue 0.00 0.00 2.38 0.00
PQAnalysis.topology.bonded_topology.bonded_topology 0.00 0.00 1.59 0.00
PQAnalysis.topology.bonded_topology.bond 0.00 0.00 1.59 0.00
PQAnalysis.topology.bonded_topology.angle 0.00 0.00 1.59 0.00
PQAnalysis.io.traj_file.raw_frame_reader 0.00 0.00 1.59 0.00
PQAnalysis.core.cell.cell 0.00 0.00 1.59 0.00
PQAnalysis.atomic_system._standard_properties 0.00 0.00 1.59 0.00
PQAnalysis.analysis.vacf.api 0.00 0.00 1.59 0.00
PQAnalysis.analysis.spectrum_broadening.api 0.00 0.00 1.59 0.00
PQAnalysis.analysis.momentum.api 0.00 0.00 1.59 0.00
PQAnalysis.analysis.vibrational.vibrational_input_file_reader 0.00 0.00 0.79 12.50
PQAnalysis.traj.formats 0.00 0.00 0.79 0.00
PQAnalysis.topology.topology 0.00 0.00 0.79 0.00
PQAnalysis.topology.selection 0.00 0.00 0.79 0.00
PQAnalysis.io.traj_file.frame_reader 0.00 0.00 0.79 0.00
PQAnalysis.io.restart_file.restart_reader 0.00 0.00 0.79 0.00
PQAnalysis.io.input_file_reader.pq_analysis._parse 0.00 0.00 0.79 0.00
PQAnalysis.io.input_file_reader.pq.pq_input_file_reader 0.00 0.00 0.79 0.00
PQAnalysis.io.input_file_reader.input_file_parser 0.00 0.00 0.79 0.00
PQAnalysis.io.info_file_reader 0.00 0.00 0.79 0.00
PQAnalysis.io.formats 0.00 0.00 0.79 0.00
PQAnalysis.analysis.momentum.momentum 0.00 0.00 0.79 0.00
PQAnalysis.core.atom.element 0.00 0.00 0.00 25.00
PQAnalysis.analysis.vacf.vacf_input_file_reader 0.00 0.00 0.00 12.50
PQAnalysis.analysis.rdf.rdf_input_file_reader 0.00 0.00 0.00 12.50
PQAnalysis.analysis.msd.msd_input_file_reader 0.00 0.00 0.00 12.50

Messages

message id occurrences
too-many-positional-arguments 28
too-many-arguments 28
too-many-locals 15
duplicate-code 14
too-many-instance-attributes 13
fixme 9
too-complex 8
inconsistent-return-statements 8
invalid-name 6
too-many-branches 5
missing-type-doc 4
too-many-return-statements 3
unused-import 2
too-many-statements 2
too-many-lines 2
redefined-builtin 2
missing-kwoa 2
use-set-for-membership 1
unexpected-keyword-arg 1
too-many-public-methods 1
possibly-used-before-assignment 1
no-member 1
missing-param-doc 1
arguments-differ 1

@galjos
galjos merged commit f2b9419 into main Jul 22, 2026
6 checks passed
@codecov

codecov Bot commented Jul 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 99.91201% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.18%. Comparing base (f8c15f6) to head (a9d2922).
⚠️ Report is 11 commits behind head on main.

Files with missing lines Patch % Lines
PQAnalysis/analysis/rdf/rdf.py 98.18% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #157      +/-   ##
==========================================
+ Coverage   90.41%   93.18%   +2.77%     
==========================================
  Files         130      170      +40     
  Lines        5685     7928    +2243     
==========================================
+ Hits         5140     7388    +2248     
+ Misses        545      540       -5     
Flag Coverage Δ
unittests 93.18% <99.91%> (+2.77%) ⬆️
Files with missing lines Coverage Δ
PQAnalysis/analysis/__init__.py 100.00% <100.00%> (ø)
PQAnalysis/analysis/momentum/__init__.py 100.00% <100.00%> (ø)
PQAnalysis/analysis/momentum/api.py 100.00% <100.00%> (ø)
PQAnalysis/analysis/momentum/exceptions.py 100.00% <100.00%> (ø)
PQAnalysis/analysis/momentum/momentum.py 100.00% <100.00%> (ø)
...s/analysis/momentum/momentum_output_file_writer.py 100.00% <100.00%> (ø)
PQAnalysis/analysis/msd/__init__.py 100.00% <100.00%> (ø)
PQAnalysis/analysis/msd/_msd_kernel_py.py 100.00% <100.00%> (ø)
PQAnalysis/analysis/msd/api.py 100.00% <100.00%> (ø)
PQAnalysis/analysis/msd/exceptions.py 100.00% <100.00%> (ø)
... and 42 more

... and 4 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant