build_tools.syllable_walk_tui.services.terrain_weights

Terrain axis weight configuration.

This module defines the weights used to compute phonaesthetic terrain scores from feature saturation percentages. Weights are configurable to allow calibration based on different phonaesthetic models or user preferences.

Design Philosophy:
  • Weights should reflect phonaesthetic reality, not be tuned to produce desired results for specific corpora

  • Each weight should have a defensible rationale independent of test outcomes

  • Users can override defaults to match their own phonaesthetic intuitions

  • All weights are documented with their phonaesthetic justification

The Three Axes:
  • Shape (Round ↔ Jagged): Bouba/Kiki dimension - perceptual “softness” vs “hardness”

  • Craft (Flowing ↔ Worked): Sung/Forged dimension - ease vs effort of articulation

  • Space (Open ↔ Dense): Valley/Workshop dimension - acoustic spaciousness vs compression

Weight Conventions:
  • Negative weights pull toward the first pole (Round, Flowing, Open)

  • Positive weights pull toward the second pole (Jagged, Worked, Dense)

  • Magnitude indicates strength of contribution (0.0-1.0 typical range)

  • Weights can exceed 1.0 for features with outsized phonaesthetic impact

References

  • Ramachandran & Hubbard (2001): Bouba/Kiki effect

  • Köhler (1929): Original “maluma/takete” experiments

  • See _working/sfa_shapes_terrain_map.md for calibration notes

Attributes

DEFAULT_TERRAIN_WEIGHTS

Classes

AxisWeights

Weights for a single terrain axis.

TerrainWeights

Complete terrain weight configuration for all three axes.

Functions

create_default_shape_weights()

Create default weights for Shape axis (Round ↔ Jagged).

create_default_craft_weights()

Create default weights for Craft axis (Flowing ↔ Worked).

create_default_space_weights()

Create default weights for Space axis (Open ↔ Dense).

create_default_terrain_weights()

Create complete terrain weights with all defaults.

load_terrain_weights([config_path])

Load terrain weights from configuration or use defaults.

Module Contents

class build_tools.syllable_walk_tui.services.terrain_weights.AxisWeights[source]

Weights for a single terrain axis.

Each weight maps a feature name to its contribution to the axis score. Negative weights pull toward the low pole, positive toward the high pole.

weights: dict[str, float]
get(feature, default=0.0)[source]

Get weight for a feature, returning default if not defined.

set(feature, value)[source]

Set weight for a feature.

items()[source]

Iterate over (feature, weight) pairs.

feature_names()[source]

Get ordered list of feature names.

class build_tools.syllable_walk_tui.services.terrain_weights.TerrainWeights[source]

Complete terrain weight configuration for all three axes.

This is the primary configuration interface. Users can: 1. Use defaults (well-documented phonaesthetic rationale) 2. Override specific weights 3. Load entirely custom configurations

shape

Weights for Shape axis (Round ↔ Jagged)

craft

Weights for Craft axis (Flowing ↔ Worked)

space

Weights for Space axis (Open ↔ Dense)

shape: AxisWeights
craft: AxisWeights
space: AxisWeights
build_tools.syllable_walk_tui.services.terrain_weights.create_default_shape_weights()[source]

Create default weights for Shape axis (Round ↔ Jagged).

The Shape axis captures the Bouba/Kiki dimension — the perceptual “roundness” or “jaggedness” of sounds. This is one of the most robust findings in phonaesthetics research.

Phonaesthetic Rationale:

TOWARD ROUND (negative weights):
contains_liquid (-0.8):

Liquids (l, r) have smooth, continuous airflow. The tongue creates no hard obstruction. Perceptually “flowing” and “soft”. Weight: -0.8 (strong but not dominant, as liquids are common)

contains_nasal (-0.6):

Nasals (m, n, ng) have resonant, humming quality. No hard closure release. Perceptually “warm” and “rounded”. Weight: -0.6 (moderate, nasals are soft but less defining than liquids)

ends_with_vowel (-0.6):

Vowel endings create open, unobstructed syllable close. No abrupt stop. Perceptually “open” and “soft”. Weight: -0.6 (moderate contribution to roundness)

TOWARD JAGGED (positive weights):
contains_plosive (+0.6):

Plosives (p, b, t, d, k, g) have complete airflow obstruction followed by sudden release. Perceptually “hard” and “abrupt”. Weight: +0.6 (reduced from 1.0 to prevent English saturation, as plosives are extremely common in all languages)

ends_with_stop (+1.0):

Stop codas create hard syllable boundaries. The syllable “cuts off” rather than fading. Perceptually very “sharp”. Weight: +1.0 (strong signal of jaggedness)

