## Registrar y calcular pares de lecturas de baja resistencia

Use `blank-readings.csv` para lecturas reales y contexto; sustituya `FILL_REAL_ID` por la identificación de muestra. Las tres filas de `demo-readings.csv` son inventadas, no mediciones MTTJ ni muestras de aceptación. `kelvin_pair_calc.py` calcula resistencia y offset de cada par de corrientes y tensiones con signo.

Python funciona sin conexión con su biblioteca estándar, sin paquetes adicionales. No controla instrumentos ni verifica las condiciones de circuito seco ni decide la aceptación del producto. Confirme hipótesis y especificación por separado según el artículo.

## Las 16 columnas de entrada

Mantenga los nombres. El script calcula con cuatro campos de lectura y conserva el resto como contexto sin comprobar sus valores.

| Columna | Significado y unidad |
| --- | --- |
| `sample_id` | Identificador de la muestra de la fila |
| `sample_state` | Estado durante la medida |
| `spec_revision` | Revisión de especificación usada |
| `sense_A_B_drawing_ref` | Referencia del esquema Sense A/B |
| `fixture_id` | Identificador del útil |
| `method` | Método registrado; los modelos usan `four_wire_current_pair` |
| `range` | Rango del instrumento |
| `source_limit_mV` | Límite de tensión de fuente registrado, en mV |
| `sample_history` | Historial, incluidos ensayos mecánicos, ambientales o eléctricos previos |
| `i_plus_mA` | Corriente real positiva con signo, en mA; mayor de 0 para calcular |
| `i_minus_mA` | Corriente real negativa con signo, en mA; menor de 0 para calcular |
| `v_plus_uV` | Tensión medida con signo emparejada con `i_plus_mA`, en μV |
| `v_minus_uV` | Tensión medida con signo emparejada con `i_minus_mA`, en μV |
| `sampled_plus_at` | Tiempo de lectura positiva, conservado como texto |
| `sampled_minus_at` | Tiempo de lectura negativa, conservado como texto |
| `note` | Notas conservadas con la fila original |

Conserve signos de corriente y tensión. Cero es un valor numérico; vacío indica medida ausente y queda vacío. Si falta uno de los cuatro campos, está vacío o contiene solo espacios, no se sustituye por cero. Los campos de contexto vacíos también permanecen vacíos.

## Cálculo y cuatro columnas de salida

Para cada par completo y válido:

`R = (V+ − V−) / (I+ − I−)`

`E = V+ − I+ R`

La segunda fórmula obtiene offset de `V = IR + E`. Entradas en μV y mA dan `R` en mΩ y `E` en μV. Supone resistencia lineal y offset estable durante el par; producir un resultado no verifica las hipótesis. Hasta 12 cifras significativas en las salidas.

| Salida | Significado |
| --- | --- |
| `r_pair_mohm` | Resistencia calculada en mΩ; vacía para par ausente o inválido |
| `offset_pair_uV` | Offset calculado en μV; vacío para par ausente o inválido |
| `calculation_status` | Estado: `calculated`, `missing` o `invalid` |
| `calculation_note` | Explicación del estado e hipótesis |

| Estado | Cuándo se escribe |
| --- | --- |
| `calculated` | Cuatro entradas numéricas finitas, corriente positiva mayor de 0, negativa menor de 0 y dos resultados finitos. Nota literal `Assumes a linear resistor and stable offset. No acceptance judgment.`: supone linealidad y offset estable sin juicio de aceptación. |
| `missing` | Alguna lectura ausente o vacía; ambas salidas numéricas vacías. `Missing readings; no zero imputation.` indica ausencia sin completar con cero. |
| `invalid` | Entrada no numérica o no finita, signos incorrectos o resultado no finito. Salidas numéricas vacías y nota con la causa. |

Notas literales de `invalid`: `Readings must be numeric.`, `Require finite readings and Iplus>0, Iminus<0.` o `Non-finite calculated output.` Exigen valores numéricos, finitos y signos correctos o indican salida no finita. Estados y notas describen cálculo, no aceptación.

## Leer los ejemplos inventados

| Fila | I+ / I− (mA) | V+ / V− (μV) | `r_pair_mohm` (mΩ) | `offset_pair_uV` (μV) | `calculation_status` |
| --- | --- | --- | ---: | ---: | --- |
| `DEMO_STABLE` | +10 / −10 | +110 / −90 | 10 | 10 | `calculated` |
| `DEMO_DRIFT` | +10 / −10 | +110 / −86 | 9.8 | 12 | `calculated` |
| `DEMO_UNEQUAL` | +12 / −8 | +130 / −70 | 10 | 10 | `calculated` |

La deriva cambia el offset supuesto de 10 a 14 μV entre lecturas, dando 9.8 mΩ y 12 μV. `calculated` no detecta ni elimina deriva. Corrientes reales desiguales +12 y −8 mA dan 10 mΩ. Lecturas vacías del modelo dejan ambas salidas vacías y estado `missing`.

## Ejecutar sin conexión y conservar entrada

Guarde script y CSV localmente y ejecute `python kelvin_pair_calc.py demo-readings.csv result.csv`. Use el modelo lleno para datos reales y otra salida. El script rechaza entrada y salida que se resuelvan como la misma ruta, preservando el original.

La salida conserva columnas originales y añade cuatro calculadas. Si ya existen con esos nombres, las reemplaza por nuevos resultados. Escribe CSV UTF-8 con marca de orden de bytes. Las ausencias siguen vacías, sin decisión aprobado/rechazado.
