This commit is contained in:
2026-05-21 17:12:18 +02:00
parent 15eed6b4c3
commit 88186aed7a
9 changed files with 2808 additions and 19 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"sel_status": "Aktivní", "sel_status": "Aktivní",
"sel_proto": "42847922MDD3003", "sel_proto": "77242113UCO3001",
"sel_role": [ "sel_role": [
"Principal Investigator", "Principal Investigator",
"Sub-Investigator", "Sub-Investigator",
+46 -13
View File
@@ -355,12 +355,21 @@ def load_patients(cursor, study):
mid = cursor.fetchone()["mid"] mid = cursor.fetchone()["mid"]
if mid is None: if mid is None:
raise RuntimeError(f"Žádná data v MySQL pro pacienty {study}") raise RuntimeError(f"Žádná data v MySQL pro pacienty {study}")
extra_cols = ""
if study == "77242113UCO3001":
extra_cols = """
rescreened_subject AS `Rescreened Subject`,
adt_ir AS `ADT-IR`,
three_or_more_advanced_therapies AS `3+ Adv. Therapies`,
only_oral_5asa_compounds AS `Only 5-ASA`,
ustekinumab AS `Ustekinumab`,
isolated_proctitis AS `Isolated Proctitis`,"""
sql = f""" sql = f"""
SELECT SELECT
subject AS `Subject`, subject AS `Subject`,
investigator AS `Investigator`, investigator AS `Investigator`,
age AS `Subject's age collection`, age AS `Subject's age collection`,
cohort_per_irt AS `Cohort per IRT`, cohort_per_irt AS `Cohort per IRT`,{extra_cols}
irt_subject_status AS `IRT Subject Status`, irt_subject_status AS `IRT Subject Status`,
last_irt_transaction AS `Last Recorded IRT Transaction`, last_irt_transaction AS `Last Recorded IRT Transaction`,
next_irt_transaction AS `Next Expected IRT Transaction`, next_irt_transaction AS `Next Expected IRT Transaction`,
@@ -403,15 +412,30 @@ def _write_prehled(wb, df_raw, study):
ws = wb.create_sheet("Přehled", 0) ws = wb.create_sheet("Přehled", 0)
ws.sheet_view.showGridLines = False ws.sheet_view.showGridLines = False
ws.merge_cells("A1:H1") is_uco = (study == "77242113UCO3001")
if is_uco:
display_headers = ["Subject", "Investigator", "Věk", "Cohort",
"Rescreened", "ADT-IR", "≥3 Adv.Th.", "5-ASA only",
"Uste.", "Isol.Proct.",
"Status", "Last IRT", "Next Visit", "Next Date"]
col_widths = [14, 22, 6, 12, 11, 8, 11, 10, 8, 12, 14, 12, 12, 13]
status_col = 11
flag_cols = set(range(5, 11)) # 1-indexed sloupce s Yes/No hodnotami
else:
display_headers = ["Subject", "Investigator", "Věk", "Cohort", "Status", "Last IRT", "Next Visit", "Next Date"]
col_widths = [14, 22, 6, 12, 14, 12, 12, 13]
status_col = 5
flag_cols = set()
last_col = get_column_letter(len(display_headers))
ws.merge_cells(f"A1:{last_col}1")
title = ws["A1"] title = ws["A1"]
title.value = f"Subject Summary — {study} ({date.today().strftime('%d-%b-%Y')})" title.value = f"Subject Summary — {study} ({date.today().strftime('%d-%b-%Y')})"
title.font = Font(name="Arial", bold=True, size=12, color="1F4E79") title.font = Font(name="Arial", bold=True, size=12, color="1F4E79")
title.alignment = Alignment(horizontal="left", vertical="center") title.alignment = Alignment(horizontal="left", vertical="center")
ws.row_dimensions[1].height = 22 ws.row_dimensions[1].height = 22
display_headers = ["Subject", "Investigator", "Věk", "Cohort", "Status", "Last IRT", "Next Visit", "Next Date"]
col_widths = [14, 22, 6, 12, 14, 12, 12, 13]
for c, (h, w) in enumerate(zip(display_headers, col_widths), 1): for c, (h, w) in enumerate(zip(display_headers, col_widths), 1):
cell = ws.cell(row=2, column=c, value=h) cell = ws.cell(row=2, column=c, value=h)
cell.font = _PAT_HEADER_FONT cell.font = _PAT_HEADER_FONT
@@ -421,16 +445,28 @@ def _write_prehled(wb, df_raw, study):
ws.column_dimensions[get_column_letter(c)].width = w ws.column_dimensions[get_column_letter(c)].width = w
ws.row_dimensions[2].height = 18 ws.row_dimensions[2].height = 18
display = pd.DataFrame({ base = {
"Subject": df_raw["Subject"].fillna(""), "Subject": df_raw["Subject"].fillna(""),
"Investigator": df_raw["Investigator"].fillna(""), "Investigator": df_raw["Investigator"].fillna(""),
"Věk": df_raw["Subject's age collection"].apply(lambda v: "" if pd.isna(v) else int(v)), "Věk": df_raw["Subject's age collection"].apply(lambda v: "" if pd.isna(v) else int(v)),
"Cohort": df_raw["Cohort per IRT"].apply(_simplify_cohort), "Cohort": df_raw["Cohort per IRT"].apply(_simplify_cohort),
}
if is_uco:
base.update({
"Rescreened": df_raw["Rescreened Subject"].fillna(""),
"ADT-IR": df_raw["ADT-IR"].fillna(""),
"≥3 Adv.Th.": df_raw["3+ Adv. Therapies"].fillna(""),
"5-ASA only": df_raw["Only 5-ASA"].fillna(""),
"Uste.": df_raw["Ustekinumab"].fillna(""),
"Isol.Proct.": df_raw["Isolated Proctitis"].fillna(""),
})
base.update({
"Status": df_raw["IRT Subject Status"].fillna(""), "Status": df_raw["IRT Subject Status"].fillna(""),
"Last IRT": df_raw["Last Recorded IRT Transaction"].fillna(""), "Last IRT": df_raw["Last Recorded IRT Transaction"].fillna(""),
"Next Visit": df_raw["Next Expected IRT Transaction"].fillna(""), "Next Visit": df_raw["Next Expected IRT Transaction"].fillna(""),
"Next Date": df_raw["Next Expected IRT Transaction Date [Local]"].apply(_fmt_date), "Next Date": df_raw["Next Expected IRT Transaction Date [Local]"].apply(_fmt_date),
}).sort_values("Subject").reset_index(drop=True) })
display = pd.DataFrame(base).sort_values("Subject").reset_index(drop=True)
for r_idx, row in display.iterrows(): for r_idx, row in display.iterrows():
excel_row = r_idx + 3 excel_row = r_idx + 3
@@ -440,17 +476,14 @@ def _write_prehled(wb, df_raw, study):
is_adolescent = row["Cohort"] == "Adolescent" is_adolescent = row["Cohort"] == "Adolescent"
fill = _PAT_EVEN_FILL if r_idx % 2 == 0 else _PAT_ODD_FILL fill = _PAT_EVEN_FILL if r_idx % 2 == 0 else _PAT_ODD_FILL
values = [row["Subject"], row["Investigator"], row["Věk"], for c_idx, val in enumerate(row, 1):
row["Cohort"], row["Status"], row["Last IRT"],
row["Next Visit"], row["Next Date"]]
for c_idx, val in enumerate(values, 1):
cell = ws.cell(row=excel_row, column=c_idx, value=val if val != "" else None) cell = ws.cell(row=excel_row, column=c_idx, value=val if val != "" else None)
cell.fill = fill cell.fill = fill
cell.border = _PAT_BORDER cell.border = _PAT_BORDER
cell.alignment = _PAT_CENTER if c_idx == 3 else _PAT_LEFT cell.alignment = _PAT_CENTER if (c_idx == 3 or c_idx in flag_cols) else _PAT_LEFT
if is_failed: if is_failed:
cell.font = _PAT_STRIKE_FONT cell.font = _PAT_STRIKE_FONT
elif c_idx == 5 and is_randomized: elif c_idx == status_col and is_randomized:
cell.font = _PAT_BOLD_FONT cell.font = _PAT_BOLD_FONT
elif c_idx == 4 and is_adolescent: elif c_idx == 4 and is_adolescent:
cell.font = _PAT_ADOLESC_FONT cell.font = _PAT_ADOLESC_FONT
@@ -459,7 +492,7 @@ def _write_prehled(wb, df_raw, study):
ws.row_dimensions[excel_row].height = 16 ws.row_dimensions[excel_row].height = 16
ws.freeze_panes = "A3" ws.freeze_panes = "A3"
ws.auto_filter.ref = f"A2:H{len(display) + 2}" ws.auto_filter.ref = f"A2:{last_col}{len(display) + 2}"
def _write_next_visits(wb, df_raw, study): def _write_next_visits(wb, df_raw, study):
+1 -1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff