Beispiel #1
0
def patient_counts_by_zip_code(inspector, person_ids=None, return_columns=None):
    """
    Returns patient counts grouped by zip code for the database or alternativily, for a supplied list of person_ids.

    Parameters
    ----------
    person_ids : list of int, optional
        list of person_ids [int].  If None (default), get the gender distribution for all individuals in the person table
    inspector : inspectomop.inspector.Inspector
    return_columns : list of str, optional
        - optional subset of columns to return from the query
        - columns : ['state','zip_code', 'count']

    Returns
    -------
    results : inspectomop.results.Results

    Notes
    -----
    Original SQL

    PE08: Number of patients grouped by zip code of residence::

        SELECT
            state,
            NVL( zip, '9999999' ) AS zip,
            count(\*) Num_Persons_count
        FROM
            person
        LEFT OUTER JOIN
            location
        USING( location_id )
        GROUP BY
            state,
            NVL( zip, '9999999' )
        ORDER BY 1, 2;
    """
    p = _alias(inspector.tables['person'], 'p')
    l = _alias(inspector.tables['location'], 'l')
    j = _join(p, l, p.c.location_id == l.c.location_id)
    columns = [j.c.l_state,j.c.l_zip,_func.count(j.c.l_zip).label('count')]
    if return_columns:
        columns = [col for col in columns if col.name in return_columns]
    if not person_ids:
        statement = _select(columns).\
                    select_from(j).\
                    group_by(j.c.l_state,j.c.l_zip).\
                    order_by(j.c.l_state, j.c.l_zip)
    else:
        statement = _select(columns).\
                    select_from(j).\
                    where(\
                        j.c.p_person_id.in_(person_ids)).\
                    group_by(j.c.l_state, j.c.l_zip).\
                    order_by(j.c.l_state, j.c.l_zip)
    return inspector.execute(statement)
Beispiel #2
0
def indications_for_drug_concept_id(concept_id, inspector,return_columns=None):
    """
    Find all indications for a drug given a concept_id.  Returns matches from NDFRT, FDB, and corresponding SNOMED conditions.

    *Note: The results set should be filtered by 'c_domain_id' == 'Condition'

    Parameters
    ----------
    concept_id : int
    inspector : inspectomop.inspector.Inspector
    return_columns : list of str, optional
        - optional subset of columns to return from the query
        - columns : ['c_concept_id', 'c_concept_name',\
                    'c_domain_id', 'min_levels_of_separation',\
                    'an_concept_id', 'an_concept_name',\
                    'an_vocab', 'de_concept_id',\
                    de_concept_name', 'de_vocab']

    Returns
    -------
    results : inspectomop.results.Results

    Notes
    -----
    SQL (see 2nd example for actual implimentation)

    D13: Find indications as condition concepts for a drug::

        select
            a.min_levels_of_separation as a_min,
            an.concept_id as an_id,
            an.concept_name as an_name,
            an.vocabulary_id as an_vocab,
            an.domain_id as an_domain,
            an.concept_class_id as an_class,
            de.concept_id as de_id,
            de.concept_name as de_name,
            de.vocabulary_id as de_vocab,
            de.domain_id as de_domain,
            de.concept_class_id as de_class
        from
            concept an
        join
            concept_ancestor a on a.ancestor_concept_id=an.concept_id
        join
            concept de on de.concept_id=a.descendant_concept_id
        where
            an.concept_class_id in ('Ind / CI', 'Indication') -- One is for NDFRT, the other for FDB Indications
            and de.vocabulary_id in ('RxNorm', 'RxNorm Extension') -- You don't need that if you join directly with DRUG_EXPOSURE
            and lower(an.concept_name) like '%diabetes%'

    To tie directly to SNOMED concepts, this query is used
        select
            c.concept_id as c_id,
            c.concept_name as c_name,
            c.vocabulary_id as c_vocab,
            c.domain_id as c_domain,
            c.concept_class_id as c_class, -- Condition
            de.concept_id as de_id,
            de.concept_name as de_name,
            de.vocabulary_id as de_vocab,
            de.domain_id as de_domain,
            de.concept_class_id as de_class -- Drug
        from
            concept an -- Indications
        join
            concept_ancestor a on a.ancestor_concept_id=an.concept_id -- connect to
        join
            concept de on de.concept_id=a.descendant_concept_id -- ...drug
        join
            concept_relationship r on r.concept_id_1=an.concept_id -- connect to
        join
            concept c on c.concept_id=r.concept_id_2 and c.domain_id='Condition' -- Snomed Conditions
        where
            an.concept_class_id in ('Ind / CI', 'Indication')
            and de.vocabulary_id in ('RxNorm', 'RxNorm Extension')
            and lower(c.concept_name) like '%diabet%'
"""



    c = _alias(inspector.tables['concept'],'c')
    de  = _alias(inspector.tables['concept'],'de')
    an = _alias(inspector.tables['concept'],'an')
    a = _alias(inspector.tables['concept_ancestor'],'a')
    r = _alias(inspector.tables['concept_relationship'],'r')


    j1 = _join(a, an, a.c.ancestor_concept_id == an.c.concept_id)
    j2 = _join(de, j1, de.c.concept_id == a.c.descendant_concept_id)
    j3 = _join(j2, r, r.c.concept_id_1 == an.c.concept_id)
    domain_id = 'Condition'
    j4 = _join(j3, c, c.c.concept_id == r.c.concept_id_2)

    concept_class_ids = ['Ind / CI', 'Indication']
    vocab_ids= ['RxNorm', 'RxNorm Extension']

    columns = [c.c.concept_id.label('c_concept_id'), c.c.concept_name.label('c_concept_name'),\
                c.c.domain_id.label('c_domain_id'),a.c.min_levels_of_separation,\
                an.c.concept_id.label('an_concept_id'), an.c.concept_name.label('an_concept_name'),\
                an.c.vocabulary_id.label('an_vocab'), de.c.concept_id.label('de_concept_id'),\
                de.c.concept_name.label('de_concept_name'),de.c.vocabulary_id.label('de_vocab')]
    if return_columns:
        columns = [col for col in columns if col.name in return_columns]
    statement = _select(columns).\
                select_from(j4).where(_and_(\
                de.c.concept_id == concept_id,\
                an.c.concept_class_id.in_(concept_class_ids),\
                de.c.vocabulary_id.in_(vocab_ids)
                ))

    return inspector.execute(statement)
