Skip to content

Commit

Permalink
Merge pull request #406 from gyorilab/improvements
Browse files Browse the repository at this point in the history
Various improvements
  • Loading branch information
bgyori authored Dec 6, 2024
2 parents 420832f + 7609e47 commit 928de3e
Show file tree
Hide file tree
Showing 5 changed files with 461 additions and 241 deletions.
65 changes: 46 additions & 19 deletions mira/metamodel/comparison.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,9 @@ class TemplateModelComparison:
def __init__(
self,
template_models: List[TemplateModel],
refinement_func: Callable[[str, str], bool]
refinement_func: Callable[[str, str], bool],
tags: Optional[List[str]] = None,
run_on_init: bool = True
):
"""Create a ModelComparisonGraphdata from a list of TemplateModels
Expand All @@ -256,7 +258,9 @@ def __init__(
self.template_models: Dict[int, TemplateModel] = {
ix: tm for ix, tm in enumerate(iterable=template_models)
}
self.compare_models()
self.tags = tags
if run_on_init:
self.compare_models()

def _add_concept_nodes_edges(
self,
Expand Down Expand Up @@ -406,15 +410,27 @@ def compare_models(self):

def compare_context(self):
tm_contexts = {}
combined_context_key_list = set()
for tm_index, tm in self.template_models.items():
tm_concepts = tm.get_concepts_map().values()
tm_contexts[tm_index] = {context_key for concept in tm_concepts for context_key in concept.context.keys()}
combined_context_value_list = list(set.union(*tm_contexts.values()))
column_names = [f"Model{tm_index}" for tm_index in self.template_models.keys()]
df = pd.DataFrame(index=combined_context_value_list,
tm_contexts[tm_index] = defaultdict(set)
for concept in tm_concepts:
for context_key, context_value in concept.context.items():
tm_contexts[tm_index][context_key].add(context_value)
combined_context_key_list.add(context_key)
tm_contexts[tm_index] = dict(tm_contexts[tm_index])
combined_context_key_list = sorted(combined_context_key_list)
if not self.tags:
column_names = [f"Model{tm_index}" for tm_index
in self.template_models.keys()]
else:
column_names = self.tags
df = pd.DataFrame(index=combined_context_key_list,
columns=column_names)
for index, col in enumerate(df.columns):
df[col] = ["X" if context in tm_contexts[index] else "" for context in df.index]
for index, col in enumerate(column_names):
df[col] = [len(tm_contexts[index][context])
if context in tm_contexts[index] else ""
for context in combined_context_key_list]
df.index.name = "Context Values"
return df

Expand Down Expand Up @@ -777,21 +793,29 @@ def draw_jupyter(self, name, prog="dot", args="", format=None, **kwargs):

return Image(name, **kwargs)

def compare_two_context(self):
def compare_context(self):
tm1_concepts = self.template_model1.get_concepts_map().values()
tm1_context_values = {context_key for concept in tm1_concepts for context_key in
concept.context.keys()}
tm1_values_by_key = defaultdict(set)
for concept in tm1_concepts:
for context_key, context_value in concept.context.items():
tm1_values_by_key[context_key].add(context_value)
tm2_concepts = self.template_model2.get_concepts_map().values()
tm2_context_values = {context_key for concept in tm2_concepts for context_key in
concept.context.keys()}
combined_context_value_list = list(tm1_context_values | tm2_context_values)
column_names = ["Model1", "Model2"]
tm2_values_by_key = defaultdict(set)
for concept in tm2_concepts:
for context_key, context_value in concept.context.items():
tm2_values_by_key[context_key].add(context_value)

combined_context_value_list = sorted(set(tm1_values_by_key) |
set(tm2_values_by_key))
column_names = [self.tag1, self.tag2]
df = pd.DataFrame(index=combined_context_value_list,
columns=column_names)
df["Model1"] = ["X" if context in tm1_context_values else "" for
context in df.index]
df["Model2"] = ["X" if context in tm2_context_values else "" for
context in df.index]
df[self.tag1] = [len(tm1_values_by_key[context])
if context in tm1_values_by_key else ""
for context in df.index]
df[self.tag2] = [len(tm2_values_by_key[context])
if context in tm1_values_by_key else ""
for context in df.index]
df.index.name = "Context Values"
return df

Expand Down Expand Up @@ -877,6 +901,7 @@ def get_concept_comparison_table(
model1: TemplateModel,
model2: TemplateModel,
refinement_func: Callable[[str, str], bool] = None,
name_only: bool = False,
) -> pd.DataFrame:
"""Compare two template models by their concepts and return a table
Expand All @@ -903,6 +928,8 @@ def get_concept_comparison_table(
def _get_name_from_concept(concept: Concept) -> str:
# Get name with grounding and context (if available)
name = concept.display_name or concept.name or "N/A"
if name_only:
return name
if concept.get_curie():
name += f" ({':'.join(concept.get_curie())})"
if concept.context:
Expand Down
29 changes: 28 additions & 1 deletion mira/metamodel/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@

import sympy
import re
import os
import unicodedata
from typing import Any
from typing import Any, Optional
from functools import lru_cache

import requests

from pydantic import GetCoreSchemaHandler
from pydantic_core import core_schema

Expand Down Expand Up @@ -102,3 +105,27 @@ def sanity_check_tm(tm):
all_initial_names = {init.concept.name for init in tm.initials.values()}
for concept in all_concept_names:
assert concept in all_initial_names, f"missing initial condition for {concept}"


def is_ontological_child(child_curie: str, parent_curie: str,
api_url: Optional[str] = None):
if api_url:
base_url = api_url
elif os.environ.get("MIRA_REST_URL"):
base_url = os.environ.get("MIRA_REST_URL")
else:
try:
import pystow
base_url = pystow.get_config("mira", "rest_url")
except ImportError:
raise ValueError("api_url must be provided or MIRA_REST_URL must be set.")
base_url = base_url.rstrip("/") + "/api" \
if not base_url.endswith("/api") else base_url
endpoint_url = base_url + '/is_ontological_child'

res = requests.post(endpoint_url, json={"child_curie": child_curie,
"parent_curie": parent_curie})

res.raise_for_status()
res_json = res.json()
return res_json['is_child']
9 changes: 0 additions & 9 deletions notebooks/hackathon_2024.12/ModelA.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@
" 'rho': {'value': 0.8},\n",
" 'nu': {'value': 0.045},\n",
" 'beta_hh': {'value': 0.03},\n",
" #'beta_rh': {'value': 0.3045},\n",
" 'beta_rh': {'value': 0.03045},\n",
" 'beta_rr': {'value': 0.025},\n",
" 'alpha': {'value': 0.75},\n",
Expand Down Expand Up @@ -123,14 +122,6 @@
"case_expr = sp.parse_expr('P + I1 + I2 + H')\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4b6fe932",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 2,
Expand Down
111 changes: 39 additions & 72 deletions notebooks/hackathon_2024.12/ModelB.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,45 @@
"N_h = S_h(t) + E_h(t) + I_h(t) + Q(t) + R(t)\n",
"N_r = S_r(t) + E_r(t) + I_r(t)\n",
"\n",
"\n",
"human_infection_rate = ((beta_1 * I_r(t) + beta_2 * I_h(t)) * S_h(t)) / N_h\n",
"rodent_infection_rate = (beta_3 * S_r(t) * I_r(t)) / N_r\n",
"\n",
"odes = [\n",
" sp.Eq(\n",
" S_h(t).diff(t),\n",
" theta_h - human_infection_rate - mu_h * S_h(t) + phi * Q(t),\n",
" ),\n",
" sp.Eq(\n",
" E_h(t).diff(t),\n",
" human_infection_rate - (alpha_1 + alpha_2 + mu_h) * E_h(t),\n",
" ),\n",
" sp.Eq(\n",
" I_h(t).diff(t),\n",
" alpha_1 * E_h(t) - (mu_h + delta_h + gamma) * I_h(t),\n",
" ),\n",
" sp.Eq(\n",
" Q(t).diff(t),\n",
" alpha_2 * E_h(t) - (phi + tau + delta_h + mu_h) * Q(t),\n",
" ),\n",
" sp.Eq(\n",
" R(t).diff(t),\n",
" gamma * I_h(t) + tau * Q(t) - mu_h * R(t),\n",
" ),\n",
" sp.Eq(\n",
" S_r(t).diff(t),\n",
" theta_r - rodent_infection_rate - mu_r * S_r(t),\n",
" ),\n",
" sp.Eq(\n",
" E_r(t).diff(t),\n",
" rodent_infection_rate - (mu_r + alpha_3) * E_r(t),\n",
" ),\n",
" sp.Eq(\n",
" I_r(t).diff(t),\n",
" alpha_3 * E_r(t) - (mu_r + delta_r) * I_r(t),\n",
" ),\n",
"]\n",
"\n",
"concept_data = {\n",
" \"S_h\": {\n",
" \"identifiers\": {\"ido\": \"0000514\"},\n",
Expand Down Expand Up @@ -85,43 +124,6 @@
" \"context\": {\"species\": \"ncbitaxon:9989\"},\n",
" },\n",
"}\n",
"human_infection_rate = ((beta_1 * I_r(t) + beta_2 * I_h(t)) * S_h(t)) / N_h\n",
"rodent_infection_rate = (beta_3 * S_r(t) * I_r(t)) / N_r\n",
"\n",
"odes = [\n",
" sp.Eq(\n",
" S_h(t).diff(t),\n",
" theta_h - human_infection_rate - mu_h * S_h(t) + phi * Q(t),\n",
" ),\n",
" sp.Eq(\n",
" E_h(t).diff(t),\n",
" human_infection_rate - (alpha_1 + alpha_2 + mu_h) * E_h(t),\n",
" ),\n",
" sp.Eq(\n",
" I_h(t).diff(t),\n",
" alpha_1 * E_h(t) - (mu_h + delta_h + gamma) * I_h(t),\n",
" ),\n",
" sp.Eq(\n",
" Q(t).diff(t),\n",
" alpha_2 * E_h(t) - (phi + tau + delta_h + mu_h) * Q(t),\n",
" ),\n",
" sp.Eq(\n",
" R(t).diff(t),\n",
" gamma * I_h(t) + tau * Q(t) - mu_h * R(t),\n",
" ),\n",
" sp.Eq(\n",
" S_r(t).diff(t),\n",
" theta_r - rodent_infection_rate - mu_r * S_r(t),\n",
" ),\n",
" sp.Eq(\n",
" E_r(t).diff(t),\n",
" rodent_infection_rate - (mu_r + alpha_3) * E_r(t),\n",
" ),\n",
" sp.Eq(\n",
" I_r(t).diff(t),\n",
" alpha_3 * E_r(t) - (mu_r + delta_r) * I_r(t),\n",
" ),\n",
"]\n",
"\n",
"\n",
"parameter_data = {\n",
Expand Down Expand Up @@ -179,41 +181,6 @@
"}\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "bc4495c3",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'theta_h': {'value': 1740000.0},\n",
" 'theta_r': {'value': 120000.0},\n",
" 'beta_1': {'value': 0.00025},\n",
" 'beta_2': {'value': 6e-05},\n",
" 'beta_3': {'value': 0.027},\n",
" 'alpha_1': {'value': 0.2},\n",
" 'alpha_2': {'value': 2.0},\n",
" 'alpha_3': {'value': 0.2},\n",
" 'phi': {'value': 2.0},\n",
" 'tau': {'value': 0.52},\n",
" 'gamma': {'value': 0.83},\n",
" 'mu_r': {'value': 1.5},\n",
" 'mu_h': {'value': 0.02},\n",
" 'delta_h': {'value': 0.2},\n",
" 'delta_r': {'value': 0.5}}"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"parameter_data"
]
},
{
"cell_type": "code",
"execution_count": 4,
Expand Down
Loading

0 comments on commit 928de3e

Please sign in to comment.