Esempio n. 1
0
def sex(patient, unit, timestamp):
    if patient == None:
        return Right({
            "variableValue": {
                "value": None
            },
            "certitude": 0,
            "how": "record not found"
        })
    else:
        gender = patient.get("gender")
        if gender is None:
            return Right({
                "variableValue": {
                    "value": None
                },
                "certitude": 0,
                "how": "gender not set"
            })
        else:
            return Right({
                "variableValue": {
                    "value": gender
                },
                "certitude":
                2,
                "how":
                f"FHIR resource 'Patient' field>'gender' = {gender}"
            })
Esempio n. 2
0
def merge_array(a, b, err):
    if a is None:
        return Right(b)
    elif b is None:
        return Right(a)
    else:
        return Right(a + [elem for elem in b if elem not in a])
Esempio n. 3
0
def address(pat):
    extensions = pat.get("extension", [])
    lat = list(
        map(
            lambda x: x["valueDecimal"],
            filter(lambda x: x.get("url", "").lower() == "latitude",
                   extensions)))
    lon = list(
        map(
            lambda x: x["valueDecimal"],
            filter(lambda x: x.get("url", "").lower() == "longitude",
                   extensions)))
    if len(lat) > 1:
        return Left("more than one latitudes")
    if len(lon) > 1:
        return Left("more than one longitudes")
    if len(lat) == 0:
        if len(lon) == 0:
            return Right(None)
        else:
            return Left("a longitude without a latitude")
    elif len(lon) == 0:
        return Left("a latitude without a longitude")
    else:
        return Right({"latitude": lat[0], "longitude": lon[0]})
Esempio n. 4
0
def query_feature(table, feature):
    feature_def = features_dict[table][feature]
    ty = feature_def["type"]
    if ty == "string":
        if "enum" not in feature_def:
            return Left("node has type string but has no enum")
        else:
            return Right({
                "feature_name":
                feature,
                "feature_qualifiers": [{
                    "operator": "=",
                    "value": v
                } for v in feature_def["enum"]]
            })
    elif ty == "integer":
        if "maximum" not in feature_def or "minimum" not in feature_def:
            return Left(
                "node has type integer but has no maximum or has no minimum")
        else:
            return Right({
                "feature_name":
                feature,
                "feature_qualifiers": [{
                    "operator": "=",
                    "value": v
                } for v in range(feature_def["minimum"],
                                 feature_def["maximum"] + 1)]
            })
    else:
        return Left(f"unsupported node type {ty}")
Esempio n. 5
0
    def handle_records_filtered(records_filtered):
        if len(records_filtered) == 0:
            from_code = calculation(codes)
            return Right({
                "variableValue": {
                    "value": None
                },
                "certitude": 0,
                "how": f"no record found code {from_code}"
            })
        else:
            ts = timestamp.timestamp()

            def key(a):
                return extract_key(a).rec(
                    lambda ext_key: diff_func(strtots(ext_key) - ts),
                    float("inf"))

            records_filtered_key = [(a, key(a)) for a in records_filtered]
            records_with_key = [
                a for a in records_filtered_key if a[1] is not None
            ]

            if len(records_with_key) == 0:
                return Right({
                    "variableValue": {
                        "value": None
                    },
                    "certitude": 0,
                    "how": f"no record found code {from_code}"
                })
            else:
                record = min(records_with_key, key=lambda a: a[1])[0]
                return convert_record_to_pds(record, unit, timestamp,
                                             clinical_variable, resource_name)
Esempio n. 6
0
def merge(a, b, err):
    if a is None:
        return Right(b)
    elif b is None:
        return Right(a)
    elif a == b:
        return Right(a)
    else:
        return Left(f"err={err} a={a} b={b}")