Beispiel #3
0
def procedure_concepts_for_keyword(keyword, inspector, return_columns=None):
    """
    Search for all concepts in the procedure domain (includes SNOMED-CT procedures, ICD9 procedures, CPT procedures and HCPCS procedures)
    for a given keyword.

    Parameters
    ----------
    keyword : str
        e.x. 'artery bypass'
    inspector : inspectomop.inspector.Inspector
    return_columns : list of str, optional
        - optional subset of columns to return from the query
        - columns : ['concept_id', 'concept_name', 'concept_code', 'concept_class_id', 'vocabulary_id', 'vocabulary_name']

    Returns
    -------
    results : inspectomop.results.Results

    Notes
    -----
    Original SQL

    P02: Find a procedure from a keyword::

        SELECT C.concept_id         Entity_Concept_Id,
               C.concept_name       Entity_Name,
               C.concept_code       Entity_Code,
               'Concept'            Entity_Type,
               C.concept_class_id      Entity_concept_class_id,
               C.vocabulary_id      Entity_vocabulary_id,
               V.vocabulary_name    Entity_vocabulary_name
        FROM
            concept   C
        INNER JOIN
            vocabulary V ON C.vocabulary_id = V.vocabulary_id
        LEFT OUTER JOIN
            concept_synonym S ON C.concept_id = S.concept_id
        WHERE
            (C.vocabulary_id IN ('ICD9Proc', 'CPT4', 'HCPCS') OR LOWER(C.concept_class_id) = 'procedure') AND
            C.concept_class_id IS NOT NULL AND
            C.standard_concept = 'S' AND
            (REGEXP_INSTR(LOWER(C.concept_name), LOWER('artery bypass')) > 0 OR
            REGEXP_INSTR(LOWER(S.concept_synonym_name), LOWER('artery bypass')) > 0) AND
            sysdate BETWEEN C.valid_start_date AND C.valid_end_date;
    """
    c = _alias(inspector.tables['concept'], 'c')
    v = _alias(inspector.tables['vocabulary'], 'v')
    s = _alias(inspector.tables['concept_synonym'])

    vocab_ids = ['SNOMED', 'ICD9Proc', 'ICD10PCS', 'CPT4', 'HCPCS']
    standard_concept = 'S'
    concept_domain = 'Procedure'
    j = _join(c, s, c.c.concept_id == s.c.concept_id)
    s1 = _select([c.c.concept_id,c.c.concept_name,c.c.concept_code,\
        c.c.concept_class_id, c.c.vocabulary_id, v.c.vocabulary_name]).\
        select_from(j).\
        where(_and_(\
            c.c.vocabulary_id.in_(vocab_ids),\
            c.c.concept_class_id != None,\
            c.c.domain_id == concept_domain,\
            c.c.standard_concept == standard_concept,\
        - seec.c.vocabulary_id == v.c.vocabulary_id))

    columns = [
        s1.c.concept_id, s1.c.concept_name, s1.c.concept_code,
        s1.c.concept_class_id, s1.c.vocabulary_id, s1.c.vocabulary_name
    ]

    if return_columns:
        columns = [col for col in columns if col.name in return_columns]
    statement = _select(columns).select_from(s1).\
        where(\
            _func.lower(s1.c.concept_name).ilike('%{}%'.format(keyword.lower())))

    return inspector.execute(statement)
