diff --git a/docs/source/hierarchical_sir_model.ipynb b/docs/source/hierarchical_sir_model.ipynb new file mode 100644 index 00000000..d67d7db7 --- /dev/null +++ b/docs/source/hierarchical_sir_model.ipynb @@ -0,0 +1,314 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Hierarchical model\n" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "import sympy\n", + "\n", + "from mira.metamodel import *\n", + "from mira.modeling import Model\n", + "from mira.modeling.amr.petrinet import template_model_to_petrinet_json\n", + "from mira.sources.amr import model_from_json\n", + "from pyro.infer.inspect import get_dependencies\n", + "from pyciemss.compiled_dynamics import CompiledDynamics\n", + "import torch\n", + "import json\n", + "from chirho.dynamical.handlers.solver import TorchDiffEq\n", + "from pyciemss.compiled_dynamics import (\n", + " _compile_param_values,\n", + " get_name,\n", + ")\n", + "def test_distribution_expressions():\n", + " beta_mean = Parameter(name='beta_mean',\n", + " distribution=Distribution(type=\"Beta1\",\n", + " parameters={'alpha': sympy.Integer(1),\n", + " 'beta': sympy.Integer(10)}))\n", + " gamma_mean = Parameter(name='gamma_mean',\n", + " distribution=Distribution(type=\"Beta1\",\n", + " parameters={'alpha': sympy.Integer(10),\n", + " 'beta': sympy.Integer(10)}))\n", + " beta = Parameter(name='beta',\n", + " distribution=Distribution(type=\"InverseGamma1\",\n", + " parameters={'shape': sympy.Symbol('beta_mean'),\n", + " 'scale': sympy.Float(0.01)}))\n", + " gamma = Parameter(name='gamma',\n", + " distribution=Distribution(type=\"InverseGamma1\",\n", + " parameters={'shape': sympy.Symbol('gamma_mean'),\n", + " 'scale': sympy.Float(0.01)}))\n", + "\n", + " # Make an SIR model with beta and gamma in rate laws\n", + " sir_model = TemplateModel(\n", + " templates=[\n", + " ControlledConversion(\n", + " subject=Concept(name='S'),\n", + " outcome=Concept(name='I'),\n", + " controller=Concept(name='I'),\n", + " rate_law=sympy.Symbol('S') * sympy.Symbol('I') * sympy.Symbol('beta')\n", + " ),\n", + " NaturalConversion(\n", + " subject=Concept(name='I'),\n", + " outcome=Concept(name='R'),\n", + " rate_law=sympy.Symbol('I') * sympy.Symbol('gamma')\n", + " ),\n", + " ],\n", + " parameters={\n", + " 'beta': beta,\n", + " 'gamma': gamma,\n", + " 'beta_mean': beta_mean,\n", + " 'gamma_mean': gamma_mean,\n", + " }\n", + " )\n", + "\n", + " model = Model(sir_model)\n", + " pn_json = template_model_to_petrinet_json(sir_model)\n", + " with open('hierarchical_sir_model.json', 'w') as fh:\n", + " json.dump(pn_json, fh)\n", + " \n", + " params = pn_json['semantics']['ode']['parameters']\n", + " assert {p['id'] for p in params} == \\\n", + " {'beta_mean', 'gamma_mean', 'beta', 'gamma'}\n", + " beta = [p for p in params if p['id'] == 'beta'][0]\n", + " assert beta['distribution']['type'] == 'InverseGamma1'\n", + " assert beta['distribution']['parameters']['shape'] == 'beta_mean'\n", + "\n", + " # Now read the model back and check if it is deserialized\n", + " tm = model_from_json(pn_json)\n", + " assert tm.parameters['beta'].distribution.type == 'InverseGamma1'\n", + " assert isinstance(tm.parameters['beta'].distribution.parameters['shape'],\n", + " SympyExprStr)\n", + " assert tm.parameters['beta'].distribution.parameters['shape'].args[0] == \\\n", + " sympy.Symbol('beta_mean')\n", + " return sir_model\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Compile the non-hierarchical model and get dependencies" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'prior_dependencies': {'persistent_beta': {'persistent_beta': set()},\n", + " 'persistent_gamma': {'persistent_gamma': set()}},\n", + " 'posterior_dependencies': {'persistent_beta': {'persistent_beta': set()},\n", + " 'persistent_gamma': {'persistent_gamma': set()}}}" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "url_sirhd = \"https://raw.githubusercontent.com/DARPA-ASKEM/simulation-integration/refs/heads/main/data/models/sirhd.json\"\n", + "compiled_model = CompiledDynamics.load(url_sirhd)\n", + "with TorchDiffEq():\n", + " #simulation = compiled_model(start_time=torch.as_tensor(0.0), end_time=torch.as_tensor(0.0))\n", + " dependencies = get_dependencies(compiled_model, model_args=[torch.as_tensor(0.0), torch.as_tensor(0.0)])\n", + "dependencies" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Compile the hierarchical model and get dependencies" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sir" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Get all the mira parameters and their dependencies before we compile the dynamics" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'beta': Parameter(name='beta', display_name=None, description=None, identifiers={}, context={}, units=None, value=None, distribution=Distribution(type='InverseGamma1', parameters={'shape': beta_mean, 'scale': 0.01})),\n", + " 'gamma': Parameter(name='gamma', display_name=None, description=None, identifiers={}, context={}, units=None, value=None, distribution=Distribution(type='InverseGamma1', parameters={'shape': gamma_mean, 'scale': 0.01})),\n", + " 'beta_mean': Parameter(name='beta_mean', display_name=None, description=None, identifiers={}, context={}, units=None, value=None, distribution=Distribution(type='Beta1', parameters={'alpha': 1, 'beta': 10})),\n", + " 'gamma_mean': Parameter(name='gamma_mean', display_name=None, description=None, identifiers={}, context={}, units=None, value=None, distribution=Distribution(type='Beta1', parameters={'alpha': 10, 'beta': 10}))}" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sir_model = test_distribution_expressions()\n", + "sir_model.parameters" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Get the dependencies in the mira model\n", + "\n", + "First we go through each mira `Parameter` that is of type `Distribution`, and determine what other parameters it depends on based on whether the `Distribution.parameter` is a `SymPyExprStr` and the name of the parameter it depends on. Build a dependency DAG based on the this investigation, and return the DAG.\n", + "\n", + "Then we topologically sort the DAG and call `MIRA_TO_PYRO` for each parameter in order." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def get_dependencies(src: TemplateModel) -> dict:\n", + " for param_info in src.parameters.values():\n", + " param_name = get_name(param_info)\n", + "\n", + " if param_info.placeholder:\n", + " continue\n", + "\n", + " param_dist = getattr(param_info, \"distribution\", None)\n", + " if param_dist is None:\n", + " param_value = param_info.value\n", + " for :\n", + " param_value = recursive_mira_distribution_to_pyro(param_dist)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Create a recursive mira distributions to pyro\n", + "However, I think we want to go one step above this so that we can determine the dependencies before we call MIRA_TO_PYRO." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "from pyciemss.mira_integration.distributions import _MIRA_TO_PYRO, _TESTED_DISTRIBUTIONS\n", + "import mira\n", + "def recursive_mira_distribution_to_pyro(mira_dist: mira.metamodel.Distribution):\n", + "\n", + " if mira_dist.type not in _MIRA_TO_PYRO.keys():\n", + " raise NotImplementedError(\n", + " f\"Conversion from MIRA distribution type {mira_dist.type} to Pyro distribution is not implemented.\"\n", + " )\n", + "\n", + " if mira_dist.type not in _TESTED_DISTRIBUTIONS:\n", + " warnings.warn(\n", + " f\"Conversion from MIRA distribution type {mira_dist.type} to Pyro distribution has not been tested.\"\n", + " )\n", + "\n", + " simple_parameters = {k: torch.as_tensor(v)\n", + " for k, v in mira_dist.parameters.items()\n", + " if not isinstance(v, mira.metamodel.SymPyExprStr)}\n", + " \n", + "\n", + " return _MIRA_TO_PYRO[mira_dist.type](simple_parameters)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/zuck016/Projects/ASKEM/build/pyciemss/pyciemss/mira_integration/distributions.py:257: UserWarning: Conversion from MIRA distribution type InverseGamma1 to Pyro distribution has not been tested.\n", + " warnings.warn(\n" + ] + }, + { + "ename": "ValueError", + "evalue": "The model parameters could not be compiled. Please check the model definition.", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", + "File \u001b[0;32m~/Projects/ASKEM/build/pyciemss/pyciemss/compiled_dynamics.py:26\u001b[0m, in \u001b[0;36mCompiledDynamics.__init__\u001b[0;34m(self, src, **kwargs)\u001b[0m\n\u001b[1;32m 25\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m---> 26\u001b[0m params \u001b[38;5;241m=\u001b[39m \u001b[43m_compile_param_values\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msrc\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 27\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n", + "File \u001b[0;32m~/.pyenv/versions/miniconda3-3.11-24.1.2-0/envs/pyciemss/lib/python3.12/functools.py:909\u001b[0m, in \u001b[0;36msingledispatch..wrapper\u001b[0;34m(*args, **kw)\u001b[0m\n\u001b[1;32m 906\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfuncname\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m requires at least \u001b[39m\u001b[38;5;124m'\u001b[39m\n\u001b[1;32m 907\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m1 positional argument\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[0;32m--> 909\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mdispatch\u001b[49m\u001b[43m(\u001b[49m\u001b[43margs\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m]\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[38;5;18;43m__class__\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkw\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/Projects/ASKEM/build/pyciemss/pyciemss/mira_integration/compiled_dynamics.py:98\u001b[0m, in \u001b[0;36m_compile_param_values_mira\u001b[0;34m(src)\u001b[0m\n\u001b[1;32m 97\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m---> 98\u001b[0m param_value \u001b[38;5;241m=\u001b[39m \u001b[43mmira_distribution_to_pyro\u001b[49m\u001b[43m(\u001b[49m\u001b[43mparam_dist\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 100\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(param_value, torch\u001b[38;5;241m.\u001b[39mnn\u001b[38;5;241m.\u001b[39mParameter):\n", + "File \u001b[0;32m~/Projects/ASKEM/build/pyciemss/pyciemss/mira_integration/distributions.py:261\u001b[0m, in \u001b[0;36mmira_distribution_to_pyro\u001b[0;34m(mira_dist)\u001b[0m\n\u001b[1;32m 257\u001b[0m warnings\u001b[38;5;241m.\u001b[39mwarn(\n\u001b[1;32m 258\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mConversion from MIRA distribution type \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mmira_dist\u001b[38;5;241m.\u001b[39mtype\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m to Pyro distribution has not been tested.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 259\u001b[0m )\n\u001b[0;32m--> 261\u001b[0m parameters \u001b[38;5;241m=\u001b[39m {k: \u001b[43mtorch\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mas_tensor\u001b[49m\u001b[43m(\u001b[49m\u001b[43mv\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;28;01mfor\u001b[39;00m k, v \u001b[38;5;129;01min\u001b[39;00m mira_dist\u001b[38;5;241m.\u001b[39mparameters\u001b[38;5;241m.\u001b[39mitems()}\n\u001b[1;32m 263\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m _MIRA_TO_PYRO[mira_dist\u001b[38;5;241m.\u001b[39mtype](parameters)\n", + "\u001b[0;31mRuntimeError\u001b[0m: Could not infer dtype of SympyExprStr", + "\nThe above exception was the direct cause of the following exception:\n", + "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[18], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m url_hierarchical \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mhttps://raw.githubusercontent.com/DARPA-ASKEM/simulation-integration/refs/heads/main/data/models/hierarchical_sir_model.json\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m----> 2\u001b[0m compiled_model \u001b[38;5;241m=\u001b[39m \u001b[43mCompiledDynamics\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mload\u001b[49m\u001b[43m(\u001b[49m\u001b[43murl_hierarchical\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 3\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m TorchDiffEq():\n\u001b[1;32m 4\u001b[0m \u001b[38;5;66;03m#simulation = compiled_model(start_time=torch.as_tensor(0.0), end_time=torch.as_tensor(0.0))\u001b[39;00m\n\u001b[1;32m 5\u001b[0m dependencies \u001b[38;5;241m=\u001b[39m get_dependencies(compiled_model, model_args\u001b[38;5;241m=\u001b[39m[torch\u001b[38;5;241m.\u001b[39mas_tensor(\u001b[38;5;241m0.0\u001b[39m), torch\u001b[38;5;241m.\u001b[39mas_tensor(\u001b[38;5;241m0.0\u001b[39m)])\n", + "File \u001b[0;32m~/.pyenv/versions/miniconda3-3.11-24.1.2-0/envs/pyciemss/lib/python3.12/functools.py:946\u001b[0m, in \u001b[0;36msingledispatchmethod.__get__.._method\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 944\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_method\u001b[39m(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[1;32m 945\u001b[0m method \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdispatcher\u001b[38;5;241m.\u001b[39mdispatch(args[\u001b[38;5;241m0\u001b[39m]\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__class__\u001b[39m)\n\u001b[0;32m--> 946\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mmethod\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[38;5;21;43m__get__\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mobj\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mcls\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/Projects/ASKEM/build/pyciemss/pyciemss/compiled_dynamics.py:169\u001b[0m, in \u001b[0;36mCompiledDynamics._load_from_url_or_path\u001b[0;34m(cls, path)\u001b[0m\n\u001b[1;32m 167\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 168\u001b[0m model \u001b[38;5;241m=\u001b[39m mira\u001b[38;5;241m.\u001b[39msources\u001b[38;5;241m.\u001b[39mamr\u001b[38;5;241m.\u001b[39mmodel_from_json_file(path)\n\u001b[0;32m--> 169\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mcls\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mload\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/.pyenv/versions/miniconda3-3.11-24.1.2-0/envs/pyciemss/lib/python3.12/functools.py:946\u001b[0m, in \u001b[0;36msingledispatchmethod.__get__.._method\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 944\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_method\u001b[39m(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[1;32m 945\u001b[0m method \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdispatcher\u001b[38;5;241m.\u001b[39mdispatch(args[\u001b[38;5;241m0\u001b[39m]\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__class__\u001b[39m)\n\u001b[0;32m--> 946\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mmethod\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[38;5;21;43m__get__\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mobj\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mcls\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/Projects/ASKEM/build/pyciemss/pyciemss/compiled_dynamics.py:179\u001b[0m, in \u001b[0;36mCompiledDynamics._load_from_template_model\u001b[0;34m(cls, template)\u001b[0m\n\u001b[1;32m 176\u001b[0m \u001b[38;5;129m@load\u001b[39m\u001b[38;5;241m.\u001b[39mregister(mira\u001b[38;5;241m.\u001b[39mmetamodel\u001b[38;5;241m.\u001b[39mTemplateModel)\n\u001b[1;32m 177\u001b[0m \u001b[38;5;129m@classmethod\u001b[39m\n\u001b[1;32m 178\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_load_from_template_model\u001b[39m(\u001b[38;5;28mcls\u001b[39m, template: mira\u001b[38;5;241m.\u001b[39mmetamodel\u001b[38;5;241m.\u001b[39mTemplateModel):\n\u001b[0;32m--> 179\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mcls\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mload\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmira\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmodeling\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mModel\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtemplate\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/.pyenv/versions/miniconda3-3.11-24.1.2-0/envs/pyciemss/lib/python3.12/functools.py:946\u001b[0m, in \u001b[0;36msingledispatchmethod.__get__.._method\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 944\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_method\u001b[39m(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[1;32m 945\u001b[0m method \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdispatcher\u001b[38;5;241m.\u001b[39mdispatch(args[\u001b[38;5;241m0\u001b[39m]\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__class__\u001b[39m)\n\u001b[0;32m--> 946\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mmethod\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[38;5;21;43m__get__\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mobj\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mcls\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/Projects/ASKEM/build/pyciemss/pyciemss/compiled_dynamics.py:184\u001b[0m, in \u001b[0;36mCompiledDynamics._load_from_mira_model\u001b[0;34m(cls, src)\u001b[0m\n\u001b[1;32m 181\u001b[0m \u001b[38;5;129m@load\u001b[39m\u001b[38;5;241m.\u001b[39mregister(mira\u001b[38;5;241m.\u001b[39mmodeling\u001b[38;5;241m.\u001b[39mModel)\n\u001b[1;32m 182\u001b[0m \u001b[38;5;129m@classmethod\u001b[39m\n\u001b[1;32m 183\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_load_from_mira_model\u001b[39m(\u001b[38;5;28mcls\u001b[39m, src: mira\u001b[38;5;241m.\u001b[39mmodeling\u001b[38;5;241m.\u001b[39mModel):\n\u001b[0;32m--> 184\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mcls\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43msrc\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/Projects/ASKEM/build/pyciemss/pyciemss/compiled_dynamics.py:28\u001b[0m, in \u001b[0;36mCompiledDynamics.__init__\u001b[0;34m(self, src, **kwargs)\u001b[0m\n\u001b[1;32m 26\u001b[0m params \u001b[38;5;241m=\u001b[39m _compile_param_values(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msrc)\n\u001b[1;32m 27\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[0;32m---> 28\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[1;32m 29\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mThe model parameters could not be compiled. Please check the model definition.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 30\u001b[0m ) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01me\u001b[39;00m\n\u001b[1;32m 32\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m k, v \u001b[38;5;129;01min\u001b[39;00m params\u001b[38;5;241m.\u001b[39mitems():\n\u001b[1;32m 33\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mhasattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, get_name(k)):\n", + "\u001b[0;31mValueError\u001b[0m: The model parameters could not be compiled. Please check the model definition." + ] + } + ], + "source": [ + "url_hierarchical = \"https://raw.githubusercontent.com/DARPA-ASKEM/simulation-integration/refs/heads/main/data/models/hierarchical_sir_model.json\"\n", + "compiled_model = CompiledDynamics.load(url_hierarchical)\n", + "with TorchDiffEq():\n", + " #simulation = compiled_model(start_time=torch.as_tensor(0.0), end_time=torch.as_tensor(0.0))\n", + " dependencies = get_dependencies(compiled_model, model_args=[torch.as_tensor(0.0), torch.as_tensor(0.0)])\n", + "dependencies" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "pyciemss", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/source/hierarchical_sir_model.json b/docs/source/hierarchical_sir_model.json new file mode 100644 index 00000000..38232814 --- /dev/null +++ b/docs/source/hierarchical_sir_model.json @@ -0,0 +1 @@ +{"header": {"name": "Model", "schema": "https://raw.githubusercontent.com/DARPA-ASKEM/Model-Representations/petrinet_v0.6/petrinet/petrinet_schema.json", "schema_name": "petrinet", "description": "Model", "model_version": "0.1"}, "properties": {}, "model": {"states": [{"id": "S", "name": "S", "grounding": {"identifiers": {}, "modifiers": {}}}, {"id": "I", "name": "I", "grounding": {"identifiers": {}, "modifiers": {}}}, {"id": "R", "name": "R", "grounding": {"identifiers": {}, "modifiers": {}}}], "transitions": [{"id": "t1", "input": ["I", "S"], "output": ["I", "I"], "properties": {"name": "t1"}}, {"id": "t2", "input": ["I"], "output": ["R"], "properties": {"name": "t2"}}]}, "semantics": {"ode": {"rates": [{"target": "t1", "expression": "I*S*beta", "expression_mathml": "ISbeta"}, {"target": "t2", "expression": "I*gamma", "expression_mathml": "Igamma"}], "initials": [], "parameters": [{"id": "beta", "distribution": {"type": "InverseGamma1", "parameters": {"shape": "beta_mean", "scale": "0.0100000000000000"}}}, {"id": "gamma", "distribution": {"type": "InverseGamma1", "parameters": {"shape": "gamma_mean", "scale": "0.0100000000000000"}}}, {"id": "beta_mean", "distribution": {"type": "Beta1", "parameters": {"alpha": "1", "beta": "10"}}}, {"id": "gamma_mean", "distribution": {"type": "Beta1", "parameters": {"alpha": "10", "beta": "10"}}}], "observables": [], "time": {"id": "t"}}}, "metadata": {"annotations": {}}} \ No newline at end of file