diff --git a/.win32.env b/.win32.env
new file mode 100644
index 0000000000..5b1e3a0ec7
--- /dev/null
+++ b/.win32.env
@@ -0,0 +1,5 @@
+DOCKER_STOCHSS_IMAGE=stochss-lab
+
+DOCKER_BASE_IMAGE=jupyter/minimal-notebook:latest
+
+JUPYTER_CONFIG_DIR=/opt/stochss-config/.jupyter
diff --git a/Dockerfile b/Dockerfile
index f080b0892f..ce3e1fc364 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -29,20 +29,20 @@ COPY --chown=jovyan:users jupyter_notebook_config.py $JUPYTER_CONFIG_DIR/jupyter
USER root
-RUN wget -q https://julialang-s3.julialang.org/bin/linux/x64/1.4/julia-1.4.2-linux-x86_64.tar.gz
-RUN tar -xvzf julia-1.4.2-linux-x86_64.tar.gz
-RUN mv julia-1.4.2 /usr/local/
-RUN chown -R jovyan:users /usr/local/julia-1.4.2/
+#RUN wget -q https://julialang-s3.julialang.org/bin/linux/x64/1.4/julia-1.4.2-linux-x86_64.tar.gz
+#RUN tar -xvzf julia-1.4.2-linux-x86_64.tar.gz
+#RUN mv julia-1.4.2 /usr/local/
+#RUN chown -R jovyan:users /usr/local/julia-1.4.2/
USER jovyan
-ENV PATH="/usr/local/julia-1.4.2/bin:${PATH}"
+#ENV PATH="/usr/local/julia-1.4.2/bin:${PATH}"
-RUN julia -e 'using Pkg; Pkg.add("IJulia")'
-RUN julia -e 'using Pkg; Pkg.add(PackageSpec(url="https://github.com/stochss/gillespy2lia", rev="main"))'
+#RUN julia -e 'using Pkg; Pkg.add("IJulia")'
+#RUN julia -e 'using Pkg; Pkg.add(PackageSpec(url="https://github.com/stochss/gillespy2lia", rev="main"))'
RUN pip install --no-cache-dir -e .
RUN rm -r /home/jovyan/work
-WORKDIR /home/jovyan
+WORKDIR /home/jovyan
\ No newline at end of file
diff --git a/Makefile b/Makefile
index ed4b61a4e7..bd9d1feb25 100644
--- a/Makefile
+++ b/Makefile
@@ -152,4 +152,4 @@ update:
docker exec -it $(DOCKER_STOCHSS_IMAGE) python -m pip install -e /stochss
-.PHONY: network volumes check-files pull notebook_image build
+.PHONY: network volumes check-files pull notebook_image build
\ No newline at end of file
diff --git a/__version__.py b/__version__.py
index 8b1219a50e..3e182b4ea2 100644
--- a/__version__.py
+++ b/__version__.py
@@ -5,7 +5,7 @@
# @website https://github.com/stochss/stochss
# =============================================================================
-__version__ = '2.3.9'
+__version__ = '2.3.11'
__title__ = 'StochSS'
__description__ = 'StochSS is an integrated development environment (IDE) \
for simulation of biochemical networks.'
diff --git a/client/app.js b/client/app.js
index f2ef090d74..7b83d8114d 100644
--- a/client/app.js
+++ b/client/app.js
@@ -212,29 +212,14 @@ documentSetup = () => {
});
}
-copyToClipboard = (text) => {
- if (window.clipboardData && window.clipboardData.setData) {
- // Internet Explorer-specific code path to prevent textarea being shown while dialog is visible.
- return window.clipboardData.setData("Text", text);
-
- }
- else if (document.queryCommandSupported && document.queryCommandSupported("copy")) {
- var textarea = document.createElement("textarea");
- textarea.textContent = text;
- textarea.style.display = 'none'; // Prevent scrolling to bottom of page in Microsoft Edge.
- document.body.appendChild(textarea);
- textarea.select();
- try {
- return document.execCommand("copy"); // Security exception may be thrown by some browsers.
- }
- catch (ex) {
- console.warn("Copy to clipboard failed.", ex);
- return false;
- }
- finally {
- document.body.removeChild(textarea);
- }
- }
+copyToClipboard = (text, success, error) => {
+ if (window.clipboardData && window.clipboardData.setData) {
+ // Internet Explorer-specific code path to prevent textarea being shown while dialog is visible.
+ return window.clipboardData.setData("Text", text);
+ }
+ else {
+ navigator.clipboard.writeText(text).then(success, error)
+ }
}
module.exports = {
diff --git a/client/modals.js b/client/modals.js
index dcc8da5eac..ac499bb04a 100644
--- a/client/modals.js
+++ b/client/modals.js
@@ -224,7 +224,7 @@ let templates = {
`
},
- presentationLinks : (modalID, title, name, headers, links) => {
+ presentationLinks : (modalID, title, headers, links) => {
return `
@@ -238,8 +238,10 @@ let templates = {
`
},
- presentationLinks : (title, name, headers, links) => {
+ presentationLinks : (title, headers, links) => {
let modalID = "presentationLinksModal"
- return templates.presentationLinks(modalID, title, name, headers, links);
+ return templates.presentationLinks(modalID, title, headers, links);
+ },
+ modelErrorHtml: (title, message) => {
+ let modalID = "modelErrorModal";
+
+ return templates.message(modalID, title, message);
}
}
\ No newline at end of file
diff --git a/client/models/domain-type.js b/client/models/domain-type.js
index 9c88aa284f..3750e1e722 100644
--- a/client/models/domain-type.js
+++ b/client/models/domain-type.js
@@ -36,6 +36,7 @@ module.exports = State.extend({
this.numParticles = 0;
},
validate: function () {
+ if((!/^[a-zA-Z0-9_]+$/.test(this.name))) return false;
return true;
}
});
\ No newline at end of file
diff --git a/client/models/event.js b/client/models/event.js
index 6f30f26b6c..ade98c5fc9 100644
--- a/client/models/event.js
+++ b/client/models/event.js
@@ -51,6 +51,7 @@ module.exports = State.extend({
validateComponent: function () {
advanced_error = false;
if(!this.name.trim() || this.name.match(/^\d/)) return false;
+ if((!/^[a-zA-Z0-9_]+$/.test(this.name))) return false;
if(!this.triggerExpression.trim()) return false;
if(!this.priority.trim()) {
this.advanced_error = true;
diff --git a/client/models/parameter.js b/client/models/parameter.js
index 1d460ecfa5..559d9eb48b 100644
--- a/client/models/parameter.js
+++ b/client/models/parameter.js
@@ -38,6 +38,7 @@ module.exports = State.extend({
},
validateComponent: function () {
if(!this.name.trim() || this.name.match(/^\d/)) return false;
+ if((!/^[a-zA-Z0-9_]+$/.test(this.name))) return false;
if(this.expression === "" || isNaN(this.expression)) return false
return true;
}
diff --git a/client/models/reaction.js b/client/models/reaction.js
index 94bfff06c4..3a7524dfd6 100644
--- a/client/models/reaction.js
+++ b/client/models/reaction.js
@@ -165,6 +165,7 @@ module.exports = State.extend({
},
validateComponent: function () {
if(!this.name.trim() || this.name.match(/^\d/)) return false;
+ if((!/^[a-zA-Z0-9_]+$/.test(this.name))) return false;
if(!this.propensity.trim() && this.reactionType === "custom-propensity") return false;
if(this.reactionType.startsWith('custom')) {
if(this.reactants.length <= 0 && this.products.length <= 0) return false;
diff --git a/client/models/rule.js b/client/models/rule.js
index afe82692b8..d4b80d6fbe 100644
--- a/client/models/rule.js
+++ b/client/models/rule.js
@@ -33,6 +33,7 @@ module.exports = State.extend({
},
validateComponent: function () {
if(!this.name.trim() || this.name.match(/^\d/)) return false;
+ if((!/^[a-zA-Z0-9_]+$/.test(this.name))) return false;
if(!this.expression.trim()) return false;
return true;
}
diff --git a/client/models/specie.js b/client/models/specie.js
index 8f1f8375b5..b0a089883b 100644
--- a/client/models/specie.js
+++ b/client/models/specie.js
@@ -44,6 +44,7 @@ module.exports = State.extend({
},
validateComponent: function () {
if(!this.name.trim() || this.name.match(/^\d/)) return false;
+ if((!/^[a-zA-Z0-9_]+$/.test(this.name))) return false;
if(this.value === "" || isNaN(this.value)) return false;
if(this.mode === "dynamic") {
if(this.isSwitchTol && (this.switchTol === "" || isNaN(this.switchTol))) return false;
diff --git a/client/models/sweep-parameter.js b/client/models/sweep-parameter.js
index 288c68c832..0850841e88 100644
--- a/client/models/sweep-parameter.js
+++ b/client/models/sweep-parameter.js
@@ -29,6 +29,9 @@ module.exports = State.extend({
steps: 'any',
hasChangedRange: 'boolean'
},
+ session: {
+ fixed: 'boolean'
+ },
derived: {
elementID: {
deps: ["collection"],
diff --git a/client/pages/file-browser.js b/client/pages/file-browser.js
index 127789df0f..00c3fa3920 100644
--- a/client/pages/file-browser.js
+++ b/client/pages/file-browser.js
@@ -23,6 +23,8 @@ let _ = require('underscore');
//support files
let app = require('../app');
let modals = require('../modals');
+//models
+let Model = require('../models/model');
//views
let PageView = require('./base');
//templates
@@ -660,7 +662,23 @@ let FileBrowser = PageView.extend({
});
},
newWorkflow: function (o, type) {
- app.newWorkflow(this, o.original._path, o.type === "spatial", type);
+ let model = new Model({
+ directory: o.original._path
+ });
+ app.getXHR(model.url(), {
+ success: function (err, response, body) {
+ model.set(body);
+ model.updateValid();
+ if(model.valid){
+ app.newWorkflow(this, o.original._path, o.type === "spatial", type);
+ }else{
+ let title = "Model Errors Detected";
+ let endpoint = path.join(app.getBasePath(), "stochss/models/edit") + '?path=' + model.directory;
+ let message = 'Errors were detected in you model
click here to fix your model';
+ $(modals.modelErrorHtml(title, message)).modal();
+ }
+ }
+ });
},
addExistingModel: function (o) {
var self = this
@@ -904,13 +922,20 @@ let FileBrowser = PageView.extend({
app.getXHR(endpoint, {
success: function (err, response, body) {
let title = body.message;
- let linkHeaders = "Shareable Presentation Link";
+ let linkHeaders = "Shareable Presentation";
let links = body.links;
- let name = o.original._path.split('/').pop().split('.ipynb')[0];
- $(modals.presentationLinks(title, name, linkHeaders, links)).modal();
+ $(modals.presentationLinks(title, linkHeaders, links)).modal();
let copyBtn = document.querySelector('#presentationLinksModal #copy-to-clipboard');
copyBtn.addEventListener('click', function (e) {
- app.copyToClipboard(links.presentation)
+ let onFulfilled = (value) => {
+ $("#copy-link-success").css("display", "inline-block");
+ }
+ let onReject = (reason) => {
+ let msg = $("#copy-link-failed");
+ msg.html(reason);
+ msg.css("display", "inline-block");
+ }
+ app.copyToClipboard(links.presentation, onFulfilled, onReject);
});
},
error: function (err, response, body) {
diff --git a/client/pages/job-presentation.js b/client/pages/job-presentation.js
index 81cdd53f97..c13e9ae9c8 100644
--- a/client/pages/job-presentation.js
+++ b/client/pages/job-presentation.js
@@ -27,7 +27,7 @@ let Job = require("../models/job");
//views
let PageView = require('./base');
let ModelView = require('../model-view/model-view');
-let ResultsView = require('../views/workflow-results');
+let ResultsView = require('../views/job-results-view');
let SettingsView = require('../views/settings-viewer');
//templates
let template = require('../templates/pages/jobPresentation.pug');
diff --git a/client/pages/loading-page.js b/client/pages/loading-page.js
index 69e573414b..8a83f98360 100644
--- a/client/pages/loading-page.js
+++ b/client/pages/loading-page.js
@@ -35,7 +35,7 @@ let LoadingPage = PageView.extend({
let urlParams = new URLSearchParams(window.location.search)
this.filePath = urlParams.get("path");
this.action = urlParams.get("action");
- this.homeLink = path.append(app.getBasePath(), 'stochss/home');
+ this.homeLink = path.join(app.getBasePath(), 'stochss/home');
},
render: function (attrs, options) {
PageView.prototype.render.apply(this, arguments);
diff --git a/client/pages/model-presentation.js b/client/pages/model-presentation.js
index 662b1dfd83..ebedef0f60 100644
--- a/client/pages/model-presentation.js
+++ b/client/pages/model-presentation.js
@@ -29,18 +29,21 @@ let PageView = require('./base');
let ModelView = require('../model-view/model-view');
//templates
let template = require('../templates/pages/modelPresentation.pug');
+let loadingTemplate = require('../templates/pages/loadingPage.pug');
+let errorTemplate = require('../templates/pages/errorTemplate.pug');
import bootstrapStyles from '../styles/bootstrap.css';
import styles from '../styles/styles.css';
import fontawesomeStyles from '@fortawesome/fontawesome-free/css/svg-with-js.min.css'
let ModelPresentationPage = PageView.extend({
- template: template,
+ template: loadingTemplate,
initialize: function (attrs, options) {
PageView.prototype.initialize.apply(this, arguments);
let urlParams = new URLSearchParams(window.location.search);
let owner = urlParams.get("owner");
let file = urlParams.get("file");
+ this.fileType = file.endsWith(".mdl") ? "Model" : "Spatial Model";
this.model = new Model({
directory: file,
for: "presentation"
@@ -51,16 +54,31 @@ let ModelPresentationPage = PageView.extend({
app.getXHR(endpoint, {
success: function (err, response, body) {
self.model.set(body);
- self.renderSubviews();
+ self.renderSubviews(false);
+ },
+ error: function (err, response, body) {
+ self.notFound = true;
+ self.renderSubviews(true);
}
});
let downloadStart = "https://live.stochss.org/stochss/download_presentation";
this.downloadLink = downloadStart + "/" + owner + "/" + file;
this.openLink = "https://open.stochss.org?open=" + this.downloadLink;
},
- renderSubviews: function () {
+ render: function (attrs, options) {
PageView.prototype.render.apply(this, arguments);
- this.renderModelView();
+ $(this.queryByHook("loading-header")).html(`Loading ${this.fileType}`);
+ $(this.queryByHook("loading-target")).css("display", "none");
+ $(this.queryByHook("loading-spinner")).css("display", "block");
+ let message = `This ${this.fileType} can be downloaded or opened in your own StochSS Live! account using the buttons at the bottom of the page.`;
+ $(this.queryByHook("loading-message")).html(message);
+ },
+ renderSubviews: function (notFound) {
+ this.template = notFound ? errorTemplate : template
+ PageView.prototype.render.apply(this, arguments);
+ if(!notFound) {
+ this.renderModelView();
+ }
},
renderModelView: function () {
let modelView = new ModelView({
diff --git a/client/pages/notebook-presentation.js b/client/pages/notebook-presentation.js
index 932b2175bc..486ee06f0f 100644
--- a/client/pages/notebook-presentation.js
+++ b/client/pages/notebook-presentation.js
@@ -25,6 +25,8 @@ let app = require('../app');
//views
let PageView = require('./base');
//templates
+let loadingTemplate = require('../templates/pages/loadingPage.pug');
+let errorTemplate = require('../templates/pages/errorTemplate.pug');
let template = require('../templates/pages/notebookPresentation.pug');
import bootstrapStyles from '../styles/bootstrap.css';
@@ -32,37 +34,52 @@ import styles from '../styles/styles.css';
import fontawesomeStyles from '@fortawesome/fontawesome-free/css/svg-with-js.min.css'
let NotebookPresentationPage = PageView.extend({
- template: template,
+ template: loadingTemplate,
initialize: function (attrs, options) {
PageView.prototype.initialize.apply(this, arguments);
let urlParams = new URLSearchParams(window.location.search);
let owner = urlParams.get("owner");
let file = urlParams.get("file");
+ this.fileType = "Notebook";
let self = this;
let queryStr = "?owner=" + owner + "&file=" + file;
let endpoint = "api/notebook/load" + queryStr;
app.getXHR(endpoint, {
success: function (err, response, body) {
self.name = body.file.split('/').pop().split('.ipynb')[0];
- self.renderSubviews(body.html);
+ self.renderSubviews(false, body.html);
+ },
+ error: function (err, response, body) {
+ self.renderSubviews(true, null);
}
});
let downloadStart = "https://live.stochss.org/stochss/notebook/download_presentation";
this.downloadLink = downloadStart + "/" + owner + "/" + file;
this.openLink = "https://open.stochss.org?open=" + this.downloadLink;
},
- renderSubviews: function (html) {
+ render: function (attrs, options) {
+ PageView.prototype.render.apply(this, arguments);
+ $(this.queryByHook("loading-header")).html(`Loading ${this.fileType}`);
+ $(this.queryByHook("loading-spinner")).css("display", "block");
+ $(this.queryByHook("loading-target")).css("display", "none");
+ let message = `This ${this.fileType} can be downloaded or opened in your own StochSS Live! account using the buttons at the bottom of the page.`;
+ $(this.queryByHook("loading-message")).html(message);
+ },
+ renderSubviews: function (notFound, html) {
+ this.template = notFound ? errorTemplate : template;
PageView.prototype.render.apply(this, arguments);
- let iframe = document.getElementById('notebook');
- let iframedoc = iframe.document;
- if (iframe.contentDocument) {
- iframedoc = iframe.contentDocument;
- }else if (iframe.contentWindow) {
- iframedoc = iframe.contentWindow.document;
- }
- if (iframedoc) {
- iframedoc.write(html);
- iframedoc.close();
+ if(!notFound){
+ let iframe = document.getElementById('notebook');
+ let iframedoc = iframe.document;
+ if (iframe.contentDocument) {
+ iframedoc = iframe.contentDocument;
+ }else if (iframe.contentWindow) {
+ iframedoc = iframe.contentWindow.document;
+ }
+ if (iframedoc) {
+ iframedoc.write(html);
+ iframedoc.close();
+ }
}
}
});
diff --git a/client/pages/workflow-manager.js b/client/pages/workflow-manager.js
index 42c982255a..cb07578b2a 100644
--- a/client/pages/workflow-manager.js
+++ b/client/pages/workflow-manager.js
@@ -27,12 +27,12 @@ let Workflow = require('../models/workflow');
//views
let PageView = require('./base');
let SettingsView = require('../views/settings');
-let LogsView = require('../views/workflow-info');
+let LogsView = require('../views/job-info-view');
let SelectView = require('ampersand-select-view');
let ModelView = require('../model-view/model-view');
let StatusView = require('../views/workflow-status');
let JobListingView = require('../views/job-listing');
-let ResultsView = require('../views/workflow-results');
+let ResultsView = require('../views/job-results-view');
let SettingsViewerView = require('../views/settings-viewer');
//templates
let template = require('../templates/pages/workflowManager.pug');
@@ -142,6 +142,7 @@ let WorkflowManager = PageView.extend({
},
removeActiveJob: function () {
$(this.queryByHook("active-job-header-container")).css("display", "none");
+ $("#review-model-section").css("display", "none");
if(this.resultsView) {
this.resultsView.remove();
}
@@ -213,6 +214,7 @@ let WorkflowManager = PageView.extend({
if(this.modelView) {
this.modelView.remove();
}
+ $("#review-model-section").css("display", "block")
let header = "Review Model: " + this.model.activeJob.model.name;
$("#model-viewer-header").html(header);
this.modelView = new ModelView({
@@ -287,7 +289,7 @@ let WorkflowManager = PageView.extend({
let hadActiveJob = Boolean(this.model.activeJob.status)
app.getXHR(this.model.url(), {
success: function (err, response, body) {
- self.model.set(body);
+ self.model.set({jobs: body.jobs, activeJob: body.activeJob});
if(!Boolean(self.model.activeJob.status)){
self.removeActiveJob();
}else if(!hadActiveJob && Boolean(self.model.activeJob.status)) {
diff --git a/client/templates/includes/editSweepParameter.pug b/client/templates/includes/editSweepParameter.pug
new file mode 100644
index 0000000000..95248b431c
--- /dev/null
+++ b/client/templates/includes/editSweepParameter.pug
@@ -0,0 +1,30 @@
+div.mx-1
+
+ if(this.model.collection.indexOf(this.model) !== 0)
+ hr
+
+ div.row
+
+ div.col-sm-2
+
+ div(data-hook=this.model.elementID + "-sweep-target")
+
+ div.col-sm-2
+
+ div(data-hook=this.model.elementID + "-target-value")=this.parameter.expression
+
+ div.col-sm-2
+
+ div(data-hook=this.model.elementID + "-target-min")
+
+ div.col-sm-2
+
+ div(data-hook=this.model.elementID + "-target-max")
+
+ div.col-sm-2
+
+ div(data-hook=this.model.elementID + "-target-steps")
+
+ div.col-sm-2
+
+ button.btn.btn-outline-secondary.box-shadow(data-hook=this.model.elementID + "-remove") X
diff --git a/client/templates/includes/gillespyResults.pug b/client/templates/includes/gillespyResults.pug
deleted file mode 100644
index ec7dc3f17e..0000000000
--- a/client/templates/includes/gillespyResults.pug
+++ /dev/null
@@ -1,81 +0,0 @@
-div#workflow-results.card.card-body
-
- div
-
- h3.inline Results
-
- button.btn.btn-outline-collapse(data-toggle="collapse" data-target="#collapse-results" data-hook="collapse-results-btn") -
-
- div.collapse.show(id="collapse-results" data-hook="workflow-results")
-
- div.collapse(id="edit-plot-args" data-hook="edit-plot-args")
-
- table.table
- thead
- tr
- th(scope="col") Title
- th(scope="col") X-axis Label
- th(scope="col") Y-axis Label
-
- tbody
- tr
- td: div(id="title" data-hook="title")
- td: div(id="xaxis" data-hook="xaxis")
- td: div(id="yaxis" data-hook="yaxis")
-
- div.card.card-body
-
- div
-
- h5.inline Plot Trajectories
-
- button.btn.btn-outline-collapse(
- data-toggle="collapse"
- data-target="#collapse-trajectories"
- id="collapse-trajectories-btn"
- data-hook="collapse-trajectories-btn"
- data-trigger="collapse-plot-container"
- data-type="trajectories"
- ) -
-
- div.collapse.show(id="collapse-trajectories")
-
- div(data-hook="trajectories-plot")
-
- div.spinner-border.workflow-plot(data-hook="trajectories-plot-spinner")
-
- button.btn.btn-primary.box-shadow(data-hook="trajectories-edit-plot" data-target="edit-plot" disabled) Edit Plot
-
- button.btn.btn-primary.box-shadow(
- data-hook="trajectories-download-png-custom"
- data-target="download-png-custom"
- data-type="trajectories"
- disabled
- ) Download PNG
-
- button.btn.btn-primary.box-shadow(
- data-hook="trajectories-download-json"
- data-target="download-json"
- data-type="trajectories"
- disabled
- ) Download JSON
-
- button.btn.btn-primary.box-shadow(id="convert-to-notebook" data-hook="convert-to-notebook") Convert to Notebook
-
- button.btn.btn-primary.box-shadow(id="download-results-csv" data-hook="download-results-csv") Download Results as .csv
-
- button.btn.btn-primary.box-shadow(id="job-presentation" data-hook="job-presentation") Publish
-
- div.saving-status(data-hook="job-action-start")
-
- div.spinner-grow
-
- span Publishing ...
-
- div.saved-status(data-hook="job-action-end")
-
- span Published
-
- div.save-error-status(data-hook="job-action-err")
-
- span Error
diff --git a/client/templates/includes/gillespyResultsEnsemble.pug b/client/templates/includes/gillespyResultsEnsemble.pug
deleted file mode 100644
index 87282e234a..0000000000
--- a/client/templates/includes/gillespyResultsEnsemble.pug
+++ /dev/null
@@ -1,194 +0,0 @@
-div#workflow-results.card.card-body
-
- div
-
- h3.inline Results
-
- button.btn.btn-outline-collapse(data-toggle="collapse" data-target="#collapse-results" data-hook="collapse-results-btn") -
-
- div.collapse.show(id="collapse-results" data-hook="workflow-results")
-
- div.collapse(id="edit-plot-args" data-hook="edit-plot-args")
-
- table.table
- thead
- tr
- th(scope="col") Title
- th(scope="col") X-axis Label
- th(scope="col") Y-axis Label
-
- tbody
- tr
- td: div(id="title" data-hook="title")
- td: div(id="xaxis" data-hook="xaxis")
- td: div(id="yaxis" data-hook="yaxis")
-
- div.card.card-body
-
- div
-
- h5.inline Plot Mean and Standard Deviation
-
- button.btn.btn-outline-collapse(
- data-toggle="collapse"
- data-target="#collapse-stddevrange"
- id="collapse-stddevrange-btn"
- data-hook="collapse-stddevrange-btn"
- data-trigger="collapse-plot-container"
- data-type="stddevran"
- ) -
-
- div.collapse.show(id="collapse-stddevrange")
-
- div(data-hook="stddevran-plot")
-
- div.spinner-border.workflow-plot(data-hook="stddevran-plot-spinner")
-
- button.btn.btn-primary.box-shadow(data-hook="stddevran-edit-plot" data-target="edit-plot" disabled) Edit Plot
-
- button.btn.btn-primary.box-shadow(
- data-hook="stddevran-download-png-custom"
- data-target="download-png-custom"
- data-type="stddevran"
- disabled
- ) Download PNG
-
- button.btn.btn-primary.box-shadow(
- data-hook="stddevran-download-json"
- data-target="download-json"
- data-type="stddevran"
- disabled
- ) Download JSON
-
- div.card.card-body
-
- div
-
- h5.inline Plot Trajectories
-
- button.btn.btn-outline-collapse(
- data-toggle="collapse"
- data-target="#collapse-trajectories"
- id="collapse-trajectories-btn"
- data-hook="collapse-trajectories-btn"
- data-trigger="collapse-plot-container"
- data-type="trajectories"
- ) +
-
- div.collapse(id="collapse-trajectories")
-
- div(data-hook="trajectories-plot")
-
- div.spinner-border.workflow-plot(data-hook="trajectories-plot-spinner")
-
- button.btn.btn-primary.box-shadow(data-hook="trajectories-edit-plot" data-target="edit-plot" disabled) Edit Plot
-
- button.btn.btn-primary.box-shadow(data-hook="multiple-plots", data-type="mltplplt" disabled) Multiple Plots
-
- button.btn.btn-primary.box-shadow(
- data-hook="trajectories-download-png-custom"
- data-target="download-png-custom"
- data-type="trajectories"
- disabled
- ) Download PNG
-
- button.btn.btn-primary.box-shadow(
- data-hook="trajectories-download-json"
- data-target="download-json"
- data-type="trajectories"
- disabled
- ) Download JSON
-
- div.card.card-body
-
- div
-
- h5.inline Plot Standard Deviation
-
- button.btn.btn-outline-collapse(
- data-toggle="collapse"
- data-target="#collapse-stddev"
- id="collapse-stddev-btn"
- data-hook="collapse-stddev-btn"
- data-trigger="collapse-plot-container"
- data-type="stddev"
- ) +
-
- div.collapse(id="collapse-stddev")
-
- div(data-hook="stddev-plot")
-
- div.spinner-border.workflow-plot(data-hook="stddev-plot-spinner")
-
- button.btn.btn-primary.box-shadow(data-hook="stddev-edit-plot" data-target="edit-plot" disabled) Edit Plot
-
- button.btn.btn-primary.box-shadow(
- data-hook="stddev-download-png-custom"
- data-target="download-png-custom"
- data-type="stddev"
- disabled
- ) Download PNG
-
- button.btn.btn-primary.box-shadow(
- data-hook="stddev-download-json"
- data-target="download-json"
- data-type="stddev"
- disabled
- ) Download JSON
-
- div.card.card-body
-
- div
-
- h5.inline Plot Trajectory Mean
-
- button.btn.btn-outline-collapse(
- data-toggle="collapse"
- data-target="#collapse-trajmean"
- id="collapse-trajmean-btn"
- data-hook="collapse-trajmean-btn"
- data-trigger="collapse-plot-container"
- data-type="avg"
- ) +
-
- div.collapse(id="collapse-trajmean")
-
- div(data-hook="avg-plot")
-
- div.spinner-border.workflow-plot(data-hook="avg-plot-spinner")
-
- button.btn.btn-primary.box-shadow(data-hook="avg-edit-plot" data-target="edit-plot" disabled) Edit Plot
-
- button.btn.btn-primary.box-shadow(
- data-hook="avg-download-png-custom"
- data-target="download-png-custom"
- data-type="avg"
- disabled
- ) Download PNG
-
- button.btn.btn-primary.box-shadow(
- data-hook="avg-download-json"
- data-target="download-json"
- data-type="avg"
- disabled
- ) Download JSON
-
- button.btn.btn-primary.box-shadow(id="convert-to-notebook" data-hook="convert-to-notebook") Convert to Notebook
-
- button.btn.btn-primary.box-shadow(id="download-results-csv" data-hook="download-results-csv") Download Results as .csv
-
- button.btn.btn-primary.box-shadow(id="job-presentation" data-hook="job-presentation") Publish
-
- div.saving-status(data-hook="job-action-start")
-
- div.spinner-grow
-
- span Publishing ...
-
- div.saved-status(data-hook="job-action-end")
-
- span Published
-
- div.save-error-status(data-hook="job-action-err")
-
- span Error
diff --git a/client/templates/includes/gillespyResultsEnsembleView.pug b/client/templates/includes/gillespyResultsEnsembleView.pug
new file mode 100644
index 0000000000..3bcdc2856e
--- /dev/null
+++ b/client/templates/includes/gillespyResultsEnsembleView.pug
@@ -0,0 +1,204 @@
+div#workflow-results.card
+
+ div.card-header.pb-0
+
+ h3.inline Results
+
+ button.btn.btn-outline-collapse(data-toggle="collapse" data-target="#collapse-results" data-hook="collapse-results-btn") -
+
+ div.collapse.show(id="collapse-results" data-hook="workflow-results")
+
+ div.card-body
+
+ div.collapse(id="edit-plot-args" data-hook="edit-plot-args")
+
+ table.table
+ thead
+ tr
+ th(scope="col") Title
+ th(scope="col") X-axis Label
+ th(scope="col") Y-axis Label
+
+ tbody
+ tr
+ td: div(id="title" data-hook="title")
+ td: div(id="xaxis" data-hook="xaxis")
+ td: div(id="yaxis" data-hook="yaxis")
+
+ div.card
+
+ div.card-header.pb-0
+
+ h5.inline Plot Mean and Standard Deviation
+
+ button.btn.btn-outline-collapse(
+ data-toggle="collapse"
+ data-target="#collapse-stddevrange"
+ id="collapse-stddevrange-btn"
+ data-hook="collapse-stddevrange-btn"
+ data-trigger="collapse-plot-container"
+ data-type="stddevran"
+ ) -
+
+ div.collapse.show(id="collapse-stddevrange")
+
+ div.card-body
+
+ div(data-hook="stddevran-plot")
+
+ div.spinner-border.workflow-plot(data-hook="stddevran-plot-spinner")
+
+ button.btn.btn-primary.box-shadow(data-hook="stddevran-edit-plot" data-target="edit-plot" disabled) Edit Plot
+
+ button.btn.btn-primary.box-shadow(
+ data-hook="stddevran-download-png-custom"
+ data-target="download-png-custom"
+ data-type="stddevran"
+ disabled
+ ) Download PNG
+
+ button.btn.btn-primary.box-shadow(
+ data-hook="stddevran-download-json"
+ data-target="download-json"
+ data-type="stddevran"
+ disabled
+ ) Download JSON
+
+ div.card
+
+ div.card-header.pb-0
+
+ h5.inline Plot Trajectories
+
+ button.btn.btn-outline-collapse(
+ data-toggle="collapse"
+ data-target="#collapse-trajectories"
+ id="collapse-trajectories-btn"
+ data-hook="collapse-trajectories-btn"
+ data-trigger="collapse-plot-container"
+ data-type="trajectories"
+ ) +
+
+ div.collapse(id="collapse-trajectories")
+
+ div.card-body
+
+ div(data-hook="trajectories-plot")
+
+ div.spinner-border.workflow-plot(data-hook="trajectories-plot-spinner")
+
+ button.btn.btn-primary.box-shadow(data-hook="trajectories-edit-plot" data-target="edit-plot" disabled) Edit Plot
+
+ button.btn.btn-primary.box-shadow(data-hook="multiple-plots", data-type="mltplplt" disabled) Multiple Plots
+
+ button.btn.btn-primary.box-shadow(
+ data-hook="trajectories-download-png-custom"
+ data-target="download-png-custom"
+ data-type="trajectories"
+ disabled
+ ) Download PNG
+
+ button.btn.btn-primary.box-shadow(
+ data-hook="trajectories-download-json"
+ data-target="download-json"
+ data-type="trajectories"
+ disabled
+ ) Download JSON
+
+ div.card
+
+ div.card-header.pb-0
+
+ h5.inline Plot Standard Deviation
+
+ button.btn.btn-outline-collapse(
+ data-toggle="collapse"
+ data-target="#collapse-stddev"
+ id="collapse-stddev-btn"
+ data-hook="collapse-stddev-btn"
+ data-trigger="collapse-plot-container"
+ data-type="stddev"
+ ) +
+
+ div.collapse(id="collapse-stddev")
+
+ div.card-body
+
+ div(data-hook="stddev-plot")
+
+ div.spinner-border.workflow-plot(data-hook="stddev-plot-spinner")
+
+ button.btn.btn-primary.box-shadow(data-hook="stddev-edit-plot" data-target="edit-plot" disabled) Edit Plot
+
+ button.btn.btn-primary.box-shadow(
+ data-hook="stddev-download-png-custom"
+ data-target="download-png-custom"
+ data-type="stddev"
+ disabled
+ ) Download PNG
+
+ button.btn.btn-primary.box-shadow(
+ data-hook="stddev-download-json"
+ data-target="download-json"
+ data-type="stddev"
+ disabled
+ ) Download JSON
+
+ div.card
+
+ div.card-header.pb-0
+
+ h5.inline Plot Trajectory Mean
+
+ button.btn.btn-outline-collapse(
+ data-toggle="collapse"
+ data-target="#collapse-trajmean"
+ id="collapse-trajmean-btn"
+ data-hook="collapse-trajmean-btn"
+ data-trigger="collapse-plot-container"
+ data-type="avg"
+ ) +
+
+ div.collapse(id="collapse-trajmean")
+
+ div.card-body
+
+ div(data-hook="avg-plot")
+
+ div.spinner-border.workflow-plot(data-hook="avg-plot-spinner")
+
+ button.btn.btn-primary.box-shadow(data-hook="avg-edit-plot" data-target="edit-plot" disabled) Edit Plot
+
+ button.btn.btn-primary.box-shadow(
+ data-hook="avg-download-png-custom"
+ data-target="download-png-custom"
+ data-type="avg"
+ disabled
+ ) Download PNG
+
+ button.btn.btn-primary.box-shadow(
+ data-hook="avg-download-json"
+ data-target="download-json"
+ data-type="avg"
+ disabled
+ ) Download JSON
+
+ button.btn.btn-primary.box-shadow(id="convert-to-notebook" data-hook="convert-to-notebook") Convert to Notebook
+
+ button.btn.btn-primary.box-shadow(id="download-results-csv" data-hook="download-results-csv") Download Results as .csv
+
+ button.btn.btn-primary.box-shadow(id="job-presentation" data-hook="job-presentation") Publish
+
+ div.saving-status(data-hook="job-action-start")
+
+ div.spinner-grow
+
+ span Publishing ...
+
+ div.saved-status(data-hook="job-action-end")
+
+ span Published
+
+ div.save-error-status(data-hook="job-action-err")
+
+ span Error
diff --git a/client/templates/includes/gillespyResultsView.pug b/client/templates/includes/gillespyResultsView.pug
new file mode 100644
index 0000000000..a7a9814814
--- /dev/null
+++ b/client/templates/includes/gillespyResultsView.pug
@@ -0,0 +1,85 @@
+div#workflow-results.card
+
+ div.card-header.pb-0
+
+ h3.inline Results
+
+ button.btn.btn-outline-collapse(data-toggle="collapse" data-target="#collapse-results" data-hook="collapse-results-btn") -
+
+ div.collapse.show(id="collapse-results" data-hook="workflow-results")
+
+ div.card-body
+
+ div.collapse(id="edit-plot-args" data-hook="edit-plot-args")
+
+ table.table
+ thead
+ tr
+ th(scope="col") Title
+ th(scope="col") X-axis Label
+ th(scope="col") Y-axis Label
+
+ tbody
+ tr
+ td: div(id="title" data-hook="title")
+ td: div(id="xaxis" data-hook="xaxis")
+ td: div(id="yaxis" data-hook="yaxis")
+
+ div.card
+
+ div.card-header.pb-0
+
+ h5.inline Plot Trajectories
+
+ button.btn.btn-outline-collapse(
+ data-toggle="collapse"
+ data-target="#collapse-trajectories"
+ id="collapse-trajectories-btn"
+ data-hook="collapse-trajectories-btn"
+ data-trigger="collapse-plot-container"
+ data-type="trajectories"
+ ) -
+
+ div.collapse.show(id="collapse-trajectories")
+
+ div.card-body
+
+ div(data-hook="trajectories-plot")
+
+ div.spinner-border.workflow-plot(data-hook="trajectories-plot-spinner")
+
+ button.btn.btn-primary.box-shadow(data-hook="trajectories-edit-plot" data-target="edit-plot" disabled) Edit Plot
+
+ button.btn.btn-primary.box-shadow(
+ data-hook="trajectories-download-png-custom"
+ data-target="download-png-custom"
+ data-type="trajectories"
+ disabled
+ ) Download PNG
+
+ button.btn.btn-primary.box-shadow(
+ data-hook="trajectories-download-json"
+ data-target="download-json"
+ data-type="trajectories"
+ disabled
+ ) Download JSON
+
+ button.btn.btn-primary.box-shadow(id="convert-to-notebook" data-hook="convert-to-notebook") Convert to Notebook
+
+ button.btn.btn-primary.box-shadow(id="download-results-csv" data-hook="download-results-csv") Download Results as .csv
+
+ button.btn.btn-primary.box-shadow(id="job-presentation" data-hook="job-presentation") Publish
+
+ div.saving-status(data-hook="job-action-start")
+
+ div.spinner-grow
+
+ span Publishing ...
+
+ div.saved-status(data-hook="job-action-end")
+
+ span Published
+
+ div.save-error-status(data-hook="job-action-err")
+
+ span Error
diff --git a/client/templates/includes/jobInfoView.pug b/client/templates/includes/jobInfoView.pug
new file mode 100644
index 0000000000..36154a634f
--- /dev/null
+++ b/client/templates/includes/jobInfoView.pug
@@ -0,0 +1,29 @@
+div#job-info-view.card
+
+ div.card-header.pb-0
+
+ h3.inline Info
+
+ button.btn.btn-outline-collapse(data-toggle="collapse" data-target="#collapse-info" data-hook="collapse-info") +
+
+ div.collapse(id="collapse-info" data-hook="job-info")
+
+ div.card-body
+
+ div.collapse(data-hook="job-statistics")
+
+ h5.inline Statistics
+
+ div(data-hook="list-of-notes")
+
+ div.collapse(data-hook="job-warnings")
+
+ h5.inline Warnings
+
+ div(data-hook="list-of-warnings")
+
+ div.collapse(data-hook="job-errors")
+
+ h5.inline Errors
+
+ div(data-hook="list-of-errors")
\ No newline at end of file
diff --git a/client/templates/includes/parameterScanResults.pug b/client/templates/includes/parameterScanResults.pug
deleted file mode 100644
index 7c02d2860e..0000000000
--- a/client/templates/includes/parameterScanResults.pug
+++ /dev/null
@@ -1,97 +0,0 @@
-div#workflow-results.card.card-body
-
- div.head
-
- h3.inline.mr-2 Results
-
- button.btn.btn-outline-collapse.mb-1(data-toggle="collapse" data-target="#collapse-results" data-hook="collapse-results-btn") -
-
- div.collapse.show(id="collapse-results" data-hook="workflow-results")
-
- div.collapse(id="edit-plot-args" data-hook="edit-plot-args")
-
- table.table
- thead
- tr
- th(scope="col") Title
- th(scope="col") X-axis Label
- th(scope="col") Y-axis Label
-
- tbody
- tr
- td: div(id="title" data-hook="title")
- td: div(id="xaxis" data-hook="xaxis")
- td: div(id="yaxis" data-hook="yaxis")
-
- div.card.card-body
-
- div
-
- h5.inline Parameter Sweep
-
- button.btn.btn-outline-collapse(
- data-toggle="collapse"
- data-target="#collapse-ts-psweep"
- id="collapse-ts-psweep-btn"
- data-hook="collapse-ts-psweep-btn"
- data-trigger="collapse-plot-container"
- data-type="ts-psweep"
- ) -
-
- div.collapse.show(id="collapse-ts-psweep")
-
- div.row
-
- div.col-md-9
-
- div(data-hook="ts-psweep-plot")
-
- div.spinner-border.workflow-plot(data-hook="ts-psweep-plot-spinner")
-
- button.btn.btn-primary.box-shadow(data-hook="ts-psweep-edit-plot" data-target="edit-plot" disabled) Edit Plot
-
- button.btn.btn-primary.box-shadow(data-hook="multiple-plots" data-type="ts-psweep-mp" style="display: none;" disabled) Multiple Plots
-
- button.btn.btn-primary.box-shadow(
- data-hook="ts-psweep-download-png-custom"
- data-target="download-png-custom"
- data-type="ts-psweep"
- disabled
- ) Download PNG
-
- button.btn.btn-primary.box-shadow(
- data-hook="ts-psweep-download-json"
- data-target="download-json"
- data-type="ts-psweep"
- disabled
- ) Download JSON
-
- div.col-md-3
-
- div.head(data-hook="plot-type-header")
-
- h6 Plot Type
-
- div.mt-2(data-hook="plot-type-select")
-
- div.head
-
- h6 Parameters
-
- div.mt-2(data-hook="parameter-ranges")
-
- button.btn.btn-primary.box-shadow(id="job-presentation" data-hook="job-presentation") Publish Presentation
-
- div.saving-status(data-hook="job-action-start")
-
- div.spinner-grow
-
- span Publishing ...
-
- div.saved-status(data-hook="job-action-end")
-
- span Published
-
- div.save-error-status(data-hook="job-action-err")
-
- span Error
diff --git a/client/templates/includes/parameterScanResultsView.pug b/client/templates/includes/parameterScanResultsView.pug
new file mode 100644
index 0000000000..94add97d48
--- /dev/null
+++ b/client/templates/includes/parameterScanResultsView.pug
@@ -0,0 +1,202 @@
+div#workflow-results.card
+
+ div.card-header.pb-0
+
+ h3.inline.mr-2 Results
+
+ div.inline
+
+ ul.nav.nav-tabs
+
+ li.nav-item
+
+ a.nav-link.tab.active(data-toggle="tab" href="#time-series") Time Series
+
+ li.nav-item
+
+ a.nav-link.tab(data-toggle="tab" href="#sweep") Sweep
+
+ button.btn.btn-outline-collapse(data-toggle="collapse" data-target="#collapse-results" data-hook="collapse-results-btn") -
+
+ div.collapse.show(id="collapse-results" data-hook="workflow-results")
+
+ div.card-body
+
+ div.collapse(id="edit-plot-args" data-hook="edit-plot-args")
+
+ table.table
+ thead
+ tr
+ th(scope="col") Title
+ th(scope="col") X-axis Label
+ th(scope="col") Y-axis Label
+
+ tbody
+ tr
+ td: div(id="title" data-hook="title")
+ td: div(id="xaxis" data-hook="xaxis")
+ td: div(id="yaxis" data-hook="yaxis")
+
+ div.tab-content
+
+ div.tab-pane.active.card(id="time-series" data-hook="time-series")
+
+ div.card-header.pb-0
+
+ h5.inline Parameter Sweep
+
+ button.btn.btn-outline-collapse(
+ data-toggle="collapse"
+ data-target="#collapse-ts-psweep"
+ id="collapse-ts-psweep-btn"
+ data-hook="collapse-ts-psweep-btn"
+ data-trigger="collapse-plot-container"
+ data-type="ts-psweep"
+ ) -
+
+ div.collapse.show(id="collapse-ts-psweep")
+
+ div.card-body
+
+ div.row
+
+ div.col-md-9
+
+ div(data-hook="ts-psweep-plot")
+
+ div.spinner-border.workflow-plot(data-hook="ts-psweep-plot-spinner")
+
+ button.btn.btn-primary.box-shadow(data-hook="ts-psweep-edit-plot" data-target="edit-plot" disabled) Edit Plot
+
+ button.btn.btn-primary.box-shadow(data-hook="multiple-plots" data-type="ts-psweep-mp" style="display: none;" disabled) Multiple Plots
+
+ button.btn.btn-primary.box-shadow(
+ data-hook="ts-psweep-download-png-custom"
+ data-target="download-png-custom"
+ data-type="ts-psweep"
+ disabled
+ ) Download PNG
+
+ button.btn.btn-primary.box-shadow(
+ data-hook="ts-psweep-download-json"
+ data-target="download-json"
+ data-type="ts-psweep"
+ disabled
+ ) Download JSON
+
+ div.col-md-3
+
+ div.head(data-hook="plot-type-header")
+
+ h6 Plot Type
+
+ div.my-3(data-hook="plot-type-select")
+
+ div.head
+
+ h6 Parameters
+
+ div.mt-3(data-hook="ts-parameter-ranges")
+
+ div.tab-pane.mt-3(id="sweep" data-hook="sweep")
+
+ div.inline.horizontal-space
+
+ span.inline(for="species-of-interest") Variable of Interest:
+
+ div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.species)
+
+ div.inline(id="species-of-interest" data-hook="specie-of-interest-list")
+
+ div.inline.horizontal-space
+
+ span.inline(for="feature-extractor") Feature Extraction:
+
+ div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.mapper)
+
+ div.inline(id="feature-extractor" data-hook="feature-extraction-list")
+
+ div.inline.horizontal-space(id="ensemble-aggragator-container" data-hook="ensemble-aggragator-container")
+
+ span.inline(for="ensemble-aggragator") Ensemble Aggragator:
+
+ div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.reducer)
+
+ div.inline(id="ensemble-aggragator" data-hook="ensemble-aggragator-list")
+
+ div.card
+
+ div.card-header.pb-0
+
+ h5.inline Parameter Sweep
+
+ button.btn.btn-outline-collapse(
+ data-toggle="collapse"
+ data-target="#collapse-psweep"
+ id="collapse-psweep-btn"
+ data-hook="collapse-psweep-btn"
+ data-trigger="collapse-plot-container"
+ data-type="psweep"
+ ) -
+
+ div.collapse.show(id="collapse-psweep")
+
+ div.card-body
+
+ div.row
+
+ div.col-md-9
+
+ div(data-hook="psweep-plot")
+
+ div.spinner-border.workflow-plot(data-hook="psweep-plot-spinner")
+
+ div.mb-3(data-hook="too-few-params")
+
+ p.text-danger
+ | The number of variable parameters cannot exceed 2. Please add another fixed parameters.
+
+ div.mb-3(data-hook="too-many-params" style="display: none")
+
+ p.text-danger
+ | The number of variable parameters cannot be 0. Please remove a fixed parameter.
+
+ button.btn.btn-primary.box-shadow(data-hook="psweep-edit-plot" data-target="edit-plot" disabled) Edit Plot
+
+ button.btn.btn-primary.box-shadow(
+ data-hook="psweep-download-png-custom"
+ data-target="download-png-custom"
+ data-type="psweep"
+ disabled
+ ) Download PNG
+
+ button.btn.btn-primary.box-shadow(
+ data-hook="psweep-download-json"
+ data-target="download-json"
+ data-type="psweep"
+ disabled
+ ) Download JSON
+
+ div.col-md-3
+
+ div.head
+
+ h6 Parameters
+
+ div.mt-3(data-hook="ps-parameter-ranges")
+
+ button.btn.btn-primary.box-shadow(id="job-presentation" data-hook="job-presentation") Publish Presentation
+
+ div.saving-status(data-hook="job-action-start")
+
+ div.spinner-grow
+
+ span Publishing ...
+
+ div.saved-status(data-hook="job-action-end")
+
+ span Published
+
+ div.save-error-status(data-hook="job-action-err")
+
+ span Error
diff --git a/client/templates/includes/parameterSettings.pug b/client/templates/includes/parameterSettings.pug
deleted file mode 100644
index a64be2313f..0000000000
--- a/client/templates/includes/parameterSettings.pug
+++ /dev/null
@@ -1,60 +0,0 @@
-div#parameter-settings.card.card-body
-
- div
-
- h3.inline Parameter Settings
-
- button.btn.btn-outline-collapse(data-toggle="collapse" data-target="#collapse-psweep-settings" data-hook="collapse") -
-
- div.collapse(class="show", id="collapse-psweep-settings")
-
- div.verticle-space
-
- span.inline(for="variable-of-interest") Variable of Interest:
-
- div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.species)
-
- div.inline(id="variable-of-interest" data-hook="variable-of-interest-list")
-
- div
-
- h5 Configure Parameter(s)
-
- table.table
- thead
- tr
- th(scope="col")
- div
- div.inline Sweep Target
-
- div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.variable)
-
- th(scope="col")
- div
- div.inline Current Value
-
- div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.value)
-
- th(scope="col")
- div
- div.inline Minimum Value
-
- div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.min)
-
- th(scope="col")
- div
- div.inline Maximum Value
-
- div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.max)
-
- th(scope="col")
- div
- div.inline Steps
-
- div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.steps)
-
- th(scope="col") Remove
-
- tbody(data-hook="ps-parameter-collection")
-
- button.btn.btn-outline-secondary.box-shadow(data-hook="add-ps-parameter") Add Parameter
\ No newline at end of file
diff --git a/client/templates/includes/parameterSettingsView.pug b/client/templates/includes/parameterSettingsView.pug
new file mode 100644
index 0000000000..0d808c67b5
--- /dev/null
+++ b/client/templates/includes/parameterSettingsView.pug
@@ -0,0 +1,117 @@
+div#parameter-settings.card
+
+ div.card-header.pb-0
+
+ h3.inline.mr-3 Parameter Settings
+
+ div.inline.mr-3
+
+ ul.nav.nav-tabs.card-header-tabs(id="parameter-settings-tabs")
+
+ li.nav-item
+
+ a.nav-link.tab.active(data-hook="parameter-settings-edit-tab" data-toggle="tab" href="#edit-parameter-settings") Edit
+
+ li.nav-item
+
+ a.nav-link.tab(data-hook="parameter-settings-view-tab" data-toggle="tab" href="#view-parameter-settings") View
+
+ button.btn.btn-outline-collapse(data-toggle="collapse" data-target="#collapse-psweep-settings" data-hook="collapse") -
+
+ div.collapse(class="show", id="collapse-psweep-settings")
+
+ div.card-body.tab-content
+
+ div.tab-pane.active(id="edit-parameter-settings" data-hook="edit-parameter-settings")
+
+ div.verticle-space
+
+ span.inline(for="variable-of-interest") Variable of Interest:
+
+ div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.species)
+
+ div.inline(id="variable-of-interest" data-hook="variable-of-interest-list")
+
+ div
+
+ h5 Configure Parameter(s)
+
+ hr
+
+ div.mx-1.row.head.align-items-baseline
+
+ div.col-sm-2
+
+ h6.inline
Sweep Target
+
+ div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.variable)
+
+ div.col-sm-2
+
+ h6.inline
Current Value
+
+ div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.value)
+
+ div.col-sm-2
+
+ h6.inline
Minimum Value
+
+ div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.min)
+
+ div.col-sm-2
+
+ h6.inline
Maximum Value
+
+ div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.max)
+
+ div.col-sm-2
+
+ h6.inline
Steps
+
+ div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.steps)
+
+ div.col-sm-2
+
+ h6
Remove
+
+ div.my-3(data-hook="ps-parameter-collection")
+
+ button.btn.btn-outline-secondary.box-shadow(data-hook="add-ps-parameter") Add Parameter
+
+ div.tab-pane(id="view-parameter-settings" data-hook="view-parameter-settings")
+
+ div
+
+ div.inline.pr-2 Variable of Interest:
+
+ div.inline(id="view-species-of-interest")=this.model.speciesOfInterest.name
+
+ div
+
+ h5.mt-3 Sweep Parameters
+
+ hr
+
+ div.mx-1.row.head.align-items-baseline
+
+ div.col-sm-3
+
+ h6.inline
Sweep Target
+
+ div.col-sm-3
+
+ h6.inline
Current Value
+
+ div.col-sm-2
+
+ h6.inline
Minimum Value
+
+ div.col-sm-2
+
+ h6.inline
Maximum Value
+
+ div.col-sm-2
+
+ h6.inline
Steps
+
+ div.my-3(data-hook="view-sweep-parameters")
diff --git a/client/templates/includes/parameterSweepResults.pug b/client/templates/includes/parameterSweepResults.pug
deleted file mode 100644
index ccd407c306..0000000000
--- a/client/templates/includes/parameterSweepResults.pug
+++ /dev/null
@@ -1,178 +0,0 @@
-div#workflow-results.card.card-body
-
- div.head
-
- h3.inline.mr-2 Results
-
- div.inline
-
- ul.nav.nav-tabs
-
- li.nav-item
-
- a.nav-link.tab(data-toggle="tab" href="#time-series") Time Series
-
- li.nav-item
-
- a.nav-link.tab.active(data-toggle="tab" href="#sweep") Sweep
-
- button.btn.btn-outline-collapse.mb-1(data-toggle="collapse" data-target="#collapse-results" data-hook="collapse-results-btn") -
-
- div.collapse.show(id="collapse-results" data-hook="workflow-results")
-
- div.collapse(id="edit-plot-args" data-hook="edit-plot-args")
-
- table.table
- thead
- tr
- th(scope="col") Title
- th(scope="col") X-axis Label
- th(scope="col") Y-axis Label
-
- tbody
- tr
- td: div(id="title" data-hook="title")
- td: div(id="xaxis" data-hook="xaxis")
- td: div(id="yaxis" data-hook="yaxis")
-
- div.tab-content
-
- div.tab-pane.card.card-body(id="time-series" data-hook="time-series")
-
- div
-
- h5.inline Parameter Sweep
-
- button.btn.btn-outline-collapse(
- data-toggle="collapse"
- data-target="#collapse-ts-psweep"
- id="collapse-ts-psweep-btn"
- data-hook="collapse-ts-psweep-btn"
- data-trigger="collapse-plot-container"
- data-type="ts-psweep"
- ) -
-
- div.collapse.show(id="collapse-ts-psweep")
-
- div.row
-
- div.col-md-9
-
- div(data-hook="ts-psweep-plot")
-
- div.spinner-border.workflow-plot(data-hook="ts-psweep-plot-spinner")
-
- button.btn.btn-primary.box-shadow(data-hook="ts-psweep-edit-plot" data-target="edit-plot" disabled) Edit Plot
-
- button.btn.btn-primary.box-shadow(data-hook="multiple-plots" data-type="ts-psweep-mp" style="display: none;" disabled) Multiple Plots
-
- button.btn.btn-primary.box-shadow(
- data-hook="ts-psweep-download-png-custom"
- data-target="download-png-custom"
- data-type="ts-psweep"
- disabled
- ) Download PNG
-
- button.btn.btn-primary.box-shadow(
- data-hook="ts-psweep-download-json"
- data-target="download-json"
- data-type="ts-psweep"
- disabled
- ) Download JSON
-
- div.col-md-3
-
- div.head(data-hook="plot-type-header")
-
- h6 Plot Type
-
- div.mt-2(data-hook="plot-type-select")
-
- div.head
-
- h6 Parameters
-
- div.mt-2(data-hook="parameter-ranges")
-
- div.tab-pane.active.mt-3(id="sweep" data-hook="sweep")
-
- div.inline.horizontal-space
-
- span.inline(for="species-of-interest") Variable of Interest:
-
- div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.species)
-
- div.inline(id="species-of-interest" data-hook="specie-of-interest-list")
-
- div.inline.horizontal-space
-
- span.inline(for="feature-extractor") Feature Extraction:
-
- div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.mapper)
-
- div.inline(id="feature-extractor" data-hook="feature-extraction-list")
-
- div.inline.horizontal-space(id="ensemble-aggragator-container" data-hook="ensemble-aggragator-container")
-
- span.inline(for="ensemble-aggragator") Ensemble Aggragator:
-
- div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.reducer)
-
- div.inline(id="ensemble-aggragator" data-hook="ensemble-aggragator-list")
-
- div.card.card-body
-
- div
-
- h5.inline Parameter Sweep
-
- button.btn.btn-outline-collapse(
- data-toggle="collapse"
- data-target="#collapse-psweep"
- id="collapse-psweep-btn"
- data-hook="collapse-psweep-btn"
- data-trigger="collapse-plot-container"
- data-type="psweep"
- ) -
-
- div.collapse.show(id="collapse-psweep")
-
- div(data-hook="psweep-plot")
-
- div.spinner-border.workflow-plot(data-hook="psweep-plot-spinner")
-
- button.btn.btn-primary.box-shadow(data-hook="psweep-edit-plot" data-target="edit-plot" disabled) Edit Plot
-
- button.btn.btn-primary.box-shadow(
- data-hook="psweep-download-png-custom"
- data-target="download-png-custom"
- data-type="psweep"
- disabled
- ) Download PNG
-
- button.btn.btn-primary.box-shadow(
- data-hook="psweep-download-json"
- data-target="download-json"
- data-type="psweep"
- disabled
- ) Download JSON
-
- button.btn.btn-primary.box-shadow(id="convert-to-notebook" data-hook="convert-to-notebook") Convert to Notebook
-
- button.btn.btn-primary.box-shadow(id="download-results-csv" data-hook="download-results-csv") Download Results as .csv
-
- button.btn.btn-primary.box-shadow(id="job-presentation" data-hook="job-presentation") Publish
-
- div.saving-status(data-hook="job-action-start")
-
- div.spinner-grow
-
- span Publishing ...
-
- div.saved-status(data-hook="job-action-end")
-
- span Published
-
- div.save-error-status(data-hook="job-action-err")
-
- span Error
diff --git a/client/templates/includes/parameterSweepResultsView.pug b/client/templates/includes/parameterSweepResultsView.pug
new file mode 100644
index 0000000000..10676fc3eb
--- /dev/null
+++ b/client/templates/includes/parameterSweepResultsView.pug
@@ -0,0 +1,184 @@
+div#workflow-results.card
+
+ div.card-header.pb-0
+
+ h3.inline.mr-2 Results
+
+ div.inline
+
+ ul.nav.nav-tabs
+
+ li.nav-item
+
+ a.nav-link.tab(data-toggle="tab" href="#time-series") Time Series
+
+ li.nav-item
+
+ a.nav-link.tab.active(data-toggle="tab" href="#sweep") Sweep
+
+ button.btn.btn-outline-collapse(data-toggle="collapse" data-target="#collapse-results" data-hook="collapse-results-btn") -
+
+ div.collapse.show(id="collapse-results" data-hook="workflow-results")
+
+ div.card-body
+
+ div.collapse(id="edit-plot-args" data-hook="edit-plot-args")
+
+ table.table
+ thead
+ tr
+ th(scope="col") Title
+ th(scope="col") X-axis Label
+ th(scope="col") Y-axis Label
+
+ tbody
+ tr
+ td: div(id="title" data-hook="title")
+ td: div(id="xaxis" data-hook="xaxis")
+ td: div(id="yaxis" data-hook="yaxis")
+
+ div.tab-content
+
+ div.tab-pane.card(id="time-series" data-hook="time-series")
+
+ div.card-header.pb-0
+
+ h5.inline Parameter Sweep
+
+ button.btn.btn-outline-collapse(
+ data-toggle="collapse"
+ data-target="#collapse-ts-psweep"
+ id="collapse-ts-psweep-btn"
+ data-hook="collapse-ts-psweep-btn"
+ data-trigger="collapse-plot-container"
+ data-type="ts-psweep"
+ ) -
+
+ div.collapse.show(id="collapse-ts-psweep")
+
+ div.card-body
+
+ div.row
+
+ div.col-md-9
+
+ div(data-hook="ts-psweep-plot")
+
+ div.spinner-border.workflow-plot(data-hook="ts-psweep-plot-spinner")
+
+ button.btn.btn-primary.box-shadow(data-hook="ts-psweep-edit-plot" data-target="edit-plot" disabled) Edit Plot
+
+ button.btn.btn-primary.box-shadow(data-hook="multiple-plots" data-type="ts-psweep-mp" style="display: none;" disabled) Multiple Plots
+
+ button.btn.btn-primary.box-shadow(
+ data-hook="ts-psweep-download-png-custom"
+ data-target="download-png-custom"
+ data-type="ts-psweep"
+ disabled
+ ) Download PNG
+
+ button.btn.btn-primary.box-shadow(
+ data-hook="ts-psweep-download-json"
+ data-target="download-json"
+ data-type="ts-psweep"
+ disabled
+ ) Download JSON
+
+ div.col-md-3
+
+ div.head(data-hook="plot-type-header")
+
+ h6 Plot Type
+
+ div.my-3(data-hook="plot-type-select")
+
+ div.head
+
+ h6 Parameters
+
+ div.mt-3(data-hook="ts-parameter-ranges")
+
+ div.tab-pane.active.mt-3(id="sweep" data-hook="sweep")
+
+ div.inline.horizontal-space
+
+ span.inline(for="species-of-interest") Variable of Interest:
+
+ div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.species)
+
+ div.inline(id="species-of-interest" data-hook="specie-of-interest-list")
+
+ div.inline.horizontal-space
+
+ span.inline(for="feature-extractor") Feature Extraction:
+
+ div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.mapper)
+
+ div.inline(id="feature-extractor" data-hook="feature-extraction-list")
+
+ div.inline.horizontal-space(id="ensemble-aggragator-container" data-hook="ensemble-aggragator-container")
+
+ span.inline(for="ensemble-aggragator") Ensemble Aggragator:
+
+ div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.reducer)
+
+ div.inline(id="ensemble-aggragator" data-hook="ensemble-aggragator-list")
+
+ div.card
+
+ div.card-header.pb-0
+
+ h5.inline Parameter Sweep
+
+ button.btn.btn-outline-collapse(
+ data-toggle="collapse"
+ data-target="#collapse-psweep"
+ id="collapse-psweep-btn"
+ data-hook="collapse-psweep-btn"
+ data-trigger="collapse-plot-container"
+ data-type="psweep"
+ ) -
+
+ div.collapse.show(id="collapse-psweep")
+
+ div.card-body
+
+ div(data-hook="psweep-plot")
+
+ div.spinner-border.workflow-plot(data-hook="psweep-plot-spinner")
+
+ button.btn.btn-primary.box-shadow(data-hook="psweep-edit-plot" data-target="edit-plot" disabled) Edit Plot
+
+ button.btn.btn-primary.box-shadow(
+ data-hook="psweep-download-png-custom"
+ data-target="download-png-custom"
+ data-type="psweep"
+ disabled
+ ) Download PNG
+
+ button.btn.btn-primary.box-shadow(
+ data-hook="psweep-download-json"
+ data-target="download-json"
+ data-type="psweep"
+ disabled
+ ) Download JSON
+
+ button.btn.btn-primary.box-shadow(id="convert-to-notebook" data-hook="convert-to-notebook") Convert to Notebook
+
+ button.btn.btn-primary.box-shadow(id="download-results-csv" data-hook="download-results-csv") Download Results as .csv
+
+ button.btn.btn-primary.box-shadow(id="job-presentation" data-hook="job-presentation") Publish
+
+ div.saving-status(data-hook="job-action-start")
+
+ div.spinner-grow
+
+ span Publishing ...
+
+ div.saved-status(data-hook="job-action-end")
+
+ span Published
+
+ div.save-error-status(data-hook="job-action-err")
+
+ span Error
diff --git a/client/templates/includes/simulationSettings.pug b/client/templates/includes/simulationSettings.pug
deleted file mode 100644
index 0033f7145a..0000000000
--- a/client/templates/includes/simulationSettings.pug
+++ /dev/null
@@ -1,106 +0,0 @@
-div#simulation-settings.card.card-body
-
- div
-
- h3.inline Simulation Settings
- button.btn.btn-outline-collapse(data-toggle="collapse", data-target="#collapse-settings", data-hook="collapse") -
-
- div.collapse(class="show", id="collapse-settings")
-
- table.table
- thead
- tr
- th(scope="col", colspan="5")
- div
- div.inline Simulation Algorithm
-
- div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.algorithm)
-
- tbody
- tr
- td
- input(type="radio", name="simAlgorithm", data-hook="select-ode", data-name="ODE")
- | ODE
-
- div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.ode)
-
- td
- input(type="radio", name="simAlgorithm", data-hook="select-ssa", data-name="SSA")
- | SSA
-
- div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.ssa)
-
- td
- input(type="radio", name="simAlgorithm", data-hook="select-tau-leaping", data-name="Tau-Leaping")
- | Tau Leaping
-
- div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.tauLeaping)
-
- td
- input(type="radio", name="simAlgorithm", data-hook="select-hybrid-tau", data-name="Hybrid-Tau-Leaping")
- | Hybrid ODE/SSA
-
- div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.hybrid)
-
- td
- input.inline(type="radio", name="simAlgorithm", data-hook="select-automatic", data-name="Automatic")
- | Choose for me
-
- div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.chooseForMe)
-
- div.row.collapse.show(data-hook="settings-container")
-
- div.col-md-5
-
- h5.inline Deterministic Settings
-
- table.table
- thead
- tr
- th(scope="col")
- div
- div.inline Relative Tolerance
-
- div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.rtol)
-
- th(scope="col")
- div
- div.inline Absolute Tolerance
-
- div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.atol)
-
- tbody
- tr
- td: div(data-hook="relative-tolerance")
- td: div(data-hook="absolute-tolerance")
-
- div.col-md-7
-
- h5.inline Stochastic Settings
-
- table.table
- thead
- tr
- th(scope="col")
- div
- div.inline Trajectories
-
- div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.realizations)
-
- th(scope="col")
- div
- div.inline Seed
-
- div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.seed)
-
- th(scope="col")
- div
- div.inline Tau Tolerance
-
- div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.ttol)
-
- tbody
- tr
- td: div(data-hook="trajectories")
- td: div(data-hook="seed")
- td: div(data-hook="tau-tolerance")
\ No newline at end of file
diff --git a/client/templates/includes/simulationSettingsView.pug b/client/templates/includes/simulationSettingsView.pug
new file mode 100644
index 0000000000..0baf7b9adf
--- /dev/null
+++ b/client/templates/includes/simulationSettingsView.pug
@@ -0,0 +1,196 @@
+div#simulation-settings.card
+
+ div.card-header.pb-0
+
+ h3.inline.mr-3 Simulation Settings
+
+ div.inline.mr-3
+
+ ul.nav.nav-tabs.card-header-tabs(id="sim-settings-tabs")
+
+ li.nav-item
+
+ a.nav-link.tab.active(data-hook="sim-settings-edit-tab" data-toggle="tab" href="#edit-sim-settings") Edit
+
+ li.nav-item
+
+ a.nav-link.tab(data-hook="sim-settings-view-tab" data-toggle="tab" href="#view-sim-settings") View
+
+ button.btn.btn-outline-collapse(data-toggle="collapse", data-target="#collapse-settings", data-hook="collapse") -
+
+ div.collapse(class="show", id="collapse-settings")
+
+ div.card-body.tab-content
+
+ div.tab-pane.active(id="edit-sim-settings" data-hook="edit-sim-settings")
+
+ div.mx-1.head.align-items-baseline
+
+ h4.inline Simulation Algorithm
+
+ div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.algorithm)
+
+ div.row.my-3
+
+ div.col-sm-2
+
+ input.pl-2.mr-2.inline(type="radio", name="simAlgorithm", data-hook="select-ode", data-name="ODE")
+
+ span.inline ODE
+
+ div.inline.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.ode)
+
+ div.col-sm-2
+
+ input.mr-2.inline(type="radio", name="simAlgorithm", data-hook="select-ssa", data-name="SSA")
+
+ span.inline SSA
+
+ div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.ssa)
+
+ div.col-sm-2
+
+ input.mr-2.inline(type="radio", name="simAlgorithm", data-hook="select-tau-leaping", data-name="Tau-Leaping")
+
+ span.inline Tau Leaping
+
+ div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.tauLeaping)
+
+ div.col-sm-3
+
+ input.mr-2.inline(type="radio", name="simAlgorithm", data-hook="select-hybrid-tau", data-name="Hybrid-Tau-Leaping")
+
+ span.inline Hybrid ODE/SSA
+
+ div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.hybrid)
+
+ div.col-sm-3
+
+ input.mr-2.inline(type="radio", name="simAlgorithm", data-hook="select-automatic", data-name="Automatic")
+
+ span.inline Choose for me
+
+ div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.chooseForMe)
+
+ div.pt-2.row.collapse.show(data-hook="settings-container")
+
+ div.col-sm-5
+
+ h5.inline Deterministic Settings
+
+ hr.mt-0
+
+ div.mx-1.row.head.align-items-baseline
+
+ div.col-sm-6
+
+ h6.inline
Relative Tolerance
+
+ div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.rtol)
+
+ div.col-sm-6
+
+ h6.inline
Absolute Tolerance
+
+ div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.atol)
+
+ div.row.my-3
+
+ div.col-sm-6
+
+ div.pl-2(data-hook="relative-tolerance")
+
+ div.col-sm-6(data-hook="absolute-tolerance")
+
+ div.col-sm-7
+
+ h5.inline Stochastic Settings
+
+ hr.mt-0
+
+ div.mx-1.row.head.align-items-baseline
+
+ dvi.col-sm-4
+
+ h6.inline
Trajectories
+
+ div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.realizations)
+
+ dvi.col-sm-4
+
+ h6.inline
Seed
+
+ div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.seed)
+
+ dvi.col-sm-4
+
+ h6.inline
Tau Tolerance
+
+ div.tooltip-icon(data-html="true" data-toggle="tooltip" title=this.tooltips.ttol)
+
+ div.row.my-3
+
+ div.col-sm-4(data-hook="trajectories")
+
+ div.col-sm-4(data-hook="seed")
+
+ div.col-sm-4(data-hook="tau-tolerance")
+
+ div.tab-pane(id="view-sim-settings" data-hook="view-sim-settings")
+
+ div
+
+ h6.inline.pr-2 Simulation Algorithm:
+
+ div.inline(data-hook="view-algorithm")
+
+ div(data-hook="view-deterministic-settings")
+
+ hr
+
+ h5 Deterministic Settings
+
+ hr
+
+ div.row
+
+ div.col-sm-6
+
+ h6.inline.pr-2 Relative Tolerance:
+
+ div.inline(data-hook="view-r-tol")=this.model.relativeTol
+
+ div.col-sm-6
+
+ h6.inline.pr-2 Absolute Tolerance:
+
+ div.inline(data-hook="view-a-tol")=this.model.absoluteTol
+
+ div(data-hook="view-stochastic-settings")
+
+ hr
+
+ h5 Stochastic Settings
+
+ hr
+
+ div.row
+
+ div.col-sm-4
+
+ h6.inline.pr-2 Trajectories:
+
+ div.inline(data-hook="view-realizations")=this.model.realizations
+
+ div.col-sm-4
+
+ h6.inline.pr-2 Seed:
+
+ div.inline(data-hook="view-seed")=this.model.seed
+
+ div.col-sm-4(data-hook="view-tau-tolerance")
+
+ h6.inline.pr-2 Tau Tolerance:
+
+ div.inline(data-hook="view-tau-tol")=this.model.tauTol
+
diff --git a/client/templates/includes/sweepParameter.pug b/client/templates/includes/sweepParameter.pug
deleted file mode 100644
index 7398fa4603..0000000000
--- a/client/templates/includes/sweepParameter.pug
+++ /dev/null
@@ -1,25 +0,0 @@
-tr
-
- td
-
- div(data-hook=this.model.elementID + "-sweep-target")
-
- td
-
- div(data-hook=this.model.elementID + "-target-value")=this.parameter.expression
-
- td
-
- div(data-hook=this.model.elementID + "-target-min")
-
- td
-
- div(data-hook=this.model.elementID + "-target-max")
-
- td
-
- div(data-hook=this.model.elementID + "-target-steps")
-
- td
-
- button.btn.btn-outline-secondary.box-shadow(data-hook=this.model.elementID + "-remove") X
diff --git a/client/templates/includes/sweepParameterRange.pug b/client/templates/includes/sweepParameterRange.pug
index eff6534ec5..c83909111e 100644
--- a/client/templates/includes/sweepParameterRange.pug
+++ b/client/templates/includes/sweepParameterRange.pug
@@ -5,11 +5,17 @@ div
div
+ div.inline.mr-2(data-hook=this.model.elementID + "-fixed-container")
+
+ span(for=this.model.elementID + "-fixed") Fixed:
+
+ input(type="checkbox" id=this.model.elementID + "-fixed" data-hook=this.model.elementID + "-fixed")
+
div.inline.mr-2=this.model.name + ":"
div.inline(style="max-width: 100%")
- div.horizontal-scroll(data-hook=this.model.elementID + "-current-value")=this.model.range[0]
+ div.horizontal-scroll(data-hook=this.model.elementID + "-current-value" style="overflow-x: visible; overflow-y: visible;")=this.model.range[0]
input.custom-range(
type="range"
diff --git a/client/templates/includes/viewSweepParameter.pug b/client/templates/includes/viewSweepParameter.pug
index c0a1ad5acb..ba8ff84ae8 100644
--- a/client/templates/includes/viewSweepParameter.pug
+++ b/client/templates/includes/viewSweepParameter.pug
@@ -1,12 +1,18 @@
-tr
-
- td=this.model.name
-
- td=this.parameter.expression
-
- td=this.model.min
-
- td=this.model.max
-
- td=this.model.steps
-
\ No newline at end of file
+div.mx-1
+
+ if(this.model.collection.indexOf(this.model) !== 0)
+ hr
+
+ div.row
+
+ div.col-sm-3
+
+ div.pl-2=this.model.name
+
+ div.col-sm-3=this.parameter.expression
+
+ div.col-sm-2=this.model.min
+
+ div.col-sm-2=this.model.max
+
+ div.col-sm-2=this.model.steps
diff --git a/client/templates/includes/workflowInfo.pug b/client/templates/includes/workflowInfo.pug
deleted file mode 100644
index 97132b0ddf..0000000000
--- a/client/templates/includes/workflowInfo.pug
+++ /dev/null
@@ -1,27 +0,0 @@
-div#workflow-info-view.card.card-body
-
- div
-
- h3.inline Info
-
- button.btn.btn-outline-collapse(data-toggle="collapse" data-target="#collapse-info" data-hook="collapse-info") +
-
- div.collapse(id="collapse-info" data-hook="workflow-info")
-
- div.collapse(data-hook="workflow-statistics")
-
- h5.inline Statistics
-
- div(data-hook="list-of-notes")
-
- div.collapse(data-hook="workflow-warnings")
-
- h5.inline Warnings
-
- div(data-hook="list-of-warnings")
-
- div.collapse(data-hook="workflow-errors")
-
- h5.inline Errors
-
- div(data-hook="list-of-errors")
\ No newline at end of file
diff --git a/client/templates/includes/workflowListing.pug b/client/templates/includes/workflowListing.pug
index f364e78d7b..329fdf2778 100644
--- a/client/templates/includes/workflowListing.pug
+++ b/client/templates/includes/workflowListing.pug
@@ -4,7 +4,10 @@ div
div.col-md-5
- a.btn.btn-outline-secondary.box-shadow.text-break(href=this.model.open style="width: 100%" role="button")=this.model.name
+ if(this.model.type == "Notebook")
+ a.btn.btn-outline-secondary.box-shadow.text-break(href=this.model.open target="_blank" style="width: 100%" role="button")=this.model.name
+ else
+ a.btn.btn-outline-secondary.box-shadow.text-break(href=this.model.open style="width: 100%" role="button")=this.model.name
div.col-md-4
diff --git a/client/templates/pages/errorTemplate.pug b/client/templates/pages/errorTemplate.pug
new file mode 100644
index 0000000000..2a66c42c7b
--- /dev/null
+++ b/client/templates/pages/errorTemplate.pug
@@ -0,0 +1,14 @@
+section.page
+
+ div#page-error.container.centered
+
+ div.logo(id="stochss-logo" data-hook="stochss-logo")
+ img(src="/hub/static/stochss-logo.png")
+
+ div.presentation-header
+
+ h1 404 PAGE NOT FOUND
+
+ div
+
+ h5="This " + this.fileType + " presentation was removed by the author and is no longer available."
\ No newline at end of file
diff --git a/client/templates/pages/workflowManager.pug b/client/templates/pages/workflowManager.pug
index ff45f09c82..55f517226a 100644
--- a/client/templates/pages/workflowManager.pug
+++ b/client/templates/pages/workflowManager.pug
@@ -36,9 +36,9 @@ section.page
div(data-hook="status-container")
- div.card.card-body(data-hook="jobs-container" style="display: none;")
+ div.card(data-hook="jobs-container" style="display: none;")
- div
+ div.card-header.pb-0
h3.inline Jobs
@@ -46,18 +46,18 @@ section.page
div.collapse.show(id="job-listing-container")
- hr
+ div.card-body
- div.row
+ div.row
- div.col-md-3: h6
Job
- div.col-md-4: h6
Start Time
- div.col-md-3: h6
Status
- div.col-md-2: h6
Remove
+ div.col-md-3: h6
Job
+ div.col-md-4: h6
Start Time
+ div.col-md-3: h6
Status
+ div.col-md-2: h6
Remove
- div.mb-3.head
+ div.mb-3.head
- div(data-hook="job-listing")
+ div(data-hook="job-listing")
div.mt-4(data-hook="active-job-header-container" style="display: none")
@@ -69,11 +69,11 @@ section.page
div(data-hook="settings-viewer-container")
- div.card
+ div#review-model-section.card(style="display: none;")
div.card-header
- h3.inline(id="model-viewer-header") "Review Model: "
+ h3.inline(id="model-viewer-header") Review Model:
button.btn.btn-outline-collapse(data-toggle="collapse" data-target="#collapse-model" data-hook="collapse-model") +
diff --git a/client/views/file-browser-view.js b/client/views/file-browser-view.js
index ab5ed5e92e..6c87c924a4 100644
--- a/client/views/file-browser-view.js
+++ b/client/views/file-browser-view.js
@@ -23,6 +23,8 @@ let _ = require('underscore');
//support files
let app = require('../app');
let modals = require('../modals');
+//models
+let Model = require('../models/model');
//views
let View = require('ampersand-view');
//templates
@@ -754,7 +756,23 @@ module.exports = View.extend({
});
},
newWorkflow: function (o, type) {
- app.newWorkflow(this, o.original._path, o.type === "spatial", type);
+ let model = new Model({
+ directory: o.original._path
+ });
+ app.getXHR(model.url(), {
+ success: function (err, response, body) {
+ model.set(body);
+ model.updateValid();
+ if(model.valid){
+ app.newWorkflow(this, o.original._path, o.type === "spatial", type);
+ }else{
+ let title = "Model Errors Detected";
+ let endpoint = path.join(app.getBasePath(), "stochss/models/edit") + '?path=' + model.directory;
+ let message = 'Errors were detected in you model
click here to fix your model';
+ $(modals.modelErrorHtml(title, message)).modal();
+ }
+ }
+ });
},
addModel: function (parentPath, modelName, message) {
var endpoint = path.join(app.getBasePath(), "stochss/models/edit")
@@ -948,13 +966,20 @@ module.exports = View.extend({
app.getXHR(endpoint, {
success: function (err, response, body) {
let title = body.message;
- let linkHeaders = "Shareable Presentation Link";
+ let linkHeaders = "Shareable Presentation";
let links = body.links;
- let name = o.original._path.split('/').pop().split('.ipynb')[0];
- $(modals.presentationLinks(title, name, linkHeaders, links)).modal();
+ $(modals.presentationLinks(title, linkHeaders, links)).modal();
let copyBtn = document.querySelector('#presentationLinksModal #copy-to-clipboard');
copyBtn.addEventListener('click', function (e) {
- app.copyToClipboard(links.presentation)
+ let onFulfilled = (value) => {
+ $("#copy-link-success").css("display", "inline-block");
+ }
+ let onReject = (reason) => {
+ let msg = $("#copy-link-failed");
+ msg.html(reason);
+ msg.css("display", "inline-block");
+ }
+ app.copyToClipboard(links.presentation, onFulfilled, onReject);
});
},
error: function (err, response, body) {
diff --git a/client/views/workflow-info.js b/client/views/job-info-view.js
similarity index 87%
rename from client/views/workflow-info.js
rename to client/views/job-info-view.js
index 526ddc3514..bb34049b6f 100644
--- a/client/views/workflow-info.js
+++ b/client/views/job-info-view.js
@@ -22,7 +22,7 @@ let app = require('../app');
//views
let View = require('ampersand-view');
//tempates
-let template = require('../templates/includes/workflowInfo.pug');
+let template = require('../templates/includes/jobInfoView.pug');
module.exports = View.extend({
template: template,
@@ -36,34 +36,34 @@ module.exports = View.extend({
this.listOfNotes = [];
let logs = attrs.logs.split("root - ");
if(logs.length > 1){
- logs.shift()
+ logs.shift();
}
logs.forEach(this.parseLogs, this);
},
render: function () {
View.prototype.render.apply(this, arguments);
if(this.parent.model.activeJob.status === "error") {
- $(this.queryByHook("workflow-info")).collapse("show");
+ $(this.queryByHook("job-info")).collapse("show");
$(this.queryByHook("collapse-info")).html("-");
}
- this.expandLogContainers()
+ this.expandLogContainers();
},
changeCollapseButtonText: function (e) {
app.changeCollapseButtonText(this, e);
},
expandLogContainers: function () {
if(this.listOfWarnings.length) {
- $(this.queryByHook('workflow-warnings')).collapse('show');
+ $(this.queryByHook('job-warnings')).collapse('show');
let listOfWarnings = "
" + this.listOfWarnings.join('
') + "
";
$(this.queryByHook('list-of-warnings')).html(listOfWarnings);
}
if(this.listOfErrors.length) {
- $(this.queryByHook('workflow-errors')).collapse('show');
+ $(this.queryByHook('job-errors')).collapse('show');
let listOfErrors = "
" + this.listOfErrors.join('
') + "
";
$(this.queryByHook('list-of-errors')).html(listOfErrors);
}
if(this.listOfNotes.length) {
- $(this.queryByHook('workflow-statistics')).collapse('show');
+ $(this.queryByHook('job-statistics')).collapse('show');
let listOfNotes = "
" + this.listOfNotes.join('
') + "
";
$(this.queryByHook('list-of-notes')).html(listOfNotes);
}
diff --git a/client/views/workflow-results.js b/client/views/job-results-view.js
similarity index 76%
rename from client/views/workflow-results.js
rename to client/views/job-results-view.js
index 95dc9fba28..9237900988 100644
--- a/client/views/workflow-results.js
+++ b/client/views/job-results-view.js
@@ -27,12 +27,12 @@ let Plotly = require('../lib/plotly');
let InputView = require('./input');
let View = require('ampersand-view');
let SelectView = require('ampersand-select-view');
-let SweepParametersView = require('./sweep-parameter-range');
+let SweepParametersView = require('./sweep-parameter-range-view');
//templates
-let gillespyResultsTemplate = require('../templates/includes/gillespyResults.pug');
-let gillespyResultsEnsembleTemplate = require('../templates/includes/gillespyResultsEnsemble.pug');
-let parameterSweepResultsTemplate = require('../templates/includes/parameterSweepResults.pug');
-let parameterScanTemplate = require('../templates/includes/parameterScanResults.pug');
+let gillespyResultsTemplate = require('../templates/includes/gillespyResultsView.pug');
+let gillespyResultsEnsembleTemplate = require('../templates/includes/gillespyResultsEnsembleView.pug');
+let parameterSweepResultsTemplate = require('../templates/includes/parameterSweepResultsView.pug');
+let parameterScanTemplate = require('../templates/includes/parameterScanResultsView.pug');
module.exports = View.extend({
events: {
@@ -55,10 +55,10 @@ module.exports = View.extend({
},
initialize: function (attrs, options) {
View.prototype.initialize.apply(this, arguments);
+ this.readOnly = Boolean(attrs.readOnly) ? attrs.readOnly : false;
this.tooltips = Tooltips.parameterSweepResults;
this.plots = {};
this.plotArgs = {};
- this.mode = Boolean(attrs.mode) ? attrs.mode : "edit";
},
render: function (attrs, options) {
let isEnsemble = this.model.settings.simulationSettings.realizations > 1 &&
@@ -70,7 +70,7 @@ module.exports = View.extend({
this.template = isEnsemble ? gillespyResultsEnsembleTemplate : gillespyResultsTemplate;
}
View.prototype.render.apply(this, arguments);
- if(this.mode === "presentation") {
+ if(this.readOnly) {
$(this.queryByHook("job-presentation")).css("display", "none");
if(!isParameterScan){
$(this.queryByHook("convert-to-notebook")).css("display", "none");
@@ -84,24 +84,20 @@ module.exports = View.extend({
var type = isEnsemble ? "stddevran" : "trajectories";
}else{
this.tsPlotData = {"parameters":{}};
+ this.fixedParameters = {};
var type = "ts-psweep";
- if(!isParameterScan) {
- this.renderSpeciesOfInterestView();
- this.renderFeatureExtractionView();
- if(isEnsemble) {
- this.renderEnsembleAggragatorView();
- }else{
- $(this.queryByHook('ensemble-aggragator-container')).css("display", "none");
- }
- this.getPlot("psweep");
- }
+ this.renderSpeciesOfInterestView();
+ this.renderFeatureExtractionView();
if(isEnsemble) {
+ this.renderEnsembleAggragatorView();
this.renderPlotTypeSelectView();
this.tsPlotData["type"] = "stddevran"
}else{
+ $(this.queryByHook('ensemble-aggragator-container')).css("display", "none");
$(this.queryByHook('plot-type-header')).css("display", "none");
this.tsPlotData["type"] = "trajectories"
}
+ this.getPlot("psweep");
this.renderSweepParameterView();
}
this.getPlot(type);
@@ -141,22 +137,20 @@ module.exports = View.extend({
let self = this;
this.cleanupPlotContainer(type);
let data = this.getPlotData(type);
- if(type === "psweep" && Boolean(this.plots[data.plt_key])) {
- this.plotFigure(this.plots[data.plt_key], type);
- }else if(type === "ts-psweep" && Boolean(this.plots[data.plt_type + data.plt_key])) {
- this.plotFigure(this.plots[data.plt_type + data.plt_key], type);
+ if(data === null) { return };
+ let storageKey = JSON.stringify(data);
+ data['plt_data'] = this.getPlotLayoutData();
+ if(Boolean(this.plots[storageKey])) {
+ let renderTypes = ['psweep', 'ts-psweep', 'ts-psweep-mp', 'mltplplt'];
+ if(renderTypes.includes(type)) {
+ this.plotFigure(this.plots[storageKey], type);
+ }
}else{
let queryStr = "?path=" + this.model.directory + "&data=" + JSON.stringify(data);
let endpoint = path.join(app.getApiPath(), "workflow/plot-results") + queryStr;
app.getXHR(endpoint, {
success: function (err, response, body) {
- if(type === "psweep") {
- self.plots[data.plt_key] = body;
- }else if(type === "ts-psweep"){
- self.plots[data.plt_type + data.plt_key] = body;
- }else{
- self.plots[type] = body;
- }
+ self.plots[storageKey] = body;
self.plotFigure(body, type);
},
error: function (err, response, body) {
@@ -170,28 +164,43 @@ module.exports = View.extend({
getPlotData: function (type) {
let data = {};
if(type === 'psweep'){
- let key = this.getPsweepKey();
- data['plt_key'] = key;
- }else if(type === "ts-psweep" || type === "ts-psweep-mp") {
- if(type === "ts-psweep-mp"){
- data['plt_type'] = "mltplplt";
- }else{
- data['plt_type'] = this.tsPlotData['type'];
+ data['sim_type'] = "ParameterSweep";
+ if(this.model.settings.parameterSweepSettings.parameters.length <= 2) {
+ data['data_keys'] = {}
+ }else {
+ let dataKeys = this.getDataKeys(false);
+ let paramDiff = this.model.settings.parameterSweepSettings.parameters.length - Object.keys(dataKeys).length
+ if(paramDiff <= 0) {
+ $(this.queryByHook(type + "-plot-spinner")).css("display", "none");
+ $(this.queryByHook("too-many-params")).css("display", "block");
+ return null;
+ }
+ if(paramDiff > 2) {
+ $(this.queryByHook(type + "-plot-spinner")).css("display", "none");
+ $(this.queryByHook("too-few-params")).css("display", "block");
+ return null;
+ }
+ $(this.queryByHook("too-few-params")).css("display", "none");
+ $(this.queryByHook("too-many-params")).css("display", "none");
+ data['data_keys'] = dataKeys;
}
- let key = this.getTSPsweepKey()
- data['plt_key'] = key;
- }else if(type === "mltplplt"){
- data['plt_type'] = type;
- data['plt_key'] = null;
- }else{
+ data['plt_key'] = this.getPlotKey(type);
+ }else if(type === "ts-psweep" || type === "ts-psweep-mp") {
+ data['sim_type'] = "GillesPy2_PS";
+ data['data_keys'] = this.getDataKeys(true);
+ data['plt_key'] = type === "ts-psweep-mp" ? "mltplplt" : this.tsPlotData.type;
+ }else {
+ data['sim_type'] = "GillesPy2";
+ data['data_keys'] = {};
data['plt_key'] = type;
}
+ return data
+ },
+ getPlotLayoutData: function () {
if(Object.keys(this.plotArgs).length){
- data['plt_data'] = this.plotArgs;
- }else{
- data['plt_data'] = null;
+ return this.plotArgs;
}
- return data
+ return null
},
getPlotForEnsembleAggragator: function (e) {
this.model.settings.resultsSettings.reducer = e.target.value;
@@ -208,38 +217,50 @@ module.exports = View.extend({
this.model.settings.parameterSweepSettings.speciesOfInterest = species;
this.getPlot('psweep')
},
- getPsweepKey: function () {
- let speciesOfInterest = this.model.settings.parameterSweepSettings.speciesOfInterest.name;
- let featureExtractor = this.model.settings.resultsSettings.mapper;
- let key = speciesOfInterest + "-" + featureExtractor
- let realizations = this.model.settings.simulationSettings.realizations;
- let algorithm = this.model.settings.simulationSettings.algorithm;
- if(algorithm !== "ODE" && realizations > 1){
- let ensembleAggragator = this.model.settings.resultsSettings.reducer;
- key += ("-" + ensembleAggragator);
+ getPlotKey: function (type) {
+ if(type === "psweep") {
+ let realizations = this.model.settings.simulationSettings.realizations;
+ let algorithm = this.model.settings.simulationSettings.algorithm;
+ let plt_key = {
+ species: this.model.settings.parameterSweepSettings.speciesOfInterest.name,
+ mapper: this.model.settings.resultsSettings.mapper,
+ reducer: algorithm !== "ODE" && realizations > 1 ? this.model.settings.resultsSettings.reducer : null
+ }
+ return plt_key;
}
- return key;
},
getTSPlotForType: function (e) {
- this.tsPlotData['type'] = e.target.value;
- let display = this.tsPlotData['type'] === "trajectories" ? "inline-block" : "none";
+ this.tsPlotData.type = e.target.value;
+ let display = this.tsPlotData.type === "trajectories" ? "inline-block" : "none";
$(this.queryByHook("multiple-plots")).css("display", display);
this.getPlot("ts-psweep");
},
- getTSPsweepKey: function () {
+ getDataKeys: function (full) {
+ if(full) { return this.tsPlotData.parameters; }
let self = this;
- let strs = Object.keys(this.tsPlotData.parameters).map(function (key) {
- return key + ":" + self.tsPlotData.parameters[key]
+ let parameters = {};
+ this.model.settings.parameterSweepSettings.parameters.forEach(function (param) {
+ if(param.fixed){
+ parameters[param.name] = self.fixedParameters[param.name];
+ }
});
- let key = strs.join(",");
- return key;
+ return parameters;
+ },
+ getType: function (storageKey) {
+ let plotData = JSON.parse(storageKey)
+ if(plotData.sim_type === "GillesPy2") { return plotData.plt_key }
+ if(plotData.sim_type === "GillesPy2_PS") { return "ts-psweep"}
+ return "psweep"
},
handleCollapsePlotContainerClick: function (e) {
app.changeCollapseButtonText(this, e);
let type = e.target.dataset.type;
- if(!this.plots[type]){
- this.getPlot(type);
+ if(['psweep', 'ts-psweep'].includes(type)) { return }
+ for (var storageKey in this.plots) {
+ let data = JSON.parse(storageKey)
+ if(data.plt_key === type) { return }
}
+ this.getPlot(type);
},
handleConvertToNotebookClick: function (e) {
let self = this;
@@ -260,7 +281,8 @@ module.exports = View.extend({
},
handleDownloadJSONClick: function (e) {
let type = e.target.dataset.type;
- let jsonData = this.plots[type];
+ let storageKey = JSON.stringify(this.getPlotData(type))
+ let jsonData = this.plots[storageKey];
let dataStr = JSON.stringify(jsonData);
let dataURI = 'data:application/json;charset=utf-8,' + encodeURIComponent(dataStr);
let exportFileDefaultName = type + '-plot.json';
@@ -391,32 +413,44 @@ module.exports = View.extend({
app.registerRenderSubview(this, speciesOfInterestView, "specie-of-interest-list");
},
renderSweepParameterView: function () {
- let sweepParameterView = this.renderCollection(
+ let tsSweepParameterView = this.renderCollection(
this.model.settings.parameterSweepSettings.parameters,
SweepParametersView,
- this.queryByHook("parameter-ranges")
+ this.queryByHook("ts-parameter-ranges")
);
+ if(this.model.settings.parameterSweepSettings.parameters.length > 2) {
+ let options = {viewOptions: {showFixed: true, parent: this}};
+ let psSweepParameterView = this.renderCollection(
+ this.model.settings.parameterSweepSettings.parameters,
+ SweepParametersView,
+ this.queryByHook("ps-parameter-ranges"),
+ options
+ );
+ }
},
setTitle: function (e) {
this.plotArgs['title'] = e.target.value
- for (var type in this.plots) {
- let fig = this.plots[type]
+ for (var storageKey in this.plots) {
+ let type = this.getType(storageKey);
+ let fig = this.plots[storageKey]
fig.layout.title.text = e.target.value
this.plotFigure(fig, type)
}
},
setXAxis: function (e) {
this.plotArgs['xaxis'] = e.target.value
- for (var type in this.plots) {
- let fig = this.plots[type]
+ for (var storageKey in this.plots) {
+ let type = this.getType(storageKey);
+ let fig = this.plots[storageKey]
fig.layout.xaxis.title.text = e.target.value
this.plotFigure(fig, type)
}
},
setYAxis: function (e) {
this.plotArgs['yaxis'] = e.target.value
- for (var type in this.plots) {
- let fig = this.plots[type]
+ for (var storageKey in this.plots) {
+ let type = this.getType(storageKey);
+ let fig = this.plots[storageKey]
fig.layout.yaxis.title.text = e.target.value
this.plotFigure(fig, type)
}
diff --git a/client/views/main.js b/client/views/main.js
index a62a9a4c2c..99e7633952 100644
--- a/client/views/main.js
+++ b/client/views/main.js
@@ -32,6 +32,12 @@ var ViewSwitcher = require('ampersand-view-switcher');
var headTemplate = require('!pug-loader!../templates/head.pug');
var bodyTemplate = require('!pug-loader!../templates/body.pug');
+String.prototype.toHtmlEntities = function() {
+ return this.replace(/./gm, function(s) {
+ return (s.match(/[a-z0-9\s]+/i)) ? s : "" + s.charCodeAt(0) + ";";
+ });
+};
+
let operationInfoModalHtml = (infoKey) => {
let fileBrowserInfo = `
In StochSS we use custom file extensions for a number of files we work with. Here is a list of our extentions with the files they are associated with:
@@ -153,11 +159,11 @@ module.exports = View.extend({
if(log.includes("$ ")){
let head = self.addNewLogBlock();
var newLog = self.formatLog(log);
- $("#user-logs").append(head + newLog);
+ $("#user-logs").append(head + newLog.toHtmlEntities());
}else{
var newLog = log;
if(newLog.trim()) {
- self.logBlock.push(newLog);
+ self.logBlock.push(newLog.toHtmlEntities());
}
}
self.logs.push(newLog);
diff --git a/client/views/model-state-buttons.js b/client/views/model-state-buttons.js
index 676604139b..9d3cabd028 100644
--- a/client/views/model-state-buttons.js
+++ b/client/views/model-state-buttons.js
@@ -308,13 +308,20 @@ module.exports = View.extend({
success: function (err, response, body) {
self.endAction("publish");
let title = body.message;
- let linkHeaders = "Shareable Presentation Link";
+ let linkHeaders = "Shareable Presentation";
let links = body.links;
- let name = self.model.name
- $(modals.presentationLinks(title, name, linkHeaders, links)).modal();
+ $(modals.presentationLinks(title, linkHeaders, links)).modal();
let copyBtn = document.querySelector('#presentationLinksModal #copy-to-clipboard');
copyBtn.addEventListener('click', function (e) {
- app.copyToClipboard(links.presentation)
+ let onFulfilled = (value) => {
+ $("#copy-link-success").css("display", "inline-block");
+ }
+ let onReject = (reason) => {
+ let msg = $("#copy-link-failed");
+ msg.html(reason);
+ msg.css("display", "inline-block");
+ }
+ app.copyToClipboard(links.presentation, onFulfilled, onReject);
});
},
error: function (err, response, body) {
diff --git a/client/views/parameter-settings.js b/client/views/parameter-settings-view.js
similarity index 55%
rename from client/views/parameter-settings.js
rename to client/views/parameter-settings-view.js
index dcaba4fce5..6bbc03e45e 100644
--- a/client/views/parameter-settings.js
+++ b/client/views/parameter-settings-view.js
@@ -24,10 +24,10 @@ let Tooltips = require('../tooltips');
let Model = require('../models/model');
//views
let View = require('ampersand-view');
-let ParameterView = require('./sweep-parameter');
let SelectView = require('ampersand-select-view');
+let ParameterView = require('./sweep-parameter-view');
//templates
-let template = require('../templates/includes/parameterSettings.pug');
+let template = require('../templates/includes/parameterSettingsView.pug');
module.exports = View.extend({
template: template,
@@ -38,17 +38,23 @@ module.exports = View.extend({
},
initialize: function (attrs, options) {
View.prototype.initialize.apply(this, arguments);
+ this.readOnly = attrs.readOnly ? attrs.readOnly : false;
this.tooltips = Tooltips.parameterSweepSettings;
- this.stochssModel = new Model({
- directory: attrs.modelDirectory
- });
- let self = this;
- app.getXHR(this.stochssModel.url(), {
- success: function (err, response, body) {
- self.stochssModel.set(body)
- self.renderSubviews();
- }
- });
+ if(this.readOnly) {
+ this.stochssModel = attrs.stochssModel;
+ this.renderSubviews();
+ }else{
+ this.stochssModel = new Model({
+ directory: attrs.modelDirectory
+ });
+ let self = this;
+ app.getXHR(this.stochssModel.url(), {
+ success: function (err, response, body) {
+ self.stochssModel.set(body);
+ self.renderSubviews();
+ }
+ });
+ }
},
changeCollapseButtonText: function (e) {
app.changeCollapseButtonText(this, e);
@@ -63,12 +69,17 @@ module.exports = View.extend({
handleAddParameterClick: function (e) {
let target = this.getParameter();
this.model.parameters.addSweepParameter(target.compID, target.name);
+ this.renderViewSweepParameters();
},
- renderParametersCollection: function () {
+ renderEditSweepParameters: function () {
+ if(this.editSweepParameters) {
+ this.editSweepParameters.remove();
+ }
let options = {"viewOptions": {
+ parent: this,
stochssParams: this.stochssModel.parameters
}}
- this.renderCollection(
+ this.editSweepParameters = this.renderCollection(
this.model.parameters,
ParameterView,
this.queryByHook("ps-parameter-collection"),
@@ -92,16 +103,47 @@ module.exports = View.extend({
app.registerRenderSubview(this, speciesOfInterestView, "variable-of-interest-list");
},
renderSubviews: function () {
- if(!Boolean(this.model.speciesOfInterest.name)) {
- this.model.speciesOfInterest = this.stochssModel.species.at(0);
+ if(!this.readOnly) {
+ if(!Boolean(this.model.speciesOfInterest.name)) {
+ this.model.speciesOfInterest = this.stochssModel.species.at(0);
+ }
+ this.model.updateVariables(this.stochssModel.parameters);
}
- this.model.updateVariables(this.stochssModel.parameters);
- this.model.parameters.on("add remove", function () {
- let disable = this.model.parameters.length >= 6 || this.model.parameters.length >= this.stochssModel.parameters.length
- $(this.queryByHook("add-ps-parameter")).prop("disabled", disable)
- }, this)
- this.renderSpeciesOfInterestView();
- this.renderParametersCollection();
+ View.prototype.render.apply(this, arguments);
+ if(this.readOnly) {
+ $(this.queryByHook('parameter-settings-edit-tab')).addClass("disabled");
+ $(".nav .disabled>a").on("click", function(e) {
+ e.preventDefault();
+ return false;
+ });
+ $(this.queryByHook('parameter-settings-view-tab')).tab('show');
+ $(this.queryByHook('edit-parameter-settings')).removeClass('active');
+ $(this.queryByHook('view-parameter-settings')).addClass('active');
+ }else{
+ this.model.parameters.on("add remove", function () {
+ let disable = this.model.parameters.length >= 6 || this.model.parameters.length >= this.stochssModel.parameters.length;
+ $(this.queryByHook("add-ps-parameter")).prop("disabled", disable);
+ }, this)
+ this.renderSpeciesOfInterestView();
+ this.renderEditSweepParameters();
+ }
+ this.renderViewSweepParameters();
+ },
+ renderViewSweepParameters: function () {
+ if(this.viewSweepParameters) {
+ this.viewSweepParameters.remove();
+ }
+ let options = {"viewOptions": {
+ parent: this,
+ stochssParams: this.stochssModel.parameters,
+ viewMode: true
+ }}
+ this.viewSweepParameters = this.renderCollection(
+ this.model.parameters,
+ ParameterView,
+ this.queryByHook("view-sweep-parameters"),
+ options
+ );
},
setVariableOfInterest: function (e) {
let target = e.target.value;
@@ -109,5 +151,6 @@ module.exports = View.extend({
return specie.compID === Number(target);
})[0];
this.model.speciesOfInterest = variable;
+ $("#view-species-of-interest").html(variable.name);
}
});
\ No newline at end of file
diff --git a/client/views/settings.js b/client/views/settings.js
index 4905e37461..36bfab5396 100644
--- a/client/views/settings.js
+++ b/client/views/settings.js
@@ -24,8 +24,8 @@ let app = require('../app');
//views
let View = require('ampersand-view');
let TimespanSettingsView = require('./timespan-settings');
-let SimulationSettingsView = require('./simulation-settings');
-let ParameterSettingsView = require('./parameter-settings');
+let ParameterSettingsView = require('./parameter-settings-view');
+let SimulationSettingsView = require('./simulation-settings-view');
//templates
let template = require('../templates/includes/settings.pug');
diff --git a/client/views/simulation-settings.js b/client/views/simulation-settings-view.js
similarity index 62%
rename from client/views/simulation-settings.js
rename to client/views/simulation-settings-view.js
index f6300beac2..8f0e0219fc 100644
--- a/client/views/simulation-settings.js
+++ b/client/views/simulation-settings-view.js
@@ -22,10 +22,10 @@ let app = require('../app');
let tests = require('./tests');
let Tooltips = require('../tooltips');
//views
-let View = require('ampersand-view');
let InputView = require('./input');
+let View = require('ampersand-view');
//templates
-let template = require('../templates/includes/simulationSettings.pug');
+let template = require('../templates/includes/simulationSettingsView.pug');
module.exports = View.extend({
template: template,
@@ -35,30 +35,44 @@ module.exports = View.extend({
'change [data-hook=select-tau-leaping]' : 'handleSelectSimulationAlgorithmClick',
'change [data-hook=select-hybrid-tau]' : 'handleSelectSimulationAlgorithmClick',
'change [data-hook=select-automatic]' : 'handleSelectSimulationAlgorithmClick',
+ 'change [data-hook=relative-tolerance]' : 'updateViewRTol',
+ 'change [data-hook=absolute-tolerance]' : 'updateViewATol',
+ 'change [data-hook=trajectories]' : 'updateViewTraj',
+ 'change [data-hook=seed]' : 'updateViewSeed',
+ 'change [data-hook=tau-tolerance]' : 'updateViewTauTol',
'click [data-hook=collapse]' : 'changeCollapseButtonText'
},
initialize: function (attrs, options) {
View.prototype.initialize.apply(this, arguments);
+ this.readOnly = attrs.readOnly ? attrs.readOnly : false;
this.tooltips = Tooltips.simulationSettings;
+ this.algorithm = this.model.isAutomatic ? "The algorithm was chosen based on your model." : this.model.algorithm;
},
render: function () {
View.prototype.render.apply(this, arguments);
- if(!this.model.isAutomatic){
- $(this.queryByHook('select-ode')).prop('checked', Boolean(this.model.algorithm === "ODE"));
- $(this.queryByHook('select-ssa')).prop('checked', Boolean(this.model.algorithm === "SSA"));
- $(this.queryByHook('select-tau-leaping')).prop('checked', Boolean(this.model.algorithm === "Tau-Leaping"));
- $(this.queryByHook('select-hybrid-tau')).prop('checked', Boolean(this.model.algorithm === "Hybrid-Tau-Leaping"));
- }else{
- $(this.queryByHook('settings-container')).collapse('hide');
- $(this.queryByHook('select-automatic')).prop('checked', this.model.isAutomatic);
- }
- this.disableInputFieldByAlgorithm();
- $(document).ready(function () {
- $('[data-toggle="tooltip"]').tooltip();
- $('[data-toggle="tooltip"]').click(function () {
- $('[data-toggle="tooltip"]').tooltip("hide");
+ if(this.readOnly) {
+ $(this.queryByHook('sim-settings-edit-tab')).addClass("disabled");
+ $(".nav .disabled>a").on("click", function(e) {
+ e.preventDefault();
+ return false;
});
- });
+ $(this.queryByHook('sim-settings-view-tab')).tab('show');
+ $(this.queryByHook('edit-sim-settings')).removeClass('active');
+ $(this.queryByHook('view-sim-settings')).addClass('active');
+ }else {
+ if(!this.model.isAutomatic){
+ $(this.queryByHook('select-ode')).prop('checked', Boolean(this.model.algorithm === "ODE"));
+ $(this.queryByHook('select-ssa')).prop('checked', Boolean(this.model.algorithm === "SSA"));
+ $(this.queryByHook('select-tau-leaping')).prop('checked', Boolean(this.model.algorithm === "Tau-Leaping"));
+ $(this.queryByHook('select-hybrid-tau')).prop('checked', Boolean(this.model.algorithm === "Hybrid-Tau-Leaping"));
+ }else{
+ $(this.queryByHook('settings-container')).collapse('hide');
+ $(this.queryByHook('select-automatic')).prop('checked', this.model.isAutomatic);
+ }
+ this.disableInputFieldByAlgorithm();
+ app.tooltipSetup();
+ }
+ this.updateViewer();
},
changeCollapseButtonText: function (e) {
app.changeCollapseButtonText(this, e);
@@ -78,9 +92,11 @@ module.exports = View.extend({
handleSelectSimulationAlgorithmClick: function (e) {
let value = e.target.dataset.name;
if(value === "Automatic"){
+ this.algorithm = "The algorithm was chosen based on your model.";
this.model.isAutomatic = true;
$(this.queryByHook('settings-container')).collapse('hide');
}else{
+ this.algorithm = value;
this.model.isAutomatic = false;
this.model.algorithm = value;
$(this.queryByHook('settings-container')).collapse('show');
@@ -91,9 +107,45 @@ module.exports = View.extend({
}
this.disableInputFieldByAlgorithm();
}
+ this.updateViewer();
},
update: function (e) {},
- updateValid: function () {},
+ updateViewATol: function (e) {
+ $(this.queryByHook("view-a-tol")).html(this.model.absoluteTol)
+ },
+ updateViewRTol: function (e) {
+ $(this.queryByHook("view-r-tol")).html(this.model.relativeTol)
+ },
+ updateViewSeed: function (e) {
+ $(this.queryByHook("view-seed")).html(this.model.seed)
+ },
+ updateViewTauTol: function (e) {
+ $(this.queryByHook("view-tau-tol")).html(this.model.tauTol)
+ },
+ updateViewTraj: function (e) {
+ $(this.queryByHook("view-realizations")).html(this.model.realizations)
+ },
+ updateValid: function (e) {},
+ updateViewer: function () {
+ $(this.queryByHook("view-algorithm")).html(this.algorithm);
+ let hideDeterministic = this.model.isAutomatic || this.model.algorithm === "SSA" || this.model.algorithm === "Tau-Leaping";
+ let hideStochastic = this.model.isAutomatic || this.model.algorithm === "ODE"
+ if(hideDeterministic) {
+ $(this.queryByHook("view-deterministic-settings")).css("display", "none");
+ }else{
+ $(this.queryByHook("view-deterministic-settings")).css("display", "block");
+ }
+ if(hideStochastic) {
+ $(this.queryByHook("view-stochastic-settings")).css("display", "none");
+ }else {
+ $(this.queryByHook("view-stochastic-settings")).css("display", "block");
+ if(this.model.algorithm === "SSA") {
+ $(this.queryByHook("view-tau-tolerance")).css("display", "none");
+ }else{
+ $(this.queryByHook("view-tau-tolerance")).css("display", "block");
+ }
+ }
+ },
subviews: {
inputRelativeTolerance: {
hook: 'relative-tolerance',
diff --git a/client/views/sweep-parameter-range.js b/client/views/sweep-parameter-range-view.js
similarity index 67%
rename from client/views/sweep-parameter-range.js
rename to client/views/sweep-parameter-range-view.js
index 00faa0a625..04cc1093ec 100644
--- a/client/views/sweep-parameter-range.js
+++ b/client/views/sweep-parameter-range-view.js
@@ -27,28 +27,44 @@ module.exports = View.extend({
events: function () {
let events = {};
events['change [data-hook=' + this.model.elementID + '-slider'] = 'setParameterRangeValue';
+ events['change [data-hook=' + this.model.elementID + '-fixed'] = 'setParameterRangeFixed';
events['input [data-hook=' + this.model.elementID + '-slider'] = 'viewParameterRangeValue';
return events;
},
initialize: function (attrs, options) {
View.prototype.initialize.apply(this, arguments);
let self = this;
- this.parameter = this.parent.model.model.parameters.filter(function (param) {
- return param.compID === self.model.paramID
- })[0];
+ this.model.fixed = false;
+ this.showFixed = Boolean(attrs.showFixed) ? attrs.showFixed : false;
let value = this.model.range[0].toString().includes('.') ? this.model.range[0] : this.model.range[0].toFixed(1)
this.parent.tsPlotData.parameters[this.model.name] = value;
+ this.parent.fixedParameters[this.model.name] = value;
},
render: function (attrs, options) {
View.prototype.render.apply(this, arguments);
+ if(!this.showFixed){
+ $(this.queryByHook(this.model.elementID + "-fixed-container")).css("display", "none");
+ }else{
+ $(this.queryByHook(this.model.elementID + '-slider')).prop("disabled", !this.model.fixed);
+ }
+ },
+ setParameterRangeFixed: function (e) {
+ this.model.fixed = e.target.checked;
+ $(this.queryByHook(this.model.elementID + '-slider')).prop("disabled", !this.model.fixed);
+ this.parent.getPlot("psweep");
},
setParameterRangeValue: function (e) {
var value = this.model.range[e.target.value];
if(!value.toString().includes(".")) {
value = value.toFixed(1)
}
- this.parent.tsPlotData.parameters[this.model.name] = value;
- this.parent.getPlot("ts-psweep");
+ if(this.showFixed) {
+ this.parent.fixedParameters[this.model.name] = value;
+ this.parent.getPlot("psweep");
+ }else{
+ this.parent.tsPlotData.parameters[this.model.name] = value;
+ this.parent.getPlot("ts-psweep");
+ }
},
viewParameterRangeValue: function (e) {
let value = this.model.range[e.target.value];
diff --git a/client/views/sweep-parameter.js b/client/views/sweep-parameter-view.js
similarity index 75%
rename from client/views/sweep-parameter.js
rename to client/views/sweep-parameter-view.js
index 1aebd9a482..8e1430dec1 100644
--- a/client/views/sweep-parameter.js
+++ b/client/views/sweep-parameter-view.js
@@ -17,42 +17,50 @@ along with this program. If not, see
.
*/
let $ = require('jquery');
+let _ = require('underscore');
//support files
let app = require('../app');
let tests = require('./tests');
//views
-let View = require('ampersand-view');
let InputView = require('./input');
+let View = require('ampersand-view');
let SelectView = require('ampersand-select-view');
//templates
-let template = require('../templates/includes/sweepParameter.pug');
+let editTemplate = require('../templates/includes/editSweepParameter.pug');
+let viewTemplate = require('../templates/includes/viewSweepParameter.pug');
module.exports = View.extend({
- template: template,
events: function () {
let events = {};
events['change [data-hook=' + this.model.elementID + '-sweep-target]'] = 'setSelectedTarget';
events['change [data-hook=' + this.model.elementID + '-target-min]'] = 'setHasChangedRange';
events['change [data-hook=' + this.model.elementID + '-target-max]'] = 'setHasChangedRange';
+ events['change [data-hook=' + this.model.elementID + '-target-steps]'] = 'updateViewer';
events['click [data-hook=' + this.model.elementID + '-remove'] = 'removeSweepParameter';
return events;
},
initialize: function (attrs, options) {
View.prototype.initialize.apply(this, arguments);
let self = this;
+ this.viewMode = attrs.viewMode ? attrs.viewMode : false;
this.parameters = attrs.stochssParams;
this.parameter = this.parameters.filter(function (param) {
return param.compID === self.model.paramID;
})[0];
- this.model.updateVariable(this.parameter);
+ if(!this.viewMode) {
+ this.model.updateVariable(this.parameter);
+ }
this.model.collection.on('add update-target remove', this.renderTargetSelectView, this);
},
render: function (attrs, options) {
+ this.template = this.viewMode ? viewTemplate : editTemplate;
View.prototype.render.apply(this, arguments);
- this.renderTargetSelectView();
- this.renderMinValInputView();
- this.renderMaxValInputView();
- this.renderStepsInputView();
+ if(!this.viewMode){
+ this.renderTargetSelectView();
+ this.renderMinValInputView();
+ this.renderMaxValInputView();
+ this.renderStepsInputView();
+ }
},
getAvailableParameters: function () {
let variableTargets = this.model.collection.map(function (variable) { return variable.paramID});
@@ -65,7 +73,7 @@ module.exports = View.extend({
return availableParameters;
},
removeSweepParameter: function () {
- this.model.collection.off('add update-target remove', this.renderTargetSelectView, this)
+ this.model.collection.off('add update-target remove', this.renderTargetSelectView, this);
this.model.collection.removeSweepParameter(this.model);
this.remove();
},
@@ -115,42 +123,39 @@ module.exports = View.extend({
app.registerRenderSubview(this, this.stepsInputView, this.model.elementID + "-target-steps");
},
renderTargetSelectView: function (e) {
- if(this.model.collection) {
- if(this.targetSelectView) {
- this.targetSelectView.remove();
- }
- let options = this.getAvailableParameters();
- this.targetSelectView = new SelectView({
- name: 'variable-target',
- required: true,
- idAttribute: 'cid',
- options: options,
- value: this.parameter.name
- });
- app.registerRenderSubview(this, this.targetSelectView, this.model.elementID + "-sweep-target");
+ if(this.vieWMode) { return }
+ if(this.targetSelectView) {
+ this.targetSelectView.remove();
}
+ let options = this.getAvailableParameters();
+ this.targetSelectView = new SelectView({
+ name: 'variable-target',
+ required: true,
+ idAttribute: 'cid',
+ options: options,
+ value: this.parameter.name
+ });
+ app.registerRenderSubview(this, this.targetSelectView, this.model.elementID + "-sweep-target");
},
setHasChangedRange: function () {
this.model.hasChangedRange = true;
+ this.updateViewer();
},
setSelectedTarget: function (e) {
let targetName = e.target.value;
this.parameter = this.parameters.filter(function (param) {
- return param.name === targetName
+ return param.name === targetName;
})[0];
this.model.paramID = this.parameter.compID;
this.model.name = this.parameter.name;
- this.model.hasChangedRange = false
- this.model.updateVariable(this.parameter)
- this.updateModelFields();
- this.model.collection.trigger('update-target');
+ this.model.hasChangedRange = false;
+ this.model.updateVariable(this.parameter);
+ this.parent.renderEditSweepParameters();
+ this.updateViewer();
},
update: function () {},
- updateModelFields: function () {
- $(this.queryByHook(this.model.elementID + "-target-value")).text(this.parameter.expression)
- this.renderMinValInputView();
- this.renderMaxValInputView();
- this.renderStepsInputView();
- },
- updateValid: function () {}
+ updateValid: function () {},
+ updateViewer: function () {
+ this.parent.renderViewSweepParameters();
+ }
});
diff --git a/client/views/workflow-group-listing.js b/client/views/workflow-group-listing.js
index c51e723eea..fc0227fce0 100644
--- a/client/views/workflow-group-listing.js
+++ b/client/views/workflow-group-listing.js
@@ -21,6 +21,8 @@ let path = require('path');
//support files
let app = require('../app');
let modals = require('../modals');
+//models
+let Model = require('../models/model');
//views
let View = require('ampersand-view');
let WorkflowListing = require("./workflow-listing");
@@ -53,10 +55,10 @@ module.exports = View.extend({
app.changeCollapseButtonText(this, e);
},
handleEnsembleSimulationClick: function (e) {
- app.newWorkflow(this, this.model.model.directory, this.model.model.is_spatial, "Ensemble Simulation")
+ this.newWorkflow("Ensemble Simulation")
},
handleParameterSweepClick: function (e) {
- app.newWorkflow(this, this.model.model.directory, this.model.model.is_spatial, "Parameter Sweep")
+ this.newWorkflow("Parameter Sweep")
},
handleTrashModelClick: function () {
if(document.querySelector('#moveToTrashConfirmModal')) {
@@ -79,6 +81,26 @@ module.exports = View.extend({
});
});
},
+ newWorkflow: function (type) {
+ let model = new Model({
+ directory: o.original._path
+ });
+ app.getXHR(model.url(), {
+ success: function (err, response, body) {
+ model.set(body);
+ model.updateValid();
+ if(model.valid){
+ app.newWorkflow(this, this.model.model.directory, this.model.model.is_spatial, type);
+ }else{
+ let title = "Model Errors Detected";
+ let endpoint = path.join(app.getBasePath(), "stochss/models/edit") + '?path=' + model.directory;
+ let message = 'Errors were detected in you model
click here to fix your model';
+ $(modals.modelErrorHtml(title, message)).modal();
+ }
+ }
+ });
+ app.newWorkflow(this, this.model.model.directory, this.model.model.is_spatial, type);
+ },
renderWorkflowCollection: function () {
if(this.workflowCollectionView){
this.workflowCollectionView.remove();
diff --git a/jupyterhub/presentation_base.py b/jupyterhub/presentation_base.py
index 421a9ed4b4..d78e22366a 100644
--- a/jupyterhub/presentation_base.py
+++ b/jupyterhub/presentation_base.py
@@ -19,21 +19,31 @@
import os
import tarfile
import tempfile
+import traceback
import docker
+from presentation_error import StochSSFileNotFoundError
+
def __get_presentation_from_volume(client, owner, file):
- volumes = client.volumes.list()
- user_volume = list(filter(lambda volume: volume.name == f"jupyterhub-user-{owner}",
- volumes))[0]
- volume_mnts = {user_volume.name: {"bind": "/user_volume", "mode": "ro"},
- "/stochss/jupyterhub": {"bind": "/mnt/cache", "mode": "rw"}}
- command = ['cp', os.path.join('/user_volume/.presentations', file),
- '/mnt/cache/presentation_cache/']
- client.containers.run('stochss-lab', command, volumes=volume_mnts)
- file_path = os.path.join('/srv/jupyterhub/presentation_cache', file)
- return file_path
+ try:
+ volumes = client.volumes.list()
+ user_volume = list(filter(lambda volume: volume.name == f"jupyterhub-user-{owner}",
+ volumes))[0]
+ volume_mnts = {user_volume.name: {"bind": "/user_volume", "mode": "ro"},
+ "/stochss/jupyterhub": {"bind": "/mnt/cache", "mode": "rw"}}
+ command = ['cp', os.path.join('/user_volume/.presentations', file),
+ '/mnt/cache/presentation_cache/']
+ client.containers.run('stochss-lab', command, volumes=volume_mnts)
+ file_path = os.path.join('/srv/jupyterhub/presentation_cache', file)
+ return file_path
+ except docker.errors.ContainerError as err:
+ message = "This presentation is no longer available."
+ raise StochSSFileNotFoundError(message, traceback.format_exc()) from err
+ except IndexError as err:
+ message = "This presentation is no longer available."
+ raise StochSSFileNotFoundError(message, traceback.format_exc()) from err
def get_presentation_from_user(owner, file, process_func, kwargs=None):
@@ -56,12 +66,15 @@ def get_presentation_from_user(owner, file, process_func, kwargs=None):
try:
user_container = list(filter(lambda container: container.name == f"jupyter-{owner}",
containers))[0]
- except IndexError:
- file_path = __get_presentation_from_volume(client, owner, file)
- else:
user_file_path = os.path.join('/home/jovyan/.presentations', file)
tar_pres = tempfile.TemporaryFile()
bits, _ = user_container.get_archive(user_file_path)
+ except IndexError:
+ file_path = __get_presentation_from_volume(client, owner, file)
+ except docker.errors.NotFound as err:
+ message = "This presentation is no longer available."
+ raise StochSSFileNotFoundError(message, traceback.format_exc()) from err
+ else:
for chunk in bits:
tar_pres.write(chunk)
tar_pres.seek(0)
diff --git a/public_models/Vilar_Oscillator/Vilar_Oscillator.ipynb b/public_models/Vilar_Oscillator/Vilar_Oscillator.ipynb
index a893cc22ff..b02db31463 100644
--- a/public_models/Vilar_Oscillator/Vilar_Oscillator.ipynb
+++ b/public_models/Vilar_Oscillator/Vilar_Oscillator.ipynb
@@ -1 +1,152 @@
-{"cells":[{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["import numpy as np\n","import gillespy2\n","from gillespy2 import Model, Species, Parameter, Reaction, Event, \\\n"," EventTrigger, EventAssignment, RateRule, \\\n"," AssignmentRule, FunctionDefinition\n","# from gillespy2 import SSACSolver\n","# from gillespy2 import TauLeapingCSolver\n","# from gillespy2 import ODECSolver\n","# from gillespy2 import TauHybridSolver"]},{"cell_type":"markdown","metadata":{},"source":["# Vilar_Oscillator"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["class VilarOscillator(Model):\n"," def __init__(self, parameter_values=None):\n"," Model.__init__(self, name=\"Vilar_Oscillator\")\n"," self.volume = 1\n","\n"," # Parameters\n"," self.add_parameter(Parameter(name=\"alpha_a\", expression=\"50\"))\n"," self.add_parameter(Parameter(name=\"alpha_a_prime\", expression=\"500\"))\n"," self.add_parameter(Parameter(name=\"alpha_r\", expression=\"0.01\"))\n"," self.add_parameter(Parameter(name=\"alpha_r_prime\", expression=\"50\"))\n"," self.add_parameter(Parameter(name=\"beta_a\", expression=\"50\"))\n"," self.add_parameter(Parameter(name=\"beta_r\", expression=\"5\"))\n"," self.add_parameter(Parameter(name=\"delta_ma\", expression=\"10\"))\n"," self.add_parameter(Parameter(name=\"delta_mr\", expression=\"0.5\"))\n"," self.add_parameter(Parameter(name=\"delta_a\", expression=\"1\"))\n"," self.add_parameter(Parameter(name=\"delta_r\", expression=\"0.2\"))\n"," self.add_parameter(Parameter(name=\"gamma_a\", expression=\"1\"))\n"," self.add_parameter(Parameter(name=\"gamma_r\", expression=\"1\"))\n"," self.add_parameter(Parameter(name=\"gamma_c\", expression=\"2\"))\n"," self.add_parameter(Parameter(name=\"theta_a\", expression=\"50\"))\n"," self.add_parameter(Parameter(name=\"theta_r\", expression=\"100\"))\n","\n"," # Variables\n"," self.add_species(Species(name=\"Da\", initial_value=1, mode=\"discrete\"))\n"," self.add_species(Species(name=\"Da_prime\", initial_value=0, mode=\"discrete\"))\n"," self.add_species(Species(name=\"Ma\", initial_value=0, mode=\"discrete\"))\n"," self.add_species(Species(name=\"Dr\", initial_value=1, mode=\"discrete\"))\n"," self.add_species(Species(name=\"Dr_prime\", initial_value=0, mode=\"discrete\"))\n"," self.add_species(Species(name=\"Mr\", initial_value=0, mode=\"discrete\"))\n"," self.add_species(Species(name=\"C\", initial_value=10, mode=\"discrete\"))\n"," self.add_species(Species(name=\"A\", initial_value=10, mode=\"discrete\"))\n"," self.add_species(Species(name=\"R\", initial_value=10, mode=\"discrete\"))\n","\n"," # Reactions\n"," self.add_reaction(Reaction(name=\"r1\", reactants={'Da_prime': 1}, products={'Da': 1}, rate=self.listOfParameters[\"theta_a\"]))\n"," self.add_reaction(Reaction(name=\"r2\", reactants={'Da': 1, 'A': 1}, products={'Da_prime': 1}, rate=self.listOfParameters[\"gamma_a\"]))\n"," self.add_reaction(Reaction(name=\"r3\", reactants={'Dr_prime': 1}, products={'Dr': 1}, rate=self.listOfParameters[\"theta_r\"]))\n"," self.add_reaction(Reaction(name=\"r4\", reactants={'Dr': 1, 'A': 1}, products={'Dr_prime': 1}, rate=self.listOfParameters[\"gamma_r\"]))\n"," self.add_reaction(Reaction(name=\"r5\", reactants={'Da_prime': 1}, products={'Da_prime': 1, 'Ma': 1}, rate=self.listOfParameters[\"alpha_a_prime\"]))\n"," self.add_reaction(Reaction(name=\"r6\", reactants={'Da': 1}, products={'Da': 1, 'Ma': 1}, rate=self.listOfParameters[\"alpha_a\"]))\n"," self.add_reaction(Reaction(name=\"r7\", reactants={'Ma': 1}, products={}, rate=self.listOfParameters[\"delta_ma\"]))\n"," self.add_reaction(Reaction(name=\"r8\", reactants={'Ma': 1}, products={'A': 1, 'Ma': 1}, rate=self.listOfParameters[\"beta_a\"]))\n"," self.add_reaction(Reaction(name=\"r9\", reactants={'Da_prime': 1}, products={'Da_prime': 1, 'A': 1}, rate=self.listOfParameters[\"theta_a\"]))\n"," self.add_reaction(Reaction(name=\"r10\", reactants={'Dr_prime': 1}, products={'Dr_prime': 1, 'A': 1}, rate=self.listOfParameters[\"theta_a\"]))\n"," self.add_reaction(Reaction(name=\"r11\", reactants={'A': 1}, products={}, rate=self.listOfParameters[\"gamma_c\"]))\n"," self.add_reaction(Reaction(name=\"r12\", reactants={'A': 1, 'R': 1}, products={'C': 1}, rate=self.listOfParameters[\"gamma_c\"]))\n"," self.add_reaction(Reaction(name=\"r13\", reactants={'Dr_prime': 1}, products={'Dr_prime': 1, 'Mr': 1}, rate=self.listOfParameters[\"alpha_r_prime\"]))\n"," self.add_reaction(Reaction(name=\"r14\", reactants={'Dr': 1}, products={'Dr': 1, 'Mr': 1}, rate=self.listOfParameters[\"alpha_r\"]))\n"," self.add_reaction(Reaction(name=\"r15\", reactants={'Mr': 1}, products={}, rate=self.listOfParameters[\"delta_mr\"]))\n"," self.add_reaction(Reaction(name=\"r16\", reactants={'Mr': 1}, products={'Mr': 1, 'R': 1}, rate=self.listOfParameters[\"beta_r\"]))\n"," self.add_reaction(Reaction(name=\"r17\", reactants={'R': 1}, products={}, rate=self.listOfParameters[\"delta_r\"]))\n"," self.add_reaction(Reaction(name=\"r18\", reactants={'C': 1}, products={'R': 1}, rate=self.listOfParameters[\"delta_a\"]))\n","\n"," # Timespan\n"," self.timespan(np.arange(0, 200, 1))"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["model = VilarOscillator()"]},{"cell_type":"markdown","metadata":{},"source":["# Simulation Parameters"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["def configure_simulation():\n"," # solver = SSACSolver(model=model)\n"," kwargs = {\n"," # \"solver\":solver,\n"," \"number_of_trajectories\":100,\n"," # \"seed\":None,\n"," # \"tau_tol\":0.03,\n"," # \"integrator_options\":{'rtol': 0.001, 'atol': 1e-06},\n"," }\n"," return kwargs"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["kwargs = configure_simulation()\n","results = model.run(**kwargs)"]},{"cell_type":"markdown","metadata":{},"source":["# Visualization"]},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":["results.plotplotly()"]}],"metadata":{},"nbformat":4,"nbformat_minor":4}
\ No newline at end of file
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import numpy as np\n",
+ "import gillespy2\n",
+ "from gillespy2 import Model, Species, Parameter, Reaction, Event, \\\n",
+ " EventTrigger, EventAssignment, RateRule, \\\n",
+ " AssignmentRule, FunctionDefinition\n",
+ "# from gillespy2 import SSACSolver\n",
+ "# from gillespy2 import TauLeapingCSolver\n",
+ "# from gillespy2 import ODECSolver\n",
+ "# from gillespy2 import TauHybridSolver"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Vilar_Oscillator"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class VilarOscillator(Model):\n",
+ " def __init__(self, parameter_values=None):\n",
+ " Model.__init__(self, name=\"Vilar_Oscillator\")\n",
+ " self.volume = 1\n",
+ "\n",
+ " # Parameters\n",
+ " self.add_parameter(Parameter(name=\"alphaA\", expression=\"50\"))\n",
+ " self.add_parameter(Parameter(name=\"alphaA_prime\", expression=\"500\"))\n",
+ " self.add_parameter(Parameter(name=\"alphaR\", expression=\"0.01\"))\n",
+ " self.add_parameter(Parameter(name=\"alphaR_prime\", expression=\"50\"))\n",
+ " self.add_parameter(Parameter(name=\"betaA\", expression=\"50\"))\n",
+ " self.add_parameter(Parameter(name=\"betaR\", expression=\"5\"))\n",
+ " self.add_parameter(Parameter(name=\"deltaMA\", expression=\"10\"))\n",
+ " self.add_parameter(Parameter(name=\"deltaMR\", expression=\"0.5\"))\n",
+ " self.add_parameter(Parameter(name=\"deltaA\", expression=\"1\"))\n",
+ " self.add_parameter(Parameter(name=\"deltaR\", expression=\"0.2\"))\n",
+ " self.add_parameter(Parameter(name=\"gammaA\", expression=\"1\"))\n",
+ " self.add_parameter(Parameter(name=\"gammaR\", expression=\"1\"))\n",
+ " self.add_parameter(Parameter(name=\"gammaC\", expression=\"2\"))\n",
+ " self.add_parameter(Parameter(name=\"thetaA\", expression=\"50\"))\n",
+ " self.add_parameter(Parameter(name=\"thetaR\", expression=\"100\"))\n",
+ "\n",
+ " # Variables\n",
+ " self.add_species(Species(name=\"Da\", initial_value=1, mode=\"discrete\"))\n",
+ " self.add_species(Species(name=\"Da_prime\", initial_value=0, mode=\"discrete\"))\n",
+ " self.add_species(Species(name=\"Ma\", initial_value=0, mode=\"discrete\"))\n",
+ " self.add_species(Species(name=\"Dr\", initial_value=1, mode=\"discrete\"))\n",
+ " self.add_species(Species(name=\"Dr_prime\", initial_value=0, mode=\"discrete\"))\n",
+ " self.add_species(Species(name=\"Mr\", initial_value=0, mode=\"discrete\"))\n",
+ " self.add_species(Species(name=\"C\", initial_value=0, mode=\"discrete\"))\n",
+ " self.add_species(Species(name=\"A\", initial_value=0, mode=\"discrete\"))\n",
+ " self.add_species(Species(name=\"R\", initial_value=0, mode=\"discrete\"))\n",
+ "\n",
+ " # Reactions\n",
+ " self.add_reaction(Reaction(name=\"r1\", reactants={'A': 1, 'R': 1}, products={'C': 1}, rate=\"gammaC\"))\n",
+ " self.add_reaction(Reaction(name=\"r2\", reactants={'A': 1}, products={}, rate=\"deltaA\"))\n",
+ " self.add_reaction(Reaction(name=\"r3\", reactants={'C': 1}, products={'R': 1}, rate=\"deltaA\"))\n",
+ " self.add_reaction(Reaction(name=\"r4\", reactants={'R': 1}, products={}, rate=\"deltaR\"))\n",
+ " self.add_reaction(Reaction(name=\"r5\", reactants={'A': 1, 'Da': 1}, products={'Da_prime': 1}, rate=\"gammaA\"))\n",
+ " self.add_reaction(Reaction(name=\"r6\", reactants={'Da_prime': 1}, products={'A': 1, 'Da': 1}, rate=\"thetaA\"))\n",
+ " self.add_reaction(Reaction(name=\"r7\", reactants={'Da': 1}, products={'Da': 1, 'Ma': 1}, rate=\"alphaA\"))\n",
+ " self.add_reaction(Reaction(name=\"r8\", reactants={'Da_prime': 1}, products={'Da_prime': 1, 'Ma': 1}, rate=\"alphaA_prime\"))\n",
+ " self.add_reaction(Reaction(name=\"r9\", reactants={'Ma': 1}, products={}, rate=\"deltaMA\"))\n",
+ " self.add_reaction(Reaction(name=\"r10\", reactants={'Ma': 1}, products={'A': 1, 'Ma': 1}, rate=\"betaA\"))\n",
+ " self.add_reaction(Reaction(name=\"r11\", reactants={'A': 1, 'Dr': 1}, products={'Dr_prime': 1}, rate=\"gammaR\"))\n",
+ " self.add_reaction(Reaction(name=\"r12\", reactants={'Dr_prime': 1}, products={'A': 1, 'Dr': 1}, rate=\"thetaR\"))\n",
+ " self.add_reaction(Reaction(name=\"r13\", reactants={'Dr': 1}, products={'Dr': 1, 'Mr': 1}, rate=\"alphaR\"))\n",
+ " self.add_reaction(Reaction(name=\"r14\", reactants={'Dr_prime': 1}, products={'Dr_prime': 1, 'Mr': 1}, rate=\"alphaR_prime\"))\n",
+ " self.add_reaction(Reaction(name=\"r15\", reactants={'Mr': 1}, products={}, rate=\"deltaMR\"))\n",
+ " self.add_reaction(Reaction(name=\"r16\", reactants={'Mr': 1}, products={'Mr': 1, 'R': 1}, rate=\"betaR\"))\n",
+ "\n",
+ " # Timespan\n",
+ " self.timespan(np.arange(0, 201, 1))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "model = VilarOscillator()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Simulation Parameters"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def configure_simulation():\n",
+ " # solver = SSACSolver(model=model)\n",
+ " kwargs = {\n",
+ " # \"solver\":solver,\n",
+ " \"number_of_trajectories\":100,\n",
+ " # \"seed\":None,\n",
+ " # \"tau_tol\":0.03,\n",
+ " # \"integrator_options\":{'rtol': 0.001, 'atol': 1e-06},\n",
+ " }\n",
+ " return kwargs"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "kwargs = configure_simulation()\n",
+ "results = model.run(**kwargs)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Visualization"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "results.plotplotly()"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/public_models/Vilar_Oscillator/Vilar_Oscillator.mdl b/public_models/Vilar_Oscillator/Vilar_Oscillator.mdl
index 2a79884e34..969351fc34 100644
--- a/public_models/Vilar_Oscillator/Vilar_Oscillator.mdl
+++ b/public_models/Vilar_Oscillator/Vilar_Oscillator.mdl
@@ -1,1432 +1 @@
-{
- "is_spatial": false,
- "defaultID": 43,
- "defaultMode": "discrete",
- "modelSettings": {
- "endSim": 200,
- "timeStep": 1,
- "volume": 1
- },
- "meshSettings": {
- "count": 2
- },
- "species": [
- {
- "compID": 1,
- "name": "Da",
- "value": 1,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- },
- {
- "compID": 2,
- "name": "Da_prime",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- },
- {
- "compID": 3,
- "name": "Ma",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- },
- {
- "compID": 4,
- "name": "Dr",
- "value": 1,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- },
- {
- "compID": 5,
- "name": "Dr_prime",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- },
- {
- "compID": 6,
- "name": "Mr",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- },
- {
- "compID": 7,
- "name": "C",
- "value": 10,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- },
- {
- "compID": 8,
- "name": "A",
- "value": 10,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- },
- {
- "compID": 9,
- "name": "R",
- "value": 10,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- ],
- "initialConditions": [],
- "parameters": [
- {
- "compID": 10,
- "name": "alpha_a",
- "expression": "50",
- "annotation": ""
- },
- {
- "compID": 11,
- "name": "alpha_a_prime",
- "expression": "500",
- "annotation": ""
- },
- {
- "compID": 12,
- "name": "alpha_r",
- "expression": "0.01",
- "annotation": ""
- },
- {
- "compID": 13,
- "name": "alpha_r_prime",
- "expression": "50",
- "annotation": ""
- },
- {
- "compID": 14,
- "name": "beta_a",
- "expression": "50",
- "annotation": ""
- },
- {
- "compID": 15,
- "name": "beta_r",
- "expression": "5",
- "annotation": ""
- },
- {
- "compID": 16,
- "name": "delta_ma",
- "expression": "10",
- "annotation": ""
- },
- {
- "compID": 17,
- "name": "delta_mr",
- "expression": "0.5",
- "annotation": ""
- },
- {
- "compID": 18,
- "name": "delta_a",
- "expression": "1",
- "annotation": ""
- },
- {
- "compID": 19,
- "name": "delta_r",
- "expression": "0.2",
- "annotation": ""
- },
- {
- "compID": 20,
- "name": "gamma_a",
- "expression": "1",
- "annotation": ""
- },
- {
- "compID": 21,
- "name": "gamma_r",
- "expression": "1",
- "annotation": ""
- },
- {
- "compID": 22,
- "name": "gamma_c",
- "expression": "2",
- "annotation": ""
- },
- {
- "compID": 23,
- "name": "theta_a",
- "expression": "50",
- "annotation": ""
- },
- {
- "compID": 24,
- "name": "theta_r",
- "expression": "100",
- "annotation": ""
- }
- ],
- "reactions": [
- {
- "compID": 25,
- "name": "r1",
- "reactionType": "change",
- "summary": "Da\\_prime \\rightarrow Da",
- "massaction": false,
- "propensity": "",
- "annotation": "",
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ],
- "rate": {
- "compID": 23,
- "name": "theta_a",
- "expression": "50",
- "annotation": ""
- },
- "reactants": [
- {
- "ratio": 1,
- "specie": {
- "compID": 2,
- "name": "Da_prime",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ],
- "products": [
- {
- "ratio": 1,
- "specie": {
- "compID": 1,
- "name": "Da",
- "value": 1,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ]
- },
- {
- "compID": 26,
- "name": "r2",
- "reactionType": "merge",
- "summary": "Da+A \\rightarrow Da\\_prime",
- "massaction": false,
- "propensity": "",
- "annotation": "",
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ],
- "rate": {
- "compID": 20,
- "name": "gamma_a",
- "expression": "1",
- "annotation": ""
- },
- "reactants": [
- {
- "ratio": 1,
- "specie": {
- "compID": 1,
- "name": "Da",
- "value": 1,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- },
- {
- "ratio": 1,
- "specie": {
- "compID": 8,
- "name": "A",
- "value": 10,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ],
- "products": [
- {
- "ratio": 1,
- "specie": {
- "compID": 2,
- "name": "Da_prime",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ]
- },
- {
- "compID": 27,
- "name": "r3",
- "reactionType": "change",
- "summary": "Dr\\_prime \\rightarrow Dr",
- "massaction": false,
- "propensity": "",
- "annotation": "",
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ],
- "rate": {
- "compID": 24,
- "name": "theta_r",
- "expression": "100",
- "annotation": ""
- },
- "reactants": [
- {
- "ratio": 1,
- "specie": {
- "compID": 5,
- "name": "Dr_prime",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ],
- "products": [
- {
- "ratio": 1,
- "specie": {
- "compID": 4,
- "name": "Dr",
- "value": 1,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ]
- },
- {
- "compID": 28,
- "name": "r4",
- "reactionType": "merge",
- "summary": "Dr+A \\rightarrow Dr\\_prime",
- "massaction": false,
- "propensity": "",
- "annotation": "",
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ],
- "rate": {
- "compID": 21,
- "name": "gamma_r",
- "expression": "1",
- "annotation": ""
- },
- "reactants": [
- {
- "ratio": 1,
- "specie": {
- "compID": 4,
- "name": "Dr",
- "value": 1,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- },
- {
- "ratio": 1,
- "specie": {
- "compID": 8,
- "name": "A",
- "value": 10,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ],
- "products": [
- {
- "ratio": 1,
- "specie": {
- "compID": 5,
- "name": "Dr_prime",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ]
- },
- {
- "compID": 29,
- "name": "r5",
- "reactionType": "split",
- "summary": "Da\\_prime \\rightarrow Da\\_prime+Ma",
- "massaction": false,
- "propensity": "",
- "annotation": "",
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ],
- "rate": {
- "compID": 11,
- "name": "alpha_a_prime",
- "expression": "500",
- "annotation": ""
- },
- "reactants": [
- {
- "ratio": 1,
- "specie": {
- "compID": 2,
- "name": "Da_prime",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ],
- "products": [
- {
- "ratio": 1,
- "specie": {
- "compID": 2,
- "name": "Da_prime",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- },
- {
- "ratio": 1,
- "specie": {
- "compID": 3,
- "name": "Ma",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ]
- },
- {
- "compID": 30,
- "name": "r6",
- "reactionType": "split",
- "summary": "Da \\rightarrow Da+Ma",
- "massaction": false,
- "propensity": "",
- "annotation": "",
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ],
- "rate": {
- "compID": 10,
- "name": "alpha_a",
- "expression": "50",
- "annotation": ""
- },
- "reactants": [
- {
- "ratio": 1,
- "specie": {
- "compID": 1,
- "name": "Da",
- "value": 1,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ],
- "products": [
- {
- "ratio": 1,
- "specie": {
- "compID": 1,
- "name": "Da",
- "value": 1,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- },
- {
- "ratio": 1,
- "specie": {
- "compID": 3,
- "name": "Ma",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ]
- },
- {
- "compID": 31,
- "name": "r7",
- "reactionType": "destruction",
- "summary": "Ma \\rightarrow \\emptyset",
- "massaction": false,
- "propensity": "",
- "annotation": "",
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ],
- "rate": {
- "compID": 16,
- "name": "delta_ma",
- "expression": "10",
- "annotation": ""
- },
- "reactants": [
- {
- "ratio": 1,
- "specie": {
- "compID": 3,
- "name": "Ma",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ],
- "products": []
- },
- {
- "compID": 32,
- "name": "r8",
- "reactionType": "split",
- "summary": "Ma \\rightarrow A+Ma",
- "massaction": false,
- "propensity": "",
- "annotation": "",
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ],
- "rate": {
- "compID": 14,
- "name": "beta_a",
- "expression": "50",
- "annotation": ""
- },
- "reactants": [
- {
- "ratio": 1,
- "specie": {
- "compID": 3,
- "name": "Ma",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ],
- "products": [
- {
- "ratio": 1,
- "specie": {
- "compID": 8,
- "name": "A",
- "value": 10,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- },
- {
- "ratio": 1,
- "specie": {
- "compID": 3,
- "name": "Ma",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ]
- },
- {
- "compID": 33,
- "name": "r9",
- "reactionType": "split",
- "summary": "Da\\_prime \\rightarrow Da\\_prime+A",
- "massaction": false,
- "propensity": "",
- "annotation": "",
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ],
- "rate": {
- "compID": 23,
- "name": "theta_a",
- "expression": "50",
- "annotation": ""
- },
- "reactants": [
- {
- "ratio": 1,
- "specie": {
- "compID": 2,
- "name": "Da_prime",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ],
- "products": [
- {
- "ratio": 1,
- "specie": {
- "compID": 2,
- "name": "Da_prime",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- },
- {
- "ratio": 1,
- "specie": {
- "compID": 8,
- "name": "A",
- "value": 10,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ]
- },
- {
- "compID": 34,
- "name": "r10",
- "reactionType": "split",
- "summary": "Dr\\_prime \\rightarrow Dr\\_prime+A",
- "massaction": false,
- "propensity": "",
- "annotation": "",
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ],
- "rate": {
- "compID": 23,
- "name": "theta_a",
- "expression": "50",
- "annotation": ""
- },
- "reactants": [
- {
- "ratio": 1,
- "specie": {
- "compID": 5,
- "name": "Dr_prime",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ],
- "products": [
- {
- "ratio": 1,
- "specie": {
- "compID": 5,
- "name": "Dr_prime",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- },
- {
- "ratio": 1,
- "specie": {
- "compID": 8,
- "name": "A",
- "value": 10,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ]
- },
- {
- "compID": 35,
- "name": "r11",
- "reactionType": "destruction",
- "summary": "A \\rightarrow \\emptyset",
- "massaction": false,
- "propensity": "",
- "annotation": "",
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ],
- "rate": {
- "compID": 22,
- "name": "gamma_c",
- "expression": "2",
- "annotation": ""
- },
- "reactants": [
- {
- "ratio": 1,
- "specie": {
- "compID": 8,
- "name": "A",
- "value": 10,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ],
- "products": []
- },
- {
- "compID": 36,
- "name": "r12",
- "reactionType": "merge",
- "summary": "A+R \\rightarrow C",
- "massaction": false,
- "propensity": "",
- "annotation": "",
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ],
- "rate": {
- "compID": 22,
- "name": "gamma_c",
- "expression": "2",
- "annotation": ""
- },
- "reactants": [
- {
- "ratio": 1,
- "specie": {
- "compID": 8,
- "name": "A",
- "value": 10,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- },
- {
- "ratio": 1,
- "specie": {
- "compID": 9,
- "name": "R",
- "value": 10,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ],
- "products": [
- {
- "ratio": 1,
- "specie": {
- "compID": 7,
- "name": "C",
- "value": 10,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ]
- },
- {
- "compID": 37,
- "name": "r13",
- "reactionType": "split",
- "summary": "Dr\\_prime \\rightarrow Dr\\_prime+Mr",
- "massaction": false,
- "propensity": "",
- "annotation": "",
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ],
- "rate": {
- "compID": 13,
- "name": "alpha_r_prime",
- "expression": "50",
- "annotation": ""
- },
- "reactants": [
- {
- "ratio": 1,
- "specie": {
- "compID": 5,
- "name": "Dr_prime",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ],
- "products": [
- {
- "ratio": 1,
- "specie": {
- "compID": 5,
- "name": "Dr_prime",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- },
- {
- "ratio": 1,
- "specie": {
- "compID": 6,
- "name": "Mr",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ]
- },
- {
- "compID": 38,
- "name": "r14",
- "reactionType": "split",
- "summary": "Dr \\rightarrow Dr+Mr",
- "massaction": false,
- "propensity": "",
- "annotation": "",
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ],
- "rate": {
- "compID": 12,
- "name": "alpha_r",
- "expression": "0.01",
- "annotation": ""
- },
- "reactants": [
- {
- "ratio": 1,
- "specie": {
- "compID": 4,
- "name": "Dr",
- "value": 1,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ],
- "products": [
- {
- "ratio": 1,
- "specie": {
- "compID": 4,
- "name": "Dr",
- "value": 1,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- },
- {
- "ratio": 1,
- "specie": {
- "compID": 6,
- "name": "Mr",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ]
- },
- {
- "compID": 39,
- "name": "r15",
- "reactionType": "destruction",
- "summary": "Mr \\rightarrow \\emptyset",
- "massaction": false,
- "propensity": "",
- "annotation": "",
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ],
- "rate": {
- "compID": 17,
- "name": "delta_mr",
- "expression": "0.5",
- "annotation": ""
- },
- "reactants": [
- {
- "ratio": 1,
- "specie": {
- "compID": 6,
- "name": "Mr",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ],
- "products": []
- },
- {
- "compID": 40,
- "name": "r16",
- "reactionType": "split",
- "summary": "Mr \\rightarrow Mr+R",
- "massaction": false,
- "propensity": "",
- "annotation": "",
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ],
- "rate": {
- "compID": 15,
- "name": "beta_r",
- "expression": "5",
- "annotation": ""
- },
- "reactants": [
- {
- "ratio": 1,
- "specie": {
- "compID": 6,
- "name": "Mr",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ],
- "products": [
- {
- "ratio": 1,
- "specie": {
- "compID": 6,
- "name": "Mr",
- "value": 0,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- },
- {
- "ratio": 1,
- "specie": {
- "compID": 9,
- "name": "R",
- "value": 10,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ]
- },
- {
- "compID": 41,
- "name": "r17",
- "reactionType": "destruction",
- "summary": "R \\rightarrow \\emptyset",
- "massaction": false,
- "propensity": "",
- "annotation": "",
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ],
- "rate": {
- "compID": 19,
- "name": "delta_r",
- "expression": "0.2",
- "annotation": ""
- },
- "reactants": [
- {
- "ratio": 1,
- "specie": {
- "compID": 9,
- "name": "R",
- "value": 10,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ],
- "products": []
- },
- {
- "compID": 42,
- "name": "r18",
- "reactionType": "change",
- "summary": "C \\rightarrow R",
- "massaction": false,
- "propensity": "",
- "annotation": "",
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ],
- "rate": {
- "compID": 18,
- "name": "delta_a",
- "expression": "1",
- "annotation": ""
- },
- "reactants": [
- {
- "ratio": 1,
- "specie": {
- "compID": 7,
- "name": "C",
- "value": 10,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ],
- "products": [
- {
- "ratio": 1,
- "specie": {
- "compID": 9,
- "name": "R",
- "value": 10,
- "mode": "discrete",
- "switchTol": 0.03,
- "switchMin": 100,
- "isSwitchTol": true,
- "annotation": "",
- "diffusionCoeff": 0,
- "subdomains": [
- "subdomain 1: ",
- "subdomain 2: "
- ]
- }
- }
- ]
- }
- ],
- "rules": [],
- "eventsCollection": [],
- "functionDefinitions": []
-}
\ No newline at end of file
+{"is_spatial":false,"defaultID":61,"defaultMode":"discrete","annotation":"","volume":1,"modelSettings":{"endSim":200,"timeStep":1},"domain":{"types":[],"particles":[]},"species":[{"compID":1,"name":"Da","value":1,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""},{"compID":2,"name":"Da_prime","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""},{"compID":3,"name":"Ma","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""},{"compID":4,"name":"Dr","value":1,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""},{"compID":5,"name":"Dr_prime","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""},{"compID":6,"name":"Mr","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""},{"compID":7,"name":"C","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""},{"compID":8,"name":"A","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""},{"compID":9,"name":"R","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}],"initialConditions":[],"parameters":[{"compID":10,"name":"alphaA","expression":50,"annotation":""},{"compID":11,"name":"alphaA_prime","expression":500,"annotation":""},{"compID":12,"name":"alphaR","expression":0.01,"annotation":""},{"compID":13,"name":"alphaR_prime","expression":50,"annotation":""},{"compID":14,"name":"betaA","expression":50,"annotation":""},{"compID":15,"name":"betaR","expression":5,"annotation":""},{"compID":16,"name":"deltaMA","expression":10,"annotation":""},{"compID":17,"name":"deltaMR","expression":0.5,"annotation":""},{"compID":18,"name":"deltaA","expression":1,"annotation":""},{"compID":19,"name":"deltaR","expression":0.2,"annotation":""},{"compID":20,"name":"gammaA","expression":1,"annotation":""},{"compID":21,"name":"gammaR","expression":1,"annotation":""},{"compID":22,"name":"gammaC","expression":2,"annotation":""},{"compID":23,"name":"thetaA","expression":50,"annotation":""},{"compID":24,"name":"thetaR","expression":100,"annotation":""}],"reactions":[{"compID":45,"name":"r1","reactionType":"merge","summary":"A+R \\rightarrow C","massaction":false,"propensity":"","annotation":"","types":[],"rate":{"compID":22,"name":"gammaC","expression":2,"annotation":""},"reactants":[{"ratio":1,"specie":{"compID":8,"name":"A","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}},{"ratio":1,"specie":{"compID":9,"name":"R","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}],"products":[{"ratio":1,"specie":{"compID":7,"name":"C","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}]},{"compID":46,"name":"r2","reactionType":"destruction","summary":"A \\rightarrow \\emptyset","massaction":false,"propensity":"","annotation":"","types":[],"rate":{"compID":18,"name":"deltaA","expression":1,"annotation":""},"reactants":[{"ratio":1,"specie":{"compID":8,"name":"A","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}],"products":[]},{"compID":47,"name":"r3","reactionType":"change","summary":"C \\rightarrow R","massaction":false,"propensity":"","annotation":"","types":[],"rate":{"compID":18,"name":"deltaA","expression":1,"annotation":""},"reactants":[{"ratio":1,"specie":{"compID":7,"name":"C","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}],"products":[{"ratio":1,"specie":{"compID":9,"name":"R","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}]},{"compID":48,"name":"r4","reactionType":"destruction","summary":"R \\rightarrow \\emptyset","massaction":false,"propensity":"","annotation":"","types":[],"rate":{"compID":19,"name":"deltaR","expression":0.2,"annotation":""},"reactants":[{"ratio":1,"specie":{"compID":9,"name":"R","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}],"products":[]},{"compID":49,"name":"r5","reactionType":"merge","summary":"A+Da \\rightarrow Da\\_prime","massaction":false,"propensity":"","annotation":"","types":[],"rate":{"compID":20,"name":"gammaA","expression":1,"annotation":""},"reactants":[{"ratio":1,"specie":{"compID":8,"name":"A","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}},{"ratio":1,"specie":{"compID":1,"name":"Da","value":1,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}],"products":[{"ratio":1,"specie":{"compID":2,"name":"Da_prime","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}]},{"compID":50,"name":"r6","reactionType":"split","summary":"Da\\_prime \\rightarrow A+Da","massaction":false,"propensity":"","annotation":"","types":[],"rate":{"compID":23,"name":"thetaA","expression":50,"annotation":""},"reactants":[{"ratio":1,"specie":{"compID":2,"name":"Da_prime","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}],"products":[{"ratio":1,"specie":{"compID":8,"name":"A","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}},{"ratio":1,"specie":{"compID":1,"name":"Da","value":1,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}]},{"compID":51,"name":"r7","reactionType":"split","summary":"Da \\rightarrow Da+Ma","massaction":false,"propensity":"","annotation":"","types":[],"rate":{"compID":10,"name":"alphaA","expression":50,"annotation":""},"reactants":[{"ratio":1,"specie":{"compID":1,"name":"Da","value":1,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}],"products":[{"ratio":1,"specie":{"compID":1,"name":"Da","value":1,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}},{"ratio":1,"specie":{"compID":3,"name":"Ma","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}]},{"compID":52,"name":"r8","reactionType":"split","summary":"Da\\_prime \\rightarrow Da\\_prime+Ma","massaction":false,"propensity":"","annotation":"","types":[],"rate":{"compID":11,"name":"alphaA_prime","expression":500,"annotation":""},"reactants":[{"ratio":1,"specie":{"compID":2,"name":"Da_prime","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}],"products":[{"ratio":1,"specie":{"compID":2,"name":"Da_prime","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}},{"ratio":1,"specie":{"compID":3,"name":"Ma","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}]},{"compID":53,"name":"r9","reactionType":"destruction","summary":"Ma \\rightarrow \\emptyset","massaction":false,"propensity":"","annotation":"","types":[],"rate":{"compID":16,"name":"deltaMA","expression":10,"annotation":""},"reactants":[{"ratio":1,"specie":{"compID":3,"name":"Ma","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}],"products":[]},{"compID":54,"name":"r10","reactionType":"split","summary":"Ma \\rightarrow A+Ma","massaction":false,"propensity":"","annotation":"","types":[],"rate":{"compID":14,"name":"betaA","expression":50,"annotation":""},"reactants":[{"ratio":1,"specie":{"compID":3,"name":"Ma","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}],"products":[{"ratio":1,"specie":{"compID":8,"name":"A","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}},{"ratio":1,"specie":{"compID":3,"name":"Ma","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}]},{"compID":55,"name":"r11","reactionType":"merge","summary":"A+Dr \\rightarrow Dr\\_prime","massaction":false,"propensity":"","annotation":"","types":[],"rate":{"compID":21,"name":"gammaR","expression":1,"annotation":""},"reactants":[{"ratio":1,"specie":{"compID":8,"name":"A","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}},{"ratio":1,"specie":{"compID":4,"name":"Dr","value":1,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}],"products":[{"ratio":1,"specie":{"compID":5,"name":"Dr_prime","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}]},{"compID":56,"name":"r12","reactionType":"split","summary":"Dr\\_prime \\rightarrow A+Dr","massaction":false,"propensity":"","annotation":"","types":[],"rate":{"compID":24,"name":"thetaR","expression":100,"annotation":""},"reactants":[{"ratio":1,"specie":{"compID":5,"name":"Dr_prime","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}],"products":[{"ratio":1,"specie":{"compID":8,"name":"A","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}},{"ratio":1,"specie":{"compID":4,"name":"Dr","value":1,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}]},{"compID":57,"name":"r13","reactionType":"split","summary":"Dr \\rightarrow Dr+Mr","massaction":false,"propensity":"","annotation":"","types":[],"rate":{"compID":12,"name":"alphaR","expression":0.01,"annotation":""},"reactants":[{"ratio":1,"specie":{"compID":4,"name":"Dr","value":1,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}],"products":[{"ratio":1,"specie":{"compID":4,"name":"Dr","value":1,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}},{"ratio":1,"specie":{"compID":6,"name":"Mr","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}]},{"compID":58,"name":"r14","reactionType":"split","summary":"Dr\\_prime \\rightarrow Dr\\_prime+Mr","massaction":false,"propensity":"","annotation":"","types":[],"rate":{"compID":13,"name":"alphaR_prime","expression":50,"annotation":""},"reactants":[{"ratio":1,"specie":{"compID":5,"name":"Dr_prime","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}],"products":[{"ratio":1,"specie":{"compID":5,"name":"Dr_prime","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}},{"ratio":1,"specie":{"compID":6,"name":"Mr","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}]},{"compID":59,"name":"r15","reactionType":"destruction","summary":"Mr \\rightarrow \\emptyset","massaction":false,"propensity":"","annotation":"","types":[],"rate":{"compID":17,"name":"deltaMR","expression":0.5,"annotation":""},"reactants":[{"ratio":1,"specie":{"compID":6,"name":"Mr","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}],"products":[]},{"compID":60,"name":"r16","reactionType":"split","summary":"Mr \\rightarrow Mr+R","massaction":false,"propensity":"","annotation":"","types":[],"rate":{"compID":15,"name":"betaR","expression":5,"annotation":""},"reactants":[{"ratio":1,"specie":{"compID":6,"name":"Mr","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}],"products":[{"ratio":1,"specie":{"compID":6,"name":"Mr","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}},{"ratio":1,"specie":{"compID":9,"name":"R","value":0,"mode":"discrete","switchTol":0.03,"switchMin":100,"isSwitchTol":true,"annotation":""}}]}],"rules":[],"eventsCollection":[],"functionDefinitions":[],"boundaryConditions":[]}
\ No newline at end of file
diff --git a/public_models/Vilar_Oscillator/Vilar_Oscillator.sbml b/public_models/Vilar_Oscillator/Vilar_Oscillator.sbml
index da67089fae..2c34230d2b 100644
--- a/public_models/Vilar_Oscillator/Vilar_Oscillator.sbml
+++ b/public_models/Vilar_Oscillator/Vilar_Oscillator.sbml
@@ -2,68 +2,69 @@
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
-
+
-
-
-
-
@@ -71,140 +72,140 @@
-
+
-
+
-
-
+
-
-
-
-
+
+
-
-
+
+
-
-
+
+
+
+
+
-
+
-
+
-
+
-
-
-
-
-
+
-
+
@@ -212,68 +213,76 @@
+
+
+
+
-
-
+
-
+
+
-
+
-
+
-
+
-
+
@@ -286,7 +295,7 @@
@@ -304,43 +313,12 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/public_models/Vilar_Oscillator/Vilar_OscillatorSciopeModelExploration.ipynb b/public_models/Vilar_Oscillator/Vilar_OscillatorSciopeModelExploration.ipynb
new file mode 100644
index 0000000000..f01589b496
--- /dev/null
+++ b/public_models/Vilar_Oscillator/Vilar_OscillatorSciopeModelExploration.ipynb
@@ -0,0 +1,330 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "%matplotlib notebook"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import numpy as np\n",
+ "import gillespy2\n",
+ "from gillespy2 import Model, Species, Parameter, Reaction, Event, \\\n",
+ " EventTrigger, EventAssignment, RateRule, \\\n",
+ " AssignmentRule, FunctionDefinition\n",
+ "from gillespy2 import SSACSolver\n",
+ "# from gillespy2 import TauLeapingCSolver\n",
+ "# from gillespy2 import ODECSolver\n",
+ "# from gillespy2 import TauHybridSolver"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Vilar_Oscillator"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class VilarOscillator(Model):\n",
+ " def __init__(self, parameter_values=None):\n",
+ " Model.__init__(self, name=\"Vilar_Oscillator\")\n",
+ " self.volume = 1\n",
+ "\n",
+ " # Parameters\n",
+ " self.add_parameter(Parameter(name=\"alphaA\", expression=\"50\"))\n",
+ " self.add_parameter(Parameter(name=\"alphaA_prime\", expression=\"500\"))\n",
+ " self.add_parameter(Parameter(name=\"alphaR\", expression=\"0.01\"))\n",
+ " self.add_parameter(Parameter(name=\"alphaR_prime\", expression=\"50\"))\n",
+ " self.add_parameter(Parameter(name=\"betaA\", expression=\"50\"))\n",
+ " self.add_parameter(Parameter(name=\"betaR\", expression=\"5\"))\n",
+ " self.add_parameter(Parameter(name=\"deltaMA\", expression=\"10\"))\n",
+ " self.add_parameter(Parameter(name=\"deltaMR\", expression=\"0.5\"))\n",
+ " self.add_parameter(Parameter(name=\"deltaA\", expression=\"1\"))\n",
+ " self.add_parameter(Parameter(name=\"deltaR\", expression=\"0.2\"))\n",
+ " self.add_parameter(Parameter(name=\"gammaA\", expression=\"1\"))\n",
+ " self.add_parameter(Parameter(name=\"gammaR\", expression=\"1\"))\n",
+ " self.add_parameter(Parameter(name=\"gammaC\", expression=\"2\"))\n",
+ " self.add_parameter(Parameter(name=\"thetaA\", expression=\"50\"))\n",
+ " self.add_parameter(Parameter(name=\"thetaR\", expression=\"100\"))\n",
+ "\n",
+ " # Variables\n",
+ " self.add_species(Species(name=\"Da\", initial_value=1, mode=\"discrete\"))\n",
+ " self.add_species(Species(name=\"Da_prime\", initial_value=0, mode=\"discrete\"))\n",
+ " self.add_species(Species(name=\"Ma\", initial_value=0, mode=\"discrete\"))\n",
+ " self.add_species(Species(name=\"Dr\", initial_value=1, mode=\"discrete\"))\n",
+ " self.add_species(Species(name=\"Dr_prime\", initial_value=0, mode=\"discrete\"))\n",
+ " self.add_species(Species(name=\"Mr\", initial_value=0, mode=\"discrete\"))\n",
+ " self.add_species(Species(name=\"C\", initial_value=0, mode=\"discrete\"))\n",
+ " self.add_species(Species(name=\"A\", initial_value=0, mode=\"discrete\"))\n",
+ " self.add_species(Species(name=\"R\", initial_value=0, mode=\"discrete\"))\n",
+ "\n",
+ " # Reactions\n",
+ " self.add_reaction(Reaction(name=\"r1\", reactants={'A': 1, 'R': 1}, products={'C': 1}, rate=\"gammaC\"))\n",
+ " self.add_reaction(Reaction(name=\"r2\", reactants={'A': 1}, products={}, rate=\"deltaA\"))\n",
+ " self.add_reaction(Reaction(name=\"r3\", reactants={'C': 1}, products={'R': 1}, rate=\"deltaA\"))\n",
+ " self.add_reaction(Reaction(name=\"r4\", reactants={'R': 1}, products={}, rate=\"deltaR\"))\n",
+ " self.add_reaction(Reaction(name=\"r5\", reactants={'A': 1, 'Da': 1}, products={'Da_prime': 1}, rate=\"gammaA\"))\n",
+ " self.add_reaction(Reaction(name=\"r6\", reactants={'Da_prime': 1}, products={'A': 1, 'Da': 1}, rate=\"thetaA\"))\n",
+ " self.add_reaction(Reaction(name=\"r7\", reactants={'Da': 1}, products={'Da': 1, 'Ma': 1}, rate=\"alphaA\"))\n",
+ " self.add_reaction(Reaction(name=\"r8\", reactants={'Da_prime': 1}, products={'Da_prime': 1, 'Ma': 1}, rate=\"alphaA_prime\"))\n",
+ " self.add_reaction(Reaction(name=\"r9\", reactants={'Ma': 1}, products={}, rate=\"deltaMA\"))\n",
+ " self.add_reaction(Reaction(name=\"r10\", reactants={'Ma': 1}, products={'A': 1, 'Ma': 1}, rate=\"betaA\"))\n",
+ " self.add_reaction(Reaction(name=\"r11\", reactants={'A': 1, 'Dr': 1}, products={'Dr_prime': 1}, rate=\"gammaR\"))\n",
+ " self.add_reaction(Reaction(name=\"r12\", reactants={'Dr_prime': 1}, products={'A': 1, 'Dr': 1}, rate=\"thetaR\"))\n",
+ " self.add_reaction(Reaction(name=\"r13\", reactants={'Dr': 1}, products={'Dr': 1, 'Mr': 1}, rate=\"alphaR\"))\n",
+ " self.add_reaction(Reaction(name=\"r14\", reactants={'Dr_prime': 1}, products={'Dr_prime': 1, 'Mr': 1}, rate=\"alphaR_prime\"))\n",
+ " self.add_reaction(Reaction(name=\"r15\", reactants={'Mr': 1}, products={}, rate=\"deltaMR\"))\n",
+ " self.add_reaction(Reaction(name=\"r16\", reactants={'Mr': 1}, products={'Mr': 1, 'R': 1}, rate=\"betaR\"))\n",
+ "\n",
+ " # Timespan\n",
+ " self.timespan(np.arange(0, 201, 1))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "model = VilarOscillator()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Simulation Parameters"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def configure_simulation():\n",
+ " solver = SSACSolver(model=model)\n",
+ " kwargs = {\n",
+ " \"solver\":solver,\n",
+ " \"number_of_trajectories\":100,\n",
+ " # \"seed\":None,\n",
+ " # \"tau_tol\":0.03,\n",
+ " # \"integrator_options\":{'rtol': 0.001, 'atol': 1e-06},\n",
+ " }\n",
+ " return kwargs"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Model Exploration"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Define simulator function (using gillespy2 wrapper)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from sciope.utilities.gillespy2 import wrapper\n",
+ "settings = configure_simulation()\n",
+ "simulator = wrapper.get_simulator(gillespy_model=model, run_settings=settings, species_of_interest=['Da', 'Da_prime', 'Ma', 'Dr', 'Dr_prime', 'Mr', 'C', 'A', 'R'])\n",
+ "expression_array = wrapper.get_parameter_expression_array(model)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Start local cluster using dask client"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from dask.distributed import Client\n",
+ "\n",
+ "c = Client()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Define parameter sampler/design and summary statistics"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from sciope.designs import latin_hypercube_sampling\n",
+ "from sciope.utilities.summarystats.auto_tsfresh import SummariesTSFRESH\n",
+ "\n",
+ "lhc = latin_hypercube_sampling.LatinHypercube(xmin=expression_array, xmax=expression_array*3)\n",
+ "lhc.generate_array(1000) # creates a LHD of size 1000\n",
+ "\n",
+ "# will use default minimal set of features\n",
+ "summary_stats = SummariesTSFRESH()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Initiate StochMET"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from sciope.stochmet.stochmet import StochMET\n",
+ "\n",
+ "met = StochMET(simulator, lhc, summary_stats)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Run parameter sweep"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "met.compute(n_points=500, chunk_size=10)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Explore the result"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# First lets add some appropiate information about the model and features\n",
+ "met.data.configurations['listOfParameters'] = list(model.listOfParameters.keys())\n",
+ "met.data.configurations['listOfSpecies'] = list(model.listOfSpecies.keys())\n",
+ "met.data.configurations['listOfSummaries'] = met.summaries.features\n",
+ "met.data.configurations['timepoints'] = model.tspan"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Here we use UMAP for dimension reduction\n",
+ "met.explore(dr_method='umap')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from sciope.models.label_propagation import LPModel\n",
+ "# here lets use the dimension reduction embedding as input data\n",
+ "data = met.dr_model.embedding_\n",
+ "\n",
+ "model_lp = LPModel()\n",
+ "# train using basinhopping\n",
+ "model_lp.train(data, met.data.user_labels, min_=0.01, max_=10, niter=50)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# just to vislualize the result we will map the label distribution to the user_labels\n",
+ "# (will enable us to see the LP model output when using method 'explore')\n",
+ "user_labels = np.copy(met.data.user_labels)\n",
+ "# takes the label corresponding to index 0\n",
+ "met.data.user_labels = model_lp.model.label_distributions_[:, 0]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "met.explore(dr_method='umap')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "met.data.user_labels = user_labels"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "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.8.5"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/public_models/Vilar_Oscillator/Vilar_OscillatorSciopeModelInference.ipynb b/public_models/Vilar_Oscillator/Vilar_OscillatorSciopeModelInference.ipynb
new file mode 100644
index 0000000000..7f8004ba54
--- /dev/null
+++ b/public_models/Vilar_Oscillator/Vilar_OscillatorSciopeModelInference.ipynb
@@ -0,0 +1,374 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "%load_ext autoreload\n",
+ "%autoreload 2"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import numpy as np\n",
+ "import gillespy2\n",
+ "from gillespy2 import Model, Species, Parameter, Reaction, Event, \\\n",
+ " EventTrigger, EventAssignment, RateRule, \\\n",
+ " AssignmentRule, FunctionDefinition\n",
+ "from gillespy2 import SSACSolver\n",
+ "# from gillespy2 import TauLeapingCSolver\n",
+ "# from gillespy2 import ODECSolver\n",
+ "# from gillespy2 import TauHybridSolver"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Vilar_Oscillator"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class VilarOscillator(Model):\n",
+ " def __init__(self, parameter_values=None):\n",
+ " Model.__init__(self, name=\"Vilar_Oscillator\")\n",
+ " self.volume = 1\n",
+ "\n",
+ " # Parameters\n",
+ " self.add_parameter(Parameter(name=\"alphaA\", expression=\"50\"))\n",
+ " self.add_parameter(Parameter(name=\"alphaA_prime\", expression=\"500\"))\n",
+ " self.add_parameter(Parameter(name=\"alphaR\", expression=\"0.01\"))\n",
+ " self.add_parameter(Parameter(name=\"alphaR_prime\", expression=\"50\"))\n",
+ " self.add_parameter(Parameter(name=\"betaA\", expression=\"50\"))\n",
+ " self.add_parameter(Parameter(name=\"betaR\", expression=\"5\"))\n",
+ " self.add_parameter(Parameter(name=\"deltaMA\", expression=\"10\"))\n",
+ " self.add_parameter(Parameter(name=\"deltaMR\", expression=\"0.5\"))\n",
+ " self.add_parameter(Parameter(name=\"deltaA\", expression=\"1\"))\n",
+ " self.add_parameter(Parameter(name=\"deltaR\", expression=\"0.2\"))\n",
+ " self.add_parameter(Parameter(name=\"gammaA\", expression=\"1\"))\n",
+ " self.add_parameter(Parameter(name=\"gammaR\", expression=\"1\"))\n",
+ " self.add_parameter(Parameter(name=\"gammaC\", expression=\"2\"))\n",
+ " self.add_parameter(Parameter(name=\"thetaA\", expression=\"50\"))\n",
+ " self.add_parameter(Parameter(name=\"thetaR\", expression=\"100\"))\n",
+ "\n",
+ " # Variables\n",
+ " self.add_species(Species(name=\"Da\", initial_value=1, mode=\"discrete\"))\n",
+ " self.add_species(Species(name=\"Da_prime\", initial_value=0, mode=\"discrete\"))\n",
+ " self.add_species(Species(name=\"Ma\", initial_value=0, mode=\"discrete\"))\n",
+ " self.add_species(Species(name=\"Dr\", initial_value=1, mode=\"discrete\"))\n",
+ " self.add_species(Species(name=\"Dr_prime\", initial_value=0, mode=\"discrete\"))\n",
+ " self.add_species(Species(name=\"Mr\", initial_value=0, mode=\"discrete\"))\n",
+ " self.add_species(Species(name=\"C\", initial_value=0, mode=\"discrete\"))\n",
+ " self.add_species(Species(name=\"A\", initial_value=0, mode=\"discrete\"))\n",
+ " self.add_species(Species(name=\"R\", initial_value=0, mode=\"discrete\"))\n",
+ "\n",
+ " # Reactions\n",
+ " self.add_reaction(Reaction(name=\"r1\", reactants={'A': 1, 'R': 1}, products={'C': 1}, rate=\"gammaC\"))\n",
+ " self.add_reaction(Reaction(name=\"r2\", reactants={'A': 1}, products={}, rate=\"deltaA\"))\n",
+ " self.add_reaction(Reaction(name=\"r3\", reactants={'C': 1}, products={'R': 1}, rate=\"deltaA\"))\n",
+ " self.add_reaction(Reaction(name=\"r4\", reactants={'R': 1}, products={}, rate=\"deltaR\"))\n",
+ " self.add_reaction(Reaction(name=\"r5\", reactants={'A': 1, 'Da': 1}, products={'Da_prime': 1}, rate=\"gammaA\"))\n",
+ " self.add_reaction(Reaction(name=\"r6\", reactants={'Da_prime': 1}, products={'A': 1, 'Da': 1}, rate=\"thetaA\"))\n",
+ " self.add_reaction(Reaction(name=\"r7\", reactants={'Da': 1}, products={'Da': 1, 'Ma': 1}, rate=\"alphaA\"))\n",
+ " self.add_reaction(Reaction(name=\"r8\", reactants={'Da_prime': 1}, products={'Da_prime': 1, 'Ma': 1}, rate=\"alphaA_prime\"))\n",
+ " self.add_reaction(Reaction(name=\"r9\", reactants={'Ma': 1}, products={}, rate=\"deltaMA\"))\n",
+ " self.add_reaction(Reaction(name=\"r10\", reactants={'Ma': 1}, products={'A': 1, 'Ma': 1}, rate=\"betaA\"))\n",
+ " self.add_reaction(Reaction(name=\"r11\", reactants={'A': 1, 'Dr': 1}, products={'Dr_prime': 1}, rate=\"gammaR\"))\n",
+ " self.add_reaction(Reaction(name=\"r12\", reactants={'Dr_prime': 1}, products={'A': 1, 'Dr': 1}, rate=\"thetaR\"))\n",
+ " self.add_reaction(Reaction(name=\"r13\", reactants={'Dr': 1}, products={'Dr': 1, 'Mr': 1}, rate=\"alphaR\"))\n",
+ " self.add_reaction(Reaction(name=\"r14\", reactants={'Dr_prime': 1}, products={'Dr_prime': 1, 'Mr': 1}, rate=\"alphaR_prime\"))\n",
+ " self.add_reaction(Reaction(name=\"r15\", reactants={'Mr': 1}, products={}, rate=\"deltaMR\"))\n",
+ " self.add_reaction(Reaction(name=\"r16\", reactants={'Mr': 1}, products={'Mr': 1, 'R': 1}, rate=\"betaR\"))\n",
+ "\n",
+ " # Timespan\n",
+ " self.timespan(np.arange(0, 201, 1))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "model = VilarOscillator()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Simulation Parameters"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def configure_simulation():\n",
+ " solver = SSACSolver(model=model)\n",
+ " kwargs = {\n",
+ " \"solver\":solver,\n",
+ " \"number_of_trajectories\":100,\n",
+ " # \"seed\":None,\n",
+ " # \"tau_tol\":0.03,\n",
+ " # \"integrator_options\":{'rtol': 0.001, 'atol': 1e-06},\n",
+ " }\n",
+ " return kwargs"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Model Inference"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from tsfresh.feature_extraction.settings import MinimalFCParameters"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Generate some fixed(observed) data based on default parameters of the model"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "kwargs = configure_simulation()\n",
+ "fixed_data = model.run(**kwargs)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Reshape the data and remove timepoints array\n",
+ "fixed_data = fixed_data.to_array()\n",
+ "fixed_data = np.asarray([x.T for x in fixed_data])\n",
+ "fixed_data = fixed_data[:, 1:, :]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Define prior distribution"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from sciope.utilities.priors import uniform_prior\n",
+ "\n",
+ "# take default from mode 1 as reference\n",
+ "default_param = np.array(list(model.listOfParameters.items()))[:, 1]\n",
+ "\n",
+ "bound = []\n",
+ "for exp in default_param:\n",
+ " bound.append(float(exp.expression))\n",
+ "\n",
+ "# Set the bounds\n",
+ "bound = np.array(bound)\n",
+ "dmin = bound * 0.1\n",
+ "dmax = bound * 2.0\n",
+ "\n",
+ "# Here we use uniform prior\n",
+ "uni_prior = uniform_prior.UniformPrior(dmin, dmax)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Define simulator"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def get_variables(params, model):\n",
+ " # params - array, need to have the same order as model.listOfParameters\n",
+ " variables = {}\n",
+ " for e, pname in enumerate(model.listOfParameters.keys()):\n",
+ " variables[pname] = params[e]\n",
+ " return variables\n",
+ "\n",
+ "# Here we use the GillesPy2 Solver\n",
+ "def simulator(params, model):\n",
+ " variables = get_variables(params, model)\n",
+ "\n",
+ " res = model.run(**kwargs, variables=variables)\n",
+ " res = res.to_array()\n",
+ " tot_res = np.asarray([x.T for x in res]) # reshape to (N, S, T)\n",
+ " # should not contain timepoints\n",
+ " tot_res = tot_res[:, 1:, :]\n",
+ "\n",
+ " return tot_res\n",
+ "\n",
+ "# Wrapper, simulator function to abc should should only take one argument (the parameter point)\n",
+ "def simulator2(x):\n",
+ " return simulator(x, model=model)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Define summary statistics and distance function"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from sciope.utilities.summarystats import auto_tsfresh\n",
+ "from sciope.utilities.distancefunctions import naive_squared\n",
+ "\n",
+ "# Function to generate summary statistics\n",
+ "summ_func = auto_tsfresh.SummariesTSFRESH()\n",
+ "\n",
+ "# Distance\n",
+ "ns = naive_squared.NaiveSquaredDistance()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Start local cluster using dask client"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from dask.distributed import Client\n",
+ "\n",
+ "c = Client()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Start abc instance"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from sciope.inference.abc_inference import ABC\n",
+ "\n",
+ "abc = ABC(fixed_data, sim=simulator2, prior_function=uni_prior, summaries_function=summ_func.compute, distance_function=ns)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# First compute the fixed(observed) mean\n",
+ "abc.compute_fixed_mean(chunk_size=2)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/opt/conda/lib/python3.8/site-packages/distributed/worker.py:3801: UserWarning: Large object of size 2.97 MiB detected in task graph: \n",
+ " (
. 1:
- plots['stddevran'] = results.plotplotly_std_dev_range(return_plotly_figure=True)
- std_res = results.stddev_ensemble()
- plots['stddev'] = std_res.plotplotly(return_plotly_figure=True)
- avg_res = results.average_ensemble()
- plots['avg'] = avg_res.plotplotly(return_plotly_figure=True)
- for _, plot in plots.items():
- plot["config"] = {"responsive":True}
- with open('results/plots.json', 'w') as plots_file:
- json.dump(plots, plots_file, cls=plotly.utils.PlotlyJSONEncoder,
- indent=4, sort_keys=True)
- except Exception as err:
- message = f"Error storing result plots: {err}\n{traceback.format_exc()}"
- log.error(message)
- return message
- return False
-
-
def __update_timespan(self):
if "timespanSettings" in self.settings.keys():
keys = self.settings['timespanSettings'].keys()
@@ -163,9 +139,8 @@ def run(self, preview=False, verbose=True):
pkl_err = self.__store_pickled_results(results=results)
if verbose:
log.info("Storing the polts of the results")
- plt_err = self.__store_result_plots(results=results)
- if pkl_err and plt_err:
+ if pkl_err:
message = "An unexpected error occured with the result object"
- trace = f"{pkl_err}\n{plt_err}"
+ trace = str(pkl_err)
raise StochSSJobResultsError(message, trace)
return None
diff --git a/stochss/handlers/util/parameter_sweep.py b/stochss/handlers/util/parameter_sweep.py
index 43251bfabd..6b67f21d7c 100644
--- a/stochss/handlers/util/parameter_sweep.py
+++ b/stochss/handlers/util/parameter_sweep.py
@@ -25,7 +25,6 @@
import traceback
import numpy
-import plotly
from gillespy2 import TauHybridSolver
@@ -136,42 +135,6 @@ def __store_pickled_results(cls, job):
return False
- @classmethod
- def __store_result_plots(cls, job):
- try:
- mappers = ["min", "max", "avg", "var", "final"]
- if "solver" in job.settings.keys():
- solver_name = job.settings['solver'].name
- else:
- solver_name = job.model.get_best_solver().name
- if "ODE" not in solver_name and job.settings['number_of_trajectories'] > 1:
- keys = list(itertools.product(job.list_of_species, mappers,
- ["min", "max", "avg", "var"]))
- else:
- keys = list(itertools.product(job.list_of_species, mappers))
- plot_figs = {}
- for key in keys:
- key = list(key)
- trace_list = job.get_plotly_traces(keys=key)
- plt_data = {'title':f"Parameter Sweep - Variable: {key[0]}"}
- job.get_plotly_layout_data(plt_data=plt_data)
- layout = plotly.graph_objs.Layout(title=dict(text=plt_data['title'], x=0.5),
- xaxis=dict(title=plt_data['xaxis_label']),
- yaxis=dict(title=plt_data['yaxis_label']))
-
- fig = dict(data=trace_list, layout=layout, config={"responsive": True})
- plot_figs['-'.join(key)] = fig
-
- with open('results/plots.json', 'w') as plots_file:
- json.dump(plot_figs, plots_file, cls=plotly.utils.PlotlyJSONEncoder,
- indent=4, sort_keys=True)
- except Exception as err:
- message = f"Error storing result plots: {err}\n{traceback.format_exc()}"
- log.error(message)
- return message
- return False
-
-
@classmethod
def __store_results(cls, job):
try:
@@ -246,8 +209,7 @@ def run(self, verbose=True):
log.info("Storing the polts of the results")
res_err = self.__store_results(job=job)
self.__store_csv_results(job=job)
- plt_err = self.__store_result_plots(job=job)
- if pkl_err and res_err and plt_err:
- self.__report_result_error(trace=f"{res_err}\n{pkl_err}\n{plt_err}")
+ if pkl_err and res_err:
+ self.__report_result_error(trace=f"{res_err}\n{pkl_err}")
elif pkl_err:
self.__report_result_error(trace=pkl_err)
diff --git a/stochss/handlers/util/parameter_sweep_1d.py b/stochss/handlers/util/parameter_sweep_1d.py
index e1744532a8..011897c1c1 100644
--- a/stochss/handlers/util/parameter_sweep_1d.py
+++ b/stochss/handlers/util/parameter_sweep_1d.py
@@ -16,13 +16,14 @@
along with this program. If not, see .
'''
+import json
import copy
import logging
import traceback
import numpy
import plotly
-import matplotlib
+# import matplotlib
log = logging.getLogger("stochss")
@@ -143,26 +144,69 @@ def get_plotly_traces(self, keys):
return trace_list
- def plot(self, keys=None):
+ # def plot(self, keys=None):
+ # '''
+ # Plot the results based on the keys using matplotlib
+
+ # Attributes
+ # ----------
+ # key : list
+ # Identifiers for the results data
+ # '''
+ # if len(keys) > 2:
+ # results = self.results[keys[0]][keys[1]][keys[2]]
+ # else:
+ # results = self.results[keys[0]][keys[1]]
+
+ # matplotlib.pyplot.subplots(figsize=(8, 8))
+ # matplotlib.pyplot.title(f"Parameter Sweep - Variable: {keys[0]}")
+ # matplotlib.pyplot.errorbar(self.param['range'], results[:, 0], results[:, 1])
+ # matplotlib.pyplot.xlabel(self.param['parameter'],
+ # fontsize=16, fontweight='bold')
+ # matplotlib.pyplot.ylabel("Population", fontsize=16, fontweight='bold')
+
+
+ @classmethod
+ def plot(cls, results, species, param, mapper="final", reducer="avg"):
'''
- Plot the results based on the keys using matplotlib
+ Plot the results with error bar from time series results.
Attributes
----------
- key : list
- Identifiers for the results data
+ results : list
+ List of GillesPy2 results objects.
+ species : str
+ Species of interest name.
+ param : dict
+ StochSS sweep parameter dictionary.
+ mapper : str
+ Key indicating the feature extraction function to use.
+ reducer : str
+ Key indicating the ensemble aggragation function to use.
'''
- if len(keys) > 2:
- results = self.results[keys[0]][keys[1]][keys[2]]
+ func_map = {"min": numpy.min, "max": numpy.max, "avg": numpy.mean,
+ "var": numpy.var, "final": lambda res: res[-1]}
+ map_results = [[func_map[mapper](traj[species]) for traj in result] for result in results]
+ if len(map_results[0]) > 1:
+ data = [[func_map[reducer](map_result),
+ numpy.std(map_result)] for map_result in map_results]
+ visible = True
else:
- results = self.results[keys[0]][keys[1]]
+ data = [[map_result[0], 0] for map_result in map_results]
+ visible = False
+ data = numpy.array(data)
+
+ error_y = dict(type="data", array=data[:, 1], visible=visible)
+ trace_list = [plotly.graph_objs.Scatter(x=param['range'],
+ y=data[:, 0], error_y=error_y)]
+
+ title = f"Parameter Sweep - Variable: {species}"
+ layout = plotly.graph_objs.Layout(title=dict(text=title, x=0.5),
+ xaxis=dict(title=f"{param['name']}"),
+ yaxis=dict(title="Population"))
- matplotlib.pyplot.subplots(figsize=(8, 8))
- matplotlib.pyplot.title(f"Parameter Sweep - Variable: {keys[0]}")
- matplotlib.pyplot.errorbar(self.param['range'], results[:, 0], results[:, 1])
- matplotlib.pyplot.xlabel(self.param['parameter'],
- fontsize=16, fontweight='bold')
- matplotlib.pyplot.ylabel("Population", fontsize=16, fontweight='bold')
+ fig = dict(data=trace_list, layout=layout)
+ return json.loads(json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder))
def run(self, job_id, verbose=False):
diff --git a/stochss/handlers/util/parameter_sweep_2d.py b/stochss/handlers/util/parameter_sweep_2d.py
index b9718cc710..162e488230 100644
--- a/stochss/handlers/util/parameter_sweep_2d.py
+++ b/stochss/handlers/util/parameter_sweep_2d.py
@@ -16,14 +16,15 @@
along with this program. If not, see .
'''
+import json
import copy
import logging
import traceback
import numpy
import plotly
-import matplotlib
-import mpl_toolkits
+# import matplotlib
+# import mpl_toolkits
log = logging.getLogger("stochss")
@@ -140,32 +141,74 @@ def get_plotly_traces(self, keys):
return trace_list
- def plot(self, keys=None):
+ # def plot(self, keys=None):
+ # '''
+ # Plot the results based on the keys using matplotlib
+
+ # Attributes
+ # ----------
+ # key : list
+ # Identifiers for the results data
+ # '''
+ # if len(keys) <= 2:
+ # results = self.results[keys[0]][keys[1]]
+ # else:
+ # results = self.results[keys[0]][keys[1]][keys[2]]
+
+ # _, axis = matplotlib.pyplot.subplots(figsize=(8, 8))
+ # matplotlib.pyplot.imshow(results)
+ # axis.set_xticks(numpy.arange(results.shape[1])+0.5, minor=False)
+ # axis.set_yticks(numpy.arange(results.shape[0])+0.5, minor=False)
+ # matplotlib.pyplot.title(f"Parameter Sweep - Variable: {keys[0]}")
+ # axis.set_xticklabels(self.params[0]['range'], minor=False, rotation=90)
+ # axis.set_yticklabels(self.params[1]['range'], minor=False)
+ # axis.set_xlabel(self.params[0]['parameter'], fontsize=16, fontweight='bold')
+ # axis.set_ylabel(self.params[1]['parameter'], fontsize=16, fontweight='bold')
+ # divider = mpl_toolkits.axes_grid1.make_axes_locatable(axis)
+ # cax = divider.append_axes("right", size="5%", pad=0.2)
+ # _ = matplotlib.pyplot.colorbar(ax=axis, cax=cax)
+
+
+ @classmethod
+ def plot(cls, results, species, params, mapper="final", reducer="avg"):
'''
- Plot the results based on the keys using matplotlib
+ Plot the results with error bar from time series results.
Attributes
----------
- key : list
- Identifiers for the results data
+ results : list
+ List of GillesPy2 results objects.
+ species : str
+ Species of interest name.
+ params : list
+ List of StochSS sweep parameter dictionaries.
+ mapper : str
+ Key indicating the feature extraction function to use.
+ reducer : str
+ Key indicating the ensemble aggragation function to use.
'''
- if len(keys) <= 2:
- results = self.results[keys[0]][keys[1]]
- else:
- results = self.results[keys[0]][keys[1]][keys[2]]
-
- _, axis = matplotlib.pyplot.subplots(figsize=(8, 8))
- matplotlib.pyplot.imshow(results)
- axis.set_xticks(numpy.arange(results.shape[1])+0.5, minor=False)
- axis.set_yticks(numpy.arange(results.shape[0])+0.5, minor=False)
- matplotlib.pyplot.title(f"Parameter Sweep - Variable: {keys[0]}")
- axis.set_xticklabels(self.params[0]['range'], minor=False, rotation=90)
- axis.set_yticklabels(self.params[1]['range'], minor=False)
- axis.set_xlabel(self.params[0]['parameter'], fontsize=16, fontweight='bold')
- axis.set_ylabel(self.params[1]['parameter'], fontsize=16, fontweight='bold')
- divider = mpl_toolkits.axes_grid1.make_axes_locatable(axis)
- cax = divider.append_axes("right", size="5%", pad=0.2)
- _ = matplotlib.pyplot.colorbar(ax=axis, cax=cax)
+ func_map = {"min": numpy.min, "max": numpy.max, "avg": numpy.mean,
+ "var": numpy.var, "final": lambda res: res[-1]}
+ data = []
+ for p_results in results:
+ map_results = [[func_map[mapper](traj[species]) for traj in result]
+ for result in p_results]
+ if len(map_results[0]) > 1:
+ red_results = [func_map[reducer](map_result) for map_result in map_results]
+ else:
+ red_results = [map_result[0] for map_result in map_results]
+ data.append(red_results)
+ data = numpy.array(data)
+
+ trace_list = [plotly.graph_objs.Heatmap(z=data, x=params[0]['range'],
+ y=params[1]['range'])]
+
+ title = f"Parameter Sweep - Variable: {species}"
+ layout = plotly.graph_objs.Layout(title=dict(text=title, x=0.5),
+ xaxis=dict(title=f"{params[0]['name']}"),
+ yaxis=dict(title=f"{params[1]['name']}"))
+ fig = dict(data=trace_list, layout=layout)
+ return json.loads(json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder))
def run(self, job_id, verbose=False):
diff --git a/stochss/handlers/util/stochss_job.py b/stochss/handlers/util/stochss_job.py
index b9beeaa818..fe295dbaca 100644
--- a/stochss/handlers/util/stochss_job.py
+++ b/stochss/handlers/util/stochss_job.py
@@ -29,10 +29,13 @@
from .stochss_base import StochSSBase
from .stochss_folder import StochSSFolder
from .stochss_model import StochSSModel
+from .parameter_sweep_1d import ParameterSweep1D
+from .parameter_sweep_2d import ParameterSweep2D
from .stochss_spatial_model import StochSSSpatialModel
from .stochss_errors import StochSSJobError, StochSSJobNotCompleteError, \
StochSSFileNotFoundError, StochSSFileExistsError, \
- FileNotJSONFormatError, PlotNotAvailableError
+ FileNotJSONFormatError, PlotNotAvailableError, \
+ StochSSJobResultsError
class StochSSJob(StochSSBase):
'''
@@ -70,7 +73,7 @@ def __create_new_job(self, mdl_path, settings=None):
path = self.get_path(full=True)
try:
os.mkdir(path)
- os.mkdir(self.get_results_path(full=True))
+ os.mkdir(self.__get_results_path(full=True))
info = {"source_model":mdl_path, "wkfl_model":None, "type":self.type, "start_time":None}
self.update_info(new_info=info, new=True)
open(os.path.join(path, "logs.txt"), "w").close()
@@ -125,15 +128,79 @@ def __get_extract_dst_path(self, mdl_file):
return os.path.join(wkgp_path, mdl_file)
+ def __get_filtered_1d_results(self, f_keys):
+ results = self.__get_pickled_results()
+ f_results = []
+ for key, result in results.items():
+ if self.__is_result_valid(f_keys, key):
+ f_results.append(result)
+ return f_results
+
+
+ def __get_filtered_2d_results(self, f_keys, param):
+ results = self.__get_pickled_results()
+ f_results = []
+ for value in param['range']:
+ p_key = f"{param['name']}:{value}"
+ p_results = []
+ for key, result in results.items():
+ if p_key in key.split(',') and self.__is_result_valid(f_keys, key):
+ p_results.append(result)
+ f_results.append(p_results)
+ return f_results
+
+
+ @classmethod
+ def __get_fixed_keys_and_dims(cls, settings, fixed):
+ p_len = len(settings['parameterSweepSettings']['parameters'])
+ dims = p_len - len(fixed.keys())
+ if dims <= 0:
+ message = "Too many fixed parameters were provided."
+ message += "At least one variable parameter is required."
+ raise StochSSJobResultsError(message)
+ if dims > 2:
+ message = "Not enough fixed parameters were provided."
+ message += "Variable parameters cannot exceed 2."
+ raise StochSSJobResultsError(message)
+ f_keys = [f"{name}:{value}" for name, value in fixed.items()]
+ return dims, f_keys
+
+
+ def __get_pickled_results(self):
+ path = os.path.join(self.__get_results_path(full=True), "results.p")
+ with open(path, "rb") as results_file:
+ return pickle.load(results_file)
+
+
+ def __get_results_path(self, full=False):
+ '''
+ Return the path to the results directory
+
+ Attributes
+ ----------
+ full : bool
+ Indicates whether or not to get the full path or local path
+ '''
+ return os.path.join(self.get_path(full=full), "results")
+
+
def __is_csv_dir(self, file):
if "results_csv" not in file:
return False
- path = os.path.join(self.get_results_path(), file)
+ path = os.path.join(self.__get_results_path(), file)
if not os.path.isdir(path):
return False
return True
+ @classmethod
+ def __is_result_valid(cls, f_keys, key):
+ for f_key in f_keys:
+ if f_key not in key.split(','):
+ return False
+ return True
+
+
def __update_settings(self):
settings = self.job['settings']['parameterSweepSettings']
if "parameters" not in settings.keys():
@@ -237,7 +304,7 @@ def get_csv_path(self, full=False):
Attributes
----------
'''
- res_path = self.get_results_path(full=full)
+ res_path = self.__get_results_path(full=full)
if not os.path.exists(res_path):
message = f"Could not find the results directory: {res_path}"
raise StochSSFileNotFoundError(message, traceback.format_exc())
@@ -321,43 +388,40 @@ def get_notebook_data(self):
return {"kwargs":kwargs, "type":wkfl_type}
- def get_plot_from_results(self, plt_key, plt_data, plt_type):
+ def get_plot_from_results(self, data_keys, plt_key, add_config=False):
'''
Get the plotly figure for the results of a job
Attributes
----------
+ data_keys : dict
+ Dictionary of param names and values used to identify the correct data.
plt_key : str
- Indentifier for the requested plot figure
- plt_data : dict
- Title and axes data for the plot
- plt_type : str
Type of plot to generate.
'''
- self.log("debug", f"Key identifying the plot to generate: {plt_type}")
- path = os.path.join(self.get_results_path(full=True), "results.p")
+ self.log("debug", f"Key identifying the plot to generate: {plt_key}")
try:
self.log("info", "Loading the results...")
- with open(path, "rb") as results_file:
- result = pickle.load(results_file)
- if plt_key is not None:
- result = result[plt_key]
+ result = self.__get_pickled_results()
+ if data_keys:
+ key = [f"{name}:{value}" for name, value in data_keys.items()]
+ key = ','.join(key)
+ result = result[key]
self.log("info", "Generating the plot...")
- if plt_type == "mltplplt":
+ if plt_key == "mltplplt":
fig = result.plotplotly(return_plotly_figure=True, multiple_graphs=True)
- elif plt_type == "stddevran":
+ elif plt_key == "stddevran":
fig = result.plotplotly_std_dev_range(return_plotly_figure=True)
else:
- if plt_type == "stddev":
+ if plt_key == "stddev":
result = result.stddev_ensemble()
- elif plt_type == "avg":
+ elif plt_key == "avg":
result = result.average_ensemble()
fig = result.plotplotly(return_plotly_figure=True)
- if plt_type != "mltplplt":
+ if add_config and plt_key != "mltplplt":
fig["config"] = {"responsive":True}
self.log("info", "Loading the plot...")
- fig = json.loads(json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder))
- return self.get_results_plot(plt_key=None, plt_data=plt_data, fig=fig)
+ return json.loads(json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder))
except FileNotFoundError as err:
message = f"Could not find the results pickle file: {str(err)}"
raise StochSSFileNotFoundError(message, traceback.format_exc()) from err
@@ -366,37 +430,59 @@ def get_plot_from_results(self, plt_key, plt_data, plt_type):
raise PlotNotAvailableError(message, traceback.format_exc()) from err
- def get_results_path(self, full=False):
+ def get_psweep_plot_from_results(self, fixed, kwargs, add_config=False):
'''
- Return the path to the results directory
+ Generate and return the parameter sweep plot form the time series results.
Attributes
----------
- full : bool
- Indicates whether or not to get the full path or local path
+ fixed : dict
+ Dictionary for parameters that remain at a fixed value.
+ kwarps : dict
+ Dictionary of keys used for post proccessing the results.
'''
- return os.path.join(self.get_path(full=full), "results")
+ self.log("debug", f"Key identifying the plot to generate: {kwargs}")
+ settings = self.load_settings()
+ try:
+ self.log("info", "Loading the results...")
+ dims, f_keys = self.__get_fixed_keys_and_dims(settings, fixed)
+ params = list(filter(lambda param: param['name'] not in fixed.keys(),
+ settings['parameterSweepSettings']['parameters']))
+ if dims == 1:
+ kwargs['param'] = params[0]
+ kwargs['results'] = self.__get_filtered_1d_results(f_keys)
+ self.log("info", "Generating the plot...")
+ fig = ParameterSweep1D.plot(**kwargs)
+ else:
+ kwargs['params'] = params
+ kwargs['results'] = self.__get_filtered_2d_results(f_keys, params[0])
+ self.log("info", "Generating the plot...")
+ fig = ParameterSweep2D.plot(**kwargs)
+ if add_config:
+ fig['config'] = {"responsive": True}
+ self.log("info", "Loading the plot...")
+ return json.loads(json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder))
+ except FileNotFoundError as err:
+ message = f"Could not find the results pickle file: {str(err)}"
+ raise StochSSFileNotFoundError(message, traceback.format_exc()) from err
+ except KeyError as err:
+ message = f"The requested plot is not available: {str(err)}"
+ raise PlotNotAvailableError(message, traceback.format_exc()) from err
- def get_results_plot(self, plt_key, plt_data, fig=None):
+ def update_fig_layout(self, fig=None, plt_data=None):
'''
Get the plotly figure for the results of a job
Attributes
----------
- plt_key : str
- Indentifier for the requested plot figure
+ fig : dict
+ Plotly figure to be updated
plt_data : dict
Title and axes data for the plot
'''
- self.log("debug", f"Key identifying the requested plot: {plt_key}")
self.log("debug", f"Title and axis data for the plot: {plt_data}")
- path = os.path.join(self.get_results_path(full=True), "plots.json")
- self.log("debug", f"Path to the job result plot file: {path}")
try:
- if fig is None:
- with open(path, "r") as plot_file:
- fig = json.load(plot_file)[plt_key]
if plt_data is None:
return fig
for key in plt_data.keys():
@@ -405,12 +491,6 @@ def get_results_plot(self, plt_key, plt_data, fig=None):
else:
fig['layout'][key]['title']['text'] = plt_data[key]
return fig
- except FileNotFoundError as err:
- message = f"Could not find the plots file: {str(err)}"
- raise StochSSFileNotFoundError(message, traceback.format_exc()) from err
- except json.decoder.JSONDecodeError as err:
- message = f"The plots file is not JSON decodable: {str(err)}"
- raise FileNotJSONFormatError(message, traceback.format_exc()) from err
except KeyError as err:
message = f"The requested plot is not available: {str(err)}"
raise PlotNotAvailableError(message, traceback.format_exc()) from err
diff --git a/stochss/handlers/workflows.py b/stochss/handlers/workflows.py
index daa572c3ed..2043c20868 100644
--- a/stochss/handlers/workflows.py
+++ b/stochss/handlers/workflows.py
@@ -234,17 +234,18 @@ async def get(self):
path = self.get_query_argument(name="path")
log.debug("The path to the workflow: %s", path)
body = json.loads(self.get_query_argument(name='data'))
- if body['plt_data'] == "None":
- body['plt_data'] = None
log.debug("Plot args passed to the plot: %s", body)
try:
- wkfl = StochSSJob(path=path)
- if "plt_type" in body.keys():
- fig = wkfl.get_plot_from_results(**body)
- wkfl.print_logs(log)
+ job = StochSSJob(path=path)
+ if body['sim_type'] in ("GillesPy2", "GillesPy2_PS"):
+ fig = job.get_plot_from_results(data_keys=body['data_keys'],
+ plt_key=body['plt_key'], add_config=True)
+ job.print_logs(log)
else:
- log.info("Loading the plot...")
- fig = wkfl.get_results_plot(**body)
+ fig = job.get_psweep_plot_from_results(fixed=body['data_keys'],
+ kwargs=body['plt_key'], add_config=True)
+ job.print_logs(log)
+ fig = job.update_fig_layout(fig=fig, plt_data=body['plt_data'])
log.debug("Plot figure: %s", fig)
self.write(fig)
except StochSSAPIError as err:
diff --git a/stochss/tests/example_models.py b/stochss/tests/example_models.py
index 17c415ac7c..60f7096cdc 100644
--- a/stochss/tests/example_models.py
+++ b/stochss/tests/example_models.py
@@ -242,21 +242,21 @@ def __init__(self):
self.volume = 1
# Parameters
- self.add_parameter(Parameter(name="alpha_a", expression="50"))
- self.add_parameter(Parameter(name="alpha_a_prime", expression="500"))
- self.add_parameter(Parameter(name="alpha_r", expression="0.01"))
- self.add_parameter(Parameter(name="alpha_r_prime", expression="50"))
- self.add_parameter(Parameter(name="beta_a", expression="50"))
- self.add_parameter(Parameter(name="beta_r", expression="5"))
- self.add_parameter(Parameter(name="delta_ma", expression="10"))
- self.add_parameter(Parameter(name="delta_mr", expression="0.5"))
- self.add_parameter(Parameter(name="delta_a", expression="1"))
- self.add_parameter(Parameter(name="delta_r", expression="0.2"))
- self.add_parameter(Parameter(name="gamma_a", expression="1"))
- self.add_parameter(Parameter(name="gamma_r", expression="1"))
- self.add_parameter(Parameter(name="gamma_c", expression="2"))
- self.add_parameter(Parameter(name="theta_a", expression="50"))
- self.add_parameter(Parameter(name="theta_r", expression="100"))
+ self.add_parameter(Parameter(name="alphaA", expression="50"))
+ self.add_parameter(Parameter(name="alphaA_prime", expression="500"))
+ self.add_parameter(Parameter(name="alphaR", expression="0.01"))
+ self.add_parameter(Parameter(name="alphaR_prime", expression="50"))
+ self.add_parameter(Parameter(name="betaA", expression="50"))
+ self.add_parameter(Parameter(name="betaR", expression="5"))
+ self.add_parameter(Parameter(name="deltaMA", expression="10"))
+ self.add_parameter(Parameter(name="deltaMR", expression="0.5"))
+ self.add_parameter(Parameter(name="deltaA", expression="1"))
+ self.add_parameter(Parameter(name="deltaR", expression="0.2"))
+ self.add_parameter(Parameter(name="gammaA", expression="1"))
+ self.add_parameter(Parameter(name="gammaR", expression="1"))
+ self.add_parameter(Parameter(name="gammaC", expression="2"))
+ self.add_parameter(Parameter(name="thetaA", expression="50"))
+ self.add_parameter(Parameter(name="thetaR", expression="100"))
# Variables
self.add_species(Species(name="Da", initial_value=1, mode="discrete"))
@@ -265,32 +265,30 @@ def __init__(self):
self.add_species(Species(name="Dr", initial_value=1, mode="discrete"))
self.add_species(Species(name="Dr_prime", initial_value=0, mode="discrete"))
self.add_species(Species(name="Mr", initial_value=0, mode="discrete"))
- self.add_species(Species(name="C", initial_value=10, mode="discrete"))
- self.add_species(Species(name="A", initial_value=10, mode="discrete"))
- self.add_species(Species(name="R", initial_value=10, mode="discrete"))
+ self.add_species(Species(name="C", initial_value=0, mode="discrete"))
+ self.add_species(Species(name="A", initial_value=0, mode="discrete"))
+ self.add_species(Species(name="R", initial_value=0, mode="discrete"))
# Reactions
- self.add_reaction(Reaction(name="r1", reactants={'Da_prime': 1}, products={'Da': 1}, rate=self.listOfParameters["theta_a"]))
- self.add_reaction(Reaction(name="r2", reactants={'Da': 1, 'A': 1}, products={'Da_prime': 1}, rate=self.listOfParameters["gamma_a"]))
- self.add_reaction(Reaction(name="r3", reactants={'Dr_prime': 1}, products={'Dr': 1}, rate=self.listOfParameters["theta_r"]))
- self.add_reaction(Reaction(name="r4", reactants={'Dr': 1, 'A': 1}, products={'Dr_prime': 1}, rate=self.listOfParameters["gamma_r"]))
- self.add_reaction(Reaction(name="r5", reactants={'Da_prime': 1}, products={'Da_prime': 1, 'Ma': 1}, rate=self.listOfParameters["alpha_a_prime"]))
- self.add_reaction(Reaction(name="r6", reactants={'Da': 1}, products={'Da': 1, 'Ma': 1}, rate=self.listOfParameters["alpha_a"]))
- self.add_reaction(Reaction(name="r7", reactants={'Ma': 1}, products={}, rate=self.listOfParameters["delta_ma"]))
- self.add_reaction(Reaction(name="r8", reactants={'Ma': 1}, products={'A': 1, 'Ma': 1}, rate=self.listOfParameters["beta_a"]))
- self.add_reaction(Reaction(name="r9", reactants={'Da_prime': 1}, products={'Da_prime': 1, 'A': 1}, rate=self.listOfParameters["theta_a"]))
- self.add_reaction(Reaction(name="r10", reactants={'Dr_prime': 1}, products={'Dr_prime': 1, 'A': 1}, rate=self.listOfParameters["theta_a"]))
- self.add_reaction(Reaction(name="r11", reactants={'A': 1}, products={}, rate=self.listOfParameters["gamma_c"]))
- self.add_reaction(Reaction(name="r12", reactants={'A': 1, 'R': 1}, products={'C': 1}, rate=self.listOfParameters["gamma_c"]))
- self.add_reaction(Reaction(name="r13", reactants={'Dr_prime': 1}, products={'Dr_prime': 1, 'Mr': 1}, rate=self.listOfParameters["alpha_r_prime"]))
- self.add_reaction(Reaction(name="r14", reactants={'Dr': 1}, products={'Dr': 1, 'Mr': 1}, rate=self.listOfParameters["alpha_r"]))
- self.add_reaction(Reaction(name="r15", reactants={'Mr': 1}, products={}, rate=self.listOfParameters["delta_mr"]))
- self.add_reaction(Reaction(name="r16", reactants={'Mr': 1}, products={'Mr': 1, 'R': 1}, rate=self.listOfParameters["beta_r"]))
- self.add_reaction(Reaction(name="r17", reactants={'R': 1}, products={}, rate=self.listOfParameters["delta_r"]))
- self.add_reaction(Reaction(name="r18", reactants={'C': 1}, products={'R': 1}, rate=self.listOfParameters["delta_a"]))
+ self.add_reaction(Reaction(name="r1", reactants={'A': 1, 'R': 1}, products={'C': 1}, rate="gammaC"))
+ self.add_reaction(Reaction(name="r2", reactants={'A': 1}, products={}, rate="deltaA"))
+ self.add_reaction(Reaction(name="r3", reactants={'C': 1}, products={'R': 1}, rate="deltaA"))
+ self.add_reaction(Reaction(name="r4", reactants={'R': 1}, products={}, rate="deltaR"))
+ self.add_reaction(Reaction(name="r5", reactants={'A': 1, 'Da': 1}, products={'Da_prime': 1}, rate="gammaA"))
+ self.add_reaction(Reaction(name="r6", reactants={'Da_prime': 1}, products={'A': 1, 'Da': 1}, rate="thetaA"))
+ self.add_reaction(Reaction(name="r7", reactants={'Da': 1}, products={'Da': 1, 'Ma': 1}, rate="alphaA"))
+ self.add_reaction(Reaction(name="r8", reactants={'Da_prime': 1}, products={'Da_prime': 1, 'Ma': 1}, rate="alphaA_prime"))
+ self.add_reaction(Reaction(name="r9", reactants={'Ma': 1}, products={}, rate="deltaMA"))
+ self.add_reaction(Reaction(name="r10", reactants={'Ma': 1}, products={'A': 1, 'Ma': 1}, rate="betaA"))
+ self.add_reaction(Reaction(name="r11", reactants={'A': 1, 'Dr': 1}, products={'Dr_prime': 1}, rate="gammaR"))
+ self.add_reaction(Reaction(name="r12", reactants={'Dr_prime': 1}, products={'A': 1, 'Dr': 1}, rate="thetaR"))
+ self.add_reaction(Reaction(name="r13", reactants={'Dr': 1}, products={'Dr': 1, 'Mr': 1}, rate="alphaR"))
+ self.add_reaction(Reaction(name="r14", reactants={'Dr_prime': 1}, products={'Dr_prime': 1, 'Mr': 1}, rate="alphaR_prime"))
+ self.add_reaction(Reaction(name="r15", reactants={'Mr': 1}, products={}, rate="deltaMR"))
+ self.add_reaction(Reaction(name="r16", reactants={'Mr': 1}, products={'Mr': 1, 'R': 1}, rate="betaR"))
# Timespan
- self.timespan(np.arange(0, 200, 1))
+ self.timespan(np.arange(0, 201, 1))
class Oregonator(Model):
diff --git a/stochss/tests/test_gillespy2.py b/stochss/tests/test_gillespy2.py
index b16fbfa94a..6275fd773c 100644
--- a/stochss/tests/test_gillespy2.py
+++ b/stochss/tests/test_gillespy2.py
@@ -161,6 +161,7 @@ def test_tau_hybrid_solver(self):
self.test_models.append(Oregonator)
self.test_models.append(TysonOscillator)
+ self.test_models.remove(VilarOscillator)
for model in self.test_models:
test_model = model()
with self.subTest(model=test_model.name):