From bfbecaba6f3c6c8cce55b4d721c238892576fd61 Mon Sep 17 00:00:00 2001 From: Prasham Marfatia Date: Wed, 29 Jan 2025 14:38:58 -0500 Subject: [PATCH 1/6] Update signed analysis route function to add parameters to rendered flask template --- src/indra_cogex/apps/gla/gene_blueprint.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/indra_cogex/apps/gla/gene_blueprint.py b/src/indra_cogex/apps/gla/gene_blueprint.py index 522ea289c..4259b23a9 100644 --- a/src/indra_cogex/apps/gla/gene_blueprint.py +++ b/src/indra_cogex/apps/gla/gene_blueprint.py @@ -232,6 +232,8 @@ def signed_analysis_route(): negative_genes=negative_genes, negative_errors=negative_errors, results=results, + minimum_evidence=form.minimum_evidence.data, + minimum_belief=form.minimum_belief.data ) return flask.render_template( "gene_analysis/signed_form.html", From 5bb04803838f0a158b43e744c227eb39c2090109 Mon Sep 17 00:00:00 2001 From: Prasham Marfatia Date: Wed, 29 Jan 2025 14:39:50 -0500 Subject: [PATCH 2/6] Create function and enpoint for browsing signed analysis statements --- src/indra_cogex/apps/search/search.py | 318 +++++++++++++++++++++++++- 1 file changed, 314 insertions(+), 4 deletions(-) diff --git a/src/indra_cogex/apps/search/search.py b/src/indra_cogex/apps/search/search.py index 9da632b5f..bf273f189 100644 --- a/src/indra_cogex/apps/search/search.py +++ b/src/indra_cogex/apps/search/search.py @@ -1,5 +1,6 @@ import json from typing import List, Optional, Mapping, Tuple +import logging from flask import Blueprint, render_template, request, jsonify, redirect, url_for from flask_jwt_extended import jwt_required @@ -9,11 +10,14 @@ from wtforms.fields.simple import BooleanField from wtforms.validators import DataRequired +from indra_cogex.analysis.metabolite_analysis import parse_metabolites from indra_cogex.apps.utils import render_statements from indra_cogex.client import Neo4jClient, autoclient from indra_cogex.client.queries import * from indra_cogex.representation import norm_id +logger = logging.getLogger(__name__) + __all__ = ["search_blueprint"] from indra_cogex.client.queries import enrich_statements @@ -242,14 +246,14 @@ def get_ora_statements( # Enrich statements with complete evidence (no limit) stmts = enrich_statements( - stmts, - client=client + stmts, + client=client ) # Create evidence count mapping evidence_counts = { - stmt.get_hash(): rel.data.get("evidence_count", 0) - for rel, stmt in zip(flattened_rels, stmts) + stmt.get_hash(): rel.data.get("evidence_count", 0) + for rel, stmt in zip(flattened_rels, stmts) } return stmts, evidence_counts @@ -289,3 +293,309 @@ def search_ora_statements(): except Exception as e: print(f"Error in get_ora_statements: {str(e)}") return jsonify({"error": str(e)}), 500 + + +@autoclient() +def get_signed_statements( + target_id: str, + positive_genes: List[str], + negative_genes: List[str], + minimum_belief: float = 0.0, + minimum_evidence: Optional[int] = None, + *, + client: Neo4jClient, +) -> Tuple[List[Statement], Mapping[int, int]]: + """Get statements for signed analysis considering relationship direction.""" + # Normalize genes + pos_genes = [norm_id('HGNC', gene.split(':')[1]) for gene in positive_genes] + neg_genes = [norm_id('HGNC', gene.split(':')[1]) for gene in negative_genes] + + # Entity handling + namespace = target_id.split(':')[0].lower() + id_part = target_id.split(':')[1] + + if namespace == 'chebi': + normalized_target = f"chebi:{id_part}" + rel_types = ["indra_rel", "has_metabolite"] + elif namespace == 'mesh': + normalized_target = f"mesh:{id_part}" + rel_types = ["indra_rel", "has_indication"] + elif namespace == 'hgnc': + normalized_target = f"hgnc:{id_part}" + rel_types = ["indra_rel"] + elif namespace == 'fplx': + normalized_target = f"fplx:{id_part}" + rel_types = ["indra_rel", "isa"] + else: + normalized_target = target_id.lower() + rel_types = ["indra_rel"] + + # Modified query to return the path + query = """ + MATCH p = (gene:BioEntity)-[r]-(target:BioEntity) + WHERE target.id = $target_id + AND type(r) IN $rel_types + AND gene.id IN $gene_list + AND r.belief > $minimum_belief + AND r.evidence_count >= $minimum_evidence + AND NOT gene.obsolete + AND ( + // Gene->Target direction + (startNode(r) = gene AND r.stmt_type IN $stmt_types_gene_to_target) + OR + // Target->Gene direction + (startNode(r) = target AND r.stmt_type IN $stmt_types_target_to_gene) + ) + RETURN p + """ + + flattened_rels = [] + + # Process positive genes + if pos_genes: + pos_params = { + "target_id": normalized_target, + "gene_list": pos_genes, + "rel_types": rel_types, + "minimum_belief": minimum_belief, + "minimum_evidence": minimum_evidence, + # When gene acts on target + "stmt_types_gene_to_target": [ + 'DecreaseAmount', + 'Inhibition' + ], + # When target acts on gene + "stmt_types_target_to_gene": [ + 'IncreaseAmount', + 'Activation', + 'Complex' + ] + } + logger.info("Executing positive genes query with params: %s", pos_params) + pos_results = client.query_tx(query, **pos_params) + for result in pos_results: + path = result[0] # Get the path from the result + rel = client.neo4j_to_relation(path) + flattened_rels.append(rel) + logger.info(f"Found {len(flattened_rels)} positive relationships") + + # Process negative genes + if neg_genes: + neg_params = { + "target_id": normalized_target, + "gene_list": neg_genes, + "rel_types": rel_types, + "minimum_belief": minimum_belief, + "minimum_evidence": minimum_evidence, + # When gene acts on target + "stmt_types_gene_to_target": [ + 'IncreaseAmount', + 'Activation' + ], + # When target acts on gene + "stmt_types_target_to_gene": [ + 'DecreaseAmount', + 'Inhibition' + ] + } + logger.info("Executing negative genes query with params: %s", neg_params) + neg_results = client.query_tx(query, **neg_params) + neg_count = 0 + for result in neg_results: + path = result[0] # Get the path from the result + rel = client.neo4j_to_relation(path) + flattened_rels.append(rel) + neg_count += 1 + logger.info(f"Found {neg_count} negative relationships") + + logger.info(f"Total relationships found: {len(flattened_rels)}") + + # Create statements + stmts = indra_stmts_from_relations(flattened_rels, deduplicate=True) + logger.info(f"Created {len(stmts)} statements") + + # Enrich statements + stmts = enrich_statements(stmts, client=client) + logger.info("Completed statement enrichment") + + # Create evidence counts mapping + evidence_counts = { + stmt.get_hash(): rel.data.get("evidence_count", 0) + for rel, stmt in zip(flattened_rels, stmts) + } + logger.info(f"Generated evidence counts: {evidence_counts}") + + return stmts, evidence_counts + + +@search_blueprint.route("/signed_statements/", methods=['GET']) +@jwt_required(optional=True) +def search_signed_statements(): + """Endpoint to get INDRA statements for signed analysis results.""" + # Log all request arguments + logger.info("Received request arguments:") + for key, value in request.args.items(): + logger.info(f"{key}: {value}") + + target_id = request.args.get("target_id") + positive_genes = request.args.getlist("positive_genes") + negative_genes = request.args.getlist("negative_genes") + minimum_evidence = request.args.get("minimum_evidence", "1") + minimum_belief = request.args.get("minimum_belief", "0.0") + + try: + minimum_evidence = int(minimum_evidence) + minimum_belief = float(minimum_belief) + except (ValueError, TypeError) as e: + logger.error(f"Parameter conversion error: {str(e)}") + return jsonify({"error": "Invalid parameter values"}), 400 + + if not target_id or (not positive_genes and not negative_genes): + return jsonify({"error": "target_id and at least one gene list required"}), 400 + + statements, evidence_counts = get_signed_statements( + target_id=target_id, + positive_genes=positive_genes, + negative_genes=negative_genes, + minimum_belief=minimum_belief, + minimum_evidence=minimum_evidence + ) + + return render_statements( + stmts=statements, + evidence_count=evidence_counts + ) + + +@autoclient() +def get_metabolite_statements( + target_id: str, + metabolites: List[str], + minimum_belief: float = 0.0, + minimum_evidence: Optional[int] = None, + *, + client: Neo4jClient, +) -> Tuple[List[Statement], Mapping[int, int]]: + """Get statements for metabolite analysis.""" + logger.info(f"\n{'=' * 80}\nStarting metabolite statement analysis") + logger.info(f"Target: {target_id}") + logger.info(f"Metabolites: {metabolites}") + logger.info(f"Minimum belief: {minimum_belief}") + logger.info(f"Minimum evidence: {minimum_evidence}\n") + + # Parse and normalize metabolite IDs + chebi_ids, errors = parse_metabolites(metabolites) + if errors: + logger.warning(f"Could not parse the following metabolites: {errors}") + + # Add CHEBI prefix and log + metabolite_list = [f"chebi:{m.lower()}" for m in chebi_ids] + logger.info(f"Normalized CHEBI IDs: {metabolite_list}") + + # Add prefix for EC codes if needed + normalized_target = f"eccode:{target_id}" if not ':' in target_id else target_id + logger.info(f"Normalized target: {normalized_target}") + + # Discovery query to check what relationships exist + discovery_query = """ + MATCH (met:BioEntity)-[r]-(target:BioEntity) + WHERE met.id IN $metabolite_list + RETURN DISTINCT + met.id as metabolite, + type(r) as rel_type, + r.stmt_type as stmt_type, + count(*) as count + """ + + logger.info("\nDiscovering relationships...") + discovery_results = client.query_tx(discovery_query, + metabolite_list=metabolite_list) + for row in discovery_results: + logger.info(f"Metabolite: {row[0]}, Type: {row[1]}, Statement Type: {row[2]}, Count: {row[3]}") + + # Main query for statements + query = """ + MATCH p = (met:BioEntity)-[r:indra_rel]-(target:BioEntity) + WHERE target.id = $target_id + AND met.id IN $metabolite_list + AND r.belief > $minimum_belief + AND r.evidence_count >= $minimum_evidence + AND NOT met.obsolete + RETURN p + """ + + params = { + "target_id": normalized_target, + "metabolite_list": metabolite_list, + "minimum_belief": minimum_belief, + "minimum_evidence": minimum_evidence + } + + logger.info("\nExecuting main query with params:") + for key, value in params.items(): + logger.info(f"{key}: {value}") + + results = client.query_tx(query, **params) + flattened_rels = [] + for result in results: + path = result[0] + rel = client.neo4j_to_relation(path) + flattened_rels.append(rel) + logger.debug(f"\nFound relationship:") + logger.debug(f"Type: {rel.data.get('stmt_type')}") + logger.debug(f"Evidence count: {rel.data.get('evidence_count')}") + logger.debug(f"Belief: {rel.data.get('belief')}") + + logger.info(f"\nFound {len(flattened_rels)} total relationships") + + # Create statements + stmts = indra_stmts_from_relations(flattened_rels, deduplicate=True) + logger.info(f"Created {len(stmts)} statements") + + # Enrich statements + stmts = enrich_statements(stmts, client=client) + logger.info("Completed statement enrichment") + + # Create evidence counts mapping + evidence_counts = { + stmt.get_hash(): rel.data.get("evidence_count", 0) + for rel, stmt in zip(flattened_rels, stmts) + } + logger.info(f"Evidence counts: {evidence_counts}") + logger.info(f"{'=' * 80}\n") + + return stmts, evidence_counts + + +@search_blueprint.route("/metabolite_statements/", methods=['GET']) +@jwt_required(optional=True) +def search_metabolite_statements(): + """Endpoint to get INDRA statements for metabolite analysis results.""" + target_id = request.args.get("target_id") + metabolites = request.args.getlist("metabolites") + + try: + minimum_evidence = int(request.args.get("minimum_evidence", "1")) + minimum_belief = float(request.args.get("minimum_belief", "0.0")) + except (ValueError, TypeError): + return jsonify({"error": "Invalid parameter values"}), 400 + + if not target_id or not metabolites: + return jsonify({"error": "target_id and metabolites are required"}), 400 + + try: + statements, evidence_counts = get_metabolite_statements( + target_id=target_id, + metabolites=metabolites, + minimum_belief=minimum_belief, + minimum_evidence=minimum_evidence, + ) + + return render_statements( + stmts=statements, + evidence_count=evidence_counts + ) + + except Exception as e: + logger.error(f"Error in get_metabolite_statements: {str(e)}") + return jsonify({"error": str(e)}), 400 From 6f10015e3fdcb3e501e7f96f3a1b07248ea6d1d9 Mon Sep 17 00:00:00 2001 From: Prasham Marfatia Date: Wed, 29 Jan 2025 14:41:03 -0500 Subject: [PATCH 3/6] Update macros to add column for statement browsing functionality --- .../gene_analysis/signed_results.html | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/indra_cogex/apps/templates/gene_analysis/signed_results.html b/src/indra_cogex/apps/templates/gene_analysis/signed_results.html index 540d7015d..af58c08e4 100644 --- a/src/indra_cogex/apps/templates/gene_analysis/signed_results.html +++ b/src/indra_cogex/apps/templates/gene_analysis/signed_results.html @@ -52,7 +52,7 @@ {% endblock %} -{% macro render_table(df, table_id) -%} +{% macro render_table(df, table_id, positive_genes, negative_genes, minimum_evidence, minimum_belief) -%} @@ -62,10 +62,19 @@ + {% for curie, name, correct, incorrect, ambig, p, conservative_p in df.values %} + {% set pos_gene_list = [] %} + {% set neg_gene_list = [] %} + {% for gene_id in positive_genes.keys() %} + {% do pos_gene_list.append("HGNC:" + gene_id) %} + {% endfor %} + {% for gene_id in negative_genes.keys() %} + {% do neg_gene_list.append("HGNC:" + gene_id) %} + {% endfor %} @@ -73,6 +82,16 @@ + {% endfor %} @@ -123,7 +142,7 @@

Reverse Causal Reasoning Analysis

query gene set. A p-value is calculated by applying a binomial test to the matches and non-matches.

- {{ render_table(results, "table-rcr") }} + {{ render_table(results, "table-rcr", positive_genes, negative_genes, minimum_evidence, minimum_belief) }} From 865d12003e784849311355c4f6b232b3e4a53619 Mon Sep 17 00:00:00 2001 From: Prasham Marfatia Date: Thu, 6 Feb 2025 11:21:39 -0500 Subject: [PATCH 4/6] Create functions for signed and continuous GSEA for statement rendering --- src/indra_cogex/apps/search/search.py | 253 ++++++++++++-------------- 1 file changed, 117 insertions(+), 136 deletions(-) diff --git a/src/indra_cogex/apps/search/search.py b/src/indra_cogex/apps/search/search.py index bf273f189..eaa4cecad 100644 --- a/src/indra_cogex/apps/search/search.py +++ b/src/indra_cogex/apps/search/search.py @@ -10,7 +10,6 @@ from wtforms.fields.simple import BooleanField from wtforms.validators import DataRequired -from indra_cogex.analysis.metabolite_analysis import parse_metabolites from indra_cogex.apps.utils import render_statements from indra_cogex.client import Neo4jClient, autoclient from indra_cogex.client.queries import * @@ -305,12 +304,33 @@ def get_signed_statements( *, client: Neo4jClient, ) -> Tuple[List[Statement], Mapping[int, int]]: - """Get statements for signed analysis considering relationship direction.""" - # Normalize genes + """Get statements showing signed relationships between genes and target. + + Parameters + ---------- + target_id : str + The ID of the target entity + positive_genes : List[str] + List of gene IDs that show positive correlation with target + negative_genes : List[str] + List of gene IDs that show negative correlation with target + minimum_belief : float, optional + Minimum belief score threshold for relationships, by default 0.0 + minimum_evidence : Optional[int], optional + Minimum number of evidences required, by default None + client : Neo4jClient + The Neo4j client instance + + Returns + ------- + : + A tuple containing: + - List of INDRA statements representing the relationships + - Dictionary mapping statement hashes to evidence counts + """ pos_genes = [norm_id('HGNC', gene.split(':')[1]) for gene in positive_genes] neg_genes = [norm_id('HGNC', gene.split(':')[1]) for gene in negative_genes] - # Entity handling namespace = target_id.split(':')[0].lower() id_part = target_id.split(':')[1] @@ -330,28 +350,24 @@ def get_signed_statements( normalized_target = target_id.lower() rel_types = ["indra_rel"] - # Modified query to return the path query = """ - MATCH p = (gene:BioEntity)-[r]-(target:BioEntity) - WHERE target.id = $target_id - AND type(r) IN $rel_types - AND gene.id IN $gene_list - AND r.belief > $minimum_belief - AND r.evidence_count >= $minimum_evidence - AND NOT gene.obsolete - AND ( - // Gene->Target direction - (startNode(r) = gene AND r.stmt_type IN $stmt_types_gene_to_target) - OR - // Target->Gene direction - (startNode(r) = target AND r.stmt_type IN $stmt_types_target_to_gene) - ) - RETURN p - """ + MATCH p = (gene:BioEntity)-[r]-(target:BioEntity) + WHERE target.id = $target_id + AND type(r) IN $rel_types + AND gene.id IN $gene_list + AND r.belief > $minimum_belief + AND r.evidence_count >= $minimum_evidence + AND NOT gene.obsolete + AND ( + (startNode(r) = gene AND r.stmt_type IN $stmt_types_gene_to_target) + OR + (startNode(r) = target AND r.stmt_type IN $stmt_types_target_to_gene) + ) + RETURN p + """ flattened_rels = [] - # Process positive genes if pos_genes: pos_params = { "target_id": normalized_target, @@ -359,27 +375,22 @@ def get_signed_statements( "rel_types": rel_types, "minimum_belief": minimum_belief, "minimum_evidence": minimum_evidence, - # When gene acts on target "stmt_types_gene_to_target": [ 'DecreaseAmount', 'Inhibition' ], - # When target acts on gene "stmt_types_target_to_gene": [ 'IncreaseAmount', 'Activation', 'Complex' ] } - logger.info("Executing positive genes query with params: %s", pos_params) pos_results = client.query_tx(query, **pos_params) for result in pos_results: - path = result[0] # Get the path from the result + path = result[0] rel = client.neo4j_to_relation(path) flattened_rels.append(rel) - logger.info(f"Found {len(flattened_rels)} positive relationships") - # Process negative genes if neg_genes: neg_params = { "target_id": normalized_target, @@ -387,43 +398,28 @@ def get_signed_statements( "rel_types": rel_types, "minimum_belief": minimum_belief, "minimum_evidence": minimum_evidence, - # When gene acts on target "stmt_types_gene_to_target": [ 'IncreaseAmount', 'Activation' ], - # When target acts on gene "stmt_types_target_to_gene": [ 'DecreaseAmount', 'Inhibition' ] } - logger.info("Executing negative genes query with params: %s", neg_params) neg_results = client.query_tx(query, **neg_params) - neg_count = 0 for result in neg_results: - path = result[0] # Get the path from the result + path = result[0] rel = client.neo4j_to_relation(path) flattened_rels.append(rel) - neg_count += 1 - logger.info(f"Found {neg_count} negative relationships") - - logger.info(f"Total relationships found: {len(flattened_rels)}") - # Create statements stmts = indra_stmts_from_relations(flattened_rels, deduplicate=True) - logger.info(f"Created {len(stmts)} statements") - - # Enrich statements stmts = enrich_statements(stmts, client=client) - logger.info("Completed statement enrichment") - # Create evidence counts mapping evidence_counts = { stmt.get_hash(): rel.data.get("evidence_count", 0) for rel, stmt in zip(flattened_rels, stmts) } - logger.info(f"Generated evidence counts: {evidence_counts}") return stmts, evidence_counts @@ -431,12 +427,6 @@ def get_signed_statements( @search_blueprint.route("/signed_statements/", methods=['GET']) @jwt_required(optional=True) def search_signed_statements(): - """Endpoint to get INDRA statements for signed analysis results.""" - # Log all request arguments - logger.info("Received request arguments:") - for key, value in request.args.items(): - logger.info(f"{key}: {value}") - target_id = request.args.get("target_id") positive_genes = request.args.getlist("positive_genes") negative_genes = request.args.getlist("negative_genes") @@ -447,7 +437,6 @@ def search_signed_statements(): minimum_evidence = int(minimum_evidence) minimum_belief = float(minimum_belief) except (ValueError, TypeError) as e: - logger.error(f"Parameter conversion error: {str(e)}") return jsonify({"error": "Invalid parameter values"}), 400 if not target_id or (not positive_genes and not negative_genes): @@ -468,127 +457,118 @@ def search_signed_statements(): @autoclient() -def get_metabolite_statements( +def get_continuous_statements( target_id: str, - metabolites: List[str], + gene_names: List[str], + source: str, minimum_belief: float = 0.0, minimum_evidence: Optional[int] = None, *, client: Neo4jClient, ) -> Tuple[List[Statement], Mapping[int, int]]: - """Get statements for metabolite analysis.""" - logger.info(f"\n{'=' * 80}\nStarting metabolite statement analysis") - logger.info(f"Target: {target_id}") - logger.info(f"Metabolites: {metabolites}") - logger.info(f"Minimum belief: {minimum_belief}") - logger.info(f"Minimum evidence: {minimum_evidence}\n") - - # Parse and normalize metabolite IDs - chebi_ids, errors = parse_metabolites(metabolites) - if errors: - logger.warning(f"Could not parse the following metabolites: {errors}") - - # Add CHEBI prefix and log - metabolite_list = [f"chebi:{m.lower()}" for m in chebi_ids] - logger.info(f"Normalized CHEBI IDs: {metabolite_list}") - - # Add prefix for EC codes if needed - normalized_target = f"eccode:{target_id}" if not ':' in target_id else target_id - logger.info(f"Normalized target: {normalized_target}") - - # Discovery query to check what relationships exist - discovery_query = """ - MATCH (met:BioEntity)-[r]-(target:BioEntity) - WHERE met.id IN $metabolite_list - RETURN DISTINCT - met.id as metabolite, - type(r) as rel_type, - r.stmt_type as stmt_type, - count(*) as count - """ + """Get statements for continuous analysis. - logger.info("\nDiscovering relationships...") - discovery_results = client.query_tx(discovery_query, - metabolite_list=metabolite_list) - for row in discovery_results: - logger.info(f"Metabolite: {row[0]}, Type: {row[1]}, Statement Type: {row[2]}, Count: {row[3]}") - - # Main query for statements - query = """ - MATCH p = (met:BioEntity)-[r:indra_rel]-(target:BioEntity) - WHERE target.id = $target_id - AND met.id IN $metabolite_list - AND r.belief > $minimum_belief - AND r.evidence_count >= $minimum_evidence - AND NOT met.obsolete - RETURN p + Parameters + ---------- + target_id : str + The ID of the target entity + gene_names : List[str] + List of gene names + source : str + Type of analysis ('indra-upstream' or 'indra-downstream') + minimum_belief : float + Minimum belief score for relationships + minimum_evidence : Optional[int] + Minimum number of evidences required + client : Neo4jClient + The Neo4j client to use for querying + Returns + ------- + : + A tuple containing: + - List of INDRA statements representing the relationships + - Dictionary mapping statement hashes to their evidence counts """ + prefix, entity = target_id.split(':', 1) + if prefix.lower() in ['fplx', 'mesh']: + normalized_target = f"{prefix.lower()}:{entity}" + else: + normalized_target = target_id.lower() + + if source == 'indra-upstream': + query = """ + MATCH path=(gene:BioEntity)-[r:indra_rel]-(target:BioEntity) + WHERE target.id = $target_id + AND gene.name IN $gene_names + AND r.belief > $minimum_belief + AND r.evidence_count >= $minimum_evidence + RETURN path + """ + elif source == 'indra-downstream': + query = """ + MATCH path=(regulator:BioEntity)-[r:indra_rel]-(gene:BioEntity) + WHERE regulator.id = $target_id + AND gene.name IN $gene_names + AND r.belief > $minimum_belief + AND r.evidence_count >= $minimum_evidence + RETURN path + """ params = { "target_id": normalized_target, - "metabolite_list": metabolite_list, + "gene_names": gene_names, "minimum_belief": minimum_belief, - "minimum_evidence": minimum_evidence + "minimum_evidence": minimum_evidence if minimum_evidence is not None else 0 } - logger.info("\nExecuting main query with params:") - for key, value in params.items(): - logger.info(f"{key}: {value}") - results = client.query_tx(query, **params) - flattened_rels = [] - for result in results: - path = result[0] - rel = client.neo4j_to_relation(path) - flattened_rels.append(rel) - logger.debug(f"\nFound relationship:") - logger.debug(f"Type: {rel.data.get('stmt_type')}") - logger.debug(f"Evidence count: {rel.data.get('evidence_count')}") - logger.debug(f"Belief: {rel.data.get('belief')}") - logger.info(f"\nFound {len(flattened_rels)} total relationships") + all_relations = [] + for result in results: + try: + rels = client.neo4j_to_relations(result[0]) + all_relations.extend(rels) + except Exception: + continue - # Create statements - stmts = indra_stmts_from_relations(flattened_rels, deduplicate=True) - logger.info(f"Created {len(stmts)} statements") + if not all_relations: + return [], {} - # Enrich statements + stmts = indra_stmts_from_relations(all_relations, deduplicate=True) stmts = enrich_statements(stmts, client=client) - logger.info("Completed statement enrichment") - # Create evidence counts mapping evidence_counts = { stmt.get_hash(): rel.data.get("evidence_count", 0) - for rel, stmt in zip(flattened_rels, stmts) + for rel, stmt in zip(all_relations, stmts) } - logger.info(f"Evidence counts: {evidence_counts}") - logger.info(f"{'=' * 80}\n") return stmts, evidence_counts -@search_blueprint.route("/metabolite_statements/", methods=['GET']) +@search_blueprint.route("/continuous_statements/", methods=['GET']) @jwt_required(optional=True) -def search_metabolite_statements(): - """Endpoint to get INDRA statements for metabolite analysis results.""" +def search_continuous_statements(): + """Endpoint to get INDRA statements for continuous analysis results.""" target_id = request.args.get("target_id") - metabolites = request.args.getlist("metabolites") + genes = request.args.getlist("genes") + source = request.args.get("source", "indra-upstream") try: - minimum_evidence = int(request.args.get("minimum_evidence", "1")) - minimum_belief = float(request.args.get("minimum_belief", "0.0")) + minimum_evidence = int(request.args.get("minimum_evidence") or 1) + minimum_belief = float(request.args.get("minimum_belief") or 0.0) except (ValueError, TypeError): return jsonify({"error": "Invalid parameter values"}), 400 - if not target_id or not metabolites: - return jsonify({"error": "target_id and metabolites are required"}), 400 + if not target_id or not genes: + return jsonify({"error": "target_id and genes are required"}), 400 try: - statements, evidence_counts = get_metabolite_statements( + statements, evidence_counts = get_continuous_statements( target_id=target_id, - metabolites=metabolites, + gene_names=genes, + source=source, minimum_belief=minimum_belief, - minimum_evidence=minimum_evidence, + minimum_evidence=minimum_evidence ) return render_statements( @@ -596,6 +576,7 @@ def search_metabolite_statements(): evidence_count=evidence_counts ) - except Exception as e: - logger.error(f"Error in get_metabolite_statements: {str(e)}") + except ValueError as e: return jsonify({"error": str(e)}), 400 + + From 843d24570105895572b4dadf73e3577aeaaab256 Mon Sep 17 00:00:00 2001 From: Prasham Marfatia Date: Thu, 6 Feb 2025 11:23:45 -0500 Subject: [PATCH 5/6] Update the results template to add feature for browsing statements --- .../gene_analysis/continuous_results.html | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/indra_cogex/apps/templates/gene_analysis/continuous_results.html b/src/indra_cogex/apps/templates/gene_analysis/continuous_results.html index ac2da9f2d..b97dac784 100644 --- a/src/indra_cogex/apps/templates/gene_analysis/continuous_results.html +++ b/src/indra_cogex/apps/templates/gene_analysis/continuous_results.html @@ -52,7 +52,7 @@ {% endblock %} -{% macro render_table(df, table_id) -%} +{% macro render_table(results, table_id) -%}
🤷 p-valueStatements
{{ curie }} {{ name }}{{ incorrect }} {{ ambig }} {{ "{:.2e}".format(p) }} + View Statements +
@@ -62,10 +62,11 @@ + - {% for curie, name, es, nes, p, q, geneset_size, matched_size in df.values %} + {% for curie, name, es, nes, p, q, geneset_size, matched_size in results.values %} @@ -73,6 +74,15 @@ + {% endfor %} From ab225a40857bd865329ed1c85b481e809e383371 Mon Sep 17 00:00:00 2001 From: Prasham Marfatia Date: Thu, 13 Feb 2025 09:16:20 -0500 Subject: [PATCH 6/6] Add additional return parameters --- src/indra_cogex/apps/gla/gene_blueprint.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/indra_cogex/apps/gla/gene_blueprint.py b/src/indra_cogex/apps/gla/gene_blueprint.py index 4259b23a9..73e21bef6 100644 --- a/src/indra_cogex/apps/gla/gene_blueprint.py +++ b/src/indra_cogex/apps/gla/gene_blueprint.py @@ -300,6 +300,9 @@ def continuous_analysis_route(): "gene_analysis/continuous_results.html", source=form.source.data, results=results, + gene_names=df[gene_name_column].values.tolist(), + minimum_evidence=form.minimum_evidence.data, + minimum_belief=form.minimum_belief.data, ) return flask.render_template( "gene_analysis/continuous_form.html",
NES p-value q-valueStatements
{{ curie }} {{ name }}{{ "{:.2f}".format(nes) }} {{ "{:.2e}".format(p) }} {{ "{:.2e}".format(q) }} + View Statements +