## Înregistrarea și calculul perechilor de citiri de rezistență mică

Păstrați citiri reale și context în `blank-readings.csv`; înlocuiți `FILL_REAL_ID` cu identificatorul. Cele trei rânduri `demo-readings.csv` sunt inventate, nu măsurări MTTJ ori probe de acceptare. `kelvin_pair_calc.py` calculează rezistență și offset pe perechi de curenți și tensiuni cu semn.

Python rulează offline numai cu biblioteca standard, fără pachete suplimentare. Nu comandă instrumente, nu validează circuit uscat și nu decide acceptarea. Confirmați ipotezele și specificația separat conform articolului.

## Cele 16 coloane de intrare

Păstrați numele. Scriptul calculează cu patru coloane de citiri; restul rămân context fără validarea valorilor.

| Coloană | Sens și unitate |
| --- | --- |
| `sample_id` | Identificatorul eșantionului din rând |
| `sample_state` | Starea la măsurare |
| `spec_revision` | Revizia specificației folosite |
| `sense_A_B_drawing_ref` | Referința schemei Sense A/B |
| `fixture_id` | Identificatorul dispozitivului de testare |
| `method` | Metoda notată; modelele folosesc `four_wire_current_pair` |
| `range` | Domeniul instrumentului |
| `source_limit_mV` | Limita de tensiune sursă notată, în mV |
| `sample_history` | Istoric, inclusiv teste mecanice, de mediu sau electrice anterioare |
| `i_plus_mA` | Curent pozitiv măsurat cu semn, în mA; mai mare de 0 pentru calcul |
| `i_minus_mA` | Curent negativ măsurat cu semn, în mA; mai mic de 0 pentru calcul |
| `v_plus_uV` | Tensiune măsurată cu semn asociată cu `i_plus_mA`, în μV |
| `v_minus_uV` | Tensiune măsurată cu semn asociată cu `i_minus_mA`, în μV |
| `sampled_plus_at` | Timpul citirii pozitive, păstrat ca text |
| `sampled_minus_at` | Timpul citirii negative, păstrat ca text |
| `note` | Note păstrate cu rândul original |

Păstrați semnele. Tensiunea zero este numerică; gol înseamnă lipsă și rămâne gol. Câmp absent, gol sau numai spații în oricare dintre cele patru nu se înlocuiește cu zero. Contextul gol rămâne gol.

## Calcul și patru ieșiri

Fiecare pereche completă validă folosește:

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

`E = V+ − I+ R`

A doua formulă scoate offsetul din `V = IR + E`. μV și mA dau `R` în mΩ și `E` în μV. Presupune liniaritate și stabilitate pe pereche; rezultatul nu confirmă ipotezele. Ieșirile au până la 12 cifre semnificative.

| Ieșire | Sens |
| --- | --- |
| `r_pair_mohm` | Rezistență în mΩ; goală pentru pereche lipsă sau invalidă |
| `offset_pair_uV` | Offset în μV; gol pentru pereche lipsă sau invalidă |
| `calculation_status` | Stare `calculated`, `missing` sau `invalid` |
| `calculation_note` | Explicația stării și ipotezelor |

| Stare | Când apare |
| --- | --- |
| `calculated` | Patru numere finite, curent pozitiv peste 0, negativ sub 0 și ieșiri finite. Text exact `Assumes a linear resistor and stable offset. No acceptance judgment.` presupune liniaritate și stabilitate fără decizie de acceptare. |
| `missing` | O citire absentă sau goală; ambele ieșiri numerice goale. `Missing readings; no zero imputation.` indică lipsă fără înlocuire cu zero. |
| `invalid` | Intrare nenumerică sau nefinită, semne greșite ori ieșire nefinită. Ieșiri numerice goale; nota indică motivul. |

Note exacte: `Readings must be numeric.`, `Require finite readings and Iplus>0, Iminus<0.` sau `Non-finite calculated output.` Cer numere, valori finite și semnele date ori anunță ieșire nefinită. Stările descriu calculul, nu acceptarea.

## Citiți exemplele inventate

| Rând | 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` |

Deriva schimbă offsetul presupus de la 10 la 14 μV și dă 9.8 mΩ și 12 μV. `calculated` nu detectează sau elimină deriva. Exemplul cu curenți inegali +12 și −8 mA dă 10 mΩ. Citiri goale lasă două ieșiri goale și `missing`.

## Rulați offline și păstrați intrarea

Cu fișiere locale rulați `python kelvin_pair_calc.py demo-readings.csv result.csv`. Pentru date reale folosiți formularul completat și altă ieșire. Scriptul respinge căi de intrare și ieșire rezolvate la aceeași cale, păstrând originalul.

Păstrează coloanele de intrare și adaugă patru calculate. Dacă numele există deja, înlocuiește coloanele cu noile rezultate. Scrie UTF-8 CSV cu marcaj de ordine a octeților. Lipsurile rămân goale, fără admis/respins.
