Python API

The public API is designed for notebooks and scripts that need results in memory. The high-level entry points mirror the installed commands:

pycurves_lib.curves_wrapper.CurvesWrapper

pycurves_md.analyze_trajectory

pycurves_md_batch.analyze_trajectory_batch

Run the vectorized local-axis/standard-frame MD path from Python.

pycurves_viewer.write_viewer

pycurves_pymol.write_pymol_scene

Static structure analysis

Use CurvesWrapper for one structure or one explicit Curves input.

Basic lifecycle

from pycurves_lib.curves_wrapper import CurvesWrapper

runner = CurvesWrapper.from_file("structure.cif")
runner.analyze()

json_text = runner.output(fmt="json")
features = runner.getFeatures()

from_file() accepts either a coordinate structure or a Curves .inp. For coordinates it infers and writes an input immediately. For an .inp, it reads the coordinate path from the input’s file= value.

analyze() performs the calculation and returns the same runner. output() requires a completed analysis, returns the rendered string, and also prints it when file=None. Use write_output() to write directly.

For the shortest run-and-render workflow:

runner = CurvesWrapper.from_file("structure.pdb")
runner.run(output=False)
runner.write_output("structure.json", fmt="json")

Constructor arguments

Prefer keyword arguments when constructing the class directly:

runner = CurvesWrapper(
    pdbfile="structure.cif",
    output_dir="inferred_inputs",
    frame_convention="standard",
    axis_convention="global",
    axis_weighting=False,
)

Argument

Behavior

pdbfile

PDB/mmCIF coordinate path. Required unless inpfile is supplied and resolves its own file= entry.

inpfile

Existing Curves topology/configuration. Mutually exclusive with dssr_json.

output_dir

Destination for inferred Curves inputs. Default: current directory.

continuous_strands

Join connected split-chain helical components during inference.

duplex_only

Disable triplex/quadruplex inference.

altloc

One-character alternate conformation, or None for the first conformer in file order.

frame_convention

"standard" (default) or "legacy".

axis_convention

"global" (default) or "local". Local forces standard frames.

axis_weighting

True or False overrides axis weighting; None keeps the configuration default.

fit_override

Override the Curves fit flag.

grv_override

Override the Curves grv (groove) flag.

mini_override

Override the Curves mini flag.

comb_override

Override the Curves comb flag.

ends_override

Override terminal virtual end levels.

auto_generate_inp

Infer an input during construction when no inpfile is supplied. Set false when you intend to call generate_inp() explicitly.

dssr_json

Optional DSSR topology report.

dssr_unit

Unit selector such as "stem:1" when a DSSR report is ambiguous.

See Analysis options and conventions for the scientific effect of these arguments.

Generating Curves inputs

runner = CurvesWrapper(
    pdbfile="structure.cif",
    output_dir="inferred_inputs",
    auto_generate_inp=False,
)
paths = runner.generate_inp(prefix="structure_auto")

generate_inp() returns a list of written paths because one coordinate file can contain multiple inferred units.

DSSR topology

runner = CurvesWrapper.from_file(
    "structure.cif",
    dssr_json="structure-dssr.json",
    dssr_unit="stem:1",
)
runner.analyze()

When no unit selector is required, inspect the available units before analysis:

runner = CurvesWrapper(
    pdbfile="structure.cif",
    dssr_json="structure-dssr.json",
    auto_generate_inp=False,
)
units = runner.list_dssr_units()

Result access

getFeatures() returns NumPy-backed internal feature arrays and selected derived records. For stable serialization and labelled tables, prefer CurvesOutputFormatter:

from pycurves_lib.io.curves_output import CurvesOutputFormatter

runner = CurvesWrapper.from_file("structure.pdb").analyze()
formatter = CurvesOutputFormatter(runner)

frames = formatter.get_dataframes()
steps = frames["local_inter_base_pair"]
json_text = formatter.render("json")

