コード例 #1
0
ファイル: run.py プロジェクト: nhsx/SynPath
def _update_patient_and_environment(
    patient: PatientAgent,
    environment: Union[
        AandEEnvironmentAgent, EnvironmentAgent, GPEnvironmentAgent, COEnvironmentAgent, OPEnvironmentAgent, IPEnvironmentAgent
    ],
    interactions: List[str],
    simulation_step: int,
    patient_time: datetime.datetime,
    update_data: dict,
    patient_record_duplicate_action: str,
    main_logger: logging.Logger,
    patient_logger: logging.Logger,
) -> None:

    supported_fhir_resources = get_supported_fhir_resources()
    required_entry_fields = get_required_entry_fields()

    new_patient_record_entries = update_data["new_patient_record_entries"]

    for entry in new_patient_record_entries:
        missing_entry_fields = required_entry_fields - set(entry)
        if len(missing_entry_fields) > 0:
            raise ValueError(
                "Each patient record entry must contain all the following "
                f"keys: {required_entry_fields}. Entry {entry} is missing "
                f"{missing_entry_fields} generated by interactions "
                f"{interactions}"
            )
        if entry["resource_type"] not in supported_fhir_resources:
            raise ValueError(
                "Currently can only support the following FHIR resources: "
                f"{supported_fhir_resources}. Found {entry['resource_type']}"
            )

    patient.update(
        [
            wrap_fhir_resource(
                entry,
                patient_time,
                environment.environment_id,
                interactions,
                simulation_step,
            )
            for entry in new_patient_record_entries
        ],
        logger=patient_logger,
        skip_existing=patient_record_duplicate_action == "skip",
    )
    environment.update(patient, update_data.get("patient_data"))
コード例 #2
0
ファイル: test_patient.py プロジェクト: nhsx/SynPath
def test_patient_conditions_update():
    patient_id = 2468
    gender = "female"
    birth_date = "1985-05-24"

    patient = PatientAgent(
        patient_id=patient_id,
        gender=gender,
        birth_date=birth_date,
    )

    condition_entry = {
        "resource_type": "Condition",
        "name": "Fever",
        "start": "2021-03-21",
    }

    patient_time = datetime.datetime.now(patient.tz)
    patient.update([wrap_fhir_resource(condition_entry, patient_time)])
コード例 #3
0
ファイル: test_patient.py プロジェクト: nhsx/SynPath
def test_initialize_patient_agent_minimal():

    patient_id = 2468
    gender = "female"
    birth_date = "1985-05-24"
    start_time = "2020-12-01"
    agent_id = 12345
    created_at = "2021-03-09"

    patient = PatientAgent(
        patient_id=patient_id,
        gender=gender,
        birth_date=birth_date,
        start_time=start_time,
        id_=agent_id,
        created_at=created_at,
    )

    patient_profile = {
        "resource_type": "Patient",
        "id": str(patient_id),
        "gender": gender,
        "birth_date": birth_date,
    }
    wrapped_entry = wrap_fhir_resource(
        patient_profile,
        patient_time=string_to_datetime(start_time),
        environment_id=-1,
        tag="patient_profile",
    )

    wrapped_entry["real_time"] = string_to_datetime(created_at)
    wrapped_entry["record_index"] = 0
    wrapped_entry["entry_id"] = patient.record[0].entry_id

    initial_patient_resource = PatientRecordEntry(**wrapped_entry)

    assert patient.id == agent_id
    assert patient.created_at == string_to_datetime(created_at)
    assert patient.__repr__() == (
        f"PatientAgent(id={agent_id}, "
        f"created_at={string_to_datetime(created_at)})")
    assert patient.record == [initial_patient_resource]