Esempio n. 7
0
    def func(patient, unit, timestamp):
        if patient == None:
            return Right({
                "variableValue": {
                    "value": None
                },
                "certitude": 0,
                "how": "record not found"
            })
        else:
            extension = patient.get("extension")
            if extension is None:
                return Right({
                    "variableValue": {
                        "value": None
                    },
                    "certitude": 0,
                    "how": "extension not found"
                })
            else:

                filtered = filter(lambda x: x["url"] == url, extension)
                if len(filtered) == 0:
                    return Right({
                        "variableValue": {
                            "value": None
                        },
                        "certitude": 0,
                        "how": f"extension not found url {url}"
                    })
                else:
                    certitude = 2
                    value = []
                    calculation = url
                    hasValueCodeableConcept = True

                    for a in filtered:
                        valueCodeableConcept = a.get("valueCodeableConcept")
                        if valueCodeableConcept is None:
                            certitude = 1
                            calculation += " valueCodeableConcept not found"
                        else:
                            hasValueCodeableConcept = True
                            value.append(valueCodeableConcept)

                    if len(value) == 0:
                        certitude = 0
                    elif not hasValueCodeableConcept:
                        calculation += " on some extension"

                    return Right({
                        "variableValue": {
                            "value": value
                        },
                        "certitude": certitude,
                        "how": calculation
                    })
Esempio n. 8
0
def one(xs):
    if len(xs) == 1:
        return Right(xs[0])
    elif len(xs) == 0:
        return Right(None)
    else:
        return Left({
            "variableValue": {
                "value": None
            },
            "how": "more than one record found",
            "certitude": 0
        })
Esempio n. 9
0
def convert_record_to_pds(record, unit, timestamp, clinical_variable,
                          resource_name):
    ts = extract_key(record)
    cert = ts.rec(const(2), 1)
    vq = record.get("valueQuantity")
    if vq is not None:
        v = vq["value"]
        from_u = vq.get("unit")
        if from_u is None:
            from_u = vq.get("code")
        mv = convert(v, from_u, unit)
        if isinstance(mv, Left):
            return mv
        else:
            v = mv.value
    else:
        v = True
        from_u = None
    c = calculation_template(clinical_variable, resource_name, timestamp,
                             record, unit)
    return Right({
        "variableValue": {
            "value":
            v,
            **({
                "unit": unit
            } if unit is not None else {
                   "unit": from_u
               } if from_u is not None else {}),
        },
        "certitude": cert,
        "timestamp": maybe.to_python(ts),
        "how": c
    })
Esempio n. 10
0
def filter_records(records, codes, resource_name):
    records_filtered = []
    for record in records:
        logger.info(f"filtering record: {record}")
        for c in codes:
            system = c["system"]
            code = c["code"]
            is_regex = c["is_regex"]

            if resource_name == "MedicationRequest":
                code2 = record.get("medication",
                                   {}).get("medicationCodeableConcept")
            else:
                code2 = record.get("code")

            if code2 is None:
                return Left({
                    "error": f"malformated record: no code",
                    "record": record
                })
            coding2 = code2.get("coding")
            if coding2 is None:
                return Left({
                    "error": f"malformated record: no coding under code",
                    "record": record
                })
            for c2 in coding2:
                if c2["system"] == system:
                    if (is_regex and re.search(code, "^" + c2["code"] +
                                               "$")) or c2["code"] == code:
                        records_filtered.append(record)
    return Right(records_filtered)
Esempio n. 11
0
def calculate_age2(born, timestamp):
    try:
        today = strtodate(timestamp)
    except Exception as e:
        return Left({"error": str(e)})
    return Right(today.year - born.year -
                 ((today.month, today.day) < (born.month, born.day)))
Esempio n. 12
0
def get_features_by_identifier(table, identifier):
    if table in input_dict:
        identifier_dict = input_dict[table]
    else:
        raise Left(f"Cannot find table {table}, available {input_dict}")

    return Right([feature for feature, identifiers in identifier_dict.items() if identifier in identifiers])
Esempio n. 13
0
def sequence(l):
    l2 = []
    for x in l:
        if isinstance(x, Left):
            return x
        else:
            l2.append(x.value)
    return Right(l2)
