From a structure to a mesh¶
Stages 2 to 6 turn the aligned structure of stage 1 into a gated mesh. Stage 2 smears the atoms into a 3D density map. Stage 3 averages that map around the axis into an (r, z) map. Stage 4 draws the pore's outline from it, stage 5 builds the membrane and reservoirs around the outline, and stage 6 meshes the result. Structures and trajectories covers stage 1, and example 06 runs every stage on a PDB entry.
$ nanopnp run case.yaml --store store --run-dir run --upto mesh
--upto mesh stops before anything is solved. Each stage is cached in the store, so changing a
key re-runs only the stages downstream of it. nanopnp stage <name> case.yaml runs one stage, and
what it needs upstream, and prints its artefact.
This page says what each stage does and which key steers it. The formulas, thresholds and their derivations are in the specification: §5.2 lists the stages, §5.2.1 the contour's conditioning and gate, §5.2.2 the mesh sizes, and the NOTEs of §5.3.1 the case keys. Measurements on ClyA are in the knowledge base, ClyA geometry and charge, §1.3 and §1.4.
The case keys¶
A structure: case may carry a geometry: block. Every key has a default, and the defaults are
the settings of the published ClyA model.
geometry:
density: {grid_spacing_nm: 0.05, kernel: gaussian_vdw, sharpness: 0.93} # stage 2
contour: {isolevel: 0.25, smoothing: taubin, simplify_tol_nm: 0.02} # stage 4
membrane: {thickness_nm: 2.8, centre_z_nm: 0.0} # stage 5
reservoir: {radius_nm: 250.0} # stage 5
numerics:
mesh: {backend: netgen, wall_h_nm: auto, size_scale: 1.0} # stage 6
No gate threshold is a case key. The thresholds are constants of the code, recorded in each artefact's key, so two runs that passed the same gates can be told apart from two that did not.
Stage 2: the density map¶
Each atom becomes a Gaussian whose width is its van der Waals radius times sharpness. The radius
comes from the CHARMM set that PDB2PQR ships, by residue and atom name, and an atom the set does not
name is refused, naming its chain, residue and atom. There is no fallback by element, because a
guessed radius makes a plausible wrong wall. The atoms of one frame are combined as a probability
that at least one is present, so the map runs from 0 in the solvent to 1 inside the protein. With
a trajectory, the frames' maps are averaged.
grid_spacing_nm sets the grid, between 0.025 and 0.05 nm (FR-04). Its nodes sit at whole
multiples of the spacing in the stage-1 frame, so the axis is a column of nodes. The map must be
finite and between 0 and 1, or the run stops naming the voxel.
Stage 3: the average around the axis¶
Stage 3 has no keys of its own: the n it averages over is the point group's. It averages the map over the n rotated copies of the assembly, then around the axis, into an (r, z) map. The averaging is exact, so no bin is interpolated.
It also reports how far the structure is from its own symmetry, as two variances around the axis: that of the n-fold average, and that of the map without it. Their difference is the part of the structure that is not n-fold symmetric. Neither is gated, because no threshold is specified. Read them from the summary:
$ nanopnp stage symmetry case.yaml --store store --json
maximum gives each variance's largest value and where it is. unresolved_radius_nm is the
radius below which the grid is too coarse to resolve any n-fold variation, so the variances there
are recorded as unresolved rather than as zero.
Stage 4: the contour¶
Stage 4 draws the pore wall as the contour of the (r, z) map at isolevel, 0.25 by default. It
then conditions the loop: a closing and an opening by a disc of radius twice the grid spacing remove
gaps and fins too thin to mesh, Taubin smoothing follows when smoothing: taubin, the loop is
simplified to within simplify_tol_nm, which must be below the grid spacing, and vertices closer
than the spacing are removed.
The loop is then gated on the criteria of §5.2.1: it must be simple, its vertices spaced and its features wide enough to mesh, and it must stay clear of the axis. Its radius is also checked against the largest sphere that fits on the axis between the atoms, frame by frame. The contour may cut into that sphere by no more than the grid spacing, and may stand no more than 1.5 nm outside it. A failure stops the run, naming the criterion, its value, the threshold and where on the loop it failed.
What stage 4 produces is a pore profile: a nanopnp/profile/v0.5 document with provenance.source:
pipeline, in the stage-1 frame. It is the same kind of document as the reference fixture, and it
can be exported and supplied to another case (see Supplying a profile).
Stage 5: the region¶
Registering the membrane¶
The density map has no bilayer, so stage 5 adds one, defined analytically in (r, z).
geometry.membrane.centre_z_nm is the height of the bilayer's centre on the stage-1 frame's axial
coordinate, which is the structure file's own. Stage 5 subtracts it from every z, so the model
frame has the bilayer centred at z = 0.
Choosing it is part of preparing the structure, because it says where the protein sits in the membrane. For ClyA, nanopnp's validation places the C-alpha centroid of residues 8 to 292 where the molecular-dynamics structure of the published model has it (§7.4, the NOTE on VAL-05). Example 06 does the same while preparing the file, so its cases keep the default of 0. For your own pore, take it from a membrane-embedded simulation, from the hydrophobic belt of the structure, or from a database of membrane-protein orientations, and record where it came from.
membrane.thickness_nm is the bilayer's thickness, and reservoir.radius_nm the radius of the
half-disc of electrolyte around the pore. Stage 5 fits the membrane's inner edge to the outer
surface of the profile, assembles the electrolyte, protein and membrane domains, and names every
boundary. It gates the junction where the membrane meets the protein, so neither a gap nor an
overlap is left there.
charge.exclusion_offset_nm, off by default, adds an ion-exclusion shell here: the profile offset
outward by that distance, meshed as an exclusion material that ions cannot enter, with the wall on
its outer surface. It is one of the two FR-15 switches, and From a structure to a
charge covers both.
Stage 6: the mesh¶
Stage 6 meshes the region under the size table of §5.2.2, with netgen by default or Gmsh on request (see Meshes).
numerics.mesh.wall_h_nm sets the element size on the pore wall. auto takes it from the Debye
length of the case's electrolyte, capped at the published model's wall size, so two cases with
different concentrations can get different meshes. size_scale multiplies every size in the
table, the wall's included, which is how a mesh-convergence study is run as a sweep.
The mesh then passes the gates every mesh does (Meshes), plus one of its own: the wall's segments must come out near the size asked for. A generated mesh is filed under its recipe, the region and the sizes, and its content hash is recorded beside that key. The manifest records the mesh a solve actually read.
Supplying a profile¶
A case can skip stages 1 to 4 and start from a profile document:
schema: nanopnp/case/v0.5
name: from-profile
inputs:
profile: {path: contour.profile.yaml}
electrolyte: ...
There is no structure: section, because a stage whose output is supplied does not run, and
neither does anything upstream of it. Stage 5 applies geometry.membrane.centre_z_nm to the
supplied profile exactly as to stage 4's. The run records the file by its SHA-256 under the
manifest's inputs.files, and the region and mesh are filed under new keys, since their input
changed. The same profile meshes to the same mesh, which example 06 asserts.
Editing the contour by hand¶
A contour may need a correction the pipeline cannot make: a loop around a flexible region that the
density does not resolve, or one stage 4 refuses. There are two routes, and both produce a profile
document that enters a run through inputs.profile.
The Geometry tab of the desktop shell. Drag, add and delete vertices on the contour, check the
edit against the §5.2.1 criteria, and save it. The shell writes the edited profile and a derived
case that uses it in place of the structure. It re-derives the profile's measurements and marks
it provenance.source: hand-edit. See Desktop shell.
A profile document edited as text. Export stage 4's profile, edit its vertices, and supply
it through inputs.profile. The document's provenance block records measurements of its own
polygon: vertex_count, min_vertex_spacing_nm, min_feature_size_nm and signed_area_nm2.
The loader checks each against the vertices. A vertex moved without them being updated is refused,
and nanopnp run exits 3 with a message such as:
provenance.signed_area_nm2 is <recorded> but these vertices give <measured>; the provenance block
does not describe this polygon
So re-derive all four after editing, and set provenance.source to hand-edit, as the shell does.
The loader does not check the label, so keeping it honest is up to you: a profile that says
pipeline claims stage 4 drew it. Either way, the edited profile is then gated like any supplied
profile, by stages 5 and 6. The Geometry tab re-derives the measurements for you, which is the
reason to prefer it.
Exporting what the stages store¶
nanopnp stage <name> case.yaml --export PATH runs the stage, from the store where it can, and
writes its artefact in the format the suffix of PATH names. The path is an output location and
changes no key. A stage or suffix it does not write is refused before anything runs, and a failed
write leaves no file.
| Stage | Suffix | Writes |
|---|---|---|
structure |
.pdb |
the aligned ensemble's first frame, with a .dcd of every frame beside it, in ångströms |
density |
.dx, .ccp4, .mrc, .map |
the 3D map as OpenDX or CCP4/MRC, in ångströms, for a molecular viewer |
density |
.npz |
the stored map, nanopnp's own format, in nm |
symmetry |
.npz |
the stored (r, z) average and its two variances, in nm |
contour |
.yaml |
the stored profile document, byte for byte |
mesh |
.msh |
the stored Gmsh MSH 4.1 mesh, byte for byte |
The 3D files are in ångströms because that is the unit molecular viewers read, and the CCP4/MRC
format defines its cell in ångströms. A map exported this way sits on the structure exported beside
it. Inside nanopnp, and in its own .npz files, lengths stay in nm (the IF-05 NOTE on length
units, §3.1). The profile and the mesh are copied byte for byte, so the file you hold has the hash
the store records.