starts_with_heavy_cluster (+0.8):

Heavy clusters (3+ consonants: “str”, “spr”) require complex articulation. Multiple obstructions in sequence. Perceptually “effortful” and “jagged”. Weight: +0.8 (distinctive marker, but relatively rare)

contains_fricative (+0.3):

Fricatives (f, s, sh, th) have turbulent airflow but no complete obstruction. Add “texture” and slight edge. Not as hard as plosives. Weight: +0.3 (mild contribution, more textural than defining)

Returns:

AxisWeights configured for Shape axis

Return type:

AxisWeights

build_tools.syllable_walk_tui.services.terrain_weights.create_default_craft_weights()[source]

Create default weights for Craft axis (Flowing ↔ Worked).

The Craft axis captures articulatory effort — whether sounds feel “sung” (easy, flowing) or “forged” (effortful, constructed).

Phonaesthetic Rationale:

TOWARD FLOWING (negative weights):
ends_with_vowel (-1.0):

Vowel endings allow breath to continue naturally. No effort to close the syllable. Like singing — notes sustain and connect. Weight: -1.0 (primary marker of flowing character)

starts_with_vowel (-0.8):

Vowel onsets require no articulatory preparation. Sound begins immediately with open vocal tract. Effortless initiation. Weight: -0.8 (strong contributor to ease)

long_vowel (-0.6):

Long vowels sustain without consonant interruption. The sound “dwells” rather than moving quickly. Singing vs speaking. Weight: -0.6 (moderate, as vowel length varies by context)

TOWARD WORKED (positive weights):
starts_with_cluster (+1.0):

Consonant clusters require coordinated articulation of multiple obstructions before the vowel. Effortful onset. Like forging — hammering multiple strikes. Weight: +1.0 (primary marker of worked character)

starts_with_heavy_cluster (+0.8):

Heavy clusters (3+ consonants) amplify the effort further. Maximum articulatory complexity at syllable onset. Weight: +0.8 (intensifier for already-worked onsets)

short_vowel (+0.4):

Short vowels move quickly to the next consonant. Less dwell time. Clipped, efficient, constructed feel. Weight: +0.4 (mild contribution, very common feature)

Returns:

AxisWeights configured for Craft axis

Return type:

AxisWeights

build_tools.syllable_walk_tui.services.terrain_weights.create_default_space_weights()[source]

Create default weights for Space axis (Open ↔ Dense).

The Space axis captures acoustic “spaciousness” — whether the syllable inventory feels airy and expansive or compact and closed.

Phonaesthetic Rationale:

TOWARD OPEN (negative weights):
ends_with_vowel (-1.0):

Vowel endings leave acoustic space after the syllable. Sound can “breathe” and resonate. Valley-like openness. Weight: -1.0 (primary marker of openness)

starts_with_vowel (-0.8):

Vowel onsets create immediate acoustic space. No consonant barrier at the beginning. Open initiation. Weight: -0.8 (strong contributor)

long_vowel (-0.6):

Long vowels expand the acoustic duration. More time in open vocal tract configuration. Spacious sound. Weight: -0.6 (moderate, duration contributes to spaciousness)

TOWARD DENSE (positive weights):
short_vowel (+0.6):

Short vowels compress the acoustic core. Less resonant space. Compact, efficient syllable structure. Weight: +0.6 (moderate-strong, common feature)

ends_with_stop (+0.6):

Stop codas close off the acoustic space abruptly. No resonance after the syllable. Compact, bounded. Weight: +0.6 (contributes to closure/density)

ends_with_nasal (+0.4):

Nasal codas partially close the oral cavity. Less open than vowel endings, but resonant through the nose. Moderate closure. Weight: +0.4 (mild density contribution)

Returns:

AxisWeights configured for Space axis

Return type:

AxisWeights

build_tools.syllable_walk_tui.services.terrain_weights.create_default_terrain_weights()[source]

Create complete terrain weights with all defaults.

This is the primary entry point for getting default configuration. All weights are documented with phonaesthetic rationale in their respective creation functions.

Returns:

TerrainWeights with all three axes configured to defaults

Return type:

TerrainWeights

build_tools.syllable_walk_tui.services.terrain_weights.load_terrain_weights(config_path=None)[source]

Load terrain weights from configuration or use defaults.

Currently returns defaults. Future versions will support loading from a TOML configuration file for user customization.

Parameters:

config_path (pathlib.Path | None) – Optional path to TOML config file (not yet implemented)

Returns:

TerrainWeights configuration

Return type:

TerrainWeights

build_tools.syllable_walk_tui.services.terrain_weights.DEFAULT_TERRAIN_WEIGHTS