def index(): """Display the Scout dashboard.""" accessible_institutes = None if not 'admin' in current_user.roles: accessible_institutes = current_user.institutes if not accessible_institutes: flash( 'Not allowed to see information - please visit the dashboard later!' ) return redirect(url_for('cases.index')) institutes = [inst for inst in store.institutes(accessible_institutes)] # Insert a entry that displays all institutes in the beginning of the array institutes.insert(0, {'_id': None, 'display_name': 'All institutes'}) institute_id = None if request.method == 'POST': institute_id = request.form.get('institute') LOG.info("Fetch all cases with institute: %s", institute_id) data = get_dashboard_info(store, institute_id) data['institutes'] = institutes data['choice'] = institute_id total_cases = data['total_cases'] LOG.info("Found %s cases", total_cases) if total_cases == 0: flash( 'no cases loaded for institute {} - please visit the dashboard later!' .format(institute_id), 'info') return redirect(url_for('cases.index')) return render_template('dashboard/index.html', **data)
def populate_institute_form(form, institute_obj): """Populate institute settings form Args: form(scout.server.blueprints.institutes.models.InstituteForm) institute_obj(dict) An institute object """ # get all other institutes to populate the select of the possible collaborators institutes_tuples = [] for inst in store.institutes(): if not inst["_id"] == institute_obj["_id"]: institutes_tuples.append(((inst["_id"], inst["display_name"]))) form.display_name.default = institute_obj.get("display_name") form.institutes.choices = institutes_tuples form.coverage_cutoff.default = institute_obj.get("coverage_cutoff") form.frequency_cutoff.default = institute_obj.get("frequency_cutoff") # collect all available default HPO terms default_phenotypes = [choice[0].split(" ")[0] for choice in form.pheno_groups.choices] if institute_obj.get("phenotype_groups"): for key, value in institute_obj["phenotype_groups"].items(): if not key in default_phenotypes: custom_group = " ".join( [key, ",", value.get("name"), "( {} )".format(value.get("abbr"))] ) form.pheno_groups.choices.append((custom_group, custom_group)) return default_phenotypes
def download_verified(): """Download all verified variants for user's cases""" user_obj = store.user(current_user.email) user_institutes = ( [inst["_id"] for inst in store.institutes()] if current_user.is_admin else user_obj.get("institutes") ) temp_excel_dir = os.path.join(variants_bp.static_folder, "verified_folder") os.makedirs(temp_excel_dir, exist_ok=True) if controllers.verified_excel_file(store, user_institutes, temp_excel_dir): data = zip_dir_to_obj(temp_excel_dir) # remove temp folder with excel files in it shutil.rmtree(temp_excel_dir) today = datetime.datetime.now().strftime("%Y-%m-%d") return send_file( data, mimetype="application/zip", as_attachment=True, download_name="_".join(["scout", "verified_variants", today]) + ".zip", cache_timeout=0, ) # remove temp folder with excel files in it shutil.rmtree(temp_excel_dir) flash("No verified variants could be exported for user's institutes", "warning") return redirect(request.referrer)
def index(): """Display the Scout dashboard.""" accessible_institutes = current_user.institutes if not 'admin' in current_user.roles: accessible_institutes = current_user.institutes if not accessible_institutes: flash('Not allowed to see information - please visit the dashboard later!') return redirect(url_for('cases.dahboard_general.html')) LOG.debug('User accessible institutes: {}'.format(accessible_institutes)) institutes = [inst for inst in store.institutes(accessible_institutes)] # Insert a entry that displays all institutes in the beginning of the array institutes.insert(0, {'_id': None, 'display_name': 'All institutes'}) institute_id = None slice_query = None panel=1 if request.method=='POST': institute_id = request.form.get('institute') slice_query = request.form.get('query') panel=request.form.get('pane_id') elif request.method=='GET': institute_id = request.args.get('institute') slice_query = request.args.get('query') # User should be restricted to their own institute if: #1) Their default institute when the page is first loaded #2) if they ask for an institute that they don't belong to #3) if they want perform a query on all institutes if not institute_id: institute_id = accessible_institutes[0] elif (not current_user.is_admin) and (slice_query and institute_id == 'None'): institute_id = accessible_institutes[0] elif (not institute_id in accessible_institutes) and not (institute_id == 'None'): institute_id = accessible_institutes[0] LOG.info("Fetch all cases with institute: %s", institute_id) data = get_dashboard_info(store, institute_id, slice_query) data['institutes'] = institutes data['choice'] = institute_id total_cases = data['total_cases'] LOG.info("Found %s cases", total_cases) if total_cases == 0: flash('no cases found for institute {} (with that query) - please visit the dashboard later!'.format(institute_id), 'info') # return redirect(url_for('cases.index')) return render_template( 'dashboard/dashboard_general.html', institute=institute_id, query=slice_query, panel=panel, **data)
def institute(institute_id): """ Edit institute data """ if institute_id not in current_user.institutes and current_user.is_admin is False: flash( "Current user doesn't have the permission to modify this institute", "warning", ) return redirect(request.referrer) institute_obj = store.institute(institute_id) form = InstituteForm(request.form) # if institute is to be updated if request.method == "POST" and form.validate_on_submit(): institute_obj = controllers.update_institute_settings( store, institute_obj, request.form) if isinstance(institute_obj, dict): flash("institute was updated ", "success") else: # an error message was retuned flash(institute_obj, "warning") return redirect(request.referrer) data = controllers.institute(store, institute_id) # get all other institutes to populate the select of the possible collaborators institutes_tuples = [] for inst in store.institutes(): if not inst["_id"] == institute_id: institutes_tuples.append(((inst["_id"], inst["display_name"]))) form.display_name.default = institute_obj.get("display_name") form.institutes.choices = institutes_tuples form.coverage_cutoff.default = institute_obj.get("coverage_cutoff") form.frequency_cutoff.default = institute_obj.get("frequency_cutoff") # collect all available default HPO terms default_phenotypes = [ choice[0].split(" ")[0] for choice in form.pheno_groups.choices ] if institute_obj.get("phenotype_groups"): for key, value in institute_obj["phenotype_groups"].items(): if not key in default_phenotypes: custom_group = " ".join([ key, ",", value.get("name"), "( {} )".format(value.get("abbr")) ]) form.pheno_groups.choices.append((custom_group, custom_group)) return render_template("/overview/institute.html", form=form, default_phenotypes=default_phenotypes, **data)
def populate_institute_form(form, institute_obj): """Populate institute settings form Args: form(scout.server.blueprints.institutes.models.InstituteForm) institute_obj(dict) An institute object """ # get all other institutes to populate the select of the possible collaborators institutes_tuples = [] for inst in store.institutes(): if not inst["_id"] == institute_obj["_id"]: institutes_tuples.append(((inst["_id"], inst["display_name"]))) form.display_name.default = institute_obj.get("display_name") form.institutes.choices = institutes_tuples form.coverage_cutoff.default = institute_obj.get("coverage_cutoff") form.frequency_cutoff.default = institute_obj.get("frequency_cutoff") # collect all available default HPO terms and populate the pheno_groups form select with these values default_phenotypes = [ choice[0].split(" ")[0] for choice in form.pheno_groups.choices ] if institute_obj.get("phenotype_groups"): for key, value in institute_obj["phenotype_groups"].items(): if not key in default_phenotypes: custom_group = " ".join([ key, ",", value.get("name"), "( {} )".format(value.get("abbr")) ]) form.pheno_groups.choices.append((custom_group, custom_group)) # populate gene panels multiselect with panels from institute available_panels = list(store.latest_panels(institute_obj["_id"])) # And from institute's collaborators for collaborator in institute_obj.get("collaborators", []): available_panels += list(store.latest_panels(collaborator)) panel_set = set() for panel in available_panels: panel_set.add((panel["panel_name"], panel["display_name"])) form.gene_panels.choices = sorted(panel_set, key=lambda tup: tup[1]) return default_phenotypes
def index(): """Display the Scout dashboard.""" accessible_institutes = current_user.institutes if not 'admin' in current_user.roles: accessible_institutes = current_user.institutes if not accessible_institutes: flash( 'Not allowed to see information - please visit the dashboard later!' ) return redirect(url_for('cases.dahboard_general.html')) LOG.debug('User accessible institutes: {}'.format(accessible_institutes)) institutes = [inst for inst in store.institutes(accessible_institutes)] # Insert a entry that displays all institutes in the beginning of the array institutes.insert(0, {'_id': None, 'display_name': 'All institutes'}) institute_id = None slice_query = None panel = 1 if request.method == 'POST': institute_id = request.form.get('institute') slice_query = request.form.get('query') panel = request.form.get('pane_id') elif request.method == 'GET': institute_id = request.args.get('institute') slice_query = request.args.get('query') # User should be restricted to their own institute if: #1) Their default institute when the page is first loaded #2) if they ask for an institute that they don't belong to #3) if they want perform a query on all institutes if not institute_id: institute_id = accessible_institutes[0] elif (not current_user.is_admin) and (slice_query and institute_id == 'None'): institute_id = accessible_institutes[0] elif (not institute_id in accessible_institutes) and not (institute_id == 'None'): institute_id = accessible_institutes[0] LOG.info("Fetch all cases with institute: %s", institute_id) data = get_dashboard_info(store, institute_id, slice_query) data['institutes'] = institutes data['choice'] = institute_id total_cases = data['total_cases'] LOG.info("Found %s cases", total_cases) if total_cases == 0: flash( 'no cases found for institute {} (with that query) - please visit the dashboard later!' .format(institute_id), 'info') # return redirect(url_for('cases.index')) return render_template('dashboard/dashboard_general.html', institute=institute_id, query=slice_query, panel=panel, **data)
def case(store, institute_obj, case_obj): """Preprocess a single case. Prepare the case to be displayed in the case view. Args: store(adapter.MongoAdapter) institute_obj(models.Institute) case_obj(models.Case) Returns: data(dict): includes the cases, how many there are and the limit. """ # Convert individual information to more readable format case_obj["individual_ids"] = [] for individual in case_obj["individuals"]: try: sex = int(individual.get("sex", 0)) except ValueError as err: sex = 0 individual["sex_human"] = SEX_MAP[sex] pheno_map = PHENOTYPE_MAP if case_obj.get("track", "rare") == "cancer": pheno_map = CANCER_PHENOTYPE_MAP individual["phenotype_human"] = pheno_map.get(individual["phenotype"]) case_obj["individual_ids"].append(individual["individual_id"]) case_obj["assignees"] = [store.user(user_email) for user_email in case_obj.get("assignees", [])] # Provide basic info on alignment files availability for this case case_has_alignments(case_obj) case_has_mt_alignments(case_obj) case_groups = {} case_group_label = {} _populate_case_groups(store, case_obj, case_groups, case_group_label) # Fetch the variant objects for suspects and causatives suspects = [ store.variant(variant_id) or variant_id for variant_id in case_obj.get("suspects", []) ] _populate_assessments(suspects) causatives = [ store.variant(variant_id) or variant_id for variant_id in case_obj.get("causatives", []) ] _populate_assessments(causatives) # get evaluated variants evaluated_variants = store.evaluated_variants(case_obj["_id"], case_obj["owner"]) _populate_assessments(evaluated_variants) # check for partial causatives and associated phenotypes partial_causatives = [] if case_obj.get("partial_causatives"): for var_id, values in case_obj["partial_causatives"].items(): causative_obj = { "variant": store.variant(var_id) or var_id, "omim_terms": values.get("diagnosis_phenotypes"), "hpo_terms": values.get("phenotype_terms"), } partial_causatives.append(causative_obj) _populate_assessments(partial_causatives) # Set of all unique genes in the default gene panels distinct_genes = set() case_obj["panel_names"] = [] case_obj["outdated_panels"] = {} for panel_info in case_obj.get("panels", []): if not panel_info.get("is_default"): continue panel_name = panel_info["panel_name"] panel_version = panel_info.get("version") panel_obj = store.gene_panel(panel_name, version=panel_version) latest_panel = store.gene_panel(panel_name) panel_info["removed"] = False if latest_panel is None else latest_panel.get("hidden", False) if not panel_obj: panel_obj = latest_panel if not panel_obj: flash(f"Case default panel '{panel_name}' could not be found.", "warning") continue flash( f"Case default panel '{panel_name}' version {panel_version} could not be found, using latest existing version", "warning", ) # Check if case-specific panel is up-to-date with latest version of the panel if panel_obj["version"] < latest_panel["version"]: extra_genes, missing_genes = _check_outdated_gene_panel(panel_obj, latest_panel) if extra_genes or missing_genes: case_obj["outdated_panels"][panel_name] = { "missing_genes": missing_genes, "extra_genes": extra_genes, } distinct_genes.update([gene["hgnc_id"] for gene in panel_obj.get("genes", [])]) full_name = "{} ({})".format(panel_obj["display_name"], panel_obj["version"]) case_obj["panel_names"].append(full_name) case_obj["default_genes"] = list(distinct_genes) for hpo_term in itertools.chain( case_obj.get("phenotype_groups", []), case_obj.get("phenotype_terms", []) ): hpo_term["hpo_link"] = "http://hpo.jax.org/app/browse/term/{}".format( hpo_term["phenotype_id"] ) if case_obj.get("rank_model_version"): rank_model_link = "".join( [ current_app.config.get("RANK_MODEL_LINK_PREFIX", ""), str(case_obj["rank_model_version"]), current_app.config.get("RANK_MODEL_LINK_POSTFIX", ""), ] ) case_obj["rank_model_link"] = rank_model_link if case_obj.get("sv_rank_model_version"): case_obj["sv_rank_model_link"] = "".join( [ current_app.config.get("SV_RANK_MODEL_LINK_PREFIX", ""), str(case_obj["sv_rank_model_version"]), current_app.config.get("SV_RANK_MODEL_LINK_POSTFIX", ""), ] ) # other collaborators than the owner of the case o_collaborators = [] for collab_id in case_obj.get("collaborators", []): if collab_id != case_obj["owner"] and store.institute(collab_id): o_collaborators.append(store.institute(collab_id)) case_obj["o_collaborators"] = [ (collab_obj["_id"], collab_obj["display_name"]) for collab_obj in o_collaborators ] collab_ids = None if institute_obj.get("collaborators"): collab_ids = [ (collab["_id"], collab["display_name"]) for collab in store.institutes() if institute_obj.get("collaborators") and collab["_id"] in institute_obj.get("collaborators") ] events = list(store.events(institute_obj, case=case_obj))
def index(): """Display the Scout dashboard.""" accessible_institutes = current_user.institutes if not "admin" in current_user.roles: accessible_institutes = current_user.institutes if not accessible_institutes: flash( "Not allowed to see information - please visit the dashboard later!" ) return redirect(url_for("cases.dahboard_general.html")) LOG.debug("User accessible institutes: {}".format(accessible_institutes)) institutes = [inst for inst in store.institutes(accessible_institutes)] # Insert a entry that displays all institutes in the beginning of the array institutes.insert(0, {"_id": None, "display_name": "All institutes"}) institute_id = None slice_query = None panel = 1 if request.method == "POST": institute_id = request.form.get("institute") slice_query = request.form.get("query") panel = request.form.get("pane_id") elif request.method == "GET": institute_id = request.args.get("institute") slice_query = request.args.get("query") # User should be restricted to their own institute if: # 1) Their default institute when the page is first loaded # 2) if they ask for an institute that they don't belong to # 3) if they want perform a query on all institutes if not institute_id: institute_id = accessible_institutes[0] elif (not current_user.is_admin) and (slice_query and institute_id == "None"): institute_id = accessible_institutes[0] elif (not institute_id in accessible_institutes) and not (institute_id == "None"): institute_id = accessible_institutes[0] LOG.info("Fetch all cases with institute: %s", institute_id) data = get_dashboard_info(store, institute_id, slice_query) data["institutes"] = institutes data["choice"] = institute_id total_cases = data["total_cases"] LOG.info("Found %s cases", total_cases) if total_cases == 0: flash( "no cases found for institute {} (with that query) - please visit the dashboard later!" .format(institute_id), "info", ) # return redirect(url_for('cases.index')) return render_template("dashboard/dashboard_general.html", institute=institute_id, query=slice_query, panel=panel, **data)