Messages PMSI¶
pmsi ¶
evenementsPMSI / RSS MCO depuis des tables — un fichier par événement.
evenements (1 ligne = 1 fichier ; colonnes-chemins relatives à evenementPMSI)
obligatoires : evt_id, ipp, sexe, date_naissance, nda, venue_date_entree
facultatives : ipp_recepteur, nom_usuel, nom_naissance, prenom, nda_recepteur,
venue_heure_entree, venue_mode_entree, venue_uf_responsable, venue_date_sortie,
venue_heure_sortie, rss_emetteur, rss_recepteur, rss_version, numero_finess,
identifiant_message, date_heure_production, commentaire
rum (1 ligne = 1 RUM ; colonnes-chemins relatives à rum)
obligatoires : evt_id, rum_id, um, um_date_entree, um_mode_entree
facultatives : rum_emetteur (défaut rum_id), rum_recepteur, action (creation),
date_action (défaut um_date_entree), um_heure_entree, um_provenance,
um_date_sortie, um_heure_sortie, um_mode_sortie, um_destination, igs2, nb_seances
diagnostics (format long ; colonnes-chemins relatives au diagnostic)
evt_id, rum_id, type ∈ {DP, DR, DAS, DAD}, code
Alternative : colonnes ``dp``, ``dr``, ``das``, ``dad`` dans ``rum``. ``das`` et ``dad``
acceptent une liste (type List de polars) ou une chaîne séparée par des virgules
(``"E11.9, I10"``). Les deux formes peuvent se combiner, sans doublon de DP ou de DR.
actes (1 ligne = 1 acte CCAM ; colonnes-chemins relatives à acte)
obligatoires : evt_id, rum_id, code, phase, activite
facultatives : quantite (1), extension_pmsi, date_realisation, extension_documentaire,
modificateurs (ex. "7J"), association_non_prevue, remboursement_exceptionnel, externe
rum_id n'est qu'une clé de jointure : l'identifiant XML du RUM est rum_emetteur
(deux RUM d'un même RSS peuvent partager le même émetteur).
write_evenements_pmsi ¶
write_evenements_pmsi(
evenements: Table,
rum: Table,
diagnostics: Table | None = None,
actes: Table | None = None,
*,
entete: dict | None = None,
out_dir: str | Path,
filename: str | Callable[[dict], str] = "{evt_id}.xml",
version: str | None = None,
xmlns: str | None = HPRIM_NS,
encoding: str = "UTF-8",
validate_xsd: str | bool = "error",
colmap: dict | None = None,
par_rum: bool = False,
identifiant_egal_nom_fichier: bool = True,
fichier_ok: bool = False,
) -> list[Path]
Écrit des fichiers evenementsPMSI (RSS MCO) depuis des tables.
Unité atomique du PMSI : le RUM, seul porteur de l'attribut action et d'un
identifiant. par_rum=True écrit un message par RUM.
Les tables sont décrites en tête du module. Toute colonne dont le nom contient /
ou commence par @ est une colonne-chemin.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
evenements
|
Table
|
une ligne par séjour (polars ou pandas). |
required |
rum
|
Table
|
une ligne par RUM. |
required |
diagnostics
|
Table | None
|
format long, |
None
|
actes
|
Table | None
|
une ligne par acte CCAM. |
None
|
entete
|
dict | None
|
|
None
|
out_dir
|
str | Path
|
dossier de sortie (créé si besoin). |
required |
filename
|
str | Callable[[dict], str]
|
gabarit formaté avec la ligne evenement, ou fonction ligne -> nom. |
'{evt_id}.xml'
|
version
|
str | None
|
version du schéma ; sinon colonne |
None
|
xmlns
|
str | None
|
|
HPRIM_NS
|
encoding
|
str
|
encodage des fichiers. |
'UTF-8'
|
validate_xsd
|
str | bool
|
|
'error'
|
colmap
|
dict | None
|
renommage de colonnes |
None
|
par_rum
|
bool
|
un fichier par RUM au lieu d'un par séjour. |
False
|
identifiant_egal_nom_fichier
|
bool
|
si vrai (défaut), l'identifiantMessage de chaque
message est exactement le nom de son fichier sans extension ( |
True
|
fichier_ok
|
bool
|
dépose un fichier |
False
|
Returns:
| Type | Description |
|---|---|
list[Path]
|
La liste des fichiers écrits. |
Raises:
| Type | Description |
|---|---|
HprimWriteError
|
colonne obligatoire manquante, identifiantMessage invalide,
ou message non conforme au XSD (avec |
Examples:
Script examples/exemple_pmsi.py :
# Régénère data/xml_tests/pmsi/00001.xml : un séjour (RSS) à deux RUM.
from datetime import date, datetime, time
import polars as pl
import pyhprimxml as hx
# En-tête du message (chaque clé peut aussi être une colonne de `evenements`)
entete = {
"version": "2.00", # version HPRIM XML des messages
"emetteur": "TEST",
"destinataire": None, # agent destinataire sans code, comme le fichier d'origine
"mode_traitement": "reel",
"acquittement_attendu": "oui",
"commentaire": "HPRIM-TEST",
"date_heure_production": datetime(2024, 1, 1, 1, 1, 1),
}
# Une ligne par séjour, donc par fichier : patient, venue, identifiant du RSS
evenements = pl.DataFrame({
"evt_id": ["00001_pmsi"], # -> fichier 00001_pmsi.xml, identifiantMessage 00001_pmsi
"ipp": ["123456789"], "ipp_recepteur": ["123456789"],
"sexe": ["M"], "nom_usuel": ["SANDWICK"], "nom_naissance": ["SANDWICK"], "prenom": ["JOHN"],
"date_naissance": [date(1970, 1, 1)],
"nda": ["987654321"], "nda_recepteur": ["987654321"],
"venue_date_entree": [date(2024, 1, 1)], "venue_heure_entree": [time(8, 0)],
"venue_mode_entree": ["8"], "venue_uf_responsable": ["4321"],
"rss_emetteur": ["0"], "rss_recepteur": ["000"],
# colonnes-chemins : attributs sans colonne dédiée
"patient/@anonyme": ["non"], "patient/@confidentiel": ["non"], "venue/@prive": ["non"],
})
# Une ligne par RUM ; rum_id = rang du RUM dans le RSS (clé de jointure)
rum = pl.DataFrame({
"evt_id": ["00001_pmsi", "00001_pmsi"],
"rum_id": [1, 2],
"rum_emetteur": ["pmsi_00001", "pmsi_00001"], # identifiant XML du RUM
"rum_recepteur": ["98765", "98766"],
"date_action": [datetime(2024, 1, 1, 8, 10), datetime(2024, 1, 1, 9, 0)],
"um": ["4321", "5000"],
"um_date_entree": [date(2024, 1, 1)] * 2,
"um_heure_entree": [time(8, 0), time(9, 0)],
"um_mode_entree": ["8", "8"],
"@classant": ["non", "non"],
"@prestationInterEtablissementA": ["non", "non"],
"medecinResponsable/identification/code": ["01234567"] * 2,
"medecinResponsable/personne/nomUsuel": ["HOBBES"] * 2,
"medecinResponsable/personne/prenoms/prenom": ["MARC-JACQUES"] * 2,
})
# Format long : une ligne par diagnostic, type dans DP, DR, DAS, DAD
diagnostics = pl.DataFrame({
"evt_id": ["00001_pmsi"] * 3,
"rum_id": [1, 1, 2],
"type": ["DP", "DR", "DP"],
"code": ["Z511", "C10", "Z743"],
})
# Une ligne par acte CCAM
actes = pl.DataFrame({
"evt_id": ["00001_pmsi"] * 5,
"rum_id": [1, 1, 1, 1, 2],
"code": ["EBLA003", "EPLF002", "NFKA006", "YYYY033", "QZRP004"],
"phase": [0] * 5, "activite": [1] * 5, "quantite": [1] * 5,
"date_realisation": [datetime(2024, 1, 1, 8, 10)] * 4 + [datetime(2024, 1, 1, 9, 10)],
"externe": ["non"] * 5, "remboursement_exceptionnel": ["non"] * 5,
})
fichiers = hx.write_evenements_pmsi(
evenements, rum, diagnostics, actes,
entete=entete,
out_dir="sortie/pmsi", # -> sortie/pmsi/00001_pmsi.xml
validate_xsd="warn", # destinataire sans code : non conforme au XSD
)
read_evenements_pmsi ¶
read_evenements_pmsi(
sources: Sources,
*,
extra: dict[str, list[str]] | None = None,
version: str | None = None,
backend: str = "polars",
exiger_ok: bool = False,
format_diagnostics: str = "long",
) -> dict[str, Table]
Lit des fichiers evenementsPMSI (RSS MCO) vers les tables de write_evenements_pmsi.
evt_id est le nom du fichier sans extension (suffixé _1, _2… si un fichier
contient plusieurs événements) ; rum_id est le rang du RUM dans le RSS.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sources
|
Sources
|
fichier, dossier, motif glob, bytes ou liste. |
required |
extra
|
dict[str, list[str]] | None
|
colonnes-chemins supplémentaires à extraire, par table, par exemple
|
None
|
version
|
str | None
|
forcer une version de schéma (sinon celle de chaque fichier). |
None
|
backend
|
str
|
|
'polars'
|
format_diagnostics
|
str
|
|
'long'
|
exiger_ok
|
bool
|
ne lit que les |
False
|
Returns:
| Type | Description |
|---|---|
dict[str, Table]
|
|
iter_evenements_pmsi ¶
iter_evenements_pmsi(
evenements: Table,
rum: Table,
diagnostics: Table | None = None,
actes: Table | None = None,
*,
entete: dict | None = None,
version: str | None = None,
colmap: dict | None = None,
par_rum: bool = False,
) -> Iterator[tuple[dict, dict]]
Itère sur (ligne evenement, arbre xmltodict) — un arbre par événement.
un message par RUM au lieu d'un message par séjour. L'événement
evt_id devient {evt_id}_{rum_id} (donc le nom de fichier par défaut aussi) ;
patient, venue et identifiantRSS sont répétés dans chaque message.