Miroslav Simko <ms@iolabs.ch> 2026-09-02T09:14:20+02:00
Commit #22 ยท 7 snippets
README.md | 2 +- src/iolabs_point_cloud_segmentation_3d/_config_model.py | 7 ++++++- src/iolabs_point_cloud_segmentation_3d/cli.py | 4 +++- src/iolabs_point_cloud_segmentation_3d/config.py | 5 ++++- 4 files changed, 14 insertions(+), 4 deletions(-)
| 33 | LasSplitMode = Literal["none", "class", "instance"] | 33 | LasSplitMode = Literal["none", "class", "instance"] |
| 34 | 34 | ||
| 35 | 35 | ||
| 36 | class ConfigError(config_loader.ConfigError): | 36 | class ConfigError(config_loader.ConfigError): |
| 37 | """Raised when the seg3d config contains unsupported keys.""" | 37 | """Raised when the seg3d config is unreadable, unknown or out of range. |
| 38 | |||
| 39 | Covers malformed config JSON, unknown keys, values that are not valid | ||
| 40 | for their field type and values outside the declared `pydantic.Field` | ||
| 41 | bounds or rejected by a `Seg3dConfig` model validator. | ||
| 42 | """ | ||
| 38 | 43 | ||
| 39 | 44 | ||
| 40 | class Seg3dConfig(config_loader.ConfigModel): | 45 | class Seg3dConfig(config_loader.ConfigModel): |
| 41 | """Numeric thresholds for the fusion pipeline (metres unless stated). | 46 | """Numeric thresholds for the fusion pipeline (metres unless stated). |
| 82 | ) -> Seg3dConfig: | 82 | ) -> Seg3dConfig: |
| 83 | """Loads the packaged default with file and `--set` overrides applied. | 83 | """Loads the packaged default with file and `--set` overrides applied. |
| 84 | 84 | ||
| 85 | Args: | 85 | Args: |
| 86 | config_path: JSON file overlaid on the packaged default, or `None`. | 86 | config_path: JSON file read instead of the packaged default, or |
| 87 | `None`. It may be partial: keys it omits fall back to the | ||
| 88 | `Seg3dConfig` field defaults, which are pinned equal to the | ||
| 89 | packaged JSON by `tests/test_config.py`. | ||
| 87 | overrides: Flat `KEY=VALUE` overrides applied last (from repeatable | 90 | overrides: Flat `KEY=VALUE` overrides applied last (from repeatable |
| 88 | `--set`), or `None`. | 91 | `--set`), or `None`. |
| 89 | 92 | ||
| 90 | Returns: | 93 | Returns: |
| 95 | help="Tablecloth (TCS) ground masks root with segment_NNN " | 95 | help="Tablecloth (TCS) ground masks root with segment_NNN " |
| 96 | "subdirs of *_tablecloth_masks.npz files.") | 96 | "subdirs of *_tablecloth_masks.npz files.") |
| 97 | p.add_argument("--out", required=True, type=Path, help="Output root dir.") | 97 | p.add_argument("--out", required=True, type=Path, help="Output root dir.") |
| 98 | p.add_argument("--config", type=Path, default=None, | 98 | p.add_argument("--config", type=Path, default=None, |
| 99 | help="JSON file overlaying the packaged seg3d.default.json.") | 99 | help="JSON config read instead of the packaged " |
| 100 | "seg3d.default.json; omitted keys keep their " | ||
| 101 | "defaults.") | ||
| 100 | p.add_argument( | 102 | p.add_argument( |
| 101 | "--set", dest="set_overrides", action="append", metavar="KEY=VALUE", | 103 | "--set", dest="set_overrides", action="append", metavar="KEY=VALUE", |
| 102 | help="Override a single config value (repeatable), e.g. --set " | 104 | help="Override a single config value (repeatable), e.g. --set " |
| 103 | "line_z_gate_m=0.7.", | 105 | "line_z_gate_m=0.7.", |
| 154 | 154 | ||
| 155 | Override without editing the packaged default: | 155 | Override without editing the packaged default: |
| 156 | 156 | ||
| 157 | ```bash | 157 | ```bash |
| 158 | # JSON file overlaying the defaults | 158 | # JSON file read instead of the packaged default (omitted keys keep their defaults) |
| 159 | uv run seg3d-fuse ... --config my_overrides.json | 159 | uv run seg3d-fuse ... --config my_overrides.json |
| 160 | # or individual repeatable key=value overrides | 160 | # or individual repeatable key=value overrides |
| 161 | uv run seg3d-fuse ... --set line_z_gate_m=0.7 --set voxel_size_m=0.05 | 161 | uv run seg3d-fuse ... --set line_z_gate_m=0.7 --set voxel_size_m=0.05 |
| 162 | ``` | 162 | ``` |
| 33 | LasSplitMode = Literal["none", "class", "instance"] | 33 | LasSplitMode = Literal["none", "class", "instance"] |
| 34 | 34 | ||
| 35 | 35 | ||
| 36 | class ConfigError(config_loader.ConfigError): | 36 | class ConfigError(config_loader.ConfigError): |
| 37 | """Raised when the seg3d config contains unsupported keys.""" | 37 | """Raised when the seg3d config is unreadable, unknown or out of range. |
| 38 | |||
| 39 | Covers malformed config JSON, unknown keys, values that are not valid | ||
| 40 | for their field type and values outside the declared `pydantic.Field` | ||
| 41 | bounds or rejected by a `Seg3dConfig` model validator. | ||
| 42 | """ | ||
| 38 | 43 | ||
| 39 | 44 | ||
| 40 | class Seg3dConfig(config_loader.ConfigModel): | 45 | class Seg3dConfig(config_loader.ConfigModel): |
| 41 | """Numeric thresholds for the fusion pipeline (metres unless stated). | 46 | """Numeric thresholds for the fusion pipeline (metres unless stated). |
| 95 | help="Tablecloth (TCS) ground masks root with segment_NNN " | 95 | help="Tablecloth (TCS) ground masks root with segment_NNN " |
| 96 | "subdirs of *_tablecloth_masks.npz files.") | 96 | "subdirs of *_tablecloth_masks.npz files.") |
| 97 | p.add_argument("--out", required=True, type=Path, help="Output root dir.") | 97 | p.add_argument("--out", required=True, type=Path, help="Output root dir.") |
| 98 | p.add_argument("--config", type=Path, default=None, | 98 | p.add_argument("--config", type=Path, default=None, |
| 99 | help="JSON file overlaying the packaged seg3d.default.json.") | 99 | help="JSON config read instead of the packaged " |
| 100 | "seg3d.default.json; omitted keys keep their " | ||
| 101 | "defaults.") | ||
| 100 | p.add_argument( | 102 | p.add_argument( |
| 101 | "--set", dest="set_overrides", action="append", metavar="KEY=VALUE", | 103 | "--set", dest="set_overrides", action="append", metavar="KEY=VALUE", |
| 102 | help="Override a single config value (repeatable), e.g. --set " | 104 | help="Override a single config value (repeatable), e.g. --set " |
| 103 | "line_z_gate_m=0.7.", | 105 | "line_z_gate_m=0.7.", |
| 82 | ) -> Seg3dConfig: | 82 | ) -> Seg3dConfig: |
| 83 | """Loads the packaged default with file and `--set` overrides applied. | 83 | """Loads the packaged default with file and `--set` overrides applied. |
| 84 | 84 | ||
| 85 | Args: | 85 | Args: |
| 86 | config_path: JSON file overlaid on the packaged default, or `None`. | 86 | config_path: JSON file read instead of the packaged default, or |
| 87 | `None`. It may be partial: keys it omits fall back to the | ||
| 88 | `Seg3dConfig` field defaults, which are pinned equal to the | ||
| 89 | packaged JSON by `tests/test_config.py`. | ||
| 87 | overrides: Flat `KEY=VALUE` overrides applied last (from repeatable | 90 | overrides: Flat `KEY=VALUE` overrides applied last (from repeatable |
| 88 | `--set`), or `None`. | 91 | `--set`), or `None`. |
| 89 | 92 | ||
| 90 | Returns: | 93 | Returns: |
nullconfig sections fall back to section defaults (pre-migration behaviour), re-validation instead ofmodel_copy(update=), doc/test parity with the packaged JSON.