Refine DICOM UPP relation loading
This commit is contained in:
@@ -24,6 +24,7 @@ PGUSER = os.getenv("PGUSER", "his_user")
|
||||
PGDATABASE = os.getenv("PGDATABASE", "pacs_db")
|
||||
PACS_TABLE = os.getenv("PACS_TABLE", "pacs_dicom_files")
|
||||
PACS_SUMMARY_TABLE = os.getenv("PACS_SUMMARY_TABLE", "pacs_dicom_study_summaries")
|
||||
PACS_ANNOTATION_TABLE = os.getenv("PACS_ANNOTATION_TABLE", "pacs_dicom_series_annotations")
|
||||
UPP_ASSET_TABLE = os.getenv("UPP_ASSET_TABLE", "upp_exam_assets")
|
||||
UPP_STL_TABLE = os.getenv("UPP_STL_TABLE", "upp_stl_files")
|
||||
USER_TABLE = os.getenv("VISUALIZER_USER_TABLE", "db_visualizer_users")
|
||||
@@ -42,6 +43,7 @@ def ident(name: str) -> str:
|
||||
|
||||
PACS_TABLE_SQL = ident(PACS_TABLE)
|
||||
PACS_SUMMARY_TABLE_SQL = ident(PACS_SUMMARY_TABLE)
|
||||
PACS_ANNOTATION_TABLE_SQL = ident(PACS_ANNOTATION_TABLE)
|
||||
UPP_ASSET_TABLE_SQL = ident(UPP_ASSET_TABLE)
|
||||
UPP_STL_TABLE_SQL = ident(UPP_STL_TABLE)
|
||||
USER_TABLE_SQL = ident(USER_TABLE)
|
||||
@@ -185,6 +187,52 @@ def relation_cte() -> str:
|
||||
SELECT *
|
||||
FROM public.{PACS_SUMMARY_TABLE_SQL}
|
||||
),
|
||||
a_label_raw AS (
|
||||
SELECT
|
||||
a.ct_number,
|
||||
CASE part.value
|
||||
WHEN 'head_neck' THEN '头颈部'
|
||||
WHEN 'chest' THEN '胸部-' || CASE COALESCE(NULLIF(a.chest_window, ''), 'unknown')
|
||||
WHEN 'lung' THEN '肺窗'
|
||||
WHEN 'mediastinal' THEN '纵隔窗'
|
||||
ELSE '无法判别'
|
||||
END
|
||||
WHEN 'upper_abdomen' THEN '上腹部-' || CASE COALESCE(NULLIF(a.upper_abdomen_phase, ''), 'unknown')
|
||||
WHEN 'plain' THEN '平扫'
|
||||
WHEN 'arterial' THEN '动脉期'
|
||||
WHEN 'portal_venous' THEN '门脉期'
|
||||
WHEN 'delayed' THEN '延迟期'
|
||||
ELSE '无法判别'
|
||||
END
|
||||
WHEN 'lower_abdomen' THEN '下腹部'
|
||||
WHEN 'pelvis' THEN '盆腔'
|
||||
ELSE NULL
|
||||
END AS label,
|
||||
CASE part.value
|
||||
WHEN 'head_neck' THEN 1
|
||||
WHEN 'chest' THEN 2
|
||||
WHEN 'upper_abdomen' THEN 3
|
||||
WHEN 'lower_abdomen' THEN 4
|
||||
WHEN 'pelvis' THEN 5
|
||||
ELSE 99
|
||||
END AS sort_key
|
||||
FROM public.{PACS_ANNOTATION_TABLE_SQL} a
|
||||
CROSS JOIN LATERAL jsonb_array_elements_text(a.body_parts) AS part(value)
|
||||
WHERE COALESCE(a.skipped, false) IS NOT TRUE
|
||||
),
|
||||
a_label_distinct AS (
|
||||
SELECT ct_number, label, min(sort_key) AS sort_key
|
||||
FROM a_label_raw
|
||||
WHERE label IS NOT NULL
|
||||
GROUP BY ct_number, label
|
||||
),
|
||||
a_labels AS (
|
||||
SELECT
|
||||
ct_number,
|
||||
to_jsonb(array_agg(label ORDER BY sort_key, label)) AS dicom_annotation_labels
|
||||
FROM a_label_distinct
|
||||
GROUP BY ct_number
|
||||
),
|
||||
u_raw AS (
|
||||
SELECT
|
||||
u.*,
|
||||
@@ -253,6 +301,7 @@ def relation_cte() -> str:
|
||||
ps.undetermined_series,
|
||||
ps.completed,
|
||||
ps.body_parts,
|
||||
COALESCE(a_labels.dicom_annotation_labels, '[]'::jsonb) AS dicom_annotation_labels,
|
||||
to_jsonb(array_remove(ARRAY[
|
||||
CASE WHEN ps.body_parts ? 'head_neck' THEN '头颈部' END,
|
||||
CASE WHEN ps.body_parts ? 'chest' THEN '胸部' END,
|
||||
@@ -297,6 +346,7 @@ def relation_cte() -> str:
|
||||
FROM keys k
|
||||
LEFT JOIN p ON p.ct_key = k.ct_key
|
||||
LEFT JOIN ps ON ps.ct_number = p.ct_number
|
||||
LEFT JOIN a_labels ON a_labels.ct_number = p.ct_number
|
||||
LEFT JOIN u ON u.ct_key = k.ct_key
|
||||
LEFT JOIN s ON s.ct_key = k.ct_key
|
||||
)
|
||||
@@ -401,6 +451,7 @@ def settings(user: dict[str, str] = Depends(admin_user)) -> dict[str, Any]:
|
||||
"tables": {
|
||||
"dicom": PACS_TABLE,
|
||||
"dicom_summary": PACS_SUMMARY_TABLE,
|
||||
"dicom_annotations": PACS_ANNOTATION_TABLE,
|
||||
"upp_assets": UPP_ASSET_TABLE,
|
||||
"upp_stl": UPP_STL_TABLE,
|
||||
},
|
||||
@@ -489,6 +540,7 @@ def status(user: dict[str, str] = Depends(current_user)) -> dict[str, Any]:
|
||||
"tables": {
|
||||
"dicom": PACS_TABLE,
|
||||
"dicom_summary": PACS_SUMMARY_TABLE,
|
||||
"dicom_annotations": PACS_ANNOTATION_TABLE,
|
||||
"upp_assets": UPP_ASSET_TABLE,
|
||||
"upp_stl": UPP_STL_TABLE,
|
||||
},
|
||||
@@ -503,6 +555,7 @@ def relations(
|
||||
algorithm_model: str = "",
|
||||
dicom_part: str = "",
|
||||
limit: int = Query(default=300, ge=1, le=1000),
|
||||
offset: int = Query(default=0, ge=0),
|
||||
user: dict[str, str] = Depends(current_user),
|
||||
) -> list[dict[str, Any]]:
|
||||
where = relation_where(q, status, algorithm_model, dicom_part)
|
||||
@@ -517,7 +570,7 @@ def relations(
|
||||
study_description, exam_description, algorithm_model, upp_status,
|
||||
pacs_series_count, dicom_file_count, annotated_series, undetermined_series, completed,
|
||||
list_present, list_record_count, stl_file_count, stl_file_count_agg,
|
||||
body_parts, dicom_body_parts, segment_categories, segment_families,
|
||||
body_parts, dicom_body_parts, dicom_annotation_labels, segment_categories, segment_families,
|
||||
pacs_updated_at, upp_updated_at, stl_updated_at
|
||||
FROM relation
|
||||
{where}
|
||||
@@ -528,6 +581,7 @@ def relations(
|
||||
COALESCE(study_time, '') DESC,
|
||||
ct_key
|
||||
LIMIT {int(limit)}
|
||||
OFFSET {int(offset)}
|
||||
""",
|
||||
timeout=24,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user