# Jak normalizować dane medyczne

> Samouczek: przekształć dane medyczne z wielu źródeł w jedną, porównywalną formę — wyszukiwanie LOINC, jednostki UCUM, daty ISO, zakresy referencyjne, brak duplikatów przy ponownej próbie i walidacja względem europejskiego profilu laboratoryjnego.

Source: https://developers.anpheros.com/pl/guides/normalize-medical-data

**Normalizacja danych medycznych oznacza przekształcenie wartości, które docierają w wielu formach, w jedną, porównywalną formę: ten sam kod dla tego samego badania, ten sam system jednostek, daty w jednym formacie, każda wartość z jej zakresem referencyjnym i jej źródłem oraz brak duplikatów.** Ten samouczek pokazuje, jak to zrobić przed dotarciem danych do rekordu HL7 FHIR R4: wyszukiwanie kodów LOINC i ATC, używanie jednostek UCUM, odrzucanie niejednoznacznych dat, zachowywanie zakresów, unikanie duplikatów przy ponownej próbie i sprawdzanie wyniku względem europejskiego profilu laboratoryjnego. Każda pokazana odpowiedź pochodzi z API Anpheros.

## Dlaczego to ważne

Ten sam wynik HbA1c może dotrzeć do Ciebie jako „HbA1c 6,4 %”, „Hemoglobina glicozilata: 6.4”, „Glycated haemoglobin 46 mmol/mol” lub tylko kod laboratoryjny, który rozumie jedno laboratorium. Dopóki nie staną się jednym kodem z jedną jednostką:

- wykres HbA1c pacjenta w czasie pokazuje trzy niepowiązane linie;
- alert „HbA1c powyżej 6,5 %” pomija dwie z wartości;
- model AI widzi cztery fakty zamiast jednego trendu;
- inny system odbierający rekord nie jest w stanie go zinterpretować.

Normalizacja powinna odbywać się w momencie, gdy dane trafiają do rekordu, raz, a nie w każdej aplikacji, która je później odczytuje.

## Co zawiera znormalizowana wartość

| Część | Znormalizowana forma | Przykład |
|---|---|---|
| Co zostało zmierzone | kod ze standardowego systemu | LOINC `4548-4` (HbA1c), RxNorm `6809` (metformina), ICD-10 `E11` (cukrzyca typu 2) |
| Wartość | liczba lub tekst tylko wtedy, gdy wynik nie jest liczbowy | `6.4` |
| Jednostka | UCUM | `%`, `mg/dL`, `mm[Hg]`, `kg` |
| Kiedy | data i czas w formacie ISO 8601, ze strefą czasową, gdy czas ma znaczenie | `2026-10-01T07:30:00Z` |
| Zakres normalny | dolna i górna granica, w tej samej jednostce | `4.0`–`5.6` |
| Źródło | kto wyprodukował i z jakiego systemu | `import` z `labx` |
| Tożsamość | coś, co sprawia, że powtórzenie jest rozpoznawalne | klucz idempotencji lub identyfikator źródła |

