API Reference
Complete reference for all modules, classes, and functions in wetting_angle_kit.
Parser Module
- class wetting_angle_kit.parsers.AseParser(filepath: str)[source]
Bases:
BaseParserASE trajectory parser for any ASE-readable file format.
- box_length_max(frame_index: int) float[source]
Return the maximum lattice vector length for a frame.
- Parameters:
frame_index (int) – Frame index.
- Returns:
Max
|a_i|over lattice vectors.- Return type:
float
- box_size_x(frame_index: int) float[source]
Return the length of the first lattice vector for a frame.
- box_size_y(frame_index: int) float[source]
Return the length of the second lattice vector for a frame.
- parse(frame_index: int, indices: ndarray | None = None) ndarray[source]
Return Cartesian coordinates for selected atoms in a frame.
- Parameters:
frame_index (int) – Frame index.
indices (ndarray, optional) – Atom indices to select; if None all atoms are returned.
- Returns:
Atom coordinates.
- Return type:
ndarray, shape (M, 3)
- parse_liquid_particles(liquid_particle_types: list[str], frame_index: int) ndarray[source]
Return positions of liquid atoms filtered by atomic symbol.
- Parameters:
liquid_particle_types (sequence[str]) – Symbols identifying liquid atoms.
frame_index (int) – Frame index.
- Returns:
Liquid atom positions.
- Return type:
ndarray, shape (L, 3)
- class wetting_angle_kit.parsers.AseWallParser(filepath: str, liquid_particle_types: list[str])[source]
Bases:
BaseParserParser extracting wall particle coordinates (excluding liquid types).
Wall particles are everything not in
liquid_particle_types. Theindicesargument ofparse()is treated as 0-based positional indices into the wall-only positions for compatibility with theBaseParsercontract.- box_length_max(frame_index: int) float[source]
Return the maximum lattice vector length for a frame.
- Parameters:
frame_index (int) – Frame index.
- Returns:
Max
|a_i|over lattice vectors.- Return type:
float
- box_size_x(frame_index: int) float[source]
Return the length of the first lattice vector for a frame.
- box_size_y(frame_index: int) float[source]
Return the length of the second lattice vector for a frame.
- find_highest_wall_part(*args: Any, **kwargs: Any) float[source]
Deprecated alias for find_highest_wall_particle.
- find_highest_wall_particle(frame_index: int) float[source]
Return the maximum z-coordinate among wall particles for a frame.
- Parameters:
frame_index (int) – Frame index.
- Returns:
Maximum z-coordinate.
- Return type:
float
- parse(frame_index: int, indices: ndarray | None = None) ndarray[source]
Return wall atom positions for a frame.
- Parameters:
frame_index (int) – Frame index.
indices (ndarray, optional) – Indices into the wall-only positions to further restrict the wall atoms; if None all wall atoms are returned.
- Returns:
Wall atoms coordinates.
- Return type:
ndarray, shape (M, 3)
- class wetting_angle_kit.parsers.AseWaterFinder(filepath: str, oxygen_type: str = 'O', hydrogen_type: str = 'H', oh_cutoff: float = 1.2)[source]
Bases:
objectIdentify water oxygen atoms by counting hydrogen neighbors via ASE neighbor list.
- class wetting_angle_kit.parsers.BaseParser[source]
Bases:
ABCAbstract interface for trajectory parsers consumed by analyzers.
Subclasses must implement
parse(),frame_count(), and the cell-geometry helpersbox_size_x(),box_size_y(), andbox_length_max(). The cell helpers are abstract because the analyzers rely on per-frame box information (PBC-aware droplet recentering, default sampling extent); a parser without it would silently degrade their accuracy.- abstractmethod box_length_max(frame_index: int) float[source]
Return the maximum lattice vector length for a frame.
- Parameters:
frame_index (int) – Frame index.
- Returns:
Max
|a_i|over lattice vectors.- Return type:
float
- abstractmethod box_size_x(frame_index: int) float[source]
Return the length of the first lattice vector for a frame.
- abstractmethod box_size_y(frame_index: int) float[source]
Return the length of the second lattice vector for a frame.
- abstractmethod parse(frame_index: int, indices: ndarray | None = None) ndarray[source]
Return Cartesian coordinates for selected atoms in a frame.
- Parameters:
frame_index (int) – Frame index.
indices (ndarray, optional) –
Atom indices to select; if None all atoms are returned. The meaning of
indicesdiffers by parser because the underlying file formats do not all preserve atom ordering across frames:LammpsDumpParser(LAMMPS) —indicesare LAMMPS particle identifiers. LAMMPS may reorder atoms between frames, so a persistent ID is needed to track the same atom.XYZParser,AseParser—indicesare positional indices into the per-frame coordinate array. These formats keep atom ordering stable across frames during simulations.
- Returns:
Atom coordinates.
- Return type:
ndarray, shape (M, 3)
- class wetting_angle_kit.parsers.LammpsDumpParser(filepath: str)[source]
Bases:
BaseParserLAMMPS dump trajectory parser backed by an OVITO pipeline.
- box_length_max(frame_index: int) float[source]
Return the maximum lattice vector length for a frame.
- Parameters:
frame_index (int) – Frame index.
- Returns:
Max
|a_i|over lattice vectors.- Return type:
float
- box_size_x(frame_index: int) float[source]
Return the length of the first lattice vector for a frame.
- box_size_y(frame_index: int) float[source]
Return the length of the second lattice vector for a frame.
- parse(frame_index: int, indices: ndarray | None = None) ndarray[source]
Return Cartesian coordinates for selected atoms in a frame.
- Parameters:
frame_index (int) – Frame index.
indices (ndarray, optional) – LAMMPS particle IDs to select; if None all atoms are returned.
- Returns:
Atom coordinates.
- Return type:
ndarray, shape (M, 3)
- class wetting_angle_kit.parsers.LammpsDumpWallParser(filepath: str, liquid_particle_types: list[int])[source]
Bases:
BaseParserLAMMPS dump file parser for extracting wall particle coordinates.
Wall particles are everything not in
liquid_particle_types; filtering is done inside the OVITO pipeline. Theindicesargument ofparse()is therefore typically ignored, but it is accepted (as LAMMPS particle IDs, likeLammpsDumpParser) to satisfy theBaseParsercontract.- box_length_max(frame_index: int) float[source]
Return the maximum lattice vector length for a frame.
- Parameters:
frame_index (int) – Frame index.
- Returns:
Max
|a_i|over lattice vectors.- Return type:
float
- box_size_x(frame_index: int) float[source]
Return the length of the first lattice vector for a frame.
- box_size_y(frame_index: int) float[source]
Return the length of the second lattice vector for a frame.
- find_highest_wall_particle(frame_index: int) float[source]
Return the maximum z-coordinate among wall particles for a frame.
- Parameters:
frame_index (int) – Frame index.
- Returns:
Maximum z-coordinate.
- Return type:
float
- load_dump_ovito() Any[source]
Build and return the OVITO pipeline for wall-only extraction.
Returns
Anybecause OVITO’s Python bindings ship without type stubs; the pipeline is opaque from the type checker’s perspective.
- parse(frame_index: int, indices: ndarray | None = None) ndarray[source]
Return wall atom positions for a frame.
- Parameters:
frame_index (int) – Frame index.
indices (ndarray, optional) – LAMMPS particle IDs to further restrict the wall atoms; if None all wall atoms are returned.
- Returns:
Wall atom coordinates.
- Return type:
ndarray, shape (M, 3)
- class wetting_angle_kit.parsers.LammpsDumpWaterFinder(filepath: str, oxygen_type: int, hydrogen_type: int, oh_cutoff: float = 1.2)[source]
Bases:
objectIdentify water oxygen atoms in a LAMMPS trajectory via an OVITO pipeline.
- class wetting_angle_kit.parsers.XYZParser(filepath: str)[source]
Bases:
BaseParserExtended XYZ trajectory parser.
- box_length_max(frame_index: int) float[source]
Return the maximum lattice vector length for a frame.
- Parameters:
frame_index (int) – Frame index.
- Returns:
Max
|a_i|over lattice vectors.- Return type:
float
- box_size_x(frame_index: int) float[source]
Return the length of the first lattice vector for a frame.
- box_size_y(frame_index: int) float[source]
Return the length of the second lattice vector for a frame.
- load_xyz_file() list[dict[str, Any]][source]
Load all frames from the XYZ file into memory using numpy.
- Returns:
Each entry has keys:
symbols,positions,lattice_matrix.- Return type:
list[dict]
- parse(frame_index: int, indices: ndarray | None = None) ndarray[source]
Return Cartesian coordinates for selected atoms in a frame.
- Parameters:
frame_index (int) – Frame index.
indices (ndarray, optional) – Atom indices to select; if None all atoms are returned.
- Returns:
Atom coordinates.
- Return type:
ndarray, shape (M, 3)
- parse_liquid_particles(liquid_particle_types: list[str], frame_index: int) ndarray[source]
Return positions of liquid atoms identified by their atomic symbol.
- Parameters:
liquid_particle_types (sequence[str]) – Symbols identifying liquid atoms.
frame_index (int) – Frame index.
- Returns:
Liquid atom positions.
- Return type:
ndarray, shape (L, 3)
- class wetting_angle_kit.parsers.XYZWallParser(filepath: str, liquid_particle_types: list[str])[source]
Bases:
BaseParserParser extracting wall particle coordinates from an XYZ trajectory.
Wall particles are everything not in
liquid_particle_types; the mask is applied atparse()time over the per-frame symbol array. Theindicesargument ofparse()is treated as 0-based positional indices into the wall-only positions, mirroringAseWallParser.- box_length_max(frame_index: int) float[source]
Return the maximum lattice vector length for a frame.
- box_size_x(frame_index: int) float[source]
Return the length of the first lattice vector for a frame.
- box_size_y(frame_index: int) float[source]
Return the length of the second lattice vector for a frame.
- find_highest_wall_particle(frame_index: int) float[source]
Return the maximum z-coordinate among wall particles for a frame.
- parse(frame_index: int, indices: ndarray | None = None) ndarray[source]
Return wall atom positions for a frame.
- Parameters:
frame_index (int) – Frame index.
indices (ndarray, optional) – 0-based indices into the wall-only positions to further restrict the result; if None all wall atoms are returned.
- Returns:
Wall atom coordinates.
- Return type:
ndarray, shape (M, 3)
- class wetting_angle_kit.parsers.XYZWaterFinder(filepath: str, oxygen_type: str = 'O', hydrogen_type: str = 'H', oh_cutoff: float = 1.2)[source]
Bases:
objectHelper for identifying water oxygen atoms in XYZ trajectories.
This is a standalone helper (not a
BaseParser) because itsparsesignature filters by atomic symbol rather than frame index, which is incompatible with the parser ABC contract.- box_length_max(frame_index: int) float[source]
Return the maximum lattice vector length for a frame.
- Parameters:
frame_index (int) – Frame index.
- Returns:
Max
|a_i|over lattice vectors.- Return type:
float
- get_water_oxygen_indices(frame_index: int) ndarray[source]
Return indices of oxygen atoms bonded to exactly two hydrogens.
- Parameters:
frame_index (int) – Frame index.
- Returns:
Oxygen atom indices belonging to water molecules.
- Return type:
ndarray
- get_water_oxygen_positions(frame_index: int) ndarray[source]
Return positions of water oxygen atoms for a frame.
- Parameters:
frame_index (int) – Frame index.
- Returns:
Oxygen atom positions; empty array if none detected.
- Return type:
ndarray, shape (N, 3)
- load_xyz_file() list[dict[str, Any]][source]
Load frames including the lattice matrix for box-size queries.
- parse(liquid_particle_types: list[str], frame_index: int) ndarray[source]
Return liquid particle coordinates filtering wall types.
- Parameters:
liquid_particle_types (sequence[str]) – Symbols for liquid particles.
frame_index (int) – Frame index.
- Returns:
Liquid atom positions.
- Return type:
ndarray, shape (L, 3)
- wetting_angle_kit.parsers.get_water_finder(filename: str, oxygen_type: Any, hydrogen_type: Any) Any[source]
Return the appropriate water oxygen finder for a given trajectory file.
- Parameters:
filename (str) – Path to trajectory file; extension determines the finder class.
oxygen_type (Any) – Oxygen type identifier (symbol or integer depending on file format).
hydrogen_type (Any) – Hydrogen type identifier (symbol or integer depending on file format).
- Returns:
Finder instance matching the file format.
- Return type:
Analysis
Base Analyzer
Abstract base class for contact-angle analyzers.
Slicing Method
Public exports for the slicing contact angle method.
- class wetting_angle_kit.analysis.slicing.SlicingTrajectoryAnalyzer(parser: Any, droplet_geometry: str = 'spherical', atom_indices: ndarray | None = None, delta_gamma: float | None = None, delta_cylinder: float | None = None, points_per_angstrom: float = 1.0, precentered: bool = False)[source]
Bases:
BaseTrajectoryAnalyzerTrajectory-level slicing contact-angle analyzer.
Frames are dispatched one-by-one to a
multiprocessing.Poolwhose workers each build their own parser once and reuse it for every frame they receive. The per-frame fitting work is delegated toSlicingFrameFitter.- analyze(frame_range: list[int] | None = None, n_jobs: int | None = None) SlicingResults[source]
Run the slicing analysis in parallel across frames.
- Parameters:
frame_range (list[int], optional) – Frame indices to process. Defaults to all frames.
n_jobs (int, optional) – Number of worker processes.
Noneletsmultiprocessing.Poolpick the default (os.cpu_count()).
- Returns:
Per-frame angles, surface contours, fit parameters and method metadata. Frames whose worker failed to produce a mean angle are omitted.
- Return type:
SlicingResults
- class wetting_angle_kit.analysis.slicing.SurfaceDefinition(atom_coords: ndarray, delta_angle: float, max_dist: float, center_geom: ndarray, gamma: float, density_conversion: float = 1.0, points_per_angstrom: float = 1.0, density_sigma: float = 3.0, cutoff_sigma: float = 5.0)[source]
Bases:
objectRadial line sampling interface estimator for slicing contact angle.
For each attitudinal angle beta the density is sampled along a ray emerging from the droplet geometric center. A simple tanh profile is fitted to obtain the interface position (“re”) which is then projected back to XZ plane.
- DEFAULT_CUTOFF_SIGMA = 5.0
- DEFAULT_DENSITY_SIGMA = 3.0
- MIN_POINTS_PER_RAY = 20
- analyze_lines() tuple[list[list[float]], list[list[float]]][source]
Sample density along radial lines and fit interface positions.
All rays of the slice share the same sampling distances and the same atomic neighbourhood, so their sample positions are stacked into a single
(R * M, 3)array and the truncated density is evaluated in onedensity_contributioncall. Only the tanh fit and the (x, z) projection are still done per ray.- Returns:
rr (list[list[float]]) – Fitted interface distances and azimuth angles
[interface_re, beta_deg].xz (list[list[float]]) – Projected interface coordinates
[x_proj, z_proj]in XZ plane.
- density_contribution(positions: ndarray) ndarray[source]
Return Gaussian-smoothed density contributions at sample positions.
Atoms farther than
cutoff_sigma * density_sigmafrom a sample point are skipped; their kernel weight is below ~4e-6 of the peak at the 5 sigma default. Every (sample, atom) pair within the cutoff is enumerated in a single C-side call viacKDTree.sparse_distance_matrixso the per-sample work happens in one vectorised numpy pass instead of an M-iteration Python loop.- Parameters:
positions (ndarray, shape (M, 3)) – Ray sampling coordinates.
Mis typically the sample count of one ray, or the stacked count of all rays of a slice whenanalyze_lines()batches the per-slice fan.- Returns:
Density values at each sampling position.
- Return type:
ndarray, shape (M,)
- static density_profile(z: ndarray, zd: float, d: float, h: float) ndarray[source]
Simple hyperbolic tangent profile used for liquid-vapor interface localization.
- Parameters:
z (ndarray) – Distances along the sampling ray (Å).
zd (float) – Liquid-vapor interface position parameter to be fitted.
d (float) – Amplitude scaling parameter.
h (float) – Offset parameter.
- Returns:
Modeled density values at each z.
- Return type:
ndarray
Binning Method
Public exports for binning contact angle method.
- class wetting_angle_kit.analysis.binning.BinningTrajectoryAnalyzer(parser: Any, atom_indices: Any, droplet_geometry: str = 'spherical', binning_params: dict[str, Any] | None = None, precentered: bool = False)[source]
Bases:
BaseTrajectoryAnalyzerBaseTrajectoryAnalyzer implementation using the density-binning method.
- analyze(frame_range: list[int] | None = None, split_factor: int | None = None, **kwargs: Any) BinningResults[source]
Run the binning analysis.
- Parameters:
frame_range (list[int], optional) – Frame indices to process. If None, all frames are used.
split_factor (int, optional) – If given, split
frame_rangeinto sub-batches of this size and compute one angle per batch; if None, all frames form a single batch.**kwargs – Reserved for future use.
- Returns:
Per-batch contact angles, density fields and isoline data.
- Return type:
BinningResults
- class wetting_angle_kit.analysis.binning.HyperbolicTangentModel(initial_params: list[float] | None = None)[source]
Bases:
SurfaceModelLiquid–vapor interface model using a hyperbolic tangent profile.
The density field is modeled as the product of two sigmoidal (tanh) terms: one depending on the spherical radial distance and one along the vertical axis.
- DEFAULT_INITIAL_PARAMS = [0.001, 0.03, 40.0, 20.0, 4.0, 1.0, 1.0]
- compute_contact_angle() float[source]
Return the contact angle (degrees) implied by fitted parameters.
- Returns:
Contact angle in degrees. Returns
nanif the fitted wall position lies outside the fitted droplet sphere (no intersection), which indicates a poor fit.- Return type:
float
- compute_isoline(scale_factor: float = 0.95) tuple[ndarray, ndarray, ndarray, ndarray][source]
Compute an iso-surface circle and wall line approximation.
Notes
scale_factorshrinks the fitted equivalent radius before tracing the iso-line. It is a visualization-only parameter: the contact angle reported bycompute_contact_angle()is derived from the unscaled fit. The default of 0.95 makes the overlaid circle sit slightly inside the density isosurface so the underlying contour plot stays visible — it is not meant to encode anything physical.- Parameters:
scale_factor (float, default 0.95) – Visualization-only scaling applied to the fitted equivalent radius before computing the iso-line traces.
- Returns:
(circle_xi, circle_zi, wall_line_xi, wall_line_zi)arrays.- Return type:
tuple(ndarray, ndarray, ndarray, ndarray)
- evaluate(x: Any) float[source]
Evaluate the fitted hyperbolic tangent model at
x.- Parameters:
x (tuple(float, float)) – Coordinates
(xi, zi).- Returns:
Density value at the given point.
- Return type:
float
- fit(x_data: Any, density_data: ndarray) HyperbolicTangentModel[source]
Fit the model parameters to provided density samples.
- Parameters:
x_data (tuple(ndarray, ndarray)) – Coordinate arrays
(xi_array, zi_array)flattened or broadcastable.density_data (ndarray) – Density values corresponding to
x_data.
- Returns:
Fitted model instance (
self).- Return type:
Visualization and Statistics
- class wetting_angle_kit.visualization.BaseTrajectoryPlotter[source]
Bases:
ABCAbstract base for trajectory plotters.
Subclasses own their own data layout (per-method result containers, directories, etc.) and must implement
summary()returning oneTrajectoryStatsper trajectory.- abstractmethod summary() list[TrajectoryStats][source]
Return per-trajectory summary statistics.
- class wetting_angle_kit.visualization.BinningTrajectoryPlotter(results: BinningResults | Iterable[BinningResults], labels: list[str] | None = None, time_steps: list[float] | None = None, time_unit: str = 'ps')[source]
Bases:
BaseTrajectoryPlotterPlot statistics derived from one or more
BinningResults.- static circular_segment_area(R: float, z_center: float, z_cut: float) float[source]
Area of the circular cap of radius
Rbelow heightz_cut.
- plot_angle_evolution(save_path: str | None = None) Figure[source]
Plot per-batch contact angle as a function of batch time.
- Parameters:
save_path (str, optional) – If provided, write the figure as standalone HTML.
- Returns:
Figure with one line per trajectory.
- Return type:
plotly.graph_objects.Figure
- plot_density_contour(result_index: int = 0, batch_index: int = 0, save_path: str | None = None) Figure[source]
Plot the density field of one batch with the fitted isoline.
- Parameters:
result_index (int, default 0) – Index into the results list (selects which trajectory).
batch_index (int, default 0) – Index of the batch within that trajectory.
save_path (str, optional) – If provided, write the figure as standalone HTML.
- Returns:
Filled contour of the density field plus dashed circle / wall isoline traces when available.
- Return type:
plotly.graph_objects.Figure
- summary() list[TrajectoryStats][source]
Return per-trajectory summary statistics.
- class wetting_angle_kit.visualization.DropletSlicePlotter(center: bool = True)[source]
Bases:
objectInteractive Plotly slice visualization with toggleable layers.
- plot_surface_points(oxygen_position: ndarray, surface_data: list[ndarray], popt: Sequence[float], wall_coords: ndarray, alpha: float | None = None, y_com: float | None = None, pbc_y: float | None = None, show_water: bool = True, show_surface: bool = True, show_circle: bool = True, show_tangent: bool = True, show_wall: bool = True) Any[source]
Create interactive Plotly figure for a single frame slice.
- Parameters:
oxygen_position (ndarray (N, 3)) – Oxygen atom coordinates.
surface_data (list[array]) – List of surface contours for selected slice.
popt (sequence) – Fitted circle parameters (x_center, z_center, radius, extra).
wall_coords (ndarray (M, 3)) – Wall particle coordinates.
alpha (float, optional) – Contact angle for tangent construction.
y_com (float, optional) – Mean y used for slicing; computed if None.
pbc_y (float, optional) – Y box length for periodic slicing.
show_water (bool) – Layer visibility toggles.
show_surface (bool) – Layer visibility toggles.
show_circle (bool) – Layer visibility toggles.
show_tangent (bool) – Layer visibility toggles.
show_wall (bool) – Layer visibility toggles.
- Returns:
Configured figure object (not saved).
- Return type:
plotly.graph_objects.Figure
- class wetting_angle_kit.visualization.SlicingTrajectoryPlotter(results: SlicingResults | Iterable[SlicingResults], labels: list[str] | None = None, time_steps: list[float] | None = None, time_unit: str = 'ps')[source]
Bases:
BaseTrajectoryPlotterPlot statistics derived from one or more
SlicingResults.- plot_angle_evolution(stat: str = 'median', per_frame_std: bool = True, running_mean: bool = True, timestep: float | None = None, time_unit: str | None = None, save_path: str | None = None) Figure[source]
Plot per-frame contact angle as a function of time.
- Parameters:
stat (str, default "median") – Per-frame aggregation across slices; one of
"median"or"mean".per_frame_std (bool, default True) – If True, draw a transparent ±σ band around the per-frame curve using the inter-slice spread within each frame — shows how noisy the contact angle estimate is at each instant.
running_mean (bool, default True) – If True, overlay the cumulative running mean of the per-frame central tendency as a dashed line, plus a transparent ±σ band of that cumulative series — shows how the time-averaged contact angle converges as more frames are accumulated.
timestep (float, optional) – Time between two consecutive frames in the trajectory file (i.e. dump interval × MD integration timestep). Applied uniformly to all trajectories, overriding the per-trajectory
time_stepspassed at construction. This is not the MD integration timestep — it is the spacing between frames as they appear in the dump.time_unit (str, optional) – Override for the x-axis time unit label. Defaults to the
time_unitpassed at construction.save_path (str, optional) – If provided, write the figure as standalone HTML.
- Returns:
Figure with one per-frame line per trajectory, optionally with an inter-slice ±σ band and/or a running mean line with its cumulative ±σ band.
- Return type:
plotly.graph_objects.Figure
- summary() list[TrajectoryStats][source]
Return per-trajectory summary statistics.
- class wetting_angle_kit.visualization.TrajectoryStats(method_name: str, label: str, mean_surface_area: float, mean_contact_angle: float, std_contact_angle: float, n_samples: int)[source]
Bases:
objectSummary statistics for a single contact-angle trajectory.
Replaces the legacy
output_stats.txtfile: instead of writing to disk, the plotter returns this dataclass so callers can both display the block (print(stats)) and reuse the underlying numbers programmatically.- method_name
Name of the analysis method (e.g.
"Slicing Analysis").- Type:
str
- label
Display label identifying the trajectory.
- Type:
str
- mean_surface_area
Mean droplet/cap surface area in Ų.
- Type:
float
- mean_contact_angle
Mean contact angle in degrees.
- Type:
float
- std_contact_angle
Standard deviation of the contact angle in degrees.
- Type:
float
- n_samples
Number of samples (frames or batches) contributing to the means.
- Type:
int