예제 #1
0
def mosaiq_input_method(patient_id="", key_namespace="", site=None, **_):
    mosaiq_details = _config.get_mosaiq_details()

    mosaiq_site = st_misc.site_picker("Mosaiq Site",
                                      default=site,
                                      key=f"{key_namespace}_mosaiq_site")

    server = mosaiq_details[mosaiq_site]["server"]
    st.write(f"Mosaiq Hostname: `{server}`")

    sql_user = keyring.get_password("MosaiqSQL_username", server)
    st.write(f"Mosaiq SQL login being used: `{sql_user}`")

    patient_id = st.text_input("Patient ID",
                               patient_id,
                               key=f"{key_namespace}_patient_id")
    st.write(patient_id)

    cursor = st_mosaiq.get_mosaiq_cursor(server)

    if patient_id == "":
        return {}

    patient_name = get_patient_name(cursor, patient_id)

    st.write(f"Patient Name: `{patient_name}`")

    patient_fields = get_patient_fields(cursor, patient_id)

    st.write("""
        #### Mosaiq patient fields
        """)

    patient_fields = patient_fields[patient_fields["monitor_units"] != 0]
    st.write(patient_fields)

    field_ids = patient_fields["field_id"]
    field_ids = field_ids.values.tolist()

    selected_field_ids = st.multiselect("Select Mosaiq field id(s)",
                                        field_ids,
                                        key=f"{key_namespace}_mosaiq_field_id")

    cursor_and_field_ids = [(cursor, field_id)
                            for field_id in selected_field_ids]
    deliveries = _deliveries.cached_deliveries_loading(
        cursor_and_field_ids, _deliveries.delivery_from_mosaiq)
    identifier = f"{mosaiq_site} Mosaiq ({', '.join([str(field_id) for field_id in selected_field_ids])})"

    return {
        "site": mosaiq_site,
        "patient_id": patient_id,
        "patient_name": patient_name,
        "data_paths": [],
        "identifier": identifier,
        "deliveries": deliveries,
    }
예제 #2
0
def mosaiq_input_method(patient_id="", key_namespace="", **_):
    mosaiq_details = get_mosaiq_details()
    site_options = list(mosaiq_details.keys())

    mosaiq_site = st.radio("Mosaiq Site",
                           site_options,
                           key=f"{key_namespace}_mosaiq_site")
    server = mosaiq_details[mosaiq_site]["server"]
    f"Mosaiq Hostname: `{server}`"

    sql_user = keyring.get_password("MosaiqSQL_username", server)
    f"Mosaiq SQL login being used: `{sql_user}`"

    patient_id = st.text_input("Patient ID",
                               patient_id,
                               key=f"{key_namespace}_patient_id")
    patient_id

    cursor = get_mosaiq_cursor(server)

    if patient_id == "":
        return {}

    patient_name = get_patient_name(cursor, patient_id)

    f"Patient Name: `{patient_name}`"

    patient_fields = get_patient_fields(cursor, patient_id)
    """
    #### Mosaiq patient fields
    """

    patient_fields = patient_fields[patient_fields["monitor_units"] != 0]
    patient_fields

    field_ids = patient_fields["field_id"]
    field_ids = field_ids.values.tolist()

    selected_field_ids = st.multiselect("Select Mosaiq field id(s)",
                                        field_ids,
                                        key=f"{key_namespace}_mosaiq_field_id")

    cursor_and_field_ids = [(cursor, field_id)
                            for field_id in selected_field_ids]
    deliveries = cached_deliveries_loading(cursor_and_field_ids,
                                           delivery_from_mosaiq)
    identifier = (
        f"Mosaiq ({', '.join([str(field_id) for field_id in selected_field_ids])})"
    )

    return {
        "patient_id": patient_id,
        "patient_name": patient_name,
        "data_paths": selected_field_ids,
        "identifier": identifier,
        "deliveries": deliveries,
    }
