Skip to content
Closed
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
31 changes: 27 additions & 4 deletions source/rrRoadRunner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,11 @@ namespace rr {

std::vector<SelectionRecord> mSelectionList;

/**
* the reaction rates of an output row, see getSelectedReactionRates
*/
std::vector<double> selectedReactionRates;

/**
* ModelGenerator obtained from the factory
*/
Expand Down Expand Up @@ -1410,16 +1415,31 @@ namespace rr {
return dResult;
}

double RoadRunner::getNthSelectedOutput(size_t index, double currentTime) {
double RoadRunner::getNthSelectedOutput(size_t index, double currentTime,
const double *reactionRates) {
const SelectionRecord &record = impl->mSelectionList[index];

if (record.selectionType == SelectionRecord::TIME) {
return currentTime;
} else if (reactionRates && record.selectionType == SelectionRecord::REACTION_RATE) {
return reactionRates[record.index];
} else {
return getValue(record);
}
}

const double *RoadRunner::getSelectedReactionRates() {
for (const SelectionRecord &record: impl->mSelectionList) {
if (record.selectionType == SelectionRecord::REACTION_RATE) {
std::vector<double> &rates = impl->selectedReactionRates;
rates.resize(impl->model->getNumReactions());
impl->model->getReactionRates(rates.size(), nullptr, rates.data());
return rates.data();
}
}
return nullptr;
}

int RoadRunner::getTimeRowIndex() {
for (u_int j = 0; j < impl->mSelectionList.size(); j++) {
const SelectionRecord &record = impl->mSelectionList[j];
Expand All @@ -1432,8 +1452,9 @@ namespace rr {
}

void RoadRunner::getSelectedValues(ls::DoubleMatrix &results, int nRow, double currentTime) {
const double *reactionRates = getSelectedReactionRates();
for (u_int j = 0; j < impl->mSelectionList.size(); j++) {
double out = getNthSelectedOutput(j, currentTime);
double out = getNthSelectedOutput(j, currentTime, reactionRates);
results(nRow, j) = out;
}
}
Expand All @@ -1443,9 +1464,10 @@ namespace rr {
assert(results.size() == impl->mSelectionList.size()
&& "given std::vector and selection list different size");

const double *reactionRates = getSelectedReactionRates();
size_t size = results.size();
for (size_t i = 0; i < size; ++i) {
results[i] = getNthSelectedOutput(i, currentTime);
results[i] = getNthSelectedOutput(i, currentTime, reactionRates);
}
}

Expand Down Expand Up @@ -5222,8 +5244,9 @@ namespace rr {
std::vector<double> result;
result.resize(impl->mSelectionList.size());

const double *reactionRates = getSelectedReactionRates();
for (int i = 0; i < impl->mSelectionList.size(); i++) {
result[i] = getNthSelectedOutput(i, impl->model->getTime());
result[i] = getNthSelectedOutput(i, impl->model->getTime(), reactionRates);
}
return result;
}
Expand Down
16 changes: 15 additions & 1 deletion source/rrRoadRunner.h
Original file line number Diff line number Diff line change
Expand Up @@ -1906,7 +1906,21 @@ namespace rr {
bool populateResult();


double getNthSelectedOutput(size_t index, double currentTime);
/**
* the value of the n'th selection, a reaction rate from reactionRates
* if given, see getSelectedReactionRates
*/
double getNthSelectedOutput(size_t index, double currentTime,
const double *reactionRates = nullptr);

/**
* Evaluates the reaction rates once for the selections of an output
* row and returns them, or nullptr if no reaction rate is selected.
* The rate of one reaction is evaluated with all reaction rates of the
* model, so reading every selected rate on its own made an output row
* quadratic in the number of reactions.
*/
const double *getSelectedReactionRates();

bool isParameterUsed(const std::string &sid);

Expand Down
25 changes: 25 additions & 0 deletions test/cxx_api_tests/RoadRunnerAPITests.h
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,31 @@ class RoadRunnerAPITests : public RoadRunnerTest {
delete testModel;
}

void getSelectedReactionRates() {
// the reaction rates of every output row are the ones of its state,
// also selected twice and between other selections
TestModel *testModel = TestModelFactory("SimpleFlux");
RoadRunner rr(testModel->str());
rr.setSelections({"time", "_J1", "[S1]", "_J0", "[S2]", "_J1"});
const ls::DoubleMatrix *result = rr.simulate(0, 10, 11);
ASSERT_EQ(result->numRows(), 11);
for (int i = 0; i < result->numRows(); ++i) {
const double s1 = (*result)(i, 2);
const double s2 = (*result)(i, 4);
EXPECT_DOUBLE_EQ((*result)(i, 1), 0.01 * s2);
EXPECT_DOUBLE_EQ((*result)(i, 3), 0.1 * s1);
EXPECT_DOUBLE_EQ((*result)(i, 5), 0.01 * s2);
}
// the last row is the state of the model at the end
std::vector<double> x = rr.getSelectedValues();
ASSERT_EQ(x.size(), 6);
EXPECT_EQ(x[1], rr.getValue("_J1"));
EXPECT_EQ(x[3], rr.getValue("_J0"));
EXPECT_EQ(x[5], rr.getValue("_J1"));
EXPECT_EQ(x[3], (*result)(10, 3));
delete testModel;
}

void getIndependentFloatingSpeciesIds() {
TestModel *testModel = TestModelFactory("SimpleFlux");
RoadRunner rr(testModel->str());
Expand Down
4 changes: 4 additions & 0 deletions test/cxx_api_tests/RoadRunnerAPITestsWithLLJit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,10 @@ TEST_F(RoadRunnerAPITestsWithLLJit, getSelectedValues){
getSelectedValues();
}

TEST_F(RoadRunnerAPITestsWithLLJit, getSelectedReactionRates){
getSelectedReactionRates();
}

TEST_F(RoadRunnerAPITestsWithLLJit, getIndependentFloatingSpeciesIds){
getIndependentFloatingSpeciesIds();
}
Expand Down
4 changes: 4 additions & 0 deletions test/cxx_api_tests/RoadRunnerAPITestsWithMCJit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,10 @@ TEST_F(RoadRunnerAPITestsWithMCJit, getSelectedValues){
getSelectedValues();
}

TEST_F(RoadRunnerAPITestsWithMCJit, getSelectedReactionRates){
getSelectedReactionRates();
}

TEST_F(RoadRunnerAPITestsWithMCJit, getIndependentFloatingSpeciesIds){
getIndependentFloatingSpeciesIds();
}
Expand Down
Loading