Beispiel #4
0
def standard_vocab_for_source_code(source_code,
                                   source_vocab_id,
                                   inspector,
                                   return_columns=None):
    """
    Convert source code to all mapped standard vocabulary concepts.

    Parameters
    ----------
    source_codes : str
        alphanumeric source_code to query on e.g ICD-9 '250.00'
    source_vocab_id : str
        - vocabulary_id from the vocabulary table e.g 'ICD9CM'
        - see https://github.com/OHDSI/CommonDataModel/wiki/VOCABULARY for a full list
    inspector : inspectomop.inspector.Inspector
    return_columns : list of str, optional
        - optional subset of columns to return from the query
        - columns : ['domain_id', 'concept_id', 'concept_name', 'concept_code', 'concept_class_id', 'vocabulary_id', 'target_concept_domain']

    Returns
    -------
    results : inspectomop.results.Results

    Notes
    -----
    Original SQL

    G05: Translate a code from a source to a standard vocabulary::

        SELECT DISTINCT
            c1.domain_id,
            c2.concept_id         as Concept_Id,
            c2.concept_name       as Concept_Name,
            c2.concept_code       as Concept_Code,
            c2.concept_class_id   as Concept_Class,
            c2.vocabulary_id      as Concept_Vocabulary_ID,
            c2.domain_id          as Target_concept_Domain
        FROM
            concept_relationship cr
        JOIN
            concept c1 ON c1.concept_id = cr.concept_id_1
        JOIN
            concept c2 ON c2.concept_id = cr.concept_id_2
        WHERE
            cr.relationship_id = 'Maps to' AND
            c1.concept_code IN ('070.0') AND
            c1.vocabulary_id = 'ICD9CM' AND
            sysdate BETWEEN cr.valid_start_date AND cr.valid_end_date;
    """

    c1 = _alias(inspector.tables['concept'], 'c1')
    c2 = _alias(inspector.tables['concept'], 'c2')
    cr = _alias(inspector.tables['concept_relationship'], 'cr')

    columns = [c1.c.domain_id, c2.c.concept_id, \
        c2.c.concept_name, c2.c.concept_code, c2.c.concept_class_id,\
        c2.c.vocabulary_id, c2.c.domain_id.label('target_concept_domain')]

    if return_columns:
        columns = [col for col in columns if col.name in return_columns]

    j1 = _join(cr, c1, c1.c.concept_id == cr.c.concept_id_1)
    j2 = _join(j1, c2, c2.c.concept_id == cr.c.concept_id_2)
    relationship_id = 'Maps to'
    statement = _select(columns).\
                distinct().\
                select_from(j2).\
                where(_and_(\
                    cr.c.relationship_id == relationship_id,\
                    c1.c.concept_code == source_code,\
                    c1.c.vocabulary_id == source_vocab_id))
    return inspector.execute(statement)
Beispiel #5
0
def condition_concepts_for_keyword(keyword, inspector, return_columns=None):
    """
    Retrieves standard concepts for a condition/keyword.

    Parameters
    ----------
    keyword : str
    inspector : inspectomop.inspector.Inspector
    return_columns : list of str, optional
        - optional subset of columns to return from the query
        - columns : ['concept_id', 'concept_name', 'concept_code', 'concept_class_id', 'vocabulary_id']

    Returns
    -------
    results : inspectomop.results.Results
        a cursor-like object with methods such as fetchone(), fetchmany() etc.

    Notes
    -----
    Original SQL

    C02: Find a condition by keyword::

        SELECT
            T.Entity_Concept_Id,
            T.Entity_Name,
            T.Entity_Code,
            T.Entity_Type,
            T.Entity_concept_class,
            T.Entity_vocabulary_id,
            T.Entity_vocabulary_name
        FROM (
            SELECT
                C.concept_id Entity_Concept_Id,
                C.concept_name Entity_Name,
                C.CONCEPT_CODE Entity_Code,
                'Concept' Entity_Type,
                C.concept_class_id Entity_concept_class,
                C.vocabulary_id Entity_vocabulary_id,
                V.vocabulary_name Entity_vocabulary_name,
                NULL Entity_Mapping_Type,
                C.valid_start_date,
                C.valid_end_date
            FROM concept C
            JOIN vocabulary V ON C.vocabulary_id = V.vocabulary_id
            LEFT JOIN concept_synonym S ON C.concept_id = S.concept_id
                WHERE
                    (C.vocabulary_id IN ('SNOMED', 'MedDRA') OR LOWER(C.concept_class_id) = 'clinical finding' ) AND
                    C.concept_class_id IS NOT NULL AND
                    ( LOWER(C.concept_name) like '%myocardial infarction%' OR
                    LOWER(S.concept_synonym_name) like '%myocardial infarction%' )
            ) T
        WHERE sysdate BETWEEN valid_start_date AND valid_end_date
        ORDER BY 6,2;
    """
    c = inspector.tables['concept']
    cs = inspector.tables['concept_synonym']
    v = inspector.tables['vocabulary']

    vocab_ids = ['SNOMED', 'MedDRA']
    concept_class_id = 'clinical_finding'
    columns = [
        c.concept_id, c.concept_name, c.concept_code, c.concept_class_id,
        v.vocabulary_id
    ]
    j = _join(c, v, c.vocabulary_id == v.vocabulary_id)
    j2 = _join(j, cs, c.concept_id == cs.concept_id, isouter=True)
    if return_columns:
        columns = [col for col in columns if col.name in return_columns]
    statement = _select(columns)\
                .select_from(j2)\
                .where(_and_(\
                _or_(c.vocabulary_id.in_(vocab_ids), _func.lower(c.concept_class_id)==concept_class_id),\
                c.concept_class_id != None,\
                _or_(_func.lower(c.concept_name).ilike('%{}%'.format(keyword.lower())),\
                    _func.lower(cs.concept_synonym_name).ilike('%{}%'.format(keyword.lower())))))\
                .distinct()
    return inspector.execute(statement)