예제 #3
0
def trf_input_method(patient_id="", key_namespace="", **_):
    indexed_trf_directory = get_indexed_trf_directory()

    patient_id = st.text_input("Patient ID",
                               patient_id,
                               key=f"{key_namespace}_patient_id")
    patient_id

    filepaths = list(
        indexed_trf_directory.glob(f"*/{patient_id}_*/*/*/*/*.trf"))

    raw_timestamps = [
        "_".join(path.parent.name.split("_")[0:2]) for path in filepaths
    ]
    timestamps = list(
        pd.to_datetime(raw_timestamps, format="%Y-%m-%d_%H%M%S").astype(str))

    timestamp_filepath_map = dict(zip(timestamps, filepaths))

    timestamps = sorted(timestamps, reverse=True)

    if len(timestamps) == 0:
        if patient_id != "":
            st.write(
                NoRecordsFound(
                    f"No TRF log file found for patient ID {patient_id}"))
        return {"patient_id": patient_id}

    if len(timestamps) == 1:
        default_timestamp = timestamps[0]
    else:
        default_timestamp = []

    selected_trf_deliveries = st.multiselect(
        "Select TRF delivery timestamp(s)",
        timestamps,
        default=default_timestamp,
        key=f"{key_namespace}_trf_deliveries",
    )

    if not selected_trf_deliveries:
        return {}
    """
    #### TRF filepath(s)
    """

    selected_filepaths = [
        timestamp_filepath_map[timestamp]
        for timestamp in selected_trf_deliveries
    ]
    [str(path.resolve()) for path in selected_filepaths]
    """
    #### Log file header(s)
    """

    headers = []
    tables = []
    for path in selected_filepaths:
        header, table = read_trf(path)
        headers.append(header)
        tables.append(table)

    headers = pd.concat(headers)
    headers.reset_index(inplace=True)
    headers.drop("index", axis=1, inplace=True)

    headers
    """
    #### Corresponding Mosaiq SQL Details
    """

    mosaiq_details = get_logfile_mosaiq_info(headers)
    mosaiq_details = mosaiq_details.drop("beam_completed", axis=1)

    mosaiq_details

    patient_names = set()
    for _, row in mosaiq_details.iterrows():
        row
        patient_name = utl_patient.convert_patient_name_from_split(
            row["last_name"], row["first_name"])
        patient_names.add(patient_name)

    patient_name = filter_patient_names(patient_names)

    deliveries = cached_deliveries_loading(tables, delivery_from_trf)

    individual_identifiers = [
        f"{path.parent.parent.parent.parent.name} {path.parent.name}"
        for path in selected_filepaths
    ]

    identifier = f"TRF ({individual_identifiers[0]})"

    return {
        "patient_id": patient_id,
        "patient_name": patient_name,
        "data_paths": selected_filepaths,
        "identifier": identifier,
        "deliveries": deliveries,
    }
예제 #4
0
def icom_input_method(patient_id="",
                      icom_directory=None,
                      key_namespace="",
                      advanced_mode_local=False,
                      **_):
    if icom_directory is None:
        icom_directory = get_default_icom_directory()

    if advanced_mode_local:
        icom_directory = st.text_input(
            "iCOM Patient Directory",
            str(icom_directory),
            key=f"{key_namespace}_icom_directory",
        )

    icom_directory = pathlib.Path(icom_directory)

    if advanced_mode_local:
        patient_id = st.text_input("Patient ID",
                                   patient_id,
                                   key=f"{key_namespace}_patient_id")
        patient_id

    icom_deliveries = list(icom_directory.glob(f"{patient_id}_*/*.xz"))
    icom_deliveries = sorted(icom_deliveries)

    icom_files_to_choose_from = [path.stem for path in icom_deliveries]

    timestamps = list(
        pd.to_datetime(icom_files_to_choose_from,
                       format="%Y%m%d_%H%M%S").astype(str))
    """
    Here you need to select the timestamps that correspond to a single
    fraction of the plan selected above. Most of the time
    you will only need to select one timestamp here, however in some
    cases you may need to select multiple timestamps.

    This can occur if for example a single fraction was delivered in separate
    beams due to either a beam interupt, or the fraction being spread
    over multiple energies
    """

    if len(timestamps) == 0:
        if patient_id != "":
            st.write(
                NoRecordsFound(
                    f"No iCOM delivery record found for patient ID {patient_id}"
                ))
        return {"patient_id": patient_id}

    if len(timestamps) == 1:
        default_timestamp = timestamps[0]
    else:
        default_timestamp = []

    timestamps = sorted(timestamps, reverse=True)

    selected_icom_deliveries = st.multiselect(
        "Select iCOM delivery timestamp(s)",
        timestamps,
        default=default_timestamp,
        key=f"{key_namespace}_icom_deliveries",
    )

    icom_filenames = [
        path.replace(" ", "_").replace("-", "").replace(":", "")
        for path in selected_icom_deliveries
    ]

    icom_paths = []
    for icom_filename in icom_filenames:
        icom_paths += list(
            icom_directory.glob(f"{patient_id}_*/{icom_filename}.xz"))

    if advanced_mode_local:
        [str(path.resolve()) for path in icom_paths]

    patient_names = set()
    for icom_path in icom_paths:
        patient_name = str(icom_path.parent.name).split("_")[-1]
        try:
            patient_name = utl_patient.convert_patient_name_from_split(
                *patient_name.split(", "))
        except:  # pylint: disable = bare-except
            pass

        patient_names.add(patient_name)

    patient_name = filter_patient_names(patient_names)

    icom_streams = load_icom_streams(icom_paths)
    deliveries = cached_deliveries_loading(icom_streams, delivery_from_icom)

    if selected_icom_deliveries:
        identifier = f"iCOM ({icom_filenames[0]})"
    else:
        identifier = None

    if len(deliveries) == 0:
        st.write(InputRequired("Please select at least one iCOM delivery"))

    results = {
        "patient_id": patient_id,
        "patient_name": patient_name,
        "icom_directory": str(icom_directory),
        "selected_icom_deliveries": selected_icom_deliveries,
        "data_paths": icom_paths,
        "identifier": identifier,
        "deliveries": deliveries,
    }

    return results