Który system kodowania pasuje do jakiego typu zasobu, jest wymieniony w [Systemach kodowania FHIR](https://developers.anpheros.com/pl/guides/fhir-code-systems).

## Krok 1: Znajdź kod

Wyszukaj terminologię platformy według nazwy angielskiej lub rumuńskiej, albo według skrótu:

```bash
curl "https://platform.anpheros.com/v1/terminology/loinc?q=hba1c" -H "Authorization: Bearer $KEY"
curl "https://platform.anpheros.com/v1/terminology/loinc?q=hemoglobina%20glicozilata" -H "Authorization: Bearer $KEY"
```

Oba zwracają tę samą koncepcję:

```json
{"data": [{"system": "http://loinc.org", "code": "4548-4", "display": "Hemoglobin A1c/Hemoglobin.total in Blood",
           "display_ro": "Hemoglobină glicozilată (HbA1c)", "category": "laboratory", "unit": "%"}], "total": 1}
```

Dla leków, [Anpheros Search](https://developers.anpheros.com/pl/guides/anpheros-search) znajduje substancję według nazwy lub marki i podaje jej kod składnika RxNorm oraz numery produktów EMA:

```bash
curl "https://platform.anpheros.com/v1/search?q=metformin&type=treatment" -H "Authorization: Bearer $KEY"
```

Pole `unit` to jednostka, której oczekuje LOINC dla danego testu. Użyj go, aby sprawdzić, co otrzymałeś. Zbuduj mapowanie z własnych nazw każdego źródła na kody raz, dla każdego źródła, i przechowuj je w swojej integracji. Nie zgaduj w czasie zapisu: gdy nazwa jest niejednoznaczna i nic w źródle tego nie wyjaśnia, pozostaw ją niezmapowaną i zapytaj źródło. [Jak zaimportować wyniki laboratoryjne do rekordu FHIR](https://developers.anpheros.com/pl/guides/import-lab-results-fhir) pokazuje, jak przechowywane i raportowane są niezmapowane markery laboratoryjne.

## Krok 2: Pisanie z kodami, jednostkami i zakresami

```bash
curl -X POST "https://platform.anpheros.com/v1/patients/$PID/observations" -H "Authorization: Bearer $KEY" \
     -H "Content-Type: application/json" -H "Idempotency-Key: lab-77-hba1c" -d '{
  "code": "4548-4", "category": "laboratory",
  "value": 6.4, "unit": "%", "effective_at": "2026-10-01T07:30:00Z",
  "reference_range": {"low": 4.0, "high": 5.6},
  "author_type": "import"
}'
```

```json
{"id": "3296315c-…", "code": "4548-4", "system": "http://loinc.org", "display": "Hemoglobin A1c/Hemoglobin.total in Blood",
 "category": "laboratory", "effective_at": "2026-10-01T07:30:00Z", "value": 6.4, "unit": "%",
 "reference_range": {"low": 4.0, "high": 5.6}, "status": "final", "fhir": "Observation/3296315c-…"}
```

Kiedy wysyłasz tylko kod, platforma uzupełnia standardową nazwę LOINC, zarówno w REST API, jak i w FHIR API (`/fhir/R4`), dzięki czemu każda aplikacja odczytuje to samo `display`. `display`, które wysyłasz samodzielnie, jest zachowywane w niezmienionej postaci.

Zachowaj również oryginalne sformułowania. W przypadku raportu laboratoryjnego, `code.text` w FHIR Observation zawiera nazwę laboratorium ("Hemoglobina glicozilata (HbA1c)") obok kodowania LOINC. Pacjent nadal rozpoznaje swój papierowy raport, a nic nie zostanie utracone, jeśli mapowanie kiedykolwiek zostanie zakwestionowane.

## Krok 3: Jednostki

Używaj kodów UCUM: `mg/dL`, `mmol/L`, `%`, `mm[Hg]`, `kg`, `cm`, `/min`, `Cel`. Dwie zasady zapobiegają większości błędów:

- **Nie konwertuj cicho.** Jeśli laboratorium zgłasza glukozę w `mmol/L`, a Twoja aplikacja wyświetla `mg/dL`, przechowuj to, co zmierzyło laboratorium, i konwertuj podczas wyświetlania. Przechowywana wartość pozostaje możliwa do prześledzenia do raportu.
- **Sprawdź jednostkę w odniesieniu do kodu.** Kody LOINC są specyficzne: HbA1c w `%` to `4548-4`, podczas gdy HbA1c w `mmol/mol` ma inny kod LOINC. Wartość, której jednostka nie pasuje do oczekiwanej jednostki kodu, jest błędem mapowania, a nie problemem z konwersją.

Anpheros nie konwertuje jednostek za Ciebie; przechowuje jednostkę, którą wysyłasz.

## Krok 4: daty

Przed zapisaniem konwertuj daty do formatu ISO 8601, używając znanego formatu źródła. `01.10.2026` to 1 października w Rumunii i wielu krajach europejskich, ale `10/01/2026` to 1 października tylko w Stanach Zjednoczonych. API odrzuca wszystko, co nie jest w formacie ISO, zamiast zgadywać:

```json
{"error": {"type": "invalid", "message": "Input should be a valid datetime or date, invalid character in year (at effective_at)", "field": "effective_at"}}
```

Wyjątkiem jest konektor laboratoryjny: akceptuje on `DD.MM.YYYY` i `DD/MM/YYYY`, ponieważ wie, że odczytuje europejski raport.

W przypadku pomiarów, w których ważna jest pora dnia (ciśnienie krwi, glukoza, dawki leków), przesyłaj czas wraz ze strefą czasową. Odczyt o 23:30 w Bukareszcie przypada na poprzedni dzień w strefie UTC, a pacjent oczekuje go w dniu, w którym został wykonany.

## Krok 5: brak duplikatów

Duplikaty powstają w wyniku ponownych prób, dwukrotnego wysłania tego samego raportu oraz otrzymania tej samej wartości przez dwie ścieżki.

- **Ponowne próby:** wyślij `Idempotency-Key`, który identyfikuje wartość w źródle, na przykład identyfikator raportu i test. Ponowne wysłanie tego samego żądania z tym samym kluczem zwraca pierwszą odpowiedź i nie zapisuje niczego nowego. SDK dodają jeden do każdego tworzenia.
- **Ten sam raport dwukrotnie:** konektor laboratorium buduje stabilny identyfikator dla każdego wiersza na podstawie raportu, kodu, daty i wartości, a następnie pomija już zaimportowane wiersze.
- **Dwie ścieżki:** przechowuj własny identyfikator systemu źródłowego za pomocą `X-Anpheros-Origin-Id` (lub w `identifier` w zasobach FHIR) i wyszukaj go przed zapisaniem wartości, które mogą powrócić inną ścieżką.

## Krok 6: Sprawdzenie zgodności z profilem

W przypadku wyników laboratoryjnych, przed poleganiem na nich, zapytaj platformę, jak zasób wypada w porównaniu z profilem raportu laboratoryjnego HL7 Europe:

```bash
curl -X POST "https://platform.anpheros.com/fhir/R4/Observation/\$validate?profile=eu-lab" -H "Authorization: Bearer $KEY" \
     -H "Content-Type: application/fhir+json" -d '{
  "resourceType": "Observation", "status": "final",
  "category": [{"coding": [{"system": "http://terminology.hl7.org/CodeSystem/observation-category", "code": "laboratory"}]}],
  "code": {"text": "HbA1c"}, "subject": {"reference": "Patient/'$PID'"},
  "valueQuantity": {"value": 6.4, "unit": "%"}
}'
```

Ten nieznormalizowany wynik otrzymuje precyzyjną listę:

```json
{"resourceType": "OperationOutcome", "issue": [
  {"severity": "error", "code": "invalid", "diagnostics": "Observation.code must carry a LOINC coding.", "expression": ["Observation.code"]},
  {"severity": "error", "code": "required", "diagnostics": "Observation.effective[x] is required.", "expression": ["Observation.effective"]},
  {"severity": "warning", "code": "business-rule", "diagnostics": "valueQuantity should carry a UCUM system and code.", "expression": ["Observation.valueQuantity"]},
  {"severity": "warning", "code": "informational", "diagnostics": "No referenceRange: interpretation will need the laboratory's ranges.", "expression": ["Observation.referenceRange"]},
  {"severity": "information", "code": "informational", "diagnostics": "No performer (laboratory) recorded.", "expression": ["Observation.performer"]},
  {"severity": "information", "code": "informational", "diagnostics": "No issued time (when the laboratory released the result).", "expression": ["Observation.issued"]}]}
```

Każdy problem odpowiada jednemu z powyższych kroków. Uruchom `$validate` w swoich testach integracyjnych, używając rzeczywistych próbek z każdego źródła.

## Krok 7: zachowaj źródło

Normalizacja zmienia sposób zapisu wartości, nigdy jej pochodzenie. Wysyłaj `author_type` (`device`, `import`, `practitioner`, `patient`) i `X-Anpheros-Source-System` przy każdej operacji zapisu. To właśnie pozwala lekarzowi, audytorowi lub modelowi AI odróżnić wynik laboratoryjny od wartości wpisanej w domu. Zobacz [Wyjaśnienie pochodzenia danych medycznych](https://developers.anpheros.com/pl/guides/medical-data-provenance).

## Lista kontrolna

- [ ] Każde źródło ma mapowanie swoich nazw na LOINC / ATC / ICD-10, przechowywane w Twojej integracji
- [ ] Niejednoznaczne nazwy pozostają niezmapowane i są zgłaszane, nigdy nie są zgadywane
- [ ] Jednostki UCUM, zgodne z kodem; brak cichych konwersji
- [ ] Daty w formacie ISO 8601, ze strefami czasowymi tam, gdzie czas ma znaczenie
- [ ] Zakresy referencyjne zachowane wraz z wartościami laboratoryjnymi
- [ ] Oryginalne sformułowanie zachowane (`code.text`)
- [ ] Klucze idempotencji lub identyfikatory źródła przy każdym zapisie
- [ ] `author_type` i system źródłowy przy każdym zapisie
- [ ] `$validate` w testach wyników laboratoryjnych

## Często zadawane pytania

### Czym jest normalizacja danych medycznych?
Konwersja danych medycznych z różnych źródeł do jednej standardowej formy: wspólnych kodów (LOINC dla testów i pomiarów, ICD-10 dla diagnoz, ATC dla leków), jednostek UCUM, dat ISO, zakresów referencyjnych i zarejestrowanego źródła, tak aby wartości z różnych systemów można było porównywać, łączyć i wymieniać.

### Czy powinienem przeliczać wszystkie wartości na jedną jednostkę?
Przechowuj jednostkę, w której mierzyło źródło, o ile jest to prawidłowa jednostka UCUM pasująca do kodu, i konwertuj podczas wyświetlania lub analizy. Dzięki temu każda przechowywana wartość jest możliwa do prześledzenia do oryginalnego raportu.

### Czy normalizacja może być w pełni automatyczna?
W większości przypadków. Kody w źródle, znane nazwy i dobrze sformułowane jednostki można mapować automatycznie. Niejednoznaczne nazwy i nieznane lokalne kody wymagają jednorazowej decyzji człowieka dla każdego źródła, po czym mapowanie staje się automatyczne.

## Powiązane

- [Systemy kodowania FHIR](https://developers.anpheros.com/pl/guides/fhir-code-systems)
- [Jak zaimportować wyniki laboratoryjne do rekordu FHIR](https://developers.anpheros.com/pl/guides/import-lab-results-fhir)
- [Wyjaśnienie pochodzenia danych medycznych](https://developers.anpheros.com/pl/guides/medical-data-provenance)
- [Interoperacyjność danych w opiece zdrowotnej](https://developers.anpheros.com/pl/guides/interoperability)
- [API danych medycznych](https://developers.anpheros.com/pl/guides/medical-data-api)
