Adding an Analysis¶
Use an existing complete analysis, such as RDF or MSD, as the structural reference. Keep the scientific estimator independent from its CLI and file format adapters.
1. Define the scientific contract¶
State the observable, normalization, units, periodic-boundary treatment, selection semantics and returned array shapes before implementing the calculation. Decide which behavior reproduces a legacy tool and which behavior is a corrected or newly defined method.
The analysis guide and tests must use the same definitions. A numerical result without its normalization and units is not a complete interface.
2. Implement the analysis package¶
A file-driven analysis typically owns these modules:
PQAnalysis/analysis/<name>/
__init__.py
api.py
<name>.py
<name>_input_file_reader.py
<name>_output_file_writer.py
exceptions.py
The analysis class or numerical function owns the calculation. The input reader validates configuration and the writer serializes results. Avoid importing CLI code from the analysis package.
If a compiled kernel is required, provide a Python or NumPy fallback with the same callable signature. Import the compiled implementation first and fall back only when it is unavailable, following the RDF, MSD and VACF packages.
3. Define inputs and outputs¶
Add input keys to the analysis input reader with explicit types, defaults and validation. Required files should be validated before the trajectory is processed. Keep aliases only when they preserve an established input contract.
Define output columns in PQAnalysis/analysis/_output_schemas.py using
AnalysisColumn and
AnalysisSchema. Field identifiers are ASCII
programmatic names; symbols and units may use Unicode scientific notation.
The data writer should subclass
AnalysisDataWriter, create an
AnalysisTable from the numerical columns,
and delegate CSV, TSV and XVG exports to the common writer. Preserve a legacy
native row format only when compatibility requires it.
4. Add the public API¶
The function in api.py is the shared orchestration layer. It should:
read and validate the analysis input;
construct trajectory, structure or Hessian readers;
construct every output writer so path conflicts fail early;
instantiate and run the scientific analysis;
write the result and return useful in-memory data where appropriate.
Export the function and supported result types from the analysis package
__init__.py and, for a general analysis workflow, from
PQAnalysis.analysis. Add the callable to Function Index.
5. Add the CLI¶
Implement a CLIBase subclass in PQAnalysis/cli/<name>.py. Its
add_arguments method defines only command-line parsing; run calls the
public API function. Reuse common arguments from
PQAnalysis/cli/_argument_parser.py, including repeatable --export for
analysis tables.
Register the class in the dispatch dictionary in PQAnalysis/cli/main.py.
Add a [project.scripts] entry in pyproject.toml only when a standalone
executable is part of the supported interface.
6. Add evidence and documentation¶
The minimum complete change includes:
analytical or independently computed numerical tests;
legacy parity tests when compatibility is claimed;
compiled-kernel and fallback parity where both exist;
input-reader validation and default tests;
API and CLI end-to-end tests;
native output and CSV, TSV and XVG tests;
existing-file failure tests for every output path;
an analysis page defining equations, assumptions, inputs and interpretation;
entries in the function index, command reference and output-schema page.
Follow Scientific Validation for reference-data provenance and tolerance rules.