The dataframe keys and JSON layout are listed in Output formats and schemas.

Class reference

class pycurves_lib.curves_wrapper.CurvesWrapper(*args, dssr_json: str | None = None, dssr_unit: str | None = None, **kwargs)[source]
classmethod CurvesWrapper.from_file(path: str, output_dir: str = '.', continuous_strands: bool = False, altloc: str | None = None, frame_convention: str = 'standard', axis_convention: str = 'global', dssr_json: str | None = None, dssr_unit: str | None = None, duplex_only: bool = False, **kwargs)[source]
CurvesWrapper.analyze(inpfile: str | None = None, pdbfile: str | None = None, mini: bool | None = None, verbose: bool = False, continuous_strands: bool | None = None, altloc: str | None = None, frame_convention: str | None = None, axis_convention: str | None = None, duplex_only: bool | None = None)[source]
CurvesWrapper.analyze_molecule(molecule: MolecularStructure, inpfile: str | None = None, mini: bool | None = None, verbose: bool = False, prev_opt_helical: ndarray | None = None, axis_sign_reference: ndarray | None = None)[source]

Run pyCurves on an already populated MolecularStructure.

This is intended for trajectory workflows where atom metadata and topology stay fixed while coordinates change frame by frame.

CurvesWrapper.run(output: bool = True, mini: bool | None = None, verbose: bool = False, output_format: str = 'curves', visualization: bool = False)[source]
CurvesWrapper.output(fmt: str = 'curves', file=None, visualization: bool = False) → str[source]
CurvesWrapper.write_output(path: str, fmt: str = 'curves', visualization: bool = False) → str[source]
CurvesWrapper.getFeatures()[source]
CurvesWrapper.generate_inp(pdbfile: str | None = None, output_dir: str | None = None, prefix: str | None = None, continuous_strands: bool = False, altloc: str | None = None, duplex_only: bool | None = None)[source]
CurvesWrapper.list_dssr_units(pdbfile: str | None = None)[source]
classmethod CurvesWrapper.normalize_conventions(frame_convention: str, axis_convention: str)[source]
class pycurves_lib.io.curves_output.CurvesOutputFormatter(runner, visualization: bool = False, fast_groove: bool = False)[source]
CurvesOutputFormatter.get_dataframes()[source]

Return a dictionary of Pandas DataFrames for all computed parameters.

CurvesOutputFormatter.render(fmt: str = 'curves', header_name: str = 'pyCurves') → str[source]
CurvesOutputFormatter.render_csv() → str[source]

Returns a string describing the CSV data or writes it to a zip file in memory (used programmatically). For CLI, curves_wrapper.py or pycurves.py should handle saving the DataFrames directly.

CurvesOutputFormatter.render_curves_text(header_name: str = 'pyCurves') → str[source]
CurvesOutputFormatter.render_json() → str[source]

General trajectory API

pycurves_md.analyze_trajectory() is the in-memory equivalent of pycurves-md.

from pycurves_md import analyze_trajectory

payload = analyze_trajectory(
    "topology.pdb",
    "trajectory.xtc",
    frames="1000:5000:10",
    mode="both",
    frame_convention="standard",
    axis_convention="local",
)

Important arguments

Argument

Behavior

topology_file

Reference PDB/mmCIF structure.

trajectory_file

Trajectory path, or None for a multi-model PDB.

inpfile

Optional fixed Curves topology.

frames

Comma/range selector such as "0,10,20:100:5"; overrides start, stop, and step.

start, stop, step

Half-open range selection when frames is absent.

mode

"per-frame", "summary", or "both".

fit, grooves, mini, comb, ends

Boolean Curves overrides. None keeps inferred/input values.

topology_mode

"reference" or per-frame "annotate".

verbose

Echo analysis logs for each selected frame.

warm_start

Seed minimized global-axis optimization from the preceding frame.

axis_continuity

Keep global-axis signs aligned to the first processed frame.

dssr_json, dssr_unit