예제 #5
0
파일: _trf.py 프로젝트: lc52520/pymedphys
def trf_input_method(patient_id="", key_namespace="", **_):
    """Streamlit GUI method to facilitate TRF data provision.

    Notes
    -----
    TRF files themselves have no innate patient alignment. An option
    for TRF collection is to use the CLI tool
    ``pymedphys trf orchestrate``. This connects to the SAMBA server
    hosted on the Elekta NSS and downloads the diagnostic backup zips.
    It then takes these TRF files and queries the Mosaiq database using
    time of delivery to identify these with a patient id (Ident.Pat_ID1)
    and name.

    As such, all references to patient ID and name within this
    ``trf_input_method`` are actually a reference to their Mosaiq
    database counterparts.
    """
    FILE_UPLOAD = "File upload"
    INDEXED_TRF_SEARCH = "Search indexed TRF directory"

    import_method = st.radio(
        "TRF import method",
        [FILE_UPLOAD, INDEXED_TRF_SEARCH],
        key=f"{key_namespace}_trf_file_import_method",
    )

    if import_method == FILE_UPLOAD:
        selected_files = st.file_uploader(
            "Upload TRF files",
            key=f"{key_namespace}_trf_file_uploader",
            accept_multiple_files=True,
        )

        if not selected_files:
            return {}

        data_paths = []
        individual_identifiers = ["Uploaded TRF file(s)"]

    if import_method == INDEXED_TRF_SEARCH:
        try:
            indexed_trf_directory = _config.get_indexed_trf_directory()
        except KeyError:
            st.write(
                _exceptions.ConfigMissing(
                    "No indexed TRF directory is configured. Please use "
                    f"'{FILE_UPLOAD}' instead."))
            return {}

        patient_id = st.text_input("Patient ID",
                                   patient_id,
                                   key=f"{key_namespace}_patient_id")
        st.write(patient_id)

        filepaths = list(
            indexed_trf_directory.glob(f"*/{patient_id}_*/*/*/*/*.trf"))

        raw_timestamps = [
            "_".join(path.parent.name.split("_")[0:2]) for path in filepaths
        ]
        timestamps = list(
            pd.to_datetime(raw_timestamps,
                           format="%Y-%m-%d_%H%M%S").astype(str))

        timestamp_filepath_map = dict(zip(timestamps, filepaths))

        timestamps = sorted(timestamps, reverse=True)

        if len(timestamps) == 0:
            if patient_id != "":
                st.write(
                    _exceptions.NoRecordsFound(
                        f"No TRF log file found for patient ID {patient_id}"))
            return {"patient_id": patient_id}

        if len(timestamps) == 1:
            default_timestamp = timestamps[0]
        else:
            default_timestamp = []

        selected_trf_deliveries = st.multiselect(
            "Select TRF delivery timestamp(s)",
            timestamps,
            default=default_timestamp,
            key=f"{key_namespace}_trf_deliveries",
        )

        if not selected_trf_deliveries:
            return {}

        st.write("""
            #### TRF filepath(s)
            """)

        selected_files = [
            timestamp_filepath_map[timestamp]
            for timestamp in selected_trf_deliveries
        ]
        st.write([str(path.resolve()) for path in selected_files])

        individual_identifiers = [
            f"{path.parent.parent.parent.parent.name} {path.parent.name}"
            for path in selected_files
        ]

        data_paths = selected_files

    st.write("""
        #### Log file header(s)
        """)

    headers = []
    tables = []
    for path_or_binary in selected_files:
        try:
            path_or_binary.seek(0)
        except AttributeError:
            pass

        header, table = read_trf(path_or_binary)
        headers.append(header)
        tables.append(table)

    headers = pd.concat(headers)
    headers.reset_index(inplace=True)
    headers.drop("index", axis=1, inplace=True)

    st.write(headers)

    deliveries = _deliveries.cached_deliveries_loading(
        tables, _deliveries.delivery_from_trf)

    identifier = f"TRF ({individual_identifiers[0]})"

    patient_name = _attempt_patient_name_from_mosaiq(headers)

    return {
        "site": None,
        "patient_id": patient_id,
        "patient_name": patient_name,
        "data_paths": data_paths,
        "identifier": identifier,
        "deliveries": deliveries,
    }
