Example #1
0
def _update_subpanel(subpanel_obj, supb_changes):
    """Update the checkboxes of a subpanel according to checkboxes checked in the model preview.

    Args:
        subpanel_obj(dict): a subpanel object
        supb_changes(dict): terms to keep under a parent term. example: {"HP:0001250": [(HP:0020207, HP:0020215, HP:0001327]}

    Returns:
        subpanel_obj(dict): an updated subpanel object
    """
    checkboxes = subpanel_obj.get("checkboxes", {})
    new_checkboxes = {}
    for parent, children_list in supb_changes.items():
        # create mini tree obj from terms in changes dict. Add all nodes at the top level initially
        root = Node(id="root", name="root", parent=None)
        all_terms = {}
        # loop over the terms to keep into the checboxes dict
        for child in children_list:
            if child.startswith("OMIM"):
                new_checkboxes[child] = checkboxes[child]
                continue
            custom_name = None
            term_title = None
            if child in checkboxes:
                custom_name = checkboxes[child].get("custom_name")
                term_title = checkboxes[child].get("term_title")
            term_obj = store.hpo_term(
                child)  # else it's an HPO term, and might have nested term:
            node = None
            try:
                node = Node(child,
                            parent=root,
                            description=term_obj["description"])
            except Exception as ex:
                flash(f"Term {child} could not be find in database")
                continue
            all_terms[child] = term_obj
            if custom_name:
                node.custom_name = custom_name
            if term_title:
                node.term_title = term_title

        # Rearrange tree nodes according the HPO ontology
        root = store.organize_tree(all_terms, root)
        LOG.info(f"Updated HPO tree:{root}:\n{RenderTree(root)}")
        exporter = DictExporter()
        for child_node in root.children:
            # export node to dict
            node_dict = exporter.export(child_node)
            new_checkboxes[child_node.name] = node_dict

    subpanel_obj["checkboxes"] = new_checkboxes
    subpanel_obj["updated"] = datetime.datetime.now()
    return subpanel_obj
Example #2
0
def _subpanel_hpo_checkgroup_add(model_dict, user_form):
    """Add an HPO term (and eventually his children) to a phenotype subpanel

    Args:
        model_dict(dict): a dictionary coresponding to a phenotype model
        user_form(request.form): a POST request form object

    Returns:
        model_dict(dict): an updated phenotype model dictionary to be saved to database
    """
    hpo_id = user_form.get("hpo_term").split(" ")[0]
    hpo_obj = store.hpo_term(hpo_id)
    if hpo_obj is None:  # user didn't provide a valid HPO term
        flash("Please specify a valid HPO term", "warning")
        return
    subpanel_id = user_form.get("hpo_subpanel_id")
    tree_dict = {}
    checkboxes = model_dict["subpanels"][subpanel_id].get("checkboxes", {})

    if hpo_id in checkboxes:  # Do not include duplicated HPO terms in checkbox items
        flash(f"Subpanel contains already HPO term '{hpo_id}'", "warning")
        return
    if user_form.get(
            "includeChildren"):  # include HPO terms children in the checkboxes
        tree_dict = store.build_phenotype_tree(hpo_id)
        if tree_dict is None:
            flash(f"An error occurred while creating HPO tree from '{hpo_id}'",
                  "danger")
            return
    else:  # include just HPO term as a standalone checkbox:
        tree_dict = dict(name=hpo_obj["_id"],
                         description=hpo_obj["description"])
    tree_dict["checkbox_type"] = "hpo"
    if user_form.get("hpoTermTitle"):
        tree_dict["term_title"] = user_form.get("hpoTermTitle")
    if user_form.get("hpo_custom_name"):
        tree_dict["custom_name"] = user_form.get("hpo_custom_name")
    checkboxes[hpo_id] = tree_dict
    model_dict["subpanels"][subpanel_id]["checkboxes"] = checkboxes
    model_dict["subpanels"][subpanel_id]["updated"] = datetime.datetime.now()
    return model_dict