Esempio n. 14
0
def update_key(d, ok, nk):
    curr_keys = list(d.keys())
    if ok in curr_keys:
        i = curr_keys.index(ok)
        d.insert(i, nk, d.pop(ok))
        return Right(())
    else:
        return Left(f"variable {ok} no longer exists")
Esempio n. 15
0
def age(patient, unit, timestamp):
    if unit is not None and unit != "year":
        return Left((f"unsupported unit {unit}", 400))

    if patient == None:
        return Right({
            "variableValue": {
                "value": None
            },
            "certitude": 0,
            "how": "record not found"
        })
    else:
        if "birthDate" in patient:
            birth_date = patient["birthDate"]
            date_of_birth = strtodate2(birth_date)
            today = timestamp.strftime("%Y-%m-%d")
            mage = calculate_age2(date_of_birth, timestamp)
            return mage.map(
                lambda age: {
                    "variableValue": {
                        "value": age,
                        "unit": "year"
                    },
                    "certitude": 2,
                    "how": {
                        "request_timestamp": today,
                        "computed_from": ["request_timestamp", "birthDate"],
                        "birthDate": {
                            "computed_from": {
                                "resourceType": "Patient",
                                "field": "birthDate"
                            },
                            "value": birth_date
                        }
                    }
                })
        else:
            return Right({
                "variableValue": {
                    "value": None
                },
                "certitude": 0,
                "how": "birthDate not set"
            })
Esempio n. 16
0
def ethnicities(pat):
    extensions = pat.get("extension", [])
    return Right(
        list(
            map(
                lambda x: x["valueString"],
                filter(
                    lambda x: x.get("url") in ethnicity_urls and "valueString"
                    in x, extensions))))
Esempio n. 17
0
def address(patient, unit, timestamp):
    if patient == None:
        return Right({
            "variableValue": {
                "value": None
            },
            "certitude": 0,
            "how": "record not found"
        })
    else:
        address = patient.get("address")
        if address is None:
            return Right({
                "variableValue": {
                    "value": None
                },
                "certitude": 0,
                "how": "address not set"
            })
        else:
            # use home type address if available, otherwise, just use the first address
            used_addr_dict = None
            for addr in address:
                if addr['use'] == 'home':
                    used_addr_dict = addr
                    break
            if not used_addr_dict:
                used_addr_dict = address[0]
            used_addr_str = '{line}, {city}, {state} {pc}, {country}'.format(
                line=','.join(used_addr_dict['line']),
                city=used_addr_dict['city'],
                state=used_addr_dict['state'],
                pc=used_addr_dict['postalCode'],
                country=used_addr_dict['country'])
            return Right({
                "variableValue": {
                    "value": used_addr_str
                },
                "certitude":
                2,
                "how":
                f"FHIR resource 'Patient' field>'address' = {used_addr_str}"
            })
Esempio n. 18
0
    def get(self, table, key):
        FHIR, GEOID, NearestRoad, NearestPoint, Visit = self.get_sub_objects()
        FHIR_keys, GEOID_keys, NearestRoad_keys, NearestPoint_keys, Visit_keys = self.get_sub_keys(
            FHIR, GEOID, NearestRoad, NearestPoint, Visit)
        if key in FHIR_keys:
            return Right(self.obj["FHIR"][key])

        for name, keys in GEOID_keys.items():
            if key in keys:
                return Right(GEOID[name])

        for name, keys in NearestRoad_keys.items():
            if old_key in keys:
                return Right(NearestRoad[name])

        for name, keys in NearestPoint_keys.items():
            if old_key in keys:
                return Right(NearestPoint[name])

        return Left(f"variable {old_key} no longer exists")
