Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Copasi javascript support #2015

Merged
merged 36 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
a166dd5
Add initial support for interpreting COPASI models using `COPASI.js` …
whomingbird Jun 18, 2024
ced0bde
move 'plotly-2.27.0.min.js' to 'application.js'
whomingbird Jun 18, 2024
14b9533
Hide "Simulate Model on Copasi" button if no local model file exists
whomingbird Jun 20, 2024
a2c309c
Load the first COPASI-compatible item when multiple items are associa…
whomingbird Jun 20, 2024
ace41da
bug fix: Load the first COPASI-compatible item to CopasiUI (the desk …
whomingbird Jun 21, 2024
a37cac0
make sure a non-public model can be loaded to Copasi with a temporary…
whomingbird Jun 21, 2024
4b84753
Show the "Simulate Model on Copasi" button on the model page if the u…
whomingbird Jun 21, 2024
32ff6ad
When the model is not publicly accessible but can be downloaded by th…
whomingbird Jun 27, 2024
79da9d3
minor tweak
whomingbird Jun 28, 2024
8715db6
add tests for 'Simulate Model on Copasi button visibility'
whomingbird Jun 28, 2024
1fc1190
delete unnecessary HTML
whomingbird Jun 28, 2024
950b9f6
add unit tests for copasi models
whomingbird Jun 28, 2024
e301b2f
add tests for "copasi simulate" action
whomingbird Jun 28, 2024
fe690c0
update route
whomingbird Jun 28, 2024
6fe1807
add test to verify the correct version is loaded in the simulation
whomingbird Jul 1, 2024
44bc70f
introduces three input fields for parameter inputs on the COPASI simu…
whomingbird Oct 2, 2024
3515cbb
add tabs for showing details of cps model
whomingbird Oct 2, 2024
ebc43ec
refactoring copasi javascript
whomingbird Oct 9, 2024
b386d96
update the view and fix the tab display problem
whomingbird Oct 10, 2024
38d1e97
Check the functionality of the 'Simulate in CopasiUI' button for mode…
whomingbird Oct 10, 2024
b5f30ff
Ensure `copasi_enabled` is checked before executing the `copasi_simul…
whomingbird Oct 10, 2024
d83cd29
add a test of simulating copasi when model is private
whomingbird Oct 10, 2024
5daeced
Merge branch 'main' into copasi-javascript-support
whomingbird Oct 10, 2024
4a3c590
Log run actions for copasi simulation
whomingbird Oct 10, 2024
1bfb2f7
fix XSS vulnerability issue
whomingbird Oct 11, 2024
de276bf
move the 3rd party javascript to vendor/assets/javascript
whomingbird Oct 16, 2024
5b849fa
fix typo
whomingbird Oct 16, 2024
f7840b6
no migration, so no changes in schema.rb
whomingbird Oct 16, 2024
c8076ab
don't use :x=> !
whomingbird Oct 16, 2024
31c7c76
update tooltip text of copasi button
whomingbird Oct 16, 2024
36d8123
merge main branch
whomingbird Oct 16, 2024
665d9d6
refactoring
whomingbird Oct 16, 2024
b37f8cd
correct the action translation
whomingbird Oct 16, 2024
edad931
fix test
whomingbird Oct 17, 2024
4348589
use `with_config_value` in the test
whomingbird Oct 17, 2024
cf74eeb
merge main
whomingbird Oct 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions app/assets/javascripts/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,8 @@
//= require select2.full.min
//= require licenses
//= require svg-pan-zoom-3.6.1/svg-pan-zoom.min
//= require copasi/copasi
//= require copasi/copasijs
//= require copasi/copasi_simulation
//= require plotly-2.27.0.min

342 changes: 342 additions & 0 deletions app/assets/javascripts/copasi/copasi.js
whomingbird marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,342 @@
/**
* @class COPASI
*
* This class wraps all the functions exported from
* emscripten and provides a more convenient interface.
*/
class COPASI {

/**
* @enum {string} TC
*
* enum for method names
*
* @property {string} LSODA Deterministic (LSODA)
* @property {string} RADAU5 Deterministic (RADAU5)
* @property {string} DIRECT_METHOD Stochastic (Direct method)
* @property {string} GIBSON_BRUCK Stochastic (Gibson + Bruck)
* @property {string} TAULEAP Stochastic (τ-Leap)
*/
TC = {
LSODA: 'Deterministic (LSODA)',
RADAU5: 'Deterministic (RADAU5)',
DIRECT_METHOD: 'Stochastic (Direct method)',
GIBSON_BRUCK: 'Stochastic (Gibson + Bruck)',
TAULEAP: 'Stochastic (τ-Leap)',
};

/**
* Constructs a new COPASI instance from the WASM module
* @param Module the WASM module
*
*/
constructor(Module) {
this.Module = Module;

// initialize wasm methods
this.getVersion = Module.getVersion
this.getMessages = Module.getMessages;
this.steadyState = Module.steadyState;
this.oneStep = Module.oneStep;
this.initCps = Module.initCps;
this.destroy = Module.destroy;

// init runtime
this.initCps();
}

/**
* loads an example (if the WASM module was compiled with FS support)
*
* @param {string} path
* @returns model information as an object
*/
loadExample(path)
{
return JSON.parse(this.Module.loadFromFile(path));
}

/**
* Loads a model from a string containing the model in
* SBML or COPASI format.
*
* @param {string} modelCode in SBML or COPASI format
* @returns model information as an object
*/
loadModel(modelCode)
{
return JSON.parse(this.Module.loadModel(modelCode));
}

/**
* simulates the currently loaded model with its current
* time course settings.
*
* @returns {object} simulation results as object
*/
simulate() {
return JSON.parse(this.Module.simulate());
}

/**
* simulates the currently loaded model with its current
* time course settings.
*
* @returns {number[][]} simulation results as 2D array
*/
simulate2D() {
this.Module.simulate();
return this._vector2dToArray(this.Module.getSimulationResults2D());
}

/**
* simulates the currently loaded model from startTime to
* endTime with numPoints points.
*
* @param {number} startTime
* @param {number} endTime
* @param {number} numPoints
*
* @returns {object} simulation results as object
*/
simulateEx(startTime, endTime, numPoints) {
return this.Module.simulateEx(startTime, endTime, numPoints);
}

/**
* simulates the currently loaded model from startTime to
* endTime with numPoints points.
*
* @param {number} startTime
* @param {number} endTime
* @param {number} numPoints
*
* @returns {number[][]} simulation results as 2D array
*/
simulateEx2D(startTime, endTime, numPoints) {
this.Module.simulateEx(startTime, endTime, numPoints);
return this._vector2dToArray(this.Module.getSimulationResults2D());
}

/**
* simulates the currently loaded model after applying
* the processing instructions:
*
* @param {object|string} yamlProcessingOptions
* @returns {object} simulation results as object
*/
simulateYaml(yamlProcessingOptions) {
if (typeof yamlProcessingOptions !== 'string') {
yamlProcessingOptions = JSON.stringify(yamlProcessingOptions);
}
return JSON.parse(this.Module.simulateYaml(yamlProcessingOptions));
}

/**
* simulates the currently loaded model after applying
* the processing instructions:
*
* @param {object|string} yamlProcessingOptions
* @returns {number[][]} simulation results as 2D array
*/
simulateYaml2D(yamlProcessingOptions) {
if (typeof yamlProcessingOptions !== 'string') {
yamlProcessingOptions = JSON.stringify(yamlProcessingOptions);
}
this.Module.simulateYaml(yamlProcessingOptions);
return this._vector2dToArray(this.Module.getSimulationResults2D());
}

/**
* resets the model
*
* after loading the model, its state was saved as parameterset,
* calling reset will apply that parameter set.
*/
reset() {
// Add code here to reset the simulator
this.Module.reset();
}


/**
* @property {string} version returns the COPASI version
*
* @example
* var copasi = new COPASI(Module);
* console.log(copasi.version);
* // prints something like:
* // 4.32.284
*/
get version() {
return this.Module.getVersion();
}

_vectorToArray(v) {
var result = [];
for (var i = 0; i < v.size(); i++) {
result.push(v.get(i));
}
return result;
}

// convert 2d vector to Array
_vector2dToArray(v) {
var result = [];
for (var i = 0; i < v.size(); i++) {
result.push(this._vectorToArray(v.get(i)));
}
return result;
}

/**
* @property {number[]} floatingSpeciesConcentrations returns floating species concentrations
*/
get floatingSpeciesConcentrations() {
return this._vectorToArray(this.Module.getFloatingSpeciesConcentrations());
}

/**
* @property {number[]} ratesOfChange returns rates of change of floating species
*/
get ratesOfChange() {
return this._vectorToArray(this.Module.getRatesOfChange());
}

/**
* @property {string[]} floatingSpeciesNames returns floating species names
*/
get floatingSpeciesNames() {
return this._vectorToArray(this.Module.getFloatingSpeciesNames());
}

/**
* @property {number[]} boundarySpeciesConcentrations returns boundary species concentrations
*/
get boundarySpeciesConcentrations() {
return this._vectorToArray(this.Module.getBoundarySpeciesConcentrations());
}

/**
* @property {string[]} boundarySpeciesNames returns boundary species names
*/
get boundarySpeciesNames() {
return this._vectorToArray(this.Module.getBoundarySpeciesNames());
}

/**
* @property {string[]} reactionNames returns reaction names
*/
get reactionNames() {
return this._vectorToArray(this.Module.getReactionNames());
}

/**
* @property {number[]} reactionRates returns reaction rates
*/
get reactionRates() {
return this._vectorToArray(this.Module.getReactionRates());
}

/**
* @property {string[]} compartmentNames returns compartment names
*/
get compartmentNames() {
return this._vectorToArray(this.Module.getCompartmentNames());
}

/**
* @property {number[]} compartmentSizes returns compartment sizes
*/
get compartmentSizes() {
return this._vectorToArray(this.Module.getCompartmentSizes());
}

/**
* @property {string[]} globalParameterNames returns global parameter names
*/
get globalParameterNames() {
return this._vectorToArray(this.Module.getGlobalParameterNames());
}

/**
* @property {number[]} globalParameterValues returns global parameter values
*/
get globalParameterValues() {
return this._vectorToArray(this.Module.getGlobalParameterValues());
}

/**
* @property {string[]} localParameterNames returns local parameter names
*
* Local parameter names, consist of the reaction name in brackets, followed by a dot
* and the parameter name. So for example: `(reaction1).k1` for the
* local parameter `k1` of the reaction `reaction1`.
*/
get localParameterNames() {
return this._vectorToArray(this.Module.getLocalParameterNames());
}

/**
* @property {number[]} localParameterValues returns local parameter values
*/
get localParameterValues() {
return this._vectorToArray(this.Module.getLocalParameterValues());
}

/**
* @property {object} timeCourseSettings returns the time course settings as json object
*
* @param {object|string} arg the time course settings to set
*/
get timeCourseSettings() {
return JSON.parse(this.Module.getTimeCourseSettings());
}

set timeCourseSettings(arg) {
// test wether arg is string, otherwise stringify
if (typeof arg !== 'string') {
arg = JSON.stringify(arg);
}
return this.Module.setTimeCourseSettings(arg);
}

/**
* @property {object} modelInfo model information as object
*/
get modelInfo() {
return JSON.parse(this.Module.getModelInfo());
}

/**
* @property {string[]} selectionList returns the selection list
*
* The selection list controls what will be in the output of the
* simulation calls.
*/
get selectionList() {
return this._vectorToArray(this.Module.getSelectionList());
}

set selectionList(arg)
{
var vector = new this.Module.StringVector();
arg.forEach((item) => vector.push_back(item));
return this.Module.setSelectionList(vector);
}

/**
* @property {number[]} selectedValues returns the selected values
*/
get selectedValues() {
return this._vectorToArray(this.Module.getSelectedValues());
}
}

// if module is defined, export the COPASI class
if (typeof module !== 'undefined') {
module.exports = COPASI;
}

//export default COPASI;
//export {COPASI};
Loading