Example #3
0
def test_institute_settings(app, user_obj, institute_obj):
    """Test function that creates institute update form and updates an institute"""

    # GIVEN a gene panel
    test_panel = store.panel_collection.find_one()
    assert test_panel

    # AND 2 mock HPO terms in database
    mock_disease_terms = [
        {
            "_id": "HP:0001298",
            "description": "Encephalopathy",
            "hpo_id": "HP:0001298"
        },
        {
            "_id": "HP:0001250",
            "description": "Seizures",
            "hpo_id": "HP:0001250"
        },
    ]
    for term in mock_disease_terms:
        store.load_hpo_term(term)
        assert store.hpo_term(term["_id"])

    # GIVEN an initialized app
    # GIVEN a valid user and institute
    with app.test_client() as client:

        client.get(url_for("auto_login"))

        # WHEN accessing the cases page (GET method)
        resp = client.get(
            url_for("overview.institute_settings",
                    institute_id=institute_obj["internal_id"]))

        # THEN it should return a page
        assert resp.status_code == 200

        # WHEN updating an institute using the following form
        form_data = {
            "display_name":
            "updated name",
            "sanger_emails": ["*****@*****.**"],
            "coverage_cutoff":
            "15",
            "frequency_cutoff":
            "0.001",
            "cohorts": ["test cohort 1", "test cohort 2"],
            "institutes": ["cust111", "cust222"],
            "pheno_groups": [
                "HP:0001298 , Encephalopathy ( ENC )",
                "HP:0001250 , Seizures ( EP )",
            ],
            "gene_panels": [test_panel["panel_name"]],
        }

        # via POST request
        resp = client.post(
            url_for("overview.institute_settings",
                    institute_id=institute_obj["internal_id"]),
            data=form_data,
        )
        assert resp.status_code == 200

        # THEN the institute object should be updated with the provided form data
        updated_institute = store.institute_collection.find_one()
        assert updated_institute["display_name"] == form_data["display_name"]
        assert updated_institute["sanger_recipients"] == form_data[
            "sanger_emails"]
        assert updated_institute["coverage_cutoff"] == int(
            form_data["coverage_cutoff"])
        assert updated_institute["frequency_cutoff"] == float(
            form_data["frequency_cutoff"])
        assert updated_institute["cohorts"] == form_data["cohorts"]
        assert updated_institute["collaborators"] == form_data["institutes"]
        assert len(updated_institute["phenotype_groups"]
                   ) == 2  # one for each HPO term
        assert updated_institute["gene_panels"] == {
            test_panel["panel_name"]: test_panel["display_name"]
        }
Example #4
0
def phenotypes_genes(store, case_obj, is_clinical=True):
    """Generate a dictionary consisting of phenotype terms with associated genes from the case HPO panel

    Args:
        store(adapter.MongoAdapter)
        case_obj(dict): models.Case
        is_clinical(bool): if True, only list genes from HPO that are among the case clinical_symbols

    Returns:
        hpo_genes(dict): a dictionary with HPO term IDs as keys and HPO terms and genes as values
                      If the dynamic phenotype panel is empty, or has been intersected to some level,
                      use dynamic gene list directly instead.
    """
    build = case_obj["genome_build"]
    # Make sure build is either "37" or "38"
    if "38" in str(build):
        build = "38"
    else:
        build = "37"
    dynamic_gene_list = [gene["hgnc_id"] for gene in case_obj.get("dynamic_gene_list", [])]

    hpo_genes = {}

    clinical_symbols = store.clinical_symbols(case_obj) if is_clinical else None
    unique_genes = hpo_genes_from_dynamic_gene_list(case_obj, is_clinical, clinical_symbols)

    by_phenotype = True  # display genes by phenotype
    hpo_gene_list = case_obj.get("dynamic_panel_phenotypes", [])
    if not hpo_gene_list and dynamic_gene_list:
        by_phenotype = False

    all_hpo_gene_list_genes = set()
    # Loop over the dynamic phenotypes of a case
    for hpo_id in hpo_gene_list:
        hpo_term = store.hpo_term(hpo_id)
        # Check that HPO term exists in database
        if hpo_term is None:
            LOG.warning(f"Could not find HPO term with ID '{hpo_id}' in database")
            continue
        # Create a list with all gene symbols (or HGNC ID if symbol is missing) associated with the phenotype
        gene_list = []
        for gene_id in hpo_term.get("genes", []):
            gene_caption = store.hgnc_gene_caption(gene_id, build)
            if gene_caption is None:
                continue
            if gene_id not in dynamic_gene_list:
                # gene was filtered out because min matching phenotypes > 1 (or the panel was generated with older genotype-phenotype mapping)
                by_phenotype = False  # do not display genes by phenotype
                continue
            add_symbol = gene_caption.get("hgnc_symbol", f"hgnc:{gene_id}")
            if is_clinical and (add_symbol not in clinical_symbols):
                continue
            gene_list.append(add_symbol)
            all_hpo_gene_list_genes.add(add_symbol)

        hpo_genes[hpo_id] = {
            "description": hpo_term.get("description"),
            "genes": ", ".join(sorted(gene_list)),
        }

    if by_phenotype is True:
        # if some gene was manually added (or is left on dynamic panel for other reasons)
        non_hpo_genes = unique_genes - all_hpo_gene_list_genes
        if len(non_hpo_genes) > 0:
            hpo_genes["Analysed genes"] = {
                "description": "Non HPO panel genes",
                "genes": ", ".join(sorted(non_hpo_genes)),
            }

    if by_phenotype is False:
        hpo_genes = {}
        hpo_genes["Analysed genes"] = {
            "description": "HPO panel",
            "genes": ", ".join(sorted(unique_genes)),
        }

    return hpo_genes