Skip to content

Read XN columns as numeric

Available in: Python (the xn= knob is a frame-materialisation option; on other surfaces XN columns read as text and cast in SQL)

AGS XN headings are numeric-or-text on disk — laterite reads them as String by default. Pass xn="numeric" to coerce them to Float64 at the door.

# what this shows: querying the AGS dictionary registry, and reading XN-typed columns as real numbers.
import laterite
from laterite.registry import child_groups, inherited_key_names

# The registry is the in-memory AGS group graph. child_groups returns GroupDescriptor
# objects; list their .code to see every group that hangs off LOCA.
loca_children = child_groups("LOCA")
print("LOCA children:", len(loca_children))
print("first few:", [g.code for g in loca_children[:3]])

# inherited_key_names walks the parent chain and returns the KEY headings a group
# inherits — SAMP samples are located by their parent borehole's LOCA_ID.
print("SAMP inherits:", inherited_key_names("SAMP"))

# AGS "XN" headings are numeric-but-text on disk. xn="numeric" casts them on read,
# so LLPL_PL (plastic limit) comes back as Float64 instead of String.
ags = laterite.read("examples/sample_site.ags", xn="numeric")
print("LLPL_PL dtype:", ags["LLPL"]["LLPL_PL"].dtype)

assert len(loca_children) == 50
assert inherited_key_names("SAMP") == {"LOCA_ID"}
assert str(ags["LLPL"]["LLPL_PL"].dtype) == "Float64"
LOCA children: 50
first few: ['BKFL', 'CDIA', 'CHIS']
SAMP inherits: {'LOCA_ID'}
LLPL_PL dtype: Float64

XN is the AGS type for a column that usually holds a number but is allowed to carry a non-numeric token (e.g. a free-text remark or a < censored value), so the safe default is to keep it as text — nothing is lost or silently dropped. The xn="numeric" opt-in says "I want these as real numbers": here LLPL_PL (plastic limit) comes back as Float64 instead of String, so it sorts and averages without a per-column .cast().

Coercion is whole-column. If an XN column in your file carries a genuine non-numeric token, xn="numeric" will surface it (rather than quietly producing text) — keep the default String read for files where that's expected.

The same example also queries the registrychild_groups("LOCA") and inherited_key_names("SAMP") walk the in-memory AGS group graph. That surface is covered in its own recipe.

See also: Explore the registry · Born-typed reads