Optional DSSR-supplied reference topology.

The return value is a JSON-compatible dictionary. mode="per-frame" adds payload["frames"], mode="summary" adds payload["summary"], and "both" adds both.

pycurves_md.analyze_trajectory(topology_file: str, trajectory_file: str | None = None, inpfile: str | None = None, output_dir: str = '.', frames: str | None = None, start: int | None = None, stop: int | None = None, step: int = 1, mode: str = 'per-frame', frame_convention: str = 'standard', axis_convention: str = 'global', axis_weighting: bool | None = None, continuous_strands: bool = False, altloc: str | None = None, fit: bool | None = None, grooves: bool | None = None, mini: bool | None = None, comb: bool | None = None, ends: bool | None = None, topology_mode: str = 'reference', verbose: bool = False, warm_start: bool = True, axis_continuity: bool = True, dssr_json: str | None = None, dssr_unit: str | None = None, duplex_only: bool = False, workers: int = 1) → Dict[source]
class pycurves_md.MDTrajectoryAnalyzer(topology_file: str, trajectory_file: str | None = None, inpfile: str | None = None, output_dir: str = '.', frame_convention: str = 'standard', axis_convention: str = 'global', axis_weighting: bool | None = None, continuous_strands: bool = False, altloc: str | None = None, fit_override: bool | None = None, grv_override: bool | None = None, mini_override: bool | None = None, comb_override: bool | None = None, ends_override: bool | None = None, topology_mode: str = 'reference', dssr_json: str | None = None, dssr_unit: str | None = None, duplex_only: bool = False)[source]

Reuse one DSSR-selected reference topology over all trajectory frames.

MDTrajectoryAnalyzer.run(*args, **kwargs)[source]
MDTrajectoryAnalyzer.write_csv(payload: Dict, prefix: str) → None[source]

Vectorized trajectory API

pycurves_md_batch.analyze_trajectory_batch() is the notebook-facing batch engine:

from pycurves_md_batch import analyze_trajectory_batch

payload = analyze_trajectory_batch(
    "topology.pdb",
    "trajectory.xtc",
    frames="0:10000:10",
    batch_size=256,
    workers=4,
    mode="summary",
    grooves=True,
)

This function supports only standard frames, the local axis, fitted bases, combined strands, and no terminal virtual levels. batch_size controls memory/throughput. workers controls process-level batch concurrency. curvesplus_axis_steps=True includes the smooth-axis step table and fit_quality=True includes fitting RMSD diagnostics.

pycurves_md_batch.analyze_trajectory_batch(topology_file: str, trajectory_file: str | None = None, inpfile: str | None = None, output_dir: str = '.', frames: str | None = None, start: int | None = None, stop: int | None = None, step: int = 1, batch_size: int = 256, mode: str = 'per-frame', continuous_strands: bool = False, altloc: str | None = None, fit: bool | None = None, grooves: bool | None = None, comb: bool | None = None, ends: bool | None = None, frame_convention: str = 'standard', axis_convention: str = 'local', curvesplus_axis_steps: bool = False, fit_quality: bool = False, axis_weighting: bool | None = None, workers: int = 1, duplex_only: bool = False) → Dict[source]

Run the vectorized local-axis/standard-frame MD path from Python.

This is the notebook-friendly equivalent of pycurves-md-batch. It is intended for canonical, standard-frame analyses supported by the batch engine.

Trajectory dataframe helpers

Use mode="per-frame" or mode="both" before extracting time-resolved data.

from pycurves_md_plot import (
    add_time_axis,
    extract_block,
    filter_rows,
    parameter_timeseries,
    pivot_parameter_matrix,
)

steps = extract_block(payload, "local_step")
steps = filter_rows(steps, level=range(5, 16), drop_terminal=1)
steps = add_time_axis(steps, time_scale=0.001, time_label="time (ns)")

