// Synthetic sensor measurements with explicit whole-column source units.
// Requires the updated native development runtime with unit-aware aner.data.
// Run from the directory containing examples/fixtures/units/measurements.csv.
import aner.data
import aner.units
import aner.tensor

var schema = data.schema()
schema = data.column(schema, "sensor_id", "String", false)
schema = schema.unit_column(name: "temperature_f", unit: "degF", nullable: true)
schema = data.unit_column(schema, name: "distance_cm", unit: "cm", nullable: true)
schema = schema.unit_column(name: "elapsed_s", unit: "s", nullable: false)
schema = data.column(schema, "eligible", "String", false)
let source = data.scan_csv("examples/fixtures/units/measurements.csv", schema, missing: "NA")
let eligible = data.where_eq(source, "eligible", value: "yes")
let report = data.summarize(eligible, max_bytes: 1048576, batch_rows: 2)
print("Validated source rows, eligible rows")
print(data.scanned_rows(report))
print(data.rows(report))
print("Eligible temperature: present, missing")
print(data.valid(report, "temperature_f"))
print(data.missing(report, "temperature_f"))
print("Eligible distance: present, missing")
print(data.valid(report, "distance_cm"))
print(data.missing(report, "distance_cm"))
let observed_mean: Point<degC> = report.unit_mean("temperature_f", target_unit: "degC")
print("Observed mean retains Point<degC> and is 23.5 within tolerance")
print(type(observed_mean))
print(observed_mean.value() > 23.499999999 && observed_mean.value() < 23.500000001)

// Missing observations are removed by an explicit policy, never filled with zero.
let complete = data.where_present(data.where_present(eligible, "temperature_f"), "distance_cm")
let table = data.collect(complete, max_rows: 100, max_bytes: 1048576, batch_rows: 2)
print("Complete rows, first and last sensor IDs")
print(data.rows(table))
print(data.text(table, 0, "sensor_id"))
print(data.text(table, data.rows(table) - 1, "sensor_id"))
print("Declared temperature column type and source unit")
print(data.column_type(table, 1))
print(data.column_unit(table, 1))
let length: Quantity<m> = table.unit_value(row: 0, column: "distance_cm", target_unit: "m")
let elapsed: Quantity<s> = table.unit_value(0, "elapsed_s", "s")
print("First distance and speed")
print(length)
print(length / elapsed)

// The full converted column preserves table order and has no missing entries.
let temperatures: Array<Point<degC>> = table.unit_values("temperature_f", target_unit: "degC")
print("Converted column type and length")
print(type(temperatures))
print(temperatures.len())
let export_unit = temperatures.unit()
let magnitudes = temperatures.values()
let model_input = magnitudes.to_tensor(rows: temperatures.len(), cols: 1)
print("Explicit numerical export unit and Tensor shape")
print(export_unit)
print(tensor.rows(model_input))
print(tensor.cols(model_input))
