# GX-TXT Python Terrain Flow Test v1

Target: GX-TXT 0.9.8.10-dev-037 or later.

This package is deliberately **not** a Session Generator. The user creates and
operates the Session manually. The package contains only the source Dataset,
portable Dataset Metadata, and registered Python scripts used to test the public
GX-TXT scientific workflow.

## Test objective

Exercise this public-only chain:

raw family Dataset
-> Dataset Metadata read
-> Python polynomial Z fit
-> derived canonical Dataset publication
-> Dataset Metadata update
-> static 3D surface through PLOT_DATASET_API_v3
-> static 3D mesh through PLOT_DATASET_API_v3
-> persistent Session-owned Native 3D representation through build_scene
-> persistence verification after Session reopen

No script reads or writes GX-TXT private persistence files.

## Source Dataset

File:

    terrain_profiles_raw.csv

Rows: 891

Columns:

    x_m
    y_m
    z_m
    profile_id
    profile_y_m

There are 11 Y-profile family members, each containing 81 X samples.

The data are a deterministic noisy quartic synthetic terrain. Random seed:
20261004. Added Gaussian noise sigma: 0.6 m.

## Metadata

After importing the CSV as a canonical Dataset:

1. Open the Dataset Metadata editor.
2. Import `terrain_profiles_raw.metadata.txt`.
3. Review the merged values.
4. Press Save.

The first Python script intentionally requires these metadata. In particular it
uses metadata to resolve logical X/Y/Z/family columns, choose the polynomial
degree, choose output grid dimensions, assign physical units to the derived
Dataset, and choose the stable output Dataset ID.

This means metadata are part of the scientific data flow, not decorative text.

## Expected numerical result

The fitted model is total-degree 4. Using the supplied deterministic data, the
expected source-fit diagnostics are approximately:

    source rows       = 891
    family members    = 11
    coefficient count = 15
    RMSE               = 0.575563 m
    R^2                = 0.998712481

Small numerical differences in the last digits are acceptable.

The fitted output grid is:

    81 x 51 = 4131 rows

and is published as:

    tutorial.terrain_surface_fit

## Scripts

### 01_fit_publish_terrain.py

Select the raw imported family Dataset as `primary`.

Tests:

- Python Script Workspace;
- Analysis Source Dataset selection;
- DATASET_VARIABLE_SCHEMA_API_v3;
- DATASET_METADATA_API_v1/read;
- CANONICAL_DATASET_API_v2;
- NumPy numerical fitting;
- DATASET_PUBLICATION_API_v2;
- DATASET_METADATA_API_v1/update;
- SESSION_PERSISTENCE_API_v1.

Expected result:

    PASS TERRAIN_FIT_PUBLISH

Then inspect `tutorial.terrain_surface_fit` in Variables and open Metadata.
The derived metadata should contain `fit.rmse_m`, `fit.r2`,
`fit.coefficients`, variable IDs, units, source Dataset ID, and downstream
presentation hints.

### 02_render_surface_v3.py

Select `tutorial.terrain_surface_fit` as `primary`.

The script reads the **derived Dataset metadata** and obtains the X/Y/Z stable
Variable IDs, units, and requested plot type from it.

It creates a normal persistent `plot.dataset.xyz` Variant using:

    PLOT_DATASET_API_v3 / validate_spec
    PLOT_DATASET_API_v3 / create_plot
    PLOT_DATASET_API_v3 / render
    PLOT_DATASET_API_v3 / artifacts

Expected result:

    PASS TERRAIN_SURFACE_V3

The new 3D surface must appear normally in the GX-TXT Plots page.

### 03_build_mesh_scene_v3.py

Keep `tutorial.terrain_surface_fit` as `primary`.

The script again consumes the derived metadata, creates a second
`plot.dataset.xyz` Variant with `plot_type=mesh`, renders the static graph, and
then calls:

    PLOT_DATASET_API_v3 / build_scene

This creates an independent Session-owned Interactive Document and VTP
resources. The script verifies that the representation is present through
public interactive-document / plot / native-viewer identity APIs.

Expected result:

    PASS TERRAIN_MESH_SCENE_V3

After it completes, open the Native 3D Viewer manually and inspect the mesh.

### 04_verify_after_reopen.py

Close and reopen the Session first. Select `tutorial.terrain_surface_fit` as
`primary`, then run the script.

It verifies:

- derived Dataset Metadata survived reopen;
- `plot.dataset.xyz` Variants survived reopen;
- at least one persistent Plot Dataset interactive representation exists;
- the Interactive Document registry contains persistent documents.

Expected result:

    PASS TERRAIN_PERSISTENCE_VERIFY

## Architectural note

`build_scene` does not treat the PNG as geometry. The public Plot Dataset 3D
pipeline prepares the canonical XYZ Dataset, exports scientific VTP geometry,
creates a persistent Interactive Document, records Dataset identity/SHA-256 and
hands the representation to the Native 3D Viewer.

Therefore the final mesh is Session-owned presentation state with scientific
provenance rather than a private file produced by the test script.
