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

Convert Goldbeter 1991 Srn Model #4

Draft
wants to merge 16 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
BSD 3-Clause License

Copyright (c) 2023, Chaste - Cancer Heart and Soft Tissue Environment
Copyright (c) 2025, Chaste - Cancer Heart and Soft Tissue Environment

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Expand Down
34 changes: 22 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,44 @@
# Chaste code generation from SBML
# SBML → Chaste

The `chaste_codegen_sbml` module takes [SBML](https://synonym.caltech.edu/) models as input and uses [libSBML](https://synonym.caltech.edu/software/libsbml/) to parse the models and output C++ code for Chaste.
`chaste_codegen_sbml` converts [SBML](https://synonym.caltech.edu/) models to C++ Chaste code. It relies on [libSBML](https://synonym.caltech.edu/software/libsbml/) for parsing SBML.

## Installation
### User install
Installation via [`pipx`](https://pipx.pypa.io/) is recommended
```
pipx install git+https://github.com/Chaste/chaste-codegen-sbml@develop
```

Alternatively, install via `pip` (optionally in a virtual environment)
Alternatively, install via `pip`
```
# Create and activate a virtual environment
# Create and activate a virtual environment (optional)
python -m venv sbml-venv
source sbml-venv/bin/activate

# Install
pip install git+https://github.com/Chaste/chaste-codegen-sbml@develop
```

### Developer install
Clone the repository and install the package in editable mode along with the `dev` dependencies:
## Usage
```
chaste_codegen_sbml [-h]
```

## Development
### Getting the code
```
# Clone the repository
git clone https://github.com/Chaste/chaste-codegen-sbml
cd chaste-codegen-sbml
pip install -e .[dev]

# Create and activate a virtual environment
python -m venv venv
source venv/bin/activate

# Install in editable mode along with dev dependencies
pip install -e ."[dev]"
```

## Usage
### Running tests
```
chaste_codegen_sbml [-h]
python -m pytest
```

## Testing
9 changes: 2 additions & 7 deletions chaste_codegen_sbml/filewriters.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import sys
import os.path
from libsbml import *
from . import translator

# Script with functions that will write all the necessary SBML info into Chaste .cpp
Expand Down Expand Up @@ -259,13 +256,11 @@ def GetClassDefinition(filename, model):
ode_name = GetOdeSystemName(filename)

##### EDITED ###################### - in this case, the rules are also variables (as totals of other variables)
odes_dict = translator.GetOdesDictionary(model)
rules_dict = translator.GetRulesDictionary(model)
num_species = len(odes_dict) + len(rules_dict)
num_state_vars = len(translator.GetOdesDictionary(model))

class_defn_str = (translator.GetBlockCommentDefinition(0, "SBML ODE System", True) +
ode_name + "::" + ode_name + " (std::vector<double> stateVariables)\n" +
translator.AddTabs(1) + ": AbstractOdeSystem(" + str(num_species) + ")\n"
translator.AddTabs(1) + ": AbstractOdeSystem(" + str(num_state_vars) + ")\n"
"{\n" +
translator.AddTabs(1) + "mpSystemInfo.reset(new CellwiseOdeSystemInformation<" + ode_name + ">);\n"
"\n" +
Expand Down
36 changes: 11 additions & 25 deletions chaste_codegen_sbml/generator.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import sys
import os
from os.path import basename
from libsbml import *
from libsbml import SBMLReader
from . import translator
from . import filewriters

Expand Down Expand Up @@ -46,42 +44,30 @@ def MoveFilesToDirectory(files, new_path):
for i in range(len(files)):
os.rename(current_path + "/" + files[i], new_path + "/" + files[i])

def Generate(path_to_file):
def Generate(sbml_file, output_filename=None, output_directory=None):
""" Main function. Arguments are:
Input, Output Filename, Output Directory. """

# path_to_file = args[1]

#Get the model from the file
reader = SBMLReader()
document = reader.readSBMLFromFile(path_to_file)
document = reader.readSBMLFromFile(sbml_file)
model = document.getModel()

#Get Name of file
# if(len(args) > 2):
# model_name = args[2]
# else:
# filename = basename(path_to_file)
# split_fname = filename.split('.')
# model_name = split_fname[0]

filename = basename(path_to_file)
model_name = filename.split('.')[0]
if not output_filename:
output_filename = os.path.basename(sbml_file).split('.')[0]

# If there are events in the model, we define the class as a cell cycle model.
# Otherwise, the model is assumed to be a subcellular reaction network model.
if( translator.IsSrnModel(model) ):
filewriters.WriteSrnModelToFile(model_name, model)
if translator.IsSrnModel(model):
filewriters.WriteSrnModelToFile(output_filename, model)
else:
filewriters.WriteCcmModelToFile(model_name, model)
filewriters.WriteCcmModelToFile(output_filename, model)

# if(len(args) > 3):
# output_directory = args[3]
# else:
# output_directory = "."
output_directory = "."
if not output_directory:
output_directory = "."

output_files = GetOutputFilenames(path_to_file, model_name)
output_files = GetOutputFilenames(sbml_file, output_filename)

#Move created files if output directory has been specified.
MoveFilesToDirectory(output_files, output_directory)
190 changes: 190 additions & 0 deletions chaste_codegen_sbml/templates/SbmlSrnWrapperModel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
/*

Copyright (c) 2005-2013, University of Oxford.
All rights reserved.

University of Oxford means the Chancellor, Masters and Scholars of the
University of Oxford, having an administrative office at Wellington
Square, Oxford OX1 2JD, UK.

This file is part of Chaste.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the University of Oxford nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef SBMLSRNWRAPPERMODEL_CPP_
#define SBMLSRNWRAPPERMODEL_CPP_

//#include "UblasIncludes.hpp"
#include "SbmlSrnWrapperModel.hpp"
#include "CellCycleModelOdeSolver.hpp"
#include "RungeKutta4IvpOdeSolver.hpp"
#include "AbstractOdeSrnModel.hpp"
#include "CvodeAdaptor.hpp"
//#include "Exception.hpp"
#include "Debug.hpp"


template<typename SBMLODE, unsigned SIZE>
SbmlSrnWrapperModel<SBMLODE, SIZE>::SbmlSrnWrapperModel(boost::shared_ptr<AbstractCellCycleModelOdeSolver> pOdeSolver)
: AbstractOdeSrnModel(SIZE, pOdeSolver)
{

// TODO add CVODE solver. See VanLeeuwen CCM in trunk

if (mpOdeSolver == boost::shared_ptr<AbstractCellCycleModelOdeSolver>())
{

#ifdef CHASTE_CVODE
mpOdeSolver = CellCycleModelOdeSolver<SbmlSrnWrapperModel<SBMLODE, SIZE>, CvodeAdaptor>::Instance();
mpOdeSolver->Initialise();
// Chaste solvers always check for stopping events, CVODE needs to be instructed to do so
mpOdeSolver->CheckForStoppingEvents();
mpOdeSolver->SetMaxSteps(10000);
#else
mpOdeSolver = CellCycleModelOdeSolver<SbmlSrnWrapperModel<SBMLODE, SIZE>, RungeKutta4IvpOdeSolver>::Instance();
mpOdeSolver->Initialise();
SetDt(0.0001); // This is small enough for both examples to converge
#endif //CHASTE_CVODE
}

assert(mpOdeSolver->IsSetUp());
}

//New method for copy constructor
template<typename SBMLODE, unsigned SIZE>
SbmlSrnWrapperModel<SBMLODE, SIZE>::SbmlSrnWrapperModel(const SbmlSrnWrapperModel& rModel)
: AbstractOdeSrnModel(rModel)
{
/*
* Set each member variable of the new SRN model that inherits
* its value from the parent.
*
* Note 1: some of the new SRN model's member variables
* will already have been correctly initialized in its constructor.
*
* Note 2: one or more of the new SRN model's member variables
* may be set/overwritten as soon as InitialiseDaughterCell() is called on
* the new SRN model.
*
* Note 3: Only set the variables defined in this class. Variables defined
* in parent classes will be defined there.
*/

assert(rModel.GetOdeSystem());
SetOdeSystem(new SBMLODE(rModel.GetOdeSystem()->rGetStateVariables()));
}

template<typename SBMLODE, unsigned SIZE>
AbstractSrnModel* SbmlSrnWrapperModel<SBMLODE, SIZE>::CreateSrnModel()
{
return new SbmlSrnWrapperModel(*this);
}


template<typename SBMLODE, unsigned SIZE>
void SbmlSrnWrapperModel<SBMLODE, SIZE>::SimulateToCurrentTime()
{

assert(mpOdeSystem != NULL);
assert(mpCell != NULL);

/* Custom behaviour: store the state variables as cell data and set any parameters
* using cell data, so that we can visualise different concentrations in Paraview.
*/

std::vector<std::string> parameterNames = mpOdeSystem->rGetParameterNames();
//Set parameters that need to be set
for (unsigned i = 0; i < parameterNames.size(); i++)
{
std::string parameterName = parameterNames[i];

//Get the value from cell data
double parameterValue = mpCell->GetCellData()->GetItem(parameterName);

mpOdeSystem->SetParameter(parameterName, parameterValue);
}

std::vector<std::string> stateVariableNames = mpOdeSystem->rGetStateVariableNames();

for (unsigned i = 0; i < stateVariableNames.size(); i++)
{
std::string stateName = stateVariableNames[i];
double stateValue = mpOdeSystem->rGetStateVariables()[i];

//Set current state variable value as cell data
mpCell->GetCellData()->SetItem(stateName, stateValue);
}


// run the ODE simulation as needed
AbstractOdeSrnModel::SimulateToCurrentTime();


}

template<typename SBMLODE, unsigned SIZE>
void SbmlSrnWrapperModel<SBMLODE, SIZE>::Initialise()
{
AbstractOdeSrnModel::Initialise(new SBMLODE);

//Initialise cell data
assert(mpOdeSystem != NULL);
assert(mpCell != NULL);

/* Custom behaviour: store the state variables as cell data and set any parameters
* using cell data, so that we can visualise different concentrations in Paraview.
*/

std::vector<std::string> stateVariableNames = mpOdeSystem->rGetStateVariableNames();

for (unsigned i = 0; i < stateVariableNames.size(); i++)
{
std::string stateName = stateVariableNames[i];
double stateValue = mpOdeSystem->rGetStateVariables()[i];

//Set current state variable value as cell data
mpCell->GetCellData()->SetItem(stateName, stateValue);
}

}


template<typename SBMLODE, unsigned SIZE>
void SbmlSrnWrapperModel<SBMLODE, SIZE>::OutputSrnModelParameters(out_stream& rParamsFile)
{
// No new parameters to output.

// Call direct parent class
AbstractOdeSrnModel::OutputSrnModelParameters(rParamsFile);
}

template<typename SBMLODE, unsigned SIZE>
double SbmlSrnWrapperModel<SBMLODE, SIZE>::GetStateVariable(const std::string& rName)
{
assert(mpOdeSystem != nullptr);
return mpOdeSystem->GetStateVariable(rName);
}

#endif /* SBMLSRNWRAPPERMODEL_CPP_ */
Loading