コード例 #4
0
ファイル: test_fhir.py プロジェクト: nhsx/SynPath
def test_convert_patient_record_entry_to_fhir():

    fhir_handler = FHIRHandler()

    patient = PatientAgent(
        patient_id="patient-0",
        gender="male",
        birth_date="1956-07-26",
    )

    entry_id = "test-entry-0"
    record_entry = PatientRecordEntry(
        real_time="",
        patient_time="",
        environment_id=None,
        interactions=None,
        simulation_step=None,
        fhir_resource_time="",
        fhir_resource_type="",
        fhir_resource={},
        record_index=0,
        entry_id=entry_id,
        entry={},
        tag="test-entry",
    )

    # NOTE: all these keys and more can be in entry but they won't
    # all get used in every resource
    # TODO: write func to return keys used by resource, also which ones are
    # required
    entry = {
        "name": "some name",
        "code": "xxx",
        "start": string_to_datetime("2021-01-10 09:00:00"),
        "end": string_to_datetime("2021-01-10 09:15:00"),
        "reason": "some reason",
        "description": "some description",
        "dosage": "some dosage",
        "duration_value": 10,
        "duration_unit": "some duration_unit",
        "value": {
            "value": 6.3,
            "unit": "mmol/l",
            "system": "http://unitsofmeasure.org",
            "code": "mmol/L",
        },
    }
    record_entry.entry = entry

    supported_fhir_resources = get_supported_fhir_resources()

    for fhir_resource_type in supported_fhir_resources:

        record_entry.fhir_resource_type = fhir_resource_type

        resource = convert_patient_record_entry_to_fhir(record_entry,
                                                        patient,
                                                        environments=None)

        assert fhir_handler.validate(resource, fhir_resource_type)

    entries = []
    for fhir_resource_type in supported_fhir_resources:
        entry["resource_type"] = fhir_resource_type
        entry["name"] = f"some name in resource {fhir_resource_type}"
        entries.append(wrap_fhir_resource(entry, entry["start"]))

    patient._update_record(entries)

    environments = None

    resources = generate_patient_fhir_resources(
        patient,
        environments,
        validate=True,
        server_url=None,
    )

    bundle_path = TEST_DATA_DIR / f"patient_{patient.patient_id}_bundle.json"

    generate_patient_fhir_bundle(
        patient,
        environments,
        bundle_type="transaction",
        validate=True,
        server_url=None,
        save_path=bundle_path,
    )

    bundle = fhir_handler.load(bundle_path,
                               "Bundle",
                               server_url=None,
                               validate=True)
コード例 #5
0
ファイル: test_patient.py プロジェクト: nhsx/SynPath
def test_initialize_patient_agent_with_comorbities():

    patient_id = 2468
    gender = "female"
    birth_date = "1985-05-24"
    start_time = "2020-12-01"
    agent_id = 12345
    created_at = "2021-03-09"

    comorbidity = {
        "resource_type": "Condition",
        "name": "Diabetes",
        "start": "2018-10-21",
    }
    wrapped_comorbidity = wrap_fhir_resource(
        comorbidity,
        patient_time=string_to_datetime(comorbidity["start"]),
        environment_id=-1,
        tag="comorbidity_diabetes",
    )
    wrapped_comorbidity["real_time"] = string_to_datetime(created_at)

    telecom = {"system": "phone", "value": "555-113-5410", "use": "home"}
    age = 35

    kwargs = {
        "patient__telecom": telecom,
        "age": age,
    }

    initial_record = [wrapped_comorbidity]

    patient = PatientAgent(
        patient_id=patient_id,
        gender=gender,
        birth_date=birth_date,
        start_time=start_time,
        id_=agent_id,
        created_at=created_at,
        record=initial_record,
        **kwargs,
    )

    patient_profile = {
        "resource_type": "Patient",
        "id": str(patient_id),
        "gender": gender,
        "birth_date": birth_date,
        "telecom": telecom,
    }
    wrapped_patient_profile = wrap_fhir_resource(
        patient_profile,
        patient_time=string_to_datetime(start_time),
        environment_id=-1,
        tag="patient_profile",
    )

    wrapped_patient_profile["real_time"] = string_to_datetime(created_at)
    wrapped_patient_profile["record_index"] = 0
    wrapped_patient_profile["entry_id"] = patient.record[0].entry_id

    initial_patient_entry = PatientRecordEntry(**wrapped_patient_profile)

    wrapped_comorbidity["real_time"] = string_to_datetime(created_at)
    wrapped_comorbidity["record_index"] = 1
    wrapped_comorbidity["entry_id"] = patient.record[1].entry_id

    comorbidity_entry = PatientRecordEntry(**wrapped_comorbidity)

    assert patient.id == agent_id
    assert patient.created_at == string_to_datetime(created_at)
    assert (patient.__repr__() == f"PatientAgent(id={agent_id}, "
            f"created_at={string_to_datetime(created_at)})")
    assert patient.age == age
    assert patient.patient__telecom == telecom
    assert len(patient.record) == 2
    assert patient.record[0] == initial_patient_entry
    assert patient.record[1] == comorbidity_entry
    assert len(patient.conditions) == 1
    assert len(patient.medications) == 0
    assert len(patient.actions) == 0
