For researchers
Search nets by coordination sequence
Identify a net from numbers you computed yourself, from the browser or from a script.
You have a periodic structure and you have computed its coordination sequences. You want to know which known net it is — or whether it is one at all.
If you have the topology itself, ask the other question instead.
Which net is this? takes a .mfpx or .cgd and answers
by canonical Systre key, which is an identification: yes, this is pcu, or no,
this collection does not hold it. A coordination-sequence search cannot do that
— two different nets can carry the same sequences — and this page is the right
tool only when sequences are what you have.
From the browser
On Search topologies, open Symmetry, transitivity and coordination sequences and use the Coordination sequences box.
One sequence per line, one line per crystallographically distinct vertex. Numbers separated by spaces or commas:
4 12 24 42 64
4 10 20 38 60
A net matches when every sequence you give can be assigned a vertex class of its own: three sequences require three distinct kinds of vertex, and giving the same sequence twice asks for two vertices that carry it, not one. Matching is done on as many shells as you supply, so four or five numbers per vertex is normally enough — and giving more shells than you are confident about will lose you the right answer rather than confirm it.
What the sequences are matched against depends on the record. A net that arrived with a MOF+ deposit is matched on the sequences that deposit supplied. The 634 records that came from the RCSR archive alone carry none — the archive has no coordination-sequence field at all — and are matched on the sequences this site computed from their own graph. Each result says which of the two it was matched on, because they do not have the same warrant. Before the computed sequences were searched, this form covered 2443 of the 3077 records and said so nowhere.
Vertex symbols, if you have them, go in the box beside it, one per line. They are combined with the sequences: a net must satisfy both.
Two things about that box. It matches the stored symbols, in the MOF+
convention — shortest cycle per angle, 6(2).6(2).6(2) style — not the RCSR
ring vertex symbol, which is a different quantity and is shown on a record under
its own key. And 42 stored rows are excluded from matching because the source
cut the string off at exactly 512 characters: a truncated string is not matched
as though it were a whole symbol. Those 42 do carry a symbol recomputed from the
net's own graph on the record itself. Six further rows — lcw's, where the
source wrote a placeholder — store no string at all, so there is nothing there to
exclude; the record serves them a ring symbol and a stated reason why no cycle
symbol exists for them.
A sequence search ignores the name, coordination and transitivity fields above it.
From a script, over REST
import requests
response = requests.post(
"https://mofplus.org/api/v1/nets/search-cs",
json={
"cs": [[4, 12, 24, 42, 64], [4, 10, 20, 38, 60]],
"vs": [],
"filter_catenated": True,
},
)
print(response.json()["results"])
No credentials needed. filter_catenated drops interpenetrated nets, whose
names carry a -c suffix; leave it false if you want them.
The response carries more than results. establishes is the sentence saying
what a match does and does not show; sequence_sources counts how many matches
rest on a source's own sequences and how many on computed ones; matched says
it per record. If what you want is an identification rather than a shortlist,
identity_endpoint names the endpoint that gives one:
with open("mynet.mfpx", "rb") as handle:
answer = requests.post(
"https://mofplus.org/api/v1/nets/identify", files={"file": handle}
)
print(answer.status_code, answer.json()["outcome"])
Read response.json()["held_pending_licence"] as well as ["results"]. It
counts nets that carried your sequence but are held pending licence
verification — a record whose licence could not be established is not listed
and answers 403 at its own URI. A match you cannot see is not the same answer as
no match.
On this collection the count is 0 for two reasons at once. No record is held
at all today: the RCSR terms were confirmed on 2026-09-09 and all 3077 are
served. And even when 634 were held, this particular search could never report
one, because a record built from the RCSR archive alone carries no coordination
sequence to match. Read a zero as "no held record was ruled out", not as
"nothing is being withheld". The
API reference has what a held record does when you fetch
it directly.
From the mofplus client
The installed client reaches the same code through the older XML-RPC endpoint:
from mofplus import user_api
api = user_api()
names = api.search_cs([[4, 12, 24, 42, 64], [4, 10, 20, 38, 60]], [])
user_api.search_cs filters catenated nets client-side by default; pass
cfilter=False to keep them.
A caveat about the other fields
Neither source this site ingests states a spacegroup or a transitivity, and
neither is inferred from a deposited cell. Both are instead computed from each
net's own graph — the symmetry of its maximum-symmetry embedding, and the
number of kinds of vertex and edge — so a filter on spacegroup or on p/q now
reaches most of the collection: 2806 of 3077 records carry those values.
271 do not, and a filter can neither match nor rule those out, so they drop from the results. The reasons are worth knowing, because each is an answer rather than a gap.
200 of the 271 are 2-periodic, and those are not missing a value at all:
they are layers rather than frameworks, so their symmetry is one of the 17
plane groups, and it lives in its own pair of columns with its own filter.
Search plane_group_number (1–17) for them — spacegroup_number will never
return one, because 11 in that numbering means P21/m and 11 in this one means
p4mm, and the two are kept apart so that neither number can ever be handed to
you under the other's name. They have no p or q either.
The remaining 71 are a genuine blank: 38 are several nets sharing one repeat unit, which no single group describes; 14 are interpenetrated arrays, where the group of one copy is not the group of the array; 18 could not be resolved at all (Systre refuses a ladder or a structure with colliding nodes, and the largest nets exhausted their time budget); and one record has no graph on either basis. The computed-topology block on each record says which applies.
r and s are a different matter: nothing computes them. They count the
faces and tiles of a tiling, and no tiling analysis runs here, so a search on
either can only ever match the single curated record that carries them. Leave
them as wildcards.
That is a measured limit rather than an unfinished job. The library this site
runs Systre from is the whole Gavrog project, tilings included, and it was tried:
for a 3-periodic net it has no route from a net to a tiling at all, and for
the 200 2-periodic nets it has one that works perfectly — but a plane tiling
has faces and no tiles, so its transitivity is a triple and does not fit an
r/s pair. docs/reports/tiling-spike-2026-09-12.md has the evidence.
The search says so wherever it applies: it reports how many nets it set aside
for want of the data, and the REST response carries the same number as
excluded_for_missing_data. Treat a filtered count as a statement about the
nets and about the metadata, and clear the field if you want the full
candidate list.
Coordination numbers and coordination sequences come from the deposited
topology, so every net with a deposit has them — 2443 of the 3077. The 634
RCSR-only records store none at all, and 19 deposited nets (raf and rag
among them) store no sequence upstream; their vertices carry an empty list,
never a computed stand-in, and this search matches the stored values only.
Those 997 vertex rows do now carry a sequence walked from the net's own graph,
served on the record as coordination_sequence_computed beside the empty
stored one — so a net this search cannot reach may still be identifiable by
opening its record. That the search does not reach it is a statement about the
sources rather than about the nets.
When nothing matches
- Drop the last shell or two. A single wrong number at shell five eliminates every candidate.
- Check you are searching distinct vertices, not every vertex in the cell. Symmetry-equivalent vertices have identical sequences; listing them all is harmless, but listing a vertex you thought was distinct and is not can over-constrain the search.
- Do not read a zero held count as "nothing withheld". Nothing is held today, and even a held record could not be reported here: a record built from the RCSR archive alone carries no coordination sequence, so this search can never match one. A net whose sequence is nowhere in our sources is not here to be found at all — see Licensing.
- Try one vertex at a time. If each sequence has candidates alone but the combination has none, your structure may be a net not yet in the database — which is worth depositing.