z230
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"sel_status": "Aktivní",
|
||||
"sel_proto": "42847922MDD3003",
|
||||
"sel_proto": "77242113UCO3001",
|
||||
"sel_role": [
|
||||
"Principal Investigator",
|
||||
"Sub-Investigator",
|
||||
|
||||
+61
-15
@@ -355,12 +355,21 @@ def load_patients(cursor, study):
|
||||
mid = cursor.fetchone()["mid"]
|
||||
if mid is None:
|
||||
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"""
|
||||
SELECT
|
||||
subject AS `Subject`,
|
||||
investigator AS `Investigator`,
|
||||
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`,
|
||||
last_irt_transaction AS `Last Recorded 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.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.value = f"Subject Summary — {study} ({date.today().strftime('%d-%b-%Y')})"
|
||||
title.font = Font(name="Arial", bold=True, size=12, color="1F4E79")
|
||||
title.alignment = Alignment(horizontal="left", vertical="center")
|
||||
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):
|
||||
cell = ws.cell(row=2, column=c, value=h)
|
||||
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.row_dimensions[2].height = 18
|
||||
|
||||
display = pd.DataFrame({
|
||||
base = {
|
||||
"Subject": df_raw["Subject"].fillna(""),
|
||||
"Investigator": df_raw["Investigator"].fillna(""),
|
||||
"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),
|
||||
}
|
||||
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(""),
|
||||
"Last IRT": df_raw["Last Recorded 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),
|
||||
}).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():
|
||||
excel_row = r_idx + 3
|
||||
@@ -440,17 +476,14 @@ def _write_prehled(wb, df_raw, study):
|
||||
is_adolescent = row["Cohort"] == "Adolescent"
|
||||
fill = _PAT_EVEN_FILL if r_idx % 2 == 0 else _PAT_ODD_FILL
|
||||
|
||||
values = [row["Subject"], row["Investigator"], row["Věk"],
|
||||
row["Cohort"], row["Status"], row["Last IRT"],
|
||||
row["Next Visit"], row["Next Date"]]
|
||||
for c_idx, val in enumerate(values, 1):
|
||||
for c_idx, val in enumerate(row, 1):
|
||||
cell = ws.cell(row=excel_row, column=c_idx, value=val if val != "" else None)
|
||||
cell.fill = fill
|
||||
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:
|
||||
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
|
||||
elif c_idx == 4 and is_adolescent:
|
||||
cell.font = _PAT_ADOLESC_FONT
|
||||
@@ -459,10 +492,10 @@ def _write_prehled(wb, df_raw, study):
|
||||
ws.row_dimensions[excel_row].height = 16
|
||||
|
||||
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, visits_df=None):
|
||||
ws = wb.create_sheet("Next Visits", 1)
|
||||
ws.sheet_view.showGridLines = False
|
||||
|
||||
@@ -491,6 +524,19 @@ def _write_next_visits(wb, df_raw, study):
|
||||
"Datum": df_raw["Next Expected IRT Transaction Date [Local]"],
|
||||
"Status": df_raw["IRT Subject Status"].fillna(""),
|
||||
})
|
||||
|
||||
# I-0: datum = screening date + 42 dní
|
||||
if visits_df is not None and not visits_df.empty:
|
||||
screen = (
|
||||
visits_df[visits_df["Visit"].str.contains("Screen", case=False, na=False)]
|
||||
.groupby("Subject")["Visit Date"].min()
|
||||
.rename("Screening Date")
|
||||
)
|
||||
df = df.join(screen, on="Subject")
|
||||
mask_i0 = df["Next Visit"].str.contains("I-0", na=False)
|
||||
df.loc[mask_i0, "Datum"] = df.loc[mask_i0, "Screening Date"] + pd.Timedelta(days=42)
|
||||
df = df.drop(columns=["Screening Date"])
|
||||
|
||||
df = df[df["Datum"].notna()]
|
||||
df = df[~df["Status"].str.contains("Screen Failed|Discontinued", na=False)]
|
||||
df = df.sort_values("Datum").reset_index(drop=True)
|
||||
@@ -579,7 +625,7 @@ def create_study_report(study):
|
||||
|
||||
# ── pacienti (Přehled + Next Visits) na začátek ──────────────────────────
|
||||
_write_prehled(wb, df_patients, study)
|
||||
_write_next_visits(wb, df_patients, study)
|
||||
_write_next_visits(wb, df_patients, study, visits_df)
|
||||
|
||||
# ── pořadí listů: Patient Visits jako první ──────────────────────────────
|
||||
names = wb.sheetnames
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+28
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
Reference in New Issue
Block a user