Migrating to 0.14¶
molpy 0.14 pairs with molcrafts-molrs 0.14 (>=0.14.0,<0.15). The two
release together and the native core ships first; a mismatched minor fails
at import, a different patch does not.
Everything below is spelled molpy. The native types you meet (Frame,
Block, Box, Atomistic, Trajectory, Element, the force-field model)
are re-exported by identity — mp.Frame is the native class — so there is
never a reason for application code to import the core directly.
Frame metadata¶
frame.metadata is gone. frame.meta is a mapping with the full dict
protocol:
frame.meta["title"] = "water box"
if "dt" in frame.meta:
dt = frame.meta["dt"]
for key, value in frame.meta.items():
...
There is no helper for reading or writing it; use it like a dict.
Field names¶
Column and component names come from molpy.core.fields as constants
(fields.X, fields.CHARGE, fields.RES_ID, …) plus the grouped tuples
fields.COORDS, fields.VELOCITIES, fields.DIPOLE, fields.QUAT,
fields.ENDPOINTS. Spell a canonical field through the constant, not as a
string literal you typed yourself.
Columns are typed and never zero-filled¶
graph.column(key) returns the column in the component's own dtype: a
float column is a zero-copy view that writes through to the graph, integer,
boolean and string columns are copies. A component that is missing on any
entity raises KeyError naming how many are missing — it is never read back
as 0. Use graph.validity(key) to find the holes, graph.get(handle, key)
for entity-wise reads, and graph.columns() to list what is registered.
atomistic.symbols and atomistic.xyz are built on these reads, so a
structure whose atoms only partly carry coordinates now raises instead of
placing the rest at the origin.
Neighbor lists¶
NeighborQuery.free(points, cutoff).query_self() (or .query(other_points))
returns a Neighbors table. Its columns are methods:
query_point_indices(), point_indices(), dist_sq(), disp()
(disp = r_j − r_i); n_pairs is an attribute.
Typifiers¶
molpy.typifier exports Typifier, Match, OPLSAATypifier,
MMFFTypifier, ClpTypifier, AmberToolsTypifier, SmartsTypifier,
LocalTypifier, TypeScope, ForceFieldParams and the region helpers.
Spellings that appeared in older docs (OplsTypifier, PairTypifier, a
Python UFFTypifier) do not exist. typify() returns a new graph.
MD, optimization and potentials¶
molpy.mdis the native MD surface re-exported verbatim.molpy.optimize.LBFGS(alsomolpy.LBFGS) is the native L-BFGS and returns(frame, OptReport). The Pythonoptimize.lbfgsmodule, theSoftPotentialand theOptimizer.run(inplace=...)wrapper are gone; compose typify →to_potentials→LBFGS(...).run(frame)yourself.molpy.potentialre-exports the kernels; nothing is defined in molpy.
Compute¶
- Shells are plain classes: construct with the measurement parameters, then
call the
computeverb with the data —RDF(n_bins=100, r_max=10.0).compute(frames, neighbors). Calling the object itself no longer works. molpy.compute.Computeis the molrsProtocol(molpy.compute.Compute is molrs.compute.Compute): a class conforms by definingcompute(...), never by subclassing. The molpy base class is gone, and with itdump()and the**configcatch-all that fed it.RadicalVoronoiandVoronoiIntegrationare now the molrs classes themselves, which keep their own verbs:RadicalVoronoi().build(...)andVoronoiIntegration().integrate(...).Workflowis removed: a DAG of analyses is a script, not a library object.ACFAnalyzerandSpectralAnalyzerare removed;IonicConductivityandDielectricSusceptibilitystream frames and no longer print progress (theprogress_everykey is gone).molpy.compute.spectraclasses are the native ones re-exported.
I/O¶
read_lammps_logreturns the nativeLammpsLog:log.runsholds oneLammpsRunperrun, whosethermois aLammpsThermowithcolumns(),rows(),["Temp"],"Step" in thermo,len(thermo)andto_dict(). The molpy dataclasses are gone.emit_all(...)is removed; loop overemit(name, ...).XMLForceFieldReader/OPLSAAForceFieldReadershells are removed; useread_xml_forcefield/read_opls_xml.from molpy.io import *exports only names that exist.
Builders¶
build_crystal(...)→Lattice(...).build(...).create_polydisperse_from_ir(ir)→ir.build()on aDistributionIR.get_forcefield_path(name)lives inmolpy.dataand returns aPath; themolpy.data.forcefieldcopy that returned a string is gone.GraphAssemblerraises on an unknown component map number instead of silently skipping it.
Verb table¶
One kind of transformation, one method name. Which family a method belongs to
is decided by what goes in and what comes out, not by what the class is called,
and 0.14 lands three renames that follow from that rule. Read graph below as
the molecular structure itself — the atoms plus the bonds between them, an
Atomistic — so a graph → graph transform reads a structure you already have
and hands back a rewritten copy, leaving the one you passed in untouched.
| 0.13 | 0.14 | Family |
|---|---|---|
GraphAssembler.assemble(world, selector) |
GraphAssembler.apply(world, selector) |
graph → graph: apply |
an analysis object called like a function, RDF(n_bins=100, r_max=10.0)(frames, neighbors) |
RDF(n_bins=100, r_max=10.0).compute(frames, neighbors) |
frames/arrays → result: compute |
molpy.pack — Packmol, Packer, Target, the *Constraint types |
removed; packing is molpack | targets → Frame: pack, and it now lives outside molpy |
apply is a rename only. The arguments keep their meaning — world is the
structure to edit, selector is the rule that decides which marked reaction
sites pair up — and so do the warning on an empty selection and the checks that
refuse overlapping edits or a net-charge change. The old name is gone outright:
there is no alias and no deprecation window. The point of the new spelling is
that the two other graph → graph entries already wore it:
StructureFinalizer.apply, which generates the angle and dihedral terms of a
finished structure, and VirtualSiteBuilder.apply, which adds virtual sites
(massless points that carry charge or polarizability but no mass). Reading any
of the three, you know the same contract holds: new structure out, input
untouched.
The compute row restates the § Compute rule above: an analysis class is
constructed with its measurement parameters and then asked for numbers through
compute — as with the radial distribution function (RDF), which measures how
the density of neighbours around an atom varies with distance. Packing, meaning
the placement of whole molecules into a simulation cell without overlaps, left
molpy altogether; § Packing below has the replacement.
What did not change: PolymerBuilder.build(topology) and its build_*
shortcuts. Those turn a recipe into a structure that did not exist before, which
is the build family, not the apply one.
Packing¶
The whole molpy.pack package is removed in 0.14 — the Packmol subprocess
wrapper, the Packer base class, Target, and the penalty constraints
(InsideBoxConstraint, OutsideBoxConstraint, InsideSphereConstraint,
OutsideSphereConstraint, MinDistanceConstraint). There is no shim and no
deprecation window: mp.pack raises AttributeError.
Packing is molpack
(pip install molcrafts-molpack), a separate optional package that molpy does
not depend on. Describe each species with a Target, attach a restraint —
molpack spells these *Restraint, e.g. InsideBoxRestraint, where molpy
spelled them *Constraint — and run the session with Molpack. The
Pack reference carries a worked example.
The deleted package had no callers: nothing in molpy, the docs, the examples, or the sibling MolCrafts packages imported it, so there is nothing to migrate beyond the import itself.
RDKit adapter¶
RDKitAdapter joins the two representations by the mp_id atom component
and RDKit atom property only. It no longer assigns id or atomic_num. An
RDKit atom with a negative mp_id becomes a new atom on the next
sync_to_internal(); an untagged RDKit atom is an error.
Removed without replacement¶
molpy.reacter, molpy.pack (packing is molpack, see above),
io.data.amber_prep, the moltemplate emit_all, the compute Workflow, the
test-data download step (fixtures are committed under tests/tests-data/).