Esempio n. 19
0
    def update_key(self, table, old_key, new_key):
        FHIR, GEOID, NearestRoad, NearestPoint, Visit = self.get_sub_objects()
        FHIR_keys, GEOID_keys, NearestRoad_keys, NearestPoint_keys, Visit_keys = self.get_sub_keys(
            FHIR, GEOID, NearestRoad, NearestPoint, Visit)
        if old_key in FHIR_keys:
            update_key(self.obj["FHIR"], old_key, new_key)
            return Right(())

        for name, keys in GEOID_keys.items():
            if old_key in keys:
                columns = GEOID[name]["columns"]
                for column_name, var_name in columns.items():
                    if var_name == old_key:
                        columns[column_name] = new_key
                        return Right(())

        for name, keys in NearestRoad_keys.items():
            if old_key in keys:
                nearest_road = NearestRoad[name]
                if old_key == nearest_road["distance_feature_name"]:
                    nearest_road["distance_feature_name"] = new_key
                else:
                    for attribute_name, feature in nearest_road[
                            "attributes_to_features_map"].items():
                        if feature["feature_name"] == old_key:
                            feature["feature_name"] = new_key
                            return Right(())

        for name, keys in NearestPoint_keys.items():
            if old_key in keys:
                nearest_point = NearestPoint[name]
                if old_key == nearest_point["distance_feature_name"]:
                    nearest_point["distance_feature_name"] = new_key
                else:
                    for attribute_name, feature in nearest_point[
                            "attributes_to_features_map"].items():
                        if feature["feature_name"] == old_key:
                            feature["feature_name"] = new_key
                            return Right(())

        return Left(f"variable {old_key} no longer exists")
Esempio n. 20
0
def set_races(pat, races):
    extensions = pat.get("extension", [])
    pat["extension"] = list(
        filter(lambda x: x.get("url") not in race_urls, extensions)) + list(
            map(
                lambda race: {
                    "url": race_urls[0],
                    "extension": [{
                        "valueString": race
                    }]
                }, races))
    return Right(pat)
Esempio n. 21
0
def set_ethnicities(pat, ethnicities):
    extensions = pat.get("extension", [])
    pat["extension"] = list(
        filter(lambda x: x.get("url") not in ethnicity_urls,
               extensions)) + list(
                   map(
                       lambda ethnicity: {
                           "url": ethnicity_urls[0],
                           "extension": [{
                               "valueString": ethnicity
                           }]
                       }, ethnicities))
    return Right(pat)
Esempio n. 22
0
def age(patient, unit, timestamp):
    if unit is not None and unit != "year":
        return Left((f"unsupported unit {unit}", 400))

    if patient == None:
        return Right({
            "variableValue": {
                "value": None
            },
            "certitude": 0,
            "how": "record not found"
        })
    else:
        if "birthDate" in patient:
            birth_date = patient["birthDate"]
            date_of_birth = strtodate(birth_date)
            today = strtodate(timestamp).strftime("%Y-%m-%d")
            mage = calculate_age2(date_of_birth, timestamp)
            return mage.map(
                lambda age: {
                    "variableValue": {
                        "value": age,
                        "units": "year"
                    },
                    "certitude":
                    2,
                    "how":
                    f"Current date '{today}' minus patient's birthdate (FHIR resource 'Patient' field>'birthDate' = '{birth_date}')"
                })
        else:
            return Right({
                "variableValue": {
                    "value": None
                },
                "certitude": 0,
                "how": "birthDate not set"
            })
Esempio n. 23
0
    def update_value(self, table, key, new_value):
        FHIR, GEOID, NearestRoad, NearestPoint, Visit = self.get_sub_objects()
        FHIR_keys, GEOID_keys, NearestRoad_keys, NearestPoint_keys, Visit_keys = self.get_sub_keys(
            FHIR, GEOID, NearestRoad, NearestPoint, Visit)
        if key in FHIR_keys:
            self.obj["FHIR"][key] = new_value
            return Right(())

        for name, keys in GEOID_keys.items():
            if key in keys:
                GEOID[name] = new_value
                return Right(())

        for name, keys in NearestRoad_keys.items():
            if key in keys:
                NearestRoad[name] = new_value
                return Right(())

        for name, keys in NearestPoint_keys.items():
            if key in keys:
                NearestPoint[name] = new_value
                return Right(())

        return Left(f"variable {key} no longer exists")