Beispiel #6
0
def place_of_service_counts_for_condition_concept_id(condition_concept_id,
                                                     inspector,
                                                     return_columns=None):
    """
    Provides counts of conditions stratified by place_of_service (Office, Inpatient Hospital, etc.)

    Parameters
    ----------
    condition_concept_id : int
        concept_id from the conditions table
    inspector : inspectomop.inspector.Inspector
    return_columns : list of str, optional
        - optional subset of columns to return from the query
        - columns : ['condition_concept_id', 'condition_concept_id,'place_of_service_concept_id', 'place_of_service', 'place_freq']

    Returns
    -------
    results : inspectomop.results.Results
        a cursor-like object with methods such as fetchone(), fetchmany() etc.

    Notes
    -----
    SQL Modified from:

    CO04: Count In what place of service where condition diagnoses::

        SELECT
            c.concept_id AS condition_concept_id,
            c.concept_name AS condition_concept_id,
            cs.place_of_service_concept_id AS place_of_service_concept_id,
            c_place.concept_name AS place_of_service,
            count(cs.place_of_service_concept_id) AS place_freq
        FROM
            main.concept AS c, main.concept AS c_place,
            (SELECT
                co.condition_concept_id AS condition_concept_id,
                co.visit_occurrence_id AS s1_visit_id
            FROM
                main.condition_occurrence AS co
            WHERE
                co.condition_concept_id = :condition_concept_id_1
                AND co.visit_occurrence_id IS NOT NULL)
        JOIN
            main.visit_occurrence AS vo
        ON
            s1_visit_id = vo.visit_occurrence_id
        JOIN
            main.care_site AS cs
        ON
            vo.care_site_id = cs.care_site_id
        WHERE
            c_place.concept_id = cs.place_of_service_concept_id
            AND c.concept_id = :concept_id_1
        GROUP BY c.concept_name
    """
    co = _alias(inspector.tables['condition_occurrence'], 'co')
    cs = _alias(inspector.tables['care_site'], 'cs')
    vo = _alias(inspector.tables['visit_occurrence'], 'vo')
    c_place = _alias(inspector.tables['concept'], 'c_place')
    c = _alias(inspector.tables['concept'], 'c')

    s1 = _select([
        co.c.condition_concept_id,
        co.c.visit_occurrence_id.label('s1_visit_id')
    ]).where(
        _and_(co.c.condition_concept_id == condition_concept_id,
              co.c.visit_occurrence_id != None))
    j1 = _join(s1, vo, s1.c.s1_visit_id == vo.c.visit_occurrence_id)
    j2 = _join(j1, cs, j1.c.vo_care_site_id == cs.c.care_site_id)

    columns = [
        c.c.concept_id.label('condition_concept_id'),
        c.c.concept_name.label('condition_concept_id'),
        j2.c.cs_place_of_service_concept_id.label(
            'place_of_service_concept_id'),
        c_place.c.concept_name.label('place_of_service'),
        _func.count(j2.c.cs_place_of_service_concept_id).label('place_freq')
    ]

    if return_columns:
        columns = [col for col in columns if col.name in return_columns]

    statement = _select(columns).\
         select_from(j2).\
         where(_and_(c_place.c.concept_id == j2.c.cs_place_of_service_concept_id, c.c.concept_id == condition_concept_id)).group_by(c.c.concept_name)

    return inspector.execute(statement)