Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: use regbot for clinical trial fetching #89

Merged
merged 4 commits into from
Dec 31, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 85 additions & 38 deletions src/dgipy/integrations/clinical_trials.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,90 @@

import logging

from regbot.fetch.clinical_trials import StandardAge
from regbot.fetch.clinical_trials import StandardAge, Status, Study
from regbot.fetch.clinical_trials import get_clinical_trials as get_trials_from_fda

_logger = logging.getLogger(__name__)


def _add_study_to_output(output: dict[str, list], drug_name: str, study: Study) -> None:
"""Update `output` in-place with results from study

:param output: in-progress raw columnar data

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing drug_name

:param study: clinical trial study data to add to output
"""
output["drug_name"].append(drug_name.upper())
output["trial_id"].append(study.protocol.identification.nct_id)
output["brief"].append(study.protocol.identification.brief_title)
output["study_type"].append(study.protocol.design.study_type)
min_age = (
study.protocol.eligibility.min_age
if study.protocol and study.protocol.eligibility
else None
)
output["min_age"].append(min_age)
max_age = (
study.protocol.eligibility.max_age
if study.protocol and study.protocol.eligibility
else None
)
output["max_age"].append(max_age)
age_groups = (
study.protocol.eligibility.std_age
if study.protocol and study.protocol.eligibility
else None
)
output["age_groups"].append(age_groups)
output["pediatric"].append(StandardAge.CHILD in age_groups if age_groups else None)
output["conditions"].append(
study.protocol.conditions.conditions
if study.protocol and study.protocol.conditions
else None
)
output["interventions"].append(
[i._asdict() for i in study.protocol.arms_intervention.interventions]
if study.protocol
and study.protocol.arms_intervention
and study.protocol.arms_intervention.interventions
else None
)
eligibility = study.protocol.eligibility
if not eligibility:
output["incl_excl_criteria"].append(None)
output["population_sex"].append(None)
output["population_description"]
else:
output["incl_excl_criteria"].append(eligibility.description)
output["population_sex"].append(eligibility.sex)
output["population_description"].append(eligibility.population)
all_locations = (
study.protocol.contacts_locations.locations
if study.protocol.contacts_locations
and study.protocol.contacts_locations.locations
else []
)

potential_sites = [
{
"name": location.facility,
"status": location.status,
"city": location.city,
"country": location.country,
"coordinates": location.geo,
}
for location in all_locations
if location.status
in {
Status.RECRUITING,
Status.NOT_YET_RECRUITING,
Status.AVAILABLE,
Status.TEMPORARILY_NOT_AVAILABLE,
Status.UNKNOWN,
}
]
output["potential_sites"].append(potential_sites)


def get_clinical_trials(terms: list[str]) -> dict:
"""Acquire associated clinical trials data for drug term

Expand Down Expand Up @@ -41,47 +119,16 @@ def get_clinical_trials(terms: list[str]) -> dict:
"pediatric": [],
"conditions": [],
"interventions": [],
"incl_excl_criteria": [],
"population_sex": [],
"population_description": [],
"potential_sites": [],
}

for drug in terms:
results = get_trials_from_fda(drug)

for study in results:
output["drug_name"].append(drug.upper())
output["trial_id"].append(study.protocol.identification.nct_id)
output["brief"].append(study.protocol.identification.brief_title)
output["study_type"].append(study.protocol.design.study_type)
min_age = (
study.protocol.eligibility.min_age
if study.protocol and study.protocol.eligibility
else None
)
output["min_age"].append(min_age)
max_age = (
study.protocol.eligibility.max_age
if study.protocol and study.protocol.eligibility
else None
)
output["max_age"].append(max_age)
age_groups = (
study.protocol.eligibility.std_age
if study.protocol and study.protocol.eligibility
else None
)
output["age_groups"].append(age_groups)
output["pediatric"].append(
StandardAge.CHILD in age_groups if age_groups else None
)
output["conditions"].append(
study.protocol.conditions.conditions
if study.protocol and study.protocol.conditions
else None
)
output["interventions"].append(
[i._asdict() for i in study.protocol.arms_intervention.interventions]
if study.protocol
and study.protocol.arms_intervention
and study.protocol.arms_intervention.interventions
else None
)
_add_study_to_output(output, drug, study)

return output
18 changes: 17 additions & 1 deletion tests/integrations/test_clinical_trials.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
from pathlib import Path

import requests_mock
from regbot.fetch.clinical_trials import InterventionType, StandardAge, StudyType
from regbot.fetch.clinical_trials import (
InterventionType,
StandardAge,
Status,
StudyType,
)

from dgipy.integrations.clinical_trials import get_clinical_trials

Expand Down Expand Up @@ -63,3 +68,14 @@ def test_get_clinical_trials(fixtures_dir: Path):
"aliases": ["AVXS-101", "Zolgensma"],
}
]
assert (
results["incl_excl_criteria"][example_index]
== "Inclusion Criteria\n\n* SMA diagnosis\n* Aged 2 to \\< 18 years\n* Have had at least four loading doses of nusinersen (Spinraza\u00ae) or at least 3 months of treatment with risdiplam (Evrysdi\u00ae) at Screening\n* Must have symptoms of SMA as defined in the protocol\n\nExclusion Criteria:\n\n* Anti Adeno Associated Virus Serotype 9 (AAV9) antibody titer using an immunoassay is reported as elevated\n* Clinically significant abnormalities in test results during screening\n* Contraindications for lumbar puncture procedure\n* At Baseline, participants are excluded if they received:\n\n * nusinersen (Spinraza\u00ae) or\n * risdiplam (Evrysdi\u00ae) within a defined timeframe\n* Vaccinations 2 weeks prior to administration of OAV101\n* Hospitalization for a pulmonary event, or for nutritional support within 2 months prior to Screening or inpatient major surgery planned.\n* Presence of an infection or febrile illness up to 30 days prior to administration of OAV101\n* Requiring invasive ventilation"
)
assert {
"name": "Child Hosp of the Kings Daughters",
"status": Status.RECRUITING,
"city": "Norfolk",
"country": "United States",
"coordinates": (36.84681, -76.28522),
} in results["potential_sites"][3]
Loading