예제 #6
0
파일: _icom.py 프로젝트: lc52520/pymedphys
def icom_input_method(patient_id="",
                      key_namespace="",
                      advanced_mode_local=False,
                      **_):
    icom_directories = _config.get_default_icom_directories()

    if advanced_mode_local:
        st.write("iCOM patient directories", icom_directories)

    icom_directories = [pathlib.Path(path) for path in icom_directories]

    if advanced_mode_local:
        patient_id = st.text_input("Patient ID",
                                   patient_id,
                                   key=f"{key_namespace}_patient_id")
        st.write(patient_id)

    icom_deliveries = []
    for path in icom_directories:
        icom_deliveries += list(path.glob(f"{patient_id}_*/*.xz"))

    icom_deliveries = sorted(icom_deliveries)

    icom_files_to_choose_from = [path.stem for path in icom_deliveries]

    timestamps = list(
        pd.to_datetime(icom_files_to_choose_from,
                       format="%Y%m%d_%H%M%S").astype(str))

    choice_path_map = dict(zip(timestamps, icom_deliveries))

    st.write("""
        Here you need to select the timestamps that correspond to a single
        fraction of the plan selected above. Most of the time
        you will only need to select one timestamp here, however in some
        cases you may need to select multiple timestamps.

        This can occur if for example a single fraction was delivered in separate
        beams due to either a beam interrupt, or the fraction being spread
        over multiple energies
        """)

    if len(timestamps) == 0:
        if patient_id != "":
            st.write(
                _exceptions.NoRecordsFound(
                    f"No iCOM delivery record found for patient ID {patient_id}"
                ))
        return {"patient_id": patient_id}

    if len(timestamps) == 1:
        default_timestamp = [timestamps[0]]
    else:
        default_timestamp = []

    timestamps = sorted(timestamps, reverse=True)

    try:
        selected_icom_deliveries = st.multiselect(
            "Select iCOM delivery timestamp(s)",
            timestamps,
            default=default_timestamp,
            key=f"{key_namespace}_icom_deliveries",
        )
    except st.errors.StreamlitAPIException:
        st.write(f"Default timestamp = `{default_timestamp}`")
        st.write(f"All timestamps = `{timestamps}`")
        raise

    icom_filenames = [
        path.replace(" ", "_").replace("-", "").replace(":", "")
        for path in selected_icom_deliveries
    ]

    icom_paths = []
    for selected in selected_icom_deliveries:
        icom_paths.append(choice_path_map[selected])

    if advanced_mode_local:
        st.write([str(path.resolve()) for path in icom_paths])

    patient_names = set()
    for icom_path in icom_paths:
        patient_name = str(icom_path.parent.name).split("_")[-1]
        try:
            patient_name = utl_patient.convert_patient_name_from_split(
                *patient_name.split(", "))
        except:  # pylint: disable = bare-except
            pass

        patient_names.add(patient_name)

    patient_name = _utilities.filter_patient_names(patient_names)

    icom_streams = load_icom_streams(icom_paths)
    deliveries = _deliveries.cached_deliveries_loading(
        icom_streams, _deliveries.delivery_from_icom)

    if selected_icom_deliveries:
        identifier = f"iCOM ({icom_filenames[0]})"
    else:
        identifier = None

    if len(deliveries) == 0:
        st.write(
            _exceptions.InputRequired(
                "Please select at least one iCOM delivery"))
        st.stop()

    results = {
        "site": None,
        "patient_id": patient_id,
        "patient_name": patient_name,
        "selected_icom_deliveries": selected_icom_deliveries,
        "data_paths": icom_paths,
        "identifier": identifier,
        "deliveries": deliveries,
    }

    return results