def run_trials(run_id): """ Returns the trials from a given run-id. You can filter the returned trias by supplying 'intv' for intervention types to be included and 'phases' for trial phases to be active """ # from pycallgraph import PyCallGraph # from pycallgraph.output import GraphvizOutput # with PyCallGraph(output=GraphvizOutput()): runner = Runner.get(run_id) if runner is None: bottle.abort(404) if not runner.done: bottle.abort(400, "Trials are not yet available") # get request vars intv = bottle.request.query.intv intv = intv.split('|') if intv else [] phases = bottle.request.query.phases phases = phases.split('|') if phases else [] reload_phases = bottle.request.query.reload_phases ret_dict = { 'trials': runner.trials_json(intv, phases) } if reload_phases: ret_dict['drug_phases'] = runner.trial_phases(intv) return json.dumps(ret_dict)
def run_trials(run_id): """ Returns the trials from a given run-id. You can filter the returned trias by supplying 'intv' for intervention types to be included and 'phases' for trial phases to be active """ # from pycallgraph import PyCallGraph # from pycallgraph.output import GraphvizOutput # with PyCallGraph(output=GraphvizOutput()): runner = Runner.get(run_id) if runner is None: bottle.abort(404) if not runner.done: bottle.abort(400, "Trials are not yet available") # get request vars intv = bottle.request.query.intv intv = intv.split('|') if intv else [] phases = bottle.request.query.phases phases = phases.split('|') if phases else [] reload_phases = bottle.request.query.reload_phases ret_dict = {'trials': runner.trials_json(intv, phases)} if reload_phases: ret_dict['drug_phases'] = runner.trial_phases(intv) return json.dumps(ret_dict)
def trial_progress(run_id): """ Returns text status from the file corresponding to the given run-id, if it's missing returns a 404. """ runner = Runner.get(run_id) if runner is None: bottle.abort(404) return runner.status
def run_overview(run_id): """ Overview results for a run. """ runner = Runner.get(run_id) if runner is None: bottle.abort(404) try: overview = runner.overview() except Exception as e: bottle.abort(400, e) return json.dumps(overview)
def trials_filter_by(run_id, filter_by): runner = Runner.get(run_id) if runner is None: bottle.abort(404) if not runner.done: bottle.abort(400, "Trial results are not available") ncts = runner.get_ncts(restrict='none') sess = _get_session() run_data = sess.get('runs', {}).get(run_id, {}) # demographics - get age and gender if 'demographics' == filter_by: f_gender = run_data.get('gender') f_age = int(run_data.get('age', 0)) for tpl in ncts: nct = tpl[0] reason = tpl[1] if len(tpl) > 1 else None if not reason: trial = Trial(nct) trial.load() # filter gender if f_gender: if 'male' == f_gender: if trial.eligibility.gender == 2: reason = "Limited to women" else: if trial.eligibility.gender == 1: reason = "Limited to men" # filter age if f_age > 0: if trial.eligibility.min_age and trial.eligibility.min_age > f_age: reason = "Patient is too young (min age %d)" % trial.eligibility.min_age elif trial.eligibility.max_age and trial.eligibility.max_age < f_age: reason = "Patient is too old (max age %d)" % trial.eligibility.max_age # TODO: REFACTOR into runner class! if reason: runner.write_trial_reason(nct, reason) runner.commit_transactions() # problems (only if NLP is on) elif 'problems' == filter_by: if USE_NLP: probs = problems().get('problems', []) # extract snomed codes from patient's problem list snomed = SNOMEDLookup() exclusion_codes = [] for problem in probs: snomed_url = problem.get('sp:problemName', {}).get('sp:code', {}).get('@id') if snomed_url is not None: snomed_code = os.path.basename(snomed_url) exclusion_codes.append(snomed_code) # look at trial criteria for tpl in ncts: nct = tpl[0] reason = tpl[1] if len(tpl) > 1 else None # if we already have a reason, this trial has already been filtered if not reason: trial = Trial(nct) trial.load() # exclusion criterion matched if trial.filter_snomed(exclusion_codes) is not None: reason = 'Matches exclusion criterium "%s" (SNOMED %s)' % ( snomed.lookup_code_meaning(match, True, True), match) break # TODO: REFACTOR # runner.write_trial_reason(nct, reason) # unknown filtering property else: return '{"error": "We can not filter by %s"}' % filter_by return '{"status": "ok"}'
def find_trials(): """ Initiates the chain to find trials for the given condition or search- term. Supply with parameters: - "cond" or "term", the prior taking precedence - "gender" ('male' or 'female') - "age" (in years) - "latlng", comma-separated latitude and longituted of the patient - "remember_input" if the condition or term should be stored in the session This method forks off and prints the status to a file which can be read by calling /trials_status/<run-id>. "run-id" is returned from this call. """ # get the runner run_id = datetime.now().isoformat() runner = Runner.get(run_id) if runner is None: runner = Runner(run_id, "run-server") runner.in_background = True # configure cond = bottle.request.query.get('cond') term = bottle.request.query.get('term') if cond: cond = re.sub(r'\s+\((disorder|finding)\)', '', cond) runner.condition = cond elif term: term = re.sub(r'\s+-(\w+)', r' NOT \1', term) term = re.sub(r'\s*([^\w\d])\s+([^-])', r' AND \2', term) runner.term = term else: bottle.abort(400, 'You need to specify "cond" or "term"') # latitude and longitude latlng = bottle.request.query.get('latlng') if latlng is None or 0 == len(latlng): latlng = '42.358,-71.06' # default to Boston parts = latlng.split(',', 2) if parts is None or 2 != len(parts): bottle.abort(400, '"latlng" must be two numbers separated by a comma') lat = parts[0] lng = parts[1] runner.reference_location = (lat, lng) # store in session age = bottle.request.query.get('age') sess = _get_session() runs = sess.get('runs', {}) runs[run_id] = { 'cond': cond, 'gender': bottle.request.query.get('gender'), 'age': int(age) if age else None, 'latlng': latlng } sess['runs'] = runs if 'true' == bottle.request.query.get('remember_input'): if cond or term: sess['last_manual_input'] = cond or term elif 'last_manual_input' in sess: del sess['last_manual_input'] # launch and return id runner.run([ 'id', 'acronym', 'keyword', 'brief_title', 'official_title', 'brief_summary', 'overall_contact', 'eligibility', 'location', 'attributes', 'intervention', 'intervention_browse', 'phase', 'study_design', 'primary_outcome' ]) return run_id
def trials_filter_by(run_id, filter_by): runner = Runner.get(run_id) if runner is None: bottle.abort(404) if not runner.done: bottle.abort(400, "Trial results are not available") ncts = runner.get_ncts(restrict='none') sess = _get_session() run_data = sess.get('runs', {}).get(run_id, {}) # demographics - get age and gender if 'demographics' == filter_by: f_gender = run_data.get('gender') f_age = int(run_data.get('age', 0)) for tpl in ncts: nct = tpl[0] reason = tpl[1] if len(tpl) > 1 else None if not reason: trial = Trial(nct) trial.load() # filter gender if f_gender: if 'male' == f_gender: if trial.eligibility.gender == 2: reason = "Limited to women" else: if trial.eligibility.gender == 1: reason = "Limited to men" # filter age if f_age > 0: if trial.eligibility.min_age and trial.eligibility.min_age > f_age: reason = "Patient is too young (min age %d)" % trial.eligibility.min_age elif trial.eligibility.max_age and trial.eligibility.max_age < f_age: reason = "Patient is too old (max age %d)" % trial.eligibility.max_age # TODO: REFACTOR into runner class! if reason: runner.write_trial_reason(nct, reason) runner.commit_transactions() # problems (only if NLP is on) elif 'problems' == filter_by: if USE_NLP: probs = problems().get('problems', []) # extract snomed codes from patient's problem list snomed = SNOMEDLookup() exclusion_codes = [] for problem in probs: snomed_url = problem.get('sp:problemName', {}).get('sp:code', {}).get('@id') if snomed_url is not None: snomed_code = os.path.basename(snomed_url) exclusion_codes.append(snomed_code) # look at trial criteria for tpl in ncts: nct = tpl[0] reason = tpl[1] if len(tpl) > 1 else None # if we already have a reason, this trial has already been filtered if not reason: trial = Trial(nct) trial.load() # exclusion criterion matched if trial.filter_snomed(exclusion_codes) is not None: reason = 'Matches exclusion criterium "%s" (SNOMED %s)' % (snomed.lookup_code_meaning(match, True, True), match) break # TODO: REFACTOR # runner.write_trial_reason(nct, reason) # unknown filtering property else: return '{"error": "We can not filter by %s"}' % filter_by return '{"status": "ok"}'
def find_trials(): """ Initiates the chain to find trials for the given condition or search- term. Supply with parameters: - "cond" or "term", the prior taking precedence - "gender" ('male' or 'female') - "age" (in years) - "latlng", comma-separated latitude and longituted of the patient - "remember_input" if the condition or term should be stored in the session This method forks off and prints the status to a file which can be read by calling /trials_status/<run-id>. "run-id" is returned from this call. """ # get the runner run_id = datetime.now().isoformat() runner = Runner.get(run_id) if runner is None: runner = Runner(run_id, "run-server") runner.in_background = True # configure cond = bottle.request.query.get('cond') term = bottle.request.query.get('term') if cond: cond = re.sub(r'\s+\((disorder|finding)\)', '', cond) runner.condition = cond elif term: term = re.sub(r'\s+-(\w+)', r' NOT \1', term) term = re.sub(r'\s*([^\w\d])\s+([^-])', r' AND \2', term) runner.term = term else: bottle.abort(400, 'You need to specify "cond" or "term"') # latitude and longitude latlng = bottle.request.query.get('latlng') if latlng is None or 0 == len(latlng): latlng = '42.358,-71.06' # default to Boston parts = latlng.split(',', 2) if parts is None or 2 != len(parts): bottle.abort(400, '"latlng" must be two numbers separated by a comma') lat = parts[0] lng = parts[1] runner.reference_location = (lat, lng) # store in session age = bottle.request.query.get('age') sess = _get_session() runs = sess.get('runs', {}) runs[run_id] = { 'cond': cond, 'gender': bottle.request.query.get('gender'), 'age': int(age) if age else None, 'latlng': latlng } sess['runs'] = runs if 'true' == bottle.request.query.get('remember_input'): if cond or term: sess['last_manual_input'] = cond or term elif 'last_manual_input' in sess: del sess['last_manual_input'] # launch and return id runner.run(['id', 'acronym', 'keyword', 'brief_title', 'official_title', 'brief_summary', 'overall_contact', 'eligibility', 'location', 'attributes', 'intervention', 'intervention_browse', 'phase', 'study_design', 'primary_outcome']) return run_id