Esempio n. 24
0
def set_addresses(pat, addresses):
    pat["address"] = list(
        map(
            lambda address: {
                "extension": [{
                    "url":
                    None,
                    "extension": [{
                        "url": "latitude",
                        "valueDecimal": address["latitude"]
                    }, {
                        "url": "longitude",
                        "valueDecimal": address["longitude"]
                    }]
                }]
            }, addresses))
    return Right(pat)
Esempio n. 25
0
 def handle_requests(requests):
     rescs = []
     for request in requests:
         method = request["method"]
         url = request["url"]
         result = urlsplit(url)
         pcs = result.path.split("/")
         qcs = map(lambda x: x.split("="), result.query.split("&"))
         if pcs[1] == "Patient":
             rescs.append(_get_patient(pcs[2]))
         else:
             patient_id = None
             for qc in qcs:
                 if qc[0] == "patient":
                     patient_id = qc[1]
             rescs.append(_get_resource(pcs[1], patient_id))
     return Right(bundle(rescs, "batch-response"))
Esempio n. 26
0
 def handle_src_and_tgt_features(src_features, tgt_features):
     edge_property_value = []
     for src_feature in src_features:
         for tgt_feature in tgt_features:
             edge = co_occurrence_feature_edge(conn, table, year,
                                               cohort_features, src_feature,
                                               tgt_feature)
             if isinstance(edge, Right):
                 edge_property_value.append({
                     "src_feature": src_feature,
                     "tgt_feature": tgt_feature,
                     "p_value": edge.value
                 })
             else:
                 return edge
     if len(edge_property_value) == 0:
         return Left("no edge found")
     else:
         return Right(edge_property_value)
Esempio n. 27
0
def validateTable(ctx, tablename, tfname, kvp):
    with open(tfname, "r", newline="", encoding="utf-8") as tfi:
        reader = csv.reader(tfi)
        header = next(reader)
        n = len(header)
        i = 0
        for row in reader:
            n2 = len(row)
            if n2 != n:
                return Left(f"row {i} number of items, expected {n}, encountered {n2}")
            i += 1
        seen = set()
        dups = []
        for x in header:
            if x in seen:
                dups.append(x)
            else:
                seen.add(x)
        if len(dups) > 0:
            return Left(f"duplicate header(s) in upload {dups}")
        header2 = list(kvp.keys())
        i2 = [a for a in header if a in header2]
        if len(i2) > 0:
            return Left(f"duplicate header(s) in input {i2}")
        conn = connect(user=ctx["dbuser"], password=ctx["dbpass"], host=ctx["dbhost"], dbname=ctx["dbname"])
        cursor = conn.cursor()
        try:
            cursor.execute('''
select column_name, data_type
from information_schema.columns
where table_schema NOT IN ('information_schema', 'pg_catalog') and table_name=%s
order by table_schema, table_name
''', (tablename,))
            rows = cursor.fetchall()
            header3 = list(map(lambda r:r[0], rows))
            d2 = [a for a in header + header2 if a not in header3]
            if len(d2) > 0:
                return Left(f"undefined header(s) in input {d2} available {header3}")
            return Right(())
        finally:
            cursor.close()
            conn.close()
Esempio n. 28
0
def error_code(result):
    return result.rec(
        lambda err: Left(("not found", 404)
                         if err[0]["status_code"] == 404 else err),
        lambda config: Right(config))
Esempio n. 29
0
 def cfvo_to_cfvo2(cfvo):
     cfvo2 = {**cfvo}
     return Right(cfvo2)
Esempio n. 30
0
def set_gender(pat, gender):
    pat["gender"] = gender
    return Right(pat)