Skip to content

Loimis — Soil Texture Parser

What is the Loimis field?

The Loimis (loimis) field encodes the particle-size composition of a soil profile across up to four depth layers, all in a single compact string. It tells you what the soil is physically made of — how much sand, silt, clay, and rock fragment content there is — and how that composition changes with depth.

A simple example:

l40-70/ls₂30/+ls₂

This reads as three layers:

Layer Notation Meaning
1 l40-70 Sand (liiv), from 40 to 70 cm depth
2 ls₂30 Sandy clay (liivsavi) with moderate rock content, upper boundary at 30 cm
3 +ls₂ Sandy clay, continuing deeper

The notation system

Fine earth (peenes)

The dominant soil material in each layer is described by a texture code:

Code Estonian name International class
l liiv Sand
pl peenliiv Fine sand
sl saviliiv Loamy sand / clayey sand
ls liivsavi Sandy loam / sandy clay loam
s savi Clay
tsl tolmjas saviliiv Silt loam
tls tolmjas liivsavi Silty clay loam
dk liivakivirähk Sandy grit / sandstone debris

Rock skeleton (kores)

Coarse fragments mixed into the layer are described by a skeleton code:

Code Estonian name Description
r rähk Gravel (2–60 mm fragments)
v veeris Cobbles (>60 mm rounded fragments)
k kruus Coarse gravel / limestone fragments
kb killustik Angular rubble
p paas Limestone bedrock plate
lu lupjakivi Calcareous / carbonate material
ck kiltkivirähk Slate or schist debris

Organic material (turfs)

Code Estonian name Description
th toorhuumus Raw/mor humus horizon (> 10 cm)
t₁ / t1 turvas I aste Weakly decomposed peat
t₂ / t2 turvas II aste Moderately decomposed peat
t₃ / t3 turvas III aste Strongly decomposed peat

Amplitude subscripts ₁–₅

An amplitude subscript immediately after a code indicates abundance or intensity of that component. The scale runs from 1 (weak / minor presence) to 5 (very strong / dominant). For example:

  • r₁ls — slight gravel content in a sandy clay layer
  • r₃ls — substantial gravel in sandy clay
  • ls₂ — moderately gravelly sandy clay (peenes with skeleton modifier)

Depth ranges

Depth is written in centimetres, either as a single value or a range:

Notation Meaning
l40 Sand layer with upper boundary at 40 cm
l40-70 Sand layer from 40 to 70 cm
+ls₂ Sandy clay continues deeper (no explicit lower boundary)

The + prefix means deeper than the previous layer — no explicit depth given.

Carbonate flag

A + immediately before a component code (not a depth marker) means the material is calcareous (e.g. +ls = calcareous sandy clay). Context distinguishes this from the depth-continuation +.

Layer separator

Layers are separated by /. Up to four layers per polygon.


The 7-step parsing pipeline

Because the loimis notation is complex and the raw data contains many encoding errors, parsing proceeds through seven stages:

  1. Normalise and split — apply error-correction lookups, discard secondary siffer annotations, and split the string into individual layer tokens.
  2. Bracket fix — validate and remove parenthesised numeric artefacts in each token.
  3. Grammar test — try each of ten grammar variants (covering all possible orderings of kores, peenes, and turfs components) and produce a canonical normalised string.
  4. Reconstituate — reassemble the normalised layers into a clean slash-separated string.
  5. Visitor — apply a structured tree-walker to extract a nested dictionary of all soil constituents, their codes, amplitudes, carbonate flags, and depth ranges.
  6. Layer depths — read the depth information from the structured dictionary to determine the number of layers and the depth of each layer boundary.
  7. Texture fractions — look up each constituent code in the texture rules table to derive clay, silt, sand, and rock-fragment percentages, and map to international texture classes.

Output fields

Depth and layer summary (6 values)

Field Type Description
nlayers int Number of distinct texture layers in this profile (1–4)
ZMX float Total profile depth — deepest layer boundary (cm)
Z1 float Lower boundary of layer 1 (cm)
Z2 float Lower boundary of layer 2 (cm); 0 if fewer than 2 layers
Z3 float Lower boundary of layer 3 (cm); 0 if fewer than 3 layers
Z4 float Lower boundary of layer 4 (cm); 0 if fewer than 4 layers

Per-layer texture (×4 layers, 32 values + 1 diagnostic)

For each layer number n (1 to 4):

Field Type Description
EST_TXTn str Estonian texture code for this layer (e.g. sl, ls)
EST_CRSn str Coarse fraction type code (e.g. r, k, v); empty if no skeleton
LXTYPEn str International texture class: SAND, LOAM, CLAY, PEAT, GRAVELS, …
CLAYn float Clay fraction (0–100 %)
SILTn float Silt fraction (0–100 %)
SANDn float Sand fraction (0–100 %)
ROCKn float Rock / skeleton fragment fraction (0–100 %)
KARBn int Carbonate flag: 1 if any constituent in the layer is calcareous (+ prefix), 0 otherwise

Diagnostic fields

Field Type Description
parse_ok_l bool True if all layers were parsed successfully. Used in the map viewer error-review style together with parse_ok_s and parse_ok_h.
parse_info str Parse status: "successful", "empty_loimis", "partial_no_info", "parse_error"
has_no_info bool True if one or more layers could not be parsed
loimis_grammar dict Full structured parse result (stored in DB but excluded from map viewer popup)
loimis_search dict Internal search-parameter snapshot (stored in DB but excluded from map viewer popup)

NaN values in texture fractions

For gravel- or rock-dominated layers (LXTYPE = "GRAVELS"), the clay, silt, and sand fractions are NaN. The rock fragment content is recorded in ROCK instead. Guard for this when computing weighted averages.

Layers beyond the profile

Z2, Z3, Z4 are 0 (not NaN) when the profile has fewer layers. Always check nlayers before using these values.


Worked example

Raw field value: "sl60/r₁l"

Layer Token Meaning
1 sl60 Clayey sand (saviliiv), upper boundary at 60 cm
2 r₁l Sand with slight gravel content

Parsed output (selected fields):

nlayers=2, ZMX=60, Z1=60, Z2=0
EST_TXT1="sl", LXTYPE1="LOAM",  CLAY1=15, SILT1=20, SAND1=65, ROCK1=0, KARB1=0
EST_TXT2="l",  LXTYPE2="SAND",  CLAY2=4,  SILT2=6,  SAND2=90, ROCK2=5, KARB2=0