twist = parameter_timeseries(
    steps,
    "twist",
    time_column="plot_time",
    aggregate=True,
)
heatmap = pivot_parameter_matrix(
    steps,
    "twist",
    index_column="plot_time",
    column="level",
)
pycurves_md_plot.load_trajectory_payload(source: str | Path | Dict) → Dict[source]

Load a pyCurves MD payload from a dict or JSON file path.

pycurves_md_plot.iter_pycurves_frames(source: str | Path | Dict | List[Dict]) → Iterator[Dict][source]

Yield per-frame payloads from a pyCurves trajectory payload or JSON file.

Passing a dict is convenient in notebooks after analyze_trajectory. Passing a path streams frames with ijson when available, which is better for large JSON files written by the CLI.

pycurves_md_plot.extract_table(source: str | Path | Dict | List[Dict], table_name: str) → DataFrame[source]

Extract a per-frame pyCurves trajectory table into a long-form DataFrame.

pycurves_md_plot.extract_block(source: str | Path | Dict | List[Dict], block: str) → DataFrame[source]

Extract one named analysis block such as step, base_pair, axis, groove, or backbone.

pycurves_md_plot.extract_summary_table(source: str | Path | Dict, table_name: str) → DataFrame[source]

Extract a summary table from a summary/both-mode MD payload or JSON file.

pycurves_md_plot.extract_summary_block(source: str | Path | Dict, block: str) → DataFrame[source]

Extract a named block’s summary table from a summary/both-mode payload.

pycurves_md_plot.filter_rows(df: DataFrame, level: Sequence[int] | None = None, strand: Sequence[int] | None = None, duplex_contains: str | None = None, drop_terminal: int = 0) → DataFrame[source]

Convenience filter for selected levels, strands, or duplex labels.

pycurves_md_plot.wrap_degrees(values) → Series[source]

Wrap angular values to the conventional [-180, 180) degree interval.

pycurves_md_plot.add_time_axis(df: DataFrame, time_scale: float = 1.0, time_label: str = 'time') → DataFrame[source]

Add plot_time to a table, preserving original frame/time columns.

pycurves_md_plot.parameter_timeseries(df: DataFrame, parameter: str, time_column: str = 'time', aggregate: bool = True, statistic: str = 'mean') → DataFrame[source]

Return time series for one parameter.

With aggregate=True, all levels/strands at each time are summarized as mean/std/min/max. With aggregate=False, the original long-form rows are returned with only finite values retained.

pycurves_md_plot.pivot_parameter_matrix(df: DataFrame, parameter: str, index_column: str = 'time', column: str = 'level') → DataFrame[source]

Build a time x level matrix for heatmaps.

pycurves_md_plot.outlier_rows(df: DataFrame, parameter: str, abs_limit: float | None = None, robust_z: float = 8.0) → DataFrame[source]

Return rows with unusually large parameter values for diagnostics.

Viewer and PyMOL writers

These functions consume an already generated visualization payload; they do not rerun the scientific analysis.

write_viewer() reads a pyCurves JSON result, resolves the structure from structure_file or the JSON’s inputs.pdbfile, and writes one HTML file. render_viewer_html() is the lower-level renderer for callers that already have a loaded result dictionary and coordinate text.

write_pymol_scene() validates the same visualization payload and writes a .pml overlay script. render_pymol_script() returns that script as a string instead; scene_prefix controls the generated PyMOL object names.

pycurves_viewer.write_viewer(json_file: str, output_file: str | None = None, structure_file: str | None = None) → Path[source]
pycurves_viewer.render_viewer_html(results: Dict[str, Any], structure_text: str, structure_format: str, title: str) → str[source]
pycurves_pymol.write_pymol_scene(json_file: str, output_file: str | None = None, structure_file: str | None = None, structure_object: str = 'pycurves_structure', scene_prefix: str = 'pycurves') → Path[source]
pycurves_pymol.render_pymol_script(results: Dict[str, Any], scene_prefix: str = 'pycurves') → str[source]