コード例 #6
0
ファイル: test_patient.py プロジェクト: nhsx/SynPath
def test_update_patient_agent():

    patient_id = 2468
    gender = "female"
    birth_date = "1985-05-24"
    patient_start_time = "2020-12-01"
    agent_id = 12345
    created_at = "2021-03-09"

    patient = PatientAgent(
        patient_id=patient_id,
        gender=gender,
        birth_date=birth_date,
        patient_start_time=patient_start_time,
        id_=agent_id,
        created_at=created_at,
    )

    assert len(patient.record) == 1
    assert len(patient.conditions) == 0

    comorbidity = {
        "resource_type": "Condition",
        "name": "Diabetes",
        "start": "2018-10-21",
    }
    wrapped_comorbidity = wrap_fhir_resource(
        comorbidity,
        patient_time=string_to_datetime(comorbidity["start"]),
        environment_id=-1,
        tag="comorbidity_diabetes",
    )
    wrapped_comorbidity["real_time"] = string_to_datetime(created_at)

    patient.update([wrapped_comorbidity])

    wrapped_comorbidity["record_index"] = 1
    wrapped_comorbidity["entry_id"] = patient.record[1].entry_id

    assert len(patient.record) == 2
    assert len(patient.conditions) == 1
    assert asdict(patient.record[-1]) == wrapped_comorbidity

    patient.update([wrapped_comorbidity], skip_existing=False)

    assert len(patient.record) == 3
    assert len(patient.conditions) == 1
    assert asdict(patient.record[-1]) == wrapped_comorbidity

    patient.update([wrapped_comorbidity], skip_existing=True)

    assert len(patient.record) == 3
    assert len(patient.conditions) == 1
    assert asdict(patient.record[-1]) == wrapped_comorbidity

    assert patient.conditions["active"][0]
    assert patient.conditions["end"][0] is None

    wrapped_comorbidity = copy.deepcopy(wrapped_comorbidity)
    wrapped_comorbidity["entry"]["end"] = "2020-10-21"

    patient.update([wrapped_comorbidity], skip_existing=True)

    assert len(patient.record) == 4
    assert len(patient.conditions) == 1
    assert asdict(patient.record[-1]) == wrapped_comorbidity

    assert not patient.conditions["active"][0]
    assert patient.conditions["end"][0] == string_to_datetime(
        wrapped_comorbidity["entry"]["end"])

    patient_agent_path = TEST_DATA_DIR / "patient_agent.tar"

    patient.save(patient_agent_path)

    _patient = PatientAgent.load(patient_agent_path)

    dfs = ["conditions", "medications", "actions"]

    for attr_name in PatientAgent.serialisable_attributes:
        if attr_name in dfs:
            # NOTE: there is some discreapncy between the two data frames:
            # in one, the timestamps can appear with timezone tz="tzutc()"
            # whereas in the other they are tz="UTC", and this causes the
            # equality check to fail - this is why .astype(str) has been
            # applied to both dataframes. We leave it to future work to
            # iron out this detail
            assert (getattr(patient, attr_name).astype(str).equals(
                getattr(_patient, attr_name).astype(str)))
        else:
            assert getattr(patient, attr_name) == getattr(_patient, attr_name)

    patient_agent_path.unlink()