diff --git a/.travis/travis_build_linux.sh b/.travis/travis_build_linux.sh
index 3009af21b0f185f8dbe2760711cc4b5663ec6f5f..a4499d303dc96fd07a21d527e37421d26ee048c7 100755
--- a/.travis/travis_build_linux.sh
+++ b/.travis/travis_build_linux.sh
@@ -18,13 +18,13 @@
# REVISION: ---
#===============================================================================
-set -e -x
+set -e
+set -x
PYTHON2="/usr/bin/python2"
PYTHON3="/usr/bin/python3"
MAKEFLAGS="-j`nproc`"
-
if [ ! -n "$MAKE" ]; then
MAKE="make -j`nproc`"
else
@@ -42,34 +42,34 @@ if type $PYTHON3 > /dev/null; then $PYTHON3 -m compileall -q . ; fi
echo "Currently in `pwd`"
(
- mkdir -p _GSL_BUILD && cd _GSL_BUILD
+ mkdir -p _GSL_BUILD && cd _GSL_BUILD
cmake -DDEBUG=ON -DPYTHON_EXECUTABLE="$PYTHON2" ..
- $MAKE && ctest --output-on-failure
- sudo make install
+ $MAKE && ctest --output-on-failure -j4
+ sudo make install && cd /tmp
$PYTHON2 -c 'import moose;print(moose.__file__);print(moose.version())'
)
(
# Now with boost.
mkdir -p _BOOST_BUILD && cd _BOOST_BUILD && \
- cmake -DWITH_BOOST=ON -DDEBUG=ON -DQUIET_MODE=ON -DPYTHON_EXECUTABLE="$PYTHON2" ..
- $MAKE && ctest --output-on-failure
+ cmake -DWITH_BOOST_ODE=ON -DDEBUG=ON -DPYTHON_EXECUTABLE="$PYTHON2" ..
+ $MAKE && ctest --output-on-failure -j4
)
# This is only applicable on linux build.
echo "Python3: Removed python2-networkx and install python3"
if type $PYTHON3 > /dev/null; then
- sudo apt-get remove -qq python-networkx
- sudo apt-get install -qq python3-networkx
+ sudo apt-get remove -qq python-networkx || echo "Error with apt"
+ sudo apt-get install -qq python3-networkx || echo "Error with apt"
(
mkdir -p _GSL_BUILD2 && cd _GSL_BUILD2 && \
cmake -DDEBUG=ON -DPYTHON_EXECUTABLE="$PYTHON3" ..
- $MAKE && ctest --output-on-failure
+ $MAKE && ctest --output-on-failure -j4
)
(
mkdir -p _BOOST_BUILD2 && cd _BOOST_BUILD2 && \
- cmake -DWITH_BOOST=ON -DDEBUG=ON -DPYTHON_EXECUTABLE="$PYTHON3" ..
- $MAKE && ctest --output-on-failure
+ cmake -DWITH_BOOST_ODE=ON -DDEBUG=ON -DPYTHON_EXECUTABLE="$PYTHON3" ..
+ $MAKE && ctest --output-on-failure -j4
)
echo "All done"
else
diff --git a/.travis/travis_build_osx.sh b/.travis/travis_build_osx.sh
index 0b446a202543a7f70409f51397ab44c10a172f7f..814f6af5293a05be09313b8cbf01ed1ca4245dbc 100755
--- a/.travis/travis_build_osx.sh
+++ b/.travis/travis_build_osx.sh
@@ -20,21 +20,23 @@
set -o nounset # Treat unset variables as an error
set -e
+# NOTE: On travis, don't enable -j`nproc` option. It may not compile properly.
+
(
# Make sure not to pick up python from /opt.
PATH=/usr/bin:/usr/local/bin:$PATH
mkdir -p _GSL_BUILD && cd _GSL_BUILD \
- && cmake -DQUIET_MODE=ON -DDEBUG=ON \
+ && cmake -DDEBUG=ON \
-DPYTHON_EXECUTABLE=`which python` ..
- make -j3 && ctest --output-on-failure
+ make && ctest --output-on-failure
cd .. # Now with boost.
mkdir -p _BOOST_BUILD && cd _BOOST_BUILD \
- && cmake -DWITH_BOOST=ON -DDEBUG=ON \
+ && cmake -DWITH_BOOST_ODE=ON -DDEBUG=ON \
-DPYTHON_EXECUTABLE=`which python` ..
- make -j3 && ctest --output-on-failure
+ make && ctest --output-on-failure
cd ..
set +e
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000000000000000000000000000000000000..565695af709d18d0db50b9bd0e1662ddcd5e30aa
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,17 @@
+# Active developers
+
+Upinder S. Bhalla Primary Architect, rdesigneur
+HarshaRani. G.V MOOSE Website, SBML support, GUI
+Dilawar Singh Multithreading, GSoC, Packaging, Maintenance, BOOST solvers
+
+# Past developers
+
+Subhasis Ray Python interface, GUI
+Niraj Dudani Neuronal solver
+Aditya Gilra NeuroML support
+Aviral Goel Moogli
+
+# Contributors
+
+Padraid Gleeson NeuroML2 support
+Dharma Teja GPU parallelization using CUDA
diff --git a/AUTHROS b/AUTHROS
deleted file mode 100644
index f568c742ebe5fc90330f250c3c5e035224fed581..0000000000000000000000000000000000000000
--- a/AUTHROS
+++ /dev/null
@@ -1,9 +0,0 @@
-Upinder S. Bhalla Primary Architect
-Niraj Dudani Neuronal solver
-Subhasis Ray Python interface
-Aditya Gilra NeuroML support
-Aviral Goel Moogli
-HarshaRani. G.V Designing of Website,read and write SBML and
- Graphical User Interface for moose
-Dilawar Singh Packaging, BOOST solvers
-Dharma Teja GPU parallelization using CUDA
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bd6aaf84449898d713efba60273018fa55b0bf0d..59977a0fa04ab1929aba24b7b7d8b56fbeb9f298 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,18 +1,6 @@
-set(CMAKE_LEGACY_CYGWIN_WIN32 0)
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
-
-
project(pymoose)
-if(COMMAND cmake_policy)
- cmake_policy(SET CMP0003 NEW)
- cmake_policy(SET CMP0004 NEW)
- if(POLICY CMP0050)
- cmake_policy(SET CMP0050 OLD)
- endif(POLICY CMP0050)
-endif(COMMAND cmake_policy)
-
-
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules")
include(CheckCXXCompiler.cmake)
include(CheckIncludeFileCXX)
@@ -88,22 +76,24 @@ else()
endif()
################################ CMAKE OPTIONS ##################################
-option(DEBUG "Build with debug support" OFF)
-option(GPROF "Build for profiling using gprof" OFF)
-option(ENABLE_UNIT_TESTS "Enable unit tests (DEBUG should also be ON)" OFF)
-option(WITH_MPI "Enable Openmpi support" OFF)
-option(WITH_BOOST "Use boost library instead of GSL" OFF)
-option(WITH_GSL "Use gsl-library. Alternative is WITH_BOOST" ON)
+option(DEBUG "Build with debug support" OFF)
+option(GPROF "Build for profiling using gprof" OFF)
+option(ENABLE_UNIT_TESTS "Enable unit tests (DEBUG should also be ON)" OFF)
+option(WITH_MPI "Enable Openmpi support" OFF)
+option(WITH_BOOST_ODE "Use boost library ode2 library instead of GSL" OFF)
+option(WITH_GSL "Use gsl-library. Alternative is WITH_BOOST" ON)
option(PARALLELIZED_SOLVERS "Use parallel version of GSOLVE. (alpha)" OFF )
-option(PARALLELIZED_CLOCK "High level parallelization of moose::Clock (alpha)" OFF )
+option(PARALLELIZED_CLOCK "High level parallelization of moose::Clock (alpha)" OFF )
+
+option(USE_PRIVATE_RNG "Stochastic Objects use their private RNG" ON)
############################ BUILD CONFIGURATION #################################
-# Default macros
+# Default definitions.
add_definitions(-DUSE_GENESIS_PARSER)
-if(DEBUG)
+if(DEBUG OR "${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
message(STATUS "Building for Debug/Unit testing")
add_definitions(-DDO_UNIT_TESTS)
set(CMAKE_BUILD_TYPE Debug)
@@ -114,15 +104,22 @@ elseif(ENABLE_UNIT_TESTS)
else()
message(STATUS "Building for Release/No unit tests.")
set(CMAKE_BUILD_TYPE Release)
- add_definitions(-UDO_UNIT_TESTS -DQUIET_MODE -O3)
+ add_definitions(-UDO_UNIT_TESTS -O3 -DDISABLE_DEBUG)
+ # Treat all warnings as errors. Some the warnings are disabled in
+ # CheckCXXCompiler.cmake .
+ add_definitions(-Werror)
endif()
-if(GPROF AND DEBUG)
+if(GPROF AND "${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
message(STATUS "Compiling with profiling with gprof")
add_definitions(-pg)
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "-pg")
endif()
+if(PARALLELIZED_SOLVERS)
+ find_package(Threads)
+endif()
+
################################### TARGETS ####################################
@@ -134,9 +131,10 @@ add_executable(moose.bin basecode/main.cpp)
# default include paths.
include_directories( ${CMAKE_CURRENT_SOURCE_DIR} )
-if(WITH_BOOST)
+# If using BOOST ODE2 library to solve ODE system, then don't use GSL.
+if(WITH_BOOST_ODE)
set(WITH_GSL OFF)
-endif(WITH_BOOST)
+endif(WITH_BOOST_ODE)
include_directories(msg basecode)
@@ -148,6 +146,12 @@ set(STATIC_LIBRARIES "" )
# Collect all shared libraries here.
set(SYSTEM_SHARED_LIBS ${LibXML2_LIBRARIES})
+# BOOST ode library performs better than GSL and ideally should be made default.
+# Making boost default means that we get rid of gsl. Boost does not have a very
+# good matrix library; it has ublas which is not well maintained and emit a lot
+# of warning during compilation. Nonetheless, WITH_BOOST_ODE works fine and
+# produce results quicker than GSL. Both boost ode and ublas are in moose source
+# tree ./external/odeint-v2 and ./external/boost-numeric-bindings
if(WITH_GSL)
find_package(GSL 1.16 REQUIRED)
if(NOT GSL_FOUND)
@@ -171,18 +175,14 @@ if(WITH_GSL)
# GSL is also used in RNG (whenever applicable), therefore include paths are
# top level.
include_directories( ${GSL_INCLUDE_DIRS} )
-elseif(WITH_BOOST)
- find_package(Boost 1.44 COMPONENTS system filesystem random REQUIRED)
+elseif(WITH_BOOST_ODE)
+ find_package(Boost 1.44 REQUIRED)
find_package( LAPACK REQUIRED )
- add_definitions( -DUSE_BOOST -UUSE_GSL )
- include_directories( ${Boost_INCLUDE_DIRS} )
- check_include_file_cxx(
- ${Boost_INCLUDE_DIRS}/boost/random/random_device.hpp
- BOOST_RANDOM_DEVICE_EXISTS
- )
- if(BOOST_RANDOM_DEVICE_EXISTS)
- add_definitions(-DBOOST_RANDOM_DEVICE_EXISTS)
- endif(BOOST_RANDOM_DEVICE_EXISTS)
+endif()
+
+# if boost ode is being used, don't use GSL.
+if(WITH_BOOST_ODE)
+ add_definitions(-DUSE_BOOST_ODE -UUSE_GSL)
endif()
@@ -264,10 +264,14 @@ if(WITH_MPI)
endif()
endif(WITH_MPI)
-if(WITH_BOOST)
+if(WITH_BOOST_ODE)
list(APPEND SYSTEM_SHARED_LIBS ${LAPACK_LIBRARIES})
list(APPEND SYSTEM_SHARED_LIBS ${Boost_LIBRARIES})
-endif(WITH_BOOST)
+endif(WITH_BOOST_ODE)
+
+if(PARALLELIZED_SOLVERS)
+ list(APPEND SYSTEM_SHARED_LIBS ${CMAKE_THREAD_LIBS_INIT})
+endif()
# These libraries could be static of dynamic. We need to discrimate between
# these two types because of --whole-archive option. See
@@ -330,7 +334,6 @@ list(APPEND MOOSE_LIBRARIES
msg
benchmarks
shell
- randnum
scheduling
moose_mpi
biophysics
@@ -483,13 +486,13 @@ include( CTest )
# onto the console if a test fails.
set(ENV{CTEST_OUTPUT_ON_FAILURE} ON)
-if(DEBUG)
+if(DEBUG OR "${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
# Run this test in debug mode. In Release mode, this does not do anything.
set(MOOSE_BIN_LOCATION $<TARGET_FILE:moose.bin>)
message(STATUS "Executable moose.bin will be at ${MOOSE_BIN_LOCATION}" )
add_test(NAME moose.bin-raw-run COMMAND moose.bin -u -q)
-endif(DEBUG)
+endif()
## PyMOOSE tests.
set(PYMOOSE_TEST_DIRECTORY ${CMAKE_SOURCE_DIR}/tests/python)
diff --git a/CheckCXXCompiler.cmake b/CheckCXXCompiler.cmake
index 92fbfdfa3c57c433baf213930c59c61300b088a7..f3fe24d921de0a6220fa427c91c02e9a37ac26dd 100644
--- a/CheckCXXCompiler.cmake
+++ b/CheckCXXCompiler.cmake
@@ -5,15 +5,17 @@ CHECK_CXX_COMPILER_FLAG( "-std=c++11" COMPILER_SUPPORTS_CXX11 )
CHECK_CXX_COMPILER_FLAG( "-std=c++0x" COMPILER_SUPPORTS_CXX0X )
CHECK_CXX_COMPILER_FLAG( "-Wno-strict-aliasing" COMPILER_WARNS_STRICT_ALIASING )
-
# Turn warning to error: Not all of the options may be supported on all
# versions of compilers. be careful here.
add_definitions(-Wall
#-Wno-return-type-c-linkage
- -Wno-unused-variable
+ -Wno-unused-variable
-Wno-unused-function
+ -Wno-unused-local-typedefs
#-Wno-unused-private-field
)
+
+
add_definitions(-fPIC)
if(COMPILER_WARNS_STRICT_ALIASING)
add_definitions( -Wno-strict-aliasing )
@@ -32,7 +34,9 @@ if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
add_definitions( -DENABLE_CPP11 )
if(APPLE)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++" )
+ #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++" )
+ message(STATUS "NOTE: Making clang to inline more aggresively" )
+ add_definitions( -mllvm -inline-threshold=1000 )
endif(APPLE)
else(COMPILER_SUPPORTS_CXX11)
add_definitions( -DBOOST_NO_CXX11_SCOPED_ENUMS -DBOOST_NO_SCOPED_ENUMS )
diff --git a/MANIFEST.in b/MANIFEST.in
deleted file mode 100644
index 8572af5e481e05ddbd78e81fcbf38f61d5a6f8c4..0000000000000000000000000000000000000000
--- a/MANIFEST.in
+++ /dev/null
@@ -1,15 +0,0 @@
-global-include *.h
-global-include *.cpp
-global-include *.c
-global-include configure.ac
-global-include *.hpp
-global-include *.cc
-global-include *.py
-global-include CMakeLists.txt
-include README
-graft cmake_modules
-graft gsl
-graft external
-graft Demos
-graft Docs
-prune buildMooseUsingCmake
diff --git a/README.md b/README.md
index dd8e63621de6d0da31186fdb10fd7f940c15e276..6e5ed75a7f0ca38b0fe1b561ee92a733fef38796 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[](https://travis-ci.org/BhallaLab/moose-core) | [](https://badge.fury.io/py/pymoose)
+[](https://travis-ci.org/BhallaLab/moose-core) | [](https://badge.fury.io/py/pymoose) | [Nightly Linux Build on OBS](https://software.opensuse.org//download.html?project=home%3Amoose&package=pymoose)
This is the core computational engine of [MOOSE simulator](https://github.com/BhallaLab/moose). This repository contains
C++ codebase and python interface called `pymoose`. For more details about MOOSE simulator, visit https://moose.ncbs.res.in .
diff --git a/basecode/Id.h b/basecode/Id.h
index 9aed5e9beac5e6cf1b7ac6b57317d1c00da827db..1b877e0b3812fb3e560717564b906caff3964774 100644
--- a/basecode/Id.h
+++ b/basecode/Id.h
@@ -174,13 +174,19 @@ private:
static vector< Element* >& elements();
};
-namespace std {
- template <> class hash<Id>{
- public :
- size_t operator()(const Id &x ) const{
- return hash<unsigned int>()( x.value() );
- }
- };
+// User defined hash function.
+// See https://en.cppreference.com/w/cpp/utility/hash for more details.
+namespace std
+{
+ template <>
+ struct hash<Id>
+ {
+ public :
+ size_t operator()(const Id &x ) const
+ {
+ return std::hash<unsigned int>()( x.value() );
+ }
+ };
}
#endif // _ID_H
diff --git a/basecode/SparseMatrix.cpp b/basecode/SparseMatrix.cpp
index b5d2acc47c27de48beeb443c553951741bad3bdf..0f1de408479f812331e7cd4cec509fa34bca5d36 100644
--- a/basecode/SparseMatrix.cpp
+++ b/basecode/SparseMatrix.cpp
@@ -8,8 +8,6 @@
** See the file COPYING.LIB for the full notice.
**********************************************************************/
-using namespace std;
-
#include <algorithm>
#include <vector>
#include <map>
@@ -17,6 +15,8 @@ using namespace std;
#include <iostream>
#include "SparseMatrix.h"
+using namespace std;
+
const unsigned int SM_MAX_ROWS = 200000;
const unsigned int SM_MAX_COLUMNS = 200000;
diff --git a/basecode/global.cpp b/basecode/global.cpp
index 09ebeaa300be9dc29178ca89533ba62c242d773c..90f82b6ba10d09363c762824c22445af309a3bb1 100644
--- a/basecode/global.cpp
+++ b/basecode/global.cpp
@@ -40,10 +40,9 @@ extern string joinPath( string pathA, string pathB);
extern string fixPath( string path);
extern string dumpStats( int );
-
namespace moose {
- int __rng_seed__ = 0;
+ unsigned long __rng_seed__ = 0;
moose::RNG<double> rng;
@@ -131,29 +130,13 @@ namespace moose {
p = p.substr( 0, pos );
else /* no parent directory to create */
return true;
+
if( p.size() == 0 )
return true;
-#ifdef USE_BOOST
- try
- {
- boost::filesystem::path pdirs( p );
- boost::filesystem::create_directories( pdirs );
- LOG( moose::info, "Created directory " << p );
- return true;
- }
- catch(const boost::filesystem::filesystem_error& e)
- {
- LOG( moose::warning, "create_directories(" << p << ") failed with "
- << e.code().message()
- );
- return false;
- }
-#else /* ----- not USE_BOOST ----- */
string command( "mkdir -p ");
command += p;
int ret = system( command.c_str() );
- cout << "+ Return code " << ret << endl;
struct stat info;
if( stat( p.c_str(), &info ) != 0 )
{
@@ -170,7 +153,6 @@ namespace moose {
LOG( moose::warning, p << " is no directory" );
return false;
}
-#endif /* ----- not USE_BOOST ----- */
return true;
}
@@ -221,4 +203,13 @@ namespace moose {
return string( buffer );
}
+ int getGlobalSeed( )
+ {
+ return __rng_seed__;
+ }
+
+ void setGlobalSeed( int seed )
+ {
+ __rng_seed__ = seed;
+ }
}
diff --git a/basecode/global.h b/basecode/global.h
index 761a310f89f73cf6b4499a559ad3c206191fb78e..1735595d9a203fdcddb98f510f11ef107eaa8385 100644
--- a/basecode/global.h
+++ b/basecode/global.h
@@ -16,14 +16,7 @@
#include <map>
#include <sstream>
-
-#ifdef USE_BOOST
-//#ifdef BOOST_FILESYSTEM_EXISTS
-#include <boost/filesystem.hpp>
-//#endif /* BOOST_FILESYSTEM_EXISTS */
-#endif
-
-#include "randnum/RNG.h" /* Use inbuilt rng */
+#include "../randnum/RNG.h" /* Use inbuilt rng */
#include "../utility/print_function.hpp"
using namespace std;
@@ -70,7 +63,7 @@ namespace moose
* initialize them. By default it is initialized by random_device (see
* global.cpp).
*/
- extern int __rng_seed__;
+ extern unsigned long __rng_seed__;
/**
* @brief Fix a path. For testing purpose.
@@ -183,6 +176,24 @@ namespace moose
*/
string moosePathToUserPath( string path );
+ /* --------------------------------------------------------------------------*/
+ /**
+ * @Synopsis Get the global seed set by call of moose.seed( X )
+ *
+ * @Returns seed (int).
+ */
+ /* ----------------------------------------------------------------------------*/
+ int getGlobalSeed( );
+
+ /* --------------------------------------------------------------------------*/
+ /**
+ * @Synopsis Set the seed for all random generator. When seed of a RNG is
+ * not set, this seed it used. It is set to -1 by default.
+ *
+ * @Param seed
+ */
+ /* ----------------------------------------------------------------------------*/
+ void setGlobalSeed( int seed );
}
#endif /* ----- #ifndef __MOOSE_GLOBAL_INC_ ----- */
diff --git a/basecode/main.cpp b/basecode/main.cpp
index d6b2822623007c0be89094ddf507b56e8d113e8b..cde0f33dc9292430bd7c23ec4b237cc28d54935e 100644
--- a/basecode/main.cpp
+++ b/basecode/main.cpp
@@ -8,6 +8,7 @@
**********************************************************************/
#include "header.h"
+#include "SparseMatrix.h"
#ifndef WIN32
#include <sys/time.h>
@@ -22,9 +23,8 @@
#include <unistd.h> // for getopt
#endif
#include "../scheduling/Clock.h"
-#include "DiagonalMsg.h"
-#include "SparseMatrix.h"
-#include "SparseMsg.h"
+#include "../msg/DiagonalMsg.h"
+#include "../msg/SparseMsg.h"
#include "../mpi/PostMaster.h"
#ifdef USE_MPI
#include <mpi.h>
diff --git a/basecode/testAsync.cpp b/basecode/testAsync.cpp
index b615611b9f62ab724b91141796a7669086d85965..3ba2b25057b17eabdc55e334670324713eb1beb6 100644
--- a/basecode/testAsync.cpp
+++ b/basecode/testAsync.cpp
@@ -6,47 +6,36 @@
** GNU Lesser General Public License version 2.1
** See the file COPYING.LIB for the full notice.
**********************************************************************/
+#include <stdio.h>
+#include <iomanip>
#include "header.h"
#include "global.h"
-
-#include <stdio.h>
-#include <iomanip>
-#include "../shell/Neutral.h"
-#include "../builtins/Arith.h"
#include "Dinfo.h"
-#include <queue>
-#include "../biophysics/IntFire.h"
+#include "SparseMatrix.h"
+
+#include "../msg/OneToOneMsg.h"
+#include "../msg/SparseMsg.h"
+#include "../msg/SingleMsg.h"
+
#include "../synapse/Synapse.h"
#include "../synapse/SynEvent.h"
#include "../synapse/SynHandlerBase.h"
#include "../synapse/SimpleSynHandler.h"
-#include "SparseMatrix.h"
-#include "SparseMsg.h"
-#include "SingleMsg.h"
-#include "OneToOneMsg.h"
-#include "../scheduling/Clock.h"
#include "../shell/Shell.h"
+#include "../shell/Neutral.h"
+
#include "../mpi/PostMaster.h"
+#include "../scheduling/Clock.h"
+#include "../builtins/Arith.h"
+#include "../biophysics/IntFire.h"
+#include "../randnum/RNG.h"
-#include "randnum/RNG.h"
+#include <queue>
int _seed_ = 0;
-moose::RNG<double> rng_;
-
-void _mtseed_( unsigned int seed )
-{
- _seed_ = seed;
- rng_.setSeed( _seed_ );
-}
-
-double _mtrand_( )
-{
- return rng_.uniform( );
-}
-
void showFields()
{
const Cinfo* nc = Neutral::initCinfo();
@@ -818,7 +807,8 @@ void testSparseMsg()
string arg;
- _mtseed_( 5489UL ); // The default value, but better to be explicit.
+ // The default value, but better to be explicit.
+ moose::setGlobalSeed( 5489UL );
Id sshid = Id::nextId();
Element* t2 = new GlobalDataElement( sshid, sshc, "test2", size );
@@ -838,7 +828,7 @@ void testSparseMsg()
vector< double > temp( size, 0.0 );
for ( unsigned int i = 0; i < size; ++i )
- temp[i] = _mtrand_() * Vmax;
+ temp[i] = moose::mtrand() * Vmax;
bool ret = Field< double >::setVec( cells, "Vm", temp );
assert( ret );
@@ -860,8 +850,8 @@ void testSparseMsg()
Field< unsigned int >::get( id, "numSynapse" );
unsigned int k = i * fieldSize;
for ( unsigned int j = 0; j < numSyn; ++j ) {
- weight[ k + j ] = _mtrand_() * weightMax;
- delay[ k + j ] = _mtrand_() * delayMax;
+ weight[ k + j ] = moose::mtrand() * weightMax;
+ delay[ k + j ] = moose::mtrand() * delayMax;
}
}
ret = Field< double >::setVec( syns, "weight", weight );
diff --git a/biophysics/Compartment.cpp b/biophysics/Compartment.cpp
index dda3ee47cfe3645a4a9efc3df895b4d9ad7f58ea..8a137df7d39497e5ef7b0d967a59076983751c14 100644
--- a/biophysics/Compartment.cpp
+++ b/biophysics/Compartment.cpp
@@ -7,8 +7,8 @@
** See the file COPYING.LIB for the full notice.
**********************************************************************/
-#include "header.h"
-#include "../randnum/randnum.h"
+#include "../basecode/header.h"
+#include "../basecode/global.h"
#include "CompartmentBase.h"
#include "Compartment.h"
@@ -25,29 +25,29 @@ const double Compartment::EPSILON = 1.0e-15;
*/
const Cinfo* Compartment::initCinfo()
{
- ///////////////////////////////////////////////////////////////////
- // static Finfo* compartmentFinfos[] = { };
-
- static string doc[] =
- {
- "Name", "Compartment",
- "Author", "Upi Bhalla",
- "Description", "Compartment object, for branching neuron models.",
- };
+ ///////////////////////////////////////////////////////////////////
+ // static Finfo* compartmentFinfos[] = { };
+
+ static string doc[] =
+ {
+ "Name", "Compartment",
+ "Author", "Upi Bhalla",
+ "Description", "Compartment object, for branching neuron models.",
+ };
static Dinfo< Compartment > dinfo;
- static Cinfo compartmentCinfo(
- "Compartment",
- CompartmentBase::initCinfo(),
- 0,
- 0,
- // compartmentFinfos,
- // sizeof( compartmentFinfos ) / sizeof( Finfo* ),
- &dinfo,
- doc,
- sizeof(doc)/sizeof(string)
- );
-
- return &compartmentCinfo;
+ static Cinfo compartmentCinfo(
+ "Compartment",
+ CompartmentBase::initCinfo(),
+ 0,
+ 0,
+ // compartmentFinfos,
+ // sizeof( compartmentFinfos ) / sizeof( Finfo* ),
+ &dinfo,
+ doc,
+ sizeof(doc)/sizeof(string)
+ );
+
+ return &compartmentCinfo;
}
static const Cinfo* compartmentCinfo = Compartment::initCinfo();
@@ -60,12 +60,12 @@ const SrcFinfo1< double >* VmOut =
*/
const SrcFinfo1< double >* axialOut =
- dynamic_cast< const SrcFinfo1< double >* > (
- compartmentCinfo->findFinfo( "axialOut" ) );
+ dynamic_cast< const SrcFinfo1< double >* > (
+ compartmentCinfo->findFinfo( "axialOut" ) );
const SrcFinfo2< double, double >* raxialOut =
- dynamic_cast< const SrcFinfo2< double, double >* > (
- compartmentCinfo->findFinfo( "raxialOut" ) );
+ dynamic_cast< const SrcFinfo2< double, double >* > (
+ compartmentCinfo->findFinfo( "raxialOut" ) );
//////////////////////////////////////////////////////////////////
// Here we put the Compartment class functions.
@@ -73,104 +73,104 @@ const SrcFinfo2< double, double >* raxialOut =
Compartment::Compartment()
{
- Vm_ = -0.06;
- Em_ = -0.06;
- Cm_ = 1.0;
- Rm_ = 1.0;
- invRm_ = 1.0;
- Ra_ = 1.0;
- Im_ = 0.0;
+ Vm_ = -0.06;
+ Em_ = -0.06;
+ Cm_ = 1.0;
+ Rm_ = 1.0;
+ invRm_ = 1.0;
+ Ra_ = 1.0;
+ Im_ = 0.0;
lastIm_ = 0.0;
- inject_ = 0.0;
- sumInject_ = 0.0;
- initVm_ = -0.06;
- A_ = 0.0;
- B_ = 0.0;
+ inject_ = 0.0;
+ sumInject_ = 0.0;
+ initVm_ = -0.06;
+ A_ = 0.0;
+ B_ = 0.0;
}
Compartment::~Compartment()
{
- ;
+ ;
}
// Value Field access function definitions.
void Compartment::vSetVm( const Eref& e, double Vm )
{
- Vm_ = Vm;
+ Vm_ = Vm;
}
double Compartment::vGetVm( const Eref& e ) const
{
- return Vm_;
+ return Vm_;
}
void Compartment::vSetEm( const Eref& e, double Em )
{
- Em_ = Em;
+ Em_ = Em;
}
double Compartment::vGetEm( const Eref& e ) const
{
- return Em_;
+ return Em_;
}
void Compartment::vSetCm( const Eref& e, double Cm )
{
- if ( rangeWarning( "Cm", Cm ) ) return;
- Cm_ = Cm;
+ if ( rangeWarning( "Cm", Cm ) ) return;
+ Cm_ = Cm;
}
double Compartment::vGetCm( const Eref& e ) const
{
- return Cm_;
+ return Cm_;
}
void Compartment::vSetRm( const Eref& e, double Rm )
{
- if ( rangeWarning( "Rm", Rm ) ) return;
- Rm_ = Rm;
- invRm_ = 1.0/Rm;
+ if ( rangeWarning( "Rm", Rm ) ) return;
+ Rm_ = Rm;
+ invRm_ = 1.0/Rm;
}
double Compartment::vGetRm( const Eref& e ) const
{
- return Rm_;
+ return Rm_;
}
void Compartment::vSetRa( const Eref& e, double Ra )
{
- if ( rangeWarning( "Ra", Ra ) ) return;
- Ra_ = Ra;
+ if ( rangeWarning( "Ra", Ra ) ) return;
+ Ra_ = Ra;
}
double Compartment::vGetRa( const Eref& e ) const
{
- return Ra_;
+ return Ra_;
}
double Compartment::vGetIm( const Eref& e ) const
{
- return lastIm_;
+ return lastIm_;
}
void Compartment::vSetInject( const Eref& e, double inject )
{
- inject_ = inject;
+ inject_ = inject;
}
double Compartment::vGetInject( const Eref& e ) const
{
- return inject_;
+ return inject_;
}
void Compartment::vSetInitVm( const Eref& e, double initVm )
{
- initVm_ = initVm;
+ initVm_ = initVm;
}
double Compartment::vGetInitVm( const Eref& e ) const
{
- return initVm_;
+ return initVm_;
}
@@ -180,84 +180,88 @@ double Compartment::vGetInitVm( const Eref& e ) const
void Compartment::vProcess( const Eref& e, ProcPtr p )
{
- //cout << "Compartment " << e.id().path() << ":: process: A = " << A_ << ", B = " << B_ << endl;
- A_ += inject_ + sumInject_ + Em_ * invRm_;
- if ( B_ > EPSILON ) {
- double x = exp( -B_ * p->dt / Cm_ );
- Vm_ = Vm_ * x + ( A_ / B_ ) * ( 1.0 - x );
- } else {
- Vm_ += ( A_ - Vm_ * B_ ) * p->dt / Cm_;
- }
- A_ = 0.0;
- B_ = invRm_;
- lastIm_ = Im_;
- Im_ = 0.0;
- sumInject_ = 0.0;
- // Send out Vm to channels, SpikeGens, etc.
- VmOut()->send( e, Vm_ );
-
- // The axial/raxial messages go out in the 'init' phase.
+ //cout << "Compartment " << e.id().path() << ":: process: A = " << A_ << ", B = " << B_ << endl;
+ A_ += inject_ + sumInject_ + Em_ * invRm_;
+ if ( B_ > EPSILON )
+ {
+ double x = exp( -B_ * p->dt / Cm_ );
+ Vm_ = Vm_ * x + ( A_ / B_ ) * ( 1.0 - x );
+ }
+ else
+ {
+ Vm_ += ( A_ - Vm_ * B_ ) * p->dt / Cm_;
+ }
+ A_ = 0.0;
+ B_ = invRm_;
+ lastIm_ = Im_;
+ Im_ = 0.0;
+ sumInject_ = 0.0;
+ // Send out Vm to channels, SpikeGens, etc.
+ VmOut()->send( e, Vm_ );
+
+ // The axial/raxial messages go out in the 'init' phase.
}
void Compartment::vReinit( const Eref& e, ProcPtr p )
{
- Vm_ = initVm_;
- A_ = 0.0;
- B_ = invRm_;
- Im_ = 0.0;
- lastIm_ = 0.0;
- sumInject_ = 0.0;
- dt_ = p->dt;
-
- // Send out the resting Vm to channels, SpikeGens, etc.
- VmOut()->send( e, Vm_ );
+ Vm_ = initVm_;
+ A_ = 0.0;
+ B_ = invRm_;
+ Im_ = 0.0;
+ lastIm_ = 0.0;
+ sumInject_ = 0.0;
+ dt_ = p->dt;
+
+ // Send out the resting Vm to channels, SpikeGens, etc.
+ VmOut()->send( e, Vm_ );
}
void Compartment::vInitProc( const Eref& e, ProcPtr p )
{
- // Send out the axial messages
- axialOut->send( e, Vm_ );
- // Send out the raxial messages
- raxialOut->send( e, Ra_, Vm_ );
+ // Send out the axial messages
+ axialOut->send( e, Vm_ );
+ // Send out the raxial messages
+ raxialOut->send( e, Ra_, Vm_ );
}
void Compartment::vInitReinit( const Eref& e, ProcPtr p )
{
- ; // Nothing happens here
+ ; // Nothing happens here
}
void Compartment::vHandleChannel( const Eref& e, double Gk, double Ek)
{
- A_ += Gk * Ek;
- B_ += Gk;
+ A_ += Gk * Ek;
+ B_ += Gk;
}
void Compartment::vHandleRaxial( double Ra, double Vm)
{
- A_ += Vm / Ra;
- B_ += 1.0 / Ra;
- Im_ += ( Vm - Vm_ ) / Ra;
+ A_ += Vm / Ra;
+ B_ += 1.0 / Ra;
+ Im_ += ( Vm - Vm_ ) / Ra;
}
void Compartment::vHandleAxial( double Vm)
{
- A_ += Vm / Ra_;
- B_ += 1.0 / Ra_;
- Im_ += ( Vm - Vm_ ) / Ra_;
+ A_ += Vm / Ra_;
+ B_ += 1.0 / Ra_;
+ Im_ += ( Vm - Vm_ ) / Ra_;
}
void Compartment::vInjectMsg( const Eref& e, double current)
{
- sumInject_ += current;
- Im_ += current;
+ sumInject_ += current;
+ Im_ += current;
}
void Compartment::vRandInject( const Eref& e, double prob, double current)
{
- if ( mtrand() < prob * dt_ ) {
- sumInject_ += current;
- Im_ += current;
- }
+ if ( moose::mtrand() < prob * dt_ )
+ {
+ sumInject_ += current;
+ Im_ += current;
+ }
}
/////////////////////////////////////////////////////////////////////
@@ -270,39 +274,39 @@ void Compartment::vRandInject( const Eref& e, double prob, double current)
void testCompartment()
{
- unsigned int size = 1;
- Eref sheller( Id().eref() );
- Shell* shell = reinterpret_cast< Shell* >( sheller.data() );
- Id comptId = shell->doCreate("Compartment", Id(), "compt", size);
- assert( Id::isValid(comptId));
- Eref compter = comptId.eref();
- Compartment* c = reinterpret_cast< Compartment* >( comptId.eref().data() );
- ProcInfo p;
- p.dt = 0.002;
- c->setInject( compter, 1.0 );
- c->setRm( compter, 1.0 );
- c->setRa( compter, 0.0025 );
- c->setCm( compter, 1.0 );
- c->setEm( compter, 0.0 );
- c->setVm( compter, 0.0 );
-
- // First, test charging curve for a single compartment
- // We want our charging curve to be a nice simple exponential
- // Vm = 1.0 - 1.0 * exp( - t / 1.0 );
- double delta = 0.0;
- double Vm = 0.0;
- double tau = 1.0;
- double Vmax = 1.0;
- for ( p.currTime = 0.0; p.currTime < 2.0; p.currTime += p.dt )
- {
- Vm = c->getVm( compter );
- double x = Vmax - Vmax * exp( -p.currTime / tau );
- delta += ( Vm - x ) * ( Vm - x );
- c->process( compter, &p );
- }
- assert( delta < 1.0e-6 );
- shell->doDelete(comptId);
- cout << "." << flush;
+ unsigned int size = 1;
+ Eref sheller( Id().eref() );
+ Shell* shell = reinterpret_cast< Shell* >( sheller.data() );
+ Id comptId = shell->doCreate("Compartment", Id(), "compt", size);
+ assert( Id::isValid(comptId));
+ Eref compter = comptId.eref();
+ Compartment* c = reinterpret_cast< Compartment* >( comptId.eref().data() );
+ ProcInfo p;
+ p.dt = 0.002;
+ c->setInject( compter, 1.0 );
+ c->setRm( compter, 1.0 );
+ c->setRa( compter, 0.0025 );
+ c->setCm( compter, 1.0 );
+ c->setEm( compter, 0.0 );
+ c->setVm( compter, 0.0 );
+
+ // First, test charging curve for a single compartment
+ // We want our charging curve to be a nice simple exponential
+ // Vm = 1.0 - 1.0 * exp( - t / 1.0 );
+ double delta = 0.0;
+ double Vm = 0.0;
+ double tau = 1.0;
+ double Vmax = 1.0;
+ for ( p.currTime = 0.0; p.currTime < 2.0; p.currTime += p.dt )
+ {
+ Vm = c->getVm( compter );
+ double x = Vmax - Vmax * exp( -p.currTime / tau );
+ delta += ( Vm - x ) * ( Vm - x );
+ c->process( compter, &p );
+ }
+ assert( delta < 1.0e-6 );
+ shell->doDelete(comptId);
+ cout << "." << flush;
}
// Comment out this define if it takes too long (about 5 seconds on
@@ -319,72 +323,73 @@ void testCompartment()
#include "../shell/Shell.h"
void testCompartmentProcess()
{
- Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() );
- unsigned int size = 100;
- double Rm = 1.0;
- double Ra = 0.01;
- double Cm = 1.0;
- double dt = 0.01;
- double runtime = 10;
- double lambda = sqrt( Rm / Ra );
-
- Id cid = shell->doCreate( "Compartment", Id(), "compt", size );
- assert( Id::isValid(cid));
- assert( cid.eref().element()->numData() == size );
-
- bool ret = Field< double >::setRepeat( cid, "initVm", 0.0 );
- assert( ret );
- Field< double >::setRepeat( cid, "inject", 0 );
- // Only apply current injection in first compartment
- Field< double >::set( ObjId( cid, 0 ), "inject", 1.0 );
- Field< double >::setRepeat( cid, "Rm", Rm );
- Field< double >::setRepeat( cid, "Ra", Ra );
- Field< double >::setRepeat( cid, "Cm", Cm );
- Field< double >::setRepeat( cid, "Em", 0 );
- Field< double >::setRepeat( cid, "Vm", 0 );
-
- // The diagonal message has a default stride of 1, so it connects
- // successive compartments.
- // Note that the src and dest elements here are identical, so we cannot
- // use a shared message. The messaging system will get confused about
- // direction to send data. So we split up the shared message that we
- // might have used, below, into two individual messages.
- // MsgId mid = shell->doAddMsg( "Diagonal", ObjId( cid ), "raxial", ObjId( cid ), "axial" );
- ObjId mid = shell->doAddMsg( "Diagonal", ObjId( cid ), "axialOut", ObjId( cid ), "handleAxial" );
- assert( !mid.bad());
- // mid = shell->doAddMsg( "Diagonal", ObjId( cid ), "handleRaxial", ObjId( cid ), "raxialOut" );
- mid = shell->doAddMsg( "Diagonal", ObjId( cid ), "raxialOut", ObjId( cid ), "handleRaxial" );
- assert( !mid.bad() );
- // ObjId managerId = Msg::getMsg( mid )->manager().objId();
- // Make the raxial data go from high to lower index compartments.
- Field< int >::set( mid, "stride", -1 );
+ Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() );
+ unsigned int size = 100;
+ double Rm = 1.0;
+ double Ra = 0.01;
+ double Cm = 1.0;
+ double dt = 0.01;
+ double runtime = 10;
+ double lambda = sqrt( Rm / Ra );
+
+ Id cid = shell->doCreate( "Compartment", Id(), "compt", size );
+ assert( Id::isValid(cid));
+ assert( cid.eref().element()->numData() == size );
+
+ bool ret = Field< double >::setRepeat( cid, "initVm", 0.0 );
+ assert( ret );
+ Field< double >::setRepeat( cid, "inject", 0 );
+ // Only apply current injection in first compartment
+ Field< double >::set( ObjId( cid, 0 ), "inject", 1.0 );
+ Field< double >::setRepeat( cid, "Rm", Rm );
+ Field< double >::setRepeat( cid, "Ra", Ra );
+ Field< double >::setRepeat( cid, "Cm", Cm );
+ Field< double >::setRepeat( cid, "Em", 0 );
+ Field< double >::setRepeat( cid, "Vm", 0 );
+
+ // The diagonal message has a default stride of 1, so it connects
+ // successive compartments.
+ // Note that the src and dest elements here are identical, so we cannot
+ // use a shared message. The messaging system will get confused about
+ // direction to send data. So we split up the shared message that we
+ // might have used, below, into two individual messages.
+ // MsgId mid = shell->doAddMsg( "Diagonal", ObjId( cid ), "raxial", ObjId( cid ), "axial" );
+ ObjId mid = shell->doAddMsg( "Diagonal", ObjId( cid ), "axialOut", ObjId( cid ), "handleAxial" );
+ assert( !mid.bad());
+ // mid = shell->doAddMsg( "Diagonal", ObjId( cid ), "handleRaxial", ObjId( cid ), "raxialOut" );
+ mid = shell->doAddMsg( "Diagonal", ObjId( cid ), "raxialOut", ObjId( cid ), "handleRaxial" );
+ assert( !mid.bad() );
+ // ObjId managerId = Msg::getMsg( mid )->manager().objId();
+ // Make the raxial data go from high to lower index compartments.
+ Field< int >::set( mid, "stride", -1 );
#ifdef DO_SPATIAL_TESTS
- shell->doSetClock( 0, dt );
- shell->doSetClock( 1, dt );
- // Ensure that the inter_compt msgs go between nodes once every dt.
- shell->doSetClock( 9, dt );
-
- shell->doUseClock( "/compt", "init", 0 );
- shell->doUseClock( "/compt", "process", 1 );
-
- shell->doReinit();
- shell->doStart( runtime );
-
- double Vmax = Field< double >::get( ObjId( cid, 0 ), "Vm" );
-
- double delta = 0.0;
- // We measure only the first 50 compartments as later we
- // run into end effects because it is not an infinite cable
- for ( unsigned int i = 0; i < size; i++ ) {
- double Vm = Field< double >::get( ObjId( cid, i ), "Vm" );
- double x = Vmax * exp( - static_cast< double >( i ) / lambda );
- delta += ( Vm - x ) * ( Vm - x );
- // cout << i << " (x, Vm) = ( " << x << ", " << Vm << " )\n";
- }
- assert( delta < 1.0e-5 );
+ shell->doSetClock( 0, dt );
+ shell->doSetClock( 1, dt );
+ // Ensure that the inter_compt msgs go between nodes once every dt.
+ shell->doSetClock( 9, dt );
+
+ shell->doUseClock( "/compt", "init", 0 );
+ shell->doUseClock( "/compt", "process", 1 );
+
+ shell->doReinit();
+ shell->doStart( runtime );
+
+ double Vmax = Field< double >::get( ObjId( cid, 0 ), "Vm" );
+
+ double delta = 0.0;
+ // We measure only the first 50 compartments as later we
+ // run into end effects because it is not an infinite cable
+ for ( unsigned int i = 0; i < size; i++ )
+ {
+ double Vm = Field< double >::get( ObjId( cid, i ), "Vm" );
+ double x = Vmax * exp( - static_cast< double >( i ) / lambda );
+ delta += ( Vm - x ) * ( Vm - x );
+ // cout << i << " (x, Vm) = ( " << x << ", " << Vm << " )\n";
+ }
+ assert( delta < 1.0e-5 );
#endif // DO_SPATIAL_TESTS
- shell->doDelete( cid );
- cout << "." << flush;
+ shell->doDelete( cid );
+ cout << "." << flush;
}
#endif // DO_UNIT_TESTS
diff --git a/biophysics/Compartment.h b/biophysics/Compartment.h
index b5c3de0455466edc5f8367841294937bb024b788..af2186bbef412765d63f550e6016ee985c800d04 100644
--- a/biophysics/Compartment.h
+++ b/biophysics/Compartment.h
@@ -21,117 +21,119 @@ namespace moose
{
class Compartment: public CompartmentBase
{
- public:
- Compartment();
- virtual ~Compartment();
-
- // Value Field access function definitions.
- virtual void vSetVm( const Eref& e, double Vm );
- virtual double vGetVm( const Eref& e ) const;
- virtual void vSetEm( const Eref& e, double Em );
- virtual double vGetEm( const Eref& e ) const;
- virtual void vSetCm( const Eref& e, double Cm );
- virtual double vGetCm( const Eref& e ) const;
- virtual void vSetRm( const Eref& e, double Rm );
- virtual double vGetRm( const Eref& e ) const;
- virtual void vSetRa( const Eref& e, double Ra );
- virtual double vGetRa( const Eref& e ) const;
- virtual double vGetIm( const Eref& e ) const;
- virtual void vSetInject( const Eref& e, double Inject );
- virtual double vGetInject( const Eref& e ) const;
- virtual void vSetInitVm( const Eref& e, double initVm );
- virtual double vGetInitVm( const Eref& e ) const;
-
- // Dest function definitions.
- /**
- * The process function does the object updating and sends out
- * messages to channels, nernsts, and so on.
- */
- void vProcess( const Eref& e, ProcPtr p );
-
- /**
- * The reinit function reinitializes all fields.
- */
- void vReinit( const Eref& e, ProcPtr p );
-
- /**
- * The initProc function is for a second phase of 'process'
- * operations. It sends the axial and raxial messages
- * to other compartments. It has to be executed out of phase
- * with the main process so that all compartments are
- * equivalent and there is no calling order dependence in
- * the results.
- */
- void vInitProc( const Eref& e, ProcPtr p );
-
- /**
- * Empty function to do another reinit step out of phase
- * with the main one. Nothing needs doing there.
- */
- void vInitReinit( const Eref& e, ProcPtr p );
-
- /**
- * handleChannel handles information coming from the channel
- * to the compartment
- */
- void vHandleChannel( const Eref& e, double Gk, double Ek);
-
- /**
- * handleRaxial handles incoming raxial message data.
- */
- void vHandleRaxial( double Ra, double Vm);
-
- /**
- * handleAxial handles incoming axial message data.
- */
- void vHandleAxial( double Vm);
-
- /**
- * Injects a constantly updated current into the compartment.
- * Unlike the 'inject' field, this injected current is
- * applicable only for a single timestep. So this is meant to
- * be used as the destination of a message rather than as a
- * one-time assignment.
- */
- void vInjectMsg( const Eref& e, double current);
-
- /**
- * Injects a constantly updated current into the
- * compartment, with a probability prob. Note that it isn't
- * the current amplitude that is random, it is the presence
- * or absence of the current that is probabilistic.
- */
- void vRandInject( const Eref& e, double prob, double current);
-
- /**
- * Dummy function to act as recipient of 'cable' message,
- * which is just for grouping compartments.
- */
- void cable();
-
-
- /**
- * Initializes the class info.
- */
- static const Cinfo* initCinfo();
- protected:
- double Vm_;
- double initVm_;
- double Em_;
- double Cm_;
- double Rm_;
- double Ra_;
- double Im_;
- double lastIm_;
- double inject_;
- double A_;
- double B_;
- double sumInject_;
-
- private:
- double invRm_;
- double dt_;
- static const double EPSILON;
+public:
+ Compartment();
+ virtual ~Compartment();
+
+ // Value Field access function definitions.
+ virtual void vSetVm( const Eref& e, double Vm );
+ virtual double vGetVm( const Eref& e ) const;
+ virtual void vSetEm( const Eref& e, double Em );
+ virtual double vGetEm( const Eref& e ) const;
+ virtual void vSetCm( const Eref& e, double Cm );
+ virtual double vGetCm( const Eref& e ) const;
+ virtual void vSetRm( const Eref& e, double Rm );
+ virtual double vGetRm( const Eref& e ) const;
+ virtual void vSetRa( const Eref& e, double Ra );
+ virtual double vGetRa( const Eref& e ) const;
+ virtual double vGetIm( const Eref& e ) const;
+ virtual void vSetInject( const Eref& e, double Inject );
+ virtual double vGetInject( const Eref& e ) const;
+ virtual void vSetInitVm( const Eref& e, double initVm );
+ virtual double vGetInitVm( const Eref& e ) const;
+
+ // Dest function definitions.
+ /**
+ * The process function does the object updating and sends out
+ * messages to channels, nernsts, and so on.
+ */
+ void vProcess( const Eref& e, ProcPtr p );
+
+ /**
+ * The reinit function reinitializes all fields.
+ */
+ void vReinit( const Eref& e, ProcPtr p );
+
+ /**
+ * The initProc function is for a second phase of 'process'
+ * operations. It sends the axial and raxial messages
+ * to other compartments. It has to be executed out of phase
+ * with the main process so that all compartments are
+ * equivalent and there is no calling order dependence in
+ * the results.
+ */
+ void vInitProc( const Eref& e, ProcPtr p );
+
+ /**
+ * Empty function to do another reinit step out of phase
+ * with the main one. Nothing needs doing there.
+ */
+ void vInitReinit( const Eref& e, ProcPtr p );
+
+ /**
+ * handleChannel handles information coming from the channel
+ * to the compartment
+ */
+ void vHandleChannel( const Eref& e, double Gk, double Ek);
+
+ /**
+ * handleRaxial handles incoming raxial message data.
+ */
+ void vHandleRaxial( double Ra, double Vm);
+
+ /**
+ * handleAxial handles incoming axial message data.
+ */
+ void vHandleAxial( double Vm);
+
+ /**
+ * Injects a constantly updated current into the compartment.
+ * Unlike the 'inject' field, this injected current is
+ * applicable only for a single timestep. So this is meant to
+ * be used as the destination of a message rather than as a
+ * one-time assignment.
+ */
+ void vInjectMsg( const Eref& e, double current);
+
+ /**
+ * Injects a constantly updated current into the
+ * compartment, with a probability prob. Note that it isn't
+ * the current amplitude that is random, it is the presence
+ * or absence of the current that is probabilistic.
+ */
+ void vRandInject( const Eref& e, double prob, double current);
+
+ /**
+ * Dummy function to act as recipient of 'cable' message,
+ * which is just for grouping compartments.
+ */
+ void cable();
+
+
+ /**
+ * Initializes the class info.
+ */
+ static const Cinfo* initCinfo();
+
+protected:
+ double Vm_;
+ double initVm_;
+ double Em_;
+ double Cm_;
+ double Rm_;
+ double Ra_;
+ double Im_;
+ double lastIm_;
+ double inject_;
+ double A_;
+ double B_;
+ double sumInject_;
+
+private:
+ double invRm_;
+ double dt_;
+ static const double EPSILON;
+
};
}
diff --git a/biophysics/CompartmentBase.cpp b/biophysics/CompartmentBase.cpp
index 1528f54f6cde2ba2d9e54cb0dcf729848e357a5b..795acb5a0950666cd24ac4c9427770104f2d0ce5 100644
--- a/biophysics/CompartmentBase.cpp
+++ b/biophysics/CompartmentBase.cpp
@@ -9,7 +9,6 @@
#include "header.h"
#include "ElementValueFinfo.h"
-#include "../randnum/randnum.h"
#include "CompartmentBase.h"
#include "CompartmentDataHolder.h"
#include "../shell/Wildcard.h"
diff --git a/biophysics/MarkovSolver.cpp b/biophysics/MarkovSolver.cpp
index b5e3ddbba288cd3ecfd8ada9b2f40601d444dd1c..0c87795063770e5675cb0cef6e15e0190e98fef6 100644
--- a/biophysics/MarkovSolver.cpp
+++ b/biophysics/MarkovSolver.cpp
@@ -85,7 +85,7 @@ Matrix* MarkovSolver::computePadeApproximant( Matrix* Q1,
vector< unsigned int >* swaps = new vector< unsigned int >;
unsigned int n = Q1->size();
unsigned int degree = mCandidates[degreeIndex];
- double *padeCoeffs;
+ double *padeCoeffs = NULL;
Matrix *V = matAlloc(n);
//Vector of Matrix pointers. Each entry is an even power of Q.
diff --git a/biophysics/Neuron.cpp b/biophysics/Neuron.cpp
index 6a5e42d390dcae427fdc6031541a51becc962d89..aa86759175fc376489128abe3f4a14d1caae32b5 100644
--- a/biophysics/Neuron.cpp
+++ b/biophysics/Neuron.cpp
@@ -105,455 +105,457 @@ const unsigned int nuParser::numVal = 13;
const Cinfo* Neuron::initCinfo()
{
- /////////////////////////////////////////////////////////////////////
- // ValueFinfos
- /////////////////////////////////////////////////////////////////////
- static ValueFinfo< Neuron, double > RM( "RM",
- "Membrane resistivity, in ohm.m^2. Default value is 1.0.",
- &Neuron::setRM,
- &Neuron::getRM
- );
- static ValueFinfo< Neuron, double > RA( "RA",
- "Axial resistivity of cytoplasm, in ohm.m. Default value is 1.0.",
- &Neuron::setRA,
- &Neuron::getRA
- );
- static ValueFinfo< Neuron, double > CM( "CM",
- "Membrane Capacitance, in F/m^2. Default value is 0.01",
- &Neuron::setCM,
- &Neuron::getCM
- );
- static ValueFinfo< Neuron, double > Em( "Em",
- "Resting membrane potential of compartments, in Volts. "
- "Default value is -0.065.",
- &Neuron::setEm,
- &Neuron::getEm
- );
- static ValueFinfo< Neuron, double > theta( "theta",
- "Angle to rotate cell geometry, around long axis of neuron. "
- "Think Longitude. Units are radians. "
- "Default value is zero, which means no rotation. ",
- &Neuron::setTheta,
- &Neuron::getTheta
- );
- static ValueFinfo< Neuron, double > phi( "phi",
- "Angle to rotate cell geometry, around elevation of neuron. "
- "Think Latitude. Units are radians. "
- "Default value is zero, which means no rotation. ",
- &Neuron::setPhi,
- &Neuron::getPhi
- );
-
- static ValueFinfo< Neuron, string > sourceFile( "sourceFile",
- "Name of source file from which to load a model. "
- "Accepts swc and dotp formats at present. "
- "Both these formats require that the appropriate channel "
- "definitions should have been loaded into /library. ",
- &Neuron::setSourceFile,
- &Neuron::getSourceFile
- );
-
- static ValueFinfo< Neuron, double > compartmentLengthInLambdas(
- "compartmentLengthInLambdas",
- "Units: meters (SI). \n"
- "Electrotonic length to use for the largest compartment in the "
- "model. Used to define subdivision of branches into compartments. "
- "For example, if we set *compartmentLengthInLambdas* to 0.1, "
- "and *lambda* (electrotonic length) is 250 microns, then it "
- "sets the compartment length to 25 microns. Thus a dendritic "
- "branch of 500 microns is subdivided into 20 commpartments. "
- "If the branch is shorter than *compartmentLengthInLambdas*, "
- "then it is not subdivided. "
- "If *compartmentLengthInLambdas* is set to 0 then the original "
- "compartmental structure of the model is preserved. "
- " Note that this routine does NOT merge branches, even if "
- "*compartmentLengthInLambdas* is bigger than the branch. "
- "While all this subdivision is being done, the Neuron class "
- "preserves as detailed a geometry as it can, so it can rebuild "
- "the more detailed version if needed. "
- "Default value of *compartmentLengthInLambdas* is 0. ",
- &Neuron::setCompartmentLengthInLambdas,
- &Neuron::getCompartmentLengthInLambdas
- );
-
- static ElementValueFinfo< Neuron, vector< string > >
- channelDistribution(
- "channelDistribution",
- "Specification for distribution of channels, CaConcens and "
- "any other model components that are defined as prototypes and "
- "have to be placed on the electrical compartments.\n"
- "Arguments: proto path field expr [field expr]...\n"
- " Each entry is terminated with an empty string. "
- "The prototype is any object created in */library*, "
- "If a channel matching the prototype name already exists, then "
- "all subsequent operations are applied to the extant channel and "
- "a new one is not created. "
- "The paired arguments are as follows: \n"
- "The *field* argument specifies the name of the parameter "
- "that is to be assigned by the expression.\n"
- "The *expression* argument is a mathematical expression in "
- "the muparser framework, which permits most operations including "
- "trig and transcendental ones. Of course it also handles simple "
- "numerical values like 1.0, 1e-10 and so on. "
- "Available arguments for muParser are:\n"
- " p, g, L, len, dia, maxP, maxG, maxL \n"
- " p: path distance from soma, measured along dendrite, in metres.\n"
- " g: geometrical distance from soma, in metres.\n"
- " L: electrotonic distance (# of lambdas) from soma, along dend. No units.\n"
- " len: length of compartment, in metres.\n"
- " dia: for diameter of compartment, in metres.\n"
- " maxP: Maximum value of *p* for this neuron. \n"
- " maxG: Maximum value of *g* for this neuron. \n"
- " maxL: Maximum value of *L* for this neuron.\n"
- "The expression for the first field must evaluate to > 0 "
- "for the channel to be installed. For example, for "
- "channels, if Field == Gbar, and func( r, L, len, dia) < 0, \n"
- "then the channel is not installed. This feature is typically "
- "used with the sign() or Heaviside H() function to limit range: "
- "for example: H(1 - L) will only put channels closer than "
- "one length constant from the soma, and zero elsewhere. \n"
- "Available fields are: \n"
- "Channels: Gbar (install), Ek \n"
- "CaConcen: shellDia (install), shellFrac (install), tau, min\n"
- "Unless otherwise noted, all fields are scaled appropriately by "
- "the dimensions of their compartment. Thus the channel "
- "maximal conductance Gbar is automatically scaled by the area "
- "of the compartment, and the user does not need to insert this "
- "scaling into the calculations.\n"
- "All parameters are expressed in SI units. Conductance, for "
- "example, is Siemens/sq metre. "
- "\n\n"
- "Some example function forms might be for a channel Gbar: \n"
- " p < 10e-6 ? 400 : 0.0 \n"
- " equivalently, \n"
- " H(10e-6 - p) * 400 \n"
- " equivalently, \n"
- " ( sign(10e-6 - p) + 1) * 200 \n"
- "Each of these forms instruct the function to "
- "set channel Gbar to 400 S/m^2 only within 10 microns path "
- "distance of soma\n"
- "\n"
- " L < 1.0 ? 100 * exp( -L ) : 0.0 \n"
- " ->Set channel Gbar to an exponentially falling function of "
- "electrotonic distance from soma, provided L is under "
- "1.0 lambdas. \n",
- &Neuron::setChannelDistribution,
- &Neuron::getChannelDistribution
- );
-
- static ElementValueFinfo< Neuron, vector< string > >
- passiveDistribution(
- "passiveDistribution",
- "Specification for distribution of passive properties of cell.\n"
- "Arguments: . path field expr [field expr]...\n"
- "Note that the arguments list starts with a period. "
- " Each entry is terminated with an empty string. "
- "The paired arguments are as follows: \n"
- "The *field* argument specifies the name of the parameter "
- "that is to be assigned by the expression.\n"
- "The *expression* argument is a mathematical expression in "
- "the muparser framework, which permits most operations including "
- "trig and transcendental ones. Of course it also handles simple "
- "numerical values like 1.0, 1e-10 and so on. "
- "Available arguments for muParser are:\n"
- " p, g, L, len, dia, maxP, maxG, maxL \n"
- " p: path distance from soma, measured along dendrite, in metres.\n"
- " g: geometrical distance from soma, in metres.\n"
- " L: electrotonic distance (# of lambdas) from soma, along dend. No units.\n"
- " len: length of compartment, in metres.\n"
- " dia: for diameter of compartment, in metres.\n"
- " maxP: Maximum value of *p* for this neuron. \n"
- " maxG: Maximum value of *g* for this neuron. \n"
- " maxL: Maximum value of *L* for this neuron.\n"
- "Available fields are: \n"
- "RM, RA, CM, Rm, Ra, Cm, Em, initVm \n"
- "The first three fields are scaled appropriately by "
- "the dimensions of their compartment. Thus the membrane "
- "resistivity RM (ohms.m^2) is automatically scaled by the area "
- "of the compartment, and the user does not need to insert this "
- "scaling into the calculations to compute Rm."
- "Using the Rm field lets the user directly assign the "
- "membrane resistance (in ohms), presumably using len and dia.\n"
- "Similarly, RA (ohms.m) and CM (Farads/m^2) are specific units "
- "and the actual values for each compartment are assigned by "
- "scaling by length and diameter. Ra (ohms) and Cm (Farads) "
- "require explicit evaluation of the expression. "
- "All parameters are expressed in SI units. Conductance, for "
- "example, is Siemens/sq metre.\n"
- "Note that time these calculations do NOT currently include spines\n",
- &Neuron::setPassiveDistribution,
- &Neuron::getPassiveDistribution
- );
-
- static ElementValueFinfo< Neuron, vector< string > >spineDistribution(
- "spineDistribution",
- "Specification for distribution of spines on dendrite. \n"
- "Arguments: proto path spacing expr [field expr]...\n"
- " Each entry is terminated with an empty string. "
- "The *prototype* is any spine object created in */library*, \n"
- "The *path* is the wildcard path of compartments on which to "
- "place the spine.\n"
- "The *spacing* is the spacing of spines, in metres. \n"
- "The *expression* argument is a mathematical expression in "
- "the muparser framework, which permits most operations including "
- "trig and transcendental ones. Of course it also handles simple "
- "numerical values like 1.0, 1e-10 and so on. "
- "The paired arguments are as follows: \n"
- "The *field* argument specifies the name of the parameter "
- "that is to be assigned by the expression.\n"
- "The *expression* argument is a mathematical expression as above. "
- "Available arguments for muParser are:\n"
- " p, g, L, len, dia, maxP, maxG, maxL \n"
- " p: path distance from soma, measured along dendrite, in metres.\n"
- " g: geometrical distance from soma, in metres.\n"
- " L: electrotonic distance (# of lambdas) from soma, along dend. No units.\n"
- " len: length of compartment, in metres.\n"
- " dia: for diameter of compartment, in metres.\n"
- " maxP: Maximum value of *p* for this neuron. \n"
- " maxG: Maximum value of *g* for this neuron. \n"
- " maxL: Maximum value of *L* for this neuron.\n"
- "The expression for the *spacing* field must evaluate to > 0 for "
- "the spine to be installed. For example, if the expresssion is\n"
- " H(1 - L) \n"
- "then the systemwill only put spines closer than "
- "one length constant from the soma, and zero elsewhere. \n"
- "Available spine parameters are: \n"
- "spacing, minSpacing, size, sizeDistrib "
- "angle, angleDistrib \n",
- &Neuron::setSpineDistribution,
- &Neuron::getSpineDistribution
- );
-
-
- static ReadOnlyValueFinfo< Neuron, unsigned int > numCompartments(
- "numCompartments",
- "Number of electrical compartments in model. ",
- &Neuron::getNumCompartments
- );
-
- static ReadOnlyValueFinfo< Neuron, unsigned int > numSpines(
- "numSpines",
- "Number of dendritic spines in model. ",
- &Neuron::getNumSpines
- );
-
- static ReadOnlyValueFinfo< Neuron, unsigned int > numBranches(
- "numBranches",
- "Number of branches in dendrites. ",
- &Neuron::getNumBranches
- );
-
- static ReadOnlyValueFinfo< Neuron, vector< double > > pathDistFromSoma(
- "pathDistanceFromSoma",
- "geometrical path distance of each segment from soma, measured by "
- "threading along the dendrite.",
- &Neuron::getPathDistFromSoma
- );
-
- static ReadOnlyValueFinfo< Neuron, vector< double > > geomDistFromSoma(
- "geometricalDistanceFromSoma",
- "geometrical distance of each segment from soma.",
- &Neuron::getGeomDistFromSoma
- );
-
- static ReadOnlyValueFinfo< Neuron, vector< double > > elecDistFromSoma(
- "electrotonicDistanceFromSoma",
- "geometrical distance of each segment from soma, as measured along "
- "the dendrite.",
- &Neuron::getElecDistFromSoma
- );
- static ReadOnlyValueFinfo< Neuron, vector< ObjId > > compartments(
- "compartments",
- "Vector of ObjIds of electrical compartments. Order matches order "
- "of segments, and also matches the order of the electrotonic and "
- "geometricalDistanceFromSoma vectors. ",
- &Neuron::getCompartments
- );
-
- static ReadOnlyLookupElementValueFinfo< Neuron, string, vector< ObjId > >
- compartmentsFromExpression(
- "compartmentsFromExpression",
- "Vector of ObjIds of electrical compartments that match the "
- "'path expression' pair in the argument string.",
- &Neuron::getExprElist
- );
-
- static ReadOnlyLookupElementValueFinfo< Neuron, string, vector< double > >
- valuesFromExpression(
- "valuesFromExpression",
- "Vector of values computed for each electrical compartment that "
- "matches the 'path expression' pair in the argument string."
- "This has 13 times the number of entries as # of compartments."
- "For each compartment the entries are: \n"
- "val, p, g, L, len, dia, maxP, maxG, maxL, x, y, z, 0",
- &Neuron::getExprVal
- );
-
- static ReadOnlyLookupElementValueFinfo< Neuron, string, vector< ObjId > >
- spinesFromExpression(
- "spinesFromExpression",
- //"Vector of ObjIds of spines/heads sitting on the electrical "
- //"compartments that match the 'path expression' pair in the "
- //"argument string.",
- "Vector of ObjIds of compartments comprising spines/heads "
- "that match the 'path expression' pair in the "
- "argument string.",
- &Neuron::getSpinesFromExpression
- );
-
- static ReadOnlyLookupElementValueFinfo< Neuron, ObjId,vector< ObjId > >
- spinesOnCompartment(
- "spinesOnCompartment",
- "Vector of ObjIds of spines shafts/heads sitting on the specified "
- "electrical compartment. If each spine has a shaft and a head,"
- "and there are 10 spines on the compartment, there will be 20 "
- "entries in the returned vector, ordered "
- "shaft0, head0, shaft1, head1, ... ",
- &Neuron::getSpinesOnCompartment
- );
-
- static ReadOnlyLookupElementValueFinfo< Neuron, ObjId, ObjId >
- parentCompartmentOfSpine(
- "parentCompartmentOfSpine",
- "Returns parent compartment of specified spine compartment."
- "Both the spine head or its shaft will return the same parent.",
- &Neuron::getParentCompartmentOfSpine
- );
-
- static ReadOnlyLookupElementValueFinfo< Neuron, vector< ObjId >, vector< ObjId > >
- spineIdsFromCompartmentIds(
- "spineIdsFromCompartmentIds",
- "Vector of ObjIds of spine entries (FieldElements on this Neuron, "
- "used for scaling) that map to the the specified "
- "electrical compartments. If a bad compartment Id is given, the"
- "corresponding spine entry is the root Id.",
- &Neuron::getSpineIdsFromCompartmentIds
- );
-
- /////////////////////////////////////////////////////////////////////
- // DestFinfos
- /////////////////////////////////////////////////////////////////////
- static DestFinfo buildSegmentTree( "buildSegmentTree",
- "Build the reference segment tree structure using the child "
- "compartments of the current Neuron. Fills in all the coords and "
- "length constant information into the segments, for later use "
- "when we build reduced compartment trees and channel "
- "distributions. Should only be called once, since subsequent use "
- "on a reduced model will lose the original full cell geometry. ",
- new EpFunc0< Neuron >( &Neuron::buildSegmentTree )
- );
- static DestFinfo setSpineAndPsdMesh( "setSpineAndPsdMesh",
- "Assigns the spine and psd mesh to the Neuron. This is used "
- "to build up a mapping from Spine entries on the Neuron to "
- "chem spines and PSDs, so that volume change operations from "
- "the Spine can propagate to the chem systems.",
- new OpFunc2< Neuron, Id, Id >( &Neuron::setSpineAndPsdMesh )
- );
- static DestFinfo setSpineAndPsdDsolve( "setSpineAndPsdDsolve",
- "Assigns the Dsolves used by spine and PSD to the Neuron. "
- "This is used "
- "to handle the rescaling of diffusion rates when spines are "
- "resized. ",
- new OpFunc2< Neuron, Id, Id >( &Neuron::setSpineAndPsdDsolve )
- );
-
- /*
- static DestFinfo rotateInSpace( "rotateInSpace",
- theta, phi
- static DestFinfo transformInSpace( "transformInSpace",
- transfMatrix(4x4)
- static DestFinfo saveAsNeuroML( "saveAsNeuroML", fname )
- static DestFinfo saveAsDotP( "saveAsDotP", fname )
- static DestFinfo saveAsSwc( "saveAsSwc", fname )
- */
- /////////////////////////////////////////////////////////////////////
- // FieldElement
- /////////////////////////////////////////////////////////////////////
- static FieldElementFinfo< Neuron, Spine > spineFinfo(
- "spine",
- "Field Element for spines. Used to handle dynamic "
- "geometry changes in spines. ",
- Spine::initCinfo(),
- &Neuron::lookupSpine,
- &Neuron::setNumSpines,
- &Neuron::getNumSpines,
- false
- );
-
- /////////////////////////////////////////////////////////////////////
- static Finfo* neuronFinfos[] =
- {
- &RM, // ValueFinfo
- &RA, // ValueFinfo
- &CM, // ValueFinfo
- &Em, // ValueFinfo
- &theta, // ValueFinfo
- &phi, // ValueFinfo
- &sourceFile, // ValueFinfo
- &compartmentLengthInLambdas, // ValueFinfo
- &numCompartments, // ReadOnlyValueFinfo
- &numSpines, // ReadOnlyValueFinfo
- &numBranches, // ReadOnlyValueFinfo
- &pathDistFromSoma, // ReadOnlyValueFinfo
- &geomDistFromSoma, // ReadOnlyValueFinfo
- &elecDistFromSoma, // ReadOnlyValueFinfo
- &compartments, // ReadOnlyValueFinfo
- &channelDistribution, // ValueFinfo
- &passiveDistribution, // ValueFinfo
- &spineDistribution, // ValueFinfo
- // &mechSpec, // ValueFinfo
- // &spineSpecification, // ValueFinfo
- &compartmentsFromExpression, // ReadOnlyLookupValueFinfo
- &valuesFromExpression, // ReadOnlyLookupValueFinfo
- &spinesFromExpression, // ReadOnlyLookupValueFinfo
- &spinesOnCompartment, // ReadOnlyLookupValueFinfo
- &parentCompartmentOfSpine, // ReadOnlyLookupValueFinfo
- &spineIdsFromCompartmentIds, // ReadOnlyLookupValueFinfo
- &buildSegmentTree, // DestFinfo
- &setSpineAndPsdMesh, // DestFinfo
- &setSpineAndPsdDsolve, // DestFinfo
- &spineFinfo, // FieldElementFinfo
- };
- static string doc[] =
- {
- "Name", "Neuron",
- "Author", "C H Chaitanya, Upi Bhalla",
- "Description", "Neuron - Manager for neurons. "
- "Handles high-level specification of distribution of "
- "spines, channels and passive properties. Also manages "
- "spine resizing through a Spine FieldElement. ",
- };
- static Dinfo<Neuron> dinfo;
- static Cinfo neuronCinfo(
- "Neuron",
- Neutral::initCinfo(),
- neuronFinfos, sizeof( neuronFinfos ) / sizeof( Finfo* ),
- &dinfo,
- doc,
- sizeof(doc)/sizeof(string)
- );
-
- return &neuronCinfo;
+ /////////////////////////////////////////////////////////////////////
+ // ValueFinfos
+ /////////////////////////////////////////////////////////////////////
+ static ValueFinfo< Neuron, double > RM( "RM",
+ "Membrane resistivity, in ohm.m^2. Default value is 1.0.",
+ &Neuron::setRM,
+ &Neuron::getRM
+ );
+ static ValueFinfo< Neuron, double > RA( "RA",
+ "Axial resistivity of cytoplasm, in ohm.m. Default value is 1.0.",
+ &Neuron::setRA,
+ &Neuron::getRA
+ );
+ static ValueFinfo< Neuron, double > CM( "CM",
+ "Membrane Capacitance, in F/m^2. Default value is 0.01",
+ &Neuron::setCM,
+ &Neuron::getCM
+ );
+ static ValueFinfo< Neuron, double > Em( "Em",
+ "Resting membrane potential of compartments, in Volts. "
+ "Default value is -0.065.",
+ &Neuron::setEm,
+ &Neuron::getEm
+ );
+ static ValueFinfo< Neuron, double > theta( "theta",
+ "Angle to rotate cell geometry, around long axis of neuron. "
+ "Think Longitude. Units are radians. "
+ "Default value is zero, which means no rotation. ",
+ &Neuron::setTheta,
+ &Neuron::getTheta
+ );
+ static ValueFinfo< Neuron, double > phi( "phi",
+ "Angle to rotate cell geometry, around elevation of neuron. "
+ "Think Latitude. Units are radians. "
+ "Default value is zero, which means no rotation. ",
+ &Neuron::setPhi,
+ &Neuron::getPhi
+ );
+
+ static ValueFinfo< Neuron, string > sourceFile( "sourceFile",
+ "Name of source file from which to load a model. "
+ "Accepts swc and dotp formats at present. "
+ "Both these formats require that the appropriate channel "
+ "definitions should have been loaded into /library. ",
+ &Neuron::setSourceFile,
+ &Neuron::getSourceFile
+ );
+
+ static ValueFinfo< Neuron, double > compartmentLengthInLambdas(
+ "compartmentLengthInLambdas",
+ "Units: meters (SI). \n"
+ "Electrotonic length to use for the largest compartment in the "
+ "model. Used to define subdivision of branches into compartments. "
+ "For example, if we set *compartmentLengthInLambdas* to 0.1, "
+ "and *lambda* (electrotonic length) is 250 microns, then it "
+ "sets the compartment length to 25 microns. Thus a dendritic "
+ "branch of 500 microns is subdivided into 20 commpartments. "
+ "If the branch is shorter than *compartmentLengthInLambdas*, "
+ "then it is not subdivided. "
+ "If *compartmentLengthInLambdas* is set to 0 then the original "
+ "compartmental structure of the model is preserved. "
+ " Note that this routine does NOT merge branches, even if "
+ "*compartmentLengthInLambdas* is bigger than the branch. "
+ "While all this subdivision is being done, the Neuron class "
+ "preserves as detailed a geometry as it can, so it can rebuild "
+ "the more detailed version if needed. "
+ "Default value of *compartmentLengthInLambdas* is 0. ",
+ &Neuron::setCompartmentLengthInLambdas,
+ &Neuron::getCompartmentLengthInLambdas
+ );
+
+ static ElementValueFinfo< Neuron, vector< string > >
+ channelDistribution(
+ "channelDistribution",
+ "Specification for distribution of channels, CaConcens and "
+ "any other model components that are defined as prototypes and "
+ "have to be placed on the electrical compartments.\n"
+ "Arguments: proto path field expr [field expr]...\n"
+ " Each entry is terminated with an empty string. "
+ "The prototype is any object created in */library*, "
+ "If a channel matching the prototype name already exists, then "
+ "all subsequent operations are applied to the extant channel and "
+ "a new one is not created. "
+ "The paired arguments are as follows: \n"
+ "The *field* argument specifies the name of the parameter "
+ "that is to be assigned by the expression.\n"
+ "The *expression* argument is a mathematical expression in "
+ "the muparser framework, which permits most operations including "
+ "trig and transcendental ones. Of course it also handles simple "
+ "numerical values like 1.0, 1e-10 and so on. "
+ "Available arguments for muParser are:\n"
+ " p, g, L, len, dia, maxP, maxG, maxL \n"
+ " p: path distance from soma, measured along dendrite, in metres.\n"
+ " g: geometrical distance from soma, in metres.\n"
+ " L: electrotonic distance (# of lambdas) from soma, along dend. No units.\n"
+ " len: length of compartment, in metres.\n"
+ " dia: for diameter of compartment, in metres.\n"
+ " maxP: Maximum value of *p* for this neuron. \n"
+ " maxG: Maximum value of *g* for this neuron. \n"
+ " maxL: Maximum value of *L* for this neuron.\n"
+ "The expression for the first field must evaluate to > 0 "
+ "for the channel to be installed. For example, for "
+ "channels, if Field == Gbar, and func( r, L, len, dia) < 0, \n"
+ "then the channel is not installed. This feature is typically "
+ "used with the sign() or Heaviside H() function to limit range: "
+ "for example: H(1 - L) will only put channels closer than "
+ "one length constant from the soma, and zero elsewhere. \n"
+ "Available fields are: \n"
+ "Channels: Gbar (install), Ek \n"
+ "CaConcen: shellDia (install), shellFrac (install), tau, min\n"
+ "Unless otherwise noted, all fields are scaled appropriately by "
+ "the dimensions of their compartment. Thus the channel "
+ "maximal conductance Gbar is automatically scaled by the area "
+ "of the compartment, and the user does not need to insert this "
+ "scaling into the calculations.\n"
+ "All parameters are expressed in SI units. Conductance, for "
+ "example, is Siemens/sq metre. "
+ "\n\n"
+ "Some example function forms might be for a channel Gbar: \n"
+ " p < 10e-6 ? 400 : 0.0 \n"
+ " equivalently, \n"
+ " H(10e-6 - p) * 400 \n"
+ " equivalently, \n"
+ " ( sign(10e-6 - p) + 1) * 200 \n"
+ "Each of these forms instruct the function to "
+ "set channel Gbar to 400 S/m^2 only within 10 microns path "
+ "distance of soma\n"
+ "\n"
+ " L < 1.0 ? 100 * exp( -L ) : 0.0 \n"
+ " ->Set channel Gbar to an exponentially falling function of "
+ "electrotonic distance from soma, provided L is under "
+ "1.0 lambdas. \n",
+ &Neuron::setChannelDistribution,
+ &Neuron::getChannelDistribution
+ );
+
+ static ElementValueFinfo< Neuron, vector< string > >
+ passiveDistribution(
+ "passiveDistribution",
+ "Specification for distribution of passive properties of cell.\n"
+ "Arguments: . path field expr [field expr]...\n"
+ "Note that the arguments list starts with a period. "
+ " Each entry is terminated with an empty string. "
+ "The paired arguments are as follows: \n"
+ "The *field* argument specifies the name of the parameter "
+ "that is to be assigned by the expression.\n"
+ "The *expression* argument is a mathematical expression in "
+ "the muparser framework, which permits most operations including "
+ "trig and transcendental ones. Of course it also handles simple "
+ "numerical values like 1.0, 1e-10 and so on. "
+ "Available arguments for muParser are:\n"
+ " p, g, L, len, dia, maxP, maxG, maxL \n"
+ " p: path distance from soma, measured along dendrite, in metres.\n"
+ " g: geometrical distance from soma, in metres.\n"
+ " L: electrotonic distance (# of lambdas) from soma, along dend. No units.\n"
+ " len: length of compartment, in metres.\n"
+ " dia: for diameter of compartment, in metres.\n"
+ " maxP: Maximum value of *p* for this neuron. \n"
+ " maxG: Maximum value of *g* for this neuron. \n"
+ " maxL: Maximum value of *L* for this neuron.\n"
+ "Available fields are: \n"
+ "RM, RA, CM, Rm, Ra, Cm, Em, initVm \n"
+ "The first three fields are scaled appropriately by "
+ "the dimensions of their compartment. Thus the membrane "
+ "resistivity RM (ohms.m^2) is automatically scaled by the area "
+ "of the compartment, and the user does not need to insert this "
+ "scaling into the calculations to compute Rm."
+ "Using the Rm field lets the user directly assign the "
+ "membrane resistance (in ohms), presumably using len and dia.\n"
+ "Similarly, RA (ohms.m) and CM (Farads/m^2) are specific units "
+ "and the actual values for each compartment are assigned by "
+ "scaling by length and diameter. Ra (ohms) and Cm (Farads) "
+ "require explicit evaluation of the expression. "
+ "All parameters are expressed in SI units. Conductance, for "
+ "example, is Siemens/sq metre.\n"
+ "Note that time these calculations do NOT currently include spines\n",
+ &Neuron::setPassiveDistribution,
+ &Neuron::getPassiveDistribution
+ );
+
+ static ElementValueFinfo< Neuron, vector< string > >spineDistribution(
+ "spineDistribution",
+ "Specification for distribution of spines on dendrite. \n"
+ "Arguments: proto path spacing expr [field expr]...\n"
+ " Each entry is terminated with an empty string. "
+ "The *prototype* is any spine object created in */library*, \n"
+ "The *path* is the wildcard path of compartments on which to "
+ "place the spine.\n"
+ "The *spacing* is the spacing of spines, in metres. \n"
+ "The *expression* argument is a mathematical expression in "
+ "the muparser framework, which permits most operations including "
+ "trig and transcendental ones. Of course it also handles simple "
+ "numerical values like 1.0, 1e-10 and so on. "
+ "The paired arguments are as follows: \n"
+ "The *field* argument specifies the name of the parameter "
+ "that is to be assigned by the expression.\n"
+ "The *expression* argument is a mathematical expression as above. "
+ "Available arguments for muParser are:\n"
+ " p, g, L, len, dia, maxP, maxG, maxL \n"
+ " p: path distance from soma, measured along dendrite, in metres.\n"
+ " g: geometrical distance from soma, in metres.\n"
+ " L: electrotonic distance (# of lambdas) from soma, along dend. No units.\n"
+ " len: length of compartment, in metres.\n"
+ " dia: for diameter of compartment, in metres.\n"
+ " maxP: Maximum value of *p* for this neuron. \n"
+ " maxG: Maximum value of *g* for this neuron. \n"
+ " maxL: Maximum value of *L* for this neuron.\n"
+ "The expression for the *spacing* field must evaluate to > 0 for "
+ "the spine to be installed. For example, if the expresssion is\n"
+ " H(1 - L) \n"
+ "then the systemwill only put spines closer than "
+ "one length constant from the soma, and zero elsewhere. \n"
+ "Available spine parameters are: \n"
+ "spacing, minSpacing, size, sizeDistrib "
+ "angle, angleDistrib \n",
+ &Neuron::setSpineDistribution,
+ &Neuron::getSpineDistribution
+ );
+
+
+ static ReadOnlyValueFinfo< Neuron, unsigned int > numCompartments(
+ "numCompartments",
+ "Number of electrical compartments in model. ",
+ &Neuron::getNumCompartments
+ );
+
+ static ReadOnlyValueFinfo< Neuron, unsigned int > numSpines(
+ "numSpines",
+ "Number of dendritic spines in model. ",
+ &Neuron::getNumSpines
+ );
+
+ static ReadOnlyValueFinfo< Neuron, unsigned int > numBranches(
+ "numBranches",
+ "Number of branches in dendrites. ",
+ &Neuron::getNumBranches
+ );
+
+ static ReadOnlyValueFinfo< Neuron, vector< double > > pathDistFromSoma(
+ "pathDistanceFromSoma",
+ "geometrical path distance of each segment from soma, measured by "
+ "threading along the dendrite.",
+ &Neuron::getPathDistFromSoma
+ );
+
+ static ReadOnlyValueFinfo< Neuron, vector< double > > geomDistFromSoma(
+ "geometricalDistanceFromSoma",
+ "geometrical distance of each segment from soma.",
+ &Neuron::getGeomDistFromSoma
+ );
+
+ static ReadOnlyValueFinfo< Neuron, vector< double > > elecDistFromSoma(
+ "electrotonicDistanceFromSoma",
+ "geometrical distance of each segment from soma, as measured along "
+ "the dendrite.",
+ &Neuron::getElecDistFromSoma
+ );
+ static ReadOnlyValueFinfo< Neuron, vector< ObjId > > compartments(
+ "compartments",
+ "Vector of ObjIds of electrical compartments. Order matches order "
+ "of segments, and also matches the order of the electrotonic and "
+ "geometricalDistanceFromSoma vectors. ",
+ &Neuron::getCompartments
+ );
+
+ static ReadOnlyLookupElementValueFinfo< Neuron, string, vector< ObjId > >
+ compartmentsFromExpression(
+ "compartmentsFromExpression",
+ "Vector of ObjIds of electrical compartments that match the "
+ "'path expression' pair in the argument string.",
+ &Neuron::getExprElist
+ );
+
+ static ReadOnlyLookupElementValueFinfo< Neuron, string, vector< double > >
+ valuesFromExpression(
+ "valuesFromExpression",
+ "Vector of values computed for each electrical compartment that "
+ "matches the 'path expression' pair in the argument string."
+ "This has 13 times the number of entries as # of compartments."
+ "For each compartment the entries are: \n"
+ "val, p, g, L, len, dia, maxP, maxG, maxL, x, y, z, 0",
+ &Neuron::getExprVal
+ );
+
+ static ReadOnlyLookupElementValueFinfo< Neuron, string, vector< ObjId > >
+ spinesFromExpression(
+ "spinesFromExpression",
+ //"Vector of ObjIds of spines/heads sitting on the electrical "
+ //"compartments that match the 'path expression' pair in the "
+ //"argument string.",
+ "Vector of ObjIds of compartments comprising spines/heads "
+ "that match the 'path expression' pair in the "
+ "argument string.",
+ &Neuron::getSpinesFromExpression
+ );
+
+ static ReadOnlyLookupElementValueFinfo< Neuron, ObjId,vector< ObjId > >
+ spinesOnCompartment(
+ "spinesOnCompartment",
+ "Vector of ObjIds of spines shafts/heads sitting on the specified "
+ "electrical compartment. If each spine has a shaft and a head,"
+ "and there are 10 spines on the compartment, there will be 20 "
+ "entries in the returned vector, ordered "
+ "shaft0, head0, shaft1, head1, ... ",
+ &Neuron::getSpinesOnCompartment
+ );
+
+ static ReadOnlyLookupElementValueFinfo< Neuron, ObjId, ObjId >
+ parentCompartmentOfSpine(
+ "parentCompartmentOfSpine",
+ "Returns parent compartment of specified spine compartment."
+ "Both the spine head or its shaft will return the same parent.",
+ &Neuron::getParentCompartmentOfSpine
+ );
+
+ static ReadOnlyLookupElementValueFinfo< Neuron, vector< ObjId >, vector< ObjId > >
+ spineIdsFromCompartmentIds(
+ "spineIdsFromCompartmentIds",
+ "Vector of ObjIds of spine entries (FieldElements on this Neuron, "
+ "used for scaling) that map to the the specified "
+ "electrical compartments. If a bad compartment Id is given, the"
+ "corresponding spine entry is the root Id.",
+ &Neuron::getSpineIdsFromCompartmentIds
+ );
+
+ /////////////////////////////////////////////////////////////////////
+ // DestFinfos
+ /////////////////////////////////////////////////////////////////////
+ static DestFinfo buildSegmentTree( "buildSegmentTree",
+ "Build the reference segment tree structure using the child "
+ "compartments of the current Neuron. Fills in all the coords and "
+ "length constant information into the segments, for later use "
+ "when we build reduced compartment trees and channel "
+ "distributions. Should only be called once, since subsequent use "
+ "on a reduced model will lose the original full cell geometry. ",
+ new EpFunc0< Neuron >( &Neuron::buildSegmentTree )
+ );
+ static DestFinfo setSpineAndPsdMesh( "setSpineAndPsdMesh",
+ "Assigns the spine and psd mesh to the Neuron. This is used "
+ "to build up a mapping from Spine entries on the Neuron to "
+ "chem spines and PSDs, so that volume change operations from "
+ "the Spine can propagate to the chem systems.",
+ new OpFunc2< Neuron, Id, Id >( &Neuron::setSpineAndPsdMesh )
+ );
+ static DestFinfo setSpineAndPsdDsolve( "setSpineAndPsdDsolve",
+ "Assigns the Dsolves used by spine and PSD to the Neuron. "
+ "This is used "
+ "to handle the rescaling of diffusion rates when spines are "
+ "resized. ",
+ new OpFunc2< Neuron, Id, Id >( &Neuron::setSpineAndPsdDsolve )
+ );
+
+ /*
+ static DestFinfo rotateInSpace( "rotateInSpace",
+ theta, phi
+ static DestFinfo transformInSpace( "transformInSpace",
+ transfMatrix(4x4)
+ static DestFinfo saveAsNeuroML( "saveAsNeuroML", fname )
+ static DestFinfo saveAsDotP( "saveAsDotP", fname )
+ static DestFinfo saveAsSwc( "saveAsSwc", fname )
+ */
+ /////////////////////////////////////////////////////////////////////
+ // FieldElement
+ /////////////////////////////////////////////////////////////////////
+ static FieldElementFinfo< Neuron, Spine > spineFinfo(
+ "spine",
+ "Field Element for spines. Used to handle dynamic "
+ "geometry changes in spines. ",
+ Spine::initCinfo(),
+ &Neuron::lookupSpine,
+ &Neuron::setNumSpines,
+ &Neuron::getNumSpines,
+ false
+ );
+
+ /////////////////////////////////////////////////////////////////////
+ static Finfo* neuronFinfos[] =
+ {
+ &RM, // ValueFinfo
+ &RA, // ValueFinfo
+ &CM, // ValueFinfo
+ &Em, // ValueFinfo
+ &theta, // ValueFinfo
+ &phi, // ValueFinfo
+ &sourceFile, // ValueFinfo
+ &compartmentLengthInLambdas, // ValueFinfo
+ &numCompartments, // ReadOnlyValueFinfo
+ &numSpines, // ReadOnlyValueFinfo
+ &numBranches, // ReadOnlyValueFinfo
+ &pathDistFromSoma, // ReadOnlyValueFinfo
+ &geomDistFromSoma, // ReadOnlyValueFinfo
+ &elecDistFromSoma, // ReadOnlyValueFinfo
+ &compartments, // ReadOnlyValueFinfo
+ &channelDistribution, // ValueFinfo
+ &passiveDistribution, // ValueFinfo
+ &spineDistribution, // ValueFinfo
+ // &mechSpec, // ValueFinfo
+ // &spineSpecification, // ValueFinfo
+ &compartmentsFromExpression, // ReadOnlyLookupValueFinfo
+ &valuesFromExpression, // ReadOnlyLookupValueFinfo
+ &spinesFromExpression, // ReadOnlyLookupValueFinfo
+ &spinesOnCompartment, // ReadOnlyLookupValueFinfo
+ &parentCompartmentOfSpine, // ReadOnlyLookupValueFinfo
+ &spineIdsFromCompartmentIds, // ReadOnlyLookupValueFinfo
+ &buildSegmentTree, // DestFinfo
+ &setSpineAndPsdMesh, // DestFinfo
+ &setSpineAndPsdDsolve, // DestFinfo
+ &spineFinfo, // FieldElementFinfo
+ };
+ static string doc[] =
+ {
+ "Name", "Neuron",
+ "Author", "C H Chaitanya, Upi Bhalla",
+ "Description", "Neuron - Manager for neurons. "
+ "Handles high-level specification of distribution of "
+ "spines, channels and passive properties. Also manages "
+ "spine resizing through a Spine FieldElement. ",
+ };
+ static Dinfo<Neuron> dinfo;
+ static Cinfo neuronCinfo(
+ "Neuron",
+ Neutral::initCinfo(),
+ neuronFinfos, sizeof( neuronFinfos ) / sizeof( Finfo* ),
+ &dinfo,
+ doc,
+ sizeof(doc)/sizeof(string)
+ );
+
+ return &neuronCinfo;
}
static const Cinfo* neuronCinfo = Neuron::initCinfo();
////////////////////////////////////////////////////////////////////////
Neuron::Neuron()
- :
- RM_( 1.0 ),
- RA_( 1.0 ),
- CM_( 0.01 ),
- Em_( -0.065 ),
- theta_( 0.0 ),
- phi_( 0.0 ),
- maxP_( 0.0 ),
- maxG_( 0.0 ),
- maxL_( 0.0 ),
- sourceFile_( "" ),
- compartmentLengthInLambdas_( 0.2 ),
- spineEntry_( this )
-{;}
+ :
+ RM_( 1.0 ),
+ RA_( 1.0 ),
+ CM_( 0.01 ),
+ Em_( -0.065 ),
+ theta_( 0.0 ),
+ phi_( 0.0 ),
+ maxP_( 0.0 ),
+ maxG_( 0.0 ),
+ maxL_( 0.0 ),
+ sourceFile_( "" ),
+ compartmentLengthInLambdas_( 0.2 ),
+ spineEntry_( this )
+{
+ ;
+}
// When copying Neuron, we next have to rerun buildSegmentTree() and
// setSpineAndPsdMesh
@@ -633,7 +635,7 @@ static void doClassSpecificMessaging( Shell* shell, Id obj, ObjId compt )
{
// cout << "Added Ca Msg for " << obj.path() << ", name = " << obj.element()->getName() << endl;
ObjId mid = shell->doAddMsg(
- "single", obj, "IkOut", elist[0], "current" );
+ "single", obj, "IkOut", elist[0], "current" );
assert( !mid.bad());
}
}
@@ -988,122 +990,133 @@ vector< ObjId > Neuron::getExprElist( const Eref& e, string line ) const
*/
vector< double > Neuron::getExprVal( const Eref& e, string line ) const
{
- Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() );
- vector< ObjId > elist;
- vector< double > val;
- unsigned long pos = line.find_first_of( " \t" );
- string path = line.substr( 0, pos );
- string expr = line.substr( pos );
- ObjId oldCwe = shell->getCwe();
- shell->setCwe( e.objId() );
- wildcardFind( path, elist );
- shell->setCwe( oldCwe );
- if ( elist.size() == 0 )
- return val;
- evalExprForElist( elist, expr, val );
- return val;
+ Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() );
+ vector< ObjId > elist;
+ vector< double > val;
+ unsigned long pos = line.find_first_of( " \t" );
+ string path = line.substr( 0, pos );
+ string expr = line.substr( pos );
+ ObjId oldCwe = shell->getCwe();
+ shell->setCwe( e.objId() );
+ wildcardFind( path, elist );
+ shell->setCwe( oldCwe );
+ if ( elist.size() == 0 )
+ return val;
+ evalExprForElist( elist, expr, val );
+ return val;
}
vector< ObjId > Neuron::getSpinesFromExpression(
- const Eref& e, string line ) const
-{
- unsigned long pos = line.find_first_of( " \t" );
- string path = line.substr( 0, pos );
- string expr = line.substr( pos );
-
- // Look for all compartments that fit the expression.
- vector< ObjId > temp = getExprElist( e, "# " + expr );
- // indexed by segIndex, includes all compts in all spines.
- /*
- vector< vector< Id > > allSpinesPerCompt( segId_.size() );
- for ( unsigned int i = 0; i < spines_.size(); ++i ) {
- assert( allSpinesPerCompt.size() > spineParentSegIndex_[i] );
- vector< Id >& s = allSpinesPerCompt[ spineParentSegIndex_[i] ];
- s.insert( s.end(), spines_[i].begin(), spines_[i].end() );
- }
- */
- vector< ObjId >ret;
- if ( allSpinesPerCompt_.size() == 0 )
- return ret;
- for ( vector< ObjId >::iterator
- i = temp.begin(); i != temp.end(); ++i ) {
- map< Id, unsigned int >::const_iterator si =
- segIndex_.find( i->id );
- assert( si != segIndex_.end() );
- assert( si->second < segId_.size() );
- if ( allSpinesPerCompt_.size() > si->second ) {
- const vector< Id >& s = allSpinesPerCompt_[ si->second ];
- for ( vector< Id >::const_iterator j = s.begin(); j != s.end(); ++j ){
- if ( matchBeforeBrace( *j, path ) )
- ret.push_back( *j );
- }
- }
- }
- return ret;
+ const Eref& e, string line ) const
+{
+ unsigned long pos = line.find_first_of( " \t" );
+ string path = line.substr( 0, pos );
+ string expr = line.substr( pos );
+
+ // Look for all compartments that fit the expression.
+ vector< ObjId > temp = getExprElist( e, "# " + expr );
+ // indexed by segIndex, includes all compts in all spines.
+ /*
+ vector< vector< Id > > allSpinesPerCompt( segId_.size() );
+ for ( unsigned int i = 0; i < spines_.size(); ++i ) {
+ assert( allSpinesPerCompt.size() > spineParentSegIndex_[i] );
+ vector< Id >& s = allSpinesPerCompt[ spineParentSegIndex_[i] ];
+ s.insert( s.end(), spines_[i].begin(), spines_[i].end() );
+ }
+ */
+ vector< ObjId >ret;
+ if ( allSpinesPerCompt_.size() == 0 )
+ return ret;
+ for ( vector< ObjId >::iterator
+ i = temp.begin(); i != temp.end(); ++i )
+ {
+ map< Id, unsigned int >::const_iterator si =
+ segIndex_.find( i->id );
+ assert( si != segIndex_.end() );
+ assert( si->second < segId_.size() );
+ if ( allSpinesPerCompt_.size() > si->second )
+ {
+ const vector< Id >& s = allSpinesPerCompt_[ si->second ];
+ for ( vector< Id >::const_iterator j = s.begin(); j != s.end(); ++j )
+ {
+ if ( matchBeforeBrace( *j, path ) )
+ ret.push_back( *j );
+ }
+ }
+ }
+ return ret;
}
vector< ObjId > Neuron::getSpinesOnCompartment(
- const Eref& e, ObjId compt ) const
-{
- vector< ObjId > ret;
- map< Id, unsigned int >::const_iterator pos =
- segIndex_.find( compt.id );
- if ( pos != segIndex_.end() ) {
- assert( pos->second < allSpinesPerCompt_.size() );
- const vector< Id >& spines = allSpinesPerCompt_[pos->second];
- for ( unsigned int i = 0; i < spines.size(); ++i )
- ret.push_back( spines[i] );
- }
- return ret;
+ const Eref& e, ObjId compt ) const
+{
+ vector< ObjId > ret;
+ map< Id, unsigned int >::const_iterator pos =
+ segIndex_.find( compt.id );
+ if ( pos != segIndex_.end() )
+ {
+ assert( pos->second < allSpinesPerCompt_.size() );
+ const vector< Id >& spines = allSpinesPerCompt_[pos->second];
+ for ( unsigned int i = 0; i < spines.size(); ++i )
+ ret.push_back( spines[i] );
+ }
+ return ret;
}
ObjId Neuron::getParentCompartmentOfSpine(
- const Eref& e, ObjId compt ) const
+ const Eref& e, ObjId compt ) const
{
- for ( unsigned int comptIndex = 0; comptIndex < allSpinesPerCompt_.size(); ++comptIndex ) {
- const vector< Id >& v = allSpinesPerCompt_[comptIndex];
- for ( unsigned int j = 0; j < v.size(); j++ )
- if ( v[j] == compt.id )
- return segId_[ comptIndex ];
- }
- return ObjId();
+ for ( unsigned int comptIndex = 0; comptIndex < allSpinesPerCompt_.size(); ++comptIndex )
+ {
+ const vector< Id >& v = allSpinesPerCompt_[comptIndex];
+ for ( unsigned int j = 0; j < v.size(); j++ )
+ if ( v[j] == compt.id )
+ return segId_[ comptIndex ];
+ }
+ return ObjId();
}
vector< ObjId > Neuron::getSpineIdsFromCompartmentIds(
- const Eref& e, vector< ObjId > compt ) const
-{
- vector< ObjId > ret;
- map< Id, unsigned int > lookupSpine;
- Id spineBase = Id( e.id().value() + 1 );
- for ( unsigned int i = 0; i < spines_.size(); ++i ) {
- for ( vector< Id >::const_iterator j = spines_[i].begin(); j != spines_[i].end(); ++j ) {
- lookupSpine[ *j ] = i;
- }
- }
- // cout << "################## " << lookupSpine.size() << endl;
- for ( map< Id, unsigned int >::const_iterator k = lookupSpine.begin(); k != lookupSpine.end(); ++k ) {
- // cout << "spine[" << k->second << "] has " << k->first.element()->getName() << endl;
- // cout << "spine[" << k->second << "] has " << k->first << endl;
+ const Eref& e, vector< ObjId > compt ) const
+{
+ vector< ObjId > ret;
+ map< Id, unsigned int > lookupSpine;
+ Id spineBase = Id( e.id().value() + 1 );
+ for ( unsigned int i = 0; i < spines_.size(); ++i )
+ {
+ for ( vector< Id >::const_iterator j = spines_[i].begin(); j != spines_[i].end(); ++j )
+ {
+ lookupSpine[ *j ] = i;
+ }
+ }
+ // cout << "################## " << lookupSpine.size() << endl;
+ for ( map< Id, unsigned int >::const_iterator k = lookupSpine.begin(); k != lookupSpine.end(); ++k )
+ {
+ // cout << "spine[" << k->second << "] has " << k->first.element()->getName() << endl;
+ // cout << "spine[" << k->second << "] has " << k->first << endl;
- }
- for ( vector< ObjId >::const_iterator j = compt.begin(); j != compt.end(); ++j )
- {
- // cout << "compt: " << *j << " " << j->element()->getName() << endl;
- map< Id, unsigned int >::const_iterator k = lookupSpine.find( j->id );
- if ( k != lookupSpine.end() ) {
- ret.push_back( ObjId( spineBase, e.dataIndex(), k->second ) );
- // cout << "spine[" << k->second << "] has " << j->element()->getName() << endl;
- } else {
- ret.push_back( ObjId() );
- }
- }
- return ret;
+ }
+ for ( vector< ObjId >::const_iterator j = compt.begin(); j != compt.end(); ++j )
+ {
+ // cout << "compt: " << *j << " " << j->element()->getName() << endl;
+ map< Id, unsigned int >::const_iterator k = lookupSpine.find( j->id );
+ if ( k != lookupSpine.end() )
+ {
+ ret.push_back( ObjId( spineBase, e.dataIndex(), k->second ) );
+ // cout << "spine[" << k->second << "] has " << j->element()->getName() << endl;
+ }
+ else
+ {
+ ret.push_back( ObjId() );
+ }
+ }
+ return ret;
}
void Neuron::buildElist( const Eref& e,
- const vector< string >& line,
- vector< ObjId >& elist,
- vector< double >& val )
+ const vector< string >& line,
+ vector< ObjId >& elist,
+ vector< double >& val )
{
Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() );
const string& path = line[1];
@@ -1111,7 +1124,7 @@ void Neuron::buildElist( const Eref& e,
ObjId oldCwe = shell->getCwe();
shell->setCwe( e.objId() );
wildcardFind( path, elist );
- sort( elist.begin(), elist.end() );
+ sort( elist.begin(), elist.end() );
shell->setCwe( oldCwe );
evalExprForElist( elist, expr, val );
}
@@ -1286,7 +1299,7 @@ static void fillSegments( vector< SwcSegment >& segs,
comptType = 3; // generic dendrite
}
}
- // cout << "Seg[" << i << "].xy = " << int(x*1e6) << " " << int(y*1e6) << endl;
+ // cout << "Seg[" << i << "].xy = " << int(x*1e6) << " " << int(y*1e6) << endl;
segs.push_back(
SwcSegment( i, comptType, x, y, z, dia/2.0, paIndex ) );
@@ -1350,7 +1363,7 @@ void Neuron::buildSegmentTree( const Eref& e )
{
vector< Id > kids;
Neutral::children( e, kids );
- sort( kids.begin(), kids.end() );
+ sort( kids.begin(), kids.end() );
soma_ = fillSegIndex( kids, segIndex_ );
if ( kids.size() == 0 || soma_ == Id() )
@@ -1769,26 +1782,30 @@ string findArg( const vector<string>& line, const string& field )
/// Add entries into the pos vector for a given compartment i.
static void addPos( unsigned int segIndex, unsigned int eIndex,
- double spacing, double minSpacing,
- double dendLength,
- vector< unsigned int >& seglistIndex,
- vector< unsigned int >& elistIndex,
- vector< double >& pos )
-{
- if ( minSpacing < spacing * 0.1 && minSpacing < 1e-7 )
- minSpacing = spacing * 0.1;
- if ( minSpacing > spacing * 0.5 )
- minSpacing = spacing * 0.5;
- unsigned int n = 1 + dendLength / minSpacing;
- double dx = dendLength / n;
- for( unsigned int i = 0; i < n; ++i ) {
- if ( moose::mtrand() < dx / spacing ) {
- seglistIndex.push_back( segIndex );
- elistIndex.push_back( eIndex );
- pos.push_back( i * dx + dx*0.5 );
- }
- }
+ double spacing, double minSpacing,
+ double dendLength,
+ vector< unsigned int >& seglistIndex,
+ vector< unsigned int >& elistIndex,
+ vector< double >& pos )
+{
+ if ( minSpacing < spacing * 0.1 && minSpacing < 1e-7 )
+ minSpacing = spacing * 0.1;
+ if ( minSpacing > spacing * 0.5 )
+ minSpacing = spacing * 0.5;
+ unsigned int n = 1 + dendLength / minSpacing;
+ double dx = dendLength / n;
+ for( unsigned int i = 0; i < n; ++i )
+ {
+ // Use global RNG.
+ if ( moose::mtrand() < dx / spacing )
+ {
+ seglistIndex.push_back( segIndex );
+ elistIndex.push_back( eIndex );
+ pos.push_back( i * dx + dx*0.5 );
+ }
+ }
}
+
/*
* This version tries to put in Pos using simple increments from the
* start of each compt. Multiple issues including inability to put
@@ -1822,169 +1839,187 @@ static void addPos( unsigned int segIndex, unsigned int eIndex,
*/
void Neuron::makeSpacingDistrib( const vector< ObjId >& elist,
- const vector< double >& val,
- vector< unsigned int >& seglistIndex,
- vector< unsigned int >& elistIndex,
- vector< double >& pos,
- const vector< string >& line ) const
-{
- string distribExpr = findArg( line, "spacingDistrib" );
- pos.resize( 0 );
- elistIndex.resize( 0 );
-
- try {
- nuParser parser( distribExpr );
-
- for ( unsigned int i = 0; i < elist.size(); ++i ) {
- unsigned int j = i * nuParser::numVal;
- if ( val[ j + nuParser::EXPR ] > 0 ) {
- double spacing = val[ j + nuParser::EXPR ];
- double spacingDistrib = parser.eval( val.begin() + j );
- if ( spacingDistrib > spacing || spacingDistrib < 0 ) {
- cout << "Warning: Neuron::makeSpacingDistrib: " <<
- "0 < " << spacingDistrib << " < " << spacing <<
- " fails on " << elist[i].path() << ". Using 0.\n";
- spacingDistrib = 0.0;
- }
- map< Id, unsigned int>::const_iterator
- lookupDend = segIndex_.find( elist[i] );
- if ( lookupDend != segIndex_.end() ) {
- double dendLength = segs_[lookupDend->second].length();
- addPos( lookupDend->second, i,
- spacing, spacingDistrib, dendLength,
- seglistIndex, elistIndex, pos );
- }
- }
- }
- }
- catch ( mu::Parser::exception_type& err )
- {
- cout << err.GetMsg() << endl;
- }
+ const vector< double >& val,
+ vector< unsigned int >& seglistIndex,
+ vector< unsigned int >& elistIndex,
+ vector< double >& pos,
+ const vector< string >& line ) const
+{
+ string distribExpr = findArg( line, "spacingDistrib" );
+ pos.resize( 0 );
+ elistIndex.resize( 0 );
+
+ try
+ {
+ nuParser parser( distribExpr );
+
+ for ( unsigned int i = 0; i < elist.size(); ++i )
+ {
+ unsigned int j = i * nuParser::numVal;
+ if ( val[ j + nuParser::EXPR ] > 0 )
+ {
+ double spacing = val[ j + nuParser::EXPR ];
+ double spacingDistrib = parser.eval( val.begin() + j );
+ if ( spacingDistrib > spacing || spacingDistrib < 0 )
+ {
+ cout << "Warning: Neuron::makeSpacingDistrib: " <<
+ "0 < " << spacingDistrib << " < " << spacing <<
+ " fails on " << elist[i].path() << ". Using 0.\n";
+ spacingDistrib = 0.0;
+ }
+ map< Id, unsigned int>::const_iterator
+ lookupDend = segIndex_.find( elist[i] );
+ if ( lookupDend != segIndex_.end() )
+ {
+ double dendLength = segs_[lookupDend->second].length();
+ addPos( lookupDend->second, i,
+ spacing, spacingDistrib, dendLength,
+ seglistIndex, elistIndex, pos );
+ }
+ }
+ }
+ }
+ catch ( mu::Parser::exception_type& err )
+ {
+ cout << err.GetMsg() << endl;
+ }
}
static void makeAngleDistrib ( const vector< ObjId >& elist,
- const vector< double >& val,
- vector< unsigned int >& elistIndex,
- vector< double >& theta,
- const vector< string >& line )
-{
- string angleExpr = findArg( line, "angle" );
- string angleDistribExpr = findArg( line, "angleDistrib" );
- // I won't bother with rotation and rotation distrb for now.
- // Easy to add, but on reflection they don't make sense.
- theta.clear();
- theta.resize( elistIndex.size(), 0.0 );
-
- try {
- nuParser angleParser( angleExpr );
- nuParser distribParser( angleDistribExpr );
- unsigned int lastIndex = ~0U;
- double angle = 0;
- double angleDistrib = 0;
- for ( unsigned int k = 0; k < elistIndex.size(); ++k ) {
- unsigned int i = elistIndex[k];
- if ( i != lastIndex ) {
- lastIndex = i;
- unsigned int j = i * nuParser::numVal;
- angle = angleParser.eval( val.begin() + j );
- angleDistrib = distribParser.eval( val.begin() + j);
- }
- if ( angleDistrib > 0 )
- theta[k] = angle + ( moose::mtrand() - 0.5 ) * angleDistrib;
- else
- theta[k] = angle;
- }
- }
- catch ( mu::Parser::exception_type& err )
- {
- cout << err.GetMsg() << endl;
- }
+ const vector< double >& val,
+ vector< unsigned int >& elistIndex,
+ vector< double >& theta,
+ const vector< string >& line )
+{
+ string angleExpr = findArg( line, "angle" );
+ string angleDistribExpr = findArg( line, "angleDistrib" );
+ // I won't bother with rotation and rotation distrb for now.
+ // Easy to add, but on reflection they don't make sense.
+ theta.clear();
+ theta.resize( elistIndex.size(), 0.0 );
+
+ try
+ {
+ nuParser angleParser( angleExpr );
+ nuParser distribParser( angleDistribExpr );
+ unsigned int lastIndex = ~0U;
+ double angle = 0;
+ double angleDistrib = 0;
+ for ( unsigned int k = 0; k < elistIndex.size(); ++k )
+ {
+ unsigned int i = elistIndex[k];
+ if ( i != lastIndex )
+ {
+ lastIndex = i;
+ unsigned int j = i * nuParser::numVal;
+ angle = angleParser.eval( val.begin() + j );
+ angleDistrib = distribParser.eval( val.begin() + j);
+ }
+
+ // Use global RNG.
+ if ( angleDistrib > 0 )
+ theta[k] = angle + ( moose::mtrand() - 0.5 ) * angleDistrib;
+ else
+ theta[k] = angle;
+ }
+ }
+ catch ( mu::Parser::exception_type& err )
+ {
+ cout << err.GetMsg() << endl;
+ }
}
static void makeSizeDistrib ( const vector< ObjId >& elist,
- const vector< double >& val,
- vector< unsigned int >& elistIndex,
- vector< double >& size,
- const vector< string >& line )
-{
- string sizeExpr = findArg( line, "size" );
- string sizeDistribExpr = findArg( line, "sizeDistrib" );
- size.clear();
- size.resize( elistIndex.size(), 0.0 );
-
- try {
- nuParser sizeParser( sizeExpr );
- nuParser distribParser( sizeDistribExpr );
- unsigned int lastIndex = ~0U;
- double sz = 1.0;
- double sizeDistrib = 0;
- for ( unsigned int k = 0; k < elistIndex.size(); ++k ) {
- unsigned int i = elistIndex[k];
- if ( i != lastIndex ) {
- lastIndex = i;
- unsigned int j = i * nuParser::numVal;
- sz = sizeParser.eval( val.begin() + j );
- sizeDistrib = distribParser.eval( val.begin() + j);
- }
- if ( sizeDistrib > 0 )
- size[k] = sz + ( moose::mtrand() - 0.5 ) * sizeDistrib;
- else
- size[k] = sz;
- }
- }
- catch ( mu::Parser::exception_type& err )
- {
- cout << err.GetMsg() << endl;
- }
+ const vector< double >& val,
+ vector< unsigned int >& elistIndex,
+ vector< double >& size,
+ const vector< string >& line )
+{
+ string sizeExpr = findArg( line, "size" );
+ string sizeDistribExpr = findArg( line, "sizeDistrib" );
+ size.clear();
+ size.resize( elistIndex.size(), 0.0 );
+
+ try
+ {
+ nuParser sizeParser( sizeExpr );
+ nuParser distribParser( sizeDistribExpr );
+ unsigned int lastIndex = ~0U;
+ double sz = 1.0;
+ double sizeDistrib = 0;
+ for ( unsigned int k = 0; k < elistIndex.size(); ++k )
+ {
+ unsigned int i = elistIndex[k];
+ if ( i != lastIndex )
+ {
+ lastIndex = i;
+ unsigned int j = i * nuParser::numVal;
+ sz = sizeParser.eval( val.begin() + j );
+ sizeDistrib = distribParser.eval( val.begin() + j);
+ }
+
+ // Use global RNG.
+ if ( sizeDistrib > 0 )
+ size[k] = sz + ( moose::mtrand() - 0.5 ) * sizeDistrib;
+ else
+ size[k] = sz;
+ }
+ }
+ catch ( mu::Parser::exception_type& err )
+ {
+ cout << err.GetMsg() << endl;
+ }
}
void Neuron::installSpines( const vector< ObjId >& elist,
- const vector< double >& val, const vector< string >& line )
+ const vector< double >& val, const vector< string >& line )
{
- Id spineProto( "/library/spine" );
+ Id spineProto( "/library/spine" );
- if ( spineProto == Id() ) {
- cout << "Warning: Neuron::installSpines: Unable to find prototype spine: /library/spine\n";
- return;
- }
- // Look up elist index from pos index, since there may be many
- // spines on each segment.
- vector< unsigned int > elistIndex;
- vector< double > pos; // spacing of the new spines along compt.
- vector< double > theta; // Angle of spines
- vector< double > size; // Size scaling of spines
- pos.reserve( elist.size() );
- elistIndex.reserve( elist.size() );
-
- makeSpacingDistrib( elist, val,
- spineParentSegIndex_, elistIndex, pos, line);
- makeAngleDistrib( elist, val, elistIndex, theta, line );
- makeSizeDistrib( elist, val, elistIndex, size, line );
- for ( unsigned int k = 0; k < spineParentSegIndex_.size(); ++k ) {
- unsigned int i = spineParentSegIndex_[k];
- Vec x, y, z;
- coordSystem( soma_, segId_[i], x, y, z );
- spines_.push_back(
- addSpine( segId_[i], spineProto, pos[k], theta[k],
- x, y, z, size[k], k )
- );
- }
- spineToMeshOrdering_.clear();
- spineToMeshOrdering_.resize( spines_.size(), 0 );
- spineStoich_.clear();
- spineStoich_.resize( spines_.size() );
- psdStoich_.clear();
- psdStoich_.resize( spines_.size() );
-
- /// Now fill in allSpinesPerCompt_ vector. First clear it out.
- allSpinesPerCompt_.clear();
- allSpinesPerCompt_.resize(segId_.size() );
- for ( unsigned int i = 0; i < spines_.size(); ++i ) {
- assert( allSpinesPerCompt_.size() > spineParentSegIndex_[i] );
- vector< Id >& s = allSpinesPerCompt_[ spineParentSegIndex_[i] ];
- s.insert( s.end(), spines_[i].begin(), spines_[i].end() );
- }
+ if ( spineProto == Id() )
+ {
+ cout << "Warning: Neuron::installSpines: Unable to find prototype spine: /library/spine\n";
+ return;
+ }
+ // Look up elist index from pos index, since there may be many
+ // spines on each segment.
+ vector< unsigned int > elistIndex;
+ vector< double > pos; // spacing of the new spines along compt.
+ vector< double > theta; // Angle of spines
+ vector< double > size; // Size scaling of spines
+ pos.reserve( elist.size() );
+ elistIndex.reserve( elist.size() );
+
+ makeSpacingDistrib( elist, val,
+ spineParentSegIndex_, elistIndex, pos, line);
+ makeAngleDistrib( elist, val, elistIndex, theta, line );
+ makeSizeDistrib( elist, val, elistIndex, size, line );
+ for ( unsigned int k = 0; k < spineParentSegIndex_.size(); ++k )
+ {
+ unsigned int i = spineParentSegIndex_[k];
+ Vec x, y, z;
+ coordSystem( soma_, segId_[i], x, y, z );
+ spines_.push_back(
+ addSpine( segId_[i], spineProto, pos[k], theta[k],
+ x, y, z, size[k], k )
+ );
+ }
+ spineToMeshOrdering_.clear();
+ spineToMeshOrdering_.resize( spines_.size(), 0 );
+ spineStoich_.clear();
+ spineStoich_.resize( spines_.size() );
+ psdStoich_.clear();
+ psdStoich_.resize( spines_.size() );
+
+ /// Now fill in allSpinesPerCompt_ vector. First clear it out.
+ allSpinesPerCompt_.clear();
+ allSpinesPerCompt_.resize(segId_.size() );
+ for ( unsigned int i = 0; i < spines_.size(); ++i )
+ {
+ assert( allSpinesPerCompt_.size() > spineParentSegIndex_[i] );
+ vector< Id >& s = allSpinesPerCompt_[ spineParentSegIndex_[i] ];
+ s.insert( s.end(), spines_[i].begin(), spines_[i].end() );
+ }
}
////////////////////////////////////////////////////////////////////////
// Interface funcs for spines
@@ -2021,8 +2056,8 @@ void Neuron::scaleBufAndRates( unsigned int spineNum,
double lenScale, double diaScale ) const
{
double volScale = lenScale * diaScale * diaScale;
- if ( doubleEq( volScale, 1.0 ) )
- return;
+ if ( doubleEq( volScale, 1.0 ) )
+ return;
if ( spineStoich_.size() == 0 )
// Perhaps no chem stuff in model, but user could have forgotten
// to assign psd and spine meshes.
@@ -2072,8 +2107,8 @@ void Neuron::scaleHeadDiffusion( unsigned int spineNum,
double len, double dia) const
{
double vol = len * dia * dia * PI * 0.25;
- // Note that the diffusion scale for the PSD uses half the length
- // of the head compartment. I'm explicitly putting this in below.
+ // Note that the diffusion scale for the PSD uses half the length
+ // of the head compartment. I'm explicitly putting this in below.
double diffScale = dia * dia * 0.25 * PI / (len/2.0);
unsigned int meshIndex = spineToMeshOrdering_[ spineNum ];
Id headCompt = Field< Id >::get( headDsolve_, "compartment" );
diff --git a/biophysics/Neuron.h b/biophysics/Neuron.h
index 777c5448600b2f56209dc016c951a359881e4da6..81b726581acd77110f76a5818c8e2ca0cf054b63 100644
--- a/biophysics/Neuron.h
+++ b/biophysics/Neuron.h
@@ -17,141 +17,141 @@
class Neuron
{
- public:
- Neuron();
- Neuron( const Neuron& other );
- void setRM( double v );
- double getRM() const;
- void setRA( double v );
- double getRA() const;
- void setCM( double v );
- double getCM() const;
- void setEm( double v );
- double getEm() const;
- void setTheta( double v );
- double getTheta() const;
- void setPhi( double v );
- double getPhi() const;
- void setSourceFile( string v );
- string getSourceFile() const;
- void setCompartmentLengthInLambdas( double v );
- double getCompartmentLengthInLambdas() const;
- unsigned int getNumCompartments() const;
- unsigned int getNumBranches() const;
- vector< double> getPathDistFromSoma() const;
- vector< double> getGeomDistFromSoma() const;
- vector< double> getElecDistFromSoma() const;
- vector< ObjId > getCompartments() const;
- vector< ObjId > getExprElist( const Eref& e, string line ) const;
- vector< double > getExprVal( const Eref& e, string line ) const;
- vector< ObjId > getSpinesFromExpression(
- const Eref& e, string line ) const;
- vector< ObjId > getSpinesOnCompartment(
- const Eref& e, ObjId compt ) const;
- ObjId getParentCompartmentOfSpine( const Eref& e, ObjId compt )
- const;
- vector< ObjId > getSpineIdsFromCompartmentIds(
- const Eref& e, vector< ObjId > compt ) const;
- void setChannelDistribution( const Eref& e, vector< string > v );
- vector< string > getChannelDistribution( const Eref& e ) const;
- void setPassiveDistribution( const Eref& e, vector< string > v );
- vector< string > getPassiveDistribution( const Eref& e ) const;
- void setSpineDistribution( const Eref& e, vector< string > v );
- vector< string > getSpineDistribution( const Eref& e ) const;
-
- void buildSegmentTree( const Eref& e );
- void setSpineAndPsdMesh( Id spineMesh, Id psdMesh );
- void setSpineAndPsdDsolve( Id spineDsolve, Id psdDsolve );
-
- ///////////////////////////////////////////////////////////////////
- // MechSpec set
- ///////////////////////////////////////////////////////////////////
- void updateSegmentLengths();
- void installSpines( const vector< ObjId >& elist,
- const vector< double >& val, const vector< string >& line );
- void makeSpacingDistrib(
- const vector< ObjId >& elist, const vector< double >& val,
- vector< unsigned int >& seglistIndex,
- vector< unsigned int >& elistIndex,
- vector< double >& pos,
- const vector< string >& line ) const;
- void parseMechSpec( const Eref& e );
- void installMechanism( const string& name,
- const vector< ObjId >& elist, const vector< double >& val,
- const vector< string >& line );
- void buildElist(
- const Eref& e,
- const vector< string >& line, vector< ObjId >& elist,
- vector< double >& val );
-
- void evalExprForElist( const vector< ObjId >& elist,
- const string& expn, vector< double >& val ) const;
-
- ///////////////////////////////////////////////////////////////////
- // Interface for Spine class, used mostly in resizing spines.
- ///////////////////////////////////////////////////////////////////
- Spine* lookupSpine( unsigned int index );
- void setNumSpines( unsigned int num );
- unsigned int getNumSpines() const;
-
- const vector< Id >& spineIds( unsigned int index ) const;
- void scaleBufAndRates( unsigned int spineNum,
- double lenScale, double diaScale ) const;
- void scaleShaftDiffusion( unsigned int spineNum,
- double len, double dia) const;
- void scaleHeadDiffusion( unsigned int spineNum,
- double len, double dia) const;
-
- /**
- * Initializes the class info.
- */
- static const Cinfo* initCinfo();
- private:
- double RM_;
- double RA_;
- double CM_;
- double Em_;
- double theta_;
- double phi_;
- double maxP_; // Maximum value of path dist from soma for this cell
- double maxG_; // Maximum value of geom dist from soma for this cell
- double maxL_; // Maximum value of elec dist from soma for this cell
- Id soma_;
- string sourceFile_;
- double compartmentLengthInLambdas_;
- vector< string > channelDistribution_;
- vector< string > passiveDistribution_;
- vector< string > spineDistribution_;
-
- /// Map to look up Seg index from Id of associated compt.
- map< Id, unsigned int > segIndex_;
- /// Look up seg index of parent compartment, from index of spine.
- vector< unsigned int > spineParentSegIndex_;
- vector< vector< Id > > spines_; /// Id of each compt in each spine.
-
- /// Ids of all spines on each compt, looked up by segIndex of compt.
- vector< vector< Id > > allSpinesPerCompt_;
-
- /// Id of stoich associated with each spine. Typically all the same.
- vector< Id > spineStoich_;
- /// Id of stoich associated with each PSD. Typically all the same.
- vector< Id > psdStoich_;
- /// looks up spine/psd mesh index from FieldIndex of selected spine.
- vector< unsigned int > spineToMeshOrdering_;
-
- Id headDsolve_; /// Id of the Dsolve for the head compt.
- Id psdDsolve_; /// Id of the Dsolve for the PSD compt.
- // looks up spine/psd Dsolve::DiffJunction::VoxelJunction index
- //from FieldIndex of selected spine.
- // Turns out this is the same as spineToMeshOrdering.
- //vector< unsigned int > spineToVoxelJunctionOrdering_;
-
- /// Holder for spine operations. Contains pointer to current Neuron.
- Spine spineEntry_;
-
- vector< Id > segId_; /// Id of compartment in each Seg entry, below.
- vector< SwcSegment > segs_;
- vector< SwcBranch > branches_;
+public:
+ Neuron();
+ Neuron( const Neuron& other );
+ void setRM( double v );
+ double getRM() const;
+ void setRA( double v );
+ double getRA() const;
+ void setCM( double v );
+ double getCM() const;
+ void setEm( double v );
+ double getEm() const;
+ void setTheta( double v );
+ double getTheta() const;
+ void setPhi( double v );
+ double getPhi() const;
+ void setSourceFile( string v );
+ string getSourceFile() const;
+ void setCompartmentLengthInLambdas( double v );
+ double getCompartmentLengthInLambdas() const;
+ unsigned int getNumCompartments() const;
+ unsigned int getNumBranches() const;
+ vector< double> getPathDistFromSoma() const;
+ vector< double> getGeomDistFromSoma() const;
+ vector< double> getElecDistFromSoma() const;
+ vector< ObjId > getCompartments() const;
+ vector< ObjId > getExprElist( const Eref& e, string line ) const;
+ vector< double > getExprVal( const Eref& e, string line ) const;
+ vector< ObjId > getSpinesFromExpression(
+ const Eref& e, string line ) const;
+ vector< ObjId > getSpinesOnCompartment(
+ const Eref& e, ObjId compt ) const;
+ ObjId getParentCompartmentOfSpine( const Eref& e, ObjId compt )
+ const;
+ vector< ObjId > getSpineIdsFromCompartmentIds(
+ const Eref& e, vector< ObjId > compt ) const;
+ void setChannelDistribution( const Eref& e, vector< string > v );
+ vector< string > getChannelDistribution( const Eref& e ) const;
+ void setPassiveDistribution( const Eref& e, vector< string > v );
+ vector< string > getPassiveDistribution( const Eref& e ) const;
+ void setSpineDistribution( const Eref& e, vector< string > v );
+ vector< string > getSpineDistribution( const Eref& e ) const;
+
+ void buildSegmentTree( const Eref& e );
+ void setSpineAndPsdMesh( Id spineMesh, Id psdMesh );
+ void setSpineAndPsdDsolve( Id spineDsolve, Id psdDsolve );
+
+ ///////////////////////////////////////////////////////////////////
+ // MechSpec set
+ ///////////////////////////////////////////////////////////////////
+ void updateSegmentLengths();
+ void installSpines( const vector< ObjId >& elist,
+ const vector< double >& val, const vector< string >& line );
+ void makeSpacingDistrib(
+ const vector< ObjId >& elist, const vector< double >& val,
+ vector< unsigned int >& seglistIndex,
+ vector< unsigned int >& elistIndex,
+ vector< double >& pos,
+ const vector< string >& line ) const;
+ void parseMechSpec( const Eref& e );
+ void installMechanism( const string& name,
+ const vector< ObjId >& elist, const vector< double >& val,
+ const vector< string >& line );
+ void buildElist(
+ const Eref& e,
+ const vector< string >& line, vector< ObjId >& elist,
+ vector< double >& val );
+
+ void evalExprForElist( const vector< ObjId >& elist,
+ const string& expn, vector< double >& val ) const;
+
+ ///////////////////////////////////////////////////////////////////
+ // Interface for Spine class, used mostly in resizing spines.
+ ///////////////////////////////////////////////////////////////////
+ Spine* lookupSpine( unsigned int index );
+ void setNumSpines( unsigned int num );
+ unsigned int getNumSpines() const;
+
+ const vector< Id >& spineIds( unsigned int index ) const;
+ void scaleBufAndRates( unsigned int spineNum,
+ double lenScale, double diaScale ) const;
+ void scaleShaftDiffusion( unsigned int spineNum,
+ double len, double dia) const;
+ void scaleHeadDiffusion( unsigned int spineNum,
+ double len, double dia) const;
+
+ /**
+ * Initializes the class info.
+ */
+ static const Cinfo* initCinfo();
+private:
+ double RM_;
+ double RA_;
+ double CM_;
+ double Em_;
+ double theta_;
+ double phi_;
+ double maxP_; // Maximum value of path dist from soma for this cell
+ double maxG_; // Maximum value of geom dist from soma for this cell
+ double maxL_; // Maximum value of elec dist from soma for this cell
+ Id soma_;
+ string sourceFile_;
+ double compartmentLengthInLambdas_;
+ vector< string > channelDistribution_;
+ vector< string > passiveDistribution_;
+ vector< string > spineDistribution_;
+
+ /// Map to look up Seg index from Id of associated compt.
+ map< Id, unsigned int > segIndex_;
+ /// Look up seg index of parent compartment, from index of spine.
+ vector< unsigned int > spineParentSegIndex_;
+ vector< vector< Id > > spines_; /// Id of each compt in each spine.
+
+ /// Ids of all spines on each compt, looked up by segIndex of compt.
+ vector< vector< Id > > allSpinesPerCompt_;
+
+ /// Id of stoich associated with each spine. Typically all the same.
+ vector< Id > spineStoich_;
+ /// Id of stoich associated with each PSD. Typically all the same.
+ vector< Id > psdStoich_;
+ /// looks up spine/psd mesh index from FieldIndex of selected spine.
+ vector< unsigned int > spineToMeshOrdering_;
+
+ Id headDsolve_; /// Id of the Dsolve for the head compt.
+ Id psdDsolve_; /// Id of the Dsolve for the PSD compt.
+ // looks up spine/psd Dsolve::DiffJunction::VoxelJunction index
+ //from FieldIndex of selected spine.
+ // Turns out this is the same as spineToMeshOrdering.
+ //vector< unsigned int > spineToVoxelJunctionOrdering_;
+
+ /// Holder for spine operations. Contains pointer to current Neuron.
+ Spine spineEntry_;
+
+ vector< Id > segId_; /// Id of compartment in each Seg entry, below.
+ vector< SwcSegment > segs_;
+ vector< SwcBranch > branches_;
};
diff --git a/biophysics/RandSpike.cpp b/biophysics/RandSpike.cpp
index 4678970f2f7836f99f3fb6e7bdb2710e48b3a9a4..57fdf8afe5774b08a03825298d572af0d0be3718 100644
--- a/biophysics/RandSpike.cpp
+++ b/biophysics/RandSpike.cpp
@@ -7,123 +7,127 @@
** See the file COPYING.LIB for the full notice.
**********************************************************************/
-#include "header.h"
-#include "../randnum/randnum.h"
+#include "../basecode/header.h"
+#include "../basecode/global.h"
+
#include "RandSpike.h"
- ///////////////////////////////////////////////////////
- // MsgSrc definitions
- ///////////////////////////////////////////////////////
-static SrcFinfo1< double > *spikeOut() {
- static SrcFinfo1< double > spikeOut( "spikeOut",
- "Sends out a trigger for an event.");
- return &spikeOut;
+///////////////////////////////////////////////////////
+// MsgSrc definitions
+///////////////////////////////////////////////////////
+static SrcFinfo1< double > *spikeOut()
+{
+ static SrcFinfo1< double > spikeOut( "spikeOut",
+ "Sends out a trigger for an event.");
+ return &spikeOut;
}
const Cinfo* RandSpike::initCinfo()
{
- ///////////////////////////////////////////////////////
- // Shared message definitions
- ///////////////////////////////////////////////////////
- static DestFinfo process( "process",
- "Handles process call",
- new ProcOpFunc< RandSpike >( &RandSpike::process ) );
- static DestFinfo reinit( "reinit",
- "Handles reinit call",
- new ProcOpFunc< RandSpike >( &RandSpike::reinit ) );
-
- static Finfo* processShared[] =
- {
- &process, &reinit
- };
-
- static SharedFinfo proc( "proc",
- "Shared message to receive Process message from scheduler",
- processShared, sizeof( processShared ) / sizeof( Finfo* ) );
-
- //////////////////////////////////////////////////////////////////
- // Dest Finfos.
- //////////////////////////////////////////////////////////////////
-
- //////////////////////////////////////////////////////////////////
- // Value Finfos.
- //////////////////////////////////////////////////////////////////
-
- static ValueFinfo< RandSpike, double > rate( "rate",
- "Specifies rate for random spike train. Note that this is"
- "probabilistic, so the instantaneous rate may differ. "
- "If the rate is assigned be message and it varies slowly then "
- "the average firing rate will approach the specified rate",
- &RandSpike::setRate,
- &RandSpike::getRate
- );
- static ValueFinfo< RandSpike, double > refractT( "refractT",
- "Refractory Time.",
- &RandSpike::setRefractT,
- &RandSpike::getRefractT
- );
- static ValueFinfo< RandSpike, double > absRefract( "abs_refract",
- "Absolute refractory time. Synonym for refractT.",
- &RandSpike::setRefractT,
- &RandSpike::getRefractT
- );
- static ValueFinfo< RandSpike, bool > doPeriodic( "doPeriodic",
- "Flag: when false, do Poisson process with specified mean rate.\n"
- "When true, fire periodically at specified rate.\n"
- "Defaults to false. Note that refractory time overrides this: "
- "Rate cannot exceed 1/refractT.",
- &RandSpike::setDoPeriodic,
- &RandSpike::getDoPeriodic
- );
- static ReadOnlyValueFinfo< RandSpike, bool > hasFired( "hasFired",
- "True if RandSpike has just fired",
- &RandSpike::getFired
- );
-
- static Finfo* spikeGenFinfos[] =
- {
- spikeOut(), // SrcFinfo
- &proc, // Shared
- &rate, // Value
- &refractT, // Value
- &absRefract, // Value
- &doPeriodic, // Value
- &hasFired, // ReadOnlyValue
- };
-
- static string doc[] =
- {
- "Name", "RandSpike",
- "Author", "Upi Bhalla",
- "Description", "RandSpike object, generates random or regular "
- "spikes at "
- "specified mean rate. Based closely on GENESIS randspike. "
- };
- static Dinfo< RandSpike > dinfo;
- static Cinfo spikeGenCinfo(
- "RandSpike",
- Neutral::initCinfo(),
- spikeGenFinfos, sizeof( spikeGenFinfos ) / sizeof( Finfo* ),
- &dinfo,
- doc,
- sizeof(doc)/sizeof(string)
- );
-
- return &spikeGenCinfo;
+ ///////////////////////////////////////////////////////
+ // Shared message definitions
+ ///////////////////////////////////////////////////////
+ static DestFinfo process( "process",
+ "Handles process call",
+ new ProcOpFunc< RandSpike >( &RandSpike::process ) );
+ static DestFinfo reinit( "reinit",
+ "Handles reinit call",
+ new ProcOpFunc< RandSpike >( &RandSpike::reinit ) );
+
+ static Finfo* processShared[] =
+ {
+ &process, &reinit
+ };
+
+ static SharedFinfo proc( "proc",
+ "Shared message to receive Process message from scheduler",
+ processShared, sizeof( processShared ) / sizeof( Finfo* ) );
+
+ //////////////////////////////////////////////////////////////////
+ // Dest Finfos.
+ //////////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////
+ // Value Finfos.
+ //////////////////////////////////////////////////////////////////
+
+ static ValueFinfo< RandSpike, double > rate( "rate",
+ "Specifies rate for random spike train. Note that this is"
+ "probabilistic, so the instantaneous rate may differ. "
+ "If the rate is assigned be message and it varies slowly then "
+ "the average firing rate will approach the specified rate",
+ &RandSpike::setRate,
+ &RandSpike::getRate
+ );
+ static ValueFinfo< RandSpike, double > refractT( "refractT",
+ "Refractory Time.",
+ &RandSpike::setRefractT,
+ &RandSpike::getRefractT
+ );
+ static ValueFinfo< RandSpike, double > absRefract( "abs_refract",
+ "Absolute refractory time. Synonym for refractT.",
+ &RandSpike::setRefractT,
+ &RandSpike::getRefractT
+ );
+ static ValueFinfo< RandSpike, bool > doPeriodic( "doPeriodic",
+ "Flag: when false, do Poisson process with specified mean rate.\n"
+ "When true, fire periodically at specified rate.\n"
+ "Defaults to false. Note that refractory time overrides this: "
+ "Rate cannot exceed 1/refractT.",
+ &RandSpike::setDoPeriodic,
+ &RandSpike::getDoPeriodic
+ );
+ static ReadOnlyValueFinfo< RandSpike, bool > hasFired( "hasFired",
+ "True if RandSpike has just fired",
+ &RandSpike::getFired
+ );
+
+ static Finfo* spikeGenFinfos[] =
+ {
+ spikeOut(), // SrcFinfo
+ &proc, // Shared
+ &rate, // Value
+ &refractT, // Value
+ &absRefract, // Value
+ &doPeriodic, // Value
+ &hasFired, // ReadOnlyValue
+ };
+
+ static string doc[] =
+ {
+ "Name", "RandSpike",
+ "Author", "Upi Bhalla",
+ "Description", "RandSpike object, generates random or regular "
+ "spikes at "
+ "specified mean rate. Based closely on GENESIS randspike. "
+ };
+ static Dinfo< RandSpike > dinfo;
+ static Cinfo spikeGenCinfo(
+ "RandSpike",
+ Neutral::initCinfo(),
+ spikeGenFinfos, sizeof( spikeGenFinfos ) / sizeof( Finfo* ),
+ &dinfo,
+ doc,
+ sizeof(doc)/sizeof(string)
+ );
+
+ return &spikeGenCinfo;
}
static const Cinfo* spikeGenCinfo = RandSpike::initCinfo();
RandSpike::RandSpike()
- :
- rate_( 0.0 ),
- realRate_( 0.0 ),
- refractT_(0.0),
- lastEvent_(0.0),
- threshold_(0.0),
- fired_( false ),
- doPeriodic_( false )
-{;}
+ :
+ rate_( 0.0 ),
+ realRate_( 0.0 ),
+ refractT_(0.0),
+ lastEvent_(0.0),
+ threshold_(0.0),
+ fired_( false ),
+ doPeriodic_( false )
+{
+ ;
+}
//////////////////////////////////////////////////////////////////
// Here we put the RandSpike class functions.
@@ -132,45 +136,49 @@ RandSpike::RandSpike()
// Value Field access function definitions.
void RandSpike::setRate( double rate )
{
- if ( rate < 0.0 ) {
- cout <<"Warning: RandSpike::setRate: Rate must be >= 0. Using 0.\n";
- rate = 0.0;
- }
- rate_ = rate;
- double prob = 1.0 - rate * refractT_;
- if ( prob <= 0.0 ) {
- cout << "Warning: RandSpike::setRate: Rate is too high compared to refractory time\n";
- realRate_ = rate_;
- } else {
- realRate_ = rate_ / prob;
- }
+ if ( rate < 0.0 )
+ {
+ cout <<"Warning: RandSpike::setRate: Rate must be >= 0. Using 0.\n";
+ rate = 0.0;
+ }
+ rate_ = rate;
+ double prob = 1.0 - rate * refractT_;
+ if ( prob <= 0.0 )
+ {
+ cout << "Warning: RandSpike::setRate: Rate is too high compared to refractory time\n";
+ realRate_ = rate_;
+ }
+ else
+ {
+ realRate_ = rate_ / prob;
+ }
}
double RandSpike::getRate() const
{
- return rate_;
+ return rate_;
}
void RandSpike::setRefractT( double val )
{
- refractT_ = val;
+ refractT_ = val;
}
double RandSpike::getRefractT() const
{
- return refractT_;
+ return refractT_;
}
bool RandSpike::getFired() const
{
- return fired_;
+ return fired_;
}
void RandSpike::setDoPeriodic( bool val )
{
- doPeriodic_ = val;
+ doPeriodic_ = val;
}
bool RandSpike::getDoPeriodic() const
{
- return doPeriodic_;
+ return doPeriodic_;
}
@@ -180,35 +188,43 @@ bool RandSpike::getDoPeriodic() const
void RandSpike::process( const Eref& e, ProcPtr p )
{
- if ( refractT_ > p->currTime - lastEvent_ || rate_ <= 0.0 )
- return;
- fired_ = false;
- if (doPeriodic_) {
- if ( (p->currTime - lastEvent_) > 1.0/rate_ ) {
- lastEvent_ = p->currTime;
- spikeOut()->send( e, p->currTime );
- fired_ = true;
- }
- } else {
- double prob = realRate_ * p->dt;
- if ( prob >= 1.0 || prob >= mtrand() )
- {
- lastEvent_ = p->currTime;
- spikeOut()->send( e, p->currTime );
- fired_ = true;
- }
- }
+ if ( refractT_ > p->currTime - lastEvent_ || rate_ <= 0.0 )
+ return;
+
+ fired_ = false;
+ if (doPeriodic_)
+ {
+ if ( (p->currTime - lastEvent_) > 1.0/rate_ )
+ {
+ lastEvent_ = p->currTime;
+ spikeOut()->send( e, p->currTime );
+ fired_ = true;
+ }
+ }
+ else
+ {
+ double prob = realRate_ * p->dt;
+ if ( prob >= 1.0 || prob >= moose::mtrand() )
+ {
+ lastEvent_ = p->currTime;
+ spikeOut()->send( e, p->currTime );
+ fired_ = true;
+ }
+ }
}
// Set it so that first spike is allowed.
void RandSpike::reinit( const Eref& e, ProcPtr p )
{
- if ( rate_ <= 0.0 ) {
- lastEvent_ = 0.0;
- realRate_ = 0.0;
- } else {
- double prob = mtrand();
- double m = 1.0 / rate_;
- lastEvent_ = m * log( prob );
- }
+ if ( rate_ <= 0.0 )
+ {
+ lastEvent_ = 0.0;
+ realRate_ = 0.0;
+ }
+ else
+ {
+ double prob = moose::mtrand();
+ double m = 1.0 / rate_;
+ lastEvent_ = m * log( prob );
+ }
}
diff --git a/biophysics/RandSpike.h b/biophysics/RandSpike.h
index 2a7da3de72c1ead13a743483faf5bbc0496c331a..682c1911bf39987301549cc86d8b0370c0e43495 100644
--- a/biophysics/RandSpike.h
+++ b/biophysics/RandSpike.h
@@ -12,40 +12,41 @@
class RandSpike
{
- public:
+public:
RandSpike();
- //////////////////////////////////////////////////////////////////
- // Field functions.
- //////////////////////////////////////////////////////////////////
- void setRate( double rate );
- double getRate() const;
-
- void setRefractT( double val );
- double getRefractT() const;
-
- void setDoPeriodic( bool val );
- bool getDoPeriodic() const;
-
- bool getFired() const;
-
- //////////////////////////////////////////////////////////////////
- // Message dest functions.
- //////////////////////////////////////////////////////////////////
-
- void process( const Eref& e, ProcPtr p );
- void reinit( const Eref& e, ProcPtr p );
-
- //////////////////////////////////////////////////////////////////
- static const Cinfo* initCinfo();
- private:
- double rate_;
- double realRate_;
- double refractT_;
- double lastEvent_;
- double threshold_;
- bool fired_;
- bool doPeriodic_;
+ //////////////////////////////////////////////////////////////////
+ // Field functions.
+ //////////////////////////////////////////////////////////////////
+ void setRate( double rate );
+ double getRate() const;
+
+ void setRefractT( double val );
+ double getRefractT() const;
+
+ void setDoPeriodic( bool val );
+ bool getDoPeriodic() const;
+
+ bool getFired() const;
+
+ //////////////////////////////////////////////////////////////////
+ // Message dest functions.
+ //////////////////////////////////////////////////////////////////
+
+ void process( const Eref& e, ProcPtr p );
+ void reinit( const Eref& e, ProcPtr p );
+
+ //////////////////////////////////////////////////////////////////
+ static const Cinfo* initCinfo();
+private:
+ double rate_;
+ double realRate_;
+ double refractT_;
+ double lastEvent_;
+ double threshold_;
+ bool fired_;
+ bool doPeriodic_;
+
};
#endif // _RANDSPIKE_H
diff --git a/biophysics/testBiophysics.cpp b/biophysics/testBiophysics.cpp
index c3069e332af55eec3310582abcdae2dd784c7bc5..e46b301257df547e76df987351834ad522b33d06 100644
--- a/biophysics/testBiophysics.cpp
+++ b/biophysics/testBiophysics.cpp
@@ -8,30 +8,19 @@
**********************************************************************/
-#include "header.h"
+#include "../basecode/header.h"
+#include "../basecode/global.h"
#include "../shell/Shell.h"
-#include "../randnum/randnum.h"
-#include "CompartmentBase.h"
#include "../utility/testing_macros.hpp"
+#include "CompartmentBase.h"
#include "Compartment.h"
-/*
-#include "HHGate.h"
-#include "ChanBase.h"
-#include "HHChannel.h"
-*/
+
extern void testCompartment(); // Defined in Compartment.cpp
extern void testCompartmentProcess(); // Defined in Compartment.cpp
extern void testMarkovRateTable(); //Defined in MarkovRateTable.cpp
extern void testVectorTable(); //Defined in VectorTable.cpp
-/*
-extern void testSpikeGen(); // Defined in SpikeGen.cpp
-extern void testCaConc(); // Defined in CaConc.cpp
-extern void testNernst(); // Defined in Nernst.cpp
-extern void testMarkovSolverBase(); //Defined in MarkovSolverBase.cpp
-extern void testMarkovSolver(); //Defined in MarkovSolver.cpp
-*/
#ifdef DO_UNIT_TESTS
@@ -46,7 +35,7 @@ void testIntFireNetwork( unsigned int runsteps = 5 )
static const double delayMax = 4;
static const double delayMin = 0;
static const double connectionProbability = 0.1;
- static const unsigned int NUM_TOT_SYN = 104576;
+ static const unsigned int NUM_TOT_SYN = 104831;
unsigned int size = 1024;
string arg;
Eref sheller( Id().eref() );
@@ -77,7 +66,9 @@ void testIntFireNetwork( unsigned int runsteps = 5 )
unsigned int nd = syn->totNumLocalField();
if ( Shell::numNodes() == 1 )
- assert( nd == NUM_TOT_SYN );
+ {
+ EXPECT_EQ( nd, NUM_TOT_SYN, "" );
+ }
else if ( Shell::numNodes() == 2 )
assert( nd == 52446 );
else if ( Shell::numNodes() == 3 )
@@ -114,8 +105,11 @@ void testIntFireNetwork( unsigned int runsteps = 5 )
// by multiple threads if the above Set call is not complete.
vector< double > origVm( size, 0.0 );
+
+ // NOTE: From
+ moose::mtseed( 5489UL );
for ( unsigned int i = 0; i < size; ++i )
- origVm[i] = mtrand() * Vmax;
+ origVm[i] = moose::mtrand() * Vmax;
double origVm100 = origVm[100];
double origVm900 = origVm[900];
@@ -146,11 +140,10 @@ void testIntFireNetwork( unsigned int runsteps = 5 )
vector< double > delay( numSynVec[i], 0.0 );
for ( unsigned int j = 0; j < numSynVec[i]; ++j )
{
- weight[i][ j ] = mtrand() * weightMax;
- delay[ j ] = delayMin + mtrand() * ( delayMax - delayMin );
+ weight[i][ j ] = moose::mtrand() * weightMax;
+ delay[ j ] = delayMin + moose::mtrand() * ( delayMax - delayMin );
}
- ret = Field< double >::
- setVec( ObjId( synId, i ), "weight", weight[i] );
+ ret = Field< double >::setVec( ObjId( synId, i ), "weight", weight[i] );
assert( ret );
ret = Field< double >::setVec( ObjId( synId, i ), "delay", delay );
assert( ret );
@@ -218,13 +211,24 @@ void testIntFireNetwork( unsigned int runsteps = 5 )
ASSERT_DOUBLE_EQ("", retVm901, 0.28303358631241327 );
ASSERT_DOUBLE_EQ("", retVm902, 0.0096374021108587178 );
*/
- ASSERT_DOUBLE_EQ("", retVm100, 0.069517018453329804 );
- ASSERT_DOUBLE_EQ("", retVm101, 0.32823493598699577 );
- ASSERT_DOUBLE_EQ("", retVm102, 0.35036493874475361 );
- ASSERT_DOUBLE_EQ("", retVm99, 0.04087358817787364 );
- ASSERT_DOUBLE_EQ("", retVm900, 0.26414663635984065 );
- ASSERT_DOUBLE_EQ("", retVm901, 0.39864519810259352 );
- ASSERT_DOUBLE_EQ("", retVm902, 0.04818717439429359 );
+
+#if 0
+ cout << endl;
+ cout << std::setprecision(12) << retVm100 << endl;
+ cout << std::setprecision(12) << retVm101 << endl;
+ cout << std::setprecision(12) << retVm102 << endl;
+ cout << std::setprecision(11) << retVm99 << endl;
+ cout << std::setprecision(12) << retVm900 << endl;
+ cout << std::setprecision(12) << retVm901 << endl;
+ cout << std::setprecision(12) << retVm902 << endl;
+#endif
+ ASSERT_DOUBLE_EQ("", retVm100, 0.0752853031478);
+ ASSERT_DOUBLE_EQ("", retVm101, 0.226731547886 );
+ ASSERT_DOUBLE_EQ("", retVm102, 0.204294350789 );
+ ASSERT_DOUBLE_EQ("", retVm99, 0.2814616871 );
+ ASSERT_DOUBLE_EQ("", retVm900, 0.194820080944 );
+ ASSERT_DOUBLE_EQ("", retVm901, 0.0490452677121);
+ ASSERT_DOUBLE_EQ("", retVm902, 0.214295483534 );
}
/*
diff --git a/builtins/Table.h b/builtins/Table.h
index 9fb78c8b69f5416c999d3383708c58f127e50be8..34397cde40e0056b5a57517d54831db73cbc9b52 100644
--- a/builtins/Table.h
+++ b/builtins/Table.h
@@ -10,10 +10,6 @@
#ifndef _TABLE_H
#define _TABLE_H
-
-#if USE_BOOST
-#include <boost/filesystem.hpp>
-#endif /* ----- USE_BOOST ----- */
#include <fstream>
/**
diff --git a/builtins/testNSDF.cpp b/builtins/testNSDF.cpp
index b99782f1e4c7280cfcc17dbf11bd1cf39469e395..86e1f96f04746ceef3930f771dfec5603679884f 100644
--- a/builtins/testNSDF.cpp
+++ b/builtins/testNSDF.cpp
@@ -73,7 +73,7 @@ void testCreateStringDataset()
hsize_t size = STR_DSET_LEN;
herr_t status;
HDF5WriterBase writer;
- string h5Filename = std::tmpnam( NULL );
+ string h5Filename = moose::random_string( 10 );
file = H5Fcreate(h5Filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
dset = writer.createStringDataset(file, STR_DSET_NAME, size, size);
assert(dset >= 0);
diff --git a/diffusion/ConcChanInfo.h b/diffusion/ConcChanInfo.h
index cd16266b5e5ea895ce7a2fec5722bb18de339a50..caf2b6b4d460b897dfd28134069f59f4163d3acf 100644
--- a/diffusion/ConcChanInfo.h
+++ b/diffusion/ConcChanInfo.h
@@ -17,14 +17,18 @@ class ConcChanInfo
public:
ConcChanInfo();
ConcChanInfo( unsigned int my, unsigned int other,
- unsigned int chan, double perm )
+ unsigned int chan, double perm, bool isSwapped )
: myPool( my ), otherPool( other ), chanPool( chan ),
+ swapped( isSwapped ),
permeability( perm )
{;}
unsigned int myPool;
unsigned int otherPool;
unsigned int chanPool;
+ bool swapped; // Flag records whether myPool/otherPool are
+ // swapped wrt inPool/outPool. System expects
+ // that inPool should be in same compt as chanPool.
double permeability;
};
diff --git a/diffusion/DiffPoolVec.cpp b/diffusion/DiffPoolVec.cpp
index cd1da649567100c4a3de2008d96c0d2d0ebd24ff..d8a9208dcc779ae82ff63783bc86a40be4c17f05 100644
--- a/diffusion/DiffPoolVec.cpp
+++ b/diffusion/DiffPoolVec.cpp
@@ -23,135 +23,140 @@ using namespace std;
* work on in single-compartment models.
*/
DiffPoolVec::DiffPoolVec()
- : id_( 0 ), n_( 1, 0.0 ), nInit_( 1, 0.0 ),
- diffConst_( 1.0e-12 ), motorConst_( 0.0 )
-{;}
+ : id_( 0 ), n_( 1, 0.0 ), nInit_( 1, 0.0 ),
+ diffConst_( 1.0e-12 ), motorConst_( 0.0 )
+{
+ ;
+}
double DiffPoolVec::getNinit( unsigned int voxel ) const
{
- assert( voxel < nInit_.size() );
- return nInit_[ voxel ];
+ assert( voxel < nInit_.size() );
+ return nInit_[ voxel ];
}
void DiffPoolVec::setNinit( unsigned int voxel, double v )
{
- assert( voxel < nInit_.size() );
- nInit_[ voxel ] = v;
+ assert( voxel < nInit_.size() );
+ nInit_[ voxel ] = v;
}
double DiffPoolVec::getN( unsigned int voxel ) const
{
- assert( voxel < n_.size() );
- return n_[ voxel ];
+ assert( voxel < n_.size() );
+ return n_[ voxel ];
}
void DiffPoolVec::setN( unsigned int voxel, double v )
{
- assert( voxel < n_.size() );
- n_[ voxel ] = v;
+ assert( voxel < n_.size() );
+ n_[ voxel ] = v;
}
double DiffPoolVec::getPrev( unsigned int voxel ) const
{
- assert( voxel < n_.size() );
- return prev_[ voxel ];
+ assert( voxel < n_.size() );
+ return prev_[ voxel ];
}
const vector< double >& DiffPoolVec::getNvec() const
{
- return n_;
+ return n_;
}
void DiffPoolVec::setNvec( const vector< double >& vec )
{
- assert( vec.size() == n_.size() );
- n_ = vec;
+ assert( vec.size() == n_.size() );
+ n_ = vec;
}
void DiffPoolVec::setNvec( unsigned int start, unsigned int num,
- vector< double >::const_iterator q )
+ vector< double >::const_iterator q )
{
- assert( start + num <= n_.size() );
- vector< double >::iterator p = n_.begin() + start;
- for ( unsigned int i = 0; i < num; ++i )
- *p++ = *q++;
+ assert( start + num <= n_.size() );
+ vector< double >::iterator p = n_.begin() + start;
+ for ( unsigned int i = 0; i < num; ++i )
+ *p++ = *q++;
}
void DiffPoolVec::setPrevVec()
{
- prev_ = n_;
+ prev_ = n_;
}
double DiffPoolVec::getDiffConst() const
{
- return diffConst_;
+ return diffConst_;
}
void DiffPoolVec::setDiffConst( double v )
{
- diffConst_ = v;
+ diffConst_ = v;
}
double DiffPoolVec::getMotorConst() const
{
- return motorConst_;
+ return motorConst_;
}
void DiffPoolVec::setMotorConst( double v )
{
- motorConst_ = v;
+ motorConst_ = v;
}
void DiffPoolVec::setNumVoxels( unsigned int num )
{
- nInit_.resize( num, 0.0 );
- n_.resize( num, 0.0 );
+ nInit_.resize( num, 0.0 );
+ n_.resize( num, 0.0 );
}
unsigned int DiffPoolVec::getNumVoxels() const
{
- return n_.size();
+ return n_.size();
}
void DiffPoolVec::setId( unsigned int id )
{
- id_ = id;
+ id_ = id;
}
unsigned int DiffPoolVec::getId() const
{
- return id_;
+ return id_;
}
void DiffPoolVec::setOps(const vector< Triplet< double > >& ops,
- const vector< double >& diagVal )
+ const vector< double >& diagVal )
{
- if ( ops.size() > 0 ) {
- assert( diagVal.size() == n_.size() );
- ops_ = ops;
- diagVal_ = diagVal;
- } else {
- ops_.clear();
- diagVal_.clear();
- }
+ if ( ops.size() > 0 )
+ {
+ assert( diagVal.size() == n_.size() );
+ ops_ = ops;
+ diagVal_ = diagVal;
+ }
+ else
+ {
+ ops_.clear();
+ diagVal_.clear();
+ }
}
void DiffPoolVec::advance( double dt )
{
- if ( ops_.size() == 0 ) return;
- for ( vector< Triplet< double > >::const_iterator
- i = ops_.begin(); i != ops_.end(); ++i )
- n_[i->c_] -= n_[i->b_] * i->a_;
+ if ( ops_.size() == 0 ) return;
+ for ( vector< Triplet< double > >::const_iterator
+ i = ops_.begin(); i != ops_.end(); ++i )
+ n_[i->c_] -= n_[i->b_] * i->a_;
- assert( n_.size() == diagVal_.size() );
- vector< double >::iterator iy = n_.begin();
- for ( vector< double >::const_iterator
- i = diagVal_.begin(); i != diagVal_.end(); ++i )
- *iy++ *= *i;
+ assert( n_.size() == diagVal_.size() );
+ vector< double >::iterator iy = n_.begin();
+ for ( vector< double >::const_iterator
+ i = diagVal_.begin(); i != diagVal_.end(); ++i )
+ *iy++ *= *i;
}
void DiffPoolVec::reinit() // Not called by the clock, but by parent.
{
- assert( n_.size() == nInit_.size() );
- prev_ = n_ = nInit_;
+ assert( n_.size() == nInit_.size() );
+ prev_ = n_ = nInit_;
}
diff --git a/diffusion/Dsolve.cpp b/diffusion/Dsolve.cpp
index d2f27122fe4eb2a9777200d76468671fa4e99cb8..ec72a97e737e06f9dc64a21f949c2047f5a49a3f 100644
--- a/diffusion/Dsolve.cpp
+++ b/diffusion/Dsolve.cpp
@@ -374,33 +374,30 @@ void Dsolve::calcJnChan( const DiffJunction& jn, Dsolve* other, double dt )
{
// Each jn has some channels
// Each channel has a chanPool, an intPool and an extPool.
- // intPool is on self, extPool is on other, but we have a problem
+ // chanPool and intPool must be on self, extPool is on other. In
+ // cases where the intPool is on other, it attempts to swap the
+ // int and ext pools, but this too could fail
// because the chanPool could be a third compartment, such as the memb
- // If we stipulate it is is on self, that is easy but not general.
+ //
+ // Don't have a solution for this case as yet.
// Other alternative is to have a message to update the N of the chan,
// so it isn't in the domain of the solver at all except for here.
// In which case we will want to point to the Moose object for it.
//
- //
for ( unsigned int i = 0; i < jn.myChannels.size(); ++i ) {
ConcChanInfo& myChan = channels_[ jn.myChannels[i] ];
DiffPoolVec& myDv = pools_[ myChan.myPool ];
DiffPoolVec& otherDv = other->pools_[ myChan.otherPool ];
DiffPoolVec& chanDv = pools_[ myChan.chanPool ];
- /*
- DiffPoolVec& myDv = pools_[ jn.myPools[myChan.myPool] ];
- DiffPoolVec& otherDv =
- other->pools_[ jn.otherPools[myChan.otherPool] ];
- DiffPoolVec& chanDv = pools_[ jn.myPools[myChan.chanPool] ];
- */
for ( vector< VoxelJunction >::const_iterator
j = jn.vj.begin(); j != jn.vj.end(); ++j ) {
double myN = myDv.getN( j->first );
double lastN = myN;
double otherN = otherDv.getN( j->second );
- double perm = myChan.permeability * chanDv.getN( j->first );
+ double chanN = chanDv.getN( j->first );
+ double perm = myChan.permeability * chanN / NA;
myN = integ( myN, perm * myN/j->firstVol,
perm * otherN/j->secondVol, dt );
otherN += lastN - myN; // Mass consv
@@ -433,7 +430,8 @@ void Dsolve::calcOtherJnChan( const DiffJunction& jn, Dsolve* other, double dt )
double myN = myDv.getN( j->first );
double lastN = myN;
double otherN = otherDv.getN( j->second );
- double perm = otherChan.permeability * chanDv.getN(j->second);
+ double chanN = chanDv.getN( j->second );
+ double perm = otherChan.permeability * chanN / NA;
myN = integ( myN, perm * myN/j->firstVol,
perm * otherN/j->secondVol, dt );
otherN += lastN - myN; // Mass consv
@@ -571,18 +569,22 @@ void Dsolve::fillConcChans( const vector< ObjId >& chans )
if (i->element()->getNeighbors( ret, chanPoolFinfo ) == 0 ) return;
ObjId chanPool( ret[0] );
ret.clear();
- /*
- ObjId inPool = i->element()->findCaller( fin );
- ObjId chanPool = i->element()->findCaller( fchan );
- ObjId outPool = i->element()->findCaller( fout );
- */
+ unsigned int outPoolValue = outPool.id.value();
+ bool swapped = false;
if ( !( inPool.bad() or chanPool.bad() ) ) {
unsigned int inPoolIndex = convertIdToPoolIndex( inPool.id );
unsigned int chanPoolIndex = convertIdToPoolIndex(chanPool.id);
- if ( inPoolIndex != ~0U && chanPoolIndex != ~0U ) {
- ConcChanInfo cci( inPoolIndex, outPool.id.value(),
- chanPoolIndex,
- Field< double >::get( *i, "permeability" )
+ if ( inPoolIndex == ~0U ) { // Swap in and out as chan is symm
+ inPoolIndex = convertIdToPoolIndex( outPool.id );
+ outPoolValue = inPool.id.value();
+ swapped = true;
+ }
+ if ( ( inPoolIndex != ~0U) && (chanPoolIndex != ~0U ) ) {
+ ConcChanInfo cci(
+ inPoolIndex, outPoolValue, chanPoolIndex,
+ Field< double >::get( *i, "permeability" ),
+ ////// Fix it below ////////
+ swapped
);
channels_.push_back( cci );
}
@@ -895,19 +897,23 @@ void Dsolve::mapChansBetweenDsolves( DiffJunction& jn, Id self, Id other)
vector< ConcChanInfo >& ch = selfSolve->channels_;
unsigned int outIndex;
for ( unsigned int i = 0; i < ch.size(); ++i ) {
+ unsigned int chanIndex = ch[i].chanPool;
outIndex = otherSolve->convertIdToPoolIndex( ch[i].otherPool );
- if ( outIndex != ~0U ) {
+ if ( (outIndex != ~0U) && (chanIndex != ~0U ) ) {
jn.myChannels.push_back(i);
ch[i].otherPool = outIndex; // replace the Id with the index.
+ ch[i].chanPool = chanIndex; //chanIndex may be on either Dsolve
}
}
// Now set up the other Dsolve.
vector< ConcChanInfo >& ch2 = otherSolve->channels_;
for ( unsigned int i = 0; i < ch2.size(); ++i ) {
+ unsigned int chanIndex = ch2[i].chanPool;
outIndex = selfSolve->convertIdToPoolIndex( ch2[i].otherPool );
- if ( outIndex != ~0U ) {
+ if ( (outIndex != ~0U) && (chanIndex != ~0U) ) {
jn.otherChannels.push_back(i);
ch2[i].otherPool = outIndex; // replace the Id with the index
+ ch2[i].chanPool = chanIndex; //chanIndex may be on either Dsolve
}
}
}
diff --git a/external/boost-numeric-bindings/boost/numeric/bindings/lapack/gees.hpp b/external/boost-numeric-bindings/boost/numeric/bindings/lapack/gees.hpp
index 2c2531c93010a797ebc71497106b5ef253f1c6ac..472ef3675b2f9e2b23f409c6e3b25e860a99722d 100644
--- a/external/boost-numeric-bindings/boost/numeric/bindings/lapack/gees.hpp
+++ b/external/boost-numeric-bindings/boost/numeric/bindings/lapack/gees.hpp
@@ -140,7 +140,9 @@ namespace boost { namespace numeric { namespace bindings {
>::value));
#endif
+#ifndef NDEBUG
typedef typename MatrA::value_type value_type ;
+#endif
int const n = traits::matrix_size1 (a);
assert (n == traits::matrix_size2 (a));
@@ -185,7 +187,9 @@ namespace boost { namespace numeric { namespace bindings {
>::value));
#endif
+#ifndef NDEBUG
typedef typename MatrA::value_type value_type ;
+#endif
int const n = traits::matrix_size1 (a);
assert (n == traits::matrix_size2 (a));
@@ -265,7 +269,9 @@ namespace boost { namespace numeric { namespace bindings {
inline
int operator() (char jobvs, MatrA& a, EigVal& w, SchVec& vs, optimal_workspace ) const {
typedef typename MatrA::value_type value_type ;
+#ifndef NDEBUG
typedef typename traits::type_traits< value_type >::real_type real_type ;
+#endif
int n = traits::matrix_size1( a );
@@ -278,7 +284,10 @@ namespace boost { namespace numeric { namespace bindings {
inline
int operator() (char jobvs, MatrA& a, EigVal& w, SchVec& vs, minimal_workspace ) const {
typedef typename MatrA::value_type value_type ;
+
+#ifndef NDEBUG
typedef typename traits::type_traits< value_type >::real_type real_type ;
+#endif
int n = traits::matrix_size1( a );
diff --git a/external/boost-numeric-bindings/boost/numeric/bindings/lapack/gesvd.hpp b/external/boost-numeric-bindings/boost/numeric/bindings/lapack/gesvd.hpp
index 0bb01fdbc8a35d2727d8f32434d04ff3e84fef86..eba01080e51873fcf9d4658db99bec7d58186620 100644
--- a/external/boost-numeric-bindings/boost/numeric/bindings/lapack/gesvd.hpp
+++ b/external/boost-numeric-bindings/boost/numeric/bindings/lapack/gesvd.hpp
@@ -295,7 +295,9 @@ namespace boost { namespace numeric { namespace bindings {
|| (jobvt == 'A' && traits::leading_dimension (vt) >= n)
|| (jobvt == 'S' && traits::leading_dimension (vt) >= minmn));
#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
+#ifndef NDEBUG
typedef typename traits::matrix_traits<MatrA>::value_type val_t;
+#endif
#else
typedef typename MatrA::value_type val_t;
#endif
diff --git a/external/boost-numeric-bindings/boost/numeric/bindings/lapack/syev.hpp b/external/boost-numeric-bindings/boost/numeric/bindings/lapack/syev.hpp
index 5aeaf382adf18cf3f9925cb9f8491d666cc1f5d1..fdd5253bcb68669e51e9d871090d254280cb1fc0 100644
--- a/external/boost-numeric-bindings/boost/numeric/bindings/lapack/syev.hpp
+++ b/external/boost-numeric-bindings/boost/numeric/bindings/lapack/syev.hpp
@@ -136,7 +136,10 @@ namespace boost { namespace numeric { namespace bindings {
template <typename A, typename W, typename Work>
inline
int syev (char jobz, char uplo, A& a, W& w, detail::workspace1<Work> workspace ) {
+
+#ifndef NDEBUG
typedef typename A::value_type value_type ;
+#endif
return detail::syev(jobz, uplo, a, w, workspace.w_);
} // syev()
@@ -195,7 +198,9 @@ namespace boost { namespace numeric { namespace bindings {
template <typename A, typename W, typename Work>
inline
int syev (char jobz, A& a, W& w, detail::workspace1<Work> workspace ) {
+#ifndef NDEBUG
typedef typename A::value_type value_type ;
+#endif
char uplo = traits::matrix_uplo_tag( a ) ;
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
typedef typename traits::matrix_traits<A>::matrix_structure matrix_structure ;
diff --git a/intfire/CMakeLists.txt b/intfire/CMakeLists.txt
index 5ee3c2fbad84ca9f879136eabec4b0410bf60589..06435a8e055245679563e08a99a360d05b3cddd6 100644
--- a/intfire/CMakeLists.txt
+++ b/intfire/CMakeLists.txt
@@ -1,14 +1,5 @@
-cmake_minimum_required(VERSION 2.6)
-INCLUDE_DIRECTORIES(../basecode)
-
-ADD_LIBRARY(intfire
- AdExIF.cpp
- AdThreshIF.cpp
- ExIF.cpp
- IntFireBase.cpp
- IzhIF.cpp
- LIF.cpp
- QIF.cpp
- testIntFire.cpp
- )
-
+cmake_minimum_required(VERSION 2.8)
+include_directories(../basecode)
+add_definitions( -std=c++11 )
+file(GLOB SRC *.cpp)
+add_library(intfire ${SRC})
diff --git a/intfire/IntFireBase.cpp b/intfire/IntFireBase.cpp
index a4364db48894e3dbb98105963f8311cb692d025e..7488c54ffca9948c52ae4fe702720bf8d9c64d5f 100644
--- a/intfire/IntFireBase.cpp
+++ b/intfire/IntFireBase.cpp
@@ -7,97 +7,99 @@
** See the file COPYING.LIB for the full notice.
**********************************************************************/
-#include "header.h"
-#include "ElementValueFinfo.h"
+#include "../basecode/header.h"
+#include "../basecode/ElementValueFinfo.h"
#include "../biophysics/CompartmentBase.h"
#include "../biophysics/Compartment.h"
#include "IntFireBase.h"
using namespace moose;
-SrcFinfo1< double >* IntFireBase::spikeOut() {
- static SrcFinfo1< double > spikeOut(
- "spikeOut",
- "Sends out spike events. The argument is the timestamp of "
- "the spike. "
- );
- return &spikeOut;
+SrcFinfo1< double >* IntFireBase::spikeOut()
+{
+ static SrcFinfo1< double > spikeOut(
+ "spikeOut",
+ "Sends out spike events. The argument is the timestamp of "
+ "the spike. "
+ );
+ return &spikeOut;
}
const Cinfo* IntFireBase::initCinfo()
{
- //////////////////////////////////////////////////////////////
- // Field Definitions
- //////////////////////////////////////////////////////////////
-
- static ElementValueFinfo< IntFireBase, double > thresh(
- "thresh",
- "firing threshold",
- &IntFireBase::setThresh,
- &IntFireBase::getThresh
- );
-
- static ElementValueFinfo< IntFireBase, double > vReset(
- "vReset",
- "voltage is set to vReset after firing",
- &IntFireBase::setVReset,
- &IntFireBase::getVReset
- );
-
- static ElementValueFinfo< IntFireBase, double > refractoryPeriod(
- "refractoryPeriod",
- "Minimum time between successive spikes",
- &IntFireBase::setRefractoryPeriod,
- &IntFireBase::getRefractoryPeriod
- );
-
- static ReadOnlyElementValueFinfo< IntFireBase, double > lastEventTime(
- "lastEventTime",
- "Timestamp of last firing.",
- &IntFireBase::getLastEventTime
- );
-
- static ReadOnlyElementValueFinfo< IntFireBase, bool > hasFired(
- "hasFired",
- "The object has fired within the last timestep",
- &IntFireBase::hasFired
- );
- //////////////////////////////////////////////////////////////
- // MsgDest Definitions
- //////////////////////////////////////////////////////////////
- static DestFinfo activation( "activation",
- "Handles value of synaptic activation arriving on this object",
- new OpFunc1< IntFireBase, double >( &IntFireBase::activation ));
-
- //////////////////////////////////////////////////////////////
-
- static Finfo* intFireFinfos[] = {
- &thresh, // Value
- &vReset, // Value
- &refractoryPeriod, // Value
- &hasFired, // ReadOnlyValue
- &lastEventTime, // ReadOnlyValue
- &activation, // DestFinfo
- IntFireBase::spikeOut() // MsgSrc
- };
-
- static string doc[] =
- {
- "Name", "IntFireBase",
- "Author", "Upi Bhalla",
- "Description", "Base class for Integrate-and-fire compartment.",
- };
+ //////////////////////////////////////////////////////////////
+ // Field Definitions
+ //////////////////////////////////////////////////////////////
+ static ElementValueFinfo< IntFireBase, double > thresh(
+ "thresh",
+ "firing threshold",
+ &IntFireBase::setThresh,
+ &IntFireBase::getThresh
+ );
+
+ static ElementValueFinfo< IntFireBase, double > vReset(
+ "vReset",
+ "voltage is set to vReset after firing",
+ &IntFireBase::setVReset,
+ &IntFireBase::getVReset
+ );
+
+ static ElementValueFinfo< IntFireBase, double > refractoryPeriod(
+ "refractoryPeriod",
+ "Minimum time between successive spikes",
+ &IntFireBase::setRefractoryPeriod,
+ &IntFireBase::getRefractoryPeriod
+ );
+
+ static ReadOnlyElementValueFinfo< IntFireBase, double > lastEventTime(
+ "lastEventTime",
+ "Timestamp of last firing.",
+ &IntFireBase::getLastEventTime
+ );
+
+ static ReadOnlyElementValueFinfo< IntFireBase, bool > hasFired(
+ "hasFired",
+ "The object has fired within the last timestep",
+ &IntFireBase::hasFired
+ );
+ //////////////////////////////////////////////////////////////
+ // MsgDest Definitions
+ //////////////////////////////////////////////////////////////
+ static DestFinfo activation(
+ "activation",
+ "Handles value of synaptic activation arriving on this object",
+ new OpFunc1< IntFireBase, double >( &IntFireBase::activation ));
+
+ //////////////////////////////////////////////////////////////
+
+ static Finfo* intFireFinfos[] =
+ {
+ &thresh, // Value
+ &vReset, // Value
+ &refractoryPeriod, // Value
+ &hasFired, // ReadOnlyValue
+ &lastEventTime, // ReadOnlyValue
+ &activation, // DestFinfo
+ IntFireBase::spikeOut() // MsgSrc
+ };
+
+ static string doc[] =
+ {
+ "Name", "IntFireBase",
+ "Author", "Upi Bhalla",
+ "Description", "Base class for Integrate-and-fire compartment.",
+ };
static ZeroSizeDinfo< int > dinfo;
- static Cinfo intFireBaseCinfo(
- "IntFireBase",
- Compartment::initCinfo(),
- intFireFinfos,
- sizeof( intFireFinfos ) / sizeof (Finfo*),
- &dinfo,
- doc,
- sizeof(doc)/sizeof(string)
- );
-
- return &intFireBaseCinfo;
+ static Cinfo intFireBaseCinfo(
+ "IntFireBase",
+ Compartment::initCinfo(),
+ intFireFinfos,
+ sizeof( intFireFinfos ) / sizeof (Finfo*),
+ &dinfo,
+ doc,
+ sizeof(doc)/sizeof(string)
+ );
+
+ return &intFireBaseCinfo;
}
static const Cinfo* intFireBaseCinfo = IntFireBase::initCinfo();
@@ -107,59 +109,59 @@ static const Cinfo* intFireBaseCinfo = IntFireBase::initCinfo();
//////////////////////////////////////////////////////////////////
IntFireBase::IntFireBase()
- :
- threshold_( 0.0 ),
- vReset_( 0.0 ),
- activation_( 0.0 ),
- refractT_( 0.0 ),
- lastEvent_( 0.0 ),
- fired_( false )
+ :
+ threshold_( 0.0 ),
+ vReset_( 0.0 ),
+ activation_( 0.0 ),
+ refractT_( 0.0 ),
+ lastEvent_( 0.0 ),
+ fired_( false )
{;}
IntFireBase::~IntFireBase()
{
- ;
+ ;
}
// Value Field access function definitions.
void IntFireBase::setThresh( const Eref& e, double val )
{
- threshold_ = val;
+ threshold_ = val;
}
double IntFireBase::getThresh( const Eref& e ) const
{
- return threshold_;
+ return threshold_;
}
void IntFireBase::setVReset( const Eref& e, double val )
{
- vReset_ = val;
+ vReset_ = val;
}
double IntFireBase::getVReset( const Eref& e ) const
{
- return vReset_;
+ return vReset_;
}
void IntFireBase::setRefractoryPeriod( const Eref& e, double val )
{
- refractT_ = val;
+ refractT_ = val;
}
double IntFireBase::getRefractoryPeriod( const Eref& e ) const
{
- return refractT_;
+ return refractT_;
}
double IntFireBase::getLastEventTime( const Eref& e ) const
{
- return lastEvent_;
+ return lastEvent_;
}
bool IntFireBase::hasFired( const Eref& e ) const
{
- return fired_;
+ return fired_;
}
//////////////////////////////////////////////////////////////////
@@ -168,5 +170,5 @@ bool IntFireBase::hasFired( const Eref& e ) const
void IntFireBase::activation( double v )
{
- activation_ += v;
+ activation_ += v;
}
diff --git a/intfire/IntFireBase.h b/intfire/IntFireBase.h
index c17dbdcabf6f62ae9ccf66565b45b1daa9660aa0..bbdc12d54f6578130bc39d67450701ee910d93dd 100644
--- a/intfire/IntFireBase.h
+++ b/intfire/IntFireBase.h
@@ -18,52 +18,52 @@ namespace moose
*/
class IntFireBase: public Compartment
{
- public:
- IntFireBase();
- virtual ~IntFireBase();
+public:
+ IntFireBase();
+ virtual ~IntFireBase();
- // Value Field access function definitions.
- void setThresh( const Eref& e, double val );
- double getThresh( const Eref& e ) const;
- void setVReset( const Eref& e, double val );
- double getVReset( const Eref& e ) const;
- void setRefractoryPeriod( const Eref& e, double val );
- double getRefractoryPeriod( const Eref& e ) const;
- double getLastEventTime( const Eref& e ) const;
- bool hasFired( const Eref& e ) const;
+ // Value Field access function definitions.
+ void setThresh( const Eref& e, double val );
+ double getThresh( const Eref& e ) const;
+ void setVReset( const Eref& e, double val );
+ double getVReset( const Eref& e ) const;
+ void setRefractoryPeriod( const Eref& e, double val );
+ double getRefractoryPeriod( const Eref& e ) const;
+ double getLastEventTime( const Eref& e ) const;
+ bool hasFired( const Eref& e ) const;
- // Dest function definitions.
- /**
- * The process function does the object updating and sends out
- * messages to channels, nernsts, and so on.
- */
- virtual void vProcess( const Eref& e, ProcPtr p ) = 0;
+ // Dest function definitions.
+ /**
+ * The process function does the object updating and sends out
+ * messages to channels, nernsts, and so on.
+ */
+ virtual void vProcess( const Eref& e, ProcPtr p ) = 0;
- /**
- * The reinit function reinitializes all fields.
- */
- virtual void vReinit( const Eref& e, ProcPtr p ) = 0;
+ /**
+ * The reinit function reinitializes all fields.
+ */
+ virtual void vReinit( const Eref& e, ProcPtr p ) = 0;
- /**
- * activation handles information coming from the SynHandler
- * to the intFire.
- */
- void activation( double val );
+ /**
+ * activation handles information coming from the SynHandler
+ * to the intFire.
+ */
+ void activation( double val );
- /// Message src for outgoing spikes.
- static SrcFinfo1< double >* spikeOut();
+ /// Message src for outgoing spikes.
+ static SrcFinfo1< double >* spikeOut();
- /**
- * Initializes the class info.
- */
- static const Cinfo* initCinfo();
- protected:
- double threshold_;
- double vReset_;
- double activation_;
- double refractT_;
- double lastEvent_;
- bool fired_;
+ /**
+ * Initializes the class info.
+ */
+ static const Cinfo* initCinfo();
+protected:
+ double threshold_;
+ double vReset_;
+ double activation_;
+ double refractT_;
+ double lastEvent_;
+ bool fired_;
};
} // namespace
diff --git a/intfire/LIF.cpp b/intfire/LIF.cpp
index 3812583acbd3bf30f69a096e70b8945bc127eee3..f1815ccde053449448896219c2c768b63eefda3c 100644
--- a/intfire/LIF.cpp
+++ b/intfire/LIF.cpp
@@ -7,8 +7,8 @@
** See the file COPYING.LIB for the full notice.
**********************************************************************/
-#include "header.h"
-#include "ElementValueFinfo.h"
+#include "../basecode/header.h"
+#include "../basecode/ElementValueFinfo.h"
#include "../biophysics/CompartmentBase.h"
#include "../biophysics/Compartment.h"
#include "IntFireBase.h"
@@ -18,23 +18,23 @@ using namespace moose;
const Cinfo* LIF::initCinfo()
{
- static string doc[] =
- {
- "Name", "LIF",
- "Author", "Upi Bhalla",
- "Description", "Leaky Integrate-and-Fire neuron"
- };
+ static string doc[] =
+ {
+ "Name", "LIF",
+ "Author", "Upi Bhalla",
+ "Description", "Leaky Integrate-and-Fire neuron"
+ };
static Dinfo< LIF > dinfo;
- static Cinfo lifCinfo(
- "LIF",
- IntFireBase::initCinfo(),
- 0, 0,
- &dinfo,
- doc,
- sizeof(doc)/sizeof(string)
- );
+ static Cinfo lifCinfo(
+ "LIF",
+ IntFireBase::initCinfo(),
+ 0, 0,
+ &dinfo,
+ doc,
+ sizeof(doc)/sizeof(string)
+ );
- return &lifCinfo;
+ return &lifCinfo;
}
static const Cinfo* lifCinfo = LIF::initCinfo();
@@ -44,10 +44,14 @@ static const Cinfo* lifCinfo = LIF::initCinfo();
//////////////////////////////////////////////////////////////////
LIF::LIF()
-{;}
+{
+ ;
+}
LIF::~LIF()
-{;}
+{
+ ;
+}
//////////////////////////////////////////////////////////////////
// LIF::Dest function definitions.
@@ -55,37 +59,43 @@ LIF::~LIF()
void LIF::vProcess( const Eref& e, ProcPtr p )
{
- fired_ = false;
- if ( p->currTime < lastEvent_ + refractT_ ) {
- Vm_ = vReset_;
- A_ = 0.0;
- B_ = 1.0 / Rm_;
- sumInject_ = 0.0;
- VmOut()->send( e, Vm_ );
- } else {
+ fired_ = false;
+ if ( p->currTime < lastEvent_ + refractT_ )
+ {
+ Vm_ = vReset_;
+ A_ = 0.0;
+ B_ = 1.0 / Rm_;
+ sumInject_ = 0.0;
+ VmOut()->send( e, Vm_ );
+ }
+ else
+ {
// activation can be a continous variable (graded synapse).
// So integrate it at every time step, thus *dt.
// For a delta-fn synapse, SynHandler-s divide by dt and send activation.
// See: http://www.genesis-sim.org/GENESIS/Hyperdoc/Manual-26.html#synchan
// for this continuous definition of activation.
- Vm_ += activation_ * p->dt;
- activation_ = 0.0;
- if ( Vm_ > threshold_ ) {
- Vm_ = vReset_;
- lastEvent_ = p->currTime;
- fired_ = true;
- spikeOut()->send( e, p->currTime );
- VmOut()->send( e, Vm_ );
- } else {
- Compartment::vProcess( e, p );
- }
- }
+ Vm_ += activation_ * p->dt;
+ activation_ = 0.0;
+ if ( Vm_ > threshold_ )
+ {
+ Vm_ = vReset_;
+ lastEvent_ = p->currTime;
+ fired_ = true;
+ spikeOut()->send( e, p->currTime );
+ VmOut()->send( e, Vm_ );
+ }
+ else
+ {
+ Compartment::vProcess( e, p );
+ }
+ }
}
void LIF::vReinit( const Eref& e, ProcPtr p )
{
- activation_ = 0.0;
- fired_ = false;
- lastEvent_ = -refractT_; // Allow it to fire right away.
- Compartment::vReinit( e, p );
+ activation_ = 0.0;
+ fired_ = false;
+ lastEvent_ = -refractT_; // Allow it to fire right away.
+ Compartment::vReinit( e, p );
}
diff --git a/intfire/LIF.h b/intfire/LIF.h
index 4b15f2c36082fa8dccec5121e1405d374b2de0e5..6bad50192924e1efec65e94c94075f1bb9aa3501 100644
--- a/intfire/LIF.h
+++ b/intfire/LIF.h
@@ -13,30 +13,32 @@
namespace moose
{
+
/**
* The IntFire class sets up an integrate-and-fire compartment.
*/
class LIF: public IntFireBase
{
- public:
- LIF();
- virtual ~LIF();
- /**
- * The process function does the object updating and sends out
- * messages to channels, nernsts, and so on.
- */
- void vProcess( const Eref& e, ProcPtr p );
+public:
+ LIF();
+ virtual ~LIF();
+ /**
+ * The process function does the object updating and sends out
+ * messages to channels, nernsts, and so on.
+ */
+ void vProcess( const Eref& e, ProcPtr p );
- /**
- * The reinit function reinitializes all fields.
- */
- void vReinit( const Eref& e, ProcPtr p );
+ /**
+ * The reinit function reinitializes all fields.
+ */
+ void vReinit( const Eref& e, ProcPtr p );
- /**
- * Initializes the class info.
- */
- static const Cinfo* initCinfo();
+ /**
+ * Initializes the class info.
+ */
+ static const Cinfo* initCinfo();
};
+
}
#endif // _LIF_H
diff --git a/kinetics/BufPool.cpp b/kinetics/BufPool.cpp
index 54e183780a6f76fcb1614878e70e02981b28ae25..a980ffc1ef3d413eab0378c5537c0cfdc9b541bb 100644
--- a/kinetics/BufPool.cpp
+++ b/kinetics/BufPool.cpp
@@ -7,7 +7,7 @@
** See the file COPYING.LIB for the full notice.
**********************************************************************/
-#include "header.h"
+#include "../basecode/header.h"
#include "PoolBase.h"
#include "Pool.h"
#include "BufPool.h"
@@ -17,28 +17,28 @@
const Cinfo* BufPool::initCinfo()
{
- //////////////////////////////////////////////////////////////
- // Field Definitions
- //////////////////////////////////////////////////////////////
-
- //////////////////////////////////////////////////////////////
- // MsgDest Definitions
- //////////////////////////////////////////////////////////////
-
- //////////////////////////////////////////////////////////////
- // SharedMsg Definitions
- //////////////////////////////////////////////////////////////
-
- static Dinfo< BufPool > dinfo;
- static Cinfo bufPoolCinfo (
- "BufPool",
- Pool::initCinfo(),
- 0,
- 0,
- &dinfo
- );
-
- return &bufPoolCinfo;
+ //////////////////////////////////////////////////////////////
+ // Field Definitions
+ //////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////
+ // MsgDest Definitions
+ //////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////
+ // SharedMsg Definitions
+ //////////////////////////////////////////////////////////////
+
+ static Dinfo< BufPool > dinfo;
+ static Cinfo bufPoolCinfo (
+ "BufPool",
+ Pool::initCinfo(),
+ 0,
+ 0,
+ &dinfo
+ );
+
+ return &bufPoolCinfo;
}
//////////////////////////////////////////////////////////////
@@ -58,24 +58,24 @@ BufPool::~BufPool()
void BufPool::vSetN( const Eref& e, double v )
{
- Pool::vSetN( e, v );
- Pool::vSetNinit( e, v );
+ Pool::vSetN( e, v );
+ Pool::vSetNinit( e, v );
}
void BufPool::vSetNinit( const Eref& e, double v )
{
- vSetN( e, v );
+ vSetN( e, v );
}
void BufPool::vSetConc( const Eref& e, double conc )
{
- double n = NA * conc * lookupVolumeFromMesh( e );
- vSetN( e, n );
+ double n = NA * conc * lookupVolumeFromMesh( e );
+ vSetN( e, n );
}
void BufPool::vSetConcInit( const Eref& e, double conc )
{
- vSetConc( e, conc );
+ vSetConc( e, conc );
}
//////////////////////////////////////////////////////////////
@@ -84,12 +84,12 @@ void BufPool::vSetConcInit( const Eref& e, double conc )
void BufPool::vProcess( const Eref& e, ProcPtr p )
{
- Pool::vReinit( e, p );
+ Pool::vReinit( e, p );
}
void BufPool::vReinit( const Eref& e, ProcPtr p )
{
- Pool::vReinit( e, p );
+ Pool::vReinit( e, p );
}
diff --git a/kinetics/BufPool.h b/kinetics/BufPool.h
index 45b401e71bfab50b73d7730c22994b159e1f73eb..a0282d9beb7b2b67707b6fa8202eefad9ae6f1ed 100644
--- a/kinetics/BufPool.h
+++ b/kinetics/BufPool.h
@@ -12,28 +12,28 @@
class BufPool: public Pool
{
- public:
- BufPool();
- ~BufPool();
+public:
+ BufPool();
+ ~BufPool();
- //////////////////////////////////////////////////////////////////
- // Field assignment stuff
- //////////////////////////////////////////////////////////////////
- /// The 'get' functions are simply inherited from Pool
- void vSetN( const Eref& e, double v );
- void vSetNinit( const Eref& e, double v );
- void vSetConc( const Eref& e, double v );
- void vSetConcInit( const Eref& e, double v );
+ //////////////////////////////////////////////////////////////////
+ // Field assignment stuff
+ //////////////////////////////////////////////////////////////////
+ /// The 'get' functions are simply inherited from Pool
+ void vSetN( const Eref& e, double v );
+ void vSetNinit( const Eref& e, double v );
+ void vSetConc( const Eref& e, double v );
+ void vSetConcInit( const Eref& e, double v );
- //////////////////////////////////////////////////////////////////
- // Dest funcs
- //////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////
+ // Dest funcs
+ //////////////////////////////////////////////////////////////////
- void vProcess( const Eref& e, ProcPtr p );
- void vReinit( const Eref& e, ProcPtr p );
+ void vProcess( const Eref& e, ProcPtr p );
+ void vReinit( const Eref& e, ProcPtr p );
- static const Cinfo* initCinfo();
- private:
+ static const Cinfo* initCinfo();
+private:
};
#endif // _BUF_POOL_H
diff --git a/kinetics/Pool.cpp b/kinetics/Pool.cpp
index 8b0eb62940d7b361d6e3b9db3236a70e310aedb3..b6b448baaa89b2f93ac1d86da308f6c04251f2f4 100644
--- a/kinetics/Pool.cpp
+++ b/kinetics/Pool.cpp
@@ -7,8 +7,8 @@
** See the file COPYING.LIB for the full notice.
**********************************************************************/
-#include "header.h"
-#include "ElementValueFinfo.h"
+#include "../basecode/header.h"
+#include "../basecode/ElementValueFinfo.h"
#include "lookupVolumeFromMesh.h"
#include "PoolBase.h"
#include "Pool.h"
@@ -17,41 +17,41 @@
const Cinfo* Pool::initCinfo()
{
- //////////////////////////////////////////////////////////////
- // Field Definitions: All inherited from PoolBase.
- //////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////
- // MsgDest Definitions: All inherited
- //////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////
- // SrcFinfo Definitions: All inherited.
- //////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////
- // SharedMsg Definitions: All inherited.
- //////////////////////////////////////////////////////////////
- static Dinfo< Pool > dinfo;
- static Cinfo poolCinfo (
- "Pool",
- PoolBase::initCinfo(),
- 0,
- 0,
- &dinfo
- );
-
- return &poolCinfo;
+ //////////////////////////////////////////////////////////////
+ // Field Definitions: All inherited from PoolBase.
+ //////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////
+ // MsgDest Definitions: All inherited
+ //////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////
+ // SrcFinfo Definitions: All inherited.
+ //////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////
+ // SharedMsg Definitions: All inherited.
+ //////////////////////////////////////////////////////////////
+ static Dinfo< Pool > dinfo;
+ static Cinfo poolCinfo (
+ "Pool",
+ PoolBase::initCinfo(),
+ 0,
+ 0,
+ &dinfo
+ );
+
+ return &poolCinfo;
}
//////////////////////////////////////////////////////////////
// Class definitions
//////////////////////////////////////////////////////////////
static const Cinfo* poolCinfo = Pool::initCinfo();
-const SrcFinfo1< double >& nOut =
- *dynamic_cast< const SrcFinfo1< double >* >(
- poolCinfo->findFinfo( "nOut" ) );
+
+const SrcFinfo1< double >& nOut = *dynamic_cast<const SrcFinfo1< double >*
+ >(poolCinfo->findFinfo( "nOut"));
Pool::Pool()
- : n_( 0.0 ), nInit_( 0.0 ), diffConst_( 0.0 ), motorConst_( 0.0 ),
- A_( 0.0 ), B_( 0.0 ), species_( 0 )
+ : n_( 0.0 ), nInit_( 0.0 ), diffConst_( 0.0 ), motorConst_( 0.0 ),
+ A_( 0.0 ), B_( 0.0 ), species_( 0 )
{;}
Pool::~Pool()
@@ -67,22 +67,25 @@ Pool::~Pool()
*/
void Pool::vSetIsBuffered( const Eref& e, bool v )
{
- static const Cinfo* bufPoolCinfo = Cinfo::find( "BufPool" );
- if (vGetIsBuffered( e ) == v)
- return;
- if (v) {
- e.element()->replaceCinfo( bufPoolCinfo );
- } else {
- e.element()->replaceCinfo( poolCinfo );
- }
+ static const Cinfo* bufPoolCinfo = Cinfo::find( "BufPool" );
+ if (vGetIsBuffered( e ) == v)
+ return;
+ if (v)
+ {
+ e.element()->replaceCinfo( bufPoolCinfo );
+ }
+ else
+ {
+ e.element()->replaceCinfo( poolCinfo );
+ }
}
bool Pool::vGetIsBuffered( const Eref& e ) const
{
- /// We need this explicit check because when the moose class is
- /// flipped, the internal C++ class isn't.
- /// Inherited by BufPool.
- return e.element()->cinfo()->name() == "BufPool";
+ /// We need this explicit check because when the moose class is
+ /// flipped, the internal C++ class isn't.
+ /// Inherited by BufPool.
+ return e.element()->cinfo()->name() == "BufPool";
}
//////////////////////////////////////////////////////////////
@@ -93,51 +96,54 @@ bool Pool::vGetIsBuffered( const Eref& e ) const
void Pool::vProcess( const Eref& e, ProcPtr p )
{
- // double A = e.sumBuf( aSlot );
- // double B = e.sumBuf( bSlot );
+ // double A = e.sumBuf( aSlot );
+ // double B = e.sumBuf( bSlot );
- if ( n_ > EPSILON && B_ > EPSILON ) {
- double C = exp( -B_ * p->dt / n_ );
- n_ *= C + (A_ / B_ ) * ( 1.0 - C );
- } else {
- n_ += ( A_ - B_ ) * p->dt;
- if ( n_ < 0.0 )
- n_ = 0.0;
- }
+ if ( n_ > EPSILON && B_ > EPSILON )
+ {
+ double C = exp( -B_ * p->dt / n_ );
+ n_ *= C + (A_ / B_ ) * ( 1.0 - C );
+ }
+ else
+ {
+ n_ += ( A_ - B_ ) * p->dt;
+ if ( n_ < 0.0 )
+ n_ = 0.0;
+ }
- A_ = B_ = 0.0;
+ A_ = B_ = 0.0;
- nOut.send( e, n_ );
+ nOut.send( e, n_ );
}
void Pool::vReinit( const Eref& e, ProcPtr p )
{
- A_ = B_ = 0.0;
- n_ = getNinit( e );
+ A_ = B_ = 0.0;
+ n_ = getNinit( e );
- nOut.send( e, n_ );
+ nOut.send( e, n_ );
}
void Pool::vReac( double A, double B )
{
- A_ += A;
- B_ += B;
+ A_ += A;
+ B_ += B;
}
void Pool::vIncrement( double val )
{
- if ( val > 0 )
- A_ += val;
- else
- B_ -= val;
+ if ( val > 0 )
+ A_ += val;
+ else
+ B_ -= val;
}
void Pool::vDecrement( double val )
{
- if ( val < 0 )
- A_ -= val;
- else
- B_ += val;
+ if ( val < 0 )
+ A_ -= val;
+ else
+ B_ += val;
}
void Pool::vnIn( double val)
@@ -149,7 +155,7 @@ void Pool::vnIn( double val)
void Pool::vHandleMolWt( const Eref& e, double v )
{
- ; // Here I should update DiffConst too.
+ ; // Here I should update DiffConst too.
}
//////////////////////////////////////////////////////////////
@@ -158,77 +164,77 @@ void Pool::vHandleMolWt( const Eref& e, double v )
void Pool::vSetN( const Eref& e, double v )
{
- n_ = v;
+ n_ = v;
}
double Pool::vGetN( const Eref& e ) const
{
- return n_;
+ return n_;
}
void Pool::vSetNinit( const Eref& e, double v )
{
- nInit_ = v;
+ nInit_ = v;
}
double Pool::vGetNinit( const Eref& e ) const
{
- return nInit_;
+ return nInit_;
}
// Conc is given in millimolar. Volume is in m^3
void Pool::vSetConc( const Eref& e, double c )
{
- n_ = NA * c * lookupVolumeFromMesh( e );
+ n_ = NA * c * lookupVolumeFromMesh( e );
}
// Returns conc in millimolar.
double Pool::vGetConc( const Eref& e ) const
{
- return (n_ / NA) / lookupVolumeFromMesh( e );
+ return (n_ / NA) / lookupVolumeFromMesh( e );
}
void Pool::vSetConcInit( const Eref& e, double c )
{
- nInit_ = NA * c * lookupVolumeFromMesh( e );
+ nInit_ = NA * c * lookupVolumeFromMesh( e );
}
void Pool::vSetDiffConst( const Eref& e, double v )
{
- diffConst_ = v;
+ diffConst_ = v;
}
double Pool::vGetDiffConst( const Eref& e ) const
{
- return diffConst_;
+ return diffConst_;
}
void Pool::vSetMotorConst( const Eref& e, double v )
{
- motorConst_ = v;
+ motorConst_ = v;
}
double Pool::vGetMotorConst( const Eref& e ) const
{
- return motorConst_;
+ return motorConst_;
}
void Pool::vSetVolume( const Eref& e, double v )
{
- cout << "Warning: Pool::vSetVolume: Operation not permitted. Ignored\n";
+ cout << "Warning: Pool::vSetVolume: Operation not permitted. Ignored\n";
}
double Pool::vGetVolume( const Eref& e ) const
{
- return lookupVolumeFromMesh( e );
+ return lookupVolumeFromMesh( e );
}
void Pool::vSetSpecies( const Eref& e, SpeciesId v )
{
- species_ = v;
+ species_ = v;
}
SpeciesId Pool::vGetSpecies( const Eref& e ) const
{
- return species_;
+ return species_;
}
diff --git a/kinetics/Pool.h b/kinetics/Pool.h
index bc4e88770a781fc67b59b2a6a6f442f4e32f46dd..51fbc5124570ba3e0e223b42e33dcc3fe0fd4a83 100644
--- a/kinetics/Pool.h
+++ b/kinetics/Pool.h
@@ -18,80 +18,80 @@
*/
class Pool: public PoolBase
{
- public:
- Pool();
- ~Pool();
+public:
+ Pool();
+ ~Pool();
- //////////////////////////////////////////////////////////////////
- // Field assignment stuff. All override virtual funcs in the Pool
- // base class.
- //////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////
+ // Field assignment stuff. All override virtual funcs in the Pool
+ // base class.
+ //////////////////////////////////////////////////////////////////
- void vSetN( const Eref& e, double v );
- double vGetN( const Eref& e ) const;
- void vSetNinit( const Eref& e, double v );
- double vGetNinit( const Eref& e ) const;
- void vSetDiffConst( const Eref& e, double v );
- double vGetDiffConst( const Eref& e ) const;
- void vSetMotorConst( const Eref& e, double v );
- double vGetMotorConst( const Eref& e ) const;
+ void vSetN( const Eref& e, double v );
+ double vGetN( const Eref& e ) const;
+ void vSetNinit( const Eref& e, double v );
+ double vGetNinit( const Eref& e ) const;
+ void vSetDiffConst( const Eref& e, double v );
+ double vGetDiffConst( const Eref& e ) const;
+ void vSetMotorConst( const Eref& e, double v );
+ double vGetMotorConst( const Eref& e ) const;
- void vSetConc( const Eref& e, double v );
- double vGetConc( const Eref& e ) const;
- void vSetConcInit( const Eref& e, double v );
- // double vGetConcInit( const Eref& e ) const;
+ void vSetConc( const Eref& e, double v );
+ double vGetConc( const Eref& e ) const;
+ void vSetConcInit( const Eref& e, double v );
+ // double vGetConcInit( const Eref& e ) const;
- /**
- * Volume is usually volume, but we also permit areal density
- * This is obtained by looking up the corresponding spatial mesh
- * entry in the parent compartment. If the message isn't set then
- * it defaults to 1.0.
- */
- void vSetVolume( const Eref& e, double v );
- double vGetVolume( const Eref& e ) const;
+ /**
+ * Volume is usually volume, but we also permit areal density
+ * This is obtained by looking up the corresponding spatial mesh
+ * entry in the parent compartment. If the message isn't set then
+ * it defaults to 1.0.
+ */
+ void vSetVolume( const Eref& e, double v );
+ double vGetVolume( const Eref& e ) const;
- void vSetSpecies( const Eref& e, SpeciesId v );
- SpeciesId vGetSpecies( const Eref& e ) const;
+ void vSetSpecies( const Eref& e, SpeciesId v );
+ SpeciesId vGetSpecies( const Eref& e ) const;
- /**
- * Functions to examine and change class between Pool and BufPool.
- */
- void vSetIsBuffered( const Eref& e, bool v );
- bool vGetIsBuffered( const Eref& e) const;
+ /**
+ * Functions to examine and change class between Pool and BufPool.
+ */
+ void vSetIsBuffered( const Eref& e, bool v );
+ bool vGetIsBuffered( const Eref& e) const;
- //////////////////////////////////////////////////////////////////
- // Dest funcs. These too override virtual funcs in the Pool base
- // class.
- //////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////
+ // Dest funcs. These too override virtual funcs in the Pool base
+ // class.
+ //////////////////////////////////////////////////////////////////
- void vHandleMolWt( const Eref& e, double v );
- void vProcess( const Eref& e, ProcPtr p );
- void vReinit( const Eref& e, ProcPtr p );
- void vReac( double A, double B );
- void vIncrement( double val );
- void vDecrement( double val );
- void vnIn( double val );
+ void vHandleMolWt( const Eref& e, double v );
+ void vProcess( const Eref& e, ProcPtr p );
+ void vReinit( const Eref& e, ProcPtr p );
+ void vReac( double A, double B );
+ void vIncrement( double val );
+ void vDecrement( double val );
+ void vnIn( double val );
- //////////////////////////////////////////////////////////////////
- // Novel Dest funcs not present in Pool base class.
- //////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////
+ // Novel Dest funcs not present in Pool base class.
+ //////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////
- static const Cinfo* initCinfo();
- private:
- double n_; /// Number of molecules in pool
- double nInit_; /// initial number of molecules.
- double diffConst_; /// Diffusion constant
- double motorConst_; /// Motor transport constant
- double A_; /// Internal state variables, used only in explict mode
- double B_;
+ //////////////////////////////////////////////////////////////////
+ static const Cinfo* initCinfo();
+private:
+ double n_; /// Number of molecules in pool
+ double nInit_; /// initial number of molecules.
+ double diffConst_; /// Diffusion constant
+ double motorConst_; /// Motor transport constant
+ double A_; /// Internal state variables, used only in explict mode
+ double B_;
- /**
- * System wide identifier for all mol pools that are chemically
- * the same species.
- */
- unsigned int species_;
+ /**
+ * System wide identifier for all mol pools that are chemically
+ * the same species.
+ */
+ unsigned int species_;
};
#endif // _POOL_H
diff --git a/kinetics/PoolBase.cpp b/kinetics/PoolBase.cpp
index f1d7e0f44ba4984981c3a1b2f48e8fd6d0678843..b00153f4198897008e089b7b00109bee0c13cfc8 100644
--- a/kinetics/PoolBase.cpp
+++ b/kinetics/PoolBase.cpp
@@ -18,201 +18,205 @@ const SpeciesId DefaultSpeciesId = 0;
const Cinfo* PoolBase::initCinfo()
{
- //////////////////////////////////////////////////////////////
- // Field Definitions
- //////////////////////////////////////////////////////////////
- static ElementValueFinfo< PoolBase, double > n(
- "n",
- "Number of molecules in pool",
- &PoolBase::setN,
- &PoolBase::getN
- );
-
- static ElementValueFinfo< PoolBase, double > nInit(
- "nInit",
- "Initial value of number of molecules in pool",
- &PoolBase::setNinit,
- &PoolBase::getNinit
- );
-
- static ElementValueFinfo< PoolBase, double > diffConst(
- "diffConst",
- "Diffusion constant of molecule",
- &PoolBase::setDiffConst,
- &PoolBase::getDiffConst
- );
-
- static ElementValueFinfo< PoolBase, double > motorConst(
- "motorConst",
- "Motor transport rate molecule. + is away from soma, - is "
- "towards soma. Only relevant for ZombiePool subclasses.",
- &PoolBase::setMotorConst,
- &PoolBase::getMotorConst
- );
-
- static ElementValueFinfo< PoolBase, double > conc(
- "conc",
- "Concentration of molecules in this pool",
- &PoolBase::setConc,
- &PoolBase::getConc
- );
-
- static ElementValueFinfo< PoolBase, double > concInit(
- "concInit",
- "Initial value of molecular concentration in pool",
- &PoolBase::setConcInit,
- &PoolBase::getConcInit
- );
-
- static ElementValueFinfo< PoolBase, double > volume(
- "volume",
- "Volume of compartment. Units are SI. "
- "Utility field, the actual volume info is "
- "stored on a volume mesh entry in the parent compartment."
- "This mapping is implicit: the parent compartment must be "
- "somewhere up the element tree, and must have matching mesh "
- "entries. If the compartment isn't"
- "available the volume is just taken as 1",
- &PoolBase::setVolume,
- &PoolBase::getVolume
- );
-
- static ElementValueFinfo< PoolBase, unsigned int > speciesId(
- "speciesId",
- "Species identifier for this mol pool. Eventually link to ontology.",
- &PoolBase::setSpecies,
- &PoolBase::getSpecies
- );
-
- static ElementValueFinfo< PoolBase, bool > isBuffered(
- "isBuffered",
- "Flag: True if Pool is buffered. "
- "In the case of Pool and BufPool the field can be assigned, to "
- "change the type of the Pool object to BufPool, or vice versa. "
- "None of the messages are affected. "
- "This object class flip can only be done in the non-zombified "
- "form of the Pool/BufPool. In Zombies it is read-only.",
- &PoolBase::setIsBuffered,
- &PoolBase::getIsBuffered
- );
-
- //////////////////////////////////////////////////////////////
- // MsgDest Definitions
- //////////////////////////////////////////////////////////////
- static DestFinfo process( "process",
- "Handles process call",
- new ProcOpFunc< PoolBase >( &PoolBase::process ) );
- static DestFinfo reinit( "reinit",
- "Handles reinit call",
- new ProcOpFunc< PoolBase >( &PoolBase::reinit ) );
-
- static DestFinfo reacDest( "reacDest",
- "Handles reaction input",
- new OpFunc2< PoolBase, double, double >( &PoolBase::reac )
- );
-
- static DestFinfo handleMolWt( "handleMolWt",
- "Separate finfo to assign molWt, and consequently diffusion const."
- "Should only be used in SharedMsg with species.",
- new EpFunc1< PoolBase, double >( &PoolBase::handleMolWt )
- );
- //////////////////////////////////////////////////////////////
- // MsgDest Definitions: These three are used for non-reaction
- // calculations involving algebraically defined rate terms.
- //////////////////////////////////////////////////////////////
- static DestFinfo increment( "increment",
- "Increments mol numbers by specified amount. Can be +ve or -ve",
- new OpFunc1< PoolBase, double >( &PoolBase::increment )
- );
-
- static DestFinfo decrement( "decrement",
- "Decrements mol numbers by specified amount. Can be +ve or -ve",
- new OpFunc1< PoolBase, double >( &PoolBase::decrement )
- );
-
- static DestFinfo nIn( "nIn",
- "Assigns the number of molecules in Pool to specified value",
- new OpFunc1< PoolBase, double >( &PoolBase::nIn )
- );
-
- //////////////////////////////////////////////////////////////
- // SrcFinfo Definitions
- //////////////////////////////////////////////////////////////
-
- static SrcFinfo1< double > nOut(
- "nOut",
- "Sends out # of molecules in pool on each timestep"
- );
-
- static SrcFinfo0 requestMolWt(
- "requestMolWt",
- "Requests Species object for mol wt"
- );
-
- //////////////////////////////////////////////////////////////
- // SharedMsg Definitions
- //////////////////////////////////////////////////////////////
- static Finfo* reacShared[] = {
- &reacDest, &nOut
- };
- static SharedFinfo reac( "reac",
- "Connects to reaction",
- reacShared, sizeof( reacShared ) / sizeof( const Finfo* )
- );
- static Finfo* procShared[] = {
- &process, &reinit
- };
- static SharedFinfo proc( "proc",
- "Shared message for process and reinit",
- procShared, sizeof( procShared ) / sizeof( const Finfo* )
- );
-
- static Finfo* speciesShared[] = {
- &requestMolWt, &handleMolWt
- };
-
- static SharedFinfo species( "species",
- "Shared message for connecting to species objects",
- speciesShared, sizeof( speciesShared ) / sizeof ( const Finfo* )
- );
-
- static Finfo* poolFinfos[] = {
- &n, // Value
- &nInit, // Value
- &diffConst, // Value
- &motorConst, // Value
- &conc, // Value
- &concInit, // Value
- &volume, // Readonly Value
- &speciesId, // Value
- &isBuffered, // Value
- &increment, // DestFinfo
- &decrement, // DestFinfo
+ //////////////////////////////////////////////////////////////
+ // Field Definitions
+ //////////////////////////////////////////////////////////////
+ static ElementValueFinfo< PoolBase, double > n(
+ "n",
+ "Number of molecules in pool",
+ &PoolBase::setN,
+ &PoolBase::getN
+ );
+
+ static ElementValueFinfo< PoolBase, double > nInit(
+ "nInit",
+ "Initial value of number of molecules in pool",
+ &PoolBase::setNinit,
+ &PoolBase::getNinit
+ );
+
+ static ElementValueFinfo< PoolBase, double > diffConst(
+ "diffConst",
+ "Diffusion constant of molecule",
+ &PoolBase::setDiffConst,
+ &PoolBase::getDiffConst
+ );
+
+ static ElementValueFinfo< PoolBase, double > motorConst(
+ "motorConst",
+ "Motor transport rate molecule. + is away from soma, - is "
+ "towards soma. Only relevant for ZombiePool subclasses.",
+ &PoolBase::setMotorConst,
+ &PoolBase::getMotorConst
+ );
+
+ static ElementValueFinfo< PoolBase, double > conc(
+ "conc",
+ "Concentration of molecules in this pool",
+ &PoolBase::setConc,
+ &PoolBase::getConc
+ );
+
+ static ElementValueFinfo< PoolBase, double > concInit(
+ "concInit",
+ "Initial value of molecular concentration in pool",
+ &PoolBase::setConcInit,
+ &PoolBase::getConcInit
+ );
+
+ static ElementValueFinfo< PoolBase, double > volume(
+ "volume",
+ "Volume of compartment. Units are SI. "
+ "Utility field, the actual volume info is "
+ "stored on a volume mesh entry in the parent compartment."
+ "This mapping is implicit: the parent compartment must be "
+ "somewhere up the element tree, and must have matching mesh "
+ "entries. If the compartment isn't"
+ "available the volume is just taken as 1",
+ &PoolBase::setVolume,
+ &PoolBase::getVolume
+ );
+
+ static ElementValueFinfo< PoolBase, unsigned int > speciesId(
+ "speciesId",
+ "Species identifier for this mol pool. Eventually link to ontology.",
+ &PoolBase::setSpecies,
+ &PoolBase::getSpecies
+ );
+
+ static ElementValueFinfo< PoolBase, bool > isBuffered(
+ "isBuffered",
+ "Flag: True if Pool is buffered. "
+ "In the case of Pool and BufPool the field can be assigned, to "
+ "change the type of the Pool object to BufPool, or vice versa. "
+ "None of the messages are affected. "
+ "This object class flip can only be done in the non-zombified "
+ "form of the Pool/BufPool. In Zombies it is read-only.",
+ &PoolBase::setIsBuffered,
+ &PoolBase::getIsBuffered
+ );
+
+ //////////////////////////////////////////////////////////////
+ // MsgDest Definitions
+ //////////////////////////////////////////////////////////////
+ static DestFinfo process( "process",
+ "Handles process call",
+ new ProcOpFunc< PoolBase >( &PoolBase::process ) );
+ static DestFinfo reinit( "reinit",
+ "Handles reinit call",
+ new ProcOpFunc< PoolBase >( &PoolBase::reinit ) );
+
+ static DestFinfo reacDest( "reacDest",
+ "Handles reaction input",
+ new OpFunc2< PoolBase, double, double >( &PoolBase::reac )
+ );
+
+ static DestFinfo handleMolWt( "handleMolWt",
+ "Separate finfo to assign molWt, and consequently diffusion const."
+ "Should only be used in SharedMsg with species.",
+ new EpFunc1< PoolBase, double >( &PoolBase::handleMolWt )
+ );
+ //////////////////////////////////////////////////////////////
+ // MsgDest Definitions: These three are used for non-reaction
+ // calculations involving algebraically defined rate terms.
+ //////////////////////////////////////////////////////////////
+ static DestFinfo increment( "increment",
+ "Increments mol numbers by specified amount. Can be +ve or -ve",
+ new OpFunc1< PoolBase, double >( &PoolBase::increment )
+ );
+
+ static DestFinfo decrement( "decrement",
+ "Decrements mol numbers by specified amount. Can be +ve or -ve",
+ new OpFunc1< PoolBase, double >( &PoolBase::decrement )
+ );
+
+ static DestFinfo nIn( "nIn",
+ "Assigns the number of molecules in Pool to specified value",
+ new OpFunc1< PoolBase, double >( &PoolBase::nIn )
+ );
+
+ //////////////////////////////////////////////////////////////
+ // SrcFinfo Definitions
+ //////////////////////////////////////////////////////////////
+
+ static SrcFinfo1< double > nOut(
+ "nOut",
+ "Sends out # of molecules in pool on each timestep"
+ );
+
+ static SrcFinfo0 requestMolWt(
+ "requestMolWt",
+ "Requests Species object for mol wt"
+ );
+
+ //////////////////////////////////////////////////////////////
+ // SharedMsg Definitions
+ //////////////////////////////////////////////////////////////
+ static Finfo* reacShared[] =
+ {
+ &reacDest, &nOut
+ };
+ static SharedFinfo reac( "reac",
+ "Connects to reaction",
+ reacShared, sizeof( reacShared ) / sizeof( const Finfo* )
+ );
+ static Finfo* procShared[] =
+ {
+ &process, &reinit
+ };
+ static SharedFinfo proc( "proc",
+ "Shared message for process and reinit",
+ procShared, sizeof( procShared ) / sizeof( const Finfo* )
+ );
+
+ static Finfo* speciesShared[] =
+ {
+ &requestMolWt, &handleMolWt
+ };
+
+ static SharedFinfo species( "species",
+ "Shared message for connecting to species objects",
+ speciesShared, sizeof( speciesShared ) / sizeof ( const Finfo* )
+ );
+
+ static Finfo* poolFinfos[] =
+ {
+ &n, // Value
+ &nInit, // Value
+ &diffConst, // Value
+ &motorConst, // Value
+ &conc, // Value
+ &concInit, // Value
+ &volume, // Readonly Value
+ &speciesId, // Value
+ &isBuffered, // Value
+ &increment, // DestFinfo
+ &decrement, // DestFinfo
&nIn, // DestFinfo
- &reac, // SharedFinfo
- &proc, // SharedFinfo
- &species, // SharedFinfo
- };
-
- static string doc[] =
- {
- "Name", "PoolBase",
- "Author", "Upi Bhalla",
- "Description", "Abstract base class for pools."
- };
- static ZeroSizeDinfo< int > dinfo;
- static Cinfo poolCinfo (
- "PoolBase",
- Neutral::initCinfo(),
- poolFinfos,
- sizeof( poolFinfos ) / sizeof ( Finfo* ),
- &dinfo,
- doc,
- sizeof( doc )/sizeof( string ),
- true // Ban creation as this is an abstract base class.
- );
-
- return &poolCinfo;
+ &reac, // SharedFinfo
+ &proc, // SharedFinfo
+ &species, // SharedFinfo
+ };
+
+ static string doc[] =
+ {
+ "Name", "PoolBase",
+ "Author", "Upi Bhalla",
+ "Description", "Abstract base class for pools."
+ };
+ static ZeroSizeDinfo< int > dinfo;
+ static Cinfo poolCinfo (
+ "PoolBase",
+ Neutral::initCinfo(),
+ poolFinfos,
+ sizeof( poolFinfos ) / sizeof ( Finfo* ),
+ &dinfo,
+ doc,
+ sizeof( doc )/sizeof( string ),
+ true // Ban creation as this is an abstract base class.
+ );
+
+ return &poolCinfo;
}
//////////////////////////////////////////////////////////////
@@ -222,7 +226,7 @@ static const Cinfo* poolCinfo = PoolBase::initCinfo();
//////////////////////////////////////////////////////////////
PoolBase::PoolBase()
- : concInit_( 0.0 )
+ : concInit_( 0.0 )
{;}
PoolBase::~PoolBase()
@@ -234,37 +238,37 @@ PoolBase::~PoolBase()
void PoolBase::process( const Eref& e, ProcPtr p )
{
- vProcess( e, p );
+ vProcess( e, p );
}
void PoolBase::reinit( const Eref& e, ProcPtr p )
{
- vReinit( e, p );
+ vReinit( e, p );
}
void PoolBase::increment( double val )
{
- vIncrement(val);
+ vIncrement(val);
}
void PoolBase::decrement( double val )
{
- vDecrement( val );
+ vDecrement( val );
}
void PoolBase::nIn( double val)
{
- vnIn(val);
+ vnIn(val);
}
void PoolBase::reac( double A, double B )
{
- vReac( A, B );
+ vReac( A, B );
}
void PoolBase::handleMolWt( const Eref& e, double v )
{
- vHandleMolWt( e, v );
+ vHandleMolWt( e, v );
}
//////////////////////////////////////////////////////////////
@@ -298,92 +302,92 @@ void PoolBase::vnIn( double val)
void PoolBase::setN( const Eref& e, double v )
{
- vSetN( e, v );
+ vSetN( e, v );
}
double PoolBase::getN( const Eref& e ) const
{
- return vGetN( e );
+ return vGetN( e );
}
void PoolBase::setNinit( const Eref& e, double v )
{
- concInit_ = v / ( NA * lookupVolumeFromMesh( e ) );
- vSetNinit( e, v );
+ concInit_ = v / ( NA * lookupVolumeFromMesh( e ) );
+ vSetNinit( e, v );
}
double PoolBase::getNinit( const Eref& e ) const
{
- return vGetNinit( e );
+ return vGetNinit( e );
}
// Conc is given in millimolar. Volume is in m^3
void PoolBase::setConc( const Eref& e, double c )
{
- vSetConc( e, c );
+ vSetConc( e, c );
}
// Returns conc in millimolar.
double PoolBase::getConc( const Eref& e ) const
{
- return vGetConc( e );
+ return vGetConc( e );
}
void PoolBase::setConcInit( const Eref& e, double c )
{
- concInit_ = c;
- vSetConcInit( e, c );
+ concInit_ = c;
+ vSetConcInit( e, c );
}
double PoolBase::vGetConcInit( const Eref& e ) const
{
- return concInit_;
+ return concInit_;
}
double PoolBase::getConcInit( const Eref& e ) const
{
- // return concInit_;
- return vGetConcInit( e );
+ // return concInit_;
+ return vGetConcInit( e );
}
void PoolBase::setDiffConst( const Eref& e, double v )
{
- vSetDiffConst( e, v );
+ vSetDiffConst( e, v );
}
double PoolBase::getDiffConst(const Eref& e ) const
{
- return vGetDiffConst( e );
+ return vGetDiffConst( e );
}
void PoolBase::setMotorConst( const Eref& e, double v )
{
- vSetMotorConst( e, v );
+ vSetMotorConst( e, v );
}
double PoolBase::getMotorConst(const Eref& e ) const
{
- return vGetMotorConst( e );
+ return vGetMotorConst( e );
}
void PoolBase::setVolume( const Eref& e, double v )
{
- vSetVolume( e, v );
+ vSetVolume( e, v );
}
double PoolBase::getVolume( const Eref& e ) const
{
- return vGetVolume( e );
+ return vGetVolume( e );
}
void PoolBase::setSpecies( const Eref& e, unsigned int v )
{
- vSetSpecies( e, v );
+ vSetSpecies( e, v );
}
unsigned int PoolBase::getSpecies( const Eref& e ) const
{
- return vGetSpecies( e );
+ return vGetSpecies( e );
}
/**
@@ -391,12 +395,12 @@ unsigned int PoolBase::getSpecies( const Eref& e ) const
*/
void PoolBase::setIsBuffered( const Eref& e, bool v )
{
- vSetIsBuffered( e, v );
+ vSetIsBuffered( e, v );
}
bool PoolBase::getIsBuffered( const Eref& e ) const
{
- return vGetIsBuffered( e );
+ return vGetIsBuffered( e );
}
//////////////////////////////////////////////////////////////
@@ -409,7 +413,7 @@ void PoolBase::vSetMotorConst( const Eref& e, double v )
double PoolBase::vGetMotorConst(const Eref& e ) const
{
- return 0.0;
+ return 0.0;
}
/// Dummy default function for most pool subclasses.
@@ -424,41 +428,43 @@ void PoolBase::vSetIsBuffered( const Eref& e, bool v )
//////////////////////////////////////////////////////////////
// static func
void PoolBase::zombify( Element* orig, const Cinfo* zClass,
- Id ksolve, Id dsolve )
+ Id ksolve, Id dsolve )
{
- if ( orig->cinfo() == zClass )
- return;
- unsigned int start = orig->localDataStart();
- unsigned int num = orig->numLocalData();
- if ( num == 0 )
- return;
- vector< unsigned int > species( num, 0 );
- vector< double > concInit( num, 0.0 );
- vector< double > diffConst( num, 0.0 );
- vector< double > motorConst( num, 0.0 );
- for ( unsigned int i = 0; i < num; ++i ) {
- Eref er( orig, i + start );
- const PoolBase* pb =
- reinterpret_cast< const PoolBase* >( er.data() );
- species[ i ] = pb->getSpecies( er );
- concInit[ i ] = pb->getConcInit( er );
- diffConst[ i ] = pb->getDiffConst( er );
- motorConst[ i ] = pb->getMotorConst( er );
- }
- orig->zombieSwap( zClass );
- for ( unsigned int i = 0; i < num; ++i ) {
- Eref er( orig, i + start );
- PoolBase* pb = reinterpret_cast< PoolBase* >( er.data() );
- pb->vSetSolver( ksolve, dsolve );
- pb->setSpecies( er, species[i] );
- pb->setConcInit( er, concInit[i] );
- pb->setDiffConst( er, diffConst[i] );
- pb->setMotorConst( er, motorConst[i] );
- }
+ if ( orig->cinfo() == zClass )
+ return;
+ unsigned int start = orig->localDataStart();
+ unsigned int num = orig->numLocalData();
+ if ( num == 0 )
+ return;
+ vector< unsigned int > species( num, 0 );
+ vector< double > concInit( num, 0.0 );
+ vector< double > diffConst( num, 0.0 );
+ vector< double > motorConst( num, 0.0 );
+ for ( unsigned int i = 0; i < num; ++i )
+ {
+ Eref er( orig, i + start );
+ const PoolBase* pb =
+ reinterpret_cast< const PoolBase* >( er.data() );
+ species[ i ] = pb->getSpecies( er );
+ concInit[ i ] = pb->getConcInit( er );
+ diffConst[ i ] = pb->getDiffConst( er );
+ motorConst[ i ] = pb->getMotorConst( er );
+ }
+ orig->zombieSwap( zClass );
+ for ( unsigned int i = 0; i < num; ++i )
+ {
+ Eref er( orig, i + start );
+ PoolBase* pb = reinterpret_cast< PoolBase* >( er.data() );
+ pb->vSetSolver( ksolve, dsolve );
+ pb->setSpecies( er, species[i] );
+ pb->setConcInit( er, concInit[i] );
+ pb->setDiffConst( er, diffConst[i] );
+ pb->setMotorConst( er, motorConst[i] );
+ }
}
// Virtual func: default does nothing.
void PoolBase::vSetSolver( Id ksolve, Id dsolve )
{
- ;
+ ;
}
diff --git a/kinetics/PoolBase.h b/kinetics/PoolBase.h
index b5aaa1b8d545e363f1c413786ba7c73b5ada9400..20ab0000eaf6b62092a65bc58104176285ca1edb 100644
--- a/kinetics/PoolBase.h
+++ b/kinetics/PoolBase.h
@@ -29,134 +29,134 @@ extern const SpeciesId DefaultSpeciesId;
*/
class PoolBase
{
- friend void testSyncArray( unsigned int size, unsigned int numThreads,
- unsigned int method );
- friend void checkVal( double time, const PoolBase* m, unsigned int size );
- friend void forceCheckVal( double time, Element* e, unsigned int size );
-
- public:
- PoolBase();
- virtual ~PoolBase();
-
- //////////////////////////////////////////////////////////////////
- // Field assignment stuff: Interface for the Cinfo, hence regular
- // funcs. These internally call the virtual funcs that do the real
- // work.
- //////////////////////////////////////////////////////////////////
- void setN( const Eref& e, double v );
- double getN( const Eref& e ) const;
- void setNinit( const Eref& e, double v );
- double getNinit( const Eref& e ) const;
- void setDiffConst( const Eref& e, double v );
- double getDiffConst( const Eref& e ) const;
- void setMotorConst( const Eref& e, double v );
- double getMotorConst( const Eref& e ) const;
-
- void setConc( const Eref& e, double v );
- double getConc( const Eref& e ) const;
- void setConcInit( const Eref& e, double v );
- double getConcInit( const Eref& e ) const;
-
- /**
- * Volume is usually volume, but we also permit areal density
- * This is obtained by looking up the corresponding spatial mesh
- * entry in the parent compartment. If the message isn't set then
- * it defaults to 1.0.
- */
- void setVolume( const Eref& e, double v );
- double getVolume( const Eref& e ) const;
-
- void setSpecies( const Eref& e, SpeciesId v );
- SpeciesId getSpecies( const Eref& e ) const;
- /**
- * Functions to examine and change class between Pool and BufPool.
- */
- void setIsBuffered( const Eref& e, bool v );
- bool getIsBuffered( const Eref& e ) const;
-
- //////////////////////////////////////////////////////////////////
- // Here are the inner virtual funcs for fields.
- // All these are pure virtual
- //////////////////////////////////////////////////////////////////
-
- virtual void vSetN( const Eref& e, double v ) = 0;
- virtual double vGetN( const Eref& e ) const = 0;
- virtual void vSetNinit( const Eref& e, double v ) = 0;
- virtual double vGetNinit( const Eref& e ) const = 0;
- virtual void vSetDiffConst( const Eref& e, double v ) = 0;
- virtual double vGetDiffConst( const Eref& e ) const = 0;
- virtual void vSetMotorConst( const Eref& e, double v );
- virtual double vGetMotorConst( const Eref& e ) const;
-
- virtual void vSetConc( const Eref& e, double v ) = 0;
- virtual double vGetConc( const Eref& e ) const = 0;
- virtual void vSetConcInit( const Eref& e, double v ) = 0;
- virtual double vGetConcInit( const Eref& e ) const;
- virtual double vGetVolume( const Eref& e ) const = 0;
- virtual void vSetVolume( const Eref& e, double v ) = 0;
- virtual void vSetSpecies( const Eref& e, SpeciesId v ) = 0;
- virtual SpeciesId vGetSpecies( const Eref& e ) const = 0;
- /// I put in a default empty function for vSetIsBuffered.
- virtual void vSetIsBuffered( const Eref& e, bool v );
- virtual bool vGetIsBuffered( const Eref& e) const = 0;
- /**
- * Assign whatever info is needed by the zombie based on the
- * solver Element. Encapsulates some unpleasant field extraction,
- * casting, and assignment. Default version of this function does
- * nothing.
- */
- virtual void vSetSolver( Id ksolve, Id dsolve );
-
- //////////////////////////////////////////////////////////////////
- /**
- * zombify is the base function for conversion between pool
- * subclasses. This can be overridden, but should work for most
- * things. This takes the original Element, and without touching
- * its messaging, replaces it with a new data object of the
- * specified zClass. It does the best it can with conversion of
- * fields. Typically needs to be followed by rescheduling and
- * possibly a class-specific function for assigning further
- * zombie fields outside the ken of the PoolBase.
- * The 'solver' argument specifies which objects handle the solver
- * for this conversion. For the Pool this is either or both of
- * a kinetic solver /ksolve/ and a diffusion solver /dsolve/.
- * The term zombie arises because this operation was originally
- * carried out to strip an object of independent function, and
- * replace it with a solver-controlled facsimile.
- */
- static void zombify( Element* original, const Cinfo* zClass,
- Id ksolve, Id dsolve );
-
- //////////////////////////////////////////////////////////////////
- // Dest funcs
- //////////////////////////////////////////////////////////////////
- void process( const Eref& e, ProcPtr p );
- void reinit( const Eref& e, ProcPtr p );
- void reac( double A, double B );
- void handleMolWt( const Eref& e, double v );
- void increment( double val );
- void decrement( double val );
- void nIn( double val );
-
- //////////////////////////////////////////////////////////////////
- // Virtual Dest funcs. Most of these have a generic do-nothing
- // function here, as most of the derived classes don't need to
- // do anything.
- //////////////////////////////////////////////////////////////////
- virtual void vProcess( const Eref& e, ProcPtr p );
- virtual void vReinit( const Eref& e, ProcPtr p );
- virtual void vReac( double A, double B );
- virtual void vHandleMolWt( const Eref& e, double v);
- virtual void vIncrement( double val );
- virtual void vDecrement( double val );
- virtual void vnIn( double val );
-
- //////////////////////////////////////////////////////////////////
- static const Cinfo* initCinfo();
- private:
- double concInit_; /// Initial concentration.
- // We don't store the conc here as this is computed on the fly
- // by derived classes. But the PoolBase::concInit is authoritative.
+ friend void testSyncArray( unsigned int size, unsigned int numThreads,
+ unsigned int method );
+ friend void checkVal( double time, const PoolBase* m, unsigned int size );
+ friend void forceCheckVal( double time, Element* e, unsigned int size );
+
+public:
+ PoolBase();
+ virtual ~PoolBase();
+
+ //////////////////////////////////////////////////////////////////
+ // Field assignment stuff: Interface for the Cinfo, hence regular
+ // funcs. These internally call the virtual funcs that do the real
+ // work.
+ //////////////////////////////////////////////////////////////////
+ void setN( const Eref& e, double v );
+ double getN( const Eref& e ) const;
+ void setNinit( const Eref& e, double v );
+ double getNinit( const Eref& e ) const;
+ void setDiffConst( const Eref& e, double v );
+ double getDiffConst( const Eref& e ) const;
+ void setMotorConst( const Eref& e, double v );
+ double getMotorConst( const Eref& e ) const;
+
+ void setConc( const Eref& e, double v );
+ double getConc( const Eref& e ) const;
+ void setConcInit( const Eref& e, double v );
+ double getConcInit( const Eref& e ) const;
+
+ /**
+ * Volume is usually volume, but we also permit areal density
+ * This is obtained by looking up the corresponding spatial mesh
+ * entry in the parent compartment. If the message isn't set then
+ * it defaults to 1.0.
+ */
+ void setVolume( const Eref& e, double v );
+ double getVolume( const Eref& e ) const;
+
+ void setSpecies( const Eref& e, SpeciesId v );
+ SpeciesId getSpecies( const Eref& e ) const;
+ /**
+ * Functions to examine and change class between Pool and BufPool.
+ */
+ void setIsBuffered( const Eref& e, bool v );
+ bool getIsBuffered( const Eref& e ) const;
+
+ //////////////////////////////////////////////////////////////////
+ // Here are the inner virtual funcs for fields.
+ // All these are pure virtual
+ //////////////////////////////////////////////////////////////////
+
+ virtual void vSetN( const Eref& e, double v ) = 0;
+ virtual double vGetN( const Eref& e ) const = 0;
+ virtual void vSetNinit( const Eref& e, double v ) = 0;
+ virtual double vGetNinit( const Eref& e ) const = 0;
+ virtual void vSetDiffConst( const Eref& e, double v ) = 0;
+ virtual double vGetDiffConst( const Eref& e ) const = 0;
+ virtual void vSetMotorConst( const Eref& e, double v );
+ virtual double vGetMotorConst( const Eref& e ) const;
+
+ virtual void vSetConc( const Eref& e, double v ) = 0;
+ virtual double vGetConc( const Eref& e ) const = 0;
+ virtual void vSetConcInit( const Eref& e, double v ) = 0;
+ virtual double vGetConcInit( const Eref& e ) const;
+ virtual double vGetVolume( const Eref& e ) const = 0;
+ virtual void vSetVolume( const Eref& e, double v ) = 0;
+ virtual void vSetSpecies( const Eref& e, SpeciesId v ) = 0;
+ virtual SpeciesId vGetSpecies( const Eref& e ) const = 0;
+ /// I put in a default empty function for vSetIsBuffered.
+ virtual void vSetIsBuffered( const Eref& e, bool v );
+ virtual bool vGetIsBuffered( const Eref& e) const = 0;
+ /**
+ * Assign whatever info is needed by the zombie based on the
+ * solver Element. Encapsulates some unpleasant field extraction,
+ * casting, and assignment. Default version of this function does
+ * nothing.
+ */
+ virtual void vSetSolver( Id ksolve, Id dsolve );
+
+ //////////////////////////////////////////////////////////////////
+ /**
+ * zombify is the base function for conversion between pool
+ * subclasses. This can be overridden, but should work for most
+ * things. This takes the original Element, and without touching
+ * its messaging, replaces it with a new data object of the
+ * specified zClass. It does the best it can with conversion of
+ * fields. Typically needs to be followed by rescheduling and
+ * possibly a class-specific function for assigning further
+ * zombie fields outside the ken of the PoolBase.
+ * The 'solver' argument specifies which objects handle the solver
+ * for this conversion. For the Pool this is either or both of
+ * a kinetic solver /ksolve/ and a diffusion solver /dsolve/.
+ * The term zombie arises because this operation was originally
+ * carried out to strip an object of independent function, and
+ * replace it with a solver-controlled facsimile.
+ */
+ static void zombify( Element* original, const Cinfo* zClass,
+ Id ksolve, Id dsolve );
+
+ //////////////////////////////////////////////////////////////////
+ // Dest funcs
+ //////////////////////////////////////////////////////////////////
+ void process( const Eref& e, ProcPtr p );
+ void reinit( const Eref& e, ProcPtr p );
+ void reac( double A, double B );
+ void handleMolWt( const Eref& e, double v );
+ void increment( double val );
+ void decrement( double val );
+ void nIn( double val );
+
+ //////////////////////////////////////////////////////////////////
+ // Virtual Dest funcs. Most of these have a generic do-nothing
+ // function here, as most of the derived classes don't need to
+ // do anything.
+ //////////////////////////////////////////////////////////////////
+ virtual void vProcess( const Eref& e, ProcPtr p );
+ virtual void vReinit( const Eref& e, ProcPtr p );
+ virtual void vReac( double A, double B );
+ virtual void vHandleMolWt( const Eref& e, double v);
+ virtual void vIncrement( double val );
+ virtual void vDecrement( double val );
+ virtual void vnIn( double val );
+
+ //////////////////////////////////////////////////////////////////
+ static const Cinfo* initCinfo();
+private:
+ double concInit_; /// Initial concentration.
+ // We don't store the conc here as this is computed on the fly
+ // by derived classes. But the PoolBase::concInit is authoritative.
};
#endif // _POOL_BASE_H
diff --git a/kinetics/ReadKkit.cpp b/kinetics/ReadKkit.cpp
index 8172ae90920e225ab8337be73316c1bd0cdca1a8..1a2e0776494a67175496e71e68a5004ddc6b2ace 100644
--- a/kinetics/ReadKkit.cpp
+++ b/kinetics/ReadKkit.cpp
@@ -228,13 +228,13 @@ void setMethod( Shell* s, Id mgr, double simdt, double plotdt,
string simpath2 = mgr.path() + "/##[ISA=StimulusTable]," +
mgr.path() + "/##[ISA=PulseGen]";
string m = lower( method );
-
+ /*
if ( m == "ksolve" || m =="gsl" || m == "gssa" || m == "gsolve" ||
m == "gillespie" || m == "stochastic" )
{
cout << " Warning: Default solver set is Exponential Euler. To set \'gsl\' or \'gssa\' solver use function mooseaddChemSolver(modelpath,\'solverType\')"<<"\n";
}
- /*
+
if ( m == "rk4" ) {
cout << "Warning, not yet implemented. Using rk5 instead\n";
@@ -312,7 +312,7 @@ Id ReadKkit::read(
assert(kinetics != Id());
Id cInfo = s->doCreate( "Annotator", basePath_, "info", 1 );
assert( cInfo != Id() );
- Field< string > ::set(cInfo, "solver", method);
+ Field< string > ::set(cInfo, "solver", "ee");
Field< double > ::set(cInfo, "runtime", maxtime_);
s->doReinit();
return mgr;
@@ -578,6 +578,8 @@ void ReadKkit::objdump( const vector< string >& args)
assignArgs( tableMap_, args );
else if ( args[1] == "stim" )
assignArgs( stimMap_, args );
+ else if ( args[1] == "kchan" )
+ assignArgs( chanMap_, args );
}
void ReadKkit::call( const vector< string >& args)
@@ -1185,9 +1187,11 @@ Id ReadKkit::buildChan( const vector< string >& args )
Id pa = shell_->doFind( head ).id;
assert( pa != Id() );
- cout << "Warning: Kchan not yet supported in MOOSE, creating dummy:\n"
- << " " << clean << "\n";
- Id chan = shell_->doCreate( "Neutral", pa, tail, 1 );
+ // cout << "Warning: Kchan not yet supported in MOOSE, creating dummy:\n" << " " << clean << "\n";
+ //
+ double permeability = atof( args[ chanMap_["perm"] ].c_str() );
+ Id chan = shell_->doCreate( "ConcChan", pa, tail, 1 );
+ Field< double >::set( chan, "permeability", permeability );
assert( chan != Id() );
string chanPath = clean.substr( 10 );
chanIds_[ chanPath ] = chan;
@@ -1346,16 +1350,14 @@ void ReadKkit::addmsg( const vector< string >& args)
if ( args[3] == "REAC" ) {
if ( args[4] == "A" && args[5] == "B" ) {
- // Ignore kchans
if ( chanIds_.find( src ) != chanIds_.end() )
- ; // found a kchan, do nothing
+ innerAddMsg( src, chanIds_, "in", dest, poolIds_, "reac");
else
innerAddMsg( src, reacIds_, "sub", dest, poolIds_, "reac");
}
else if ( args[4] == "B" && args[5] == "A" ) {
- // Ignore kchans
if ( chanIds_.find( src ) != chanIds_.end() )
- ; // found a kchan, do nothing
+ innerAddMsg( src, chanIds_, "out", dest, poolIds_, "reac");
else
// dest pool is product of src reac
innerAddMsg( src, reacIds_, "prd", dest, poolIds_, "reac");
@@ -1387,6 +1389,10 @@ void ReadKkit::addmsg( const vector< string >& args)
else
innerAddMsg( src, mmEnzIds_, "prd", dest, poolIds_, "reac" );
}
+ else if ( args[3] == "NUMCHAN" ) { // Msg from chan pool to concchan
+ if ( chanIds_.find( dest ) != chanIds_.end() )
+ innerAddMsg( src, poolIds_, "nOut", dest, chanIds_, "setNumChan");
+ }
else if ( args[3] == "PLOT" ) { // Time-course output for pool
string head;
string temp;
diff --git a/kinetics/ReadKkit.h b/kinetics/ReadKkit.h
index 8e171fc64fa9de30df7781227abf4cdd2fa141b4..1dae27bfacc1cb33cb36ccda199502e67c524c11 100644
--- a/kinetics/ReadKkit.h
+++ b/kinetics/ReadKkit.h
@@ -217,6 +217,7 @@ class ReadKkit
map< string, int > groupMap_;
map< string, int > tableMap_;
map< string, int > stimMap_;
+ map< string, int > chanMap_;
map< string, Id > poolIds_;
map< string, Id > reacIds_;
map< string, Id > enzIds_;
diff --git a/kinetics/WriteKkit.cpp b/kinetics/WriteKkit.cpp
index c32b1fa024b8b7f0a03fecc6da05ff5f5855607c..3c3bc890afa1dbac1f5022bfc457ad1eefcbce52 100644
--- a/kinetics/WriteKkit.cpp
+++ b/kinetics/WriteKkit.cpp
@@ -26,255 +26,268 @@
void writeHeader( ofstream& fout,
- double simdt, double plotdt, double maxtime, double defaultVol)
+ double simdt, double plotdt, double maxtime, double defaultVol)
{
- time_t rawtime;
- time( &rawtime );
-
- fout <<
- "//genesis\n"
- "// kkit Version 11 flat dumpfile\n\n";
- fout << "// Saved on " << ctime( &rawtime ) << endl;
- fout << "include kkit {argv 1}\n";
- fout << "FASTDT = " << simdt << endl;
- fout << "SIMDT = " << simdt << endl;
- fout << "CONTROLDT = " << plotdt << endl;
- fout << "PLOTDT = " << plotdt << endl;
- fout << "MAXTIME = " << maxtime << endl;
- fout << "TRANSIENT_TIME = 2\n"
- "VARIABLE_DT_FLAG = 0\n";
- fout << "DEFAULT_VOL = " << defaultVol << endl;
- fout << "VERSION = 11.0\n"
- "setfield /file/modpath value ~/scripts/modules\n"
- "kparms\n\n";
-
- fout <<
- "initdump -version 3 -ignoreorphans 1\n"
- "simobjdump table input output alloced step_mode stepsize x y z\n"
- "simobjdump xtree path script namemode sizescale\n"
- "simobjdump xcoredraw xmin xmax ymin ymax\n"
- "simobjdump xtext editable\n"
- "simobjdump xgraph xmin xmax ymin ymax overlay\n"
- "simobjdump xplot pixflags script fg ysquish do_slope wy\n"
- "simobjdump group xtree_fg_req xtree_textfg_req plotfield expanded movealone \\\n"
- " link savename file version md5sum mod_save_flag x y z\n"
- "simobjdump geometry size dim shape outside xtree_fg_req xtree_textfg_req x y z\n"
- "simobjdump kpool DiffConst CoInit Co n nInit mwt nMin vol slave_enable \\\n"
- " geomname xtree_fg_req xtree_textfg_req x y z\n"
- "simobjdump kreac kf kb notes xtree_fg_req xtree_textfg_req x y z\n"
- "simobjdump kenz CoComplexInit CoComplex nComplexInit nComplex vol k1 k2 k3 \\\n"
- " keepconc usecomplex notes xtree_fg_req xtree_textfg_req link x y z\n"
- "simobjdump stim level1 width1 delay1 level2 width2 delay2 baselevel trig_time \\\n"
- " trig_mode notes xtree_fg_req xtree_textfg_req is_running x y z\n"
- "simobjdump xtab input output alloced step_mode stepsize notes editfunc \\\n"
- " xtree_fg_req xtree_textfg_req baselevel last_x last_y is_running x y z\n"
- "simobjdump kchan perm gmax Vm is_active use_nernst notewriteReacs xtree_fg_req \\\n"
- " xtree_textfg_req x y z\n"
- "simobjdump transport input output alloced step_mode stepsize dt delay clock \\\n"
- " kf xtree_fg_req xtree_textfg_req x y z\n"
- "simobjdump proto x y z\n";
- //"simundump geometry /kinetics/geometry 0 1.6667e-19 3 sphere \"\" white black 0 0 0\n\n";
+ time_t rawtime;
+ time( &rawtime );
+
+ fout <<
+ "//genesis\n"
+ "// kkit Version 11 flat dumpfile\n\n";
+ fout << "// Saved on " << ctime( &rawtime ) << endl;
+ fout << "include kkit {argv 1}\n";
+ fout << "FASTDT = " << simdt << endl;
+ fout << "SIMDT = " << simdt << endl;
+ fout << "CONTROLDT = " << plotdt << endl;
+ fout << "PLOTDT = " << plotdt << endl;
+ fout << "MAXTIME = " << maxtime << endl;
+ fout << "TRANSIENT_TIME = 2\n"
+ "VARIABLE_DT_FLAG = 0\n";
+ fout << "DEFAULT_VOL = " << defaultVol << endl;
+ fout << "VERSION = 11.0\n"
+ "setfield /file/modpath value ~/scripts/modules\n"
+ "kparms\n\n";
+
+ fout <<
+ "initdump -version 3 -ignoreorphans 1\n"
+ "simobjdump table input output alloced step_mode stepsize x y z\n"
+ "simobjdump xtree path script namemode sizescale\n"
+ "simobjdump xcoredraw xmin xmax ymin ymax\n"
+ "simobjdump xtext editable\n"
+ "simobjdump xgraph xmin xmax ymin ymax overlay\n"
+ "simobjdump xplot pixflags script fg ysquish do_slope wy\n"
+ "simobjdump group xtree_fg_req xtree_textfg_req plotfield expanded movealone \\\n"
+ " link savename file version md5sum mod_save_flag x y z\n"
+ "simobjdump geometry size dim shape outside xtree_fg_req xtree_textfg_req x y z\n"
+ "simobjdump kpool DiffConst CoInit Co n nInit mwt nMin vol slave_enable \\\n"
+ " geomname xtree_fg_req xtree_textfg_req x y z\n"
+ "simobjdump kreac kf kb notes xtree_fg_req xtree_textfg_req x y z\n"
+ "simobjdump kenz CoComplexInit CoComplex nComplexInit nComplex vol k1 k2 k3 \\\n"
+ " keepconc usecomplex notes xtree_fg_req xtree_textfg_req link x y z\n"
+ "simobjdump stim level1 width1 delay1 level2 width2 delay2 baselevel trig_time \\\n"
+ " trig_mode notes xtree_fg_req xtree_textfg_req is_running x y z\n"
+ "simobjdump xtab input output alloced step_mode stepsize notes editfunc \\\n"
+ " xtree_fg_req xtree_textfg_req baselevel last_x last_y is_running x y z\n"
+ "simobjdump kchan perm gmax Vm is_active use_nernst notewriteReacs xtree_fg_req \\\n"
+ " xtree_textfg_req x y z\n"
+ "simobjdump transport input output alloced step_mode stepsize dt delay clock \\\n"
+ " kf xtree_fg_req xtree_textfg_req x y z\n"
+ "simobjdump proto x y z\n";
+ //"simundump geometry /kinetics/geometry 0 1.6667e-19 3 sphere \"\" white black 0 0 0\n\n";
}
string trimPath(Id id, Id comptid)
{
- string msgpath = Field <string> :: get(id,"path");
- ObjId compartment(msgpath);
- string path1;
- cout << " trimpath " << msgpath <<endl;
- // triming the string compartment Level
- while( Field<string>::get(compartment,"className") != "CubeMesh"
- && Field<string>::get(compartment,"className") != "CylMesh"
- )
- compartment = Field<ObjId> :: get(compartment, "parent");
- string cmpt = Field < string > :: get(compartment,"name");
- if (cmpt != "kinetics")
- { std::size_t found = msgpath.find(cmpt);
- if (found !=std::string::npos)
- path1 = msgpath.substr(found-1,msgpath.length());
- else
- {
- path1 = msgpath;
-
- }
- }
- else
- { std :: size_t found = msgpath.find(cmpt);
- if (found !=std::string::npos)
- { string pathC = msgpath.substr(found-1,msgpath.length());
- std :: size_t slash = pathC.find('/',found);
- if (slash !=std::string::npos)
- path1 = pathC.substr(slash,pathC.length());
- else
- { path1 = msgpath;
- }
- }
- }
- cout << " path " << path1 << endl;
- return path1;
+ string msgpath = Field <string> :: get(id,"path");
+ ObjId compartment(msgpath);
+ string path1;
+ cout << " trimpath " << msgpath <<endl;
+ // triming the string compartment Level
+ while( Field<string>::get(compartment,"className") != "CubeMesh"
+ && Field<string>::get(compartment,"className") != "CylMesh"
+ )
+ compartment = Field<ObjId> :: get(compartment, "parent");
+ string cmpt = Field < string > :: get(compartment,"name");
+ if (cmpt != "kinetics")
+ {
+ std::size_t found = msgpath.find(cmpt);
+ if (found !=std::string::npos)
+ path1 = msgpath.substr(found-1,msgpath.length());
+ else
+ {
+ path1 = msgpath;
+ }
+ }
+ else
+ {
+ std :: size_t found = msgpath.find(cmpt);
+ if (found !=std::string::npos)
+ {
+ string pathC = msgpath.substr(found-1,msgpath.length());
+ std :: size_t slash = pathC.find('/',found);
+ if (slash !=std::string::npos)
+ path1 = pathC.substr(slash,pathC.length());
+ else
+ {
+ path1 = msgpath;
+ }
+ }
+ }
+ cout << " path " << path1 << endl;
+ return path1;
}
Id getEnzCplx( Id id )
{
- vector < Id > srct = LookupField <string,vector < Id> >::get(id, "neighbors","cplxDest");
- return srct[0];
+ vector < Id > srct = LookupField <string,vector < Id> >::get(id, "neighbors","cplxDest");
+ return srct[0];
}
Id getEnzMol( Id id )
{
- vector < Id > srct = LookupField <string,vector < Id> >::get(id, "neighbors","enzDest");
- return srct[0];
+ vector < Id > srct = LookupField <string,vector < Id> >::get(id, "neighbors","enzDest");
+ return srct[0];
}
void writeEnz( ofstream& fout, Id id,
- string colour, string textcolour,
- double x, double y, Id comptid )
+ string colour, string textcolour,
+ double x, double y, Id comptid )
{
- string path = id.path();
- string comptname = Field < string > :: get(comptid,"name");
- string poolpath = trimPath(id,comptid);
-
-
- double k1 = 0;
- double k2 = 0;
- double k3 = 0;
- double nInit = 0;
- double concInit = 0;
- double n = 0;
- double conc = 0;
- Id enzMol = getEnzMol( id );
- assert( enzMol != Id() );
- double vol = Field< double >::get( enzMol, "volume" ) * NA * 1e-3;
- unsigned int isMichaelisMenten = 0;
- string enzClass = Field < string > :: get(id,"className");
- if (enzClass == "ZombieMMenz" or enzClass == "MMenz")
- { k1 = Field < double > :: get (id,"numKm");
- k3 = Field < double > :: get (id,"kcat");
- k2 = 4.0*k3;
- k1 = (k2 + k3) / k1;
- isMichaelisMenten = 1;
- }
- else if (enzClass == "ZombieEnz" or enzClass == "Enz")
- { k1 = Field< double >::get( id, "k1" );
- k2 = Field< double >::get( id, "k2" );
- k3 = Field< double >::get( id, "k3" );
- Id cplx = getEnzCplx( id );
- assert( cplx != Id() );
- nInit = Field< double >::get( cplx, "nInit" );
- n = Field< double >::get( cplx, "n" );
- concInit = Field< double >::get( cplx, "concInit" );
- conc = Field< double >::get( cplx, "conc" );
- }
- fout << "simundump kenz /kinetics" << poolpath << " 0 " <<
- concInit << " " <<
- conc << " " <<
- nInit << " " <<
- n << " " <<
- vol << " " <<
- k1 << " " <<
- k2 << " " <<
- k3 << " " <<
- 0 << " " <<
- isMichaelisMenten << " " <<
- "\"\"" << " " <<
- colour << " " << textcolour << " \"\"" <<
- " " << x << " " << y << " 0\n";
+ string path = id.path();
+ string comptname = Field < string > :: get(comptid,"name");
+ string poolpath = trimPath(id,comptid);
+
+
+ double k1 = 0;
+ double k2 = 0;
+ double k3 = 0;
+ double nInit = 0;
+ double concInit = 0;
+ double n = 0;
+ double conc = 0;
+ Id enzMol = getEnzMol( id );
+ assert( enzMol != Id() );
+ double vol = Field< double >::get( enzMol, "volume" ) * NA * 1e-3;
+ unsigned int isMichaelisMenten = 0;
+ string enzClass = Field < string > :: get(id,"className");
+ if (enzClass == "ZombieMMenz" or enzClass == "MMenz")
+ {
+ k1 = Field < double > :: get (id,"numKm");
+ k3 = Field < double > :: get (id,"kcat");
+ k2 = 4.0*k3;
+ k1 = (k2 + k3) / k1;
+ isMichaelisMenten = 1;
+ }
+ else if (enzClass == "ZombieEnz" or enzClass == "Enz")
+ {
+ k1 = Field< double >::get( id, "k1" );
+ k2 = Field< double >::get( id, "k2" );
+ k3 = Field< double >::get( id, "k3" );
+ Id cplx = getEnzCplx( id );
+ assert( cplx != Id() );
+ nInit = Field< double >::get( cplx, "nInit" );
+ n = Field< double >::get( cplx, "n" );
+ concInit = Field< double >::get( cplx, "concInit" );
+ conc = Field< double >::get( cplx, "conc" );
+ }
+ fout << "simundump kenz /kinetics" << poolpath << " 0 " <<
+ concInit << " " <<
+ conc << " " <<
+ nInit << " " <<
+ n << " " <<
+ vol << " " <<
+ k1 << " " <<
+ k2 << " " <<
+ k3 << " " <<
+ 0 << " " <<
+ isMichaelisMenten << " " <<
+ "\"\"" << " " <<
+ colour << " " << textcolour << " \"\"" <<
+ " " << x << " " << y << " 0\n";
}
void writeReac( ofstream& fout, Id id,
- string colour, string textcolour,
- double x, double y, Id comptid )
+ string colour, string textcolour,
+ double x, double y, Id comptid )
{
- string reacPar = Field <string> :: get(comptid,"name");
- string reacname = Field<string> :: get(id, "name");
- double kf = Field< double >::get( id, "numKf" );
- double kb = Field< double >::get( id, "numKb" );
-
- unsigned int numSub =
- Field< unsigned int >::get( id, "numSubstrates" );
- unsigned int numPrd =
- Field< unsigned int >::get( id, "numProducts" );
- fout << "simundump kreac /kinetics" << trimPath(id,comptid) << " 0 " <<
- kf << " " << kb << " \"\" " <<
- colour << " " << textcolour << " " << x << " " << y << " 0\n";
+ string reacPar = Field <string> :: get(comptid,"name");
+ string reacname = Field<string> :: get(id, "name");
+ double kf = Field< double >::get( id, "numKf" );
+ double kb = Field< double >::get( id, "numKb" );
+
+ unsigned int numSub =
+ Field< unsigned int >::get( id, "numSubstrates" );
+ unsigned int numPrd =
+ Field< unsigned int >::get( id, "numProducts" );
+ fout << "simundump kreac /kinetics" << trimPath(id,comptid) << " 0 " <<
+ kf << " " << kb << " \"\" " <<
+ colour << " " << textcolour << " " << x << " " << y << " 0\n";
}
unsigned int getSlaveEnable( Id id )
{
- static const Finfo* setNinitFinfo =
- PoolBase::initCinfo()->findFinfo( "set_nInit" );
- static const Finfo* setConcInitFinfo =
- PoolBase::initCinfo()->findFinfo( "set_concInit" );
- unsigned int ret = 0;
- vector< Id > src;
- if ( id.element()->cinfo()->isA( "BufPool" ) ) {
- if ( id.element()->getNeighbors( src, setConcInitFinfo ) > 0 ) {
- ret = 2;
- } else if ( id.element()->getNeighbors( src, setNinitFinfo ) > 0 ){
- ret = 4;
- }
- } else {
- return 0;
- }
- if ( ret == 0 )
- return 4; // Just simple buffered molecule
- if ( src[0].element()->cinfo()->isA( "StimulusTable" ) )
- return ret; // Following a table, this is fine.
+ static const Finfo* setNinitFinfo =
+ PoolBase::initCinfo()->findFinfo( "set_nInit" );
+ static const Finfo* setConcInitFinfo =
+ PoolBase::initCinfo()->findFinfo( "set_concInit" );
+ unsigned int ret = 0;
+ vector< Id > src;
+ if ( id.element()->cinfo()->isA( "BufPool" ) )
+ {
+ if ( id.element()->getNeighbors( src, setConcInitFinfo ) > 0 )
+ {
+ ret = 2;
+ }
+ else if ( id.element()->getNeighbors( src, setNinitFinfo ) > 0 )
+ {
+ ret = 4;
+ }
+ }
+ else
+ {
+ return 0;
+ }
+ if ( ret == 0 )
+ return 4; // Just simple buffered molecule
+ if ( src[0].element()->cinfo()->isA( "StimulusTable" ) )
+ return ret; // Following a table, this is fine.
- // Fallback: I have no idea what sent it the input, assume it is legit.
- return ret;
+ // Fallback: I have no idea what sent it the input, assume it is legit.
+ return ret;
}
void writePool( ofstream& fout, Id id,
- string colour, string textcolour,
- double x, double y, Id comptid,int comptIndex )
+ string colour, string textcolour,
+ double x, double y, Id comptid,int comptIndex )
{
- string poolPar = Field <string> :: get(comptid,"name");
- string pooltype = Field < string > :: get(id,"className");
- double diffConst = Field< double >::get( id, "diffConst" );
- double concInit = Field< double >::get( id, "concInit" );
- //double conc = Field< double >::get( id, "conc" );
- double nInit = Field< double >::get( id, "nInit" );
- //double n = Field< double >::get( id, "n" );
- double volume = Field< double >::get( id, "volume" );
- string geometry;
- stringstream geometryTemp ;
- unsigned int slave_enable = 0;
- if (pooltype == "BufPool" or pooltype == "ZombieBufPool")
- { vector< Id > children = Field< vector< Id > >::get( id, "children" );
- if (children.size() == 0)
- slave_enable = 4;
- for ( vector< Id >::iterator i = children.begin(); i != children.end(); ++i )
- { string funcpath = Field <string> :: get(*i,"path");
- string clsname = Field <string> :: get(*i,"className");
- if (clsname == "Function" or clsname == "ZombieFunction")
- slave_enable = 0;
- else
- slave_enable = 4;
+ string poolPar = Field <string> :: get(comptid,"name");
+ string pooltype = Field < string > :: get(id,"className");
+ double diffConst = Field< double >::get( id, "diffConst" );
+ double concInit = Field< double >::get( id, "concInit" );
+ //double conc = Field< double >::get( id, "conc" );
+ double nInit = Field< double >::get( id, "nInit" );
+ //double n = Field< double >::get( id, "n" );
+ double volume = Field< double >::get( id, "volume" );
+ string geometry;
+ stringstream geometryTemp ;
+ unsigned int slave_enable = 0;
+ if (pooltype == "BufPool" or pooltype == "ZombieBufPool")
+ {
+ vector< Id > children = Field< vector< Id > >::get( id, "children" );
+ if (children.size() == 0)
+ slave_enable = 4;
+ for ( vector< Id >::iterator i = children.begin(); i != children.end(); ++i )
+ {
+ string funcpath = Field <string> :: get(*i,"path");
+ string clsname = Field <string> :: get(*i,"className");
+ if (clsname == "Function" or clsname == "ZombieFunction")
+ slave_enable = 0;
+ else
+ slave_enable = 4;
- }
- }
- if (comptIndex > 0)
- geometryTemp << "/geometry[" << comptIndex <<"]";
- else
- geometryTemp << "/geometry";
-
- // simobjdump kpool DiffConst CoInit Co n nInit mwt nMin vol slave_enable
-
- fout << "simundump kpool /kinetics" << trimPath(id,comptid) << " 0 " <<
- diffConst << " " <<
- 0 << " " <<
- 0 << " " <<
- 0 << " " <<
- nInit << " " <<
- 0 << " " << 0 << " " << // mwt, nMin
- volume * NA * 1e-3 << " " << // volscale
- slave_enable << //GENESIS FIELD HERE.
- " /kinetics"<< geometryTemp.str() << " " <<
- colour << " " << textcolour << " " << x << " " << y << " 0\n";
+ }
+ }
+ if (comptIndex > 0)
+ geometryTemp << "/geometry[" << comptIndex <<"]";
+ else
+ geometryTemp << "/geometry";
+
+ // simobjdump kpool DiffConst CoInit Co n nInit mwt nMin vol slave_enable
+
+ fout << "simundump kpool /kinetics" << trimPath(id,comptid) << " 0 " <<
+ diffConst << " " <<
+ 0 << " " <<
+ 0 << " " <<
+ 0 << " " <<
+ nInit << " " <<
+ 0 << " " << 0 << " " << // mwt, nMin
+ volume * NA * 1e-3 << " " << // volscale
+ slave_enable << //GENESIS FIELD HERE.
+ " /kinetics"<< geometryTemp.str() << " " <<
+ colour << " " << textcolour << " " << x << " " << y << " 0\n";
}
void writePlot( ofstream& fout, Id id,
- string colour, string textcolour,
- double x, double y )
+ string colour, string textcolour,
+ double x, double y )
{
string path = id.path();
size_t pos = path.find( "/graphs" );
@@ -291,143 +304,148 @@ void writePlot( ofstream& fout, Id id,
void writeGui( ofstream& fout )
{
- fout << "simundump xgraph /graphs/conc1 0 0 99 0.001 0.999 0\n"
- "simundump xgraph /graphs/conc2 0 0 100 0 1 0\n"
- "simundump xgraph /moregraphs/conc3 0 0 100 0 1 0\n"
- "simundump xgraph /moregraphs/conc4 0 0 100 0 1 0\n"
- "simundump xcoredraw /edit/draw 0 -6 4 -2 6\n"
- "simundump xtree /edit/draw/tree 0 \\\n"
- " /kinetics/#[],/kinetics/#[]/#[],/kinetics/#[]/#[]/#[][TYPE!=proto],/kinetics/#[]/#[]/#[][TYPE!=linkinfo]/##[] \"edit_elm.D <v>; drag_from_edit.w <d> <S> <x> <y> <z>\" auto 0.6\n"
- "simundump xtext /file/notes 0 1\n";
+ fout << "simundump xgraph /graphs/conc1 0 0 99 0.001 0.999 0\n"
+ "simundump xgraph /graphs/conc2 0 0 100 0 1 0\n"
+ "simundump xgraph /moregraphs/conc3 0 0 100 0 1 0\n"
+ "simundump xgraph /moregraphs/conc4 0 0 100 0 1 0\n"
+ "simundump xcoredraw /edit/draw 0 -6 4 -2 6\n"
+ "simundump xtree /edit/draw/tree 0 \\\n"
+ " /kinetics/#[],/kinetics/#[]/#[],/kinetics/#[]/#[]/#[][TYPE!=proto],/kinetics/#[]/#[]/#[][TYPE!=linkinfo]/##[] \"edit_elm.D <v>; drag_from_edit.w <d> <S> <x> <y> <z>\" auto 0.6\n"
+ "simundump xtext /file/notes 0 1\n";
}
void writeFooter( ofstream& fout )
{
- fout << "\nenddump\n";
- fout << "complete_loading\n";
+ fout << "\nenddump\n";
+ fout << "complete_loading\n";
}
void storeMMenzMsgs( Id enz, vector< string >& msgs, Id comptid )
{
- Id enzparentId = Field <ObjId> :: get(enz,"parent");
- string enzPar = Field <string> :: get(enzparentId,"name");
- string enzName = Field<string> :: get(enz,"name");
-
- vector < Id > srct = LookupField <string,vector < Id> >::get(enz, "neighbors","sub");
- for (vector <Id> :: iterator rsub = srct.begin();rsub != srct.end();rsub++)
- {
- string s = "addmsg /kinetics" + trimPath(*rsub, comptid) + " /kinetics" + trimPath(enz, comptid) + " SUBSTRATE n";
- msgs.push_back( s );
- s = "addmsg /kinetics" + trimPath(enz, comptid) + " /kinetics" + trimPath( *rsub, comptid ) + " REAC sA B";
- msgs.push_back( s );
- }
- vector < Id > prct = LookupField <string,vector < Id> >::get(enz, "neighbors","prd");
- for (vector <Id> :: iterator rprd = prct.begin();rprd != prct.end();rprd++)
- {
- string s = "addmsg /kinetics" + trimPath( enz, comptid ) + " /kinetics" + trimPath(*rprd, comptid) + " MM_PRD pA";
- msgs.push_back( s );
- }
- vector < Id > enzC = LookupField <string,vector < Id> >::get(enz, "neighbors","enzDest");
- for (vector <Id> :: iterator enzCl = enzC.begin();enzCl != enzC.end();enzCl++)
- {
- string s = "addmsg /kinetics" + trimPath( *enzCl, comptid ) + " /kinetics" + trimPath(enz, comptid) + " ENZYME n";
- msgs.push_back( s );
- }
+ Id enzparentId = Field <ObjId> :: get(enz,"parent");
+ string enzPar = Field <string> :: get(enzparentId,"name");
+ string enzName = Field<string> :: get(enz,"name");
+
+ vector < Id > srct = LookupField <string,vector < Id> >::get(enz, "neighbors","sub");
+ for (vector <Id> :: iterator rsub = srct.begin(); rsub != srct.end(); rsub++)
+ {
+ string s = "addmsg /kinetics" + trimPath(*rsub, comptid) + " /kinetics" + trimPath(enz, comptid) + " SUBSTRATE n";
+ msgs.push_back( s );
+ s = "addmsg /kinetics" + trimPath(enz, comptid) + " /kinetics" + trimPath( *rsub, comptid ) + " REAC sA B";
+ msgs.push_back( s );
+ }
+ vector < Id > prct = LookupField <string,vector < Id> >::get(enz, "neighbors","prd");
+ for (vector <Id> :: iterator rprd = prct.begin(); rprd != prct.end(); rprd++)
+ {
+ string s = "addmsg /kinetics" + trimPath( enz, comptid ) + " /kinetics" + trimPath(*rprd, comptid) + " MM_PRD pA";
+ msgs.push_back( s );
+ }
+ vector < Id > enzC = LookupField <string,vector < Id> >::get(enz, "neighbors","enzDest");
+ for (vector <Id> :: iterator enzCl = enzC.begin(); enzCl != enzC.end(); enzCl++)
+ {
+ string s = "addmsg /kinetics" + trimPath( *enzCl, comptid ) + " /kinetics" + trimPath(enz, comptid) + " ENZYME n";
+ msgs.push_back( s );
+ }
}
void storeCplxEnzMsgs( Id enz, vector< string >& msgs, Id comptid )
-{ Id enzparentId = Field <ObjId> :: get(enz,"parent");
- string enzPar = Field <string> :: get(enzparentId,"name");
- string enzName = Field<string> :: get(enz,"name");
-
- vector < Id > srct = LookupField <string,vector < Id> >::get(enz, "neighbors","sub");
- for (vector <Id> :: iterator rsub = srct.begin();rsub != srct.end();rsub++)
- {
- string s = "addmsg /kinetics" + trimPath(*rsub, comptid) + " /kinetics" + trimPath(enz, comptid) + " SUBSTRATE n";
- msgs.push_back( s );
- s = "addmsg /kinetics" + trimPath(enz, comptid) + " /kinetics" + trimPath( *rsub, comptid ) + " REAC sA B";
- msgs.push_back( s );
- }
- vector < Id > prct = LookupField <string,vector < Id> >::get(enz, "neighbors","prd");
- for (vector <Id> :: iterator rprd = prct.begin();rprd != prct.end();rprd++)
- {
- string s = "addmsg /kinetics" + trimPath( enz, comptid ) + " /kinetics" + trimPath(*rprd, comptid) + " MM_PRD pA";
- msgs.push_back( s );
- }
- vector < Id > enzC = LookupField <string,vector < Id> >::get(enz, "neighbors","enzOut");
- for (vector <Id> :: iterator enzCl = enzC.begin();enzCl != enzC.end();enzCl++)
- {
- string s = "addmsg /kinetics" + trimPath( *enzCl, comptid ) + " /kinetics" + trimPath(enz, comptid) + " ENZYME n";
- msgs.push_back( s );
- s = "addmsg /kinetics" + trimPath( enz, comptid ) + " /kinetics" + trimPath(*enzCl, comptid) + " REAC eA B";
- msgs.push_back( s );
- }
+{
+ Id enzparentId = Field <ObjId> :: get(enz,"parent");
+ string enzPar = Field <string> :: get(enzparentId,"name");
+ string enzName = Field<string> :: get(enz,"name");
+
+ vector < Id > srct = LookupField <string,vector < Id> >::get(enz, "neighbors","sub");
+ for (vector <Id> :: iterator rsub = srct.begin(); rsub != srct.end(); rsub++)
+ {
+ string s = "addmsg /kinetics" + trimPath(*rsub, comptid) + " /kinetics" + trimPath(enz, comptid) + " SUBSTRATE n";
+ msgs.push_back( s );
+ s = "addmsg /kinetics" + trimPath(enz, comptid) + " /kinetics" + trimPath( *rsub, comptid ) + " REAC sA B";
+ msgs.push_back( s );
+ }
+ vector < Id > prct = LookupField <string,vector < Id> >::get(enz, "neighbors","prd");
+ for (vector <Id> :: iterator rprd = prct.begin(); rprd != prct.end(); rprd++)
+ {
+ string s = "addmsg /kinetics" + trimPath( enz, comptid ) + " /kinetics" + trimPath(*rprd, comptid) + " MM_PRD pA";
+ msgs.push_back( s );
+ }
+ vector < Id > enzC = LookupField <string,vector < Id> >::get(enz, "neighbors","enzOut");
+ for (vector <Id> :: iterator enzCl = enzC.begin(); enzCl != enzC.end(); enzCl++)
+ {
+ string s = "addmsg /kinetics" + trimPath( *enzCl, comptid ) + " /kinetics" + trimPath(enz, comptid) + " ENZYME n";
+ msgs.push_back( s );
+ s = "addmsg /kinetics" + trimPath( enz, comptid ) + " /kinetics" + trimPath(*enzCl, comptid) + " REAC eA B";
+ msgs.push_back( s );
+ }
}
void storeEnzMsgs( Id enz, vector< string >& msgs, Id comptid )
{
- string enzClass = Field < string > :: get(enz,"className");
- if (enzClass == "ZombieMMenz" or enzClass == "MMenz")
- storeMMenzMsgs(enz, msgs, comptid);
- else
- storeCplxEnzMsgs( enz, msgs, comptid );
+ string enzClass = Field < string > :: get(enz,"className");
+ if (enzClass == "ZombieMMenz" or enzClass == "MMenz")
+ storeMMenzMsgs(enz, msgs, comptid);
+ else
+ storeCplxEnzMsgs( enz, msgs, comptid );
}
void storeReacMsgs( Id reac, vector< string >& msgs, Id comptid )
{
- vector < Id > srct = LookupField <string,vector < Id> >::get(reac, "neighbors","sub");
- for (vector <Id> :: iterator rsub = srct.begin();rsub != srct.end();rsub++)
- { string s = "addmsg /kinetics" + trimPath(*rsub, comptid) + " /kinetics" + trimPath(reac, comptid) + " SUBSTRATE n";
- msgs.push_back( s );
- s = "addmsg /kinetics" + trimPath(reac, comptid) + " /kinetics" + trimPath( *rsub, comptid ) + " REAC A B";
- msgs.push_back( s );
- }
- vector < Id > prct = LookupField <string,vector < Id> >::get(reac, "neighbors","prd");
- for (vector <Id> :: iterator rprd = prct.begin();rprd != prct.end();rprd++)
- { string rpath = Field <string> :: get(reac,"path");
- string cpath = Field <string> :: get(comptid,"path");
- string prdPath = Field <string> :: get(*rprd,"path");
- string s = "addmsg /kinetics" + trimPath( *rprd, comptid ) + " /kinetics" + trimPath(reac, comptid) + " PRODUCT n";
- msgs.push_back( s );
- s = "addmsg /kinetics" + trimPath(reac, comptid) + " /kinetics" + trimPath( *rprd,comptid ) + " REAC B A";
- msgs.push_back( s );
- }
+ vector < Id > srct = LookupField <string,vector < Id> >::get(reac, "neighbors","sub");
+ for (vector <Id> :: iterator rsub = srct.begin(); rsub != srct.end(); rsub++)
+ {
+ string s = "addmsg /kinetics" + trimPath(*rsub, comptid) + " /kinetics" + trimPath(reac, comptid) + " SUBSTRATE n";
+ msgs.push_back( s );
+ s = "addmsg /kinetics" + trimPath(reac, comptid) + " /kinetics" + trimPath( *rsub, comptid ) + " REAC A B";
+ msgs.push_back( s );
+ }
+ vector < Id > prct = LookupField <string,vector < Id> >::get(reac, "neighbors","prd");
+ for (vector <Id> :: iterator rprd = prct.begin(); rprd != prct.end(); rprd++)
+ {
+ string rpath = Field <string> :: get(reac,"path");
+ string cpath = Field <string> :: get(comptid,"path");
+ string prdPath = Field <string> :: get(*rprd,"path");
+ string s = "addmsg /kinetics" + trimPath( *rprd, comptid ) + " /kinetics" + trimPath(reac, comptid) + " PRODUCT n";
+ msgs.push_back( s );
+ s = "addmsg /kinetics" + trimPath(reac, comptid) + " /kinetics" + trimPath( *rprd,comptid ) + " REAC B A";
+ msgs.push_back( s );
+ }
}
void storeFunctionMsgs( Id func, vector< string >& msgs,map < double, pair<Id, int> > & compt_vol )
{
- // Get the msg sources into this Function object.
- ObjId poolPath = Neutral::parent( func.eref() );
- double poolvol = Field < double > :: get(poolPath,"Volume");
- Id poolParentId = compt_vol[poolvol].first;
- string poolParent = Field <string> :: get(compt_vol[poolvol].first,"name");
- Id xi(func.value()+1);
- vector < Id > func_input = LookupField <string,vector < Id> >::get(xi, "neighbors","input");
-
- for (vector <Id> :: iterator funcIp = func_input.begin();funcIp != func_input.end();funcIp++)
- { string funcIp_path = Field < string > :: get(*funcIp,"path");
- double vol = Field < double > :: get(*funcIp,"Volume");
- Id parentId = compt_vol[vol].first;
- string parentname = Field <string> :: get(parentId,"name");
- string s = "addmsg /kinetics" + trimPath(*funcIp, parentId)+ " /kinetics" + trimPath(poolPath,poolParentId) +
- " SUMTOTAL n nInit";
- msgs.push_back(s);
- }
+ // Get the msg sources into this Function object.
+ ObjId poolPath = Neutral::parent( func.eref() );
+ double poolvol = Field < double > :: get(poolPath,"Volume");
+ Id poolParentId = compt_vol[poolvol].first;
+ string poolParent = Field <string> :: get(compt_vol[poolvol].first,"name");
+ Id xi(func.value()+1);
+ vector < Id > func_input = LookupField <string,vector < Id> >::get(xi, "neighbors","input");
+
+ for (vector <Id> :: iterator funcIp = func_input.begin(); funcIp != func_input.end(); funcIp++)
+ {
+ string funcIp_path = Field < string > :: get(*funcIp,"path");
+ double vol = Field < double > :: get(*funcIp,"Volume");
+ Id parentId = compt_vol[vol].first;
+ string parentname = Field <string> :: get(parentId,"name");
+ string s = "addmsg /kinetics" + trimPath(*funcIp, parentId)+ " /kinetics" + trimPath(poolPath,poolParentId) +
+ " SUMTOTAL n nInit";
+ msgs.push_back(s);
+ }
}
void storePlotMsgs( Id tab, vector< string >& msgs, Id pool, string bg, Id comptid)
-{ string tabPath = tab.path();
- string poolPath = Field <string> :: get(pool,"path");
- string poolName = Field <string> :: get(pool,"name");
-
- size_t pos = tabPath.find( "/graphs" );
- if ( pos == string::npos )
- pos = tabPath.find( "/moregraphs" );
- assert( pos != string::npos );
- tabPath = tabPath.substr( pos );
- string s = "addmsg /kinetics" + trimPath( poolPath, comptid) + " " + tabPath +
- " PLOT Co *" + poolName + " *" + bg;
- msgs.push_back( s );
+{
+ string tabPath = tab.path();
+ string poolPath = Field <string> :: get(pool,"path");
+ string poolName = Field <string> :: get(pool,"name");
+
+ size_t pos = tabPath.find( "/graphs" );
+ if ( pos == string::npos )
+ pos = tabPath.find( "/moregraphs" );
+ assert( pos != string::npos );
+ tabPath = tabPath.substr( pos );
+ string s = "addmsg /kinetics" + trimPath( poolPath, comptid) + " " + tabPath +
+ " PLOT Co *" + poolName + " *" + bg;
+ msgs.push_back( s );
}
/**
@@ -436,52 +454,54 @@ void storePlotMsgs( Id tab, vector< string >& msgs, Id pool, string bg, Id compt
*/
double estimateSimTimes( double& simDt, double& plotDt )
{
- double runTime = Field< double >::get( Id( 1 ), "runTime" );
- if ( runTime <= 0 )
- runTime = 100.0;
- vector< double > dts =
- Field< vector< double> >::get( Id( 1 ), "dts" );
-
- simDt = dts[11];
- plotDt = dts[18];
- cout << "estimatesimtimes" << simDt << plotDt;
- if ( plotDt <= 0 )
- plotDt = runTime / 200.0;
- if ( simDt == 0 )
- simDt = 0.01;
- if ( simDt > plotDt )
- simDt = plotDt / 100;
-
- return runTime;
+ double runTime = Field< double >::get( Id( 1 ), "runTime" );
+ if ( runTime <= 0 )
+ runTime = 100.0;
+ vector< double > dts =
+ Field< vector< double> >::get( Id( 1 ), "dts" );
+
+ simDt = dts[11];
+ plotDt = dts[18];
+ cout << "estimatesimtimes" << simDt << plotDt;
+ if ( plotDt <= 0 )
+ plotDt = runTime / 200.0;
+ if ( simDt == 0 )
+ simDt = 0.01;
+ if ( simDt > plotDt )
+ simDt = plotDt / 100;
+
+ return runTime;
}
/// Returns an estimate of the default volume used in the model.
double estimateDefaultVol( Id model )
{
- vector< Id > children =
- Field< vector< Id > >::get( model, "children" );
- vector< double > vols;
- double maxVol = 0;
- for ( vector< Id >::iterator i = children.begin();
- i != children.end(); ++i ) {
- if ( i->element()->cinfo()->isA( "ChemCompt" ) ) {
- double v = Field< double >::get( *i, "volume" );
- if ( i->element()->getName() == "kinetics" )
- return v;
- vols.push_back( v );
- if ( maxVol < v )
- maxVol = v;
- }
- }
- if ( maxVol > 0 )
- return maxVol;
- return 1.0e-15;
+ vector< Id > children =
+ Field< vector< Id > >::get( model, "children" );
+ vector< double > vols;
+ double maxVol = 0;
+ for ( vector< Id >::iterator i = children.begin();
+ i != children.end(); ++i )
+ {
+ if ( i->element()->cinfo()->isA( "ChemCompt" ) )
+ {
+ double v = Field< double >::get( *i, "volume" );
+ if ( i->element()->getName() == "kinetics" )
+ return v;
+ vols.push_back( v );
+ if ( maxVol < v )
+ maxVol = v;
+ }
+ }
+ if ( maxVol > 0 )
+ return maxVol;
+ return 1.0e-15;
}
void writeMsgs( ofstream& fout, const vector< string >& msgs )
{
- for ( vector< string >::const_iterator i = msgs.begin();
- i != msgs.end(); ++i )
- fout << *i << endl;
+ for ( vector< string >::const_iterator i = msgs.begin();
+ i != msgs.end(); ++i )
+ fout << *i << endl;
}
void writeGroup(ofstream& fout,Id model)
{
@@ -489,7 +509,7 @@ void writeGroup(ofstream& fout,Id model)
int x = 10;
int y = 20;
int num = wildcardFind( model.path() + "/##[TYPE=Neutral]", group );
- for ( vector< ObjId >::iterator itr = group.begin(); itr != group.end();itr++)
+ for ( vector< ObjId >::iterator itr = group.begin(); itr != group.end(); itr++)
{
string path = Field<string>::get(*itr,"path");
size_t pos = path.find( "/kinetics" );
@@ -497,149 +517,158 @@ void writeGroup(ofstream& fout,Id model)
{
path = path.substr( pos );
fout << "simundump group " << path << " 0 " <<
- "blue" << " " << "green" << " x 0 0 \"\" defaultfile \\\n";
+ "blue" << " " << "green" << " x 0 0 \"\" defaultfile \\\n";
fout << " defaultfile.g 0 0 0 " << x << " " << y << " 0\n";
}
}
}
void writeKkit( Id model, const string& fname )
-{ ofstream fout( fname.c_str(), ios::out );
- vector< ObjId > chemCompt;
- vector< string > msgs;
- double simDt;
- double plotDt;
-
- double runTime = estimateSimTimes( simDt, plotDt );
- double defaultVol = estimateDefaultVol( model );
- writeHeader( fout, simDt, plotDt, runTime, defaultVol );
- string bg = "cyan";
- string fg = "black";
- double x = 0;
- double y = 0;
-
- map < double, pair<Id, int> > compt_vol;
-
- unsigned int num = wildcardFind( model.path() + "/##[ISA=ChemCompt]", chemCompt );
- if ( num == 0 ) {
- cout << "Warning: writeKkit:: No model found on " << model <<
- endl;
- return;
- }
- for ( vector< ObjId >::iterator itr = chemCompt.begin(); itr != chemCompt.end();itr++)
- {
- vector < unsigned int>dims;
- unsigned int dims_size;
- dims_size = 1;
- unsigned index = 0;
- string comptPath = Field<string>::get(*itr,"path");
- string comptname = Field<string>::get(*itr,"name");
- if (comptname != "kinetics")
- {
- fout << "simundump group /kinetics/" << comptname << " 0 " <<
- "blue" << " " << "green" << " x 0 0 \"\" defaultfile \\\n";
- fout << " defaultfile.g 0 0 0 " << rand() % 10 + 1 << " " << rand() % 10 + 1 << " 0\n";
- }
- double size = Field<double>::get(ObjId(*itr,index),"Volume");
- unsigned int ndim = Field<unsigned int>::get(ObjId(*itr,index),"NumDimensions");
- ostringstream geometry;
- int vecIndex = itr-chemCompt.begin();
- if (vecIndex > 0)
- geometry << "simundump geometry /kinetics" << "/geometry[" << vecIndex <<"] 0 " << size << " " << ndim << " sphere " <<" \"\" white black 0 0 0\n";
- else
- geometry << "simundump geometry /kinetics" << "/geometry 0 " << size << " " << ndim << " sphere " <<" \"\" white black 0 0 0\n";
- fout << geometry.str();
- compt_vol.insert(make_pair(size,make_pair(*itr,vecIndex)));
- } // compartmentclose
- writeGroup(fout, model);
- map<double, pair<Id, int> >::iterator compt;
- for (compt = compt_vol.begin(); compt != compt_vol.end(); compt++)
- {
- string comptPath = Field<string>::get(compt->second.first,"path");
- // Species
- vector< ObjId > Compt_spe;
- wildcardFind(comptPath+"/##[ISA=PoolBase]",Compt_spe);
- int species_size = 1;
- string objname;
- for (vector <ObjId> :: iterator itrp = Compt_spe.begin();itrp != Compt_spe.end();itrp++)
- { string path = Field <string> :: get (*itrp,"path");
- Id enzPoolparent = Field <ObjId> :: get(*itrp,"parent");
- string enzpoolClass = Field <string> :: get(enzPoolparent,"className");
- if (enzpoolClass != "ZombieEnz" or enzpoolClass != "Enz")
- { Id annotaId( path+"/info");
- if ( annotaId != Id() )
- { double x = Field <double> :: get(annotaId,"x");
- double y = Field <double> :: get(annotaId,"y");
- string fg = Field <string> :: get(annotaId,"textColor");
- string bg = Field <string> :: get(annotaId,"color");
- writePool(fout, *itrp,bg,fg,x,y,compt->second.first,compt->second.second);
- }
- }
- } //species is closed
- vector< ObjId > Compt_Func;
- wildcardFind(comptPath+"/##[ISA=Function]",Compt_Func);
- for (vector <ObjId> :: iterator itrF= Compt_Func.begin();itrF != Compt_Func.end();itrF++)
- { storeFunctionMsgs( *itrF, msgs,compt_vol);
- }
- // Reaction
- vector< ObjId > Compt_Reac;
- wildcardFind(comptPath+"/##[ISA=ReacBase]",Compt_Reac);
- for (vector <ObjId> :: iterator itrR= Compt_Reac.begin();itrR != Compt_Reac.end();itrR++)
- {
- string path = Field<string> :: get(*itrR,"path");
- Id annotaId( path+"/info");
- string noteClass = Field<string> :: get(annotaId,"className");
- string notes;
- double x = Field <double> :: get(annotaId,"x");
- double y = Field <double> :: get(annotaId,"y");
- string fg = Field <string> :: get(annotaId,"textColor");
- string bg = Field <string> :: get(annotaId,"color");
- writeReac( fout, *itrR, bg, fg, x, y, compt->second.first);
- storeReacMsgs( *itrR, msgs, compt->second.first );
- }// reaction
- vector< ObjId > Compt_Enz;
- wildcardFind(comptPath+"/##[ISA=EnzBase]",Compt_Enz);
- for (vector <ObjId> :: iterator itrE= Compt_Enz.begin();itrE != Compt_Enz.end();itrE++)
- { string path = Field<string> :: get(*itrE,"path");
- Id annotaId( path+"/info");
- string noteClass = Field<string> :: get(annotaId,"className");
- string notes;
- double x = Field <double> :: get(annotaId,"x");
- double y = Field <double> :: get(annotaId,"y");
- string fg = Field <string> :: get(annotaId,"textColor");
- string bg = Field <string> :: get(annotaId,"color");
- writeEnz( fout, *itrE, bg, fg, x, y, compt->second.first);
- storeEnzMsgs( *itrE, msgs, compt->second.first);
- }// reaction
-
- } //compatment loop
- writeGui ( fout);
-
- /* Table */
-
- vector< ObjId > table;
- wildcardFind(model.path()+"/##[ISA=Table2]",table);
- for (vector <ObjId> :: iterator itrT= table.begin();itrT != table.end();itrT++)
- { string tabPath = Field <string> :: get(*itrT,"path");
- vector < Id > tabSrc = LookupField <string,vector < Id> >::get(*itrT, "neighbors","requestOut");
- for (vector <Id> :: iterator tabItem= tabSrc.begin();tabItem != tabSrc.end();tabItem++)
- { string path = Field <string> :: get(*tabItem,"path");
- double vol = Field < double> :: get (*tabItem,"Volume");
- //Trying to find the compartment name via volume
- //otherwise if we go via parent, sometimes it might
- // get groupname so maped compartment Id and volume
-
- Id parentId = compt_vol[vol].first;
- string parentname = Field <string> :: get(parentId,"name");
- Id annotaId(path+"/info");
- double x = Field <double> :: get(annotaId,"x");
- double y = Field <double> :: get(annotaId,"y");
- string bg = Field <string> :: get(annotaId,"textColor");
- string fg = Field <string> :: get(annotaId,"color");
- writePlot( fout, *itrT, bg, fg, x, y );
- storePlotMsgs( *itrT, msgs,*tabItem,fg, parentId);
+{
+ ofstream fout( fname.c_str(), ios::out );
+ vector< ObjId > chemCompt;
+ vector< string > msgs;
+ double simDt;
+ double plotDt;
+
+ double runTime = estimateSimTimes( simDt, plotDt );
+ double defaultVol = estimateDefaultVol( model );
+ writeHeader( fout, simDt, plotDt, runTime, defaultVol );
+ string bg = "cyan";
+ string fg = "black";
+ double x = 0;
+ double y = 0;
+
+ map < double, pair<Id, int> > compt_vol;
+
+ unsigned int num = wildcardFind( model.path() + "/##[ISA=ChemCompt]", chemCompt );
+ if ( num == 0 )
+ {
+ cout << "Warning: writeKkit:: No model found on " << model <<
+ endl;
+ return;
+ }
+ for ( vector< ObjId >::iterator itr = chemCompt.begin(); itr != chemCompt.end(); itr++)
+ {
+ vector < unsigned int>dims;
+ unsigned int dims_size;
+ dims_size = 1;
+ unsigned index = 0;
+ string comptPath = Field<string>::get(*itr,"path");
+ string comptname = Field<string>::get(*itr,"name");
+ if (comptname != "kinetics")
+ {
+ fout << "simundump group /kinetics/" << comptname << " 0 " <<
+ "blue" << " " << "green" << " x 0 0 \"\" defaultfile \\\n";
+ fout << " defaultfile.g 0 0 0 " << rand() % 10 + 1 << " " << rand() % 10 + 1 << " 0\n";
+ }
+ double size = Field<double>::get(ObjId(*itr,index),"Volume");
+ unsigned int ndim = Field<unsigned int>::get(ObjId(*itr,index),"NumDimensions");
+ ostringstream geometry;
+ int vecIndex = itr-chemCompt.begin();
+ if (vecIndex > 0)
+ geometry << "simundump geometry /kinetics" << "/geometry[" << vecIndex <<"] 0 " << size << " " << ndim << " sphere " <<" \"\" white black 0 0 0\n";
+ else
+ geometry << "simundump geometry /kinetics" << "/geometry 0 " << size << " " << ndim << " sphere " <<" \"\" white black 0 0 0\n";
+ fout << geometry.str();
+ compt_vol.insert(make_pair(size,make_pair(*itr,vecIndex)));
+ } // compartmentclose
+ writeGroup(fout, model);
+ map<double, pair<Id, int> >::iterator compt;
+ for (compt = compt_vol.begin(); compt != compt_vol.end(); compt++)
+ {
+ string comptPath = Field<string>::get(compt->second.first,"path");
+ // Species
+ vector< ObjId > Compt_spe;
+ wildcardFind(comptPath+"/##[ISA=PoolBase]",Compt_spe);
+ int species_size = 1;
+ string objname;
+ for (vector <ObjId> :: iterator itrp = Compt_spe.begin(); itrp != Compt_spe.end(); itrp++)
+ {
+ string path = Field <string> :: get (*itrp,"path");
+ Id enzPoolparent = Field <ObjId> :: get(*itrp,"parent");
+ string enzpoolClass = Field <string> :: get(enzPoolparent,"className");
+ if (enzpoolClass != "ZombieEnz" or enzpoolClass != "Enz")
+ {
+ Id annotaId( path+"/info");
+ if ( annotaId != Id() )
+ {
+ double x = Field <double> :: get(annotaId,"x");
+ double y = Field <double> :: get(annotaId,"y");
+ string fg = Field <string> :: get(annotaId,"textColor");
+ string bg = Field <string> :: get(annotaId,"color");
+ writePool(fout, *itrp,bg,fg,x,y,compt->second.first,compt->second.second);
+ }
+ }
+ } //species is closed
+ vector< ObjId > Compt_Func;
+ wildcardFind(comptPath+"/##[ISA=Function]",Compt_Func);
+ for (vector <ObjId> :: iterator itrF= Compt_Func.begin(); itrF != Compt_Func.end(); itrF++)
+ {
+ storeFunctionMsgs( *itrF, msgs,compt_vol);
+ }
+ // Reaction
+ vector< ObjId > Compt_Reac;
+ wildcardFind(comptPath+"/##[ISA=ReacBase]",Compt_Reac);
+ for (vector <ObjId> :: iterator itrR= Compt_Reac.begin(); itrR != Compt_Reac.end(); itrR++)
+ {
+ string path = Field<string> :: get(*itrR,"path");
+ Id annotaId( path+"/info");
+ string noteClass = Field<string> :: get(annotaId,"className");
+ string notes;
+ double x = Field <double> :: get(annotaId,"x");
+ double y = Field <double> :: get(annotaId,"y");
+ string fg = Field <string> :: get(annotaId,"textColor");
+ string bg = Field <string> :: get(annotaId,"color");
+ writeReac( fout, *itrR, bg, fg, x, y, compt->second.first);
+ storeReacMsgs( *itrR, msgs, compt->second.first );
+ }// reaction
+ vector< ObjId > Compt_Enz;
+ wildcardFind(comptPath+"/##[ISA=EnzBase]",Compt_Enz);
+ for (vector <ObjId> :: iterator itrE= Compt_Enz.begin(); itrE != Compt_Enz.end(); itrE++)
+ {
+ string path = Field<string> :: get(*itrE,"path");
+ Id annotaId( path+"/info");
+ string noteClass = Field<string> :: get(annotaId,"className");
+ string notes;
+ double x = Field <double> :: get(annotaId,"x");
+ double y = Field <double> :: get(annotaId,"y");
+ string fg = Field <string> :: get(annotaId,"textColor");
+ string bg = Field <string> :: get(annotaId,"color");
+ writeEnz( fout, *itrE, bg, fg, x, y, compt->second.first);
+ storeEnzMsgs( *itrE, msgs, compt->second.first);
+ }// reaction
+
+ } //compatment loop
+ writeGui ( fout);
+
+ /* Table */
+
+ vector< ObjId > table;
+ wildcardFind(model.path()+"/##[ISA=Table2]",table);
+ for (vector <ObjId> :: iterator itrT= table.begin(); itrT != table.end(); itrT++)
+ {
+ string tabPath = Field <string> :: get(*itrT,"path");
+ vector < Id > tabSrc = LookupField <string,vector < Id> >::get(*itrT, "neighbors","requestOut");
+ for (vector <Id> :: iterator tabItem= tabSrc.begin(); tabItem != tabSrc.end(); tabItem++)
+ {
+ string path = Field <string> :: get(*tabItem,"path");
+ double vol = Field < double> :: get (*tabItem,"Volume");
+ //Trying to find the compartment name via volume
+ //otherwise if we go via parent, sometimes it might
+ // get groupname so maped compartment Id and volume
+
+ Id parentId = compt_vol[vol].first;
+ string parentname = Field <string> :: get(parentId,"name");
+ Id annotaId(path+"/info");
+ double x = Field <double> :: get(annotaId,"x");
+ double y = Field <double> :: get(annotaId,"y");
+ string bg = Field <string> :: get(annotaId,"textColor");
+ string fg = Field <string> :: get(annotaId,"color");
+ writePlot( fout, *itrT, bg, fg, x, y );
+ storePlotMsgs( *itrT, msgs,*tabItem,fg, parentId);
- }
- }// table
- writeMsgs( fout, msgs );
- writeFooter( fout );
+ }
+ }// table
+ writeMsgs( fout, msgs );
+ writeFooter( fout );
}
diff --git a/ksolve/BoostSys.cpp b/ksolve/BoostSys.cpp
index 4a3faf018f7acc4995b052d40bd6687a4c638a75..0a6e4eb33bb02ee10955f680d43070d7f4ae20cc 100644
--- a/ksolve/BoostSys.cpp
+++ b/ksolve/BoostSys.cpp
@@ -18,7 +18,7 @@
#include <iostream>
#include "VoxelPools.h"
-#ifdef USE_BOOST
+#ifdef USE_BOOST_ODE
BoostSys::BoostSys( ) : vp( NULL )
{ ; }
@@ -34,5 +34,6 @@ void BoostSys::operator()( const vector_type_ y
VoxelPools::evalRates( y, dydt, t, vp );
}
-#else /* ----- not USE_BOOST ----- */
-#endif /* ----- not USE_BOOST ----- */
+#else /* ----- not USE_BOOST_ODE ----- */
+
+#endif /* ----- not USE_BOOST_ODE ----- */
diff --git a/ksolve/BoostSys.h b/ksolve/BoostSys.h
index 8714b3d4541cdbf5a80cfb74d3fb734aa839afc3..ae97723a52ddf24e6cc10ac97f0da573b93ffceb 100644
--- a/ksolve/BoostSys.h
+++ b/ksolve/BoostSys.h
@@ -1,11 +1,10 @@
#ifndef BOOSTSYSTEM_H
#define BOOSTSYSTEM_H
-#ifdef USE_BOOST
+#ifdef USE_BOOST_ODE
#include <vector>
#include <string>
-
#include <boost/numeric/odeint.hpp>
typedef double value_type_;
@@ -34,23 +33,23 @@ class VoxelPools;
*/
class BoostSys
{
- public:
- BoostSys( );
- ~BoostSys();
+public:
+ BoostSys( );
+ ~BoostSys( );
- /* Operator is called by boost ode-solver */
- void operator()( const vector_type_ y , vector_type_& dydt, const double t );
+ /* Operator is called by boost ode-solver */
+ void operator()( const vector_type_ y , vector_type_& dydt, const double t );
- /* Pointer to the arbitrary parameters of the system */
- VoxelPools* vp;
- void* params;
+ /* Pointer to the arbitrary parameters of the system */
+ VoxelPools* vp;
+ void* params;
- double epsAbs;
- double epsRel;
- std::string method;
+ double epsAbs;
+ double epsRel;
+ std::string method;
};
-#endif // USE_BOOST
+#endif // USE_BOOST_ODE
#endif /* end of include guard: BOOSTSYSTEM_H */
diff --git a/ksolve/CMakeLists.txt b/ksolve/CMakeLists.txt
index c26bbcecedbd48da80fbb8f88831c1f2fd8dbdf8..f35588de2c69225086b36e306e023d546c88ae68 100644
--- a/ksolve/CMakeLists.txt
+++ b/ksolve/CMakeLists.txt
@@ -1,11 +1,11 @@
-cmake_minimum_required(VERSION 2.6)
+cmake_minimum_required(VERSION 2.8)
include(CheckIncludeFileCXX)
include_directories(../builtins ../basecode ../utility ../kinetics)
include_directories(../ )
include_directories(../mesh)
include_directories(../external/muparser/include )
-IF(WITH_BOOST)
+IF(WITH_BOOST_ODE)
check_include_file_cxx( ${Boost_INCLUDE_DIRS}/boost/numeric/odeint.hpp
ODEINT_EXISTS)
# If boost distribution does not have its own odeint library, use the
@@ -16,7 +16,7 @@ IF(WITH_BOOST)
include_directories( ../external/boost-numeric-bindings )
elseif(WITH_GSL)
include_directories( ${GSL_INCLUDE_DIRS} )
-endif(WITH_BOOST)
+endif(WITH_BOOST_ODE)
if(PARALLELIZED_SOLVERS)
message( STATUS "Parallel version of KSolve and Gsolve" )
@@ -46,7 +46,7 @@ set(KSOLVE_SRCS
if(WITH_GSL)
list(APPEND KSOLVE_SRCS SteadyStateGsl.cpp )
-elseif(WITH_BOOST)
+elseif(WITH_BOOST_ODE)
list(APPEND KSOLVE_SRCS SteadyStateBoost.cpp )
list(APPEND KSOLVE_SRCS BoostSys.cpp)
endif(WITH_GSL)
diff --git a/ksolve/Gsolve.cpp b/ksolve/Gsolve.cpp
index 25a5c060e7fcc6cb14c6be0550a1121b5842d548..c7f5cb8ac00bcc159ee2fc54c3260c0c2dd61630 100644
--- a/ksolve/Gsolve.cpp
+++ b/ksolve/Gsolve.cpp
@@ -6,10 +6,12 @@
** GNU Lesser General Public License version 2.1
** See the file COPYING.LIB for the full notice.
**********************************************************************/
-#include "header.h"
+#include "../basecode/header.h"
+#include "../basecode/global.h"
-#include "VoxelPoolsBase.h"
#include "../mesh/VoxelJunction.h"
+
+#include "VoxelPoolsBase.h"
#include "XferInfo.h"
#include "ZombiePoolInterface.h"
@@ -21,7 +23,6 @@
#include "GssaSystem.h"
#include "Stoich.h"
#include "GssaVoxelPools.h"
-#include "../randnum/randnum.h"
#include <future>
#include <atomic>
@@ -215,6 +216,11 @@ Gsolve::Gsolve() :
;
}
+Gsolve& Gsolve::operator=(const Gsolve& )
+{
+ return *this;
+}
+
Gsolve::~Gsolve()
{
;
@@ -419,7 +425,9 @@ void Gsolve::process( const Eref& e, ProcPtr p )
*i = round( *i );
#else
double base = floor( *i );
- if ( mtrand() >= (*i - base) )
+
+ // Use global RNG.
+ if ( moose::mtrand() >= (*i - base) )
*i = base;
else
*i = base + 1.0;
diff --git a/ksolve/Gsolve.h b/ksolve/Gsolve.h
index 78f572abc3a32d03af85a67812f67bb34ee04398..cb51181468c1a30966a0f53593538eb1658bca82 100644
--- a/ksolve/Gsolve.h
+++ b/ksolve/Gsolve.h
@@ -17,6 +17,9 @@ public:
Gsolve();
~Gsolve();
+ // Assignment operator required for c++11
+ Gsolve& operator=(const Gsolve& );
+
//////////////////////////////////////////////////////////////////
// Field assignment stuff
//////////////////////////////////////////////////////////////////
diff --git a/ksolve/GssaSystem.h b/ksolve/GssaSystem.h
index 6c81c5139f1efd24c1271957e099dacd5b16e7d0..c1b8ad91df09b453162f77215f31cdd38f255436 100644
--- a/ksolve/GssaSystem.h
+++ b/ksolve/GssaSystem.h
@@ -18,35 +18,40 @@
class Stoich;
class GssaSystem
{
- public:
- GssaSystem()
- : stoich( 0 ), useRandInit( true ), isReady( false )
- {;}
- vector< vector< unsigned int > > dependency;
- vector< vector< unsigned int > > dependentMathExpn;
- vector< vector< unsigned int > > ratesDependentOnPool;
-
- /// Transpose of stoichiometry matrix.
- KinSparseMatrix transposeN;
- Stoich* stoich;
-
- /**
- * Flag: True when using probabilistic (random) rounding.
- * When initializing the mol# from floating-point Sinit values,
- * we have two options. One is to look at each Sinit, and round
- * to the nearest integer. The other is to look at each Sinit,
- * and probabilistically round up or down depending on the
- * value. For example, if we had a Sinit value of 1.49,
- * this would always be rounded to 1.0 if the flag is false,
- * and would be rounded to 1.0 and 2.0 in the ratio 51:49 if
- * the flag is true.
- */
- bool useRandInit;
-
- /**
- * Flag: True when all initialization is done.
- */
- bool isReady;
+public:
+ GssaSystem()
+ : stoich(0), useRandInit(true), isReady(false), honorMassConservation(true)
+ {;}
+ vector< vector< unsigned int > > dependency;
+ vector< vector< unsigned int > > dependentMathExpn;
+ vector< vector< unsigned int > > ratesDependentOnPool;
+
+ /// Transpose of stoichiometry matrix.
+ KinSparseMatrix transposeN;
+ Stoich* stoich;
+
+ /**
+ * Flag: True when using probabilistic (random) rounding.
+ * When initializing the mol# from floating-point Sinit values,
+ * we have two options. One is to look at each Sinit, and round
+ * to the nearest integer. The other is to look at each Sinit,
+ * and probabilistically round up or down depending on the
+ * value. For example, if we had a Sinit value of 1.49,
+ * this would always be rounded to 1.0 if the flag is false,
+ * and would be rounded to 1.0 and 2.0 in the ratio 51:49 if
+ * the flag is true.
+ */
+ bool useRandInit = true;
+
+ /**
+ * Flag: True when all initialization is done.
+ */
+ bool isReady = false;
+
+ /* When set to true, it makes sure that after rounding number of molecules,
+ * the sum of molecules is does not differ more than 1.0 molecules.
+ */
+ bool honorMassConservation = true;
};
#endif // _GSSA_SYSTEM_H
diff --git a/ksolve/GssaVoxelPools.cpp b/ksolve/GssaVoxelPools.cpp
index 273964301a5e40d0a8b853fdee1b198ccd3c616f..4128d0a6dcd65010cbe263fdcb178f83cdee3ef3 100644
--- a/ksolve/GssaVoxelPools.cpp
+++ b/ksolve/GssaVoxelPools.cpp
@@ -48,7 +48,7 @@ const double SAFETY_FACTOR = 1.0 + 1.0e-9;
//////////////////////////////////////////////////////////////
GssaVoxelPools::GssaVoxelPools() :
- VoxelPoolsBase(), t_( 0.0 ), atot_( 0.0 )
+ VoxelPoolsBase(), t_( 0.0 ), atot_( 0.0 )
{ ; }
GssaVoxelPools::~GssaVoxelPools()
@@ -78,15 +78,15 @@ void GssaVoxelPools::updateDependentMathExpn(
g->stoich->funcs( *i )->evalPool( varS(), time );
}
*/
- /*
+ /*
unsigned int numFuncs = g->stoich->getNumFuncs();
for( unsigned int i = 0; i < numFuncs; ++i )
{
g->stoich->funcs( i )->evalPool( varS(), time );
}
- */
- // This function is equivalent to the loop above.
- g->stoich->updateFuncs( varS(), time );
+ */
+ // This function is equivalent to the loop above.
+ g->stoich->updateFuncs( varS(), time );
}
void GssaVoxelPools::updateDependentRates(
@@ -139,7 +139,7 @@ void GssaVoxelPools::setNumReac( unsigned int n )
*/
bool GssaVoxelPools::refreshAtot( const GssaSystem* g )
{
- g->stoich->updateFuncs( varS(), t_ );
+ g->stoich->updateFuncs( varS(), t_ );
updateReacVelocities( g, S(), v_ );
atot_ = 0;
for ( vector< double >::const_iterator
@@ -178,8 +178,8 @@ void GssaVoxelPools::advance( const ProcInfo* p, const GssaSystem* g )
if ( atot_ <= 0.0 ) // reac system is stuck, will not advance.
{
t_ = nextt;
- g->stoich->updateFuncs( varS(), t_ );
- // updateDependentMathExpn( g, 0, t_ );
+ g->stoich->updateFuncs( varS(), t_ );
+ // updateDependentMathExpn( g, 0, t_ );
return;
}
unsigned int rindex = pickReac();
@@ -191,8 +191,8 @@ void GssaVoxelPools::advance( const ProcInfo* p, const GssaSystem* g )
if ( !refreshAtot( g ) ) // Stuck state.
{
t_ = nextt;
- g->stoich->updateFuncs( varS(), t_ );
- // updateDependentMathExpn( g, 0, t_ );
+ g->stoich->updateFuncs( varS(), t_ );
+ // updateDependentMathExpn( g, 0, t_ );
return;
}
// We had a roundoff error, fixed it, but now need to be sure
@@ -208,17 +208,22 @@ void GssaVoxelPools::advance( const ProcInfo* p, const GssaSystem* g )
assert( rindex < v_.size() );
}
+#if ENABLE_CPP11
+ double sign = std::copysign( 1, v_[rindex] );
+#else
double sign = double(v_[rindex] >= 0) - double(0 > v_[rindex] );
+#endif
+
g->transposeN.fireReac( rindex, Svec(), sign );
- numFire_[rindex]++;
+ numFire_[rindex]++;
double r = rng_.uniform();
+
while ( r <= 0.0 )
- {
r = rng_.uniform();
- }
+
t_ -= ( 1.0 / atot_ ) * log( r );
- g->stoich->updateFuncs( varS(), t_ );
+ g->stoich->updateFuncs( varS(), t_ );
// updateDependentMathExpn( g, rindex, t_ );
updateDependentRates( g->dependency[ rindex ], g->stoich );
}
@@ -233,36 +238,66 @@ void GssaVoxelPools::reinit( const GssaSystem* g )
double* n = varS();
- if ( g->useRandInit )
+ if( g->useRandInit )
{
- // round up or down probabilistically depending on fractional
- // num molecules.
+ vector<double> error(numVarPools, 0.0);
+ map<double, vector<Eref>> groupByVal;
+
for ( unsigned int i = 0; i < numVarPools; ++i )
{
- double base = floor( n[i] );
+ error[i] = n[i];
+ double base = std::floor( n[i] );
assert( base >= 0.0 );
double frac = n[i] - base;
- if ( rng_.uniform() > frac )
+ if ( rng_.uniform() >= frac )
n[i] = base;
else
n[i] = base + 1.0;
+
+ error[i] -= n[i];
+
+ //if( true )
+ //{
+ // //NOTE: Thats how I get the name of the pool at this index.
+ // Eref e = g->stoich->getPoolByIndex( i ).eref();
+ // groupByVal[n[i]].push_back( e );
+
+ // // Guess the fix the error.
+ //}
+
+
+ }
+
+ double extra = std::accumulate( error.begin(), error.end(), 0.0 );
+ if( std::abs(extra) > 0.1 )
+ {
+ cout << "WARNING: Extra " << extra
+ << " molecules in system after converting fractional to integer e.g. 1.1 = 1 (~90% of times) or 2 (~10% of times)." << endl;
}
}
else // Just round to the nearest int.
{
for ( unsigned int i = 0; i < numVarPools; ++i )
{
+#if ENABLE_CPP11
+ // Just like rint but does not raise exception.
+ // See http://en.cppreference.com/w/cpp/numeric/math/nearbyint for
+ // details.
+ n[i] = std::nearbyint(n[i]);
+#else
n[i] = round( n[i] );
+#endif
}
}
+
t_ = 0.0;
refreshAtot( g );
- numFire_.assign( v_.size(), 0 );
+ numFire_.assign( v_.size(), 0 );
}
vector< unsigned int > GssaVoxelPools::numFire() const
{
- return numFire_;
+ return numFire_;
}
/////////////////////////////////////////////////////////////////////////
diff --git a/ksolve/GssaVoxelPools.h b/ksolve/GssaVoxelPools.h
index 716698a48037aab51363745fc19348b9536f415b..b0bc90e5c20487ae5e2ddfb7da0fa6893c6b520f 100644
--- a/ksolve/GssaVoxelPools.h
+++ b/ksolve/GssaVoxelPools.h
@@ -34,7 +34,7 @@ public:
void advance( const ProcInfo* p, const GssaSystem* g );
- vector< unsigned int > numFire() const;
+ vector< unsigned int > numFire() const;
/**
* Cleans out all reac rates and recalculates atot. Needed whenever a
@@ -88,8 +88,8 @@ private:
vector< double > v_;
// Possibly we should put independent RNGS, so save one here.
- // Count how many times each reaction has fired.
- vector< unsigned int > numFire_;
+ // Count how many times each reaction has fired.
+ vector< unsigned int > numFire_;
/**
* @brief RNG.
diff --git a/ksolve/Ksolve.cpp b/ksolve/Ksolve.cpp
index 8b7b5ac9ddeaa261724ad8eda3954cfc496d2010..b55d0d1212d43744be7a3232f7a8cb53cdcac03f 100644
--- a/ksolve/Ksolve.cpp
+++ b/ksolve/Ksolve.cpp
@@ -6,7 +6,7 @@
** GNU Lesser General Public License version 2.1
** See the file COPYING.LIB for the full notice.
**********************************************************************/
-#include "header.h"
+#include "../basecode/header.h"
#ifdef USE_GSL
#include <gsl/gsl_errno.h>
#include <gsl/gsl_matrix.h>
@@ -21,7 +21,7 @@
#include "RateTerm.h"
#include "FuncTerm.h"
-#include "SparseMatrix.h"
+#include "../basecode/SparseMatrix.h"
#include "KinSparseMatrix.h"
#include "Stoich.h"
#include "../shell/Shell.h"
@@ -217,7 +217,7 @@ Ksolve::Ksolve()
:
#if USE_GSL
method_( "rk5" ),
-#elif USE_BOOST
+#elif USE_BOOST_ODE
method_( "rk5a" ),
#endif
epsAbs_( 1e-7 ),
@@ -265,7 +265,7 @@ void Ksolve::setMethod( string method )
"' not known, using rk5\n";
method_ = "rk5";
}
-#elif USE_BOOST
+#elif USE_BOOST_ODE
// TODO: Check for boost related methods.
method_ = method;
#endif
@@ -380,7 +380,7 @@ void Ksolve::setStoich( Id stoich )
pools_[i].setStoich( stoichPtr_, &ode );
// pools_[i].setIntDt( ode.initStepSize ); // We're setting it up anyway
}
-#elif USE_BOOST
+#elif USE_BOOST_ODE
ode.dimension = stoichPtr_->getNumAllPools();
ode.boostSys.epsAbs = epsAbs_;
ode.boostSys.epsRel = epsRel_;
@@ -511,7 +511,7 @@ void Ksolve::process( const Eref& e, ProcPtr p )
dsolvePtr_->getBlock( dvalues );
// Second, set the prev_ value in DiffPoolVec
dsolvePtr_->setPrev();
- setBlock( dvalues );
+ setBlock( dvalues );
}
size_t nvPools = pools_.size( );
diff --git a/ksolve/OdeSystem.h b/ksolve/OdeSystem.h
index 0f7e37a64c5eae9f54b5055641528bf98edb24c5..84e2c72fa8ca9bc2b5245a255cdd9bb072df03eb 100644
--- a/ksolve/OdeSystem.h
+++ b/ksolve/OdeSystem.h
@@ -10,11 +10,11 @@
#ifndef _ODE_SYSTEM_H
#define _ODE_SYSTEM_H
-#if USE_BOOST
+#if USE_BOOST_ODE
#include "BoostSys.h"
#elif USE_GSL
#include <gsl/gsl_odeiv2.h>
-#endif /* ----- not USE_BOOST ----- */
+#endif /* ----- not USE_BOOST_ODE ----- */
class OdeSystem {
public:
@@ -36,11 +36,11 @@ class OdeSystem {
double epsAbs; // Absolute error
double epsRel; // Relative error
-#if USE_BOOST
+#if USE_BOOST_ODE
//BoostSys* pBoostSys;
BoostSys boostSys;
size_t dimension;
-#endif /* ----- USE_BOOST ----- */
+#endif /* ----- USE_BOOST_ODE ----- */
};
#endif // _ODE_SYSTEM_H
diff --git a/ksolve/SteadyStateBoost.cpp b/ksolve/SteadyStateBoost.cpp
index 98e5b210d3141f89f64c7aaa5aee323872371879..a96439baec7d42630d9fe2441641a2c5c5521bd0 100644
--- a/ksolve/SteadyStateBoost.cpp
+++ b/ksolve/SteadyStateBoost.cpp
@@ -339,7 +339,6 @@ SteadyState::SteadyState()
solutionStatus_( 0 ),
numFailed_( 0 )
{
- rng.setSeed( moose::__rng_seed__ );
}
SteadyState::~SteadyState()
@@ -1046,7 +1045,7 @@ void SteadyState::fitConservationRules(
double ytot = 0.0;
for ( int k = j; k < lastJ; ++k )
{
- y[k] = rng.uniform( );
+ y[k] = moose::mtrand();
ytot += y[k] * U( i, k );
}
assert( fabs( ytot ) > EPSILON );
diff --git a/ksolve/SteadyStateBoost.h b/ksolve/SteadyStateBoost.h
index 66303a18165037a9ea5cf5869aaa40f4355ca922..7db6b0da8c8d9e5a180a2670a97bca2a7e170bbd 100644
--- a/ksolve/SteadyStateBoost.h
+++ b/ksolve/SteadyStateBoost.h
@@ -125,9 +125,7 @@ private:
unsigned int numFailed_;
VoxelPools pool_;
- moose::RNG<double> rng;
-
-#if USE_BOOST
+#if USE_BOOST_ODE
NonlinearSystem* ss;
#endif
diff --git a/ksolve/SteadyStateGsl.cpp b/ksolve/SteadyStateGsl.cpp
index e8d805d7a4d78de23cb1dcb81740715308bf0b4f..295b5256d5edcd4e574ef7b9e99222db4aef9e23 100644
--- a/ksolve/SteadyStateGsl.cpp
+++ b/ksolve/SteadyStateGsl.cpp
@@ -18,7 +18,9 @@
* Likewise, if you want to carry out a dose-response calculation.
*/
-#include "header.h"
+#include "../basecode/header.h"
+#include "../basecode/global.h"
+
#include "SparseMatrix.h"
#include "KinSparseMatrix.h"
#include "RateTerm.h"
@@ -28,7 +30,6 @@
#include "XferInfo.h"
#include "ZombiePoolInterface.h"
#include "Stoich.h"
-#include "../randnum/randnum.h"
#ifdef USE_GSL
#include <gsl/gsl_errno.h>
@@ -64,249 +65,250 @@ const double SteadyState::DELTA = 1e-6;
*/
struct reac_info
{
- int rank;
- int num_reacs;
- size_t num_mols;
- int nIter;
- double convergenceCriterion;
+ int rank;
+ int num_reacs;
+ size_t num_mols;
+ int nIter;
+ double convergenceCriterion;
- double* T;
- VoxelPools* pool;
- vector< double > nVec;
+ double* T;
+ VoxelPools* pool;
+ vector< double > nVec;
#ifdef USE_GSL
- gsl_matrix* Nr;
- gsl_matrix* gamma;
+ gsl_matrix* Nr;
+ gsl_matrix* gamma;
#endif
};
const Cinfo* SteadyState::initCinfo()
{
- /**
- * This picks up the entire Stoich data structure
- static Finfo* gslShared[] =
- {
- new SrcFinfo( "reinitSrc", Ftype0::global() ),
- new DestFinfo( "assignStoich",
- Ftype1< void* >::global(),
- RFCAST( &SteadyState::assignStoichFunc )
- ),
- new DestFinfo( "setMolN",
- Ftype2< double, unsigned int >::global(),
- RFCAST( &SteadyState::setMolN )
- ),
- new SrcFinfo( "requestYsrc", Ftype0::global() ),
- new DestFinfo( "assignY",
- Ftype1< double* >::global(),
- RFCAST( &SteadyState::assignY )
- ),
- };
- */
-
- /**
- * These are the fields of the SteadyState class
- */
- ///////////////////////////////////////////////////////
- // Field definitions
- ///////////////////////////////////////////////////////
- static ValueFinfo< SteadyState, Id > stoich(
- "stoich",
- "Specify the Id of the stoichiometry system to use",
- &SteadyState::setStoich,
- &SteadyState::getStoich
- );
- static ReadOnlyValueFinfo< SteadyState, bool > badStoichiometry(
- "badStoichiometry",
- "Bool: True if there is a problem with the stoichiometry",
- &SteadyState::badStoichiometry
- );
- static ReadOnlyValueFinfo< SteadyState, bool > isInitialized(
- "isInitialized",
- "True if the model has been initialized successfully",
- &SteadyState::isInitialized
- );
- static ReadOnlyValueFinfo< SteadyState, unsigned int > nIter(
- "nIter",
- "Number of iterations done by steady state solver",
- &SteadyState::getNiter
- );
- static ReadOnlyValueFinfo< SteadyState, string > status(
- "status",
- "Status of solver",
- &SteadyState::getStatus
- );
- static ValueFinfo< SteadyState, unsigned int > maxIter(
- "maxIter",
- "Max permissible number of iterations to try before giving up",
- &SteadyState::setMaxIter,
- &SteadyState::getMaxIter
- );
- static ValueFinfo< SteadyState, double> convergenceCriterion(
- "convergenceCriterion",
- "Fractional accuracy required to accept convergence",
- &SteadyState::setConvergenceCriterion,
- &SteadyState::getConvergenceCriterion
- );
- static ReadOnlyValueFinfo< SteadyState, unsigned int > numVarPools(
- "numVarPools",
- "Number of variable molecules in reaction system.",
- &SteadyState::getNumVarPools
- );
- static ReadOnlyValueFinfo< SteadyState, unsigned int > rank(
- "rank",
- "Number of independent molecules in reaction system",
- &SteadyState::getRank
- );
- static ReadOnlyValueFinfo< SteadyState, unsigned int > stateType(
- "stateType",
- "0: stable; 1: unstable; 2: saddle; 3: osc?; 4: one near-zero eigenvalue; 5: other",
- &SteadyState::getStateType
- );
- static ReadOnlyValueFinfo< SteadyState, unsigned int >
- nNegEigenvalues (
- "nNegEigenvalues",
- "Number of negative eigenvalues: indicates type of solution",
- &SteadyState::getNnegEigenvalues
- );
- static ReadOnlyValueFinfo< SteadyState, unsigned int >
- nPosEigenvalues(
- "nPosEigenvalues",
- "Number of positive eigenvalues: indicates type of solution",
- &SteadyState::getNposEigenvalues
- );
- static ReadOnlyValueFinfo< SteadyState, unsigned int > solutionStatus(
- "solutionStatus",
- "0: Good; 1: Failed to find steady states; "
- "2: Failed to find eigenvalues",
- &SteadyState::getSolutionStatus
- );
- static LookupValueFinfo< SteadyState, unsigned int, double > total(
- "total",
- "Totals table for conservation laws. The exact mapping of"
- "this to various sums of molecules is given by the "
- "conservation matrix, and is currently a bit opaque."
- "The value of 'total' is set to initial conditions when"
- "the 'SteadyState::settle' function is called."
- "Assigning values to the total is a special operation:"
- "it rescales the concentrations of all the affected"
- "molecules so that they are at the specified total."
- "This happens the next time 'settle' is called.",
- &SteadyState::setTotal,
- &SteadyState::getTotal
- );
- static ReadOnlyLookupValueFinfo<
- SteadyState, unsigned int, double > eigenvalues(
- "eigenvalues",
- "Eigenvalues computed for steady state",
- &SteadyState::getEigenvalue
- );
- ///////////////////////////////////////////////////////
- // MsgDest definitions
- ///////////////////////////////////////////////////////
- static DestFinfo setupMatrix( "setupMatrix",
- "This function initializes and rebuilds the matrices used "
- "in the calculation.",
- new OpFunc0< SteadyState >(&SteadyState::setupMatrix)
- );
-
- static DestFinfo settle( "settle",
- "Finds the nearest steady state to the current initial "
- "conditions. This function rebuilds the entire calculation "
- "only if the object has not yet been initialized.",
- new OpFunc0< SteadyState >( &SteadyState::settleFunc )
- );
- static DestFinfo resettle( "resettle",
- "Finds the nearest steady state to the current initial "
- "conditions. This function rebuilds the entire calculation ",
- new OpFunc0< SteadyState >( &SteadyState::resettleFunc )
- );
- static DestFinfo showMatrices( "showMatrices",
- "Utility function to show the matrices derived for the calculations on the reaction system. Shows the Nr, gamma, and total matrices",
- new OpFunc0< SteadyState >( &SteadyState::showMatrices )
- );
- static DestFinfo randomInit( "randomInit",
- "Generate random initial conditions consistent with the mass"
- "conservation rules. Typically invoked in order to scan"
- "states",
- new EpFunc0< SteadyState >(
- &SteadyState::randomizeInitialCondition )
- );
- ///////////////////////////////////////////////////////
- // Shared definitions
- ///////////////////////////////////////////////////////
-
- static Finfo * steadyStateFinfos[] = {
- &stoich, // Value
- &badStoichiometry, // ReadOnlyValue
- &isInitialized, // ReadOnlyValue
- &nIter, // ReadOnlyValue
- &status, // ReadOnlyValue
- &maxIter, // Value
- &convergenceCriterion, // ReadOnlyValue
- &numVarPools, // ReadOnlyValue
- &rank, // ReadOnlyValue
- &stateType, // ReadOnlyValue
- &nNegEigenvalues, // ReadOnlyValue
- &nPosEigenvalues, // ReadOnlyValue
- &solutionStatus, // ReadOnlyValue
- &total, // LookupValue
- &eigenvalues, // ReadOnlyLookupValue
- &setupMatrix, // DestFinfo
- &settle, // DestFinfo
- &resettle, // DestFinfo
- &showMatrices, // DestFinfo
- &randomInit, // DestFinfo
-
-
- };
-
- static string doc[] =
- {
- "Name", "SteadyState",
- "Author", "Upinder S. Bhalla, 2009, updated 2014, NCBS",
- "Description", "SteadyState: works out a steady-state value for "
- "a reaction system. "
- "This class uses the GSL multidimensional root finder algorithms "
- "to find the fixed points closest to the "
- "current molecular concentrations. "
- "When it finds the fixed points, it figures out eigenvalues of "
- "the solution, as a way to help classify the fixed points. "
- "Note that the method finds unstable as well as stable fixed "
- "points.\n "
- "The SteadyState class also provides a utility function "
- "*randomInit()* to "
- "randomly initialize the concentrations, within the constraints "
- "of stoichiometry. This is useful if you are trying to find "
- "the major fixed points of the system. Note that this is "
- "probabilistic. If a fixed point is in a very narrow range of "
- "state space the probability of finding it is small and you "
- "will have to run many iterations with different initial "
- "conditions to find it.\n "
- "The numerical calculations used by the SteadyState solver are "
- "prone to failing on individual calculations. All is not lost, "
- "because the system reports the solutionStatus. "
- "It is recommended that you test this field after every "
- "calculation, so you can simply ignore "
- "cases where it failed and try again with different starting "
- "conditions.\n "
- "Another rule of thumb is that the SteadyState object is more "
- "likely to succeed in finding solutions from a new starting point "
- "if you numerically integrate the chemical system for a short "
- "time (typically under 1 second) before asking it to find the "
- "fixed point. "
- };
-
- static Dinfo< SteadyState > dinfo;
- static Cinfo steadyStateCinfo(
- "SteadyState",
- Neutral::initCinfo(),
- steadyStateFinfos,
- sizeof( steadyStateFinfos )/sizeof(Finfo *),
- &dinfo,
- doc, sizeof( doc ) / sizeof( string )
- );
-
- return &steadyStateCinfo;
+ /**
+ * This picks up the entire Stoich data structure
+ static Finfo* gslShared[] =
+ {
+ new SrcFinfo( "reinitSrc", Ftype0::global() ),
+ new DestFinfo( "assignStoich",
+ Ftype1< void* >::global(),
+ RFCAST( &SteadyState::assignStoichFunc )
+ ),
+ new DestFinfo( "setMolN",
+ Ftype2< double, unsigned int >::global(),
+ RFCAST( &SteadyState::setMolN )
+ ),
+ new SrcFinfo( "requestYsrc", Ftype0::global() ),
+ new DestFinfo( "assignY",
+ Ftype1< double* >::global(),
+ RFCAST( &SteadyState::assignY )
+ ),
+ };
+ */
+
+ /**
+ * These are the fields of the SteadyState class
+ */
+ ///////////////////////////////////////////////////////
+ // Field definitions
+ ///////////////////////////////////////////////////////
+ static ValueFinfo< SteadyState, Id > stoich(
+ "stoich",
+ "Specify the Id of the stoichiometry system to use",
+ &SteadyState::setStoich,
+ &SteadyState::getStoich
+ );
+ static ReadOnlyValueFinfo< SteadyState, bool > badStoichiometry(
+ "badStoichiometry",
+ "Bool: True if there is a problem with the stoichiometry",
+ &SteadyState::badStoichiometry
+ );
+ static ReadOnlyValueFinfo< SteadyState, bool > isInitialized(
+ "isInitialized",
+ "True if the model has been initialized successfully",
+ &SteadyState::isInitialized
+ );
+ static ReadOnlyValueFinfo< SteadyState, unsigned int > nIter(
+ "nIter",
+ "Number of iterations done by steady state solver",
+ &SteadyState::getNiter
+ );
+ static ReadOnlyValueFinfo< SteadyState, string > status(
+ "status",
+ "Status of solver",
+ &SteadyState::getStatus
+ );
+ static ValueFinfo< SteadyState, unsigned int > maxIter(
+ "maxIter",
+ "Max permissible number of iterations to try before giving up",
+ &SteadyState::setMaxIter,
+ &SteadyState::getMaxIter
+ );
+ static ValueFinfo< SteadyState, double> convergenceCriterion(
+ "convergenceCriterion",
+ "Fractional accuracy required to accept convergence",
+ &SteadyState::setConvergenceCriterion,
+ &SteadyState::getConvergenceCriterion
+ );
+ static ReadOnlyValueFinfo< SteadyState, unsigned int > numVarPools(
+ "numVarPools",
+ "Number of variable molecules in reaction system.",
+ &SteadyState::getNumVarPools
+ );
+ static ReadOnlyValueFinfo< SteadyState, unsigned int > rank(
+ "rank",
+ "Number of independent molecules in reaction system",
+ &SteadyState::getRank
+ );
+ static ReadOnlyValueFinfo< SteadyState, unsigned int > stateType(
+ "stateType",
+ "0: stable; 1: unstable; 2: saddle; 3: osc?; 4: one near-zero eigenvalue; 5: other",
+ &SteadyState::getStateType
+ );
+ static ReadOnlyValueFinfo< SteadyState, unsigned int >
+ nNegEigenvalues (
+ "nNegEigenvalues",
+ "Number of negative eigenvalues: indicates type of solution",
+ &SteadyState::getNnegEigenvalues
+ );
+ static ReadOnlyValueFinfo< SteadyState, unsigned int >
+ nPosEigenvalues(
+ "nPosEigenvalues",
+ "Number of positive eigenvalues: indicates type of solution",
+ &SteadyState::getNposEigenvalues
+ );
+ static ReadOnlyValueFinfo< SteadyState, unsigned int > solutionStatus(
+ "solutionStatus",
+ "0: Good; 1: Failed to find steady states; "
+ "2: Failed to find eigenvalues",
+ &SteadyState::getSolutionStatus
+ );
+ static LookupValueFinfo< SteadyState, unsigned int, double > total(
+ "total",
+ "Totals table for conservation laws. The exact mapping of"
+ "this to various sums of molecules is given by the "
+ "conservation matrix, and is currently a bit opaque."
+ "The value of 'total' is set to initial conditions when"
+ "the 'SteadyState::settle' function is called."
+ "Assigning values to the total is a special operation:"
+ "it rescales the concentrations of all the affected"
+ "molecules so that they are at the specified total."
+ "This happens the next time 'settle' is called.",
+ &SteadyState::setTotal,
+ &SteadyState::getTotal
+ );
+ static ReadOnlyLookupValueFinfo<
+ SteadyState, unsigned int, double > eigenvalues(
+ "eigenvalues",
+ "Eigenvalues computed for steady state",
+ &SteadyState::getEigenvalue
+ );
+ ///////////////////////////////////////////////////////
+ // MsgDest definitions
+ ///////////////////////////////////////////////////////
+ static DestFinfo setupMatrix( "setupMatrix",
+ "This function initializes and rebuilds the matrices used "
+ "in the calculation.",
+ new OpFunc0< SteadyState >(&SteadyState::setupMatrix)
+ );
+
+ static DestFinfo settle( "settle",
+ "Finds the nearest steady state to the current initial "
+ "conditions. This function rebuilds the entire calculation "
+ "only if the object has not yet been initialized.",
+ new OpFunc0< SteadyState >( &SteadyState::settleFunc )
+ );
+ static DestFinfo resettle( "resettle",
+ "Finds the nearest steady state to the current initial "
+ "conditions. This function rebuilds the entire calculation ",
+ new OpFunc0< SteadyState >( &SteadyState::resettleFunc )
+ );
+ static DestFinfo showMatrices( "showMatrices",
+ "Utility function to show the matrices derived for the calculations on the reaction system. Shows the Nr, gamma, and total matrices",
+ new OpFunc0< SteadyState >( &SteadyState::showMatrices )
+ );
+ static DestFinfo randomInit( "randomInit",
+ "Generate random initial conditions consistent with the mass"
+ "conservation rules. Typically invoked in order to scan"
+ "states",
+ new EpFunc0< SteadyState >(
+ &SteadyState::randomizeInitialCondition )
+ );
+ ///////////////////////////////////////////////////////
+ // Shared definitions
+ ///////////////////////////////////////////////////////
+
+ static Finfo * steadyStateFinfos[] =
+ {
+ &stoich, // Value
+ &badStoichiometry, // ReadOnlyValue
+ &isInitialized, // ReadOnlyValue
+ &nIter, // ReadOnlyValue
+ &status, // ReadOnlyValue
+ &maxIter, // Value
+ &convergenceCriterion, // ReadOnlyValue
+ &numVarPools, // ReadOnlyValue
+ &rank, // ReadOnlyValue
+ &stateType, // ReadOnlyValue
+ &nNegEigenvalues, // ReadOnlyValue
+ &nPosEigenvalues, // ReadOnlyValue
+ &solutionStatus, // ReadOnlyValue
+ &total, // LookupValue
+ &eigenvalues, // ReadOnlyLookupValue
+ &setupMatrix, // DestFinfo
+ &settle, // DestFinfo
+ &resettle, // DestFinfo
+ &showMatrices, // DestFinfo
+ &randomInit, // DestFinfo
+
+
+ };
+
+ static string doc[] =
+ {
+ "Name", "SteadyState",
+ "Author", "Upinder S. Bhalla, 2009, updated 2014, NCBS",
+ "Description", "SteadyState: works out a steady-state value for "
+ "a reaction system. "
+ "This class uses the GSL multidimensional root finder algorithms "
+ "to find the fixed points closest to the "
+ "current molecular concentrations. "
+ "When it finds the fixed points, it figures out eigenvalues of "
+ "the solution, as a way to help classify the fixed points. "
+ "Note that the method finds unstable as well as stable fixed "
+ "points.\n "
+ "The SteadyState class also provides a utility function "
+ "*randomInit()* to "
+ "randomly initialize the concentrations, within the constraints "
+ "of stoichiometry. This is useful if you are trying to find "
+ "the major fixed points of the system. Note that this is "
+ "probabilistic. If a fixed point is in a very narrow range of "
+ "state space the probability of finding it is small and you "
+ "will have to run many iterations with different initial "
+ "conditions to find it.\n "
+ "The numerical calculations used by the SteadyState solver are "
+ "prone to failing on individual calculations. All is not lost, "
+ "because the system reports the solutionStatus. "
+ "It is recommended that you test this field after every "
+ "calculation, so you can simply ignore "
+ "cases where it failed and try again with different starting "
+ "conditions.\n "
+ "Another rule of thumb is that the SteadyState object is more "
+ "likely to succeed in finding solutions from a new starting point "
+ "if you numerically integrate the chemical system for a short "
+ "time (typically under 1 second) before asking it to find the "
+ "fixed point. "
+ };
+
+ static Dinfo< SteadyState > dinfo;
+ static Cinfo steadyStateCinfo(
+ "SteadyState",
+ Neutral::initCinfo(),
+ steadyStateFinfos,
+ sizeof( steadyStateFinfos )/sizeof(Finfo *),
+ &dinfo,
+ doc, sizeof( doc ) / sizeof( string )
+ );
+
+ return &steadyStateCinfo;
}
static const Cinfo* steadyStateCinfo = SteadyState::initCinfo();
@@ -316,42 +318,42 @@ static const Cinfo* steadyStateCinfo = SteadyState::initCinfo();
///////////////////////////////////////////////////
SteadyState::SteadyState()
- :
- nIter_( 0 ),
- maxIter_( 100 ),
- badStoichiometry_( 0 ),
- status_( "OK" ),
- isInitialized_( 0 ),
- isSetup_( 0 ),
- convergenceCriterion_( 1e-7 ),
+ :
+ nIter_( 0 ),
+ maxIter_( 100 ),
+ badStoichiometry_( 0 ),
+ status_( "OK" ),
+ isInitialized_( 0 ),
+ isSetup_( 0 ),
+ convergenceCriterion_( 1e-7 ),
#ifdef USE_GSL
- LU_( 0 ),
- Nr_( 0 ),
- gamma_( 0 ),
+ LU_( 0 ),
+ Nr_( 0 ),
+ gamma_( 0 ),
#endif
- stoich_(),
- numVarPools_( 0 ),
- nReacs_( 0 ),
- rank_( 0 ),
- reassignTotal_( 0 ),
- nNegEigenvalues_( 0 ),
- nPosEigenvalues_( 0 ),
- stateType_( 0 ),
- solutionStatus_( 0 ),
- numFailed_( 0 )
+ stoich_(),
+ numVarPools_( 0 ),
+ nReacs_( 0 ),
+ rank_( 0 ),
+ reassignTotal_( 0 ),
+ nNegEigenvalues_( 0 ),
+ nPosEigenvalues_( 0 ),
+ stateType_( 0 ),
+ solutionStatus_( 0 ),
+ numFailed_( 0 )
{
- ;
+ ;
}
SteadyState::~SteadyState()
{
#ifdef USE_GSL
- if ( LU_ != 0 )
- gsl_matrix_free( LU_ );
- if ( Nr_ != 0 )
- gsl_matrix_free( Nr_ );
- if ( gamma_ != 0 )
- gsl_matrix_free( gamma_ );
+ if ( LU_ != 0 )
+ gsl_matrix_free( LU_ );
+ if ( Nr_ != 0 )
+ gsl_matrix_free( Nr_ );
+ if ( gamma_ != 0 )
+ gsl_matrix_free( gamma_ );
#endif
}
@@ -359,118 +361,136 @@ SteadyState::~SteadyState()
// Field function definitions
///////////////////////////////////////////////////
-Id SteadyState::getStoich() const {
- return stoich_;
+Id SteadyState::getStoich() const
+{
+ return stoich_;
}
-void SteadyState::setStoich( Id value ) {
- if ( !value.element()->cinfo()->isA( "Stoich" ) ) {
- cout << "Error: SteadyState::setStoich: Must be of Stoich class\n";
- return;
- }
-
- stoich_ = value;
- Stoich* stoichPtr = reinterpret_cast< Stoich* >( value.eref().data());
- numVarPools_ = Field< unsigned int >::get( stoich_, "numVarPools" );
- nReacs_ = Field< unsigned int >::get( stoich_, "numRates" );
- setupSSmatrix();
- double vol = LookupField< unsigned int, double >::get(
- stoichPtr->getCompartment(), "oneVoxelVolume", 0 );
- pool_.setVolume( vol );
- pool_.setStoich( stoichPtr, 0 );
- pool_.updateAllRateTerms( stoichPtr->getRateTerms(),
- stoichPtr->getNumCoreRates() );
- isInitialized_ = 1;
+void SteadyState::setStoich( Id value )
+{
+ if ( !value.element()->cinfo()->isA( "Stoich" ) )
+ {
+ cout << "Error: SteadyState::setStoich: Must be of Stoich class\n";
+ return;
+ }
+
+ stoich_ = value;
+ Stoich* stoichPtr = reinterpret_cast< Stoich* >( value.eref().data());
+ numVarPools_ = Field< unsigned int >::get( stoich_, "numVarPools" );
+ nReacs_ = Field< unsigned int >::get( stoich_, "numRates" );
+ setupSSmatrix();
+ double vol = LookupField< unsigned int, double >::get(
+ stoichPtr->getCompartment(), "oneVoxelVolume", 0 );
+ pool_.setVolume( vol );
+ pool_.setStoich( stoichPtr, 0 );
+ pool_.updateAllRateTerms( stoichPtr->getRateTerms(),
+ stoichPtr->getNumCoreRates() );
+ isInitialized_ = 1;
}
-bool SteadyState::badStoichiometry() const {
- return badStoichiometry_;
+bool SteadyState::badStoichiometry() const
+{
+ return badStoichiometry_;
}
-bool SteadyState::isInitialized() const {
- return isInitialized_;
+bool SteadyState::isInitialized() const
+{
+ return isInitialized_;
}
-unsigned int SteadyState::getNiter() const {
- return nIter_;
+unsigned int SteadyState::getNiter() const
+{
+ return nIter_;
}
-string SteadyState::getStatus() const {
- return status_;
+string SteadyState::getStatus() const
+{
+ return status_;
}
-unsigned int SteadyState::getMaxIter() const {
- return maxIter_;
+unsigned int SteadyState::getMaxIter() const
+{
+ return maxIter_;
}
-void SteadyState::setMaxIter( unsigned int value ) {
- maxIter_ = value;
+void SteadyState::setMaxIter( unsigned int value )
+{
+ maxIter_ = value;
}
-unsigned int SteadyState::getRank() const {
- return rank_;
+unsigned int SteadyState::getRank() const
+{
+ return rank_;
}
-unsigned int SteadyState::getNumVarPools() const {
- return numVarPools_;
+unsigned int SteadyState::getNumVarPools() const
+{
+ return numVarPools_;
}
-unsigned int SteadyState::getStateType() const {
- return stateType_;
+unsigned int SteadyState::getStateType() const
+{
+ return stateType_;
}
-unsigned int SteadyState::getNnegEigenvalues() const {
- return nNegEigenvalues_;
+unsigned int SteadyState::getNnegEigenvalues() const
+{
+ return nNegEigenvalues_;
}
-unsigned int SteadyState::getNposEigenvalues() const {
- return nPosEigenvalues_;
+unsigned int SteadyState::getNposEigenvalues() const
+{
+ return nPosEigenvalues_;
}
-unsigned int SteadyState::getSolutionStatus() const {
- return solutionStatus_;
+unsigned int SteadyState::getSolutionStatus() const
+{
+ return solutionStatus_;
}
-void SteadyState::setConvergenceCriterion( double value ) {
- if ( value > 1e-10 )
- convergenceCriterion_ = value;
- else
- cout << "Warning: Convergence criterion " << value <<
- " too small. Old value " <<
- convergenceCriterion_ << " retained\n";
+void SteadyState::setConvergenceCriterion( double value )
+{
+ if ( value > 1e-10 )
+ convergenceCriterion_ = value;
+ else
+ cout << "Warning: Convergence criterion " << value <<
+ " too small. Old value " <<
+ convergenceCriterion_ << " retained\n";
}
-double SteadyState::getConvergenceCriterion() const {
- return convergenceCriterion_;
+double SteadyState::getConvergenceCriterion() const
+{
+ return convergenceCriterion_;
}
double SteadyState::getTotal( const unsigned int i ) const
{
- if ( i < total_.size() )
- return total_[i];
- cout << "Warning: SteadyState::getTotal: index " << i <<
- " out of range " << total_.size() << endl;
- return 0.0;
+ if ( i < total_.size() )
+ return total_[i];
+ cout << "Warning: SteadyState::getTotal: index " << i <<
+ " out of range " << total_.size() << endl;
+ return 0.0;
}
void SteadyState::setTotal( const unsigned int i, double val )
{
- if ( i < total_.size() ) {
- total_[i] = val;
- reassignTotal_ = 1;
- return;
- }
- cout << "Warning: SteadyState::setTotal: index " << i <<
- " out of range " << total_.size() << endl;
+ if ( i < total_.size() )
+ {
+ total_[i] = val;
+ reassignTotal_ = 1;
+ return;
+ }
+ cout << "Warning: SteadyState::setTotal: index " << i <<
+ " out of range " << total_.size() << endl;
}
double SteadyState::getEigenvalue( const unsigned int i ) const
{
- if ( i < eigenvalues_.size() )
- return eigenvalues_[i];
- cout << "Warning: SteadyState::getEigenvalue: index " << i <<
- " out of range " << eigenvalues_.size() << endl;
- return 0.0;
+ if ( i < eigenvalues_.size() )
+ return eigenvalues_[i];
+ cout << "Warning: SteadyState::getEigenvalue: index " << i <<
+ " out of range " << eigenvalues_.size() << endl;
+ return 0.0;
}
///////////////////////////////////////////////////
@@ -480,16 +500,16 @@ double SteadyState::getEigenvalue( const unsigned int i ) const
// Static func
void SteadyState::setupMatrix()
{
- setupSSmatrix();
+ setupSSmatrix();
}
void SteadyState::settleFunc()
{
- settle( 0 );
+ settle( 0 );
}
void SteadyState::resettleFunc()
{
- settle( 1 );
+ settle( 1 );
}
// Dummy function
@@ -506,8 +526,10 @@ void print_gsl_mat( gsl_matrix* m, const char* name )
{
size_t i, j;
printf( "%s[%lu, %lu] = \n", name, m->size1, m->size2 );
- for (i = 0; i < m->size1; i++) {
- for (j = 0; j < m->size2; j++) {
+ for (i = 0; i < m->size1; i++)
+ {
+ for (j = 0; j < m->size2; j++)
+ {
double x = gsl_matrix_get (m, i, j );
if ( fabs( x ) < 1e-9 ) x = 0;
printf( "%6g", x );
@@ -520,129 +542,140 @@ void print_gsl_mat( gsl_matrix* m, const char* name )
void SteadyState::showMatrices()
{
- if ( !isInitialized_ ) {
- cout << "SteadyState::showMatrices: Sorry, the system is not yet initialized.\n";
- return;
- }
- int numConsv = numVarPools_ - rank_;
- cout << "Totals: ";
- for ( int i = 0; i < numConsv; ++i )
- cout << total_[i] << " ";
- cout << endl;
+ if ( !isInitialized_ )
+ {
+ cout << "SteadyState::showMatrices: Sorry, the system is not yet initialized.\n";
+ return;
+ }
+ int numConsv = numVarPools_ - rank_;
+ cout << "Totals: ";
+ for ( int i = 0; i < numConsv; ++i )
+ cout << total_[i] << " ";
+ cout << endl;
#ifdef USE_GSL
- print_gsl_mat( gamma_, "gamma" );
- print_gsl_mat( Nr_, "Nr" );
- print_gsl_mat( LU_, "LU" );
+ print_gsl_mat( gamma_, "gamma" );
+ print_gsl_mat( Nr_, "Nr" );
+ print_gsl_mat( LU_, "LU" );
#endif
}
void SteadyState::setupSSmatrix()
{
#ifdef USE_GSL
- if ( numVarPools_ == 0 || nReacs_ == 0 )
- return;
-
- int nTot = numVarPools_ + nReacs_;
- gsl_matrix* N = gsl_matrix_calloc (numVarPools_, nReacs_);
- if ( LU_ ) { // Clear out old one.
- gsl_matrix_free( LU_ );
- }
- LU_ = gsl_matrix_calloc (numVarPools_, nTot);
- vector< int > entry = Field< vector< int > >::get(
- stoich_, "matrixEntry" );
- vector< unsigned int > colIndex = Field< vector< unsigned int > >::get(
- stoich_, "columnIndex" );
- vector< unsigned int > rowStart = Field< vector< unsigned int > >::get(
- stoich_, "rowStart" );
-
- // cout << endl << endl;
- for ( unsigned int i = 0; i < numVarPools_; ++i ) {
- gsl_matrix_set (LU_, i, i + nReacs_, 1 );
- unsigned int k = rowStart[i];
- // cout << endl << i << ": ";
- for ( unsigned int j = 0; j < nReacs_; ++j ) {
- double x = 0;
- if ( j == colIndex[k] && k < rowStart[i+1] ) {
- x = entry[k++];
- }
- // cout << " " << x;
- gsl_matrix_set (N, i, j, x);
- gsl_matrix_set (LU_, i, j, x );
- }
- }
- cout << endl << endl;
-
- rank_ = myGaussianDecomp( LU_ );
-
- unsigned int nConsv = numVarPools_ - rank_;
- if ( nConsv == 0 ) {
- cout << "SteadyState::setupSSmatrix(): Number of conserved species == 0. Aborting\n";
- return;
- }
-
- if ( Nr_ ) { // Clear out old one.
- gsl_matrix_free( Nr_ );
- }
- Nr_ = gsl_matrix_calloc ( rank_, nReacs_ );
- // Fill up Nr.
- for ( unsigned int i = 0; i < rank_; i++)
- for ( unsigned int j = i; j < nReacs_; j++)
- gsl_matrix_set (Nr_, i, j, gsl_matrix_get( LU_, i, j ) );
-
- if ( gamma_ ) { // Clear out old one.
- gsl_matrix_free( gamma_ );
- }
- gamma_ = gsl_matrix_calloc (nConsv, numVarPools_ );
-
- // Fill up gamma
- for ( unsigned int i = rank_; i < numVarPools_; ++i )
- for ( unsigned int j = 0; j < numVarPools_; ++j )
- gsl_matrix_set( gamma_, i - rank_, j,
- gsl_matrix_get( LU_, i, j + nReacs_ ) );
-
- // Fill up boundary condition values
- total_.resize( nConsv );
- total_.assign( nConsv, 0.0 );
-
- /*
- cout << "S = (";
- for ( unsigned int j = 0; j < numVarPools_; ++j )
- cout << s_->S()[ j ] << ", ";
- cout << "), Sinit = ( ";
- for ( unsigned int j = 0; j < numVarPools_; ++j )
- cout << s_->Sinit()[ j ] << ", ";
- cout << ")\n";
- */
- Id ksolve = Field< Id >::get( stoich_, "ksolve" );
- vector< double > nVec =
- LookupField< unsigned int, vector< double > >::get(
- ksolve,"nVec", 0 );
-
- if ( nVec.size() >= numVarPools_ ) {
- for ( unsigned int i = 0; i < nConsv; ++i )
- for ( unsigned int j = 0; j < numVarPools_; ++j )
- total_[i] += gsl_matrix_get( gamma_, i, j ) * nVec[ j ];
- isSetup_ = 1;
- } else {
- cout << "Error: SteadyState::setupSSmatrix(): unable to get"
- "pool numbers from ksolve.\n";
- isSetup_ = 0;
- }
-
- gsl_matrix_free( N );
+ if ( numVarPools_ == 0 || nReacs_ == 0 )
+ return;
+
+ int nTot = numVarPools_ + nReacs_;
+ gsl_matrix* N = gsl_matrix_calloc (numVarPools_, nReacs_);
+ if ( LU_ ) // Clear out old one.
+ {
+ gsl_matrix_free( LU_ );
+ }
+ LU_ = gsl_matrix_calloc (numVarPools_, nTot);
+ vector< int > entry = Field< vector< int > >::get(
+ stoich_, "matrixEntry" );
+ vector< unsigned int > colIndex = Field< vector< unsigned int > >::get(
+ stoich_, "columnIndex" );
+ vector< unsigned int > rowStart = Field< vector< unsigned int > >::get(
+ stoich_, "rowStart" );
+
+ // cout << endl << endl;
+ for ( unsigned int i = 0; i < numVarPools_; ++i )
+ {
+ gsl_matrix_set (LU_, i, i + nReacs_, 1 );
+ unsigned int k = rowStart[i];
+ // cout << endl << i << ": ";
+ for ( unsigned int j = 0; j < nReacs_; ++j )
+ {
+ double x = 0;
+ if ( j == colIndex[k] && k < rowStart[i+1] )
+ {
+ x = entry[k++];
+ }
+ // cout << " " << x;
+ gsl_matrix_set (N, i, j, x);
+ gsl_matrix_set (LU_, i, j, x );
+ }
+ }
+ cout << endl << endl;
+
+ rank_ = myGaussianDecomp( LU_ );
+
+ unsigned int nConsv = numVarPools_ - rank_;
+ if ( nConsv == 0 )
+ {
+ cout << "SteadyState::setupSSmatrix(): Number of conserved species == 0. Aborting\n";
+ return;
+ }
+
+ if ( Nr_ ) // Clear out old one.
+ {
+ gsl_matrix_free( Nr_ );
+ }
+ Nr_ = gsl_matrix_calloc ( rank_, nReacs_ );
+ // Fill up Nr.
+ for ( unsigned int i = 0; i < rank_; i++)
+ for ( unsigned int j = i; j < nReacs_; j++)
+ gsl_matrix_set (Nr_, i, j, gsl_matrix_get( LU_, i, j ) );
+
+ if ( gamma_ ) // Clear out old one.
+ {
+ gsl_matrix_free( gamma_ );
+ }
+ gamma_ = gsl_matrix_calloc (nConsv, numVarPools_ );
+
+ // Fill up gamma
+ for ( unsigned int i = rank_; i < numVarPools_; ++i )
+ for ( unsigned int j = 0; j < numVarPools_; ++j )
+ gsl_matrix_set( gamma_, i - rank_, j,
+ gsl_matrix_get( LU_, i, j + nReacs_ ) );
+
+ // Fill up boundary condition values
+ total_.resize( nConsv );
+ total_.assign( nConsv, 0.0 );
+
+ /*
+ cout << "S = (";
+ for ( unsigned int j = 0; j < numVarPools_; ++j )
+ cout << s_->S()[ j ] << ", ";
+ cout << "), Sinit = ( ";
+ for ( unsigned int j = 0; j < numVarPools_; ++j )
+ cout << s_->Sinit()[ j ] << ", ";
+ cout << ")\n";
+ */
+ Id ksolve = Field< Id >::get( stoich_, "ksolve" );
+ vector< double > nVec =
+ LookupField< unsigned int, vector< double > >::get(
+ ksolve,"nVec", 0 );
+
+ if ( nVec.size() >= numVarPools_ )
+ {
+ for ( unsigned int i = 0; i < nConsv; ++i )
+ for ( unsigned int j = 0; j < numVarPools_; ++j )
+ total_[i] += gsl_matrix_get( gamma_, i, j ) * nVec[ j ];
+ isSetup_ = 1;
+ }
+ else
+ {
+ cout << "Error: SteadyState::setupSSmatrix(): unable to get"
+ "pool numbers from ksolve.\n";
+ isSetup_ = 0;
+ }
+
+ gsl_matrix_free( N );
#endif
}
static double op( double x )
{
- return x * x;
+ return x * x;
}
static double invop( double x )
{
- if ( x > 0.0 )
- return sqrt( x );
- return 0.0;
+ if ( x > 0.0 )
+ return sqrt( x );
+ return 0.0;
}
@@ -654,140 +687,153 @@ static double invop( double x )
*/
#ifdef USE_GSL
int iterate( const gsl_multiroot_fsolver_type* st, struct reac_info *ri,
- int maxIter )
+ int maxIter )
{
- int status = 0;
- gsl_vector* x = gsl_vector_calloc( ri->num_mols );
- gsl_multiroot_fsolver *solver =
- gsl_multiroot_fsolver_alloc( st, ri->num_mols );
- gsl_multiroot_function func = {&ss_func, ri->num_mols, ri};
-
- // This gives the starting point for finding the solution
- for ( unsigned int i = 0; i < ri->num_mols; ++i )
- gsl_vector_set( x, i, invop( ri->nVec[i] ) );
-
- gsl_multiroot_fsolver_set( solver, &func, x );
-
- ri->nIter = 0;
- do {
- ri->nIter++;
- status = gsl_multiroot_fsolver_iterate( solver );
- if (status ) break;
- status = gsl_multiroot_test_residual(
- solver->f, ri->convergenceCriterion);
- } while (status == GSL_CONTINUE && ri->nIter < maxIter );
-
- gsl_multiroot_fsolver_free( solver );
- gsl_vector_free( x );
- return status;
+ int status = 0;
+ gsl_vector* x = gsl_vector_calloc( ri->num_mols );
+ gsl_multiroot_fsolver *solver =
+ gsl_multiroot_fsolver_alloc( st, ri->num_mols );
+ gsl_multiroot_function func = {&ss_func, ri->num_mols, ri};
+
+ // This gives the starting point for finding the solution
+ for ( unsigned int i = 0; i < ri->num_mols; ++i )
+ gsl_vector_set( x, i, invop( ri->nVec[i] ) );
+
+ gsl_multiroot_fsolver_set( solver, &func, x );
+
+ ri->nIter = 0;
+ do
+ {
+ ri->nIter++;
+ status = gsl_multiroot_fsolver_iterate( solver );
+ if (status ) break;
+ status = gsl_multiroot_test_residual(
+ solver->f, ri->convergenceCriterion);
+ }
+ while (status == GSL_CONTINUE && ri->nIter < maxIter );
+
+ gsl_multiroot_fsolver_free( solver );
+ gsl_vector_free( x );
+ return status;
}
#endif
void SteadyState::classifyState( const double* T )
{
#ifdef USE_GSL
- // unsigned int nConsv = numVarPools_ - rank_;
- gsl_matrix* J = gsl_matrix_calloc ( numVarPools_, numVarPools_ );
- // double* yprime = new double[ numVarPools_ ];
- // vector< double > yprime( numVarPools_, 0.0 );
- // Generate an approximation to the Jacobean by generating small
- // increments to each of the molecules in the steady state, one
- // at a time, and putting the resultant rate vector into a column
- // of the J matrix.
- // This needs a bit of heuristic to decide what is a 'small' increment.
- // Use the CoInits for this. Stoichiometry shouldn't matter too much.
- // I used the totals from consv rules earlier, but that can have
- // negative values.
- double tot = 0.0;
- Stoich* s = reinterpret_cast< Stoich* >( stoich_.eref().data() );
- vector< double > nVec = LookupField< unsigned int, vector< double > >::get(
- s->getKsolve(), "nVec", 0 );
- for ( unsigned int i = 0; i < numVarPools_; ++i ) {
- tot += nVec[i];
- }
- tot *= DELTA;
-
- vector< double > yprime( nVec.size(), 0.0 );
- // Fill up Jacobian
- for ( unsigned int i = 0; i < numVarPools_; ++i ) {
- double orig = nVec[i];
- if ( isNaN( orig ) ) {
- cout << "Warning: SteadyState::classifyState: orig=nan\n";
- solutionStatus_ = 2; // Steady state OK, eig failed
- gsl_matrix_free ( J );
- return;
- }
- if ( isNaN( tot ) ) {
- cout << "Warning: SteadyState::classifyState: tot=nan\n";
- solutionStatus_ = 2; // Steady state OK, eig failed
- gsl_matrix_free ( J );
- return;
- }
- nVec[i] = orig + tot;
-
- pool_.updateRates( &nVec[0], &yprime[0] );
- nVec[i] = orig;
-
- // Assign the rates for each mol.
- for ( unsigned int j = 0; j < numVarPools_; ++j ) {
- gsl_matrix_set( J, i, j, yprime[j] );
- }
- }
-
- // Jacobian is now ready. Find eigenvalues.
- gsl_vector_complex* vec = gsl_vector_complex_alloc( numVarPools_ );
- gsl_eigen_nonsymm_workspace* workspace =
- gsl_eigen_nonsymm_alloc( numVarPools_ );
- int status = gsl_eigen_nonsymm( J, vec, workspace );
- eigenvalues_.clear();
- eigenvalues_.resize( numVarPools_, 0.0 );
- if ( status != GSL_SUCCESS ) {
- cout << "Warning: SteadyState::classifyState failed to find eigenvalues. Status = " <<
- status << endl;
- solutionStatus_ = 2; // Steady state OK, eig classification failed
- } else { // Eigenvalues are ready. Classify state.
- nNegEigenvalues_ = 0;
- nPosEigenvalues_ = 0;
- for ( unsigned int i = 0; i < numVarPools_; ++i ) {
- gsl_complex z = gsl_vector_complex_get( vec, i );
- double r = GSL_REAL( z );
- nNegEigenvalues_ += ( r < -EPSILON );
- nPosEigenvalues_ += ( r > EPSILON );
- eigenvalues_[i] = r;
- // We have a problem here because numVarPools_ usually > rank
- // This means we have several zero eigenvalues.
- }
-
- if ( nNegEigenvalues_ == rank_ )
- stateType_ = 0; // Stable
- else if ( nPosEigenvalues_ == rank_ ) // Never see it.
- stateType_ = 1; // Unstable
- else if (nPosEigenvalues_ == 1)
- stateType_ = 2; // Saddle
- else if ( nPosEigenvalues_ >= 2 )
- stateType_ = 3; // putative oscillatory
- else if ( nNegEigenvalues_ == ( rank_ - 1) && nPosEigenvalues_ == 0 )
- stateType_ = 4; // one zero or unclassified eigenvalue. Messy.
- else
- stateType_ = 5; // Other
- }
-
- gsl_vector_complex_free( vec );
- gsl_matrix_free ( J );
- gsl_eigen_nonsymm_free( workspace );
+ // unsigned int nConsv = numVarPools_ - rank_;
+ gsl_matrix* J = gsl_matrix_calloc ( numVarPools_, numVarPools_ );
+ // double* yprime = new double[ numVarPools_ ];
+ // vector< double > yprime( numVarPools_, 0.0 );
+ // Generate an approximation to the Jacobean by generating small
+ // increments to each of the molecules in the steady state, one
+ // at a time, and putting the resultant rate vector into a column
+ // of the J matrix.
+ // This needs a bit of heuristic to decide what is a 'small' increment.
+ // Use the CoInits for this. Stoichiometry shouldn't matter too much.
+ // I used the totals from consv rules earlier, but that can have
+ // negative values.
+ double tot = 0.0;
+ Stoich* s = reinterpret_cast< Stoich* >( stoich_.eref().data() );
+ vector< double > nVec = LookupField< unsigned int, vector< double > >::get(
+ s->getKsolve(), "nVec", 0 );
+ for ( unsigned int i = 0; i < numVarPools_; ++i )
+ {
+ tot += nVec[i];
+ }
+ tot *= DELTA;
+
+ vector< double > yprime( nVec.size(), 0.0 );
+ // Fill up Jacobian
+ for ( unsigned int i = 0; i < numVarPools_; ++i )
+ {
+ double orig = nVec[i];
+ if ( isNaN( orig ) )
+ {
+ cout << "Warning: SteadyState::classifyState: orig=nan\n";
+ solutionStatus_ = 2; // Steady state OK, eig failed
+ gsl_matrix_free ( J );
+ return;
+ }
+ if ( isNaN( tot ) )
+ {
+ cout << "Warning: SteadyState::classifyState: tot=nan\n";
+ solutionStatus_ = 2; // Steady state OK, eig failed
+ gsl_matrix_free ( J );
+ return;
+ }
+ nVec[i] = orig + tot;
+
+ pool_.updateRates( &nVec[0], &yprime[0] );
+ nVec[i] = orig;
+
+ // Assign the rates for each mol.
+ for ( unsigned int j = 0; j < numVarPools_; ++j )
+ {
+ gsl_matrix_set( J, i, j, yprime[j] );
+ }
+ }
+
+ // Jacobian is now ready. Find eigenvalues.
+ gsl_vector_complex* vec = gsl_vector_complex_alloc( numVarPools_ );
+ gsl_eigen_nonsymm_workspace* workspace =
+ gsl_eigen_nonsymm_alloc( numVarPools_ );
+ int status = gsl_eigen_nonsymm( J, vec, workspace );
+ eigenvalues_.clear();
+ eigenvalues_.resize( numVarPools_, 0.0 );
+ if ( status != GSL_SUCCESS )
+ {
+ cout << "Warning: SteadyState::classifyState failed to find eigenvalues. Status = " <<
+ status << endl;
+ solutionStatus_ = 2; // Steady state OK, eig classification failed
+ }
+ else // Eigenvalues are ready. Classify state.
+ {
+ nNegEigenvalues_ = 0;
+ nPosEigenvalues_ = 0;
+ for ( unsigned int i = 0; i < numVarPools_; ++i )
+ {
+ gsl_complex z = gsl_vector_complex_get( vec, i );
+ double r = GSL_REAL( z );
+ nNegEigenvalues_ += ( r < -EPSILON );
+ nPosEigenvalues_ += ( r > EPSILON );
+ eigenvalues_[i] = r;
+ // We have a problem here because numVarPools_ usually > rank
+ // This means we have several zero eigenvalues.
+ }
+
+ if ( nNegEigenvalues_ == rank_ )
+ stateType_ = 0; // Stable
+ else if ( nPosEigenvalues_ == rank_ ) // Never see it.
+ stateType_ = 1; // Unstable
+ else if (nPosEigenvalues_ == 1)
+ stateType_ = 2; // Saddle
+ else if ( nPosEigenvalues_ >= 2 )
+ stateType_ = 3; // putative oscillatory
+ else if ( nNegEigenvalues_ == ( rank_ - 1) && nPosEigenvalues_ == 0 )
+ stateType_ = 4; // one zero or unclassified eigenvalue. Messy.
+ else
+ stateType_ = 5; // Other
+ }
+
+ gsl_vector_complex_free( vec );
+ gsl_matrix_free ( J );
+ gsl_eigen_nonsymm_free( workspace );
#endif
}
static bool isSolutionPositive( const vector< double >& x )
{
- for ( vector< double >::const_iterator
- i = x.begin(); i != x.end(); ++i ) {
- if ( *i < 0.0 ) {
- cout << "Warning: SteadyState iteration gave negative concs\n";
- return false;
- }
- }
- return true;
+ for ( vector< double >::const_iterator
+ i = x.begin(); i != x.end(); ++i )
+ {
+ if ( *i < 0.0 )
+ {
+ cout << "Warning: SteadyState iteration gave negative concs\n";
+ return false;
+ }
+ }
+ return true;
}
/**
@@ -797,76 +843,84 @@ static bool isSolutionPositive( const vector< double >& x )
void SteadyState::settle( bool forceSetup )
{
#ifdef USE_GSL
- gsl_set_error_handler_off();
-
- if ( !isInitialized_ ) {
- cout << "Error: SteadyState object has not been initialized. No calculations done\n";
- return;
- }
- if ( forceSetup || isSetup_ == 0 ) {
- setupSSmatrix();
- }
-
- // Setting up matrices and vectors for the calculation.
- unsigned int nConsv = numVarPools_ - rank_;
- double * T = (double *) calloc( nConsv, sizeof( double ) );
-
- unsigned int i, j;
-
-
- Id ksolve = Field< Id >::get( stoich_, "ksolve" );
- struct reac_info ri;
- ri.rank = rank_;
- ri.num_reacs = nReacs_;
- ri.num_mols = numVarPools_;
- ri.T = T;
- ri.Nr = Nr_;
- ri.gamma = gamma_;
- ri.pool = &pool_;
- ri.nVec =
- LookupField< unsigned int, vector< double > >::get(
- ksolve,"nVec", 0 );
- ri.convergenceCriterion = convergenceCriterion_;
-
- // Fill up boundary condition values
- if ( reassignTotal_ ) { // The user has defined new conservation values.
- for ( i = 0; i < nConsv; ++i )
- T[i] = total_[i];
- reassignTotal_ = 0;
- } else {
- for ( i = 0; i < nConsv; ++i )
- for ( j = 0; j < numVarPools_; ++j )
- T[i] += gsl_matrix_get( gamma_, i, j ) * ri.nVec[ j ];
- total_.assign( T, T + nConsv );
- }
-
- vector< double > repair( numVarPools_, 0.0 );
- for ( unsigned int j = 0; j < numVarPools_; ++j )
- repair[j] = ri.nVec[j];
-
- int status = iterate( gsl_multiroot_fsolver_hybrids, &ri, maxIter_ );
- if ( status ) // It failed. Fall back with the Newton method
- status = iterate( gsl_multiroot_fsolver_dnewton, &ri, maxIter_ );
- status_ = string( gsl_strerror( status ) );
- nIter_ = ri.nIter;
- if ( status == GSL_SUCCESS && isSolutionPositive( ri.nVec ) ) {
- solutionStatus_ = 0; // Good solution
- LookupField< unsigned int, vector< double > >::set(
- ksolve,"nVec", 0, ri.nVec );
- classifyState( T );
- } else {
- cout << "Warning: SteadyState iteration failed, status = " <<
- status_ << ", nIter = " << nIter_ << endl;
- // Repair the mess
- for ( unsigned int j = 0; j < numVarPools_; ++j )
- ri.nVec[j] = repair[j];
- solutionStatus_ = 1; // Steady state failed.
- LookupField< unsigned int, vector< double > >::set(
- ksolve,"nVec", 0, ri.nVec );
- }
-
- // Clean up.
- free( T );
+ gsl_set_error_handler_off();
+
+ if ( !isInitialized_ )
+ {
+ cout << "Error: SteadyState object has not been initialized. No calculations done\n";
+ return;
+ }
+ if ( forceSetup || isSetup_ == 0 )
+ {
+ setupSSmatrix();
+ }
+
+ // Setting up matrices and vectors for the calculation.
+ unsigned int nConsv = numVarPools_ - rank_;
+ double * T = (double *) calloc( nConsv, sizeof( double ) );
+
+ unsigned int i, j;
+
+
+ Id ksolve = Field< Id >::get( stoich_, "ksolve" );
+ struct reac_info ri;
+ ri.rank = rank_;
+ ri.num_reacs = nReacs_;
+ ri.num_mols = numVarPools_;
+ ri.T = T;
+ ri.Nr = Nr_;
+ ri.gamma = gamma_;
+ ri.pool = &pool_;
+ ri.nVec =
+ LookupField< unsigned int, vector< double > >::get(
+ ksolve,"nVec", 0 );
+ ri.convergenceCriterion = convergenceCriterion_;
+
+ // Fill up boundary condition values
+ if ( reassignTotal_ ) // The user has defined new conservation values.
+ {
+ for ( i = 0; i < nConsv; ++i )
+ T[i] = total_[i];
+ reassignTotal_ = 0;
+ }
+ else
+ {
+ for ( i = 0; i < nConsv; ++i )
+ for ( j = 0; j < numVarPools_; ++j )
+ T[i] += gsl_matrix_get( gamma_, i, j ) * ri.nVec[ j ];
+ total_.assign( T, T + nConsv );
+ }
+
+ vector< double > repair( numVarPools_, 0.0 );
+ for ( unsigned int j = 0; j < numVarPools_; ++j )
+ repair[j] = ri.nVec[j];
+
+ int status = iterate( gsl_multiroot_fsolver_hybrids, &ri, maxIter_ );
+ if ( status ) // It failed. Fall back with the Newton method
+ status = iterate( gsl_multiroot_fsolver_dnewton, &ri, maxIter_ );
+ status_ = string( gsl_strerror( status ) );
+ nIter_ = ri.nIter;
+ if ( status == GSL_SUCCESS && isSolutionPositive( ri.nVec ) )
+ {
+ solutionStatus_ = 0; // Good solution
+ LookupField< unsigned int, vector< double > >::set(
+ ksolve,"nVec", 0, ri.nVec );
+ classifyState( T );
+ }
+ else
+ {
+ cout << "Warning: SteadyState iteration failed, status = " <<
+ status_ << ", nIter = " << nIter_ << endl;
+ // Repair the mess
+ for ( unsigned int j = 0; j < numVarPools_; ++j )
+ ri.nVec[j] = repair[j];
+ solutionStatus_ = 1; // Steady state failed.
+ LookupField< unsigned int, vector< double > >::set(
+ ksolve,"nVec", 0, ri.nVec );
+ }
+
+ // Clean up.
+ free( T );
#endif
}
@@ -874,42 +928,48 @@ void SteadyState::settle( bool forceSetup )
#ifdef USE_GSL
int ss_func( const gsl_vector* x, void* params, gsl_vector* f )
{
- struct reac_info* ri = (struct reac_info *)params;
- // Stoich* s = reinterpret_cast< Stoich* >( ri->stoich.eref().data() );
- int num_consv = ri->num_mols - ri->rank;
-
- for ( unsigned int i = 0; i < ri->num_mols; ++i ) {
- double temp = op( gsl_vector_get( x, i ) );
- if ( isNaN( temp ) || isInfinity( temp ) ) {
- return GSL_ERANGE;
- } else {
- ri->nVec[i] = temp;
- }
- }
- vector< double > vels;
- ri->pool->updateReacVelocities( &ri->nVec[0], vels );
- assert( vels.size() == static_cast< unsigned int >( ri->num_reacs ) );
-
- // y = Nr . v
- // Note that Nr is row-echelon: diagonal and above.
- for ( int i = 0; i < ri->rank; ++i ) {
- double temp = 0;
- for ( int j = i; j < ri->num_reacs; ++j )
- temp += gsl_matrix_get( ri->Nr, i, j ) * vels[j];
- gsl_vector_set( f, i, temp );
- }
-
- // dT = gamma.S - T
- for ( int i = 0; i < num_consv; ++i ) {
- double dT = - ri->T[i];
- for ( unsigned int j = 0; j < ri->num_mols; ++j )
- dT += gsl_matrix_get( ri->gamma, i, j) *
- op( gsl_vector_get( x, j ) );
-
- gsl_vector_set( f, i + ri->rank, dT );
- }
-
- return GSL_SUCCESS;
+ struct reac_info* ri = (struct reac_info *)params;
+ // Stoich* s = reinterpret_cast< Stoich* >( ri->stoich.eref().data() );
+ int num_consv = ri->num_mols - ri->rank;
+
+ for ( unsigned int i = 0; i < ri->num_mols; ++i )
+ {
+ double temp = op( gsl_vector_get( x, i ) );
+ if ( isNaN( temp ) || isInfinity( temp ) )
+ {
+ return GSL_ERANGE;
+ }
+ else
+ {
+ ri->nVec[i] = temp;
+ }
+ }
+ vector< double > vels;
+ ri->pool->updateReacVelocities( &ri->nVec[0], vels );
+ assert( vels.size() == static_cast< unsigned int >( ri->num_reacs ) );
+
+ // y = Nr . v
+ // Note that Nr is row-echelon: diagonal and above.
+ for ( int i = 0; i < ri->rank; ++i )
+ {
+ double temp = 0;
+ for ( int j = i; j < ri->num_reacs; ++j )
+ temp += gsl_matrix_get( ri->Nr, i, j ) * vels[j];
+ gsl_vector_set( f, i, temp );
+ }
+
+ // dT = gamma.S - T
+ for ( int i = 0; i < num_consv; ++i )
+ {
+ double dT = - ri->T[i];
+ for ( unsigned int j = 0; j < ri->num_mols; ++j )
+ dT += gsl_matrix_get( ri->gamma, i, j) *
+ op( gsl_vector_get( x, j ) );
+
+ gsl_vector_set( f, i + ri->rank, dT );
+ }
+
+ return GSL_SUCCESS;
}
/**
@@ -923,24 +983,27 @@ int ss_func( const gsl_vector* x, void* params, gsl_vector* f )
*/
void eliminateRowsBelow( gsl_matrix* U, int start, int leftCol )
{
- int numMols = U->size1;
- double pivot = gsl_matrix_get( U, start, leftCol );
- assert( fabs( pivot ) > SteadyState::EPSILON );
- for ( int i = start + 1; i < numMols; ++i ) {
- double factor = gsl_matrix_get( U, i, leftCol );
- if ( fabs ( factor ) > SteadyState::EPSILON ) {
- factor = factor / pivot;
- for ( size_t j = leftCol + 1; j < U->size2; ++j ) {
- double x = gsl_matrix_get( U, i, j );
- double y = gsl_matrix_get( U, start, j );
- x -= y * factor;
- if ( fabs( x ) < SteadyState::EPSILON )
- x = 0.0;
- gsl_matrix_set( U, i, j, x );
- }
- }
- gsl_matrix_set( U, i, leftCol, 0.0 ); // Cleaning up.
- }
+ int numMols = U->size1;
+ double pivot = gsl_matrix_get( U, start, leftCol );
+ assert( fabs( pivot ) > SteadyState::EPSILON );
+ for ( int i = start + 1; i < numMols; ++i )
+ {
+ double factor = gsl_matrix_get( U, i, leftCol );
+ if ( fabs ( factor ) > SteadyState::EPSILON )
+ {
+ factor = factor / pivot;
+ for ( size_t j = leftCol + 1; j < U->size2; ++j )
+ {
+ double x = gsl_matrix_get( U, i, j );
+ double y = gsl_matrix_get( U, start, j );
+ x -= y * factor;
+ if ( fabs( x ) < SteadyState::EPSILON )
+ x = 0.0;
+ gsl_matrix_set( U, i, j, x );
+ }
+ }
+ gsl_matrix_set( U, i, leftCol, 0.0 ); // Cleaning up.
+ }
}
/**
@@ -953,24 +1016,29 @@ void eliminateRowsBelow( gsl_matrix* U, int start, int leftCol )
*/
int reorderRows( gsl_matrix* U, int start, int leftCol )
{
- int leftMostRow = start;
- int numReacs = U->size2 - U->size1;
- int newLeftCol = numReacs;
- for ( size_t i = start; i < U->size1; ++i ) {
- for ( int j = leftCol; j < numReacs; ++j ) {
- if ( fabs( gsl_matrix_get( U, i, j ) ) > SteadyState::EPSILON ){
- if ( j < newLeftCol ) {
- newLeftCol = j;
- leftMostRow = i;
- }
- break;
- }
- }
- }
- if ( leftMostRow != start ) { // swap them.
- gsl_matrix_swap_rows( U, start, leftMostRow );
- }
- return newLeftCol;
+ int leftMostRow = start;
+ int numReacs = U->size2 - U->size1;
+ int newLeftCol = numReacs;
+ for ( size_t i = start; i < U->size1; ++i )
+ {
+ for ( int j = leftCol; j < numReacs; ++j )
+ {
+ if ( fabs( gsl_matrix_get( U, i, j ) ) > SteadyState::EPSILON )
+ {
+ if ( j < newLeftCol )
+ {
+ newLeftCol = j;
+ leftMostRow = i;
+ }
+ break;
+ }
+ }
+ }
+ if ( leftMostRow != start ) // swap them.
+ {
+ gsl_matrix_swap_rows( U, start, leftMostRow );
+ }
+ return newLeftCol;
}
/**
@@ -982,19 +1050,20 @@ int reorderRows( gsl_matrix* U, int start, int leftCol )
*/
int myGaussianDecomp( gsl_matrix* U )
{
- int numMols = U->size1;
- int numReacs = U->size2 - numMols;
- int i;
- // Start out with a nonzero entry at 0,0
- int leftCol = reorderRows( U, 0, 0 );
-
- for ( i = 0; i < numMols - 1; ++i ) {
- eliminateRowsBelow( U, i, leftCol );
- leftCol = reorderRows( U, i + 1, leftCol );
- if ( leftCol == numReacs )
- break;
- }
- return i + 1;
+ int numMols = U->size1;
+ int numReacs = U->size2 - numMols;
+ int i;
+ // Start out with a nonzero entry at 0,0
+ int leftCol = reorderRows( U, 0, 0 );
+
+ for ( i = 0; i < numMols - 1; ++i )
+ {
+ eliminateRowsBelow( U, i, leftCol );
+ leftCol = reorderRows( U, i + 1, leftCol );
+ if ( leftCol == numReacs )
+ break;
+ }
+ return i + 1;
}
//////////////////////////////////////////////////////////////////
@@ -1003,24 +1072,26 @@ int myGaussianDecomp( gsl_matrix* U )
void recalcTotal( vector< double >& tot, gsl_matrix* g, const double* S )
{
- assert( g->size1 == tot.size() );
- for ( unsigned int i = 0; i < g->size1; ++i ) {
- double t = 0.0;
- for ( unsigned int j = 0; j < g->size2; ++j )
- t += gsl_matrix_get( g, i, j ) * S[j];
- tot[ i ] = t;
- }
+ assert( g->size1 == tot.size() );
+ for ( unsigned int i = 0; i < g->size1; ++i )
+ {
+ double t = 0.0;
+ for ( unsigned int j = 0; j < g->size2; ++j )
+ t += gsl_matrix_get( g, i, j ) * S[j];
+ tot[ i ] = t;
+ }
}
#endif // end of long section of functions using GSL
static bool checkAboveZero( const vector< double >& y )
{
- for ( vector< double >::const_iterator
- i = y.begin(); i != y.end(); ++i ) {
- if ( *i < 0.0 )
- return false;
- }
- return true;
+ for ( vector< double >::const_iterator
+ i = y.begin(); i != y.end(); ++i )
+ {
+ if ( *i < 0.0 )
+ return false;
+ }
+ return true;
}
/**
@@ -1030,54 +1101,62 @@ static bool checkAboveZero( const vector< double >& y )
void SteadyState::randomizeInitialCondition( const Eref& me )
{
#ifdef USE_GSL
- Id ksolve = Field< Id >::get( stoich_, "ksolve" );
- vector< double > nVec =
- LookupField< unsigned int, vector< double > >::get(
- ksolve,"nVec", 0 );
- int numConsv = total_.size();
- recalcTotal( total_, gamma_, &nVec[0] );
- // The reorderRows function likes to have an I matrix at the end of
- // numVarPools_, so we provide space for it, although only its first
- // column is used for the total vector.
- gsl_matrix* U = gsl_matrix_calloc ( numConsv, numVarPools_ + numConsv );
- for ( int i = 0; i < numConsv; ++i ) {
- for ( unsigned int j = 0; j < numVarPools_; ++j ) {
- gsl_matrix_set( U, i, j, gsl_matrix_get( gamma_, i, j ) );
- }
- gsl_matrix_set( U, i, numVarPools_, total_[i] );
- }
- // Do the forward elimination
- int rank = myGaussianDecomp( U );
- assert( rank = numConsv );
-
- vector< double > eliminatedTotal( numConsv, 0.0 );
- for ( int i = 0; i < numConsv; ++i ) {
- eliminatedTotal[i] = gsl_matrix_get( U, i, numVarPools_ );
- }
-
- // Put Find a vector Y that fits the consv rules.
- vector< double > y( numVarPools_, 0.0 );
- do {
- fitConservationRules( U, eliminatedTotal, y );
- } while ( !checkAboveZero( y ) );
-
- // Sanity check. Try the new vector with the old gamma and tots
- for ( int i = 0; i < numConsv; ++i ) {
- double tot = 0.0;
- for ( unsigned int j = 0; j < numVarPools_; ++j ) {
- tot += y[j] * gsl_matrix_get( gamma_, i, j );
- }
- assert( fabs( tot - total_[i] ) / tot < EPSILON );
- }
-
- // Put the new values into S.
- // cout << endl;
- for ( unsigned int j = 0; j < numVarPools_; ++j ) {
- nVec[j] = y[j];
- // cout << y[j] << " ";
- }
- LookupField< unsigned int, vector< double > >::set(
- ksolve,"nVec", 0, nVec );
+ Id ksolve = Field< Id >::get( stoich_, "ksolve" );
+ vector< double > nVec =
+ LookupField< unsigned int, vector< double > >::get(
+ ksolve,"nVec", 0 );
+ int numConsv = total_.size();
+ recalcTotal( total_, gamma_, &nVec[0] );
+ // The reorderRows function likes to have an I matrix at the end of
+ // numVarPools_, so we provide space for it, although only its first
+ // column is used for the total vector.
+ gsl_matrix* U = gsl_matrix_calloc ( numConsv, numVarPools_ + numConsv );
+ for ( int i = 0; i < numConsv; ++i )
+ {
+ for ( unsigned int j = 0; j < numVarPools_; ++j )
+ {
+ gsl_matrix_set( U, i, j, gsl_matrix_get( gamma_, i, j ) );
+ }
+ gsl_matrix_set( U, i, numVarPools_, total_[i] );
+ }
+ // Do the forward elimination
+ int rank = myGaussianDecomp( U );
+ assert( rank = numConsv );
+
+ vector< double > eliminatedTotal( numConsv, 0.0 );
+ for ( int i = 0; i < numConsv; ++i )
+ {
+ eliminatedTotal[i] = gsl_matrix_get( U, i, numVarPools_ );
+ }
+
+ // Put Find a vector Y that fits the consv rules.
+ vector< double > y( numVarPools_, 0.0 );
+ do
+ {
+ fitConservationRules( U, eliminatedTotal, y );
+ }
+ while ( !checkAboveZero( y ) );
+
+ // Sanity check. Try the new vector with the old gamma and tots
+ for ( int i = 0; i < numConsv; ++i )
+ {
+ double tot = 0.0;
+ for ( unsigned int j = 0; j < numVarPools_; ++j )
+ {
+ tot += y[j] * gsl_matrix_get( gamma_, i, j );
+ }
+ assert( fabs( tot - total_[i] ) / tot < EPSILON );
+ }
+
+ // Put the new values into S.
+ // cout << endl;
+ for ( unsigned int j = 0; j < numVarPools_; ++j )
+ {
+ nVec[j] = y[j];
+ // cout << y[j] << " ";
+ }
+ LookupField< unsigned int, vector< double > >::set(
+ ksolve,"nVec", 0, nVec );
#endif
}
@@ -1087,36 +1166,43 @@ void SteadyState::randomizeInitialCondition( const Eref& me )
*/
#ifdef USE_GSL
void SteadyState::fitConservationRules(
- gsl_matrix* U, const vector< double >& eliminatedTotal,
- vector< double >&y
- )
+ gsl_matrix* U, const vector< double >& eliminatedTotal,
+ vector< double >&y
+)
{
- int numConsv = total_.size();
- int lastJ = numVarPools_;
- for ( int i = numConsv - 1; i >= 0; --i ) {
- for ( unsigned int j = 0; j < numVarPools_; ++j ) {
- double g = gsl_matrix_get( U, i, j );
- if ( fabs( g ) > EPSILON ) {
- // double ytot = calcTot( g, i, j, lastJ );
- double ytot = 0.0;
- for ( int k = j; k < lastJ; ++k ) {
- y[k] = mtrand();
- ytot += y[k] * gsl_matrix_get( U, i, k );
- }
- assert( fabs( ytot ) > EPSILON );
- double lastYtot = 0.0;
- for ( unsigned int k = lastJ; k < numVarPools_; ++k ) {
- lastYtot += y[k] * gsl_matrix_get( U, i, k );
- }
- double scale = ( eliminatedTotal[i] - lastYtot ) / ytot;
- for ( int k = j; k < lastJ; ++k ) {
- y[k] *= scale;
- }
- lastJ = j;
- break;
- }
- }
- }
+ int numConsv = total_.size();
+ int lastJ = numVarPools_;
+ for ( int i = numConsv - 1; i >= 0; --i )
+ {
+ for ( unsigned int j = 0; j < numVarPools_; ++j )
+ {
+ double g = gsl_matrix_get( U, i, j );
+ if ( fabs( g ) > EPSILON )
+ {
+ // double ytot = calcTot( g, i, j, lastJ );
+ double ytot = 0.0;
+ for ( int k = j; k < lastJ; ++k )
+ {
+ // Use global RNG.
+ y[k] = moose::mtrand();
+ ytot += y[k] * gsl_matrix_get( U, i, k );
+ }
+ assert( fabs( ytot ) > EPSILON );
+ double lastYtot = 0.0;
+ for ( unsigned int k = lastJ; k < numVarPools_; ++k )
+ {
+ lastYtot += y[k] * gsl_matrix_get( U, i, k );
+ }
+ double scale = ( eliminatedTotal[i] - lastYtot ) / ytot;
+ for ( int k = j; k < lastJ; ++k )
+ {
+ y[k] *= scale;
+ }
+ lastJ = j;
+ break;
+ }
+ }
+ }
}
#endif
diff --git a/ksolve/Stoich.cpp b/ksolve/Stoich.cpp
index 458151401e2c2a0bcb36a9f04671e1e3b3947891..3cd9d9022bc419096a5c75ec90491f2e9a145b13 100644
--- a/ksolve/Stoich.cpp
+++ b/ksolve/Stoich.cpp
@@ -81,9 +81,9 @@ const Cinfo* Stoich::initCinfo()
" This is used to protect the chemical system from going unstable"
" in cases where the numerical integration gives a negative value."
" Typically it is a small negative value but is obviously"
- " physically impossible. In some cases we want to use the "
+ " physically impossible. In some cases we want to use the "
" solvers to handle general systems of equations (not purely "
- " chemical ones), so we have this flag to allow it.",
+ " chemical ones), so we have this flag to allow it.",
&Stoich::setAllowNegative,
&Stoich::getAllowNegative
);
@@ -554,6 +554,17 @@ vector< unsigned int > Stoich::getPoolIdMap() const
return ret;
}
+Id Stoich::getPoolByIndex( unsigned int index ) const
+{
+ map< Id, unsigned int >::const_iterator i;
+ for ( i = poolLookup_.begin(); i != poolLookup_.end(); ++i )
+ {
+ if( i->second == index )
+ return i->first;
+ }
+ return Id();
+}
+
unsigned int Stoich::getNumRates() const
{
return rates_.size();
@@ -594,8 +605,8 @@ const FuncTerm* Stoich::funcs( unsigned int i ) const
bool Stoich::isFuncTarget( unsigned int poolIndex ) const
{
- assert( poolIndex < funcTarget_.size() );
- return ( funcTarget_[poolIndex] != ~0U );
+ assert( poolIndex < funcTarget_.size() );
+ return ( funcTarget_[poolIndex] != ~0U );
}
vector< int > Stoich::getMatrixEntry() const
@@ -935,9 +946,9 @@ void Stoich::resizeArrays()
species_.resize( totNumPools, 0 );
- funcTarget_.clear();
- // Only the pools controlled by a func (targets) have positive indices.
- funcTarget_.resize( totNumPools, ~0 );
+ funcTarget_.clear();
+ // Only the pools controlled by a func (targets) have positive indices.
+ funcTarget_.resize( totNumPools, ~0 );
unsigned int totNumRates =
( reacVec_.size() + offSolverReacVec_.size() ) * (1+useOneWay_) +
@@ -1089,13 +1100,13 @@ void Stoich::installAndUnschedFunc( Id func, Id pool, double volScale )
string expr = Field< string >::get( func, "expr" );
ft->setExpr( expr );
// Tie the output of the FuncTerm to the pool it controls.
- unsigned int targetIndex = convertIdToPoolIndex( pool );
+ unsigned int targetIndex = convertIdToPoolIndex( pool );
ft->setTarget( targetIndex );
ft->setVolScale( volScale );
unsigned int funcIndex = convertIdToFuncIndex( func );
assert( funcIndex != ~0U );
- // funcTarget_ vector tracks which pools are controlled by which func.
- funcTarget_[targetIndex] = funcIndex;
+ // funcTarget_ vector tracks which pools are controlled by which func.
+ funcTarget_[targetIndex] = funcIndex;
funcs_[ funcIndex ] = ft;
}
@@ -1401,8 +1412,9 @@ void Stoich::unZombifyModel()
unZombifyPools();
- vector< Id > temp = reacVec_; temp.insert( temp.end(),
- offSolverReacVec_.begin(), offSolverReacVec_.end() );
+ vector< Id > temp = reacVec_;
+ temp.insert( temp.end(),
+ offSolverReacVec_.begin(), offSolverReacVec_.end() );
for ( vector< Id >::iterator i = temp.begin(); i != temp.end(); ++i )
{
Element* e = i->element();
@@ -1410,8 +1422,9 @@ void Stoich::unZombifyModel()
ReacBase::zombify( e, reacCinfo, Id() );
}
- temp = mmEnzVec_; temp.insert( temp.end(),
- offSolverMMenzVec_.begin(), offSolverMMenzVec_.end() );
+ temp = mmEnzVec_;
+ temp.insert( temp.end(),
+ offSolverMMenzVec_.begin(), offSolverMMenzVec_.end() );
for ( vector< Id >::iterator i = temp.begin(); i != temp.end(); ++i )
{
Element* e = i->element();
@@ -1419,8 +1432,9 @@ void Stoich::unZombifyModel()
EnzBase::zombify( e, mmEnzCinfo, Id() );
}
- temp = enzVec_; temp.insert( temp.end(),
- offSolverEnzVec_.begin(), offSolverEnzVec_.end() );
+ temp = enzVec_;
+ temp.insert( temp.end(),
+ offSolverEnzVec_.begin(), offSolverEnzVec_.end() );
for ( vector< Id >::iterator i = temp.begin(); i != temp.end(); ++i )
{
Element* e = i->element();
@@ -1428,8 +1442,9 @@ void Stoich::unZombifyModel()
CplxEnzBase::zombify( e, enzCinfo, Id() );
}
- temp = poolFuncVec_; temp.insert( temp.end(),
- incrementFuncVec_.begin(), incrementFuncVec_.end() );
+ temp = poolFuncVec_;
+ temp.insert( temp.end(),
+ incrementFuncVec_.begin(), incrementFuncVec_.end() );
for ( vector< Id >::iterator i = temp.begin(); i != temp.end(); ++i )
{
Element* e = i->element();
diff --git a/ksolve/Stoich.h b/ksolve/Stoich.h
index bea3d067f1b560863ac02f8240841274c1e75af4..93e63b9f79fa7a0b344bb3d85638773206db74d6 100644
--- a/ksolve/Stoich.h
+++ b/ksolve/Stoich.h
@@ -91,6 +91,8 @@ class Stoich
*/
vector< unsigned int > getPoolIdMap() const;
+ Id getPoolByIndex( unsigned int index ) const;
+
/**
* Take the provided wildcard path to build the list of elements
* managed by this solver.
@@ -485,7 +487,7 @@ class Stoich
*/
bool useOneWay_;
- /**
+ /**
* True if pools are permitted to take negative concentrations.
* This may happen if solver is handling a general equation system
* that is not constrained by chemical rules.
diff --git a/ksolve/VoxelPools.cpp b/ksolve/VoxelPools.cpp
index 64b07be22f8ab7c16761881de85461b5f606433a..38c5e2e76e3fdba4668df119db07ce2a80127b5a 100644
--- a/ksolve/VoxelPools.cpp
+++ b/ksolve/VoxelPools.cpp
@@ -12,7 +12,7 @@
#include <gsl/gsl_errno.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_odeiv2.h>
-#elif USE_BOOST
+#elif USE_BOOST_ODE
#include <boost/numeric/odeint.hpp>
using namespace boost::numeric;
#endif
@@ -36,17 +36,17 @@ using namespace boost::numeric;
VoxelPools::VoxelPools()
{
#ifdef USE_GSL
- driver_ = 0;
+ driver_ = 0;
#endif
}
VoxelPools::~VoxelPools()
{
- for ( unsigned int i = 0; i < rates_.size(); ++i )
- delete( rates_[i] );
+ for ( unsigned int i = 0; i < rates_.size(); ++i )
+ delete( rates_[i] );
#ifdef USE_GSL
- if ( driver_ )
- gsl_odeiv2_driver_free( driver_ );
+ if ( driver_ )
+ gsl_odeiv2_driver_free( driver_ );
#endif
}
@@ -55,12 +55,12 @@ VoxelPools::~VoxelPools()
//////////////////////////////////////////////////////////////
void VoxelPools::reinit( double dt )
{
- VoxelPoolsBase::reinit();
+ VoxelPoolsBase::reinit();
#ifdef USE_GSL
- if ( !driver_ )
- return;
- gsl_odeiv2_driver_reset( driver_ );
- gsl_odeiv2_driver_reset_hstart( driver_, dt / 10.0 );
+ if ( !driver_ )
+ return;
+ gsl_odeiv2_driver_reset( driver_ );
+ gsl_odeiv2_driver_reset_hstart( driver_, dt / 10.0 );
#endif
}
@@ -68,15 +68,18 @@ void VoxelPools::setStoich( Stoich* s, const OdeSystem* ode )
{
stoichPtr_ = s;
#ifdef USE_GSL
- if ( ode ) {
+ if ( ode )
+ {
sys_ = ode->gslSys;
if ( driver_ )
gsl_odeiv2_driver_free( driver_ );
+
driver_ = gsl_odeiv2_driver_alloc_y_new(
- &sys_, ode->gslStep, ode->initStepSize,
- ode->epsAbs, ode->epsRel );
+ &sys_, ode->gslStep, ode->initStepSize,
+ ode->epsAbs, ode->epsRel
+ );
}
-#elif USE_BOOST
+#elif USE_BOOST_ODE
if( ode )
sys_ = ode->boostSys;
#endif
@@ -88,11 +91,12 @@ void VoxelPools::advance( const ProcInfo* p )
double t = p->currTime - p->dt;
#ifdef USE_GSL
int status = gsl_odeiv2_driver_apply( driver_, &t, p->currTime, varS());
- if ( status != GSL_SUCCESS ) {
+ if ( status != GSL_SUCCESS )
+ {
cout << "Error: VoxelPools::advance: GSL integration error at time "
- << t << "\n";
+ << t << "\n";
cout << "Error info: " << status << ", " <<
- gsl_strerror( status ) << endl;
+ gsl_strerror( status ) << endl;
if ( status == GSL_EMAXITER )
cout << "Max number of steps exceeded\n";
else if ( status == GSL_ENOPROG )
@@ -102,7 +106,7 @@ void VoxelPools::advance( const ProcInfo* p )
assert( 0 );
}
-#elif USE_BOOST
+#elif USE_BOOST_ODE
// NOTE: Make sure to assing vp to BoostSys vp. In next call, it will be used by
@@ -144,126 +148,128 @@ void VoxelPools::advance( const ProcInfo* p )
if( sys_.method == "rk2" )
odeint::integrate_const( rk_midpoint_stepper_type_()
- , sys_ , Svec()
- , p->currTime - p->dt, p->currTime, std::min( p->dt, fixedDt )
- );
+ , sys_ , Svec()
+ , p->currTime - p->dt, p->currTime, std::min( p->dt, fixedDt )
+ );
else if( sys_.method == "rk4" )
odeint::integrate_const( rk4_stepper_type_()
- , sys_ , Svec()
- , p->currTime - p->dt, p->currTime, std::min( p->dt, fixedDt )
- );
+ , sys_ , Svec()
+ , p->currTime - p->dt, p->currTime, std::min( p->dt, fixedDt )
+ );
else if( sys_.method == "rk5")
odeint::integrate_const( rk_karp_stepper_type_()
- , sys_ , Svec()
- , p->currTime - p->dt, p->currTime, std::min( p->dt, fixedDt )
- );
+ , sys_ , Svec()
+ , p->currTime - p->dt, p->currTime, std::min( p->dt, fixedDt )
+ );
else if( sys_.method == "rk5a")
odeint::integrate_adaptive(
- odeint::make_controlled<rk_karp_stepper_type_>( absTol, relTol)
- , sys_
- , Svec()
- , p->currTime - p->dt
- , p->currTime
- , p->dt
- );
+ odeint::make_controlled<rk_karp_stepper_type_>( absTol, relTol)
+ , sys_
+ , Svec()
+ , p->currTime - p->dt
+ , p->currTime
+ , p->dt
+ );
else if ("rk54" == sys_.method )
odeint::integrate_const( rk_karp_stepper_type_()
- , sys_ , Svec()
- , p->currTime - p->dt, p->currTime, std::min( p->dt, fixedDt )
- );
+ , sys_ , Svec()
+ , p->currTime - p->dt, p->currTime, std::min( p->dt, fixedDt )
+ );
else if ("rk54a" == sys_.method )
odeint::integrate_adaptive(
- odeint::make_controlled<rk_karp_stepper_type_>( absTol, relTol )
- , sys_, Svec()
- , p->currTime - p->dt
- , p->currTime
- , p->dt
- );
+ odeint::make_controlled<rk_karp_stepper_type_>( absTol, relTol )
+ , sys_, Svec()
+ , p->currTime - p->dt
+ , p->currTime
+ , p->dt
+ );
else if ("rk5" == sys_.method )
odeint::integrate_const( rk_dopri_stepper_type_()
- , sys_ , Svec()
- , p->currTime - p->dt, p->currTime, std::min( p->dt, fixedDt )
- );
+ , sys_ , Svec()
+ , p->currTime - p->dt, p->currTime, std::min( p->dt, fixedDt )
+ );
else if ("rk5a" == sys_.method )
odeint::integrate_adaptive(
- odeint::make_controlled<rk_dopri_stepper_type_>( absTol, relTol )
- , sys_, Svec()
- , p->currTime - p->dt
- , p->currTime
- , p->dt
- );
+ odeint::make_controlled<rk_dopri_stepper_type_>( absTol, relTol )
+ , sys_, Svec()
+ , p->currTime - p->dt
+ , p->currTime
+ , p->dt
+ );
else if( sys_.method == "rk8" )
odeint::integrate_const( rk_felhberg_stepper_type_()
- , sys_ , Svec()
- , p->currTime - p->dt, p->currTime, std::min( p->dt, fixedDt )
- );
+ , sys_ , Svec()
+ , p->currTime - p->dt, p->currTime, std::min( p->dt, fixedDt )
+ );
else if( sys_.method == "rk8a" )
odeint::integrate_adaptive(
- odeint::make_controlled<rk_felhberg_stepper_type_>( absTol, relTol )
- , sys_, Svec()
- , p->currTime - p->dt
- , p->currTime
- , p->dt
- );
+ odeint::make_controlled<rk_felhberg_stepper_type_>( absTol, relTol )
+ , sys_, Svec()
+ , p->currTime - p->dt
+ , p->currTime
+ , p->dt
+ );
else
odeint::integrate_adaptive(
- odeint::make_controlled<rk_karp_stepper_type_>( absTol, relTol )
- , sys_, Svec()
- , p->currTime - p->dt
- , p->currTime
- , p->dt
- );
+ odeint::make_controlled<rk_karp_stepper_type_>( absTol, relTol )
+ , sys_, Svec()
+ , p->currTime - p->dt
+ , p->currTime
+ , p->dt
+ );
#endif
- if ( !stoichPtr_->getAllowNegative() ) { // clean out negatives
- unsigned int nv = stoichPtr_->getNumVarPools();
- double* vs = varS();
- for ( unsigned int i = 0; i < nv; ++i ) {
- if ( signbit(vs[i]) )
- vs[i] = 0.0;
- }
- }
+ if ( !stoichPtr_->getAllowNegative() ) // clean out negatives
+ {
+ unsigned int nv = stoichPtr_->getNumVarPools();
+ double* vs = varS();
+ for ( unsigned int i = 0; i < nv; ++i )
+ {
+ if ( signbit(vs[i]) )
+ vs[i] = 0.0;
+ }
+ }
}
void VoxelPools::setInitDt( double dt )
{
#ifdef USE_GSL
- gsl_odeiv2_driver_reset_hstart( driver_, dt );
+ gsl_odeiv2_driver_reset_hstart( driver_, dt );
#endif
}
#ifdef USE_GSL
// static func. This is the function that goes into the Gsl solver.
int VoxelPools::gslFunc( double t, const double* y, double *dydt,
- void* params )
+ void* params )
{
- VoxelPools* vp = reinterpret_cast< VoxelPools* >( params );
- // Stoich* s = reinterpret_cast< Stoich* >( params );
- double* q = const_cast< double* >( y ); // Assign the func portion.
-
- // Assign the buffered pools
- // Not possible because this is a static function
- // Not needed because dydt = 0;
- /*
- double* b = q + s->getNumVarPools();
- vector< double >::const_iterator sinit = Sinit_.begin() + s->getNumVarPools();
- for ( unsigned int i = 0; i < s->getNumBufPools(); ++i )
- *b++ = *sinit++;
- */
-
- vp->stoichPtr_->updateFuncs( q, t );
- vp->updateRates( y, dydt );
+ VoxelPools* vp = reinterpret_cast< VoxelPools* >( params );
+ // Stoich* s = reinterpret_cast< Stoich* >( params );
+ double* q = const_cast< double* >( y ); // Assign the func portion.
+
+ // Assign the buffered pools
+ // Not possible because this is a static function
+ // Not needed because dydt = 0;
+ /*
+ double* b = q + s->getNumVarPools();
+ vector< double >::const_iterator sinit = Sinit_.begin() + s->getNumVarPools();
+ for ( unsigned int i = 0; i < s->getNumBufPools(); ++i )
+ *b++ = *sinit++;
+ */
+
+ vp->stoichPtr_->updateFuncs( q, t );
+ vp->updateRates( y, dydt );
#ifdef USE_GSL
- return GSL_SUCCESS;
+ return GSL_SUCCESS;
#else
- return 0;
+ return 0;
#endif
}
-#elif USE_BOOST
+#elif USE_BOOST_ODE
void VoxelPools::evalRates(
const vector_type_& y, vector_type_& dydt, const double t, VoxelPools* vp
- )
+)
{
vp->updateRates( &y[0], &dydt[0] );
}
@@ -274,64 +280,66 @@ void VoxelPools::evalRates(
///////////////////////////////////////////////////////////////////////
void VoxelPools::updateAllRateTerms( const vector< RateTerm* >& rates,
- unsigned int numCoreRates )
+ unsigned int numCoreRates )
{
- // Clear out old rates if any
- for ( unsigned int i = 0; i < rates_.size(); ++i )
- delete( rates_[i] );
-
- rates_.resize( rates.size() );
- for ( unsigned int i = 0; i < numCoreRates; ++i )
- rates_[i] = rates[i]->copyWithVolScaling( getVolume(), 1, 1 );
- for ( unsigned int i = numCoreRates; i < rates.size(); ++i ) {
- rates_[i] = rates[i]->copyWithVolScaling( getVolume(),
- getXreacScaleSubstrates(i - numCoreRates),
- getXreacScaleProducts(i - numCoreRates ) );
- }
+ // Clear out old rates if any
+ for ( unsigned int i = 0; i < rates_.size(); ++i )
+ delete( rates_[i] );
+
+ rates_.resize( rates.size() );
+ for ( unsigned int i = 0; i < numCoreRates; ++i )
+ rates_[i] = rates[i]->copyWithVolScaling( getVolume(), 1, 1 );
+ for ( unsigned int i = numCoreRates; i < rates.size(); ++i )
+ {
+ rates_[i] = rates[i]->copyWithVolScaling( getVolume(),
+ getXreacScaleSubstrates(i - numCoreRates),
+ getXreacScaleProducts(i - numCoreRates ) );
+ }
}
void VoxelPools::updateRateTerms( const vector< RateTerm* >& rates,
- unsigned int numCoreRates, unsigned int index )
+ unsigned int numCoreRates, unsigned int index )
{
- // During setup or expansion of the reac system, it is possible to
- // call this function before the rates_ term is assigned. Disable.
- if ( index >= rates_.size() )
- return;
- delete( rates_[index] );
- if ( index >= numCoreRates )
- rates_[index] = rates[index]->copyWithVolScaling(
- getVolume(),
- getXreacScaleSubstrates(index - numCoreRates),
- getXreacScaleProducts(index - numCoreRates ) );
- else
- rates_[index] = rates[index]->copyWithVolScaling(
- getVolume(), 1.0, 1.0 );
+ // During setup or expansion of the reac system, it is possible to
+ // call this function before the rates_ term is assigned. Disable.
+ if ( index >= rates_.size() )
+ return;
+ delete( rates_[index] );
+ if ( index >= numCoreRates )
+ rates_[index] = rates[index]->copyWithVolScaling(
+ getVolume(),
+ getXreacScaleSubstrates(index - numCoreRates),
+ getXreacScaleProducts(index - numCoreRates ) );
+ else
+ rates_[index] = rates[index]->copyWithVolScaling(
+ getVolume(), 1.0, 1.0 );
}
void VoxelPools::updateRates( const double* s, double* yprime ) const
{
- const KinSparseMatrix& N = stoichPtr_->getStoichiometryMatrix();
- vector< double > v( N.nColumns(), 0.0 );
- vector< double >::iterator j = v.begin();
- // totVar should include proxyPools only if this voxel uses them
- unsigned int totVar = stoichPtr_->getNumVarPools() +
- stoichPtr_->getNumProxyPools();
- // totVar should include proxyPools if this voxel does not use them
- unsigned int totInvar = stoichPtr_->getNumBufPools();
- assert( N.nColumns() == 0 ||
- N.nRows() == stoichPtr_->getNumAllPools() );
- assert( N.nColumns() == rates_.size() );
-
- for ( vector< RateTerm* >::const_iterator
- i = rates_.begin(); i != rates_.end(); i++) {
- *j++ = (**i)( s );
- assert( !std::isnan( *( j-1 ) ) );
- }
-
- for (unsigned int i = 0; i < totVar; ++i)
- *yprime++ = N.computeRowRate( i , v );
- for (unsigned int i = 0; i < totInvar ; ++i)
- *yprime++ = 0.0;
+ const KinSparseMatrix& N = stoichPtr_->getStoichiometryMatrix();
+ vector< double > v( N.nColumns(), 0.0 );
+ vector< double >::iterator j = v.begin();
+ // totVar should include proxyPools only if this voxel uses them
+ unsigned int totVar = stoichPtr_->getNumVarPools() +
+ stoichPtr_->getNumProxyPools();
+ // totVar should include proxyPools if this voxel does not use them
+ unsigned int totInvar = stoichPtr_->getNumBufPools();
+ assert( N.nColumns() == 0 ||
+ N.nRows() == stoichPtr_->getNumAllPools() );
+ assert( N.nColumns() == rates_.size() );
+
+ for ( vector< RateTerm* >::const_iterator
+ i = rates_.begin(); i != rates_.end(); i++)
+ {
+ *j++ = (**i)( s );
+ assert( !std::isnan( *( j-1 ) ) );
+ }
+
+ for (unsigned int i = 0; i < totVar; ++i)
+ *yprime++ = N.computeRowRate( i , v );
+ for (unsigned int i = 0; i < totInvar ; ++i)
+ *yprime++ = 0.0;
}
/**
@@ -340,28 +348,29 @@ void VoxelPools::updateRates( const double* s, double* yprime ) const
* to analyze velocity.
*/
void VoxelPools::updateReacVelocities(
- const double* s, vector< double >& v ) const
+ const double* s, vector< double >& v ) const
{
- const KinSparseMatrix& N = stoichPtr_->getStoichiometryMatrix();
- assert( N.nColumns() == rates_.size() );
-
- vector< RateTerm* >::const_iterator i;
- v.clear();
- v.resize( rates_.size(), 0.0 );
- vector< double >::iterator j = v.begin();
-
- for ( i = rates_.begin(); i != rates_.end(); i++) {
- *j++ = (**i)( s );
- assert( !std::isnan( *( j-1 ) ) );
- }
+ const KinSparseMatrix& N = stoichPtr_->getStoichiometryMatrix();
+ assert( N.nColumns() == rates_.size() );
+
+ vector< RateTerm* >::const_iterator i;
+ v.clear();
+ v.resize( rates_.size(), 0.0 );
+ vector< double >::iterator j = v.begin();
+
+ for ( i = rates_.begin(); i != rates_.end(); i++)
+ {
+ *j++ = (**i)( s );
+ assert( !std::isnan( *( j-1 ) ) );
+ }
}
/// For debugging: Print contents of voxel pool
void VoxelPools::print() const
{
- cout << "numAllRates = " << rates_.size() <<
- ", numLocalRates= " << stoichPtr_->getNumCoreRates() << endl;
- VoxelPoolsBase::print();
+ cout << "numAllRates = " << rates_.size() <<
+ ", numLocalRates= " << stoichPtr_->getNumCoreRates() << endl;
+ VoxelPoolsBase::print();
}
////////////////////////////////////////////////////////////
@@ -370,8 +379,8 @@ void VoxelPools::print() const
*/
void VoxelPools::setVolumeAndDependencies( double vol )
{
- VoxelPoolsBase::setVolumeAndDependencies( vol );
- updateAllRateTerms( stoichPtr_->getRateTerms(),
- stoichPtr_->getNumCoreRates() );
+ VoxelPoolsBase::setVolumeAndDependencies( vol );
+ updateAllRateTerms( stoichPtr_->getRateTerms(),
+ stoichPtr_->getNumCoreRates() );
}
diff --git a/ksolve/VoxelPools.h b/ksolve/VoxelPools.h
index bd1e5ec5003e23d33699723d04ed21340791458a..a8f0b4aef36a8fe7290eec8418d2716ef684878e 100644
--- a/ksolve/VoxelPools.h
+++ b/ksolve/VoxelPools.h
@@ -14,7 +14,7 @@
#include "OdeSystem.h"
#include "VoxelPoolsBase.h"
-#ifdef USE_BOOST
+#ifdef USE_BOOST_ODE
#include "BoostSys.h"
#endif
@@ -52,15 +52,15 @@ public:
/// Set initial timestep to use by the solver.
void setInitDt( double dt );
-#ifdef USE_GSL /* ----- not USE_BOOST ----- */
+#ifdef USE_GSL /* ----- not USE_BOOST_ODE ----- */
static int gslFunc( double t, const double* y, double *dydt, void* params);
-#elif USE_BOOST
+#elif USE_BOOST_ODE
static void evalRates( const vector_type_& y
, vector_type_& dydt
, const double t
, VoxelPools* vp
);
-#endif /* ----- not USE_BOOST ----- */
+#endif /* ----- not USE_BOOST_ODE ----- */
//////////////////////////////////////////////////////////////////
// Rate manipulation and calculation functions
@@ -102,7 +102,7 @@ private:
#ifdef USE_GSL
gsl_odeiv2_driver* driver_;
gsl_odeiv2_system sys_;
-#elif USE_BOOST
+#elif USE_BOOST_ODE
BoostSys sys_;
#endif
diff --git a/ksolve/VoxelPoolsBase.cpp b/ksolve/VoxelPoolsBase.cpp
index 22831c66d816d09784d4dc0cabfc960bf68031e8..f0261245c61cb6ae7f3466519a149d05eba17065 100644
--- a/ksolve/VoxelPoolsBase.cpp
+++ b/ksolve/VoxelPoolsBase.cpp
@@ -22,13 +22,14 @@
// Class definitions
//////////////////////////////////////////////////////////////
-VoxelPoolsBase::VoxelPoolsBase()
- :
- stoichPtr_( 0 ),
- S_(1),
- Sinit_(1),
- volume_(1.0)
-{ ; }
+VoxelPoolsBase::VoxelPoolsBase() :
+ stoichPtr_( 0 ),
+ S_(1),
+ Sinit_(1),
+ volume_(1.0)
+{
+ ;
+}
VoxelPoolsBase::~VoxelPoolsBase()
{}
@@ -53,91 +54,93 @@ void VoxelPoolsBase::reinit()
//////////////////////////////////////////////////////////////
const double* VoxelPoolsBase::S() const
{
- return &S_[0];
+ return &S_[0];
}
vector< double >& VoxelPoolsBase::Svec()
{
- return S_;
+ return S_;
}
double* VoxelPoolsBase::varS()
{
- return &S_[0];
+ return &S_[0];
}
const double* VoxelPoolsBase::Sinit() const
{
- return &Sinit_[0];
+ return &Sinit_[0];
}
double* VoxelPoolsBase::varSinit()
{
- return &Sinit_[0];
+ return &Sinit_[0];
}
unsigned int VoxelPoolsBase::size() const
{
- return Sinit_.size();
+ return Sinit_.size();
}
void VoxelPoolsBase::setVolume( double vol )
{
- volume_ = vol;
+ volume_ = vol;
}
double VoxelPoolsBase::getVolume() const
{
- return volume_;
+ return volume_;
}
void VoxelPoolsBase::setVolumeAndDependencies( double vol )
{
- double ratio = vol / volume_;
- volume_ = vol;
- for ( vector< double >::iterator
- i = Sinit_.begin(); i != Sinit_.end(); ++i )
- *i *= ratio;
+ double ratio = vol / volume_;
+ volume_ = vol;
+ for ( vector< double >::iterator
+ i = Sinit_.begin(); i != Sinit_.end(); ++i )
+ *i *= ratio;
- for ( vector< double >::iterator i = S_.begin(); i != S_.end(); ++i )
- *i *= ratio;
+ for ( vector< double >::iterator i = S_.begin(); i != S_.end(); ++i )
+ *i *= ratio;
- // I would like to update the xReacScaleSubstreates and Products here,
- // but I don't know the order of their reactions. So leave it to
- // a subsequent call via Ksolve or Stoich.
+ // I would like to update the xReacScaleSubstreates and Products here,
+ // but I don't know the order of their reactions. So leave it to
+ // a subsequent call via Ksolve or Stoich.
}
void VoxelPoolsBase::scaleVolsBufsRates(
- double ratio, const Stoich* stoichPtr )
-{
- volume_ *= ratio; // Scale vol
- for ( vector< double >::iterator
- i = Sinit_.begin(); i != Sinit_.end(); ++i )
- *i *= ratio; // Scale Bufs
- // Here we also need to set the Ns for the buffered pools.
- unsigned int start = stoichPtr_->getNumVarPools();
- unsigned int end = start + stoichPtr_->getNumBufPools();
- assert( end == Sinit_.size() );
- for ( unsigned int i = start; i < end; ++i ) {
- // Must not reassign pools that are controlled by functions.
- if ( !stoichPtr->isFuncTarget(i) )
- S_[i] = Sinit_[i];
- }
-
- // Scale rates. Start by clearing out old rates if any
- for ( unsigned int i = 0; i < rates_.size(); ++i )
- delete( rates_[i] );
-
- unsigned int numCoreRates = stoichPtr->getNumCoreRates();
- const vector< RateTerm* >& rates = stoichPtr->getRateTerms();
- rates_.resize( rates.size() );
- for ( unsigned int i = 0; i < numCoreRates; ++i )
- rates_[i] = rates[i]->copyWithVolScaling( getVolume(), 1, 1 );
- for ( unsigned int i = numCoreRates; i < rates.size(); ++i ) {
- rates_[i] = rates[i]->copyWithVolScaling( getVolume(),
- getXreacScaleSubstrates(i - numCoreRates),
- getXreacScaleProducts(i - numCoreRates ) );
- }
+ double ratio, const Stoich* stoichPtr )
+{
+ volume_ *= ratio; // Scale vol
+ for ( vector< double >::iterator
+ i = Sinit_.begin(); i != Sinit_.end(); ++i )
+ *i *= ratio; // Scale Bufs
+ // Here we also need to set the Ns for the buffered pools.
+ unsigned int start = stoichPtr_->getNumVarPools();
+ unsigned int end = start + stoichPtr_->getNumBufPools();
+ assert( end == Sinit_.size() );
+ for ( unsigned int i = start; i < end; ++i )
+ {
+ // Must not reassign pools that are controlled by functions.
+ if ( !stoichPtr->isFuncTarget(i) )
+ S_[i] = Sinit_[i];
+ }
+
+ // Scale rates. Start by clearing out old rates if any
+ for ( unsigned int i = 0; i < rates_.size(); ++i )
+ delete( rates_[i] );
+
+ unsigned int numCoreRates = stoichPtr->getNumCoreRates();
+ const vector< RateTerm* >& rates = stoichPtr->getRateTerms();
+ rates_.resize( rates.size() );
+ for ( unsigned int i = 0; i < numCoreRates; ++i )
+ rates_[i] = rates[i]->copyWithVolScaling( getVolume(), 1, 1 );
+ for ( unsigned int i = numCoreRates; i < rates.size(); ++i )
+ {
+ rates_[i] = rates[i]->copyWithVolScaling( getVolume(),
+ getXreacScaleSubstrates(i - numCoreRates),
+ getXreacScaleProducts(i - numCoreRates ) );
+ }
}
//////////////////////////////////////////////////////////////
@@ -146,129 +149,134 @@ void VoxelPoolsBase::scaleVolsBufsRates(
void VoxelPoolsBase::setN( unsigned int i, double v )
{
- S_[i] = v;
- if ( S_[i] < 0.0 )
- S_[i] = 0.0;
+ S_[i] = v;
+ if ( S_[i] < 0.0 )
+ S_[i] = 0.0;
}
double VoxelPoolsBase::getN( unsigned int i ) const
{
- return S_[i];
+ return S_[i];
}
void VoxelPoolsBase::setNinit( unsigned int i, double v )
{
- Sinit_[i] = v;
- if ( Sinit_[i] < 0.0 )
- Sinit_[i] = 0.0;
+ Sinit_[i] = v;
+ if ( Sinit_[i] < 0.0 )
+ Sinit_[i] = 0.0;
}
double VoxelPoolsBase::getNinit( unsigned int i ) const
{
- return Sinit_[i];
+ return Sinit_[i];
}
void VoxelPoolsBase::setDiffConst( unsigned int i, double v )
{
- ; // Do nothing.
+ ; // Do nothing.
}
double VoxelPoolsBase::getDiffConst( unsigned int i ) const
{
- return 0;
+ return 0;
}
//////////////////////////////////////////////////////////////
// Handle cross compartment reactions
//////////////////////////////////////////////////////////////
void VoxelPoolsBase::xferIn(
- const vector< unsigned int >& poolIndex,
- const vector< double >& values,
- const vector< double >& lastValues,
- unsigned int voxelIndex )
+ const vector< unsigned int >& poolIndex,
+ const vector< double >& values,
+ const vector< double >& lastValues,
+ unsigned int voxelIndex )
{
- unsigned int offset = voxelIndex * poolIndex.size();
- vector< double >::const_iterator i = values.begin() + offset;
- vector< double >::const_iterator j = lastValues.begin() + offset;
- for ( vector< unsigned int >::const_iterator
- k = poolIndex.begin(); k != poolIndex.end(); ++k ) {
- S_[*k] += *i++ - *j++;
- }
+ unsigned int offset = voxelIndex * poolIndex.size();
+ vector< double >::const_iterator i = values.begin() + offset;
+ vector< double >::const_iterator j = lastValues.begin() + offset;
+ for ( vector< unsigned int >::const_iterator
+ k = poolIndex.begin(); k != poolIndex.end(); ++k )
+ {
+ S_[*k] += *i++ - *j++;
+ }
}
void VoxelPoolsBase::xferInOnlyProxies(
- const vector< unsigned int >& poolIndex,
- const vector< double >& values,
- unsigned int numProxyPools,
- unsigned int voxelIndex )
-{
- unsigned int offset = voxelIndex * poolIndex.size();
- vector< double >::const_iterator i = values.begin() + offset;
- unsigned int proxyEndIndex = stoichPtr_->getNumVarPools() +
- stoichPtr_->getNumProxyPools();
- for ( vector< unsigned int >::const_iterator
- k = poolIndex.begin(); k != poolIndex.end(); ++k ) {
- // if ( *k >= S_.size() - numProxyPools )
- if ( *k >= stoichPtr_->getNumVarPools() && *k < proxyEndIndex ) {
- // cout << S_[*k] << ", " << Sinit_[*k] << ", " << *i << endl;
- Sinit_[*k] = *i;
- S_[*k] = *i;
- }
- i++;
- }
+ const vector< unsigned int >& poolIndex,
+ const vector< double >& values,
+ unsigned int numProxyPools,
+ unsigned int voxelIndex )
+{
+ unsigned int offset = voxelIndex * poolIndex.size();
+ vector< double >::const_iterator i = values.begin() + offset;
+ unsigned int proxyEndIndex = stoichPtr_->getNumVarPools() +
+ stoichPtr_->getNumProxyPools();
+ for ( vector< unsigned int >::const_iterator
+ k = poolIndex.begin(); k != poolIndex.end(); ++k )
+ {
+ // if ( *k >= S_.size() - numProxyPools )
+ if ( *k >= stoichPtr_->getNumVarPools() && *k < proxyEndIndex )
+ {
+ // cout << S_[*k] << ", " << Sinit_[*k] << ", " << *i << endl;
+ Sinit_[*k] = *i;
+ S_[*k] = *i;
+ }
+ i++;
+ }
}
void VoxelPoolsBase::xferOut(
- unsigned int voxelIndex,
- vector< double >& values,
- const vector< unsigned int >& poolIndex)
+ unsigned int voxelIndex,
+ vector< double >& values,
+ const vector< unsigned int >& poolIndex)
{
- unsigned int offset = voxelIndex * poolIndex.size();
- vector< double >::iterator i = values.begin() + offset;
- for ( vector< unsigned int >::const_iterator
- k = poolIndex.begin(); k != poolIndex.end(); ++k ) {
- *i++ = S_[*k];
- }
+ unsigned int offset = voxelIndex * poolIndex.size();
+ vector< double >::iterator i = values.begin() + offset;
+ for ( vector< unsigned int >::const_iterator
+ k = poolIndex.begin(); k != poolIndex.end(); ++k )
+ {
+ *i++ = S_[*k];
+ }
}
void VoxelPoolsBase::addProxyVoxy(
- unsigned int comptIndex, Id otherComptId, unsigned int voxel )
+ unsigned int comptIndex, Id otherComptId, unsigned int voxel )
{
- if ( comptIndex >= proxyPoolVoxels_.size() ) {
- proxyPoolVoxels_.resize( comptIndex + 1 );
- }
+ if ( comptIndex >= proxyPoolVoxels_.size() )
+ {
+ proxyPoolVoxels_.resize( comptIndex + 1 );
+ }
- proxyPoolVoxels_[comptIndex].push_back( voxel );
- proxyComptMap_[otherComptId] = comptIndex;
+ proxyPoolVoxels_[comptIndex].push_back( voxel );
+ proxyComptMap_[otherComptId] = comptIndex;
}
void VoxelPoolsBase::addProxyTransferIndex(
- unsigned int comptIndex, unsigned int transferIndex )
+ unsigned int comptIndex, unsigned int transferIndex )
{
- if ( comptIndex >= proxyTransferIndex_.size() )
- proxyTransferIndex_.resize( comptIndex + 1 );
- proxyTransferIndex_[comptIndex].push_back( transferIndex );
+ if ( comptIndex >= proxyTransferIndex_.size() )
+ proxyTransferIndex_.resize( comptIndex + 1 );
+ proxyTransferIndex_[comptIndex].push_back( transferIndex );
}
bool VoxelPoolsBase::hasXfer( unsigned int comptIndex ) const
{
- if ( comptIndex >= proxyPoolVoxels_.size() )
- return false;
- return (proxyPoolVoxels_[ comptIndex ].size() > 0);
+ if ( comptIndex >= proxyPoolVoxels_.size() )
+ return false;
+ return (proxyPoolVoxels_[ comptIndex ].size() > 0);
}
bool VoxelPoolsBase::isVoxelJunctionPresent( Id i1, Id i2 ) const
{
- if ( i1 == Id () )
- return false;
- if ( proxyComptMap_.find( i1 ) == proxyComptMap_.end() )
- return false;
- if ( i2 == Id() ) // This is intentionally blank, only one jn.
- return true;
- // If there is an i2 but it isn't on the map, then not connected.
- if ( proxyComptMap_.find( i2 ) == proxyComptMap_.end() )
- return false;
- return true;
+ if ( i1 == Id () )
+ return false;
+ if ( proxyComptMap_.find( i1 ) == proxyComptMap_.end() )
+ return false;
+ if ( i2 == Id() ) // This is intentionally blank, only one jn.
+ return true;
+ // If there is an i2 but it isn't on the map, then not connected.
+ if ( proxyComptMap_.find( i2 ) == proxyComptMap_.end() )
+ return false;
+ return true;
}
////////////////////////////////////////////////////////////////////
@@ -277,32 +285,32 @@ bool VoxelPoolsBase::isVoxelJunctionPresent( Id i1, Id i2 ) const
void VoxelPoolsBase::resetXreacScale( unsigned int size )
{
- xReacScaleSubstrates_.assign( size, 1.0 );
- xReacScaleProducts_.assign( size, 1.0 );
+ xReacScaleSubstrates_.assign( size, 1.0 );
+ xReacScaleProducts_.assign( size, 1.0 );
}
void VoxelPoolsBase::forwardReacVolumeFactor( unsigned int i, double volume )
{
- assert( i < xReacScaleSubstrates_.size() );
- xReacScaleSubstrates_[i] *= volume / getVolume();
- // cout << "forwardReacVolumeFactor[" << i << "] = " << xReacScaleSubstrates_[i] <<endl;
+ assert( i < xReacScaleSubstrates_.size() );
+ xReacScaleSubstrates_[i] *= volume / getVolume();
+ // cout << "forwardReacVolumeFactor[" << i << "] = " << xReacScaleSubstrates_[i] <<endl;
}
void VoxelPoolsBase::backwardReacVolumeFactor( unsigned int i, double volume )
{
- assert( i < xReacScaleProducts_.size() );
- xReacScaleProducts_[i] *= volume / getVolume();
- // cout << "backwardReacVolumeFactor[" << i << "] = "<< xReacScaleProducts_[i] <<endl;
+ assert( i < xReacScaleProducts_.size() );
+ xReacScaleProducts_[i] *= volume / getVolume();
+ // cout << "backwardReacVolumeFactor[" << i << "] = "<< xReacScaleProducts_[i] <<endl;
}
double VoxelPoolsBase::getXreacScaleSubstrates( unsigned int i ) const
{
- return xReacScaleSubstrates_[i];
+ return xReacScaleSubstrates_[i];
}
double VoxelPoolsBase::getXreacScaleProducts( unsigned int i ) const
{
- return xReacScaleProducts_[i];
+ return xReacScaleProducts_[i];
}
/**
@@ -310,88 +318,102 @@ double VoxelPoolsBase::getXreacScaleProducts( unsigned int i ) const
* are not present on current voxel.
*/
void VoxelPoolsBase::filterCrossRateTerms(
- const vector< Id >& offSolverReacs,
- const vector< pair< Id, Id > >& offSolverReacCompts )
-{
- assert (offSolverReacs.size() == offSolverReacCompts.size() );
- // unsigned int numCoreRates = stoichPtr_->getNumCoreRates();
- for ( unsigned int i = 0; i < offSolverReacCompts.size(); ++i ) {
- const pair< Id, Id >& p = offSolverReacCompts[i];
- if ( !isVoxelJunctionPresent( p.first, p.second) ) {
- Id reacId = offSolverReacs[i];
- const Cinfo* reacCinfo = reacId.element()->cinfo();
- unsigned int k = stoichPtr_->convertIdToReacIndex( offSolverReacs[i] );
- // Start by replacing the immediate cross reaction term.
- if ( rates_[k] )
- delete rates_[k];
- rates_[k] = new ExternReac;
- if ( stoichPtr_->getOneWay() ) {
- k++; // Delete the next entry too, it is the reverse reacn.
- assert( k < rates_.size() );
- if ( reacCinfo->isA( "ReacBase" ) ) {
- if ( rates_[k] )
- delete rates_[k];
- rates_[k] = new ExternReac;
- }
- if ( reacCinfo->isA( "CplxEnzBase" ) ) { // Delete next two.
- if ( rates_[k] )
- delete rates_[k];
- rates_[k] = new ExternReac;
- k++;
- assert( k < rates_.size() );
- if ( rates_[k] )
- delete rates_[k];
- rates_[k] = new ExternReac;
- }
- } else {
- if ( reacCinfo->isA( "CplxEnzBase" ) ) { // Delete next one.
- k++;
- assert( k < rates_.size() );
- if ( rates_[k] )
- delete rates_[k];
- rates_[k] = new ExternReac;
- }
- }
- }
- }
+ const vector< Id >& offSolverReacs,
+ const vector< pair< Id, Id > >& offSolverReacCompts )
+{
+ assert (offSolverReacs.size() == offSolverReacCompts.size() );
+ // unsigned int numCoreRates = stoichPtr_->getNumCoreRates();
+ for ( unsigned int i = 0; i < offSolverReacCompts.size(); ++i )
+ {
+ const pair< Id, Id >& p = offSolverReacCompts[i];
+ if ( !isVoxelJunctionPresent( p.first, p.second) )
+ {
+ Id reacId = offSolverReacs[i];
+ const Cinfo* reacCinfo = reacId.element()->cinfo();
+ unsigned int k = stoichPtr_->convertIdToReacIndex( offSolverReacs[i] );
+ // Start by replacing the immediate cross reaction term.
+ if ( rates_[k] )
+ delete rates_[k];
+ rates_[k] = new ExternReac;
+ if ( stoichPtr_->getOneWay() )
+ {
+ k++; // Delete the next entry too, it is the reverse reacn.
+ assert( k < rates_.size() );
+ if ( reacCinfo->isA( "ReacBase" ) )
+ {
+ if ( rates_[k] )
+ delete rates_[k];
+ rates_[k] = new ExternReac;
+ }
+ if ( reacCinfo->isA( "CplxEnzBase" ) ) // Delete next two.
+ {
+ if ( rates_[k] )
+ delete rates_[k];
+ rates_[k] = new ExternReac;
+ k++;
+ assert( k < rates_.size() );
+ if ( rates_[k] )
+ delete rates_[k];
+ rates_[k] = new ExternReac;
+ }
+ }
+ else
+ {
+ if ( reacCinfo->isA( "CplxEnzBase" ) ) // Delete next one.
+ {
+ k++;
+ assert( k < rates_.size() );
+ if ( rates_[k] )
+ delete rates_[k];
+ rates_[k] = new ExternReac;
+ }
+ }
+ }
+ }
}
////////////////////////////////////////////////////////////////////////
void VoxelPoolsBase::print() const
{
- cout << "S_.size=" << S_.size() << ", volume = " << volume_ << endl;
- cout << "proxyPoolsVoxels.size()=" << proxyPoolVoxels_.size() <<
- ", proxyTransferIndex.size()=" << proxyTransferIndex_.size() <<
- endl;
- assert( proxyPoolVoxels_.size() == proxyTransferIndex_.size() );
- for ( unsigned int i = 0; i < proxyPoolVoxels_.size(); ++i ) {
- cout << "ppv[" << i << "]=";
- const vector< unsigned int >& ppv = proxyPoolVoxels_[i];
- for ( unsigned int j = 0; j < ppv.size(); ++j ) {
- cout << " " << ppv[j];
- }
- cout << endl;
- }
- for ( unsigned int i = 0; i < proxyTransferIndex_.size(); ++i ) {
- cout << "pti[" << i << "]=";
- const vector< unsigned int >& pti = proxyTransferIndex_[i];
- for ( unsigned int j = 0; j < pti.size(); ++j ) {
- cout << " " << pti[j];
- }
- cout << endl;
- }
- cout <<
- "xReacScaleSubstrates.size()=" << xReacScaleSubstrates_.size() <<
- ", xReacScaleProducts.size()=" << xReacScaleProducts_.size() <<
- endl;
- assert( xReacScaleSubstrates_.size() == xReacScaleProducts_.size() );
- for ( unsigned int i = 0; i < xReacScaleSubstrates_.size(); ++i ) {
- cout << i << " " << xReacScaleSubstrates_[i] << " " <<
- xReacScaleProducts_[i] << endl;
- }
- cout << "############## RATES ######################\n";
- for ( unsigned int i = 0; i < rates_.size(); ++i ) {
- cout << i << " : " << rates_[i]->getR1() << ", " <<
- rates_[i]->getR2() << endl;
- }
+ cout << "S_.size=" << S_.size() << ", volume = " << volume_ << endl;
+ cout << "proxyPoolsVoxels.size()=" << proxyPoolVoxels_.size() <<
+ ", proxyTransferIndex.size()=" << proxyTransferIndex_.size() <<
+ endl;
+ assert( proxyPoolVoxels_.size() == proxyTransferIndex_.size() );
+ for ( unsigned int i = 0; i < proxyPoolVoxels_.size(); ++i )
+ {
+ cout << "ppv[" << i << "]=";
+ const vector< unsigned int >& ppv = proxyPoolVoxels_[i];
+ for ( unsigned int j = 0; j < ppv.size(); ++j )
+ {
+ cout << " " << ppv[j];
+ }
+ cout << endl;
+ }
+ for ( unsigned int i = 0; i < proxyTransferIndex_.size(); ++i )
+ {
+ cout << "pti[" << i << "]=";
+ const vector< unsigned int >& pti = proxyTransferIndex_[i];
+ for ( unsigned int j = 0; j < pti.size(); ++j )
+ {
+ cout << " " << pti[j];
+ }
+ cout << endl;
+ }
+ cout <<
+ "xReacScaleSubstrates.size()=" << xReacScaleSubstrates_.size() <<
+ ", xReacScaleProducts.size()=" << xReacScaleProducts_.size() <<
+ endl;
+ assert( xReacScaleSubstrates_.size() == xReacScaleProducts_.size() );
+ for ( unsigned int i = 0; i < xReacScaleSubstrates_.size(); ++i )
+ {
+ cout << i << " " << xReacScaleSubstrates_[i] << " " <<
+ xReacScaleProducts_[i] << endl;
+ }
+ cout << "############## RATES ######################\n";
+ for ( unsigned int i = 0; i < rates_.size(); ++i )
+ {
+ cout << i << " : " << rates_[i]->getR1() << ", " <<
+ rates_[i]->getR2() << endl;
+ }
}
diff --git a/mesh/NeuroNode.cpp b/mesh/NeuroNode.cpp
index 9e86634acaf067e232023a23daba1e53f2035476..9610227b2308ada7650fd9cb00e2ad9853b4cf50 100644
--- a/mesh/NeuroNode.cpp
+++ b/mesh/NeuroNode.cpp
@@ -533,6 +533,8 @@ void NeuroNode::buildSpinyTree(
void NeuroNode::setParentAndChildren( unsigned int index, int dendParent,
vector< NeuroNode >& nodes, const unordered_map< Id, unsigned int >& dendMap )
{
+ if (dendParent < 0 || static_cast< unsigned int >(dendParent) >= nodes.size() )
+ return;
parent_ = dendParent;
const unordered_map< Id, unsigned int >::const_iterator dendLookup =
dendMap.find( nodes[dendParent].elecCompt_ );
diff --git a/msg/SingleMsg.cpp b/msg/SingleMsg.cpp
index 8286e2e75414928e73192aed52c4bb328e4eab9c..c8ba6f001d952beb817fbf2e019e1b5f6230d2d8 100644
--- a/msg/SingleMsg.cpp
+++ b/msg/SingleMsg.cpp
@@ -19,48 +19,51 @@ vector< SingleMsg* > SingleMsg::msg_;
/////////////////////////////////////////////////////////////////////
SingleMsg::SingleMsg( const Eref& e1, const Eref& e2, unsigned int msgIndex)
- : Msg( ObjId( managerId_, (msgIndex != 0 ) ? msgIndex: msg_.size() ),
- e1.element(), e2.element() ),
- i1_( e1.dataIndex() ),
- i2_( e2.dataIndex() ),
- f2_( e2.fieldIndex() )
-{
- if ( msgIndex == 0 ) {
- msg_.push_back( this );
- return;
- } else if ( msg_.size() <= msgIndex ) {
- msg_.resize( msgIndex + 1 );
- }
- msg_[ msgIndex ] = this;
+ : Msg( ObjId( managerId_, (msgIndex != 0 ) ? msgIndex: msg_.size() ),
+ e1.element(), e2.element() ),
+ i1_( e1.dataIndex() ),
+ i2_( e2.dataIndex() ),
+ f2_( e2.fieldIndex() )
+{
+ if ( msgIndex == 0 )
+ {
+ msg_.push_back( this );
+ return;
+ }
+ else if ( msg_.size() <= msgIndex )
+ {
+ msg_.resize( msgIndex + 1 );
+ }
+ msg_[ msgIndex ] = this;
}
SingleMsg::~SingleMsg()
{
- assert( mid_.dataIndex < msg_.size() );
- msg_[ mid_.dataIndex ] = 0; // ensure deleted ptr isn't reused.
+ assert( mid_.dataIndex < msg_.size() );
+ msg_[ mid_.dataIndex ] = 0; // ensure deleted ptr isn't reused.
}
Eref SingleMsg::firstTgt( const Eref& src ) const
{
- if ( src.element() == e1_ )
- return Eref( e2_, i2_, f2_ );
- else if ( src.element() == e2_ )
- return Eref( e1_, i1_ );
- return Eref( 0, 0 );
+ if ( src.element() == e1_ )
+ return Eref( e2_, i2_, f2_ );
+ else if ( src.element() == e2_ )
+ return Eref( e1_, i1_ );
+ return Eref( 0, 0 );
}
void SingleMsg::sources( vector< vector< Eref > >& v ) const
{
- v.clear();
- v.resize( e2_->numData() );
- v[i2_].resize( 1, Eref( e1_, i1_ ) );
+ v.clear();
+ v.resize( e2_->numData() );
+ v[i2_].resize( 1, Eref( e1_, i1_ ) );
}
void SingleMsg::targets( vector< vector< Eref > >& v ) const
{
- v.clear();
- v.resize( e1_->numData() );
- v[i1_].resize( 1, Eref( e2_, i2_, f2_ ) );
+ v.clear();
+ v.resize( e1_->numData() );
+ v[i1_].resize( 1, Eref( e2_, i2_, f2_ ) );
}
@@ -77,54 +80,65 @@ bool SingleMsg::isMsgHere( const Qinfo& q ) const
DataId SingleMsg::i1() const
{
- return i1_;
+ return i1_;
}
DataId SingleMsg::i2() const
{
- return i2_;
+ return i2_;
}
Id SingleMsg::managerId() const
{
- return SingleMsg::managerId_;
+ return SingleMsg::managerId_;
}
ObjId SingleMsg::findOtherEnd( ObjId f ) const
{
- if ( f.element() == e1() ) {
- if ( f.dataIndex == i1_ )
- return ObjId( e2()->id(), i2_ );
- } else if ( f.element() == e2() ) {
- if ( f.dataIndex == i2_ )
- return ObjId( e1()->id(), i1_ );
- }
- return ObjId( 0, BADINDEX );
+ if ( f.element() == e1() )
+ {
+ if ( f.dataIndex == i1_ )
+ return ObjId( e2()->id(), i2_ );
+ }
+ else if ( f.element() == e2() )
+ {
+ if ( f.dataIndex == i2_ )
+ return ObjId( e1()->id(), i1_ );
+ }
+ return ObjId( 0, BADINDEX );
}
Msg* SingleMsg::copy( Id origSrc, Id newSrc, Id newTgt,
- FuncId fid, unsigned int b, unsigned int n ) const
-{
- const Element* orig = origSrc.element();
- if ( n <= 1 ) {
- SingleMsg* ret = 0;
- if ( orig == e1() ) {
- ret = new SingleMsg( Eref( newSrc.element(), i1_ ),
- Eref( newTgt.element(), i2_, f2_ ), 0 );
- ret->e1()->addMsgAndFunc( ret->mid(), fid, b );
- } else if ( orig == e2() ) {
- ret = new SingleMsg( Eref( newTgt.element(), i1_ ),
- Eref( newSrc.element(), i2_, f2_ ), 0 );
- ret->e2()->addMsgAndFunc( ret->mid(), fid, b );
- } else {
- assert( 0 );
- }
- return ret;
- } else {
- // Here we need a SliceMsg which goes from one 2-d array to another.
- cout << "Error: SingleMsg::copy: SliceMsg not yet implemented\n";
- return 0;
- }
+ FuncId fid, unsigned int b, unsigned int n ) const
+{
+ const Element* orig = origSrc.element();
+ if ( n <= 1 )
+ {
+ SingleMsg* ret = 0;
+ if ( orig == e1() )
+ {
+ ret = new SingleMsg( Eref( newSrc.element(), i1_ ),
+ Eref( newTgt.element(), i2_, f2_ ), 0 );
+ ret->e1()->addMsgAndFunc( ret->mid(), fid, b );
+ }
+ else if ( orig == e2() )
+ {
+ ret = new SingleMsg( Eref( newTgt.element(), i1_ ),
+ Eref( newSrc.element(), i2_, f2_ ), 0 );
+ ret->e2()->addMsgAndFunc( ret->mid(), fid, b );
+ }
+ else
+ {
+ assert( 0 );
+ }
+ return ret;
+ }
+ else
+ {
+ // Here we need a SliceMsg which goes from one 2-d array to another.
+ cout << "Error: SingleMsg::copy: SliceMsg not yet implemented\n";
+ return 0;
+ }
}
///////////////////////////////////////////////////////////////////////
@@ -133,37 +147,38 @@ Msg* SingleMsg::copy( Id origSrc, Id newSrc, Id newTgt,
const Cinfo* SingleMsg::initCinfo()
{
- ///////////////////////////////////////////////////////////////////
- // Field definitions.
- ///////////////////////////////////////////////////////////////////
- static ValueFinfo< SingleMsg, DataId > index1(
- "i1",
- "Index of source object.",
- &SingleMsg::setI1,
- &SingleMsg::getI1
- );
- static ValueFinfo< SingleMsg, DataId > index2(
- "i2",
- "Index of dest object.",
- &SingleMsg::setI2,
- &SingleMsg::getI2
- );
-
- static Finfo* singleMsgFinfos[] = {
- &index1, // value
- &index2, // value
- };
-
- static Dinfo< short > dinfo;
- static Cinfo singleMsgCinfo (
- "SingleMsg", // name
- Msg::initCinfo(), // base class
- singleMsgFinfos,
- sizeof( singleMsgFinfos ) / sizeof( Finfo* ), // num Fields
- &dinfo
- );
-
- return &singleMsgCinfo;
+ ///////////////////////////////////////////////////////////////////
+ // Field definitions.
+ ///////////////////////////////////////////////////////////////////
+ static ValueFinfo< SingleMsg, DataId > index1(
+ "i1",
+ "Index of source object.",
+ &SingleMsg::setI1,
+ &SingleMsg::getI1
+ );
+ static ValueFinfo< SingleMsg, DataId > index2(
+ "i2",
+ "Index of dest object.",
+ &SingleMsg::setI2,
+ &SingleMsg::getI2
+ );
+
+ static Finfo* singleMsgFinfos[] =
+ {
+ &index1, // value
+ &index2, // value
+ };
+
+ static Dinfo< short > dinfo;
+ static Cinfo singleMsgCinfo (
+ "SingleMsg", // name
+ Msg::initCinfo(), // base class
+ singleMsgFinfos,
+ sizeof( singleMsgFinfos ) / sizeof( Finfo* ), // num Fields
+ &dinfo
+ );
+
+ return &singleMsgCinfo;
}
static const Cinfo* singleMsgCinfo = SingleMsg::initCinfo();
@@ -171,48 +186,48 @@ static const Cinfo* singleMsgCinfo = SingleMsg::initCinfo();
DataId SingleMsg::getI1() const
{
- return i1_;
+ return i1_;
}
void SingleMsg::setI1( DataId di )
{
- i1_ = di;
- e1()->markRewired();
- e2()->markRewired();
+ i1_ = di;
+ e1()->markRewired();
+ e2()->markRewired();
}
DataId SingleMsg::getI2() const
{
- return i2_;
+ return i2_;
}
void SingleMsg::setI2( DataId di )
{
- i2_ = di;
- e1()->markRewired();
- e2()->markRewired();
+ i2_ = di;
+ e1()->markRewired();
+ e2()->markRewired();
}
void SingleMsg::setTargetField( unsigned int f )
{
- f2_ = f;
- e1()->markRewired();
+ f2_ = f;
+ e1()->markRewired();
}
unsigned int SingleMsg::getTargetField() const
{
- return f2_;
+ return f2_;
}
/// Static function for Msg access
unsigned int SingleMsg::numMsg()
{
- return msg_.size();
+ return msg_.size();
}
/// Static function for Msg access
char* SingleMsg::lookupMsg( unsigned int index )
{
- assert( index < msg_.size() );
- return reinterpret_cast< char* >( msg_[index] );
+ assert( index < msg_.size() );
+ return reinterpret_cast< char* >( msg_[index] );
}
diff --git a/msg/SparseMsg.cpp b/msg/SparseMsg.cpp
index 7511aa0f50a3bd437011e33bf60d66576d7e974b..0196ed30df92d83c61b7802f9615d1e557583778 100644
--- a/msg/SparseMsg.cpp
+++ b/msg/SparseMsg.cpp
@@ -7,11 +7,11 @@
** See the file COPYING.LIB for the full notice.
**********************************************************************/
-#include "header.h"
-#include "SparseMatrix.h"
-#include "SparseMsg.h"
-#include "../randnum/randnum.h"
+#include "../basecode/header.h"
+#include "../basecode/global.h"
#include "../shell/Shell.h"
+#include "../basecode/SparseMatrix.h"
+#include "SparseMsg.h"
// Initializing static variables
Id SparseMsg::managerId_;
@@ -23,34 +23,34 @@ vector< SparseMsg* > SparseMsg::msg_;
const Cinfo* SparseMsg::initCinfo()
{
- ///////////////////////////////////////////////////////////////////
- // Field definitions.
- ///////////////////////////////////////////////////////////////////
- static ReadOnlyValueFinfo< SparseMsg, unsigned int > numRows(
- "numRows",
- "Number of rows in matrix.",
- &SparseMsg::getNumRows
- );
- static ReadOnlyValueFinfo< SparseMsg, unsigned int > numColumns(
- "numColumns",
- "Number of columns in matrix.",
- &SparseMsg::getNumColumns
- );
- static ReadOnlyValueFinfo< SparseMsg, unsigned int > numEntries(
- "numEntries",
- "Number of Entries in matrix.",
- &SparseMsg::getNumEntries
- );
-
- static ValueFinfo< SparseMsg, vector< unsigned int > > connectionList(
- "connectionList",
- "Pairwise specification of connection matrix where each x,y value "
- "represents a connection from src[x] to dest[y]. "
- "The (x,y) entries are ordered in a single vector as \n"
- "(x0, x1,... x_n-1, y0, y1,... y_n-1)\n",
- &SparseMsg::setEntryPairs,
- &SparseMsg::getEntryPairs
- );
+ ///////////////////////////////////////////////////////////////////
+ // Field definitions.
+ ///////////////////////////////////////////////////////////////////
+ static ReadOnlyValueFinfo< SparseMsg, unsigned int > numRows(
+ "numRows",
+ "Number of rows in matrix.",
+ &SparseMsg::getNumRows
+ );
+ static ReadOnlyValueFinfo< SparseMsg, unsigned int > numColumns(
+ "numColumns",
+ "Number of columns in matrix.",
+ &SparseMsg::getNumColumns
+ );
+ static ReadOnlyValueFinfo< SparseMsg, unsigned int > numEntries(
+ "numEntries",
+ "Number of Entries in matrix.",
+ &SparseMsg::getNumEntries
+ );
+
+ static ValueFinfo< SparseMsg, vector< unsigned int > > connectionList(
+ "connectionList",
+ "Pairwise specification of connection matrix where each x,y value "
+ "represents a connection from src[x] to dest[y]. "
+ "The (x,y) entries are ordered in a single vector as \n"
+ "(x0, x1,... x_n-1, y0, y1,... y_n-1)\n",
+ &SparseMsg::setEntryPairs,
+ &SparseMsg::getEntryPairs
+ );
/// Connection matrix entries to manipulate in Python.
static ReadOnlyValueFinfo< SparseMsg, vector< unsigned int > >
@@ -76,106 +76,107 @@ const Cinfo* SparseMsg::initCinfo()
&SparseMsg::getRowStart
);
- static ValueFinfo< SparseMsg, double > probability(
- "probability",
- "connection probability for random connectivity.",
- &SparseMsg::setProbability,
- &SparseMsg::getProbability
- );
+ static ValueFinfo< SparseMsg, double > probability(
+ "probability",
+ "connection probability for random connectivity.",
+ &SparseMsg::setProbability,
+ &SparseMsg::getProbability
+ );
- static ValueFinfo< SparseMsg, long > seed(
- "seed",
- "Random number seed for generating probabilistic connectivity.",
- &SparseMsg::setSeed,
- &SparseMsg::getSeed
- );
+ static ValueFinfo< SparseMsg, unsigned long > seed(
+ "seed",
+ "Random number seed for generating probabilistic connectivity.",
+ &SparseMsg::setSeed,
+ &SparseMsg::getSeed
+ );
////////////////////////////////////////////////////////////////////////
// DestFinfos
////////////////////////////////////////////////////////////////////////
- static DestFinfo setRandomConnectivity( "setRandomConnectivity",
- "Assigns connectivity with specified probability and seed",
- new OpFunc2< SparseMsg, double, long >(
- &SparseMsg::setRandomConnectivity ) );
-
- static DestFinfo setEntry( "setEntry",
- "Assigns single row,column value",
- new OpFunc3< SparseMsg, unsigned int, unsigned int, unsigned int >(
- &SparseMsg::setEntry ) );
-
- static DestFinfo unsetEntry( "unsetEntry",
- "Clears single row,column entry",
- new OpFunc2< SparseMsg, unsigned int, unsigned int >(
- &SparseMsg::unsetEntry ) );
-
- static DestFinfo clear( "clear",
- "Clears out the entire matrix",
- new OpFunc0< SparseMsg >(
- &SparseMsg::clear ) );
-
- static DestFinfo transpose( "transpose",
- "Transposes the sparse matrix",
- new OpFunc0< SparseMsg >(
- &SparseMsg::transpose ) );
-
- static DestFinfo pairFill( "pairFill",
- "Fills entire matrix using pairs of (x,y) indices to indicate "
- "presence of a connection. If the target is a FieldElement it"
- "automagically assigns FieldIndices.",
- new OpFunc2< SparseMsg,
- vector< unsigned int >, vector< unsigned int> >(
- &SparseMsg::pairFill ) );
-
- static DestFinfo tripletFill( "tripletFill",
- "Fills entire matrix using triplets of (x,y,fieldIndex) to fully "
- "specify every connection in the sparse matrix.",
- new OpFunc3< SparseMsg,
- vector< unsigned int >, vector< unsigned int>,
- vector< unsigned int > >(
- &SparseMsg::tripletFill ) );
-
- static DestFinfo tripletFill1( "tripletFill1",
- "Single contiguous array to fill entire connection matrix using "
- "triplets of (x,y, fieldindex) ordered as \n"
- "(x0, x1,... xn-1, y0, y1,... yn-1, fi0, fi1,... fi_n-1)\n",
- new OpFunc1< SparseMsg, vector< unsigned int > >(
- &SparseMsg::tripletFill1 ) );
+ static DestFinfo setRandomConnectivity( "setRandomConnectivity",
+ "Assigns connectivity with specified probability and seed",
+ new OpFunc2< SparseMsg, double, long >(
+ &SparseMsg::setRandomConnectivity ) );
+
+ static DestFinfo setEntry( "setEntry",
+ "Assigns single row,column value",
+ new OpFunc3< SparseMsg, unsigned int, unsigned int, unsigned int >(
+ &SparseMsg::setEntry ) );
+
+ static DestFinfo unsetEntry( "unsetEntry",
+ "Clears single row,column entry",
+ new OpFunc2< SparseMsg, unsigned int, unsigned int >(
+ &SparseMsg::unsetEntry ) );
+
+ static DestFinfo clear( "clear",
+ "Clears out the entire matrix",
+ new OpFunc0< SparseMsg >(
+ &SparseMsg::clear ) );
+
+ static DestFinfo transpose( "transpose",
+ "Transposes the sparse matrix",
+ new OpFunc0< SparseMsg >(
+ &SparseMsg::transpose ) );
+
+ static DestFinfo pairFill( "pairFill",
+ "Fills entire matrix using pairs of (x,y) indices to indicate "
+ "presence of a connection. If the target is a FieldElement it"
+ "automagically assigns FieldIndices.",
+ new OpFunc2< SparseMsg,
+ vector< unsigned int >, vector< unsigned int> >(
+ &SparseMsg::pairFill ) );
+
+ static DestFinfo tripletFill( "tripletFill",
+ "Fills entire matrix using triplets of (x,y,fieldIndex) to fully "
+ "specify every connection in the sparse matrix.",
+ new OpFunc3< SparseMsg,
+ vector< unsigned int >, vector< unsigned int>,
+ vector< unsigned int > >(
+ &SparseMsg::tripletFill ) );
+
+ static DestFinfo tripletFill1( "tripletFill1",
+ "Single contiguous array to fill entire connection matrix using "
+ "triplets of (x,y, fieldindex) ordered as \n"
+ "(x0, x1,... xn-1, y0, y1,... yn-1, fi0, fi1,... fi_n-1)\n",
+ new OpFunc1< SparseMsg, vector< unsigned int > >(
+ &SparseMsg::tripletFill1 ) );
////////////////////////////////////////////////////////////////////////
// Assemble it all.
////////////////////////////////////////////////////////////////////////
- static Finfo* sparseMsgFinfos[] = {
- &numRows, // readonly value
- &numColumns, // readonly value
- &numEntries, // readonly value
- &connectionList, // value
- &matrixEntry, // ReadOnlyValue
- &columnIndex, // ReadOnlyValue
- &rowStart, // ReadOnlyValue
- &probability, // value
- &seed, // value
- &setRandomConnectivity, // dest
- &setEntry, // dest
- &unsetEntry, //dest
- &clear, //dest
- &transpose, //dest
- &pairFill, //dest
- &tripletFill, //dest
- &tripletFill1, //dest
- };
-
- static Dinfo< short > dinfo;
- static Cinfo sparseMsgCinfo (
- "SparseMsg", // name
- Msg::initCinfo(), // base class
- sparseMsgFinfos,
- sizeof( sparseMsgFinfos ) / sizeof( Finfo* ), // num Fields
- &dinfo
- );
-
- return &sparseMsgCinfo;
+ static Finfo* sparseMsgFinfos[] =
+ {
+ &numRows, // readonly value
+ &numColumns, // readonly value
+ &numEntries, // readonly value
+ &connectionList, // value
+ &matrixEntry, // ReadOnlyValue
+ &columnIndex, // ReadOnlyValue
+ &rowStart, // ReadOnlyValue
+ &probability, // value
+ &seed, // value
+ &setRandomConnectivity, // dest
+ &setEntry, // dest
+ &unsetEntry, //dest
+ &clear, //dest
+ &transpose, //dest
+ &pairFill, //dest
+ &tripletFill, //dest
+ &tripletFill1, //dest
+ };
+
+ static Dinfo< short > dinfo;
+ static Cinfo sparseMsgCinfo (
+ "SparseMsg", // name
+ Msg::initCinfo(), // base class
+ sparseMsgFinfos,
+ sizeof( sparseMsgFinfos ) / sizeof( Finfo* ), // num Fields
+ &dinfo
+ );
+
+ return &sparseMsgCinfo;
}
static const Cinfo* sparseMsgCinfo = SparseMsg::initCinfo();
@@ -185,41 +186,44 @@ static const Cinfo* sparseMsgCinfo = SparseMsg::initCinfo();
//////////////////////////////////////////////////////////////////
void SparseMsg::setProbability ( double probability )
{
- p_ = probability;
- mtseed( seed_ );
- randomConnect( probability );
+ p_ = probability;
+ randomConnect( probability );
}
double SparseMsg::getProbability ( ) const
{
- return p_;
+ return p_;
}
-void SparseMsg::setSeed ( long seed )
+void SparseMsg::setSeed ( unsigned long seed )
{
- seed_ = seed;
- mtseed( seed_ );
- randomConnect( p_ );
+ if( seed > 0 )
+ seed_ = seed;
+ else
+ seed_ = rd_();
+
+ rng_.seed( seed_ );
+ randomConnect( p_ );
}
-long SparseMsg::getSeed () const
+unsigned long SparseMsg::getSeed () const
{
- return seed_;
+ return seed_;
}
unsigned int SparseMsg::getNumRows() const
{
- return matrix_.nRows();
+ return matrix_.nRows();
}
unsigned int SparseMsg::getNumColumns() const
{
- return matrix_.nColumns();
+ return matrix_.nColumns();
}
unsigned int SparseMsg::getNumEntries() const
{
- return matrix_.nEntries();
+ return matrix_.nEntries();
}
vector< unsigned int > SparseMsg::getMatrixEntry() const
@@ -239,24 +243,25 @@ vector< unsigned int > SparseMsg::getRowStart() const
void SparseMsg::setEntryPairs( vector< unsigned int > v )
{
- vector< unsigned int > src( v.begin(), v.begin() + v.size()/2 );
- vector< unsigned int > dest( v.begin() + v.size()/2, v.end() );
- pairFill( src, dest );
+ vector< unsigned int > src( v.begin(), v.begin() + v.size()/2 );
+ vector< unsigned int > dest( v.begin() + v.size()/2, v.end() );
+ pairFill( src, dest );
}
vector< unsigned int > SparseMsg::getEntryPairs() const
{
- vector< unsigned int > cols = matrix_.colIndex();
- vector< unsigned int > y;
- for ( unsigned int row = 0; row < matrix_.nRows(); ++row ) {
- unsigned int begin = matrix_.rowStart()[row];
- unsigned int end = matrix_.rowStart()[row+1];
- for ( unsigned int j = begin; j < end; ++j )
- y.push_back( row );
- }
- assert( cols.size() == y.size() );
- y.insert( y.end(), cols.begin(), cols.end() );
- return y;
+ vector< unsigned int > cols = matrix_.colIndex();
+ vector< unsigned int > y;
+ for ( unsigned int row = 0; row < matrix_.nRows(); ++row )
+ {
+ unsigned int begin = matrix_.rowStart()[row];
+ unsigned int end = matrix_.rowStart()[row+1];
+ for ( unsigned int j = begin; j < end; ++j )
+ y.push_back( row );
+ }
+ assert( cols.size() == y.size() );
+ y.insert( y.end(), cols.begin(), cols.end() );
+ return y;
}
//////////////////////////////////////////////////////////////////
@@ -265,109 +270,115 @@ vector< unsigned int > SparseMsg::getEntryPairs() const
void SparseMsg::setRandomConnectivity( double probability, long seed )
{
- p_ = probability;
- seed_ = seed;
- mtseed( seed );
- randomConnect( probability );
+ p_ = probability;
+ rng_.seed( seed );
+ randomConnect( probability );
}
void SparseMsg::setEntry(
- unsigned int row, unsigned int column, unsigned int value )
+ unsigned int row, unsigned int column, unsigned int value )
{
- matrix_.set( row, column, value );
+ matrix_.set( row, column, value );
}
void SparseMsg::unsetEntry( unsigned int row, unsigned int column )
{
- matrix_.unset( row, column );
+ matrix_.unset( row, column );
}
void SparseMsg::clear()
{
- matrix_.clear();
+ matrix_.clear();
}
void SparseMsg::transpose()
{
- matrix_.transpose();
- e1()->markRewired();
- e2()->markRewired();
+ matrix_.transpose();
+ e1()->markRewired();
+ e2()->markRewired();
}
void SparseMsg::updateAfterFill()
{
- unsigned int startData = e2_->localDataStart();
- unsigned int endData = startData + e2_->numLocalData();
- SparseMatrix< unsigned int > temp( matrix_);
- temp.transpose();
- for ( unsigned int i = 0; i < temp.nRows(); ++ i ) {
- const unsigned int* colIndex;
- const unsigned int* entry;
- unsigned int num = temp.getRow( i, &entry, &colIndex );
- if ( i >= startData && i < endData ) {
- // Inefficient. Better to do it in one pass after getting
- // the max num
- e2_->resizeField( i - startData, num + 1 );
- }
- }
- e1()->markRewired();
- e2()->markRewired();
+ unsigned int startData = e2_->localDataStart();
+ unsigned int endData = startData + e2_->numLocalData();
+ SparseMatrix< unsigned int > temp( matrix_);
+ temp.transpose();
+ for ( unsigned int i = 0; i < temp.nRows(); ++ i )
+ {
+ const unsigned int* colIndex;
+ const unsigned int* entry;
+ unsigned int num = temp.getRow( i, &entry, &colIndex );
+ if ( i >= startData && i < endData )
+ {
+ // Inefficient. Better to do it in one pass after getting
+ // the max num
+ e2_->resizeField( i - startData, num + 1 );
+ }
+ }
+ e1()->markRewired();
+ e2()->markRewired();
}
void SparseMsg::pairFill( vector< unsigned int > src,
- vector< unsigned int> dest )
-{
- // Sanity check
- vector< unsigned int >::const_iterator i;
- for ( i = src.begin(); i != src.end(); ++i ) {
- if (*i >= e1()->numData() ) {
- cout << "Warning: SparseMsg::pairFill: Src index " << *i <<
- " exceeds Src array size " << e1()->numData() <<
- ". Aborting\n";
- return;
- }
- }
- for ( i = dest.begin(); i != dest.end(); ++i ) {
- if (*i >= e2()->numData() ) {
- cout << "Warning: SparseMsg::pairFill: Dest index " << *i <<
- " exceeds Dest array size " << e2()->numData() <<
- ". Aborting\n";
- return;
- }
- }
-
- vector< unsigned int > numAtDest( dest.size(), 0 );
- vector< unsigned int > fieldIndex( dest.size(), 0 );
- for ( unsigned int i = 0; i < dest.size(); ++i ) {
- fieldIndex[i] = numAtDest[ dest[i] ];
- // Could do on previous line, but clarity
- ++numAtDest[ dest[i] ];
- }
-
- /**
- * We set retainSize flag to true since the # of src/dest objects
- * doesn't change. We can explicitly assign it elsewhere if needed.
- */
- matrix_.tripletFill( src, dest, fieldIndex, true );
- updateAfterFill();
+ vector< unsigned int> dest )
+{
+ // Sanity check
+ vector< unsigned int >::const_iterator i;
+ for ( i = src.begin(); i != src.end(); ++i )
+ {
+ if (*i >= e1()->numData() )
+ {
+ cout << "Warning: SparseMsg::pairFill: Src index " << *i <<
+ " exceeds Src array size " << e1()->numData() <<
+ ". Aborting\n";
+ return;
+ }
+ }
+ for ( i = dest.begin(); i != dest.end(); ++i )
+ {
+ if (*i >= e2()->numData() )
+ {
+ cout << "Warning: SparseMsg::pairFill: Dest index " << *i <<
+ " exceeds Dest array size " << e2()->numData() <<
+ ". Aborting\n";
+ return;
+ }
+ }
+
+ vector< unsigned int > numAtDest( dest.size(), 0 );
+ vector< unsigned int > fieldIndex( dest.size(), 0 );
+ for ( unsigned int i = 0; i < dest.size(); ++i )
+ {
+ fieldIndex[i] = numAtDest[ dest[i] ];
+ // Could do on previous line, but clarity
+ ++numAtDest[ dest[i] ];
+ }
+
+ /**
+ * We set retainSize flag to true since the # of src/dest objects
+ * doesn't change. We can explicitly assign it elsewhere if needed.
+ */
+ matrix_.tripletFill( src, dest, fieldIndex, true );
+ updateAfterFill();
}
void SparseMsg::tripletFill( vector< unsigned int > src,
- vector< unsigned int> destDataIndex,
- vector< unsigned int> destFieldIndex )
+ vector< unsigned int> destDataIndex,
+ vector< unsigned int> destFieldIndex )
{
- // We set retainSize flag to true
- matrix_.tripletFill( src, destDataIndex, destFieldIndex, true );
- updateAfterFill();
+ // We set retainSize flag to true
+ matrix_.tripletFill( src, destDataIndex, destFieldIndex, true );
+ updateAfterFill();
}
void SparseMsg::tripletFill1( vector< unsigned int > v )
{
- unsigned int s3 = v.size() / 3;
- vector< unsigned int > src( v.begin(), v.begin() + s3 );
- vector< unsigned int > dest( v.begin() + s3, v.begin() + 2 * s3 );
- vector< unsigned int > fieldIndex( v.begin() + 2 * s3, v.end() );
- tripletFill( src, dest, fieldIndex );
+ unsigned int s3 = v.size() / 3;
+ vector< unsigned int > src( v.begin(), v.begin() + s3 );
+ vector< unsigned int > dest( v.begin() + s3, v.begin() + 2 * s3 );
+ vector< unsigned int > fieldIndex( v.begin() + 2 * s3, v.end() );
+ tripletFill( src, dest, fieldIndex );
}
//////////////////////////////////////////////////////////////////
@@ -376,59 +387,70 @@ void SparseMsg::tripletFill1( vector< unsigned int > v )
SparseMsg::SparseMsg( Element* e1, Element* e2, unsigned int msgIndex )
- : Msg( ObjId( managerId_, (msgIndex != 0) ? msgIndex: msg_.size() ),
- e1, e2 ),
- numThreads_( 1 ),
- nrows_( 0 ),
- p_( 0.0 ), seed_( 0 )
-{
- unsigned int nrows = 0;
- unsigned int ncolumns = 0;
- nrows = e1->numData();
- ncolumns = e2->numData();
- matrix_.setSize( nrows, ncolumns );
- if ( msgIndex == 0 ) {
- msg_.push_back( this );
- } else {
- if ( msg_.size() <= msgIndex )
- msg_.resize( msgIndex + 1 );
- msg_[ msgIndex ] = this;
- }
-
- // cout << Shell::myNode() << ": SparseMsg constructor between " << e1->getName() << " and " << e2->getName() << endl;
+ : Msg( ObjId( managerId_, (msgIndex != 0) ? msgIndex: msg_.size() ),
+ e1, e2 ),
+ numThreads_( 1 ),
+ nrows_( 0 ),
+ p_( 0.0 ), seed_( 0 )
+{
+ unsigned int nrows = 0;
+ unsigned int ncolumns = 0;
+ nrows = e1->numData();
+ ncolumns = e2->numData();
+ matrix_.setSize( nrows, ncolumns );
+ if ( msgIndex == 0 )
+ {
+ msg_.push_back( this );
+ }
+ else
+ {
+ if ( msg_.size() <= msgIndex )
+ msg_.resize( msgIndex + 1 );
+ msg_[ msgIndex ] = this;
+ }
+
+ // cout << Shell::myNode() << ": SparseMsg constructor between " << e1->getName() << " and " << e2->getName() << endl;
+
+ // Init rng with random device.
+ if( seed_ == 0 )
+ rng_.seed( rd_() );
}
SparseMsg::~SparseMsg()
{
- assert( mid_.dataIndex < msg_.size() );
- msg_[ mid_.dataIndex ] = 0; // ensure deleted ptr isn't reused.
+ assert( mid_.dataIndex < msg_.size() );
+ msg_[ mid_.dataIndex ] = 0; // ensure deleted ptr isn't reused.
}
unsigned int rowIndex( const Element* e, const DataId& d )
{
- // FieldDataHandlerBase* fdh = dynamic_cast< FieldDataHandlerBase* >( e->dataHandler() );
+ // FieldDataHandlerBase* fdh = dynamic_cast< FieldDataHandlerBase* >( e->dataHandler() );
- return d;
+ return d;
}
Eref SparseMsg::firstTgt( const Eref& src ) const
{
- if ( matrix_.nEntries() == 0 )
- return Eref( 0, 0 );
-
- if ( src.element() == e1_ ) {
- const unsigned int* fieldIndex;
- const unsigned int* colIndex;
- unsigned int n = matrix_.getRow( src.dataIndex(),
- &fieldIndex, &colIndex );
- if ( n != 0 ) {
- return Eref( e2_, colIndex[0], fieldIndex[0] );
- }
- } else if ( src.element() == e2_ ) {
- return Eref( e1_, 0 );
- }
- return Eref( 0, 0 );
+ if ( matrix_.nEntries() == 0 )
+ return Eref( 0, 0 );
+
+ if ( src.element() == e1_ )
+ {
+ const unsigned int* fieldIndex;
+ const unsigned int* colIndex;
+ unsigned int n = matrix_.getRow( src.dataIndex(),
+ &fieldIndex, &colIndex );
+ if ( n != 0 )
+ {
+ return Eref( e2_, colIndex[0], fieldIndex[0] );
+ }
+ }
+ else if ( src.element() == e2_ )
+ {
+ return Eref( e1_, 0 );
+ }
+ return Eref( 0, 0 );
}
/**
@@ -442,163 +464,184 @@ Eref SparseMsg::firstTgt( const Eref& src ) const
*/
unsigned int SparseMsg::randomConnect( double probability )
{
- unsigned int nRows = matrix_.nRows(); // Sources
- unsigned int nCols = matrix_.nColumns(); // Destinations
- matrix_.clear();
- unsigned int totalSynapses = 0;
- vector< unsigned int > sizes( nCols, 0 );
- unsigned int totSynNum = 0;
- Element* syn = e2_;
- unsigned int startData = syn->localDataStart();
- unsigned int endData = startData + syn->numLocalData();
-
- assert( nCols == syn->numData() );
-
- matrix_.transpose();
- for ( unsigned int i = 0; i < nCols; ++i ) {
- vector< unsigned int > synIndex;
- // This needs to be obtained from current size of syn array.
- // unsigned int synNum = sizes[ i ];
- unsigned int synNum = 0;
- for ( unsigned int j = 0; j < nRows; ++j ) {
- double r = mtrand(); // Want to ensure it is called each time round the loop.
- if ( r < probability ) {
- synIndex.push_back( synNum );
- ++synNum;
- ++totSynNum;
- } else {
- synIndex.push_back( ~0 );
- }
- }
-
- if ( i >= startData && i < endData ) {
- e2_->resizeField( i - startData, synNum );
- }
- totalSynapses += synNum;
- matrix_.addRow( i, synIndex );
- /*
- * This is the correct form, but I need to implement something
- * to check up for target nodes in order to use this.
- if ( i >= startData && i < endData ) {
- e2_->resizeField( i - startData, synNum );
- totalSynapses += synNum;
- matrix_.addRow( i, synIndex );
- } else {
- synIndex.resize( 0 );
- synIndex.assign( nRows, ~0 );
- matrix_.addRow( i, synIndex );
- }
- */
- }
-
- matrix_.transpose();
- // cout << Shell::myNode() << ": sizes.size() = " << sizes.size() << ", ncols = " << nCols << ", startSynapse = " << startSynapse << endl;
- e1()->markRewired();
- e2()->markRewired();
- return totalSynapses;
+ unsigned int nRows = matrix_.nRows(); // Sources
+ unsigned int nCols = matrix_.nColumns(); // Destinations
+ matrix_.clear();
+ unsigned int totalSynapses = 0;
+ vector< unsigned int > sizes( nCols, 0 );
+ unsigned int totSynNum = 0;
+ Element* syn = e2_;
+ unsigned int startData = syn->localDataStart();
+ unsigned int endData = startData + syn->numLocalData();
+
+ assert( nCols == syn->numData() );
+
+ matrix_.transpose();
+ for ( unsigned int i = 0; i < nCols; ++i )
+ {
+ vector< unsigned int > synIndex;
+ // This needs to be obtained from current size of syn array.
+ // unsigned int synNum = sizes[ i ];
+ unsigned int synNum = 0;
+ for ( unsigned int j = 0; j < nRows; ++j )
+ {
+ double r = dist_( rng_ ); // Want to ensure it is called each time round the loop.
+ if ( r < probability )
+ {
+ synIndex.push_back( synNum );
+ ++synNum;
+ ++totSynNum;
+ }
+ else
+ {
+ synIndex.push_back( ~0 );
+ }
+ }
+
+ if ( i >= startData && i < endData )
+ {
+ e2_->resizeField( i - startData, synNum );
+ }
+ totalSynapses += synNum;
+ matrix_.addRow( i, synIndex );
+ /*
+ * This is the correct form, but I need to implement something
+ * to check up for target nodes in order to use this.
+ if ( i >= startData && i < endData ) {
+ e2_->resizeField( i - startData, synNum );
+ totalSynapses += synNum;
+ matrix_.addRow( i, synIndex );
+ } else {
+ synIndex.resize( 0 );
+ synIndex.assign( nRows, ~0 );
+ matrix_.addRow( i, synIndex );
+ }
+ */
+ }
+
+ matrix_.transpose();
+ // cout << Shell::myNode() << ": sizes.size() = " << sizes.size() << ", ncols = " << nCols << ", startSynapse = " << startSynapse << endl;
+ e1()->markRewired();
+ e2()->markRewired();
+ return totalSynapses;
}
Id SparseMsg::managerId() const
{
- return SparseMsg::managerId_;
+ return SparseMsg::managerId_;
}
void SparseMsg::setMatrix( const SparseMatrix< unsigned int >& m )
{
- matrix_ = m;
+ matrix_ = m;
}
SparseMatrix< unsigned int >& SparseMsg::getMatrix( )
{
- return matrix_;
+ return matrix_;
}
ObjId SparseMsg::findOtherEnd( ObjId f ) const
{
- if ( f.element() == e1() ) {
- const unsigned int* entry;
- const unsigned int* colIndex;
- unsigned int num = matrix_.getRow( f.dataIndex, &entry, &colIndex );
- if ( num > 0 ) { // Return the first matching entry.
- return ObjId( e2()->id(), colIndex[0] );
- }
- return ObjId( 0, BADINDEX );
- } else if ( f.element() == e2() ) { // Bad! Slow! Avoid!
- vector< unsigned int > entry;
- vector< unsigned int > rowIndex;
- unsigned int num = matrix_.getColumn( f.dataIndex, entry, rowIndex );
- if ( num > 0 ) { // Return the first matching entry.
- return ObjId( e1()->id(), DataId( rowIndex[0] ) );
- }
- }
- return ObjId( 0, BADINDEX );
+ if ( f.element() == e1() )
+ {
+ const unsigned int* entry;
+ const unsigned int* colIndex;
+ unsigned int num = matrix_.getRow( f.dataIndex, &entry, &colIndex );
+ if ( num > 0 ) // Return the first matching entry.
+ {
+ return ObjId( e2()->id(), colIndex[0] );
+ }
+ return ObjId( 0, BADINDEX );
+ }
+ else if ( f.element() == e2() ) // Bad! Slow! Avoid!
+ {
+ vector< unsigned int > entry;
+ vector< unsigned int > rowIndex;
+ unsigned int num = matrix_.getColumn( f.dataIndex, entry, rowIndex );
+ if ( num > 0 ) // Return the first matching entry.
+ {
+ return ObjId( e1()->id(), DataId( rowIndex[0] ) );
+ }
+ }
+ return ObjId( 0, BADINDEX );
}
Msg* SparseMsg::copy( Id origSrc, Id newSrc, Id newTgt,
- FuncId fid, unsigned int b, unsigned int n ) const
-{
- const Element* orig = origSrc.element();
- if ( n <= 1 ) {
- SparseMsg* ret = 0;
- if ( orig == e1() ) {
- ret = new SparseMsg( newSrc.element(), newTgt.element(), 0 );
- ret->e1()->addMsgAndFunc( ret->mid(), fid, b );
- } else if ( orig == e2() ) {
- ret = new SparseMsg( newTgt.element(), newSrc.element(), 0 );
- ret->e2()->addMsgAndFunc( ret->mid(), fid, b );
- } else {
- assert( 0 );
- }
- ret->setMatrix( matrix_ );
- ret->nrows_ = nrows_;
- return ret;
- } else {
- // Here we need a SliceMsg which goes from one 2-d array to another.
- cout << "Error: SparseMsg::copy: SparseSliceMsg not yet implemented\n";
- return 0;
- }
+ FuncId fid, unsigned int b, unsigned int n ) const
+{
+ const Element* orig = origSrc.element();
+ if ( n <= 1 )
+ {
+ SparseMsg* ret = 0;
+ if ( orig == e1() )
+ {
+ ret = new SparseMsg( newSrc.element(), newTgt.element(), 0 );
+ ret->e1()->addMsgAndFunc( ret->mid(), fid, b );
+ }
+ else if ( orig == e2() )
+ {
+ ret = new SparseMsg( newTgt.element(), newSrc.element(), 0 );
+ ret->e2()->addMsgAndFunc( ret->mid(), fid, b );
+ }
+ else
+ {
+ assert( 0 );
+ }
+ ret->setMatrix( matrix_ );
+ ret->nrows_ = nrows_;
+ return ret;
+ }
+ else
+ {
+ // Here we need a SliceMsg which goes from one 2-d array to another.
+ cout << "Error: SparseMsg::copy: SparseSliceMsg not yet implemented\n";
+ return 0;
+ }
}
void fillErefsFromMatrix(
- const SparseMatrix< unsigned int >& matrix,
- vector< vector < Eref > >& v, Element* e1, Element* e2 )
-{
- v.clear();
- v.resize( e1->numData() );
- assert( e1->numData() == matrix.nRows() );
- assert( e2->numData() == matrix.nColumns() );
- for ( unsigned int i = 0; i < e1->numData(); ++i ) {
- const unsigned int* entry;
- const unsigned int* colIndex;
- unsigned int num = matrix.getRow( i, &entry, &colIndex );
- v[i].resize( num );
- for ( unsigned int j = 0; j < num; ++j ) {
- v[i][j] = Eref( e2, colIndex[j], entry[j] );
- }
- }
+ const SparseMatrix< unsigned int >& matrix,
+ vector< vector < Eref > >& v, Element* e1, Element* e2 )
+{
+ v.clear();
+ v.resize( e1->numData() );
+ assert( e1->numData() == matrix.nRows() );
+ assert( e2->numData() == matrix.nColumns() );
+ for ( unsigned int i = 0; i < e1->numData(); ++i )
+ {
+ const unsigned int* entry;
+ const unsigned int* colIndex;
+ unsigned int num = matrix.getRow( i, &entry, &colIndex );
+ v[i].resize( num );
+ for ( unsigned int j = 0; j < num; ++j )
+ {
+ v[i][j] = Eref( e2, colIndex[j], entry[j] );
+ }
+ }
}
void SparseMsg::sources( vector< vector < Eref > >& v ) const
{
- SparseMatrix< unsigned int > temp( matrix_ );
- temp.transpose();
- fillErefsFromMatrix( temp, v, e2_, e1_ );
+ SparseMatrix< unsigned int > temp( matrix_ );
+ temp.transpose();
+ fillErefsFromMatrix( temp, v, e2_, e1_ );
}
void SparseMsg::targets( vector< vector< Eref > >& v ) const
{
- fillErefsFromMatrix( matrix_, v, e1_, e2_ );
+ fillErefsFromMatrix( matrix_, v, e1_, e2_ );
}
/// Static function for Msg access
unsigned int SparseMsg::numMsg()
{
- return msg_.size();
+ return msg_.size();
}
/// Static function for Msg access
char* SparseMsg::lookupMsg( unsigned int index )
{
- assert( index < msg_.size() );
- return reinterpret_cast< char* >( msg_[index] );
+ assert( index < msg_.size() );
+ return reinterpret_cast< char* >( msg_[index] );
}
diff --git a/msg/SparseMsg.h b/msg/SparseMsg.h
index 3d7ba580a1c19cc6ea22e54b2202d41f2285228e..0061a9fe4f30d183667fa19b17e2992c40599fee 100644
--- a/msg/SparseMsg.h
+++ b/msg/SparseMsg.h
@@ -10,6 +10,8 @@
#ifndef _SPARSE_MSG_H
#define _SPARSE_MSG_H
+#include "../randnum/RNG.h"
+
/**
* This is a parallelized sparse message.
* It is a general message type optimized for sparse matrix like
@@ -27,6 +29,7 @@
* Synapses, which are array fields of IntFire objects.
* The sparse connectivity maps between the source IntFire and target
* Synapses.
+ *
* The location of the entry in the sparse matrix provides the index of
* the target IntFire.
* The data value in the sparse matrix provides the index of the Synapse
@@ -39,113 +42,117 @@
* BiSparseMsg.
* It can be modified after creation to add or remove message entries.
*/
+
class SparseMsg: public Msg
{
- friend unsigned int Msg::initMsgManagers(); // for initializing Id.
- public:
- SparseMsg( Element* e1, Element* e2, unsigned int msgIndex );
- ~SparseMsg();
-
- Eref firstTgt( const Eref& src ) const;
-
- void sources( vector< vector< Eref > >& v ) const;
- void targets( vector< vector< Eref > >& v ) const;
-
- unsigned int randomConnect( double probability );
-
- Id managerId() const;
-
- ObjId findOtherEnd( ObjId end ) const;
-
- Msg* copy( Id origSrc, Id newSrc, Id newTgt,
- FuncId fid, unsigned int b, unsigned int n ) const;
-
- /**
- * Assigns the whole connection matrix
- */
- void setMatrix( const SparseMatrix< unsigned int >& m );
-
- /**
- * Returns the connection matrix
- */
- SparseMatrix< unsigned int >& getMatrix();
-
- // Uses default addToQ function.
-
- /////////////////////////////////////////////////////////////////
- // Here we define the Element interface functions for SparseMsg
- /////////////////////////////////////////////////////////////////
- void setRandomConnectivity( double probability, long seed );
- double getProbability() const;
- void setProbability( double value );
-
- //
- vector< unsigned int > getMatrixEntry() const;
- vector< unsigned int > getColIndex() const;
- vector< unsigned int > getRowStart() const;
-
- long getSeed() const;
- void setSeed( long value );
-
- vector< unsigned int > getEntryPairs() const;
- void setEntryPairs( vector< unsigned int > entries );
-
- void setEntry( unsigned int row, unsigned int column,
- unsigned int value );
-
- void unsetEntry( unsigned int row, unsigned int column );
-
- // Still need to implement array field gets.
-
- unsigned int getNumRows() const;
- unsigned int getNumColumns() const;
- unsigned int getNumEntries() const;
- void clear();
- void transpose();
-
- /**
- * Fills up the entire message based on pairs of src,dest (i.e.,
- * row,column) values. All filled entries are set to zero.
- */
- void pairFill( vector< unsigned int > src,
- vector< unsigned int> dest );
-
- /**
- * Fills up the entire message based on triplets of
- * src,destDataIndex,destFieldIndex
- */
- void tripletFill( vector< unsigned int > src,
- vector< unsigned int> dest,
- vector< unsigned int > field );
-
- /**
- * Fills up the entire message based on triplets of
- * src,destDataIndex,destFieldIndex, but catenates them all into
- * a single long vector since PyMoose doesn't know how to handle
- * multiple vectors.
- */
- void tripletFill1( vector< unsigned int > entries );
-
- /**
- * Utility function to update all sorts of values after we've
- * rebuilt the matrix.
- */
- void updateAfterFill();
-
- /// Msg lookup functions
- static unsigned int numMsg();
- static char* lookupMsg( unsigned int index );
-
- static const Cinfo* initCinfo();
-
- private:
- SparseMatrix< unsigned int > matrix_;
- unsigned int numThreads_; // Number of threads to partition
- unsigned int nrows_; // The original size of the matrix.
- double p_;
- unsigned long seed_;
- static Id managerId_; // The Element that manages Sparse Msgs.
- static vector< SparseMsg* > msg_;
+ friend unsigned int Msg::initMsgManagers(); // for initializing Id.
+
+public:
+
+ SparseMsg( Element* e1, Element* e2, unsigned int msgIndex );
+ ~SparseMsg();
+
+ Eref firstTgt( const Eref& src ) const;
+
+ void sources( vector< vector< Eref > >& v ) const;
+ void targets( vector< vector< Eref > >& v ) const;
+
+ unsigned int randomConnect( double probability );
+
+ Id managerId() const;
+
+ ObjId findOtherEnd( ObjId end ) const;
+
+ Msg* copy( Id origSrc, Id newSrc, Id newTgt,
+ FuncId fid, unsigned int b, unsigned int n ) const;
+
+ /**
+ * Assigns the whole connection matrix
+ */
+ void setMatrix( const SparseMatrix< unsigned int >& m );
+
+ /**
+ * Returns the connection matrix
+ */
+ SparseMatrix< unsigned int >& getMatrix();
+
+ // Uses default addToQ function.
+
+ // Here we define the Element interface functions for SparseMsg
+ void setRandomConnectivity( double probability, long seed );
+ double getProbability() const;
+ void setProbability( double value );
+
+ vector< unsigned int > getMatrixEntry() const;
+ vector< unsigned int > getColIndex() const;
+ vector< unsigned int > getRowStart() const;
+
+ unsigned long getSeed() const;
+ void setSeed( unsigned long value );
+
+ vector< unsigned int > getEntryPairs() const;
+ void setEntryPairs( vector< unsigned int > entries );
+
+ void setEntry( unsigned int row, unsigned int column,
+ unsigned int value );
+
+ void unsetEntry( unsigned int row, unsigned int column );
+
+ // Still need to implement array field gets.
+ unsigned int getNumRows() const;
+ unsigned int getNumColumns() const;
+ unsigned int getNumEntries() const;
+ void clear();
+ void transpose();
+
+ /**
+ * Fills up the entire message based on pairs of src,dest (i.e.,
+ * row,column) values. All filled entries are set to zero.
+ */
+ void pairFill( vector< unsigned int > src,
+ vector< unsigned int> dest );
+
+ /**
+ * Fills up the entire message based on triplets of
+ * src,destDataIndex,destFieldIndex
+ */
+ void tripletFill( vector< unsigned int > src,
+ vector< unsigned int> dest,
+ vector< unsigned int > field );
+
+ /**
+ * Fills up the entire message based on triplets of
+ * src,destDataIndex,destFieldIndex, but catenates them all into
+ * a single long vector since PyMoose doesn't know how to handle
+ * multiple vectors.
+ */
+ void tripletFill1( vector< unsigned int > entries );
+
+ /**
+ * Utility function to update all sorts of values after we've
+ * rebuilt the matrix.
+ */
+ void updateAfterFill();
+
+ /// Msg lookup functions
+ static unsigned int numMsg();
+ static char* lookupMsg( unsigned int index );
+
+ static const Cinfo* initCinfo();
+
+private:
+ SparseMatrix< unsigned int > matrix_;
+ unsigned int numThreads_; // Number of threads to partition
+ unsigned int nrows_; // The original size of the matrix.
+ double p_;
+ static Id managerId_; // The Element that manages Sparse Msgs.
+ static vector< SparseMsg* > msg_;
+
+ // RNG.
+ unsigned long seed_;
+ moose::MOOSE_RANDOM_DEVICE rd_;
+ moose::MOOSE_RNG_DEFAULT_ENGINE rng_;
+ moose::MOOSE_UNIFORM_DISTRIBUTION<double> dist_;
};
#endif // _SPARSE_MSG_H
diff --git a/pymoose/CMakeLists.txt b/pymoose/CMakeLists.txt
index b5d118b764800099c1753c54876237d34de57b54..3c69dacdc764bede7bb78324b759f653141bde4e 100644
--- a/pymoose/CMakeLists.txt
+++ b/pymoose/CMakeLists.txt
@@ -1,5 +1,4 @@
-add_definitions(-DPYMOOSE)
-include_directories(../basecode ../msg)
+cmake_minimum_required(VERSION 2.8)
set(PYMOOSE_SRCS
moosemodule.cpp
@@ -7,8 +6,8 @@ set(PYMOOSE_SRCS
mfield.cpp
pymooseinit.cpp
melement.cpp
- test_moosemodule.cpp
PyRun.cpp
+ test_moosemodule.cpp
)
# Build _moose.so in source directory and them copy everything to
@@ -35,15 +34,20 @@ add_definitions(-DUSE_NUMPY)
add_definitions(-DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION)
-execute_process( COMMAND ${PYTHON_EXECUTABLE}-config --includes
- OUTPUT_VARIABLE PYTHON_INCLUDE_FLAGS
- OUTPUT_STRIP_TRAILING_WHITESPACE
- )
-execute_process( COMMAND ${PYTHON_EXECUTABLE}-config --libs
- OUTPUT_VARIABLE PYTHON_LIBRARIES
- OUTPUT_STRIP_TRAILING_WHITESPACE
- )
-message( STATUS "Python include flags: ${PYTHON_INCLUDE_FLAGS}" )
+# make sure the Python.h is found.
+find_package( PythonLibs REQUIRED)
+include_directories( ${PYTHON_INCLUDE_DIRS} )
+
+#execute_process( COMMAND ${PYTHON_EXECUTABLE}-config --includes
+# OUTPUT_VARIABLE PYTHON_INCLUDE_FLAGS
+# OUTPUT_STRIP_TRAILING_WHITESPACE
+# )
+#execute_process( COMMAND ${PYTHON_EXECUTABLE}-config --libs
+# OUTPUT_VARIABLE PYTHON_LIBRARIES
+# OUTPUT_STRIP_TRAILING_WHITESPACE
+# )
+# message( STATUS "Python include flags: ${PYTHON_INCLUDE_FLAGS}" )
+
set_target_properties(_moose PROPERTIES
COMPILE_DEFINITIONS "PYMOOSE"
COMPILE_FLAGS "${PYTHON_INCLUDE_FLAGS}"
@@ -62,7 +66,6 @@ if(HDF5_LIBRARY_DIRS)
set_target_properties( _moose PROPERTIES LINK_FLAGS "-L${HDF5_LIBRARY_DIRS}" )
endif()
-
if(MACOSX)
set(CMAKE_MODULE_LINKER_FLAGS "-undefined dynamic_lookup")
message(STATUS "ADDING some linker flags ${CMAKE_EXE_LINKER_FLAGS}")
@@ -83,7 +86,6 @@ else(MACOSX)
${MOOSE_LIBRARIES}
${STATIC_LIBRARIES}
"-Wl,--no-whole-archive"
- # ${PYTHON_LIBRARIES}
${SYSTEM_SHARED_LIBS}
)
endif(MACOSX)
diff --git a/pymoose/melement.cpp b/pymoose/melement.cpp
index 82856488d2fe318e52b0e0a19081d9db45be4a13..47ce0e407d7dffaaeca1ce5e509425929d277ff6 100644
--- a/pymoose/melement.cpp
+++ b/pymoose/melement.cpp
@@ -49,7 +49,7 @@
#include <Python.h>
#include <structmember.h>
-#ifdef USE_BOOST
+#ifdef USE_BOOST_ODE
#include <boost/format.hpp>
#endif
diff --git a/pymoose/mfield.cpp b/pymoose/mfield.cpp
index 7e73f2650e979d17ef72952699f4274121f3358c..9cb2b073706f74bf5a082f33379a0b5d7f23fe35 100644
--- a/pymoose/mfield.cpp
+++ b/pymoose/mfield.cpp
@@ -116,11 +116,12 @@ int moose_Field_init(_Field * self, PyObject * args, PyObject * kwargs)
}
self->owner = ((_ObjId*)owner);
Py_INCREF(self->owner);
- ObjId tmp = ((_ObjId*)owner)->oid_;
- size_t size = strlen(fieldName);
- char * name = (char*)calloc(size+1, sizeof(char));
- strncpy(name, fieldName, size);
- self->name = name;
+ self->name = strdup(fieldName);
+ if (!self->name) {
+ PyErr_NoMemory();
+ return -1;
+ }
+
// In earlier version I tried to deallocate the existing
// self->name if it is not NULL. But it turns out that it
// causes a SIGABRT. In any case it should not be an issue as
@@ -316,7 +317,7 @@ PyObject * moose_DestField_call(PyObject * self, PyObject * args,
PyObject * arg = PyTuple_GetItem(args, ii);
Py_INCREF(arg);
PyTuple_SetItem(newargs, ii+1, arg);
- Py_DECREF(arg);
+ //Py_DECREF(arg);
}
// Call ObjId._setDestField with the new arguments
PyObject * ret = moose_ObjId_setDestField(((_Field*)self)->owner, newargs);
diff --git a/pymoose/moosemodule.cpp b/pymoose/moosemodule.cpp
index ae638e18c3afc90267e20467fb89577ba9c95ba3..acf86f0235bb32feff830f6d6de8b6fd2c3eb859 100644
--- a/pymoose/moosemodule.cpp
+++ b/pymoose/moosemodule.cpp
@@ -20,7 +20,7 @@
#include <exception>
-#if USE_BOOST
+#if USE_BOOST_ODE
#include <boost/format.hpp>
#endif
@@ -2536,66 +2536,6 @@ int defineLookupFinfos(const Cinfo * cinfo)
return 1;
}
-int defineDestFinfos(const Cinfo * cinfo)
-{
- const string& className = cinfo->name();
-#ifndef NDEBUG
- if (verbosity > 1)
- {
- cout << "\tCreating destField attributes for " << className << endl;
- }
-#endif
- vector <PyGetSetDef>& vec = get_getsetdefs()[className];
- /*
- We do not know the final number of user-accessible
- destFinfos as we have to ignore the destFinfos starting
- with get/set. So use a vector instead of C array.
- */
- size_t currIndex = vec.size();
- for (unsigned int ii = 0; ii < cinfo->getNumDestFinfo(); ++ii)
- {
- Finfo * destFinfo = const_cast<Cinfo*>(cinfo)->getDestFinfo(ii);
- const string& name = destFinfo->name();
- /*
- get_{xyz} and set_{xyz} are internal destFinfos for
- accessing valueFinfos. Ignore them.
-
- With the '_' removed from internal get/set for value
- fields, we cannot separate them out. - Subha Fri Jan 31
- 16:43:51 IST 2014
-
- The policy changed in the past and hence the following were commented out.
- - Subha Tue May 26 00:25:28 EDT 2015
- */
- // if (name.find("get") == 0 || name.find("set") == 0){
- // continue;
- // }
- PyGetSetDef destFieldGetSet;
- vec.push_back(destFieldGetSet);
-
- vec[currIndex].name = (char*)calloc(name.size() + 1, sizeof(char));
- strncpy(vec[currIndex].name,
- const_cast<char*>(name.c_str()),
- name.size());
-
- vec[currIndex].doc = (char*) "D_field";
- vec[currIndex].get = (getter)moose_ObjId_get_destField_attr;
- PyObject * args = PyTuple_New(1);
- if (args == NULL)
- {
- cerr << "moosemodule.cpp: defineDestFinfos: Failed to allocate tuple" << endl;
- return 0;
- }
- PyTuple_SetItem(args, 0, PyString_FromString(name.c_str()));
- vec[currIndex].closure = (void*)args;
-
- //LOG( debug, "\tCreated destField " << vec[currIndex].name );
-
- ++currIndex;
- } // ! for
-
- return 1;
-}
int defineClass(PyObject * module_dict, const Cinfo * cinfo)
{
@@ -2770,6 +2710,63 @@ PyObject * moose_ObjId_get_destField_attr(PyObject * self, void * closure)
return (PyObject*)ret;
}
+
+int defineDestFinfos(const Cinfo * cinfo)
+{
+ const string& className = cinfo->name();
+#ifndef NDEBUG
+ if (verbosity > 1)
+ {
+ cout << "\tCreating destField attributes for " << className << endl;
+ }
+#endif
+ vector <PyGetSetDef>& vec = get_getsetdefs()[className];
+ /*
+ We do not know the final number of user-accessible
+ destFinfos as we have to ignore the destFinfos starting
+ with get/set. So use a vector instead of C array.
+ */
+ size_t currIndex = vec.size();
+ for (unsigned int ii = 0; ii < cinfo->getNumDestFinfo(); ++ii)
+ {
+ Finfo * destFinfo = const_cast<Cinfo*>(cinfo)->getDestFinfo(ii);
+ const string& name = destFinfo->name();
+ /*
+ get_{xyz} and set_{xyz} are internal destFinfos for
+ accessing valueFinfos. Ignore them.
+
+ With the '_' removed from internal get/set for value
+ fields, we cannot separate them out. - Subha Fri Jan 31
+ 16:43:51 IST 2014
+
+ The policy changed in the past and hence the following were commented out.
+ - Subha Tue May 26 00:25:28 EDT 2015
+ */
+ // if (name.find("get") == 0 || name.find("set") == 0){
+ // continue;
+ // }
+ PyGetSetDef destFieldGetSet;
+ vec.push_back(destFieldGetSet);
+
+ vec[currIndex].name = strdup(name.c_str());
+ vec[currIndex].doc = (char*) "Destination field";
+ vec[currIndex].get = (getter)moose_ObjId_get_destField_attr;
+ PyObject *args = PyTuple_New(1);
+ if (!args || !vec[currIndex].name) {
+ cerr << "moosemodule.cpp: defineDestFinfos: allocation failed\n";
+ return 0;
+ }
+ PyTuple_SetItem(args, 0, PyString_FromString(name.c_str()));
+ vec[currIndex].closure = (void*)args;
+
+ //LOG( debug, "\tCreated destField " << vec[currIndex].name );
+
+ ++currIndex;
+ } // ! for
+
+ return 1;
+}
+
/**
Try to obtain a LookupField object for a specified
lookupFinfo. The first item in `closure` must be the name of
diff --git a/python/moose/chemUtil/add_Delete_ChemicalSolver.py b/python/moose/chemUtil/add_Delete_ChemicalSolver.py
index cc350ec6087ac1b731b0a274b75eeeebb8a3de77..9b11a5c148c094ae2b125cf0407c1395dfad7db3 100644
--- a/python/moose/chemUtil/add_Delete_ChemicalSolver.py
+++ b/python/moose/chemUtil/add_Delete_ChemicalSolver.py
@@ -1,158 +1,140 @@
# -*- coding: utf-8 -*-
+__author__ = "HarshaRani"
+__credits__ = ["Upi Lab"]
+__license__ = "GPL3"
+__version__ = "1.0.0"
+__maintainer__ = "HarshaRani"
+__email__ = "hrani@ncbs.res.in"
+__status__ = "Development"
+__updated__ = "Sep 03 2018"
+
+
+'''
+mooseAddChemSolver and mooseDeleteChemSolver is for adding and deleting only
+Chemical solver
+'''
+
import moose
-from fixXreacs import fixXreacs
+from moose.fixXreacs import fixXreacs
def positionCompt( compt ):
i = 0
while (i != len(compt)-1):
- #print "PositionCompt ", compt[i+1],compt[i+1].volume, compt[i], compt[i].volume
compt[i+1].x1 += compt[i].x1
compt[i+1].x0 += compt[i].x1
i += 1
-def moosedeleteChemSolver(modelRoot):
- """Delete solvers from Chemical Compartment
+def mooseDeleteChemSolver(modelRoot):
+ """Delete solvers from Chemical Compartment """
- """
- compts = moose.wildcardFind(modelRoot + '/##[ISA=ChemCompt]')
- for compt in compts:
- if moose.exists(compt.path + '/stoich'):
- st = moose.element(compt.path + '/stoich')
- st_ksolve = st.ksolve
- st_dsolve = st.dsolve
-
- moose.delete(st)
- if moose.exists((st_ksolve).path):
- moose.delete(st_ksolve)
- print("KSolver is deleted for modelpath %s " % modelRoot)
- if moose.exists((st_dsolve).path):
- moose.delete(st_dsolve)
- print("DSolver is deleted for modelpath %s " % modelRoot)
- '''
compts = moose.wildcardFind(modelRoot + '/##[ISA=ChemCompt]')
- for compt in compts:
- if moose.exists(compt.path + '/stoich'):
- st = moose.element(compt.path + '/stoich')
- st_ksolve = st.ksolve
- moose.delete(st)
- if moose.exists((st_ksolve).path):
- moose.delete(st_ksolve)
- print("Solver is deleted for modelpath %s " % modelRoot)
-
- '''
-
-def mooseaddChemSolver(modelRoot, solver):
+ if all(isinstance(x, (moose.CubeMesh,moose.CylMesh)) for x in compts):
+ for compt in compts:
+ if moose.exists(compt.path + '/stoich'):
+ st = moose.element(compt.path + '/stoich')
+ st_ksolve = st.ksolve
+ st_dsolve = st.dsolve
+
+ moose.delete(st)
+
+ if moose.exists((st_ksolve).path):
+ print("KSolver is deleted for modelpath %s " % st_ksolve)
+ moose.delete(st_ksolve)
+
+ if moose.exists((st_dsolve).path) and st_dsolve.path != '/':
+ print("DSolver is deleted for modelpath %s " % st_dsolve)
+ moose.delete(st_dsolve)
+ else:
+ return ("mooseDeleteChemSolver is only for deleting Chemical Model solver which has to be `CubeMesh` or `CylMesh` found ",list(set([x.className for x in compts]) - set(['CubeMesh',"CylMesh"])))
+
+def stdSolvertype(solverName):
+ if solverName.lower() in ["gssa","gillespie","stochastic","gsolve"]:
+ return "gssa"
+ elif solverName.lower() in ["gsl","runge kutta","deterministic","ksolve","rungekutta","rk5","rkf","rk"]:
+ return "gsl"
+ elif solverName.lower() in ["ee","exponential euler","exponentialeuler","neutral"]:
+ return "ee"
+ return "ee"
+
+def mooseAddChemSolver(modelRoot, solver):
"""
- Add the solvers to Chemical compartment
+ Add the solvers only if all are Chemical compartment
"""
- compt = moose.wildcardFind(modelRoot + '/##[ISA=ChemCompt]')
- if compt:
- comptinfo = moose.Annotator(moose.element(compt[0]).path + '/info')
- previousSolver = comptinfo.solver
- currentSolver = previousSolver
- if solver == "Gillespie" or solver == "gssa":
- currentSolver = "gssa"
- elif solver == "Runge Kutta" or solver == "gsl":
- currentSolver = "gsl"
- elif solver == "Exponential Euler" or solver == "ee":
- currentSolver = "ee"
-
- if previousSolver != currentSolver:
- # if previousSolver != currentSolver
- comptinfo.solver = currentSolver
- if (moose.exists(compt[0].path + '/stoich')):
- # "A: and stoich exists then delete the stoich add solver"
- deleteSolver(modelRoot)
- setCompartmentSolver(modelRoot, currentSolver)
- return True
- else:
- # " B: stoich doesn't exists then addSolver, this is when object is deleted which delete's the solver "
- # " and solver is also changed, then add addsolver "
- setCompartmentSolver(modelRoot, currentSolver)
- return True
+ compts = moose.wildcardFind(modelRoot + '/##[ISA=ChemCompt]')
+ if all(isinstance(x, (moose.CubeMesh,moose.CylMesh)) for x in compts):
+ if not compts:
+ return ("Atleast one compartment is required ")
+ elif ( len(compts) > 3 ):
+ return ("Warning: setSolverOnCompt Cannot handle " , len(compts) , " chemical compartments\n")
+
else:
- if moose.exists(compt[0].path + '/stoich'):
- # " stoich exist, doing nothing"
- return False
- else:
- # "but stoich doesn't exist,this is when object is deleted which deletes the solver
- # " but solver are not changed, then also call addSolver"
+ comptinfo = moose.Annotator(moose.element(compts[0]).path + '/info')
+
+ previousSolver = stdSolvertype(comptinfo.solver)
+ currentSolver = stdSolvertype(solver)
+
+ if previousSolver != currentSolver:
+ comptinfo.solver = currentSolver
+ if (moose.exists(compts[0].path + '/stoich')):
+ # "A: and stoich exists then delete the stoich add solver"
+ mooseDeleteChemSolver(modelRoot)
setCompartmentSolver(modelRoot, currentSolver)
return True
- return False
+ else:
+ if not moose.exists(compts[0].path + '/stoich'):
+ # " stoich exist, doing nothing"
+ setCompartmentSolver(modelRoot, currentSolver)
+ return True
+ else:
+
+ return ("mooseAddChemSolver is only for adding Chemical Model which has to be `CubeMesh` or `CylMesh` found ",list(set([x.className for x in compts]) - set(['CubeMesh',"CylMesh"])))
def setCompartmentSolver(modelRoot, solver):
- comptlist = dict((c, c.volume) for c in moose.wildcardFind(modelRoot + '/##[ISA=ChemCompt]'))
- comptVol = {}
- compts = []
- vol = [v for k,v in comptlist.items()]
- volumeSort = sorted(vol)
- for k,v in comptlist.items():
- comptVol[k]= v
- for volSor in volumeSort:
- for a,b in comptVol.items():
- if b == volSor:
- compts.append(a)
-
- #compts = [key for key, value in sorted(comptlist.items(), key=lambda (k,v): (v,k))]
- if ( len(compts) == '0'):
- print ("Atleast one compartment is required ")
- return
- else:
- if ( len(compts) > 3 ):
- print ("Warning: setSolverOnCompt Cannot handle " , len(compts) , " chemical compartments\n")
- return;
+ """
+ If Solver type is 'gsl' or 'gssa' do add Solver
+ if 'ee' nothing
- elif (len(compts) >1 ):
- positionCompt(compts)
+ """
+ if solver != 'ee':
+ comptlist = dict((c.volume, c) for c in moose.wildcardFind(modelRoot + '/##[ISA=ChemCompt]'))
+ vollist = sorted(comptlist.keys())
+ compts = [comptlist[key] for key in vollist]
- fixXreacs( modelRoot )
+ #compts = [key for key, value in sorted(comptlist.items(), key=lambda (k,v): (v,k))]
+
+ if (len(compts) >1 ):
+ positionCompt(compts)
+ fixXreacs( modelRoot )
+
+ vollist = sorted(comptlist.keys())
+ compts = [comptlist[key] for key in vollist]
+ #compts = [key for key, value in sorted(comptlist.items(), key=lambda (k,v): (v,k))]
for compt in compts:
if solver != 'ee':
- if (solver == 'gsl') or (solver == 'Runge Kutta'):
+ if (solver == 'gsl'):
ksolve = moose.Ksolve(compt.path + '/ksolve')
- if (solver == 'gssa') or (solver == 'Gillespie'):
+ if (solver == 'gssa') :
ksolve = moose.Gsolve(compt.path + '/gsolve')
-
- dsolve = moose.Dsolve(compt.path+'/dsolve')
+
+ if (len(compts) > 1):
+ dsolve = moose.Dsolve(compt.path+'/dsolve')
+
stoich = moose.Stoich(compt.path + '/stoich')
- stoich.compartment = compt
stoich.ksolve = ksolve
- stoich.dsolve = dsolve
+ if (len(compts) > 1):
+ stoich.dsolve = dsolve
+
+ stoich.compartment = compt
stoich.path = compt.path + "/##"
- ksolveList = moose.wildcardFind(modelRoot+'/##[ISA=Ksolve]')
+
+
dsolveList = moose.wildcardFind(modelRoot+'/##[ISA=Dsolve]')
- stoichList = moose.wildcardFind(modelRoot+'/##[ISA=Stoich]')
-
i = 0
while(i < len(dsolveList)-1):
dsolveList[i+1].buildMeshJunctions(dsolveList[i])
i += 1
-
- print( " Solver is added to model path %s" % modelRoot )
- '''
- compts = moose.wildcardFind(modelRoot + '/##[ISA=ChemCompt]')
- for compt in compts:
- if (solver == 'gsl') or (solver == 'Runge Kutta'):
- ksolve = moose.Ksolve(compt.path + '/ksolve')
- if (solver == 'gssa') or (solver == 'Gillespie'):
- ksolve = moose.Gsolve(compt.path + '/gsolve')
- if (solver != 'ee'):
- stoich = moose.Stoich(compt.path + '/stoich')
- stoich.compartment = compt
- stoich.ksolve = ksolve
- if moose.exists(compt.path):
- stoich.path = compt.path + "/##"
- stoichList = moose.wildcardFind(modelRoot + '/##[ISA=Stoich]')
- if len(stoichList) == 2:
- stoichList[1].buildXreacs(stoichList[0])
- if len(stoichList) == 3:
- stoichList[1].buildXreacs(stoichList[0])
- stoichList[1].buildXreacs(stoichList[2])
-
- for i in stoichList:
- i.filterXreacs()
- print( " Solver is added to model path %s" % modelRoot )
- '''
+ if not modelRoot[:1].startswith('/'):
+ modelRoot ='/'+modelRoot
+ print( " Solver is added to model path `%s` with `%s` solver" % (modelRoot,solver) )
diff --git a/python/fixXreacs.py b/python/moose/fixXreacs.py
similarity index 100%
rename from python/fixXreacs.py
rename to python/moose/fixXreacs.py
diff --git a/python/moose/genesis/writeKkit.py b/python/moose/genesis/writeKkit.py
index c94ca3daddfc1e0a0215ccb04e84986c2c0fad8a..f6bba42b84394f8963b31d97240a88679f453f8c 100644
--- a/python/moose/genesis/writeKkit.py
+++ b/python/moose/genesis/writeKkit.py
@@ -224,9 +224,11 @@ def writeEnz( modelpath,f,sceneitems):
concInit = 0;
n = 0;
conc = 0;
- enzParent = enz.parent
- if (isinstance(enzParent.className,moose.Pool)) or (isinstance(enzParent.className,moose.ZombiePool)):
- print(" raise exception enz doesn't have pool as parent")
+ if len(moose.element(enz).neighbors['enzDest']) == 1:
+ enzParent = moose.element(moose.element(enz).neighbors['enzDest'][0])
+
+ if not (isinstance(enzParent,moose.PoolBase)):
+ print(" raise exception enz doesn't have pool as parent %s",moose.element(enz).path)
return False
else:
vol = enzParent.volume * NA * 1e-3;
diff --git a/python/moose/moose.py b/python/moose/moose.py
index a949e5f4b5429952c38be7b9e2414694652dad9a..b9acb706279e4744800bed8e1690419953f63c40 100644
--- a/python/moose/moose.py
+++ b/python/moose/moose.py
@@ -10,7 +10,7 @@ from contextlib import closing
import warnings
import pydoc
from io import StringIO
-
+from os.path import splitext
import moose
import moose.utils as mu
@@ -62,6 +62,42 @@ except Exception as e:
# Import function from C++ module into moose namespace.
from moose._moose import *
+#`loadModel` is deleted from global import,
+# this is to bypass the call from c++ module which is due to fixXreacs() which is
+# now written in python and readKkit.cpp will not be possible to set/call the solver due to this
+
+del globals()['loadModel']
+
+def loadModel(filename, target,method=None):
+ solverClass = 'Neutral'
+ if method != None:
+ solverClass = method
+ try:
+ f = open(filename,'r')
+ f.close()
+ except IOError as e:
+ print (e)
+ return
+ else:
+ file_name,extension = splitext(filename)
+ if extension in [".swc",".p"]:
+ ret = moose._moose.loadModel(filename,target,"Neutral")
+ elif extension in [".g",".cspace"]:
+ #only if genesis or cspace file, then mooseAddChemSolver is called
+ ret = moose._moose.loadModel(filename,target,"ee")
+
+ method = "ee"
+ if solverClass.lower() in ["gssa","gillespie","stochastic","gsolve"]:
+ method = "gssa"
+ elif solverClass.lower() in ["gsl","runge kutta","deterministic","ksolve","rungekutta","rk5","rkf","rk"]:
+ method = "gsl"
+ elif solverClass.lower() in ["exponential euler","exponentialeuler","neutral"]:
+ method = "ee"
+
+ if method != 'ee':
+ chemError_ = _chemUtil.add_Delete_ChemicalSolver.mooseAddChemSolver(target,method)
+ return ret
+
def version( ):
return VERSION
@@ -149,20 +185,20 @@ def mooseWriteKkit(modelpath, filepath,sceneitems={}):
return _writeKkit.mooseWriteKkit(modelpath, filepath,sceneitems)
-def moosedeleteChemSolver(modelpath):
+def mooseDeleteChemSolver(modelpath):
""" deletes solver on all the compartment and its children.
This is neccesary while created a new moose object on a pre-existing modelpath,\n
- this should be followed by mooseaddChemSolver for add solvers on to compartment to simulate else
+ this should be followed by mooseAddChemSolver for add solvers on to compartment to simulate else
default is Exponential Euler (ee)
"""
if chemImport_:
- return _chemUtil.add_Delete_ChemicalSolver.moosedeleteChemSolver(modelpath)
+ return _chemUtil.add_Delete_ChemicalSolver.mooseDeleteChemSolver(modelpath)
else:
print( chemError_ )
return False
-def mooseaddChemSolver(modelpath, solver):
+def mooseAddChemSolver(modelpath, solver):
""" Add solver on chemical compartment and its children for calculation
keyword arguments:\n
@@ -174,7 +210,8 @@ def mooseaddChemSolver(modelpath, solver):
"""
if chemImport_:
- return _chemUtil.add_Delete_ChemicalSolver.mooseaddChemSolver(modelpath, solver)
+ chemError_ = _chemUtil.add_Delete_ChemicalSolver.mooseAddChemSolver(modelpath, solver)
+ return chemError_
else:
print( chemError_ )
return False
diff --git a/python/moose/print_utils.py b/python/moose/print_utils.py
index 5cc08416a1c7784219272c2a779522d08f953748..e34062313057c38e4720e874dfd7b938f9b7f412 100644
--- a/python/moose/print_utils.py
+++ b/python/moose/print_utils.py
@@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
-# print_utils.py:
-#
# A library with some print functions. Very useful during development.
from __future__ import print_function, division, absolute_import
diff --git a/python/rdesigneur/rdesigneur.py b/python/rdesigneur/rdesigneur.py
index 66a2ea68996ee4dae577254b438c40a2b9c72dc4..aa5b3fce4b5513a3579fae9e365687e7f24c6ce3 100644
--- a/python/rdesigneur/rdesigneur.py
+++ b/python/rdesigneur/rdesigneur.py
@@ -23,13 +23,14 @@ import os
import moose
import numpy as np
import math
-import itertools
import sys
import time
+import matplotlib.pyplot as plt
import rdesigneur.rmoogli as rmoogli
from rdesigneur.rdesigneurProtos import *
-import fixXreacs
+from moose.fixXreacs import fixXreacs
+#import fixXreacs
#from . import fixXreacs
#from rdesigneur.rmoogli import *
#import rmoogli
@@ -77,6 +78,8 @@ class rdesigneur:
combineSegments = True,
stealCellFromLibrary = False,
verbose = True,
+ addSomaChemCompt = False, # Put a soma chemCompt on neuroMesh
+ addEndoChemCompt = False, # Put an endo compartment, typically for ER, on each of the NeuroMesh compartments.
diffusionLength= 2e-6,
meshLambda = -1.0, #This is a backward compatibility hack
temperature = 32,
@@ -87,6 +90,7 @@ class rdesigneur:
elecPlotDt = 0.1e-3, # Same default as from MOOSE
funcDt = 0.1e-3, # Used when turnOffElec is False.
# Otherwise system uses chemDt.
+ numWaveFrames = 100, # Number of frames to use for waveplots
cellProto = [],
spineProto = [],
chanProto = [],
@@ -97,8 +101,8 @@ class rdesigneur:
chemDistrib = [],
adaptorList= [],
stimList = [],
- plotList = [],
- moogList = [],
+ plotList = [], # elecpath, geom_expr, object, field, title ['wave' [min max]]
+ moogList = [],
params = None
):
""" Constructor of the rdesigner. This just sets up internal fields
@@ -111,6 +115,8 @@ class rdesigneur:
self.combineSegments = combineSegments
self.stealCellFromLibrary = stealCellFromLibrary
self.verbose = verbose
+ self.addSomaChemCompt = addSomaChemCompt
+ self.addEndoChemCompt = addEndoChemCompt
self.diffusionLength= diffusionLength
if meshLambda > 0.0:
print("Warning: meshLambda argument is deprecated. Please use 'diffusionLength' instead.\nFor now rdesigneur will accept this argument.")
@@ -122,6 +128,7 @@ class rdesigneur:
self.elecPlotDt= elecPlotDt
self.funcDt= funcDt
self.chemPlotDt= chemPlotDt
+ self.numWaveFrames = numWaveFrames
self.cellProtoList = cellProto
self.spineProtoList = spineProto
@@ -136,17 +143,24 @@ class rdesigneur:
self.params = params
self.adaptorList = adaptorList
- self.stimList = stimList
- self.plotList = plotList
- self.saveList = plotList #ADDED BY Sarthak
+ try:
+ self.stimList = [ rstim.convertArg(i) for i in stimList ]
+ self.plotList = [ rplot.convertArg(i) for i in plotList ]
+ self.moogList = [ rmoog.convertArg(i) for i in moogList ]
+ except BuildError as msg:
+ print("Error: rdesigneur: " + msg)
+ quit()
+
+ #self.saveList = plotList #ADDED BY Sarthak
self.saveAs = []
- self.moogList = moogList
self.plotNames = []
+ self.wavePlotNames = []
self.saveNames = []
self.moogNames = []
self.cellPortionElist = []
self.spineComptElist = []
self.tabForXML = []
+ self._endos = []
if not moose.exists( '/library' ):
library = moose.Neutral( '/library' )
@@ -169,16 +183,10 @@ class rdesigneur:
len( self.cellPortionElist ), "compartments.")
if hasattr( self , 'chemid' ):
dmstoich = moose.element( self.dendCompt.path + '/stoich' )
- print("Chem part of model has ",
- self.dendCompt.mesh.num, "dendrite voxels X",
- dmstoich.numAllPools, "pools,\n ")
- if hasattr( self , 'spineCompt' ):
- smstoich = moose.element( self.spineCompt.path + '/stoich')
- pmstoich = moose.element( self.psdCompt.path + '/stoich' )
- print(self.spineCompt.mesh.num, "spine voxels X",
- smstoich.numAllPools, "pools,",
- self.psdCompt.mesh.num, "psd voxels X",
- pmstoich.numAllPools, "pools.")
+ print("Chem part of model has the following compartments: ")
+ for j in moose.wildcardFind( '/model/chem/##[ISA=ChemCompt]'):
+ s = moose.element( j.path + '/stoich' )
+ print( "In {}, {} voxels X {} pools".format( j.name, j.mesh.num, s.numAllPools ) )
def buildModel( self, modelPath = '/model' ):
if moose.exists( modelPath ):
@@ -205,7 +213,6 @@ class rdesigneur:
self._configureClocks()
if self.verbose:
self._printModelStats()
- self._savePlots()
except BuildError as msg:
print("Error: rdesigneur: model build failed:", msg)
@@ -462,10 +469,10 @@ class rdesigneur:
# Here we hack geomExpr to use it for the syn weight. We assume it
# is just a number. In due course
# it should be possible to actually evaluate it according to geom.
- synWeight = float( stimInfo[1] )
+ synWeight = float( stimInfo.geom_expr )
stimObj = []
for i in dendCompts + spineCompts:
- path = i.path + '/' + stimInfo[2] + '/sh/synapse[0]'
+ path = i.path + '/' + stimInfo.relpath + '/sh/synapse[0]'
if moose.exists( path ):
synInput = make_synInput( name='synInput', parent=path )
synInput.doPeriodic = doPeriodic
@@ -478,13 +485,17 @@ class rdesigneur:
# Here we set up the distributions
################################################################
def buildPassiveDistrib( self ):
- # [. path field expr [field expr]...]
+ # [path field expr [field expr]...]
# RM, RA, CM set specific values, per unit area etc.
- # Ra, Ra, Cm set absolute values.
+ # Rm, Ra, Cm set absolute values.
# Also does Em, Ek, initVm
# Expression can use p, g, L, len, dia, maxP, maxG, maxL.
temp = []
for i in self.passiveDistrib:
+ if (len( i ) < 3) or (len(i) %2 != 1):
+ raise BuildError( "buildPassiveDistrib: Need 3 + N*2 arguments, have {}".format( len(i) ) )
+
+ temp.append( '.' )
temp.extend( i )
temp.extend( [""] )
self.elecid.passiveDistribution = temp
@@ -605,22 +616,24 @@ class rdesigneur:
# [ region_wildcard, region_expr, path, field, title]
def _parseComptField( self, comptList, plotSpec, knownFields ):
# Put in stuff to go through fields if the target is a chem object
- field = plotSpec[3]
+ field = plotSpec.field
if not field in knownFields:
print("Warning: Rdesigneur::_parseComptField: Unknown field '{}'".format( field ) )
return (), ""
kf = knownFields[field] # Find the field to decide type.
if ( kf[0] == 'CaConcBase' or kf[0] == 'ChanBase' or kf[0] == 'NMDAChan' or kf[0] == 'VClamp' ):
- objList = self._collapseElistToPathAndClass( comptList, plotSpec[2], kf[0] )
+ objList = self._collapseElistToPathAndClass( comptList, plotSpec.relpath, kf[0] )
return objList, kf[1]
elif (field == 'n' or field == 'conc' or field == 'volume' ):
- path = plotSpec[2]
+ path = plotSpec.relpath
pos = path.find( '/' )
if pos == -1: # Assume it is in the dend compartment.
path = 'dend/' + path
pos = path.find( '/' )
chemCompt = path[:pos]
+ if chemCompt[-5:] == "_endo":
+ chemCompt = chemCompt[0:-5]
cc = moose.element( self.modelPath + '/chem/' + chemCompt)
voxelVec = []
temp = [ self._makeUniqueNameStr( i ) for i in comptList ]
@@ -634,13 +647,13 @@ class rdesigneur:
voxelVec = [i for i in range(len( em ) ) if em[i] in comptSet ]
# Here we collapse the voxelVec into objects to plot.
- allObj = moose.vec( self.modelPath + '/chem/' + plotSpec[2] )
+ allObj = moose.vec( self.modelPath + '/chem/' + plotSpec.relpath )
#print "####### allObj=", self.modelPath + '/chem/' + plotSpec[2]
if len( allObj ) >= len( voxelVec ):
objList = [ allObj[int(j)] for j in voxelVec]
else:
objList = []
- print( "Warning: Rdesigneur::_parseComptField: unknown Object: '", plotSpec[2], "'" )
+ print( "Warning: Rdesigneur::_parseComptField: unknown Object: '", plotSpec.relpath, "'" )
#print "############", chemCompt, len(objList), kf[1]
return objList, kf[1]
@@ -672,7 +685,7 @@ class rdesigneur:
dummy = moose.element( '/' )
k = 0
for i in self.plotList:
- pair = i[0] + " " + i[1]
+ pair = i.elecpath + ' ' + i.geom_expr
dendCompts = self.elecid.compartmentsFromExpression[ pair ]
spineCompts = self.elecid.spinesFromExpression[ pair ]
plotObj, plotField = self._parseComptField( dendCompts, i, knownFields )
@@ -683,15 +696,21 @@ class rdesigneur:
#print( "PlotList: {0}: numobj={1}, field ={2}, nd={3}, ns={4}".format( pair, numPlots, plotField, len( dendCompts ), len( spineCompts ) ) )
if numPlots > 0:
tabname = graphs.path + '/plot' + str(k)
- scale = knownFields[i[3]][2]
- units = knownFields[i[3]][3]
- self.plotNames.append( ( tabname, i[4], k, scale, units, i[3] ) )
+ scale = knownFields[i.field][2]
+ units = knownFields[i.field][3]
+ if i.mode == 'wave':
+ self.wavePlotNames.append( [ tabname, i.title, k, scale, units, i.field, i.ymin, i.ymax ] )
+ else:
+ self.plotNames.append( [ tabname, i.title, k, scale, units, i.field, i.ymin, i.ymax ] )
+ if len( i.saveFile ) > 4 and i.saveFile[-4] == '.xml' or i.saveFile:
+ self.saveNames.append( [ tabname, len(self.saveNames), scale, units, i ] )
+
k += 1
- if i[3] == 'n' or i[3] == 'conc' or i[3] == 'volume' or i[3] == 'Gbar':
+ if i.field == 'n' or i.field == 'conc' or i.field == 'volume' or i.field == 'Gbar':
tabs = moose.Table2( tabname, numPlots )
else:
tabs = moose.Table( tabname, numPlots )
- if i[3] == 'spikeTime':
+ if i.field == 'spikeTime':
tabs.vec.threshold = -0.02 # Threshold for classifying Vm as a spike.
tabs.vec.useSpikeMode = True # spike detect mode on
@@ -719,8 +738,8 @@ class rdesigneur:
moogliBase = moose.Neutral( self.modelPath + '/moogli' )
k = 0
for i in self.moogList:
- kf = knownFields[i[3]]
- pair = i[0] + " " + i[1]
+ kf = knownFields[i.field]
+ pair = i.elecpath + " " + i.geom_expr
dendCompts = self.elecid.compartmentsFromExpression[ pair ]
spineCompts = self.elecid.spinesFromExpression[ pair ]
dendObj, mooField = self._parseComptField( dendCompts, i, knownFields )
@@ -728,13 +747,6 @@ class rdesigneur:
assert( mooField == mooField2 )
mooObj3 = dendObj + spineObj
numMoogli = len( mooObj3 )
- #dendComptMap = self.dendCompt.elecComptMap
- #self.moogliViewer = rmoogli.makeMoogli( self, mooObj3, mooField )
- if len( i ) == 5:
- i.extend( kf[4:6] )
- elif len( i ) == 6:
- i.extend( [kf[5]] )
- #self.moogliViewer = rmoogli.makeMoogli( self, mooObj3, i, kf )
self.moogNames.append( rmoogli.makeMoogli( self, mooObj3, i, kf ) )
@@ -757,8 +769,8 @@ rdesigneur.rmoogli.updateMoogliViewer()
self.display( len( self.moogNames ) + 1 )
def display( self, startIndex = 0 ):
- import matplotlib.pyplot as plt
for i in self.plotNames:
+ # ?, title, fignum, scale, ylabel, wave/spikeTime, ymin, ymax
plt.figure( i[2] + startIndex )
plt.title( i[1] )
plt.xlabel( "Time (s)" )
@@ -776,144 +788,79 @@ rdesigneur.rmoogli.updateMoogliViewer()
t = np.arange( 0, vtab[0].vector.size, 1 ) * vtab[0].dt
for j in vtab:
plt.plot( t, j.vector * i[3] )
- if len( self.moogList ) > 0:
+ if i[6] != i[7]:
+ plt.ylim( i[6], i[7] )
+ if len( self.moogList ) or len( self.wavePlotNames ) > 0:
plt.ion()
+ # Here we build the plots and lines for the waveplots
+ self.initWavePlots( startIndex )
+ if len( self.wavePlotNames ) > 0:
+ for i in range( 3 ):
+ self.displayWavePlots()
plt.show( block=True )
+ self._save()
+
+
+ def initWavePlots( self, startIndex ):
+ self.frameDt = moose.element( '/clock' ).currentTime/self.numWaveFrames
+ for wpn in range( len(self.wavePlotNames) ):
+ i = self.wavePlotNames[wpn]
+ vtab = moose.vec( i[0] )
+ if len( vtab ) < 2:
+ print( "Warning: Waveplot {} abandoned, only {} points".format( i[1], len( vtab ) ) )
+ continue
+ dFrame = len( vtab[0].vector ) / self.numWaveFrames
+ if dFrame < 1:
+ dFrame = 1
+ vpts = np.array( [ [k.vector[j] for j in range( 0, len( k.vector ), dFrame ) ] for k in vtab] ).T * i[3]
+ fig = plt.figure( i[2] + startIndex )
+ ax = fig.add_subplot( 111 )
+ plt.title( i[1] )
+ plt.xlabel( "position (voxels)" )
+ plt.ylabel( i[4] )
+ if i[6] != i[7]:
+ mn = i[6]
+ mx = i[7]
+ else:
+ mn = np.min(vpts)
+ mx = np.max(vpts)
+ if mn/mx < 0.3:
+ mn = 0
+ ax.set_ylim( mn, mx )
+ line, = plt.plot( range( len( vtab ) ), vpts[0] )
+ timeLabel = plt.text( len(vtab ) * 0.05, mn + 0.9*(mx-mn), 'time = 0' )
+ self.wavePlotNames[wpn].append( [fig, line, vpts, timeLabel] )
+ fig.canvas.draw()
+
+ def displayWavePlots( self ):
+ for f in range( self.numWaveFrames ):
+ for i in self.wavePlotNames:
+ wp = i[-1]
+ if len( wp[2] ) > f:
+ wp[1].set_ydata( wp[2][f] )
+ wp[3].set_text( "time = {:.1f}".format(f*self.frameDt) )
+ wp[0].canvas.draw()
+ #plt.pause(0.001)
#This calls the _save function which saves only if the filenames have been specified
- self._save()
################################################################
# Here we get the time-series data and write to various formats
################################################################
#[TO DO] Add NSDF output function
'''
- The author of the functions -- [_savePlots(), _getTimeSeriesTable(), _writeXML(), _writeCSV(), _saveFormats(), _save()] is
+ The original author of the functions -- [_savePlots(), _writeXML(), _writeCSV(), _save()] is
Sarthak Sharma.
Email address: sarthaks442@gmail.com
+ Heavily modified by U.S. Bhalla
'''
-
- def _savePlots( self ):
-
- knownFields = {
- 'Vm':('CompartmentBase', 'getVm', 1000, 'Memb. Potential (mV)' ),
- 'Cm':('CompartmentBase', 'getCm', 1e12, 'Memb. capacitance (pF)' ),
- 'Rm':('CompartmentBase', 'getRm', 1e-9, 'Memb. Res (GOhm)' ),
- 'Ra':('CompartmentBase', 'getRa', 1e-6, 'Axial Res (MOhm)' ),
- 'spikeTime':('CompartmentBase', 'getVm', 1, 'Spike Times (s)'),
- 'Im':('CompartmentBase', 'getIm', 1e9, 'Memb. current (nA)' ),
- 'inject':('CompartmentBase', 'getInject', 1e9, 'inject current (nA)' ),
- 'Gbar':('ChanBase', 'getGbar', 1e9, 'chan max conductance (nS)' ),
- 'modulation':('ChanBase', 'getModulation', 1, 'chan modulation (unitless)' ),
- 'Gk':('ChanBase', 'getGk', 1e9, 'chan conductance (nS)' ),
- 'Ik':('ChanBase', 'getIk', 1e9, 'chan current (nA)' ),
- 'ICa':('NMDAChan', 'getICa', 1e9, 'Ca current (nA)' ),
- 'Ca':('CaConcBase', 'getCa', 1e3, 'Ca conc (uM)' ),
- 'n':('PoolBase', 'getN', 1, '# of molecules'),
- 'conc':('PoolBase', 'getConc', 1000, 'Concentration (uM)' ),
- 'volume':('PoolBase', 'getVolume', 1e18, 'Volume (um^3)' ),
- 'current':('VClamp', 'getCurrent', 1e9, 'Holding Current (nA)')
- }
-
- save_graphs = moose.Neutral( self.modelPath + '/save_graphs' )
- dummy = moose.element( '/' )
- k = 0
-
- for i in self.saveList:
- pair = i[0] + " " + i[1]
- dendCompts = self.elecid.compartmentsFromExpression[ pair ]
- spineCompts = self.elecid.spinesFromExpression[ pair ]
- plotObj, plotField = self._parseComptField( dendCompts, i, knownFields )
- plotObj2, plotField2 = self._parseComptField( spineCompts, i, knownFields )
- assert( plotField == plotField2 )
- plotObj3 = plotObj + plotObj2
- numPlots = sum( i != dummy for i in plotObj3 )
- if numPlots > 0:
- save_tabname = save_graphs.path + '/save_plot' + str(k)
- scale = knownFields[i[3]][2]
- units = knownFields[i[3]][3]
- self.saveNames.append( ( save_tabname, i[4], k, scale, units ) )
- k += 1
- if i[3] == 'n' or i[3] == 'conc' or i[3] == 'volume' or i[3] == 'Gbar':
- save_tabs = moose.Table2( save_tabname, numPlots )
- save_vtabs = moose.vec( save_tabs )
- else:
- save_tabs = moose.Table( save_tabname, numPlots )
- save_vtabs = moose.vec( save_tabs )
- if i[3] == 'spikeTime':
- save_vtabs.threshold = -0.02 # Threshold for classifying Vm as a spike.
- save_vtabs.useSpikeMode = True # spike detect mode on
- q = 0
- for p in [ x for x in plotObj3 if x != dummy ]:
- moose.connect( save_vtabs[q], 'requestOut', p, plotField )
- q += 1
-
- def _getTimeSeriesTable( self ):
-
- '''
- This function gets the list with all the details of the simulation
- required for plotting.
- This function adds flexibility in terms of the details
- we wish to store.
- '''
-
- knownFields = {
- 'Vm':('CompartmentBase', 'getVm', 1000, 'Memb. Potential (mV)' ),
- 'spikeTime':('CompartmentBase', 'getVm', 1, 'Spike Times (s)'),
- 'Im':('CompartmentBase', 'getIm', 1e9, 'Memb. current (nA)' ),
- 'inject':('CompartmentBase', 'getInject', 1e9, 'inject current (nA)' ),
- 'Gbar':('ChanBase', 'getGbar', 1e9, 'chan max conductance (nS)' ),
- 'Gk':('ChanBase', 'getGk', 1e9, 'chan conductance (nS)' ),
- 'Ik':('ChanBase', 'getIk', 1e9, 'chan current (nA)' ),
- 'ICa':('NMDAChan', 'getICa', 1e9, 'Ca current (nA)' ),
- 'Ca':('CaConcBase', 'getCa', 1e3, 'Ca conc (uM)' ),
- 'n':('PoolBase', 'getN', 1, '# of molecules'),
- 'conc':('PoolBase', 'getConc', 1000, 'Concentration (uM)' ),
- 'volume':('PoolBase', 'getVolume', 1e18, 'Volume (um^3)' )
- }
-
- '''
- This takes data from plotList
- saveList is exactly like plotList but with a few additional arguments:
- ->It will have a resolution option, i.e., the number of decimal figures to which the value should be rounded
- ->There is a list of "saveAs" formats
- With saveList, the user will able to set what all details he wishes to be saved.
- '''
-
- for i,ind in enumerate(self.saveNames):
- pair = self.saveList[i][0] + " " + self.saveList[i][1]
- dendCompts = self.elecid.compartmentsFromExpression[ pair ]
- spineCompts = self.elecid.spinesFromExpression[ pair ]
- # Here we get the object details from plotList
- savePlotObj, plotField = self._parseComptField( dendCompts, self.saveList[i], knownFields )
- savePlotObj2, plotField2 = self._parseComptField( spineCompts, self.saveList[i], knownFields )
- savePlotObj3 = savePlotObj + savePlotObj2
-
- rowList = list(ind)
- save_vtab = moose.vec( ind[0] )
- t = np.arange( 0, save_vtab[0].vector.size, 1 ) * save_vtab[0].dt
-
- rowList.append(save_vtab[0].dt)
- rowList.append(t)
- rowList.append([jvec.vector * ind[3] for jvec in save_vtab]) #get values
- rowList.append(self.saveList[i][3])
- rowList.append(filter(lambda obj: obj.path != '/', savePlotObj3)) #this filters out dummy elements
-
- if (type(self.saveList[i][-1])==int):
- rowList.append(self.saveList[i][-1])
- else:
- rowList.append(12)
-
- self.tabForXML.append(rowList)
- rowList = []
-
- timeSeriesTable = self.tabForXML # the list with all the details of plot
- return timeSeriesTable
-
- def _writeXML( self, filename, timeSeriesData ): #to write to XML file
-
- plotData = timeSeriesData
- print("[CAUTION] The '%s' file might be very large if all the compartments are to be saved." % filename)
+ def _writeXML( self, plotData, time, vtab ):
+ tabname = plotData[0]
+ idx = plotData[1]
+ scale = plotData[2]
+ units = plotData[3]
+ rp = plotData[4]
+ filename = rp.saveFile[:-4] + str(idx) + '.xml'
root = etree.Element("TimeSeriesPlot")
parameters = etree.SubElement( root, "parameters" )
if self.params == None:
@@ -926,81 +873,59 @@ rdesigneur.rmoogli.updateMoogliViewer()
#plotData contains all the details of a single plot
title = etree.SubElement( root, "timeSeries" )
- title.set( 'title', str(plotData[1]))
- title.set( 'field', str(plotData[8]))
- title.set( 'scale', str(plotData[3]))
- title.set( 'units', str(plotData[4]))
- title.set( 'dt', str(plotData[5]))
+ title.set( 'title', rp.title)
+ title.set( 'field', rp.field)
+ title.set( 'scale', str(scale) )
+ title.set( 'units', units)
+ title.set( 'dt', str(vtab[0].dt) )
+ res = rp.saveResolution
p = []
- assert(len(plotData[7]) == len(plotData[9]))
-
- res = plotData[10]
- for ind, jvec in enumerate(plotData[7]):
+ for t, v in zip( time, vtab ):
p.append( etree.SubElement( title, "data"))
- p[-1].set( 'path', str(plotData[9][ind].path))
- p[-1].text = ''.join( str(round(value,res)) + ' ' for value in jvec )
-
+ p[-1].set( 'path', v.path )
+ p[-1].text = ''.join( str(round(y,res)) + ' ' for y in v.vector )
tree = etree.ElementTree(root)
tree.write(filename)
- def _writeCSV(self, filename, timeSeriesData):
-
- plotData = timeSeriesData
- dataList = []
- header = []
- time = plotData[6]
- res = plotData[10]
-
- for ind, jvec in enumerate(plotData[7]):
- header.append(plotData[9][ind].path)
- dataList.append([round(value,res) for value in jvec.tolist()])
- dl = [tuple(lst) for lst in dataList]
- rows = zip(tuple(time), *dl)
- header.insert(0, "time")
-
+ def _writeCSV( self, plotData, time, vtab ):
+ tabname = plotData[0]
+ idx = plotData[1]
+ scale = plotData[2]
+ units = plotData[3]
+ rp = plotData[4]
+ filename = rp.saveFile[:-4] + str(idx) + '.csv'
+
+ header = ["time",]
+ valMatrix = [time,]
+ header.extend( [ v.path for v in vtab ] )
+ valMatrix.extend( [ v.vector for v in vtab ] )
+ nv = np.array( valMatrix ).T
with open(filename, 'wb') as f:
writer = csv.writer(f, quoting=csv.QUOTE_MINIMAL)
writer.writerow(header)
- for row in rows:
+ for row in nv:
writer.writerow(row)
##########****SAVING*****###############
- def _saveFormats(self, timeSeriesData, k, *filenames):
- "This takes in the filenames and writes to corresponding format."
- if filenames:
- for filename in filenames:
- for name in filename:
- print (name)
- if name[-4:] == '.xml':
- self._writeXML(name, timeSeriesData)
- print(name, " written")
- elif name[-4:] == '.csv':
- self._writeCSV(name, timeSeriesData)
- print(name, " written")
- else:
- print("not possible")
- pass
- else:
- pass
def _save( self ):
- timeSeriesTable = self._getTimeSeriesTable()
- for i,sList in enumerate(self.saveList):
-
- if (len(sList) >= 6) and (type(sList[5]) != int):
- self.saveAs.extend(filter(lambda fmt: type(fmt)!=int, sList[5:]))
- try:
- timeSeriesData = timeSeriesTable[i]
- except IndexError:
- print("The object to be plotted has all dummy elements.")
- pass
- self._saveFormats(timeSeriesData, i, self.saveAs)
- self.saveAs=[]
+ for i in self.saveNames:
+ tabname = i[0]
+ idx = i[1]
+ scale = i[2]
+ units = i[3]
+ rp = i[4] # The rplot data structure, it has the setup info.
+
+ vtab = moose.vec( tabname )
+ t = np.arange( 0, vtab[0].vector.size, 1 ) * vtab[0].dt
+ ftype = rp.filename[-4:]
+ if ftype == '.xml':
+ self._writeXML( i, t, vtab )
+ elif ftype == '.csv':
+ self._writeCSV( i, t, vtab )
else:
- pass
- else:
- pass
+ print("Save format '{}' not known, please use .csv or .xml".format( ftype ) )
################################################################
# Here we set up the stims
@@ -1008,9 +933,11 @@ rdesigneur.rmoogli.updateMoogliViewer()
def _buildStims( self ):
knownFields = {
'inject':('CompartmentBase', 'setInject'),
- 'Ca':('CaConcBase', 'getCa'),
+ 'Ca':('CaConcBase', 'setCa'),
'n':('PoolBase', 'setN'),
'conc':('PoolBase', 'setConc'),
+ 'nInit':('PoolBase', 'setNinit'),
+ 'concInit':('PoolBase', 'setConcInit'),
'vclamp':('CompartmentBase', 'setInject'),
'randsyn':('SynChan', 'addSpike'),
'periodicsyn':('SynChan', 'addSpike')
@@ -1019,17 +946,17 @@ rdesigneur.rmoogli.updateMoogliViewer()
k = 0
# Stimlist = [path, geomExpr, relPath, field, expr_string]
for i in self.stimList:
- pair = i[0] + " " + i[1]
+ pair = i.elecpath + " " + i.geom_expr
dendCompts = self.elecid.compartmentsFromExpression[ pair ]
spineCompts = self.elecid.spinesFromExpression[ pair ]
#print( "pair = {}, numcompts = {},{} ".format( pair, len( dendCompts), len( spineCompts ) ) )
- if i[3] == 'vclamp':
+ if i.field == 'vclamp':
stimObj3 = self._buildVclampOnCompt( dendCompts, spineCompts, i )
stimField = 'commandIn'
- elif i[3] == 'randsyn':
+ elif i.field == 'randsyn':
stimObj3 = self._buildSynInputOnCompt( dendCompts, spineCompts, i )
stimField = 'setRate'
- elif i[3] == 'periodicsyn':
+ elif i.field == 'periodicsyn':
stimObj3 = self._buildSynInputOnCompt( dendCompts, spineCompts, i, doPeriodic = True )
stimField = 'setRate'
else:
@@ -1042,9 +969,9 @@ rdesigneur.rmoogli.updateMoogliViewer()
funcname = stims.path + '/stim' + str(k)
k += 1
func = moose.Function( funcname )
- func.expr = i[4]
- if i[3] == 'vclamp': # Hack to clean up initial condition
- func.doEvalAtReinit = 1
+ func.expr = i.expr
+ #if i[3] == 'vclamp': # Hack to clean up initial condition
+ func.doEvalAtReinit = 1
for q in stimObj3:
moose.connect( func, 'valueOut', q, stimField )
@@ -1267,6 +1194,7 @@ rdesigneur.rmoogli.updateMoogliViewer()
if len( comptlist ) == 0:
raise BuildError( "validateChem: no compartment on: " + cpath )
+ '''
if len( comptlist ) == 1:
return;
@@ -1276,6 +1204,7 @@ rdesigneur.rmoogli.updateMoogliViewer()
print(cpath, sortedComptlist)
raise BuildError( "validateChem: Require 3 chem compartments, have: " + str( len( sortedComptlist ) ) )
'''
+ '''
if not( sortedComptlist[0].name.lower() == 'dend' and \
sortedComptlist[1].name.lower() == 'spine' and \
sortedComptlist[2].name.lower() == 'psd' ):
@@ -1287,38 +1216,115 @@ rdesigneur.rmoogli.updateMoogliViewer()
#################################################################
+ def _isModelFromKkit( self ):
+ for i in self.chemProtoList:
+ if i[0][-2:] == ".g":
+ return True
+ return False
+
+ def _assignComptNamesFromKkit( self ):
+ '''
+ Algorithm: Identify compts by volume. Assume a couple of standard
+ orders depending on the addSomaChemCompt and addEndoChemCompt
+ flags:\n
+ ascc = 0, aecc = 0: dend, spine, psd.\n
+ ascc = 0, aecc = 1: dend, dend_endo, spine, spine_endo, psd, psd_endo.\n
+ ascc = 1, aecc = 0: soma, dend, spine, psd.\n
+ ascc = 1, aecc = 1: soma, soma_endo, dend, dend_endo, spine, spine_endo, psd, psd_endo.\n
+ In all cases, a shorter list of chem compartments will only fill
+ up the list to the available length.\n
+ soma_endo can be thought of as nucleus.\n
+ psd_endo doesn't really make sense, as peri-synaptic region really
+ needs to talk both to PSD and to spine bulk.
+ '''
+ comptList = moose.wildcardFind( self.chemid.path + '/#[ISA=ChemCompt]' )
+ #print( "comptList = {}".format ( [i.name for i in comptList]) )
+ if len( comptList ) < 2:
+ if comptList[0].name != 'dend':
+ comptList[0].name = 'dend'
+ return comptList
+ if not self._isModelFromKkit():
+ print( "Not isModelfromKkit" )
+ return comptList
+ sortedComptList = sorted( comptList, key=lambda x: -x.volume )
+ if self.addSomaChemCompt:
+ if self.addEndoChemCompt:
+ sortedNames = ["soma", "soma_endo", "dend", "dend_endo", "spine", "spine_endo", "psd", "psd_endo", ]
+ else:
+ sortedNames = ["soma", "dend", "spine","psd"]
+ else:
+ if self.addEndoChemCompt:
+ sortedNames = ["dend", "dend_endo", "spine", "spine_endo", "psd", "psd_endo", ]
+ else:
+ sortedNames = ["dend", "spine","psd"]
+
+ #print( "sortedNames = {}".format( sortedNames ) )
+ for i in range(min( len( sortedComptList ), len( sortedNames ) ) ):
+ #print( "SortedClist= {}".format( sortedComptList[i] ))
+ if sortedComptList[i].name != sortedNames[i]:
+ sortedComptList[i].name = sortedNames[i]
+ return sortedComptList
+
+
def _buildNeuroMesh( self ):
- comptlist = moose.wildcardFind( self.chemid.path + '/#[ISA=ChemCompt]' )
- sortedComptList = sorted( comptlist, key=lambda x: -x.volume )
- # A little juggling here to put the chem pathways onto new meshes.
+ # Address the following cases:
+ # - dend alone
+ # - dend with spine and PSD
+ # - above plus n endo meshes located as per name suffix:
+ # er_1_dend, vesicle_2_spine,
+ # - above plus presyn, e.g.:
+ # er_1_dend, vesicle_2_spine,
+ # - above plus soma
+ # - soma alone
+ # - soma plus n endo meshes
+
self.chemid.name = 'temp_chem'
newChemid = moose.Neutral( self.model.path + '/chem' )
- self.dendCompt = moose.NeuroMesh( newChemid.path + '/dend' )
- self.dendCompt.geometryPolicy = 'cylinder'
- self.dendCompt.separateSpines = 0
- if len( sortedComptList ) == 3:
+ comptlist = self._assignComptNamesFromKkit()
+ comptdict = { i.name:i for i in comptlist }
+ if len(comptdict) == 1 or 'dend' in comptdict:
+ self.dendCompt = moose.NeuroMesh( newChemid.path + '/dend' )
+ self.dendCompt.geometryPolicy = 'cylinder'
+ self.dendCompt.separateSpines = 0
+ self._moveCompt( comptdict['dend'], self.dendCompt )
+ comptdict['dend'] = self.dendCompt
+
+ if 'dend' in comptdict and 'spine' in comptdict:
+ #print( "comptdict = {}".format (comptdict ) )
self.dendCompt.separateSpines = 1
self.spineCompt = moose.SpineMesh( newChemid.path + '/spine' )
moose.connect( self.dendCompt, 'spineListOut', self.spineCompt, 'spineList' )
+ self._moveCompt( comptdict['spine'], self.spineCompt )
+ comptdict['spine'] = self.spineCompt
+ # We need to make a PSD in the spine even if it is uninhabited.
self.psdCompt = moose.PsdMesh( newChemid.path + '/psd' )
moose.connect( self.dendCompt, 'psdListOut', self.psdCompt, 'psdList','OneToOne')
- #Move the old reac systems onto the new compartments.
- self._moveCompt( sortedComptList[0], self.dendCompt )
- if len( sortedComptList ) == 3:
- self._moveCompt( sortedComptList[1], self.spineCompt )
- self._moveCompt( sortedComptList[2], self.psdCompt )
+ if 'psd' in comptdict: # Shift stuff over if any.
+ self._moveCompt( comptdict['psd'], self.psdCompt )
+ comptdict['psd'] = self.psdCompt
+
self.dendCompt.diffLength = self.diffusionLength
self.dendCompt.subTree = self.cellPortionElist
+ for i in comptdict:
+ if len(i) > 5:
+ if i[-5:] == '_endo':
+ endo = moose.EndoMesh( newChemid.path + '/' +i )
+ surround = comptdict[i[0:-5]]
+ self._endos.append( [endo, surround] )
+ #print( "{}****{}".format(i[0:-5], comptdict[i[0:-5]]))
+ self._moveCompt( comptdict[i], endo )
+ comptdict[i] = endo
moose.delete( self.chemid )
self.chemid = newChemid
+
#################################################################
def _configureSolvers( self ) :
if not hasattr( self, 'chemid' ):
return
if not hasattr( self, 'dendCompt' ):
raise BuildError( "configureSolvers: no chem meshes defined." )
- fixXreacs.fixXreacs( self.chemid.path )
+ fixXreacs( self.chemid.path )
dmksolve = moose.Ksolve( self.dendCompt.path + '/ksolve' )
dmdsolve = moose.Dsolve( self.dendCompt.path + '/dsolve' )
dmstoich = moose.Stoich( self.dendCompt.path + '/stoich' )
@@ -1349,6 +1355,8 @@ rdesigneur.rmoogli.updateMoogliViewer()
pmstoich.compartment = self.psdCompt
pmstoich.ksolve = pmksolve
pmstoich.dsolve = pmdsolve
+ if len( moose.wildcardFind( 'self.psdCompt.path/##[ISA=PoolBase]' ) ) == 0:
+ moose.Pool( self.psdCompt.path + '/dummy' )
pmstoich.path = self.psdCompt.path + "/##"
# Here we should test what kind of geom we have to use
@@ -1359,6 +1367,23 @@ rdesigneur.rmoogli.updateMoogliViewer()
# set up the connections so that the spine volume scaling can happen
self.elecid.setSpineAndPsdMesh( self.spineCompt, self.psdCompt)
self.elecid.setSpineAndPsdDsolve( smdsolve, pmdsolve )
+ for i in self._endos:
+ i[0].isMembraneBound = True
+ i[0].surround = i[1]
+ #i[0].elecComptMap = i[1].elecComptMap
+ path = i[0].path
+ #print( "Doing endo {} inside {}".format( path, i[1].path ) )
+ if self.useGssa:
+ eksolve = moose.Gsolve( path + '/ksolve' )
+ else:
+ eksolve = moose.Ksolve( path + '/ksolve' )
+ edsolve = moose.Dsolve( path + '/dsolve' )
+ estoich = moose.Stoich( path + '/stoich' )
+ estoich.compartment = i[0]
+ estoich.ksolve = eksolve
+ estoich.dsolve = edsolve
+ estoich.path = path + "/##"
+ edsolve.buildMeshJunctions( moose.element(i[1].path + '/dsolve' ))
################################################################
def _loadChem( self, fname, chemName ):
@@ -1369,6 +1394,7 @@ rdesigneur.rmoogli.updateMoogliViewer()
print("loadChem: No compartment found in file: ", fname)
return
# Sort comptlist in decreasing order of volume
+ '''
sortedComptlist = sorted( comptlist, key=lambda x: -x.volume )
if ( len( sortedComptlist ) >= 1 ):
sortedComptlist[0].name = 'dend'
@@ -1376,6 +1402,7 @@ rdesigneur.rmoogli.updateMoogliViewer()
sortedComptlist[1].name = 'spine'
if ( len( sortedComptlist ) >= 3 ):
sortedComptlist[2].name = 'psd'
+ '''
################################################################
@@ -1384,6 +1411,7 @@ rdesigneur.rmoogli.updateMoogliViewer()
for i in moose.wildcardFind( a.path + '/#' ):
if ( i.name != 'mesh' ):
moose.move( i, b )
+ #print( "Moving {} {} to {}".format( i.className, i.name, b.name ))
moose.delete( a )
################################################################
def _buildAdaptor( self, meshName, elecRelPath, elecField, \
@@ -1458,3 +1486,94 @@ rdesigneur.rmoogli.updateMoogliViewer()
moose.connect( i[3], 'requestOut', chemVec[j], chemFieldSrc)
msg = moose.connect( i[3], 'output', elObj, elecFieldDest )
+
+#######################################################################
+# Some helper classes, used to define argument lists.
+#######################################################################
+
+class baseplot:
+ def __init__( self,
+ elecpath='soma', geom_expr='1', relpath='.', field='Vm' ):
+ self.elecpath = elecpath
+ self.geom_expr = geom_expr
+ self.relpath = relpath
+ self.field = field
+
+class rplot( baseplot ):
+ def __init__( self,
+ elecpath = 'soma', geom_expr = '1', relpath = '.', field = 'Vm',
+ title = 'Membrane potential',
+ mode = 'time',
+ ymin = 0.0, ymax = 0.0,
+ saveFile = "", saveResolution = 3, show = True ):
+ baseplot.__init__( self, elecpath, geom_expr, relpath, field )
+ self.title = title
+ self.mode = mode # Options: time, wave, wave_still, raster
+ self.ymin = ymin # If ymin == ymax, it autoscales.
+ self.ymax = ymax
+ if len( saveFile ) < 5:
+ self.saveFile = ""
+ else:
+ f = saveFile.split('.')
+ if len(f) < 2 or ( f[-1] != 'xml' and f[-1] != 'csv' ):
+ raise BuildError( "rplot: Filetype is '{}', must be of type .xml or .csv.".format( f[-1] ) )
+ self.saveFile = saveFile
+ self.show = show
+
+ def printme( self ):
+ print( "{}, {}, {}, {}, {}, {}, {}, {}, {}, {}".format(
+ self.elecpath,
+ self.geom_expr, self.relpath, self.field, self.title,
+ self.mode, self.ymin, self.ymax, self.saveFile, self.show ) )
+
+ @staticmethod
+ def convertArg( arg ):
+ if isinstance( arg, rplot ):
+ return arg
+ elif isinstance( arg, list ):
+ return rplot( *arg )
+ else:
+ raise BuildError( "rplot initialization failed" )
+
+class rmoog( baseplot ):
+ def __init__( self,
+ elecpath = 'soma', geom_expr = '1', relpath = '.', field = 'Vm',
+ title = 'Membrane potential',
+ ymin = 0.0, ymax = 0.0,
+ show = True ): # Could put in other display options.
+ baseplot.__init__( self, elecpath, geom_expr, relpath, field )
+ self.title = title
+ self.ymin = ymin # If ymin == ymax, it autoscales.
+ self.ymax = ymax
+ self.show = show
+
+ @staticmethod
+ def convertArg( arg ):
+ if isinstance( arg, rmoog ):
+ return arg
+ elif isinstance( arg, list ):
+ return rmoog( *arg )
+ else:
+ raise BuildError( "rmoog initialization failed" )
+
+ # Stimlist = [path, geomExpr, relPath, field, expr_string]
+class rstim( baseplot ):
+ def __init__( self,
+ elecpath = 'soma', geom_expr = '1', relpath = '.', field = 'inject', expr = '0'):
+ baseplot.__init__( self, elecpath, geom_expr, relpath, field )
+ self.expr = expr
+
+ def printme( self ):
+ print( "{}, {}, {}, {}, {}, {}, {}, {}, {}, {}".format(
+ self.elecpath,
+ self.geom_expr, self.relpath, self.field, self.expr ) )
+
+ @staticmethod
+ def convertArg( arg ):
+ if isinstance( arg, rstim ):
+ return arg
+ elif isinstance( arg, list ):
+ return rstim( *arg )
+ else:
+ raise BuildError( "rstim initialization failed" )
+
diff --git a/python/rdesigneur/rdesigneurProtos.py b/python/rdesigneur/rdesigneurProtos.py
index ec5d705936d16a3fe624afa12dead0f83dc99e7d..920caabaa6ce0a2eb8c1717f19b019e69006fd60 100644
--- a/python/rdesigneur/rdesigneurProtos.py
+++ b/python/rdesigneur/rdesigneurProtos.py
@@ -757,8 +757,8 @@ def makePassiveHHsoma(name = 'passiveHHsoma', parent='/library'):
if not moose.exists( elecpath ):
elecid = moose.Neuron( elecpath )
dia = 500e-6
- soma = buildComptWrapper( elecid, 'soma', dia, dia, 0.0,
- 0.33333333, 3000, 0.01 )
+ soma = buildCompt( elecid, 'soma', dx = dia, dia = dia, x = 0.0,
+ RM = 0.33333333, RA = 3000, CM = 0.01 )
soma.initVm = -65e-3 # Resting of -65, from HH
soma.Em = -54.4e-3 # 10.6 mV above resting of -65, from HH
else:
diff --git a/python/rdesigneur/rmoogli.py b/python/rdesigneur/rmoogli.py
index f98549c0b2f9b4109774da64d57a68ebbb9396a5..16317b5686aca2abb90e58faad963dcd17b21061 100644
--- a/python/rdesigneur/rmoogli.py
+++ b/python/rdesigneur/rmoogli.py
@@ -20,21 +20,29 @@ def makeMoogli( rd, mooObj, args, fieldInfo ):
# Cleaner still would be to have the C code give a vector of values
# For now it means something different for chem and elec displays.
#moogliEntry = [elecPath,bool,whichObjToDisplay,FieldToDisplay,titleForDisplay,rangeMin,rangeMax]
- mooField = args[3]
- relObjPath = args[2]
+ mooField = args.field
+ relObjPath = args.relpath
numMoogli = len( mooObj )
+ if args.ymin != args.ymax:
+ ymin = args.ymin
+ ymax = args.ymax
+ else:
+ ymin = fieldInfo[4]
+ ymax = fieldInfo[5]
+ print( "fieldinfo = {}, ymin = {}, ymax = {}".format( fieldInfo, ymin, ymax ))
viewer = moogul.MooView()
if mooField == 'n' or mooField == 'conc':
#moogul.updateDiffCoords( mooObj )
reacSystem = moogul.MooReacSystem( mooObj, fieldInfo,
field = mooField, relativeObj = relObjPath,
- valMin = args[5], valMax = args[6] )
+ valMin = ymin, valMax = ymax )
viewer.addDrawable( reacSystem )
else:
neuron = moogul.MooNeuron( rd.elecid, fieldInfo,
field = mooField, relativeObj = relObjPath,
- valMin = args[5], valMax = args[6] )
+ valMin = ymin, valMax = ymax )
+ print( "min = {}, max = {}".format(ymin, ymax) )
viewer.addDrawable( neuron )
return viewer
diff --git a/randnum/Binomial.cpp b/randnum/Binomial.cpp
deleted file mode 100644
index 2014c283cd19ff846e883e71e2940f386ec7dfac..0000000000000000000000000000000000000000
--- a/randnum/Binomial.cpp
+++ /dev/null
@@ -1,388 +0,0 @@
-/*******************************************************************
- * File: Binomial.cpp
- * Description:
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2007-10-28 13:44:46
- ********************************************************************/
-/**********************************************************************
- ** This program is part of 'MOOSE', the
- ** Messaging Object Oriented Simulation Environment,
- ** also known as GENESIS 3 base code.
- ** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
- ** It is made available under the terms of the
- ** GNU General Public License version 2
- ** See the file COPYING.LIB for the full notice.
- **********************************************************************/
-
-#ifndef _BINOMIAL_CPP
-#define _BINOMIAL_CPP
-#include <cmath>
-#include "randnum.h"
-#include "utility/numutil.h"
-#include "Binomial.h"
-#include <vector>
-#include <iostream>
-#include <climits>
-using namespace std;
-
-// First 10 entries in lookup table
-const double fc[] = {
- 0.08106146679532726,
- 0.04134069595540929,
- 0.02767792568499834,
- 0.02079067210376509,
- 0.01664469118982119,
- 0.01387612882307075,
- 0.01189670994589177,
- 0.01041126526197209,
- 0.009255462182712733,
- 0.008330563433362871
-};
-
-
-/// Insert first 100 elements in lookup table
-const vector <double> initializeLookupTable()
-{
- static vector <double> table;
-
- for ( int i = 0; i < 10; ++i )
- {
- table.push_back(fc[i]);
- }
- for ( int i = 10; i < 100; ++i )
- {
- double denom = 1.0/(i+1);
- double value = (0.083333333333333333 - (0.002777777777777778 - 0.0007936508*denom*denom)*denom*denom)*denom;
- table.push_back(value);
- }
- return table;
-}
-static const vector <double> lookupTable = initializeLookupTable();
-
-
-
-/**
- retrieve fc value from table or calculate it depending on the value of k
-*/
-inline double getFc(unsigned int k)
-{
- if (lookupTable.size() <= k )
- {
- double denom = 1.0/(k+1);
- return (0.083333333333333333 - (0.002777777777777778 - 0.0007936508*denom*denom)*denom*denom)*denom;
- }
- else
- {
- return lookupTable[k];
- }
-}
-
-/**
- Binomial distribution generator with parameters n and p. p is the
- probability of the favoured outcome, n is the number of trials.
- */
-Binomial::Binomial( long n, double p):n_(n), p_(p)
-{
-
- if (( p < 0 ) || ( p > 1 ))
- {
- cerr << "ERROR: p must be in [0,1] range." << endl;
- p = 0.0;
- return;
- }
- if ( n < 1 )
- {
- cerr << "ERROR: n must be >= 1" << endl;
- return;
- }
-
-
- double tmpMean;
- double tmp;
- isInverted_ = false;
-
-// tmpMean = n*((p < 0.5)? p : (1-p));
-
-// if ((tmpMean > 10.0))
-// {
- // the above can be simplified as: ( saves one floating point comparison, aesthetically pleasing :D )
- if ( n > 20 )
- {
- if( p < 0.5 )
- {
- p_ = p;
- }
- else
- {
- p_ = 1.0 - p;
- isInverted_ = true;
- }
- tmpMean = n*p_;
-
- tmp = sqrt(tmpMean*(1.0 - p_));
- paramC_ = tmpMean + 0.5;
- paramB_ = 1.15 + 2.53*tmp;
- paramA_ = -0.0873 + 0.0248*paramB_ + 0.01*p_;
- paramAlpha_ = (2.83 + 5.1/paramB_)*tmp;
- paramUr_ = 0.43;
- paramVr_ = 0.92 - 4.2/paramB_;
- paramUrVr_ = 0.86*paramVr_;
- paramM_ = floor(tmpMean+p_);
- paramR_ = floor(p_/(1-p_));
- paramNr_ = (n+1)*paramR_;
- paramNpq_ = tmpMean*(1-p_);
- }
- mean_ = n_*p_;
-}
-
-long Binomial::getN() const
-{
- return n_;
-}
-
-double Binomial::getP() const
-{
- if ( isInverted_)
- {
- return 1 - p_;
- }
- else
- {
- return p_;
- }
-}
-
-double Binomial::getMean() const
-{
- if (isInverted_)
- {
- return (n_ - mean_);
- }else{
- return mean_;
- }
-}
-
-double Binomial::getVariance() const
-{
- static double variance = sqrt(n_*p_*(1.0-p_));
- return variance;
-}
-
-/**
- returns the next random number in this distribution as the ratio of
- the number of positive outcomes and the total number of trials.
- This is the most naive implementation. This is ok for small n.
- For large n such that mean > 10, we use BTRD algorithm by Hoermann.
- See documentation of generateTrd() for further detail.
-*/
-double Binomial::getNextSample() const
-{
- double sample = 0;
- if ( p_ == 0 )
- {
- sample = (double)0;
- }
- else if ( isClose<double>(1.0,p_, DBL_EPSILON))
- {
- sample = (double)n_;
- }
- else
- {
- if ( mean_ > 10 )
- {
- sample = isInverted_? n_ - generateTrd(): generateTrd();
- }
- else
- {
- for ( unsigned int i = 0; i < n_; ++i)
- {
- double myRand = mtrand();
- if ( myRand < p_ )
- {
- sample+=1;
- }
- }
- }
-// cerr << "Sample value: " << sample << " " << isInverted_<< endl;
- }
-
- return sample;
-}
-
-/**
- Generate binomially distributed random numbers using transformed
- rejection with decomposition as described in "The Generation of
- Binomial Random Variable" by W Hoermann.
-*/
-double Binomial::generateTrd() const
-{
-
- double varV;
- double varU;
- double varUs;
- double varK;
- double varKm;
- double varF;
- double varNm;
- double varH;
- double varNk;
- double varI;
- double varRho;
- double varT;
-
- while ( true )
- {
- // 1a: generate a uniform random number v
- varV = mtrand();
- if ( varV <= paramUrVr_ )
- {
- // 1b: if v <= urvr then u = v/vr - 0.43
- double varU = varV/paramVr_ - 0.43;
- // 1c: return floor( (2*a/(0.5 - |u|) + b ) * u + c )
- return floor((2*paramA_/(0.5 - fabs(varU)) + paramB_ )*varU+paramC_);
- }
- // 2a: if ( v >= vr ) then generate a uniform random number u in (-0.5,+0.5)
- if ( varV >= paramVr_ )
- {
- varU = mtrand() - 0.5;
- }
- else // 2b: otherwise
- {
- // 2b(i): set u = v/vr - 0.93
- varU = varV/paramVr_ - 0.93;
- // 2b(ii): set u = sign(u)*0.5 - u
- varU = (varU > 0)? 0.5 - varU : - 0.5 - varU;
- // 2b(iii) generate a uniform random number v in (0,vr)
- varV = mtrand()*paramVr_;
- }
- // 3.0a: us = 0.5 - |u|
- varUs = (varU < 0) ? 0.5 + varU : 0.5 - varU;
- // 3.0b: k = floor( ( 2*a/us + b )*u + c )
- varK = floor( (2*paramA_/varUs+paramB_)*varU + paramC_);
- // 3.0c: if k < 0 or k > n go to (1)
- if ( (varK < 0) || ( varK > n_ ))
- {
- continue;
- }
-
- // 3.0d: v = v*alpha/(a/(us*us)+b)
- varV = varV*paramAlpha_/(paramA_/(varUs*varUs) + paramB_ );
- // 3.0e: km = | k - m |
- varKm = ( varK < paramM_)? paramM_ - varK : varK - paramM_;
- // 3.0f: if km > 15 go to 3.2 , else ...
- if ( varKm <= 15 )
- {
- // 3.1: recursive evaluation of f(k)
- // 3.1a: f = 1
- varF = 1;
- // 3.1b: if (m < k)
- if ( paramM_ < varK )
- {
- // 3.1b(i): set i = m
- varI = paramM_;
- // 3.1b(ii): repeat i = i+1, f = f*(nr/i - r) until (i == k).
- while ( varI < varK )
- {
- ++varI;
- varF *= (paramNr_/varI - paramR_);
- }
- }
- else // 3.1c: otherwise ...
- {
- // 3.1c(i) if ( m > k)
- if ( paramM_ > varK )
- {
- // 3.1c(ii): i = k
- varI = varK;
- // 3.1c(ii): repeat i = i+1, v = v*(nr/i - r) until (i == m).
- while ( varI < paramM_)
- {
- ++varI;
- varV *= (paramNr_/varI -paramR_);
- }
- }
- //3.1d: if v <= f return k, otherwise goto (1)
- if ( varV <= varF )
- {
- return varK;
- }
- }
- }
- // 3.2: Squeeze acceptance or rejection
- // 3.2a: v = log(v)
- varV = log(varV);
- // 3.2b: rho = ( km/npq )*(((km/3+0.625)*km + 1/6)/npq+0.5)
- varRho = (varKm/paramNpq_)*(((varKm/3.0+ 0.625)*varKm+0.16666666666666667)/paramNpq_+0.5);
- // 3.2c: t = - km*km/(2*npq)
- varT = -varKm*varKm*0.5/paramNpq_;
- // 3.2d: if ( v < t - rho ) then return k
- if ( varV < ( varT - varRho ))
- {
- return varK;
- }
- // 3.2e: if ( v > t+rho ) then goto (1)
- if ( varV > (varT + varRho))
- {
- continue;
- }
- // 3.3: Set-up for 3.4
- // 3.3a: nm = n - m + 1
- varNm = n_ - paramM_ + 1;
- // 3.3b: h = (m+0.5)*log((m+1)/(r*nm)) + fc(m) + fc(n-m)
- varH = (paramM_ + 0.5)*log((paramM_+1)/(paramR_*varNm)) + getFc((int)paramM_) + getFc((int)(n_-paramM_));
- // 3.4: Final acceptance-rejection test
- // 3.4a: nk = n - k + 1;
- varNk = n_ - varK + 1;
- // 3.4b: if ( v <= h + (n+1)*log(nm/nk) + (k+0.5)*log(nk*r/(k+1)) - fc(k) -fc(n-k) then return k
- if ( varV <= varH + (n_ + 1)*log(varNm/varNk) + ( varK + 0.5)*log(varNk*paramR_/(varK+1)) - getFc((int)varK) - getFc((int)(n_ - varK)))
- {
- return varK;
- }
- // 3.4c: otherwise goto (1)
- }
-}
-
-
-/**
- TODO: what to do to automatically test the quality of the random
- number generation? We can check the mean and variance perhaps?
- We should also check the plot of the distribution manually.
-*/
-void testBinomial()
-{
-
- int trialMin = 2;
- int trialMax = trialMin*1000;
-
- double tmp;
-
-
- for ( int i = trialMin; i < trialMax; i =(int)( i* 1.5) )
- {
- for ( double p = 0.1; p < .95; p += 0.1)
- {
- Binomial b(i, p);
- tmp = 0;
- for ( int j = 0; j < i; ++j )
- {
- tmp += b.getNextSample();
- }
- cerr << "Diff( " << i << "," << p << ") "
- << tmp/i - b.getMean()
- << " [ " << tmp/i << " - " << b.getMean() <<" ]"
- << endl;
- }
- }
-}
-#if 0 // test main
-int main(void)
-{
- testBinomial();
- return 0;
-}
-
-#endif // test main
-
-
-#endif
diff --git a/randnum/Binomial.h b/randnum/Binomial.h
deleted file mode 100644
index 06401f4d32061bea9b68d11955572e79f04bb423..0000000000000000000000000000000000000000
--- a/randnum/Binomial.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*******************************************************************
- * File: Binomial.h
- * Description: Implements binomial distribution
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2007-10-28 13:42:24
- ********************************************************************/
-/**********************************************************************
-** This program is part of 'MOOSE', the
-** Messaging Object Oriented Simulation Environment,
-** also known as GENESIS 3 base code.
-** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
-** It is made available under the terms of the
-** GNU General Public License version 2
-** See the file COPYING.LIB for the full notice.
-**********************************************************************/
-
-#ifndef _BINOMIAL_H
-#define _BINOMIAL_H
-#include "Probability.h"
-
-class Binomial:public Probability
-{
- public:
- Binomial(){};
- Binomial( long n, double p);
- long getN() const;
- double getP() const;
- double getMean() const;
- double getVariance() const;
- double getNextSample() const;
-
- private:
- double generateTrd() const;
- bool isInverted_;
-
- unsigned long n_;
- double p_;
- double mean_;
-
- double paramC_;
- double paramB_;
- double paramA_;
- double paramAlpha_;
- double paramUr_;
- double paramVr_;
- double paramUrVr_;
- double paramM_;
- double paramR_;
- double paramNr_;
- double paramNpq_;
-};
-
-
-#endif
diff --git a/randnum/BinomialRng.cpp b/randnum/BinomialRng.cpp
deleted file mode 100644
index 50765b2e0b2e6edf0ed37a9dbc5e1b8aeb215e0a..0000000000000000000000000000000000000000
--- a/randnum/BinomialRng.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-/*******************************************************************
- * File: BinomialRng.cpp
- * Description:
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2007-11-08 10:58:01
- ********************************************************************/
-/**********************************************************************
- ** This program is part of 'MOOSE', the
- ** Messaging Object Oriented Simulation Environment,
- ** also known as GENESIS 3 base code.
- ** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
- ** It is made available under the terms of the
- ** GNU General Public License version 2
- ** See the file COPYING.LIB for the full notice.
- **********************************************************************/
-
-#ifndef _BINOMIALRNG_CPP
-#define _BINOMIALRNG_CPP
-#include "BinomialRng.h"
-#include "Binomial.h"
-#include "utility/numutil.h"
-#include <cmath>
-extern const Cinfo* initRandGeneratorCinfo();
-
-const Cinfo* BinomialRng::initCinfo()
-{
- static ValueFinfo< BinomialRng, double > n(
- "n",
- "Parameter n of the binomial distribution. In a coin toss experiment,"
- " this is the number of tosses.",
- &BinomialRng::setN,
- &BinomialRng::getN);
- static ValueFinfo < BinomialRng, double > p(
- "p",
- "Parameter p of the binomial distribution. In a coin toss experiment,"
-" this is the probability of one of the two sides of the coin being on"
-" top.",
- &BinomialRng::setP,
- &BinomialRng::getP);
- static Finfo* binomialRngFinfos[] = {
- &n,
- &p,
- };
-
- static string doc[] = {
- "Name", "BinomialRng",
- "Author", "Subhasis Ray",
- "Description", "Binomially distributed random number generator.",
- };
- Dinfo < BinomialRng> dinfo;
- static Cinfo binomialRngCinfo(
- "BinomialRng",
- RandGenerator::initCinfo(),
- binomialRngFinfos,
- sizeof(binomialRngFinfos)/sizeof(Finfo*),
- &dinfo,
- doc,
- sizeof( doc ) / sizeof( string ));
- return &binomialRngCinfo;
-}
-
-
-static const Cinfo* binomialRngCinfo = BinomialRng::initCinfo();
-
-BinomialRng::BinomialRng()
-{
- isNSet_ = false;
- isPSet_ = false;
- isModified_ = true;
-
- n_ = 0;
- p_ = 0;
-}
-
-/**
- Set parameter n ( number of trials for a two-outcome experiment).
- This must be set before the actual generator is instantiated.
- */
-void BinomialRng::setN(double value)
-{
- unsigned long n = (unsigned long)value;
- if ( n <= 0 )
- {
- cerr << "ERROR: BinomialRng::innerSetN - n must be a positive integer." << endl;
- return;
- }
-
- if(!isNSet_)
- {
- isNSet_ = true;
- n_ = n;
- }
- else
- {
- if (n_!= n )
- {
- n_ = n;
- isModified_ = true;
- }
- }
-
- if ( isNSet_ && isPSet_ && isModified_)
- { {
- if ( rng_ )
- {
- delete rng_;
- }
- rng_ = new Binomial((unsigned long)n_,p_);
- isModified_ = false;
- }
- }
-}
-
-/**
- Returns parameter n.
- */
-double BinomialRng::getN() const
-{
- return n_;
-}
-
-/**
- Set parameter p ( the probability of the outcome of interest ).
- This must be set before the actual generator is instantiated.
- */
-void BinomialRng::setP(double p)
-{
- if ( p < 0 || p > 1) {
- cerr << "ERROR: BinomialRng::setP - p must be in (0,1) range." << endl;
- return;
- }
- if ( !isPSet_) {
- p_ = p;
- isPSet_ = true;
- } else {
- if (!isClose< double >(p_,p, DBL_EPSILON)) {
- p_ = p;
- isModified_ = true;
- }
- }
-
- if ( isNSet_ && isPSet_ && isModified_ ){
- if ( rng_ ){
- delete rng_;
- }
- rng_ = new Binomial((long)(n_),p_);
- isModified_ = false;
- }
-}
-
-/**
- returns parameter p.
-*/
-double BinomialRng::getP() const
-{
- return p_;
-}
-
-
-/**
- reports error if one or more of the parameters are not set.
-*/
-void BinomialRng::vReinit( const Eref& e, ProcPtr p)
-{
- if ( isNSet_ ){
- if ( isPSet_ ){
- if ( !rng_ ){
- rng_ = new Binomial((unsigned long)(n_), p_);
- }
- } else {
- cerr << "ERROR: BinomialRng::reinit - first set value of p." << endl;
- }
- } else {
- cerr << "ERROR: BinomialRng::reinit - first set value of n." << endl;
- }
-}
-
-
-#endif
diff --git a/randnum/BinomialRng.h b/randnum/BinomialRng.h
deleted file mode 100644
index df470a5100c1548262fc5b7f51e6ba9e90f270ce..0000000000000000000000000000000000000000
--- a/randnum/BinomialRng.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*******************************************************************
- * File: BinomialRng.h
- * Description:
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2007-11-08 10:48:59
- ********************************************************************/
-/**********************************************************************
-** This program is part of 'MOOSE', the
-** Messaging Object Oriented Simulation Environment,
-** also known as GENESIS 3 base code.
-** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
-** It is made available under the terms of the
-** GNU General Public License version 2
-** See the file COPYING.LIB for the full notice.
-**********************************************************************/
-
-#ifndef _BINOMIALRNG_H
-#define _BINOMIALRNG_H
-
-#include "randnum.h"
-#include "../basecode/header.h"
-#include "RandGenerator.h"
-#include "Binomial.h"
-
-class BinomialRng: public RandGenerator
-{
- public:
- BinomialRng();
- void setN(double n);
- double getN() const;
- void setP(double p);
- double getP() const;
- virtual void vReinit( const Eref& e, ProcPtr p);
-
- static const Cinfo * initCinfo();
- private:
- bool isNSet_;
- unsigned long n_;
- bool isPSet_;
- double p_;
- bool isModified_;
-};
-
-#endif
diff --git a/randnum/CMakeLists.txt b/randnum/CMakeLists.txt
index 343f7f7fa0d67a9f3c3384493d712f279b8c42da..cc4de6b76f7791ed222525d41f499689770447dc 100644
--- a/randnum/CMakeLists.txt
+++ b/randnum/CMakeLists.txt
@@ -1,8 +1,11 @@
-file(GLOB random_SRC "*.cpp")
+cmake_minimum_required(VERSION 2.8)
-include_directories(../basecode )
-if(WITH_GSL)
- include_directories(${GSL_INCLUDE_DIRS})
-endif(WITH_GSL)
+if( ${CMAKE_SOURCE_DIR} EQUAL ${CMAKE_CURRENT_SOURCE_DIR} )
+ add_definitions( -std=c++11 -g -Wall )
+endif()
-add_library(randnum ${random_SRC})
+add_executable( normal_dist
+ ${CMAKE_CURRENT_SOURCE_DIR}/test_normal_dist.cpp)
+
+enable_testing()
+add_test( NAME test_normal_dist COMMAND $<TARGET_FILE:normal_dist> )
diff --git a/randnum/Definitions.h b/randnum/Definitions.h
new file mode 100644
index 0000000000000000000000000000000000000000..19ef33fa5a6c78cd4da6fa77a12696de638f7028
--- /dev/null
+++ b/randnum/Definitions.h
@@ -0,0 +1,46 @@
+/***
+ * Filename: Definitions.h
+ *
+ * Description: Various definitions.
+ *
+ * Version: 0.0.1
+ * Created: 2018-08-04
+
+ * Revision: none
+ *
+ * Author: Dilawar Singh <dilawars@ncbs.res.in>
+ * Organization: NCBS Bangalore
+ *
+ * License: GNU GPL3
+ */
+
+#ifndef DEFINITIONS_H
+#define DEFINITIONS_H
+
+#include <random>
+
+namespace moose {
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @Synopsis MOOSE's random device. Use it from <random>
+ */
+/* ----------------------------------------------------------------------------*/
+typedef std::random_device MOOSE_RANDOM_DEVICE;
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @Synopsis Global random number generator engine. Everywhere we use this
+ * engine.
+ */
+/* ----------------------------------------------------------------------------*/
+typedef std::mersenne_twister_engine< std::uint_fast32_t, 32, 624, 397, 31
+ , 0x9908b0df, 11
+ , 0xffffffff, 7
+ , 0x9d2c5680, 15
+ , 0xefc60000, 18, 1812433253
+ > MOOSE_RNG_DEFAULT_ENGINE;
+
+}
+
+#endif /* end of include guard: DEFINITIONS_H */
diff --git a/randnum/Distributions.h b/randnum/Distributions.h
new file mode 100644
index 0000000000000000000000000000000000000000..d58fd905938ec5f7457d1d03b2a1584197b445c4
--- /dev/null
+++ b/randnum/Distributions.h
@@ -0,0 +1,34 @@
+/***
+ * Filename: Distributions.h
+ *
+ * Description: All distributions.
+ *
+ * Version: 0.0.1
+ * Created: 2018-08-04
+
+ * Revision: none
+ *
+ * Author: Dilawar Singh <dilawars@ncbs.res.in>
+ * Organization: NCBS Bangalore
+ *
+ * License: GNU GPL2
+ */
+
+#ifndef DISTRIBUTIONS_H
+#define DISTRIBUTIONS_H
+
+#include "NormalDistribution.hpp"
+#include <random>
+
+namespace moose {
+
+ template<typename T=double>
+ using MOOSE_UNIFORM_DISTRIBUTION = std::uniform_real_distribution<T>;
+
+ template<typename T=double>
+ using MOOSE_NORMAL_DISTRIBUTION = moose::normal_distribution<T>;
+
+}
+
+
+#endif /* end of include guard: DISTRIBUTIONS_H */
diff --git a/randnum/Exponential.cpp b/randnum/Exponential.cpp
deleted file mode 100644
index 99f7770db0a0f3158990e8e0a112185cea9187fa..0000000000000000000000000000000000000000
--- a/randnum/Exponential.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-/*******************************************************************
- * File: Exponential.cpp
- * Description:
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2007-11-01 09:03:51
- ********************************************************************/
-/**********************************************************************
-** This program is part of 'MOOSE', the
-** Messaging Object Oriented Simulation Environment,
-** also known as GENESIS 3 base code.
-** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
-** It is made available under the terms of the
-** GNU General Public License version 2
-** See the file COPYING.LIB for the full notice.
-**********************************************************************/
-
-#ifndef _EXPONENTIAL_CPP
-#define _EXPONENTIAL_CPP
-#include "Exponential.h"
-#include "randnum.h"
-#include "utility/numutil.h"
-#include <iostream>
-#include <cmath>
-
-using namespace std;
-
-Exponential::Exponential(double mean):mean_(mean),generator_(&(Exponential::randomMinimization))
-{
-}
-
-Exponential::Exponential(ExponentialGenerator method, double mean):mean_(mean)
-{
- switch(method)
- {
- case LOGARITHMIC:
- generator_ = &(Exponential::logarithmic);
- break;
- default:
- generator_ = &(Exponential::randomMinimization);
- break;
- }
-}
-
-double Exponential::getMean() const
-{
- return mean_;
-}
-
-double Exponential::getVariance() const
-{
- return mean_*mean_;
-}
-
-double Exponential::getNextSample() const
-{
- return generator_(mean_);
-}
-
-
-double Exponential::logarithmic(double mean)
-{
- double uniform = mtrand();
- if ( uniform <= 0 )
- {
- uniform = 1.0e-6;
- }
-
- return - mean*log(uniform);
-}
-
-extern unsigned long genrand_int32(void);
-
-/**
- successive entries in the series
- {Qk} = {(ln2/1! + (ln2)^2/2! + (ln2)^3/3! + ... + (ln2)^k/k!)}
- used in the random minimization algorithm.
- */
-static const double q[] =
-{
- 1.0, // dummy for q[0]
- 0.69314718055994528622676,
- 0.93337368751904603580982,
- 0.98887779618386761892879,
- 0.99849592529149611142003,
- 0.99982928110613900063441,
- 0.99998331641007276449074,
- 0.99999856914387685868917,
- 0.99999989069255590390384,
- 0.99999999247341597730099,
- 0.99999999952832763217003,
- 0.99999999997288147035590 // > 0.99999999953433871269226 = 1 - 2^(-31)
-};
-
-/**
- See Knuth, Vol II Sec 3.4.1 : Algorithm S
- */
-
-double Exponential::randomMinimization(double mean)
-{
- double result;
-
- unsigned long uniform = genrand_int32(); // 1) generate t+1 (=32) bit uniform random binary fraction .b0..bt
- int j = 0;
-
- if ( uniform == 0 )
- {
- uniform = 1;
- }
-
- while (0x80000000 & uniform ) // 1) detect the first 0 bit
- {
- uniform = uniform << 1; // 1a) shift off leading j+1 bits, setting u = .b(j+1) .. b(t)
- ++j;
- }
- uniform = uniform << 1; // 1a)shift off leading j+1 bits, setting u = .b(j+1) .. b(t)
- double uniform_frac = uniform / 4294967296.0;
-
- if ( uniform_frac < LN2 ) // 2) u < ln2?
- {
- result = mean*(j*LN2 + uniform_frac); // x <- mean * ( j * ln2 + u )
- }
- else
- {
- // 3) minimize
- unsigned int k = 2;
- unsigned long v = ~0UL;
- unsigned long u;
-
- while ( ( uniform_frac >= q[k] ))
- {
- k++;
- }
- for ( unsigned int i = 0; i < k; ++i )
- {
- u = genrand_int32();
- if ( u < v )
- {
- v = u;
- }
- }
-
- result = mean*( j + v/4294967296.0 )*LN2;
- }
-
- return result;
-}
-#if 0 // test main
-#include <vector>
-int main(void)
-{
- double mean = .25;
- double sum = 0.0;
- double sd = 0.0;
- vector <unsigned> classes;
- Exponential ex(mean);
- int MAX_SAMPLE = 100000;
- int MAX_CLASSES = 1000;
-
-
- for ( int i = 0; i < MAX_CLASSES; ++i )
- {
- classes.push_back(0);
- }
-
- for ( int i = 0; i < MAX_SAMPLE; ++i )
- {
- double p = ex.getNextSample();//aliasMethod();
- int index = (int)(p*MAX_CLASSES);
-// cout << index << " ] " << p << endl;
-
- if ( index < MAX_CLASSES){
- classes[index]++;
- }
- else
- {
- classes[MAX_CLASSES-1]++;
- }
-
-
- sum += p;
- sd += (p - mean)*(p - mean);
- }
- mean = sum/MAX_SAMPLE;
- sd = sqrt(sd/MAX_SAMPLE);
- cout << "mean = " << mean << " sd = " << sd << endl;
- for ( int i = 0; i < MAX_CLASSES; ++i )
- {
- cout << classes[i] << endl;
- }
-
- return 0;
-}
-#endif // test main
-
-
-#endif
diff --git a/randnum/Exponential.h b/randnum/Exponential.h
deleted file mode 100644
index 7c92e0884ae790c77be386fe05fc1de9715b2dc7..0000000000000000000000000000000000000000
--- a/randnum/Exponential.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*******************************************************************
- * File: Exponential.h
- * Description:
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2007-11-01 08:59:47
- ********************************************************************/
-/**********************************************************************
-** This program is part of 'MOOSE', the
-** Messaging Object Oriented Simulation Environment,
-** also known as GENESIS 3 base code.
-** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
-** It is made available under the terms of the
-** GNU General Public License version 2
-** See the file COPYING.LIB for the full notice.
-**********************************************************************/
-
-#ifndef _EXPONENTIAL_H
-#define _EXPONENTIAL_H
-#include "Probability.h"
-enum ExponentialGenerator
-{
- LOGARITHMIC,
- RANDOM_MINIMIZATION
-};
-
-
-class Exponential: public Probability
-{
- public:
- Exponential(double mean);
- Exponential( ExponentialGenerator generator, double mean);
-
- double getMean() const;
- double getVariance() const;
- double getNextSample() const;
- private:
- double mean_;
- double (*generator_)(double);
- static double logarithmic(double mean);
- static double randomMinimization(double mean);
-
-
-};
-
-
-
-#endif
diff --git a/randnum/ExponentialRng.cpp b/randnum/ExponentialRng.cpp
deleted file mode 100644
index 9b9bbada08537ddd6913bb2b93ae5f6a814a1023..0000000000000000000000000000000000000000
--- a/randnum/ExponentialRng.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-/*******************************************************************
- * File: ExponentialRng.cpp
- * Description:
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2007-11-08 11:33:45
- ********************************************************************/
-/**********************************************************************
-** This program is part of 'MOOSE', the
-** Messaging Object Oriented Simulation Environment,
-** also known as GENESIS 3 base code.
-** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
-** It is made available under the terms of the
-** GNU General Public License version 2
-** See the file COPYING.LIB for the full notice.
-**********************************************************************/
-
-#ifndef _EXPONENTIALRNG_CPP
-#define _EXPONENTIALRNG_CPP
-
-#include "RandGenerator.h"
-#include "ExponentialRng.h"
-
-const Cinfo* ExponentialRng::initCinfo()
-{
- static ValueFinfo< ExponentialRng, double > mean(
- "mean",
- "Mean of the exponential distribution.",
- &ExponentialRng::setMean,
- &ExponentialRng::getMean);
-
- static ValueFinfo< ExponentialRng, int > method(
- "method",
- "The algorithm to use for computing the sample. Two methods are"
- " supported: 0 - logarithmic and 1 - random minimization."
- " The logarithmic method is slower (it computes a"
- " logarithm). Default is random minimization. See Knuth, Vol II Sec"
- " 3.4.1 : Algorithm S.",
- &ExponentialRng::setMethod,
- &ExponentialRng::getMethod);
-
- static Finfo* exponentialRngFinfos[] = {
- &mean,
- &method,
- };
-
- static string doc[] = {
- "Name", "ExponentialRng",
- "Author", "Subhasis Ray",
- "Description", "Exponentially distributed random number generator.\n"
- "Exponential distribution with mean k is defined by the probability"
- " density function p(x; k) = k * exp(-k * x) if x >= 0, else 0."
- " By default this class uses the random minimization method"
- " described in Knuth's TAOCP Vol II Sec 3.4.1 (Algorithm S).",
- };
- static Dinfo< ExponentialRng > dinfo;
- static Cinfo exponentialRngCinfo(
- "ExponentialRng",
- RandGenerator::initCinfo(),
- exponentialRngFinfos,
- sizeof(exponentialRngFinfos)/sizeof(Finfo*),
- &dinfo,
- doc,
- sizeof( doc ) / sizeof( string ));
- return &exponentialRngCinfo;
-}
-
-
-static const Cinfo* exponentialRngCinfo = ExponentialRng::initCinfo();
-
-ExponentialRng::ExponentialRng()
-{
- mean_ = 0;
- isMeanSet_ = false;
- method_ = RANDOM_MINIMIZATION;
-}
-/**
- Replaces the same method in base class. Returns the mean as
- stored in this object independent of the actual generator object.
- */
-double ExponentialRng::getMean() const
-{
- return mean_;
-}
-/**
- Sets the mean. Since exponential distribution is defined in terms
- of this parameter, it is stored locally independent of the
- instantiation of the internal generator object.
-*/
-void ExponentialRng::setMean(double mean)
-{
- if ( !rng_ ){
- rng_ = new Exponential(mean);
- isMeanSet_ = true;
- }
-}
-
-/**
- Reports error in case the parameter mean has not been set.
- */
-void ExponentialRng::vReinit(const Eref& e, ProcPtr p)
-{
- Exponential * erng = static_cast<Exponential *>(rng_);
- if (!erng){
- cerr << "ERROR: ExponentialRng::vReinit - mean must be set before using the Exponential distribution generator." << endl;
- }
-}
-
-/**
- Returns the algorithm used for sample generation.
- 0 for logarithmic method.
- 1 for random minimization method.
- */
-int ExponentialRng::getMethod() const
-{
- return method_;
-}
-
-/**
- Sets the algorithm used for sample generation.
- 0 for logarithmic method.
- 1 for random minimization method.
- Default is random minimization.
- */
-void ExponentialRng::setMethod(int method)
-{
- Exponential * erng = static_cast< Exponential * >(rng_);
- if (!erng){
- switch ( method ){
- case 0:
- method_ = LOGARITHMIC;
- break;
- default:
- method_ = RANDOM_MINIMIZATION;
- break;
- }
- } else {
- cerr << "Warning: Will not change method after generator object has been"
- << " created. Method in use:"
- << method << " ("
- << (method == 0? "logarithmic": "random minimization")
- << ")" << endl;
- }
-}
-
-#endif
diff --git a/randnum/ExponentialRng.h b/randnum/ExponentialRng.h
deleted file mode 100644
index 08a8c2452bfaa0e6145c3ce962aef39d310b1697..0000000000000000000000000000000000000000
--- a/randnum/ExponentialRng.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*******************************************************************
- * File: ExponentialRng.h
- * Description:
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2007-11-08 11:27:50
- ********************************************************************/
-/**********************************************************************
-** This program is part of 'MOOSE', the
-** Messaging Object Oriented Simulation Environment,
-** also known as GENESIS 3 base code.
-** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
-** It is made available under the terms of the
-** GNU General Public License version 2
-** See the file COPYING.LIB for the full notice.
-**********************************************************************/
-
-#ifndef _EXPONENTIALRNG_H
-#define _EXPONENTIALRNG_H
-#include "randnum.h"
-#include "../basecode/header.h"
-#include "RandGenerator.h"
-#include "Exponential.h"
-
-/**
- This is MOOSE wrapper for Exponentially distributed random number generator class, Exponential.
- The default
- */
-class ExponentialRng: public RandGenerator
-{
- public:
- ExponentialRng();
- double getMean() const;
- void setMean(double mean);
- int getMethod() const;
- void setMethod(int method);
- virtual void vReinit( const Eref& e, ProcPtr p);
-
- static const Cinfo* initCinfo();
-
- private:
- double mean_;
- bool isMeanSet_;
- int method_;
-
-};
-
-
-#endif
diff --git a/randnum/Gamma.cpp b/randnum/Gamma.cpp
deleted file mode 100644
index e2eb58ea2be8995081950bf94be67bd29835a7ca..0000000000000000000000000000000000000000
--- a/randnum/Gamma.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-/*******************************************************************
- * File: Gamma.cpp
- * Description:
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2007-11-05 18:33:01
- ********************************************************************/
-/**********************************************************************
- ** This program is part of 'MOOSE', the
- ** Messaging Object Oriented Simulation Environment,
- ** also known as GENESIS 3 base code.
- ** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
- ** It is made available under the terms of the
- ** GNU General Public License version 2
- ** See the file COPYING.LIB for the full notice.
- **********************************************************************/
-
-#ifndef _GAMMA_CPP
-#define _GAMMA_CPP
-#include <cmath>
-#include "utility/numutil.h"
-#include "Gamma.h"
-#include "Exponential.h"
-#include "randnum.h"
-Gamma::Gamma(double alpha, double theta):alpha_(alpha), theta_(theta)
-{
- if (( alpha < 0 ) || (theta < 0 ))
- {
- cerr << "ERROR: setting parameter of Gamma distribution to negative. Setting both to 1." << endl;
- alpha_ = 1;
- theta_ = 1;
- }
-}
-double Gamma::getAlpha()
-{
- return alpha_;
-}
-
-double Gamma::getTheta()
-{
- return theta_;
-}
-
-double Gamma::getMean() const
-{
- return alpha_*theta_;
-}
-
-double Gamma::getVariance() const
-{
- return alpha_*theta_*theta_;
-}
-
-double Gamma::getNextSample() const
-{
- double result;
-
- if ( alpha_ <= 1 )
- {
- result = gammaSmall();
- }
- else
- {
- result = gammaLarge();
- }
- if ( !isClose< double >(theta_, 1.0, DBL_EPSILON))
- {
- result *= theta_;
- }
-
- return result;
-}
-
-// See Algorithm A in TAOCP by Knuth, Vol 2 ,Section 3.4.1
-double Gamma::gammaLarge() const// alpha > 1
-{
- double result = 0.0;
- // a1. generate candidate
- double yValue;
- double uniformU;
- double uniformV;
- double check;
- double tmp;
-
- while (true)
- {
- uniformU = mtrand();
- yValue = tan(M_PI*uniformU);
- tmp = sqrt(2*alpha_ - 1)*yValue;
-
- result = tmp + alpha_ - 1;
- if (result > 0)
- {
- uniformV = mtrand();
- check = ( 1 + yValue*yValue )*exp((alpha_ - 1.0)*log(result/(alpha_ - 1.0)) - tmp);
- if (uniformV < check )
- {
- return result;
- }
- }
- }
- return result; // silence the compiler
-}
-
-
-// See: TAOCP by Knuth, Vol 2, 3.4.1 Exercise 16
-double Gamma::gammaSmall() const // 0 < alpha < 1
-{
- static Exponential expGen(1.0);
-
- // G1. initialize
- static double p = NATURAL_E/(alpha_+NATURAL_E);
- static double pByE = 1.0/(alpha_+NATURAL_E);
- double uniformU;
- double expSample;
- double xValue = 0.0;
- double qValue;
-
- while ( true )
- {
- // G2. generate G deviate
- uniformU = mtrand();
- expSample = expGen.getNextSample();
- while (expSample == 0 )
- {
- expSample = expGen.getNextSample();
- }
-
- if ( uniformU < p )
- {
- xValue = exp(-expSample/alpha_);
- if ( uniformU < pByE )
- {
- return xValue;
- }
- qValue = p*exp(-xValue);
- }
- else
- {
- xValue = 1 + expSample;
- qValue = p + (1.0-p)*pow(xValue, alpha_ - 1.0);
- }
-
- // G3. reject?
- if ( uniformU < qValue )
- {
- return xValue;
- }
- }
- return xValue; // silence the compiler
-}
-
-
-#endif
diff --git a/randnum/Gamma.h b/randnum/Gamma.h
deleted file mode 100644
index 2812c76277fb62dade6e5c3fe54d031e61055376..0000000000000000000000000000000000000000
--- a/randnum/Gamma.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*******************************************************************
- * File: Gamma.h
- * Description:
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2007-11-05 19:22:32
- ********************************************************************/
-/**********************************************************************
-** This program is part of 'MOOSE', the
-** Messaging Object Oriented Simulation Environment,
-** also known as GENESIS 3 base code.
-** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
-** It is made available under the terms of the
-** GNU General Public License version 2
-** See the file COPYING.LIB for the full notice.
-**********************************************************************/
-
-#ifndef _GAMMA_H
-#define _GAMMA_H
-#include "Probability.h"
-#include <iostream>
-using namespace std;
-
-class Gamma: public Probability
-{
- public:
- Gamma(double alpha, double theta);
- double getAlpha();
- double getTheta();
- double getMean() const;
- double getVariance() const;
- double getNextSample() const;
- private:
- double alpha_;
- double theta_;
- double gammaSmall() const;
- double gammaLarge() const;
-
-};
-
-
-#endif
diff --git a/randnum/GammaRng.cpp b/randnum/GammaRng.cpp
deleted file mode 100644
index eac78fbaefe2e94e17921902a4dcec532320d1dd..0000000000000000000000000000000000000000
--- a/randnum/GammaRng.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/*******************************************************************
- * File: GammaRng.cpp
- * Description:
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2007-11-08 11:56:00
- ********************************************************************/
-/**********************************************************************
-** This program is part of 'MOOSE', the
-** Messaging Object Oriented Simulation Environment,
-** also known as GENESIS 3 base code.
-** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
-** It is made available under the terms of the
-** GNU General Public License version 2
-** See the file COPYING.LIB for the full notice.
-**********************************************************************/
-
-#ifndef _GAMMARNG_CPP
-#define _GAMMARNG_CPP
-#include "GammaRng.h"
-#include "utility/numutil.h"
-#include <cmath>
-
-const Cinfo* GammaRng::initCinfo()
-{
- static ValueFinfo< GammaRng, double > alpha(
- "alpha",
- "Parameter alpha of the gamma distribution.",
- &GammaRng::setAlpha,
- &GammaRng::getAlpha);
- static ValueFinfo< GammaRng, double > theta(
- "theta",
- "Parameter theta of the Gamma distribution.",
- &GammaRng::setTheta,
- &GammaRng::getTheta);
- static Finfo* gammaRngFinfos[] = {
- &alpha,
- &theta,
- };
-
- static string doc[] = {
- "Name", "GammaRng",
- "Author", "Subhasis Ray",
- "Description", "Gamma distributed random number generator.",
- };
-
- Dinfo < GammaRng > dinfo;
- static Cinfo gammaRngCinfo(
- "GammaRng",
- RandGenerator::initCinfo(),
- gammaRngFinfos,
- sizeof(gammaRngFinfos)/sizeof(Finfo*),
- &dinfo,
- doc,
- sizeof( doc ) / sizeof( string ));
- return &gammaRngCinfo;
-}
-
-
-static const Cinfo* gammaRngCinfo = GammaRng::initCinfo();
-
-GammaRng::GammaRng()
-{
- isAlphaSet_ = false;
- isThetaSet_ = false;
- alpha_ = 1;
- theta_ = 1;
-}
-/**
- returns the shape parameter.
-*/
-double GammaRng::getAlpha() const
-{
- return alpha_;
-}
-/**
- Sets parameter alpha. Also known as the shape parameter.
-*/
-void GammaRng::setAlpha(double alpha)
-{
-
- if (fabs(alpha) < DBL_MIN)
- {
- cerr << "ERROR: Shape parameter alpha must be non-zero." << endl;
- return;
- }
- Gamma * grng = static_cast< Gamma * >(rng_);
- if ( grng ) {
- alpha_ = grng->getAlpha();
- } else {
- alpha_ = alpha;
- isAlphaSet_ = true;
- if ( isThetaSet_ ){
- rng_ = new Gamma(alpha_, theta_);
- }
- }
-}
-/**
- returns the scale parameter.
-*/
-double GammaRng::getTheta()const
-{
- return theta_;
-}
-
-/**
- Sets parameter theta. Also known as the scale parameter.
-*/
-void GammaRng::setTheta(double theta)
-{
-
- if (fabs(theta) < DBL_MIN)
- {
- cerr << "ERROR: Scale parameter theta must be non-zero." << endl;
- return;
- }
- Gamma* grng = static_cast<Gamma*>(rng_);
- if ( grng ){
- theta_ = grng->getTheta();
- } else {
- theta_ = theta;
- isThetaSet_ = true;
- if (isAlphaSet_ ){
- rng_ = new Gamma(alpha_, theta_);
- }
- }
-}
-/**
- reports error if parameters have not been set properly.
-*/
-void GammaRng::vReinit(const Eref& e, ProcPtr p)
-{
- if (! rng_ )
- {
- cerr << "ERROR: GammaRng::vReinit - parameters alpha and theta must be set before using the Gamma distribution generator." << endl;
- }
-}
-
-#endif
diff --git a/randnum/GammaRng.h b/randnum/GammaRng.h
deleted file mode 100644
index 381da44e74b09c581326721e8365e07b8ea760e9..0000000000000000000000000000000000000000
--- a/randnum/GammaRng.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*******************************************************************
- * File: GammaRng.h
- * Description:
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2007-11-08 11:53:29
- ********************************************************************/
-/**********************************************************************
-** This program is part of 'MOOSE', the
-** Messaging Object Oriented Simulation Environment,
-** also known as GENESIS 3 base code.
-** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
-** It is made available under the terms of the
-** GNU General Public License version 2
-** See the file COPYING.LIB for the full notice.
-**********************************************************************/
-
-#ifndef _GAMMARNG_H
-#define _GAMMARNG_H
-#include "randnum.h"
-#include "basecode/header.h"
-#include "RandGenerator.h"
-#include "Gamma.h"
-
-/**
- This is MOOSE wrapper for Gammaly distributed random number generator class, Gamma.
- The default
- */
-class GammaRng: public RandGenerator
-{
- public:
- GammaRng();
- virtual ~GammaRng() { ; }
- double getAlpha() const;
- double getTheta() const;
- void setAlpha(double alpha);
- void setTheta(double theta);
-
- virtual void vReinit( const Eref& e, ProcPtr p);
-
- static const Cinfo * initCinfo();
-
- private:
- double alpha_;
- double theta_;
-
- bool isAlphaSet_;
- bool isThetaSet_;
-};
-
-
-#endif
diff --git a/randnum/Normal.cpp b/randnum/Normal.cpp
deleted file mode 100644
index 608ce92804319037370324513fd2a8b070e534aa..0000000000000000000000000000000000000000
--- a/randnum/Normal.cpp
+++ /dev/null
@@ -1,604 +0,0 @@
-/*******************************************************************
- * File: Normal.cpp
- * Description:
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2007-10-31 13:48:53
- ********************************************************************/
-/**********************************************************************
- ** This program is part of 'MOOSE', the
- ** Messaging Object Oriented Simulation Environment,
- ** also known as GENESIS 3 base code.
- ** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
- ** It is made available under the terms of the
- ** GNU General Public License version 2
- ** See the file COPYING.LIB for the full notice.
- **********************************************************************/
-
-#ifndef _NORMAL_CPP
-#define _NORMAL_CPP
-#include "Normal.h"
-#include "randnum.h"
-#include "../utility/numutil.h"
-#include <cmath>
-#include <iostream>
-using namespace std;
-
-extern unsigned long genrand_int32(void);
-Normal::Normal(double mean, double variance, NormalGenerator method):mean_(mean), variance_(variance), method_(method)
-{
- if (variance <= 0.0 )
- {
- cout << "Warning: cannot set variance <= 0. Setting to 1.0." << endl;
- variance_ = 1.0;
- }
-
- isStandard_ = isClose< double >(0.0, mean, DBL_EPSILON) && isClose < double > (1.0, variance, DBL_EPSILON);
- switch(method)
- {
- case ALIAS:
- generator_ = &(Normal::aliasMethod);
- break;
- case BOX_MUELLER:
- generator_ = &(Normal::BoxMueller);
- break;
-#ifdef USE_GSL
- case ZIGGURAT:
- generator_ = &(Normal::gslZiggurat);
- break;
-#endif
- default:
- cerr << "ERROR: Normal() - generator method# " << method << ". Don't know how to do this. Using alias method."<<endl;
- generator_ = &(Normal::aliasMethod);
- }
-}
-
-double dummy()
-{
- return 0.0;
-}
-
-double Normal::getNextSample() const
-{
- double sd = sqrt(variance_);
- double sample = generator_();
- if (!isStandard_)
- {
- sample = mean_ + sd*sample;
- }
- return sample;
-}
-
-double Normal::getMean() const
-{
- return mean_;
-}
-
-void Normal::setMean( double mean)
-{
- mean_ = mean;
- isStandard_ = isClose< double >(0.0, mean_, DBL_EPSILON) && isClose< double >(1.0, variance_, DBL_EPSILON);
-}
-
-double Normal::getVariance() const
-{
- return variance_;
-}
-
-void Normal::setVariance( double variance )
-{
- if (variance <= 0.0)
- {
- cout << "Warning: cannot set variance < 0." << endl;
- return;
- }
- variance_ = variance;
- isStandard_ = isClose< double > (0.0, mean_, DBL_EPSILON) && isClose< double >(1.0, variance_, DBL_EPSILON);
-}
-
-NormalGenerator Normal::getMethod(void)
-{
- return method_;
-}
-
-void Normal::setMethod(NormalGenerator method)
-{
- method_ = method;
- switch(method)
- {
- case ALIAS:
- generator_ = &(Normal::aliasMethod);
- break;
- case BOX_MUELLER:
- generator_ = &(Normal::BoxMueller);
- break;
-#ifdef USE_GSL
- case ZIGGURAT:
- generator_ = &(Normal::gslZiggurat);
- break;
-#endif
- default:
- cerr << "ERROR: Normal() - generator method# " << method << ". Don't know how to do this. Using alias method."<<endl;
- generator_ = &(Normal::aliasMethod);
- method_ = ALIAS;
- }
-}
-
-#ifdef USE_GSL
-#include <gsl/gsl_rng.h>
-#include <gsl/gsl_randist.h>
-
-double Normal::gslZiggurat()
-{
- static const gsl_rng_type * T;
- static gsl_rng * r;
- static bool inited = false;
- if (!inited)
- {
- /* create a generator chosen by the
- environment variable GSL_RNG_TYPE */
-
- gsl_rng_env_setup();
-
- T = gsl_rng_default;
- r = gsl_rng_alloc (T);
- inited = true;
- }
- return gsl_ran_gaussian_ziggurat(r, 1.0);
-}
-
-#endif // !USE_GSL
-/**
- Very simple but costly implementation
-*/
-double Normal::BoxMueller()
-{
- double result;
- double a, b, r;
- do
- {
- a = 2.0 * mtrand() - 1.0;
- b = 2.0 * mtrand() - 1.0;
- r = a * a + b * b;
- } while ( r >= 1.0 );
- r = sqrt( - 2.0 * log(r) / r );
- result = r * a;
-
- return result;
-}
-/**
- Refer to:
- Eine Alias-Methode zur Stichprohenentnahme aus Normalverteilungen.
- JH Ahrens and U Dieter, 19 89, Computing
-
- We are assuming size of long to be 32 bit
-*/
-
-const unsigned long y[] =
-{
- 200, 199, 199, 198, 197, 196, 195, 193, 192, 190, 188, 186, 184, 181, 179, 176, 173, 170, 167, 164, 161, 157, 154, 151, 147, 143, 140, 136, 132, 128, 125, 121, 117, 113, 110, 106, 102, 98, 95, 91, 88, 84, 81, 77, 74, 71, 68, 64, 61, 59, 56, 53, 50, 48, 45, 43, 40, 38, 36, 34, 32, 30, 28, 27, 25, 23, 22, 20, 19, 18, 17, 15, 14, 13, 12, 11, 11, 10, 9, 8, 8, 7, 6, 6, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-const long a[] =
-{
- 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 27, 26, 25, 24, 23, 22, 21, -1, 19, 19, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
-};
-
-const unsigned long q[] =
-{
- 28, 32, 33, 36, 40, 43, 45, 47, 51, 53, 57, 59, 27, 37, 43, 54, 28, 45, 60, 63, 49, 61, 52, 34, 63, 46, 34, 18, 47, 40, 36, 29, 61, 57, 53, 51, 47, 43, 40, 37, 33, 31, 27, 25, 21, 19, 17, 14, 11, 9 , 8, 5, 54, 51, 49, 46, 44, 41, 39, 37, 35, 33, 31, 29, 28, 26, 24, 23, 21, 20, 19, 18, 16, 15, 14, 13, 12, 12, 11, 10, 9, 9, 8, 7, 7, 6, 6, 5, 5, 5, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
-};
-const double c = 0.004996971959878404;
-
-const double d = 1.861970434352886050;
-/*********************************************************************************************************************************/
-/* TODO: This implementation has a bug. The sample mean deviates a lot
- * from the generator mean for very small numbers, like 1e-7
- * Need to make sure that this is not due to 32/64 bit incompatibility.
- */
-/*********************************************************************************************************************************/
-double Normal::aliasMethod()
-{
- double result;
-
- unsigned long uniform;
- unsigned long uniform_prime;
- unsigned long x_num;
- unsigned long t_num;
- unsigned long v_num;
-
- unsigned long i_num, k_num, sgn;
-
- while (true)
- {
-
- // 1) u = .B1..B7 (base 256) - we take the little endian approach
- uniform = genrand_int32(); // .B1B2B3B4 - limited by precision
-
- // 1a) s = B1[0]
- sgn = uniform & 0x80000000UL;
- // 1b) B1[0] = 0
- uniform = uniform & 0x7fffffffUL;
-
- // 2) i = B1[1..7]
- i_num = uniform >> 24;
- // 3) k = (B2 ^ B4) and retain least significant 6 bits of k
- k_num = ((uniform >> 16) ^ uniform ) & 0x0000003fUL;
-
- // 4) k <q[i]? goto 7
- if ( k_num >= q[i_num] )
- {
- // 5) i = a[i]
- i_num = a[i_num];
-
- // 5a)i = ~0? goto 11
- if (i_num != ~(0UL))
- {
-
- // 6) B1 = i
- uniform = (uniform & 0x00ffffffUL) | (i_num << (WORD_LENGTH-8));
-
- // 6a) x = 8*u
- x_num = uniform << 3;
-
- // 6b) goto 8 - s = 0? return x: return -x
- // result = x_num/4294967296.0; // convert to double
-// result = (sgn == 0) ? result : -result;
- //return result;
- break;
- }
- }
- else
- {
-
-
- // 7) x = 8*u
- x_num = uniform << 3;
-
- // 7a) if (k <= y[i-1] - y[i]) goto 9
- if (k_num > y[i_num-1] - y[i_num])
- {
- // 8) s = 0? return x: return -x
-// result = x_num/4294967296.0; // convert to double
-// result = (sgn == 0) ? result : -result;
- //return result;
- break;
-
- }
-
- // 9) u' = .B1'..B7' .. using B1-B4 for precision limitation
- uniform_prime = genrand_int32();
- // 9a) t = x*x/2
- t_num = x_num*(x_num/2);
-
- // 9b) v = c*(y[i] + u'*(y[i-1] - y[i] + 1))
- v_num = (unsigned long)(c*(y[i_num] + uniform_prime*(y[i_num - 1] - y[i_num] + 1)));
-
- // 10) v > exp(-t)? goto 1: goto 8
-
-
- if ( testAcceptance(t_num, v_num ))
- {
- result = x_num/4294967296.0; // convert to double
- result = (sgn == 0) ? result : -result;
- //return result;
- break;
-
- }else
- {
- continue;
- }
- }
-
- // 11) u = .B1..B7
- uniform = genrand_int32();
-
- // 11a) u < 1/9? goto 1
- if ( uniform/4294967296.0 < 1.0/9.0)
- {
- continue;
- }
-
- // 12) x = 3.75 + 0.25/u
- unsigned long divider = ((uniform << 24) +
- ((uniform << 16) & 0x00ff0000UL) +
- ((uniform << 8) & 0x0000ff00UL) +
- (uniform & 0x000000ffUL));
-
- x_num = (unsigned long)( 3.75 + (1.0*0x40000000UL)/divider);
- // 12a) t = x*x/2-8, v = d*u*u*u'
- t_num = x_num*x_num/2 - 0x8UL;
- v_num = (unsigned long)(d*uniform*uniform*uniform_prime);
-
- // 12b) goto 10
- // 10) v > exp(-t)? goto 1: goto 8
- if ( testAcceptance(t_num, v_num) )
- {
- // 8)
-// result = x_num/4294967296.0; // convert to double
-// result = (sgn == 0) ? result : -result;
-// return result;
- break;
-
-
- }else // goto 1
- {
- continue;
- }
- }
- // 8)
- result = (sgn == 0) ? x_num/4294967296.0 : -(x_num/4294967296.0);
-
- return result;
-
-}
-/**
- Method to check if v > exp(-t) without doing the exponentiation
- TODO: try to do everything in integer arithmetic
-*/
-bool Normal::testAcceptance(unsigned long t_num, unsigned long v_num)
-{
- bool accept = false;
- bool cont = true;
-
- double t = t_num/4294967296.0;
- double v = v_num/4294967296.0;
-// return (v > exp(-t));
-
- while(cont)
- { // a)
- if ( t >= LN2 )
- {
- // b)
- t = t - LN2;
- v += v;
-
- if ( v > 1 )
- {
- return false;
- }
- else
- {
- continue;
- }
- }
- // c)
- v = v + t - 1;
- if ( v <= 0 )
- {
- return true;
- }
- // d)
- double r = t * t;
- v = v + v - r;
- if ( v > 0)
- {
- return false;
- }
- double c = 3.0;
- // e)
- while(true)
- {
- r *= t;
- v = v * c + r;
- if ( v <= 0)
- {
- return true;
- }
- c += 1.0;
- // f)
- r *= t;
- v = v * c - r;
- if ( v > 0 )
- {
- return false;
- }
- c += 1.0;
- }
- }
- return accept;
-}
-
-/**
- See Knuth, TAOCP Vol 2 Sec 3.4.1
- Algorithm M: The Rectangle-wedge-tail method discovered by G Marsaglia
- TODO: implement it by filling the gaps
-*/
-#if 0
-double algorithmM() // not implemented
-{
- cout << "algorithmM() - not yet implemented." << endl;
- return 0.0;
-
- double result;
- double u;
- int psi;
- // TODO: construct these auxiliary tables.
- static int P[32];
- static int Q[32];
- static int Y[32];
- static int Z[32];
- static int S[32];
- static int D[32];
- static int E[32];
- // M1 [ Get U ]
- // U = (.b0b1b2....bt)2
- u = mtrand();
- // M2 [Rectangle?]
- // psi = b0
- // j = (b1b2b3b4b5)2
- // f = (.b6b7..bt)2
- // if ( f >= Pj ) { X = Yj + f*Zj; goto M9 }
- // else if ( j <= 15, i.e. b1 == 0 ) { X = Sj + f*Qj; goto M9 }
-
- // M3 [ Wedge or tail? ]
- // Now 15 <= j <= 31 and each particular value j occurs with probability pj
- // if ( j == 31 ) goto M7
-
- // M4 [ Get U <= V ]
- // Generate two new uniform deviates, U and V; if U > V, exchange U <-> V
- // Set X =S(j-15) + U/5
-
- // M5 [ Easy case? ]
- // if ( V <= Dj ) goto M9
-
- // M6 [ Another try? ]
- // if ( V > U + Ej * (exp[( S(j-14)^2 - X^2 )/2] - 1 ) ) goto M4
- // else goto M9
-
- // M7 [ Get supertail deviate ]
- // Generate two new independent uniform deviates U and V
- // set X = sqrt(9-2*lnV)
-
- // M8 [ Reject? ]
- // if ( U*X >= 3 ) goto M7
-
- // M9 [ Attach sign ]
- // if ( psi == 1 ) X = -X
-
- return result;
-}
-#endif
-/**
- TODO: Not yet implemented.
-*/
-double algorithmF()
-{
- cout << "algorithmF() - not implemented." << endl;
-
- double result = 0;
- return result;
-}
-
-
-#ifdef DO_UNIT_TESTS
-#include <cassert>
-#include <vector>
-
-void checkMeanVariance(Normal& normalGen, unsigned seqLen)
-{
- vector < double > seq;
- double mean = 0.0;
- for ( unsigned ii = 0; ii < seqLen; ++ii)
- {
- double sample = normalGen.getNextSample();
- seq.push_back(sample);
- mean += sample;
- }
- mean /= seqLen;
- cout << "Testing Normal: " << normalGen.getMethod() << " method for " << seqLen << " samples :: mean set - " << normalGen.getMean() << ", sample mean - " << mean << ". ";
- double variance = 0.0;
- for ( unsigned ii = 0; ii < seqLen; ++ ii)
- {
- variance += (mean - seq[ii]) * (mean - seq[ii]);
- }
- variance /= seqLen;
- cout << "variance set - " << normalGen.getVariance() << ", sample variance - " << variance << endl;
-}
-
-void testNormal()
-{
- // const unsigned SEQ_LEN = 1000;
-
- Normal* normalGen = new Normal();
- // make sure default constructor creates standard normal
- assert(isClose< double >(normalGen->getMean(), 0.0, DBL_EPSILON));
- assert(isClose< double > (normalGen->getVariance(), 1.0, DBL_EPSILON));
- // check if setting method is effective
- normalGen->setMethod(ALIAS);
- assert(normalGen->getMethod() == ALIAS);
- checkMeanVariance(*normalGen, 1000); // check the sample mean and variance for "alias method"
- delete normalGen;
- normalGen = new Normal(100.0, 33.0, BOX_MUELLER);
- assert(normalGen->getMethod() == BOX_MUELLER);
- assert(isClose< double >(normalGen->getMean(), 100.0, DBL_EPSILON));
- assert(isClose(normalGen->getVariance(), 33.0, DBL_EPSILON));
- checkMeanVariance(*normalGen, 1000); // check the sample mean and variance for "Box-Mueller method"
- delete normalGen;
-
- // non standard normal distr.
- normalGen = new Normal();
- normalGen->setMean(-100.0);
- normalGen->setVariance(3.0);
- checkMeanVariance(*normalGen, 1000);
-}
-#if 0 // keep it out of compilation
-void testByte2Double()
-{
- double res;
-
- unsigned char bytes[] =
- {
- 0, 0, 0, 0, 0
- };
- bytes[4] = 0x5;
- res = byte2double(bytes, 5);
- printf("0.0000000005 H = %.20g\n", res);
- bytes[3] = 0x4;
- res = byte2double(bytes, 4);
- printf("0.00000004 H = %.20g\n", res);
- bytes[2] = 0x3;
- res = byte2double(bytes, 3);
- printf("0.000003 H = %.20g\n", res);
- bytes[1] = 0x2;
- res = byte2double(bytes, 2);
- printf("0.0002 H = %.20g\n", res);
- assert(isClose< double >(res, 0.000030517578125));
- bytes[0] = 0x1;
- res = byte2double(bytes, 1);
- printf("0.01 H = %.20g\n", res);
- assert(res == 0.00390625);
- res = byte2double(bytes, 5);
- printf("0.0102030405 in hex = %.20g\n", res);
- assert(isClose< double >(res, 0.0039369473279293742962, 1e-9));// the right comparison is from the same program. Should check for various architectures.
-}
-#endif // #if 0
-#endif // !DO_UNIT_TESTS
-
-#if defined(DO_UNIT_TESTS) && defined(TEST_MAIN)
-// Test main
-
-int main(void)
-{
- double mean = 0.0;
- double sd = 0.0;
- double sum = 0.0;
- int freq [200];
- Normal n(BOX_MUELLER);
-
- for ( int i = 0; i < 200; ++i )
- {
- freq[i] = 0;
- }
-
- for ( int i = 0; i < 10000; ++i )
- {
- double p = n.getNextSample();//aliasMethod();
- int index = (int)(p*100)+99;
- cout << index << " ] " << p << endl;
- if ( index < 0 )
- index = 0;
- else if ( index > 199 )
- index = 199;
-
- freq[index]++;
-
- sum += p;
- sd = p*p;
- }
- mean = sum/1000;
- sd = sd/1000;
- cout << mean << " " << sd << endl;
- for ( int i = 0; i < 200; ++i )
- {
- cout << freq[i] << endl;
- }
-
- testNormal();
-
- return 0;
-}
-#endif // ! define(DO_UNIT_TESTS) && defined(TEST_MAIN)
-
-
-#endif
diff --git a/randnum/Normal.h b/randnum/Normal.h
deleted file mode 100644
index c74cf9bb3a66405ed6f8fd7e71f1d52da288d44b..0000000000000000000000000000000000000000
--- a/randnum/Normal.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*******************************************************************
- * File: Normal.h
- * Description: Generates random numbers with normal
- * distribution.
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2007-10-30 11:22:51
- ********************************************************************/
-/**********************************************************************
- ** This program is part of 'MOOSE', the
- ** Messaging Object Oriented Simulation Environment,
- ** also known as GENESIS 3 base code.
- ** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
- ** It is made available under the terms of the
- ** GNU General Public License version 2
- ** See the file COPYING.LIB for the full notice.
- **********************************************************************/
-
-#ifndef _NORMAL_H
-#define _NORMAL_H
-#include "Probability.h"
-enum NormalGenerator
-{
- ALIAS,
- BOX_MUELLER,
- ZIGGURAT
-};
-
-class Normal : public Probability
-{
-
- public:
- Normal(double mean=0.0, double variance=1.0, NormalGenerator algorithm=ALIAS);
- double getMean() const;
- void setMean(double value);
- double getVariance() const;
- void setVariance( double value );
- NormalGenerator getMethod(void);
- void setMethod(NormalGenerator method);
- double getNextSample() const;
- private:
- double mean_;
- double variance_;
- double (*generator_)();
- bool isStandard_;
- NormalGenerator method_;
- static double BoxMueller();
- static double aliasMethod();
- static double gslZiggurat();
- static bool testAcceptance(unsigned long t, unsigned long v);
-};
-
-
-#endif
diff --git a/randnum/NormalDistribution.hpp b/randnum/NormalDistribution.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..c79fdf5407bc9446deb3dbca39dec57b7cdd5c17
--- /dev/null
+++ b/randnum/NormalDistribution.hpp
@@ -0,0 +1,197 @@
+/***
+ * Generates normally distributed numbers. Based on GSL implementation.
+ *
+ * Created: 2018-08-04
+ * Author: Dilawar Singh <dilawars@ncbs.res.in>
+ * Organization: NCBS Bangalore
+ * License: GNU GPL3
+ */
+
+#ifndef NORMALDISTRIBUTION_H
+#define NORMALDISTRIBUTION_H
+
+#include "Definitions.h"
+
+/* position of right-most step */
+#define PARAM_R 3.44428647676
+
+namespace moose {
+namespace details {
+
+/* tabulated values for the heigt of the Ziggurat levels */
+static const double ytab[128] =
+{
+ 1, 0.963598623011, 0.936280813353, 0.913041104253,
+ 0.892278506696, 0.873239356919, 0.855496407634, 0.838778928349,
+ 0.822902083699, 0.807732738234, 0.793171045519, 0.779139726505,
+ 0.765577436082, 0.752434456248, 0.739669787677, 0.727249120285,
+ 0.715143377413, 0.703327646455, 0.691780377035, 0.68048276891,
+ 0.669418297233, 0.65857233912, 0.647931876189, 0.637485254896,
+ 0.62722199145, 0.617132611532, 0.607208517467, 0.597441877296,
+ 0.587825531465, 0.578352913803, 0.569017984198, 0.559815170911,
+ 0.550739320877, 0.541785656682, 0.532949739145, 0.524227434628,
+ 0.515614886373, 0.507108489253, 0.498704867478, 0.490400854812,
+ 0.482193476986, 0.47407993601, 0.466057596125, 0.458123971214,
+ 0.450276713467, 0.442513603171, 0.434832539473, 0.427231532022,
+ 0.419708693379, 0.41226223212, 0.404890446548, 0.397591718955,
+ 0.390364510382, 0.383207355816, 0.376118859788, 0.369097692334,
+ 0.362142585282, 0.355252328834, 0.348425768415, 0.341661801776,
+ 0.334959376311, 0.328317486588, 0.321735172063, 0.31521151497,
+ 0.308745638367, 0.302336704338, 0.29598391232, 0.289686497571,
+ 0.283443729739, 0.27725491156, 0.271119377649, 0.265036493387,
+ 0.259005653912, 0.253026283183, 0.247097833139, 0.241219782932,
+ 0.235391638239, 0.229612930649, 0.223883217122, 0.218202079518,
+ 0.212569124201, 0.206983981709, 0.201446306496, 0.195955776745,
+ 0.190512094256, 0.185114984406, 0.179764196185, 0.174459502324,
+ 0.169200699492, 0.1639876086, 0.158820075195, 0.153697969964,
+ 0.148621189348, 0.143589656295, 0.138603321143, 0.133662162669,
+ 0.128766189309, 0.123915440582, 0.119109988745, 0.114349940703,
+ 0.10963544023, 0.104966670533, 0.100343857232, 0.0957672718266,
+ 0.0912372357329, 0.0867541250127, 0.082318375932, 0.0779304915295,
+ 0.0735910494266, 0.0693007111742, 0.065060233529, 0.0608704821745,
+ 0.056732448584, 0.05264727098, 0.0486162607163, 0.0446409359769,
+ 0.0407230655415, 0.0368647267386, 0.0330683839378, 0.0293369977411,
+ 0.0256741818288, 0.0220844372634, 0.0185735200577, 0.0151490552854,
+ 0.0118216532614, 0.00860719483079, 0.00553245272614, 0.00265435214565
+};
+
+/* tabulated values for 2^24 times x[i]/x[i+1],
+ * used to accept for U*x[i+1]<=x[i] without any floating point operations */
+static const unsigned long ktab[128] =
+{
+ 0, 12590644, 14272653, 14988939,
+ 15384584, 15635009, 15807561, 15933577,
+ 16029594, 16105155, 16166147, 16216399,
+ 16258508, 16294295, 16325078, 16351831,
+ 16375291, 16396026, 16414479, 16431002,
+ 16445880, 16459343, 16471578, 16482744,
+ 16492970, 16502368, 16511031, 16519039,
+ 16526459, 16533352, 16539769, 16545755,
+ 16551348, 16556584, 16561493, 16566101,
+ 16570433, 16574511, 16578353, 16581977,
+ 16585398, 16588629, 16591685, 16594575,
+ 16597311, 16599901, 16602354, 16604679,
+ 16606881, 16608968, 16610945, 16612818,
+ 16614592, 16616272, 16617861, 16619363,
+ 16620782, 16622121, 16623383, 16624570,
+ 16625685, 16626730, 16627708, 16628619,
+ 16629465, 16630248, 16630969, 16631628,
+ 16632228, 16632768, 16633248, 16633671,
+ 16634034, 16634340, 16634586, 16634774,
+ 16634903, 16634972, 16634980, 16634926,
+ 16634810, 16634628, 16634381, 16634066,
+ 16633680, 16633222, 16632688, 16632075,
+ 16631380, 16630598, 16629726, 16628757,
+ 16627686, 16626507, 16625212, 16623794,
+ 16622243, 16620548, 16618698, 16616679,
+ 16614476, 16612071, 16609444, 16606571,
+ 16603425, 16599973, 16596178, 16591995,
+ 16587369, 16582237, 16576520, 16570120,
+ 16562917, 16554758, 16545450, 16534739,
+ 16522287, 16507638, 16490152, 16468907,
+ 16442518, 16408804, 16364095, 16301683,
+ 16207738, 16047994, 15704248, 15472926
+};
+
+/* tabulated values of 2^{-24}*x[i] */
+static const double wtab[128] =
+{
+ 1.62318314817e-08, 2.16291505214e-08, 2.54246305087e-08, 2.84579525938e-08,
+ 3.10340022482e-08, 3.33011726243e-08, 3.53439060345e-08, 3.72152672658e-08,
+ 3.8950989572e-08, 4.05763964764e-08, 4.21101548915e-08, 4.35664624904e-08,
+ 4.49563968336e-08, 4.62887864029e-08, 4.75707945735e-08, 4.88083237257e-08,
+ 5.00063025384e-08, 5.11688950428e-08, 5.22996558616e-08, 5.34016475624e-08,
+ 5.44775307871e-08, 5.55296344581e-08, 5.65600111659e-08, 5.75704813695e-08,
+ 5.85626690412e-08, 5.95380306862e-08, 6.04978791776e-08, 6.14434034901e-08,
+ 6.23756851626e-08, 6.32957121259e-08, 6.42043903937e-08, 6.51025540077e-08,
+ 6.59909735447e-08, 6.68703634341e-08, 6.77413882848e-08, 6.8604668381e-08,
+ 6.94607844804e-08, 7.03102820203e-08, 7.11536748229e-08, 7.1991448372e-08,
+ 7.2824062723e-08, 7.36519550992e-08, 7.44755422158e-08, 7.52952223703e-08,
+ 7.61113773308e-08, 7.69243740467e-08, 7.77345662086e-08, 7.85422956743e-08,
+ 7.93478937793e-08, 8.01516825471e-08, 8.09539758128e-08, 8.17550802699e-08,
+ 8.25552964535e-08, 8.33549196661e-08, 8.41542408569e-08, 8.49535474601e-08,
+ 8.57531242006e-08, 8.65532538723e-08, 8.73542180955e-08, 8.8156298059e-08,
+ 8.89597752521e-08, 8.97649321908e-08, 9.05720531451e-08, 9.138142487e-08,
+ 9.21933373471e-08, 9.30080845407e-08, 9.38259651738e-08, 9.46472835298e-08,
+ 9.54723502847e-08, 9.63014833769e-08, 9.71350089201e-08, 9.79732621669e-08,
+ 9.88165885297e-08, 9.96653446693e-08, 1.00519899658e-07, 1.0138063623e-07,
+ 1.02247952126e-07, 1.03122261554e-07, 1.04003996769e-07, 1.04893609795e-07,
+ 1.05791574313e-07, 1.06698387725e-07, 1.07614573423e-07, 1.08540683296e-07,
+ 1.09477300508e-07, 1.1042504257e-07, 1.11384564771e-07, 1.12356564007e-07,
+ 1.13341783071e-07, 1.14341015475e-07, 1.15355110887e-07, 1.16384981291e-07,
+ 1.17431607977e-07, 1.18496049514e-07, 1.19579450872e-07, 1.20683053909e-07,
+ 1.21808209468e-07, 1.2295639141e-07, 1.24129212952e-07, 1.25328445797e-07,
+ 1.26556042658e-07, 1.27814163916e-07, 1.29105209375e-07, 1.30431856341e-07,
+ 1.31797105598e-07, 1.3320433736e-07, 1.34657379914e-07, 1.36160594606e-07,
+ 1.37718982103e-07, 1.39338316679e-07, 1.41025317971e-07, 1.42787873535e-07,
+ 1.44635331499e-07, 1.4657889173e-07, 1.48632138436e-07, 1.50811780719e-07,
+ 1.53138707402e-07, 1.55639532047e-07, 1.58348931426e-07, 1.61313325908e-07,
+ 1.64596952856e-07, 1.68292495203e-07, 1.72541128694e-07, 1.77574279496e-07,
+ 1.83813550477e-07, 1.92166040885e-07, 2.05295471952e-07, 2.22600839893e-07
+};
+
+} // namespace moose::details
+
+/* --------------------------------------------------------------------------*/
+/**
+ * @Synopsis Get a Normally Distribution value from a given RNG.
+ *
+ * @tparam T
+ */
+/* ----------------------------------------------------------------------------*/
+template<typename T = double>
+class normal_distribution
+{
+
+public:
+
+ normal_distribution( T mean = 0.0, T sigma = 1.0) :
+ mean_(mean), sigma_(sigma)
+ {
+ mean_ = mean;
+ sigma_ = sigma;
+ }
+
+ ~normal_distribution() { ; }
+
+ double operator()( moose::MOOSE_RNG_DEFAULT_ENGINE& r )
+ {
+ unsigned long U=0, sign=0, i=0, j=0;
+ T x=0, y=0;
+
+ while (1)
+ {
+ U = r();
+ i = U & 0x0000007F; /* 7 bit to choose the step */
+ sign = U & 0x00000080; /* 1 bit for the sign */
+ j = U>>8; /* 24 bit for the x-value */
+
+ x = j*details::wtab[i];
+ if (j < details::ktab[i]) break;
+
+ if (i<127)
+ {
+ double y0 = 0, y1 = 0;
+ y0 = details::ytab[i];
+ y1 = details::ytab[i+1];
+ y = y1+(y0-y1)*r();
+ }
+ else
+ {
+ x = PARAM_R - std::log(1.0 - r()) / PARAM_R;
+ y = exp( - PARAM_R*(x-0.5* PARAM_R)) * r();
+ }
+ if (y < std::exp(-0.5*x*x)) break;
+ }
+ return sign ? sigma_*x : -sigma_*x;
+ }
+
+public:
+
+ T mean_;
+ T sigma_;
+};
+
+} // namespace moose
+
+#endif /* end of include guard: NORMALDISTRIBUTION_H */
diff --git a/randnum/NormalRng.cpp b/randnum/NormalRng.cpp
deleted file mode 100644
index e31f636f31a900b7bed1b657d4785f3b89c9e5a9..0000000000000000000000000000000000000000
--- a/randnum/NormalRng.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/*******************************************************************
- * File: NormalRng.cpp
- * Description: This is the MOOSE front end for class Normal,
- * which generates normally distributed random
- * doubles.
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2007-11-03 22:07:04
- ********************************************************************/
-/**********************************************************************
-** This program is part of 'MOOSE', the
-** Messaging Object Oriented Simulation Environment,
-** also known as GENESIS 3 base code.
-** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
-** It is made available under the terms of the
-** GNU General Public License version 2
-** See the file COPYING.LIB for the full notice.
-**********************************************************************/
-
-#ifndef _NORMALRNG_CPP
-#define _NORMALRNG_CPP
-#include "NormalRng.h"
-#include "Normal.h"
-const Cinfo* NormalRng::initCinfo()
-{
- static ValueFinfo< NormalRng, double > mean(
- "mean",
- "Mean of the normal distribution",
- &NormalRng::setMean,
- &NormalRng::getMean);
- static ValueFinfo< NormalRng, double > variance(
- "variance",
- "Variance of the normal distribution",
- &NormalRng::setVariance,
- &NormalRng::getVariance);
- static ValueFinfo< NormalRng, int > method(
- "method",
- "Algorithm used for computing the sample. The default is 0 = alias"
- " method by Ahrens and Dieter. Other options are: 1 = Box-Mueller method"
- " and 2 = ziggurat method.",
- &NormalRng::setMethod,
- &NormalRng::getMethod);
- static Finfo* normalRngFinfos[] = {
- &mean,
- &variance,
- &method,
- };
-
- static string doc[] = {
- "Name", "NormalRng",
- "Author", "Subhasis Ray",
- "Description", "Normally distributed random number generator.",
- };
- Dinfo< NormalRng > dinfo;
- static Cinfo normalRngCinfo(
- "NormalRng",
- RandGenerator::initCinfo(),
- normalRngFinfos,
- sizeof(normalRngFinfos)/sizeof(Finfo*),
- &dinfo,
- doc,
- sizeof( doc ) / sizeof( string ));
- return &normalRngCinfo;
-}
-
-
-static const Cinfo* normalRngCinfo = NormalRng::initCinfo();
-
-/**
- Set the mean of the internal generator object.
- */
-void NormalRng::setMean(double mean)
-{
- Normal* nrng = static_cast < Normal* >(rng_);
- if (nrng){
- nrng->setMean(mean);
- }
-}
-
-/**
- Since normal distribution is defined in terms of mean and variance, we
- want to store them in order to create the internal generator object.
- */
-void NormalRng::setVariance(double variance)
-{
- if ( variance < 0 )
- {
- cerr << "ERROR: variance cannot be negative." << endl;
- return;
- }
- Normal * nrng = static_cast < Normal* >(rng_);
- if (nrng){
- nrng->setVariance(variance);
- }
-}
-
-/**
- Returns the algorithm used.
- 0 for alias method.
- 1 for BoxMueller method.
- */
-int NormalRng::getMethod() const
-{
- Normal* nrng = static_cast < Normal * > (rng_);
- if (nrng){
- return nrng->getMethod();
- }
- return 0;
-}
-/**
- Set the algorithm to be used.
- 1 for BoxMueller method.
- Anything else for alias method.
- */
-void NormalRng::setMethod(int method)
-{
- Normal* nrng = static_cast <Normal*> (rng_);
- if ( nrng ){
- cout << "Warning: Changing method after generator object has been created. Current method: " << nrng->getMethod() << ". New method: " << method << endl;
- nrng->setMethod((NormalGenerator)method);
- }
-}
-
-void NormalRng::vReinit(const Eref& e, ProcPtr p)
-{
- // do nothing
-}
-
-/**
- By default the method used for normal distribution is alias method
- by Ahrens and Dieter. In order to use some method other than the
- default Alias method, one should call setMethod with a proper
- method index before calling reset ( reinit ). Since different
- methods create different random sequences, the combined sequence
- may not have the intended distribution. By default mean and
- variance are set to 0.0 and 1.0 respectively.
- */
-NormalRng::NormalRng():RandGenerator()
-{
- rng_ = new Normal();
-}
-#endif
diff --git a/randnum/NormalRng.h b/randnum/NormalRng.h
deleted file mode 100644
index 55e100d2b4f0760541b334a80e21346fa474d3b1..0000000000000000000000000000000000000000
--- a/randnum/NormalRng.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*******************************************************************
- * File: NormalRng.h
- * Description:
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2007-11-05 10:19:18
- ********************************************************************/
-/**********************************************************************
-** This program is part of 'MOOSE', the
-** Messaging Object Oriented Simulation Environment,
-** also known as GENESIS 3 base code.
-** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
-** It is made available under the terms of the
-** GNU General Public License version 2
-** See the file COPYING.LIB for the full notice.
-**********************************************************************/
-
-#ifndef _NORMALRNG_H
-#define _NORMALRNG_H
-#include "randnum.h"
-#include "basecode/header.h"
-#include "RandGenerator.h"
-#include "Normal.h"
-
-/**
- This is MOOSE wrapper for normally distributed random number generator class, Normal.
- The default
- */
-class NormalRng: public RandGenerator
-{
- public:
- NormalRng();
- virtual ~NormalRng() { ; }
- void setMean(double mean);
- void setVariance(double variance);
- void setMethod(int method);
- int getMethod() const;
- virtual void vReinit( const Eref& e, ProcPtr p);
-
- static const Cinfo * initCinfo();
-};
-
-
-#endif
diff --git a/randnum/Poisson.cpp b/randnum/Poisson.cpp
deleted file mode 100644
index fe06c4e34b91b96742c17347ab4d6fd323837ca0..0000000000000000000000000000000000000000
--- a/randnum/Poisson.cpp
+++ /dev/null
@@ -1,232 +0,0 @@
-/*******************************************************************
- * File: Poisson.cpp
- * Description:
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2007-11-01 16:09:38
- ********************************************************************/
-/**********************************************************************
-** This program is part of 'MOOSE', the
-** Messaging Object Oriented Simulation Environment,
-** also known as GENESIS 3 base code.
-** copyright (C) 2003-2010 Upinder S. Bhalla. and NCBS
-** It is made available under the terms of the
-** GNU General Public License version 2
-** See the file COPYING.LIB for the full notice.
-**********************************************************************/
-/******************************************************************
- * Some of the functions have been copied/adapted from stochastic
- * library package by Agner Fog, published under GPL.
- * Refer to http://www.agner.org/random/ for more information.
- ******************************************************************/
-#ifndef _POISSON_CPP
-#define _POISSON_CPP
-#include "Poisson.h"
-#include "randnum.h"
-#include "utility/numutil.h"
-#include "Gamma.h"
-#include "Binomial.h"
-#include <cmath>
-#include <iostream>
-
-using namespace std;
-
-Poisson::Poisson(double mean):mean_(mean), gammaGen_(NULL) //, binomialGen_(NULL)
- , generator_(NULL)
-{
- /* replicates setMean */
- if (mean <= 0.0)
- {
- cerr << "ERROR: Poisson::setMean - mean must be positive. Setting to 1.0" << endl;
- mean_ = 1.0;
- }
- if ( mean_ < 17)
- {
- generator_ = Poisson::poissonSmall;
- mValue_ = exp(-mean_);
- }
- else
- {
- generator_ = Poisson::poissonLarge;
- mValue_ = floor(0.875*mean_);
- if (gammaGen_)
- {
- delete gammaGen_;
- }
- gammaGen_ = new Gamma(mValue_, 1.0);
- }
-}
-
-Poisson::~Poisson()
-{
- if (gammaGen_)
- {
- delete gammaGen_;
- }
-}
-
-
-void Poisson::setMean(double mean)
-{
- if (mean <= 0.0)
- {
- cerr << "ERROR: Poisson::setMean - mean must be positive. Setting to 1.0" << endl;
- mean_ = 1.0;
- }
- if ( mean_ < 17)
- {
- generator_ = Poisson::poissonSmall;
- mValue_ = exp(-mean_);
- }
- else
- {
- generator_ = Poisson::poissonLarge;
- mValue_ = floor(0.875*mean_);
- if (gammaGen_)
- {
- delete gammaGen_;
- }
- gammaGen_ = new Gamma(mValue_, 1.0);
- }
-}
-
-double Poisson::getMean() const
-{
- return mean_;
-}
-
-double Poisson::getVariance() const
-{
- return mean_;
-}
-
-double Poisson::getNextSample() const
-{
- if (!generator_)
- {
- cerr << "ERROR: Poisson::getNextSample() - generator function is NULL" << endl;
- return 0.0;
- }
- return generator_(*this);
-}
-
-/**
- Poisson distributed random number generator when mean is small.
- See: TAOCP by Knuth, Volume 2, Section 3.4.1
- */
-double Poisson::poissonSmall(const Poisson& poisson)
-{
- double product = 1.0;
-
- int i = 0;
- while ( product > poisson.mValue_ )
- {
- product *= mtrand();
- ++i;
- }
- return i;
-}
-
-/**
- Poisson distributed random number generator when mean is large.
- See: TAOCP by Knuth, Volume 2, Section 3.4.1
- */
-/* //replaced by cleaner version
- double Poisson::poissonLarge() const
-{
-
- // generate X with the gamma distribution of order floor(alpha*mu)
- // where alpha is a suitable constant
- static double m_value = floor(0.875*mean_); // alpha = 7/8 = 0.875 is a good value according to Ahrens and Dieter
- static Gamma gammaGen(m_value, 1.0);
- double n_value;
-
- double x_value = gammaGen.getNextSample();
-
- if ( x_value < mean_ )
- {
- Poisson poissonGen(mean_ - x_value);
- n_value = m_value + poissonGen.getNextSample();
- }
- else
- {
- Binomial binomialGen((long)m_value-1,mean_/x_value);
- n_value = binomialGen.getNextSample();
- }
-
- return n_value;
-}
-*/
- // WATCH OUT: this is recursive. look for better alternative.
-double Poisson::poissonLarge(const Poisson& poisson)
-{
- double xValue = poisson.gammaGen_->getNextSample();
- if (xValue < poisson.mean_)
- {
- Poisson poissonGen(poisson.mean_ - xValue);
- return poisson.mValue_ + poissonGen.getNextSample();
- }
- Binomial binomialGen((long)poisson.mValue_ - 1, poisson.mean_/xValue);
- return binomialGen.getNextSample();
-}
-
-#ifdef TEST_MAIN
-
-#include <vector>
-#include <algorithm>
-#include <cstdlib>
-int main(int argc, char **argv)
-{
- double mean = 4;
-
- if (argc > 1)
- mean = atof(argv[1]);
-
-
- double sum = 0.0;
- double sd = 0.0;
- vector <double> samples;
- Poisson poisson(mean);
- int MAX_SAMPLE = 100000;
- unsigned index;
-
-
- cout << "epsilon = " << getMachineEpsilon() << endl;
- for ( int i = 0; i < MAX_SAMPLE; ++i )
- {
- double p = poisson.getNextSample();//aliasMethod();
- samples.push_back(p);
-
- sum += p;
- sd += (p - mean)*(p - mean);
- }
- mean = sum/MAX_SAMPLE;
- sd = sqrt(sd/MAX_SAMPLE);
- cout << "mean = " << mean << " sd = " << sd << endl;
- sort(samples.begin(), samples.end());
-
- unsigned i = 0;
- unsigned start = 0;
- index = 0;
-
- while ( i < samples.size() )
- {
- int count = 0;
-
- while( ( i < samples.size() ) && (samples[i] == samples[start] ))
- {
- ++count;
- ++i;
- }
- while( index < samples[start])
- {
- cout << index++ << " " << 0 << endl;
- }
-
- cout << index++ << " " << count << endl;
- start = i;
- }
- return 0;
-}
-#endif // test main
-#endif
diff --git a/randnum/Poisson.h b/randnum/Poisson.h
deleted file mode 100644
index 985bd56f56693bc3991bbf9e8967348acec326a0..0000000000000000000000000000000000000000
--- a/randnum/Poisson.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*******************************************************************
- * File: Poisson.h
- * Description:
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2007-11-02 09:43:47
- ********************************************************************/
-/**********************************************************************
-** This program is part of 'MOOSE', the
-** Messaging Object Oriented Simulation Environment,
-** also known as GENESIS 3 base code.
-** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
-** It is made available under the terms of the
-** GNU General Public License version 2
-** See the file COPYING.LIB for the full notice.
-**********************************************************************/
-
-#ifndef _POISSON_H
-#define _POISSON_H
-
-#include "Probability.h"
-#include "Gamma.h"
-#include "Binomial.h"
-
-class Poisson;
-
-typedef double (Poisson::*PoissonGenerator)() const;
-
-#define CALL_POSSON_GENERATOR(object,ptrToMember) ((object).*(ptrToMember))
-
-class Poisson:public Probability
-{
- public:
- Poisson(double mean=1.0);
- ~Poisson();
-
- void setMean(double mean);
- double getMean() const;
- double getVariance() const;
- double getNextSample() const;
- private:
- double mean_;
- static double poissonSmall(const Poisson&);
- static double poissonLarge(const Poisson&);
- Gamma* gammaGen_;
- //Binomial* binomialGen_;
- double (*generator_)(const Poisson&);
- double mValue_;
-};
-
-#endif
diff --git a/randnum/PoissonRng.cpp b/randnum/PoissonRng.cpp
deleted file mode 100644
index b8ac5b5c140730fe859b41c3ad8464e88eef9ba1..0000000000000000000000000000000000000000
--- a/randnum/PoissonRng.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*******************************************************************
- * File: PoissonRng.cpp
- * Description:
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2007-11-08 09:53:32
- * Updated: 2014-09-29
- ********************************************************************/
-/**********************************************************************
-** This program is part of 'MOOSE', the
-** Messaging Object Oriented Simulation Environment,
-** also known as GENESIS 3 base code.
-** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
-** It is made available under the terms of the
-** GNU General Public License version 2
-** See the file COPYING.LIB for the full notice.
-**********************************************************************/
-
-#ifndef _POISSONRNG_CPP
-#define _POISSONRNG_CPP
-#include "../basecode/header.h"
-#include "PoissonRng.h"
-
-const Cinfo* PoissonRng::initCinfo()
-{
- static ValueFinfo< PoissonRng, double > mean(
- "mean",
- "Mean of the Poisson distribution.",
- &PoissonRng::setMean,
- &PoissonRng::getMean);
- static Finfo* poissonRngFinfos[] = {
- &mean,
- };
- static string doc[] = {
- "Name", "PoissonRng",
- "Author", "Subhasis Ray",
- "Description", "Poisson distributed random number generator.",
- };
- static Dinfo< PoissonRng > dinfo;
- static Cinfo poissonRngCinfo(
- "PoissonRng",
- RandGenerator::initCinfo(),
- poissonRngFinfos,
- sizeof(poissonRngFinfos)/sizeof(Finfo*),
- &dinfo,
- doc,
- sizeof( doc ) / sizeof( string ));
-
- return &poissonRngCinfo;
-}
-
-
-static const Cinfo* poissonRngCinfo = PoissonRng::initCinfo();
-
-PoissonRng::PoissonRng()
-{
- //do nothing. should not try to get mean
-}
-
-/**
- Sets the mean. Since poisson distribution is defined in terms of
- the rate parameter or the mean, it is mandatory to set this before
- using the generator.
-*/
-void PoissonRng::setMean(double mean)
-{
- Poisson * prng = static_cast<Poisson*>(rng_);
- if ( !prng ){
- rng_ = new Poisson(mean);
- } else {
- prng->setMean(mean);
- }
-}
-/**
- reports error in case the parameter mean has not been set.
-*/
-void PoissonRng::vReinit(const Eref& e, ProcPtr p)
-{
- if ( !rng_ )
- {
- cerr << "ERROR: PoissonRng::vReinit - mean must be set before using the Poisson distribution generator." << endl;
- }
-}
-
-
-#endif
diff --git a/randnum/PoissonRng.h b/randnum/PoissonRng.h
deleted file mode 100644
index 119276b750d04b58700a161cfb78ca1e2cd1f37b..0000000000000000000000000000000000000000
--- a/randnum/PoissonRng.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*******************************************************************
- * File: PoissonRng.h
- * Description:
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2007-11-07 16:22:35
- ********************************************************************/
-/**********************************************************************
-** This program is part of 'MOOSE', the
-** Messaging Object Oriented Simulation Environment,
-** also known as GENESIS 3 base code.
-** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
-** It is made available under the terms of the
-** GNU General Public License version 2
-** See the file COPYING.LIB for the full notice.
-**********************************************************************/
-
-#ifndef _POISSONRNG_H
-#define _POISSONRNG_H
-#include "Poisson.h"
-#include "RandGenerator.h"
-class PoissonRng:public RandGenerator
-{
- public:
- PoissonRng();
- virtual ~PoissonRng() { ; }
- void setMean(double mean);
- virtual void vReinit(const Eref& e, ProcPtr p);
- static const Cinfo * initCinfo();
-};
-
-
-#endif
diff --git a/randnum/Probability.cpp b/randnum/Probability.cpp
deleted file mode 100644
index c7ad7da78c116b8e505ef465186bfb1480e0ed03..0000000000000000000000000000000000000000
--- a/randnum/Probability.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/*******************************************************************
- * File: Probability.cpp
- * Description:
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2007-10-28 13:35:39
- ********************************************************************/
-/**********************************************************************
-** This program is part of 'MOOSE', the
-** Messaging Object Oriented Simulation Environment,
-** also known as GENESIS 3 base code.
-** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
-** It is made available under the terms of the
-** GNU General Public License version 2
-** See the file COPYING.LIB for the full notice.
-**********************************************************************/
-
-#ifndef _PROBABILITY_CPP
-#define _PROBABILITY_CPP
-#include "Probability.h"
-
-//const Cinfo* initProbabilityCinfo
-// TODO: implement some tests for generated distributions
-// Kolmogorov-Smirnov test in particular
-
-#endif
diff --git a/randnum/Probability.h b/randnum/Probability.h
deleted file mode 100644
index 61c5acf5d5ad1c2488949b5e6c3977f3210f0719..0000000000000000000000000000000000000000
--- a/randnum/Probability.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*******************************************************************
- * File: Probability.h
- * Description: This is base class for various probability
- * distribution generator classes.
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2007-10-28 13:30:41
- ********************************************************************/
-/**********************************************************************
-** This program is part of 'MOOSE', the
-** Messaging Object Oriented Simulation Environment,
-** also known as GENESIS 3 base code.
-** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
-** It is made available under the terms of the
-** GNU General Public License version 2
-** See the file COPYING.LIB for the full notice.
-**********************************************************************/
-
-#ifndef _PROBABILITY_H
-#define _PROBABILITY_H
-
-
-/**
- Base class for implementing various probability distributions.
- */
-class Probability
-{
- public:
- virtual ~Probability(){};
-
- virtual double getMean() const =0;
- virtual double getVariance()const =0;
- virtual double getNextSample()const =0;
-
- private:
-// long double mean_; // TODO : do we really need this?
-// long double variance_;// TODO : do we really need this?
-};
-
-#endif
diff --git a/randnum/RNG.h b/randnum/RNG.h
index 9eb1639ec093dd4088d20aea500155f38a74d0ff..758e599ba4ea21f666607e2a0d54bfed1f635e30 100644
--- a/randnum/RNG.h
+++ b/randnum/RNG.h
@@ -19,29 +19,17 @@
#ifndef __RNG_INC
#define __RNG_INC
-#ifdef USE_BOOST
-
-#include <boost/random.hpp>
-#include <boost/random/uniform_01.hpp>
-
-#if defined(BOOST_RANDOM_DEVICE_EXISTS)
-#include <boost/random/random_device.hpp>
-#endif // BOOST_RANDOM_DEVICE_EXISTS
-#else /* ----- not USE_BOOST ----- */
-#include <ctime>
-#include "randnum.h"
-#endif /* ----- not USE_BOOST ----- */
-
#include <limits>
#include <iostream>
-
-#ifdef ENABLE_CPP11
#include <random>
-#endif
+
+#include "Definitions.h"
+#include "Distributions.h"
using namespace std;
-namespace moose {
+namespace moose
+{
/*
* =====================================================================================
@@ -65,17 +53,8 @@ class RNG
void setRandomSeed( )
{
-#if defined(USE_BOOST)
-#if defined(BOOST_RANDOM_DEVICE_EXISTS)
- boost::random::random_device rd;
- setSeed( rd() );
-#endif
-#elif defined(ENABLE_CPP11)
- std::random_device rd;
- setSeed( rd() );
-#else
- mtseed( time(NULL) );
-#endif /* ----- not ENABLE_CPP11 ----- */
+ MOOSE_RANDOM_DEVICE rd_;
+ setSeed( rd_() );
}
/* ==================== ACCESSORS ======================================= */
@@ -91,20 +70,15 @@ class RNG
*
* @param seed
*/
- void setSeed( const unsigned long int seed )
+ void setSeed( const unsigned long seed )
{
seed_ = seed;
if( seed == 0 )
{
- setRandomSeed( );
- return;
+ MOOSE_RANDOM_DEVICE rd_;
+ seed_ = rd_();
}
-
-#if defined(USE_BOOST) || defined(ENABLE_CPP11)
rng_.seed( seed_ );
-#else
- mtseed( seed_ );
-#endif
}
/**
@@ -115,11 +89,7 @@ class RNG
*/
T uniform( const T a, const T b)
{
-#if defined(USE_BOOST) || defined(ENABLE_CPP11)
return ( b - a ) * dist_( rng_ ) + a;
-#else
- return (b-a) * mtrand() + a;
-#endif
}
/**
@@ -130,11 +100,7 @@ class RNG
*/
T uniform( void )
{
-#if defined(USE_BOOST) || defined(ENABLE_CPP11)
return dist_( rng_ );
-#else
- return mtrand();
-#endif
}
@@ -143,17 +109,11 @@ class RNG
T res_;
T seed_;
-#if USE_BOOST
- boost::random::mt19937 rng_;
- boost::random::uniform_01<T> dist_;
-#elif ENABLE_CPP11
- std::mt19937 rng_;
- std::uniform_real_distribution<> dist_;
-#endif /* ----- not ENABLE_CPP11 ----- */
+ moose::MOOSE_RNG_DEFAULT_ENGINE rng_;
+ moose::MOOSE_UNIFORM_DISTRIBUTION<double> dist_;
}; /* ----- end of template class RNG ----- */
-
} /* namespace moose ends */
#endif /* ----- #ifndef __RNG_INC ----- */
diff --git a/randnum/RandGenerator.cpp b/randnum/RandGenerator.cpp
deleted file mode 100644
index 7bd80f355fc4528866de305a6a746c249a06f0e2..0000000000000000000000000000000000000000
--- a/randnum/RandGenerator.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-/*******************************************************************
- * File: RandGenerator.cpp
- * Description: Interface class for MOOSE to access various
- * random number generator.
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2007-11-03 21:48:17
- ********************************************************************/
-/**********************************************************************
- ** This program is part of 'MOOSE', the
- ** Messaging Object Oriented Simulation Environment,
- ** also known as GENESIS 3 base code.
- ** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
- ** It is made available under the terms of the
- ** GNU General Public License version 2
- ** See the file COPYING.LIB for the full notice.
- **********************************************************************/
-
-#ifndef _RANDGENERATOR_CPP
-#define _RANDGENERATOR_CPP
-
-#include "../basecode/header.h"
-#include "RandGenerator.h"
-
-static SrcFinfo1< double >* output()
-{
- static SrcFinfo1< double > output(
- "output",
- "Generated random number.");
- return &output;
-}
-
-const Cinfo * RandGenerator::initCinfo()
-{
- //////////////////////////////////////////////////////////////
- // MsgDest Definitions
- //////////////////////////////////////////////////////////////
- static DestFinfo process(
- "process",
- "Handles process call, updates internal time stamp.",
- new ProcOpFunc< RandGenerator >( &RandGenerator::process ));
- static DestFinfo reinit(
- "reinit",
- "Handles reinit call.",
- new ProcOpFunc< RandGenerator >( &RandGenerator::reinit ));
- //////////////////////////////////////////////////////////////
- // SharedMsg Definitions
- //////////////////////////////////////////////////////////////
- static Finfo* procShared[] = {
- &process, &reinit
- };
- static SharedFinfo proc(
- "proc",
- "Shared message for process and reinit",
- procShared, sizeof( procShared ) / sizeof( const Finfo* ));
-
- //////////////////////////////////////////////////////////////
- // ValueFinfo Definitions
- //////////////////////////////////////////////////////////////
-
- static ReadOnlyValueFinfo<RandGenerator, double> sample(
- "sample",
- "Generated pseudorandom number.",
- &RandGenerator::getSample);
- static ReadOnlyValueFinfo< RandGenerator, double > mean(
- "mean",
- "Mean of the distribution.",
- &RandGenerator::getMean);
- static ReadOnlyValueFinfo<RandGenerator, double> variance(
- "variance",
- "Variance of the distribution.",
- &RandGenerator::getVariance);
-
- static Finfo * randGeneratorFinfos[] = {
- &sample,
- &mean,
- &variance,
- output(),
- &proc,
- };
-
- static string doc[] = {
- "Name", "RandGenerator",
- "Author", "Subhasis Ray",
- "Description", "Base class for random number generators for sampling various"
- " probability distributions. This class should not be used"
- " directly. Instead, its subclasses named after specific distributions"
- " should be used.",
- };
-
- static Dinfo< RandGenerator > dinfo;
- static Cinfo randGeneratorCinfo(
- "RandGenerator",
- Neutral::initCinfo(),
- randGeneratorFinfos,
- sizeof(randGeneratorFinfos)/sizeof(Finfo*),
- &dinfo,
- doc,
- sizeof( doc ) / sizeof( string ));
-
- return &randGeneratorCinfo;
-}
-
-static const Cinfo * randGeneratorCinfo = RandGenerator::initCinfo();
-
-RandGenerator::RandGenerator()
-{
- sample_ = 0.0;
- rng_ = NULL;
-}
-
-RandGenerator::~RandGenerator()
-{
- if (rng_)
- {
- delete rng_;
- rng_ = NULL;
- }
-}
-
-double RandGenerator::getMean() const
-{
- if (rng_)
- {
- return rng_->getMean();
- }
- return 0.0;
-}
-
-double RandGenerator::getVariance() const
-{
- if (rng_)
- {
- return rng_->getVariance();
- }
- return 0.0;
-}
-
-double RandGenerator::getSample() const
-{
- return sample_;
-}
-
-void RandGenerator::process( const Eref& e, ProcPtr p )
-{
- if (rng_){
- sample_ = rng_->getNextSample();
- output()->send(e, sample_);
- }
-}
-
-void RandGenerator::reinit(const Eref& e, ProcPtr p)
-{
- vReinit(e, p);
-}
-
-void RandGenerator::vReinit(const Eref& e, ProcPtr p)
-{
- cerr << "RandGenerator::vReinit() - this function should never be reached. Guilty party: " << e.id().path() << endl;
-}
-
-#endif
diff --git a/randnum/RandGenerator.h b/randnum/RandGenerator.h
deleted file mode 100644
index 7e37b716ceabce763c2573e80a2611583a414cc2..0000000000000000000000000000000000000000
--- a/randnum/RandGenerator.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*******************************************************************
- * File: RandGenerator.h
- * Description:
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2007-11-07 16:25:08
- ********************************************************************/
-/**********************************************************************
-** This program is part of 'MOOSE', the
-** Messaging Object Oriented Simulation Environment,
-** also known as GENESIS 3 base code.
-** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
-** It is made available under the terms of the
-** GNU General Public License version 2
-** See the file COPYING.LIB for the full notice.
-**********************************************************************/
-
-#ifndef _RANDGENERATOR_H
-#define _RANDGENERATOR_H
-
-#include "randnum.h"
-#include "basecode/header.h"
-#include "Probability.h"
-
-/**
- This class is a moose interface to underlying random number
- generators (which is an instance of Probability class).
- */
-class RandGenerator
-{
- public:
- RandGenerator();
- virtual ~RandGenerator();
- double getMean() const;
- double getVariance() const;
- double getSample() const;
- void process( const Eref& e, ProcPtr info);
- void reinit( const Eref& e, ProcPtr info);
- virtual void vReinit( const Eref& e, ProcPtr info);
-
- static const Cinfo * initCinfo();
- protected:
- Probability* rng_;
- double sample_;
-};
-
-
-#endif
diff --git a/randnum/Uniform.cpp b/randnum/Uniform.cpp
deleted file mode 100644
index 1b9fb8bf9f6fdca4c453bf7dae42a018a63b4695..0000000000000000000000000000000000000000
--- a/randnum/Uniform.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-/*******************************************************************
- * File: Uniform.cpp
- * Description:
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2008-02-21 17:12:55
- ********************************************************************/
-/**********************************************************************
-** This program is part of 'MOOSE', the
-** Messaging Object Oriented Simulation Environment,
-** also known as GENESIS 3 base code.
-** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
-** It is made available under the terms of the
-** GNU General Public License version 2
-** See the file COPYING.LIB for the full notice.
-**********************************************************************/
-
-#ifndef _UNIFORM_CPP
-#define _UNIFORM_CPP
-
-#include <cassert>
-#include <iostream>
-#include <vector>
-
-#include "Uniform.h"
-#include "randnum.h"
-#include "utility/numutil.h"
-using namespace std;
-
-Uniform::Uniform()
-{
- min_ = 0.0;
- max_ = 1.0;
-}
-Uniform::Uniform(double min, double max)
-{
- if ( min >= max )
- {
- cerr << "ERROR: specified lowerbound is greater than upper bound." << endl;
- min_ = 0.0;
- max_ = 1.0;
- return;
- }
-
- min_ = min;
- max_ = max;
-}
-double Uniform::getMean() const
-{
- return (max_ + min_) / 2.0;
-}
-double Uniform::getVariance()const
-{
- return (max_- min_) * (max_ - min_)/12.0;
-}
-double Uniform::getMin() const
-{
- return min_;
-}
-double Uniform::getMax() const
-{
- return max_;
-}
-void Uniform::setMin(double min)
-{
- min_ = min;
-}
-void Uniform::setMax(double max)
-{
- max_ = max;
-}
-double Uniform::getNextSample() const
-{
- assert( max_ > min_ );
- return mtrand()*(max_-min_)+min_;
-}
-
-#ifdef DO_UNIT_TESTS
-void doTest(double min, double max, unsigned count)
-{
- Uniform rng;
-
- rng.setMin(min);
- rng.setMax(max);
- assert(isClose<double>(min, rng.getMin(), DBL_EPSILON));
- assert(isClose<double>(max, rng.getMax(), DBL_EPSILON));
- vector <double> seq;
- double mean = 0.0;
-
-
- for (unsigned ii = 0; ii < count; ++ii )
- {
- double sample;
- sample = rng.getNextSample();
- mean += sample;
- seq.push_back(sample);
- }
- mean /= count;
- double var = 0.0;
- for(unsigned ii = 0; ii <seq.size(); ++ii)
- {
- var += (mean - seq[ii]) * (mean - seq[ii]);
- }
- var = var / count;
- cout << "theoretical mean: " << rng.getMean() << ", sample mean: " << mean << ", theoretical var: " << rng.getVariance() << ", sample var: " << var << ", sample size: " << count << endl;
-
-}
-
-void testUniform()
-{
- cout << "testUniform(): testing uniform rng.\n";
- doTest(-10.0, 10.0, 1000);
- doTest(1e-10, 1.1e-10, 1000);
-}
-
-#endif // DO_UNIT_TESTS
-#if defined( TEST_MAIN ) && defined(DO_UNIT_TESTS)
-int main(void)
-{
- testUniform();
-}
-
-#endif // !defined( TEST_MAIN ) && defined(DO_UNIT_TESTS)
-
-#endif
diff --git a/randnum/Uniform.h b/randnum/Uniform.h
deleted file mode 100644
index 3073fb8252578b8f20424682fd76710d3c5f414d..0000000000000000000000000000000000000000
--- a/randnum/Uniform.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*******************************************************************
- * File: Uniform.h
- * Description:
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2008-02-21 17:09:54
- ********************************************************************/
-/**********************************************************************
-** This program is part of 'MOOSE', the
-** Messaging Object Oriented Simulation Environment,
-** also known as GENESIS 3 base code.
-** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
-** It is made available under the terms of the
-** GNU General Public License version 2
-** See the file COPYING.LIB for the full notice.
-**********************************************************************/
-
-#ifndef _UNIFORM_H
-#define _UNIFORM_H
-
-#include "Probability.h"
-
-class Uniform: public Probability
-{
- public:
- Uniform();
- Uniform(double min, double max);
- double getMean() const;
- double getVariance() const;
- double getNextSample() const;
- double getMin() const;
- double getMax() const;
- void setMin(double min);
- void setMax(double max);
-
- private:
- double min_;
- double max_;
-
-};
-
-
-#endif
diff --git a/randnum/UniformRng.cpp b/randnum/UniformRng.cpp
deleted file mode 100644
index 15630b7c459fb28404b4d043c1a6f31cf212ac97..0000000000000000000000000000000000000000
--- a/randnum/UniformRng.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/*******************************************************************
- * File: UniformRng.cpp
- * Description:
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2008-02-01 11:30:20
- ********************************************************************/
-/**********************************************************************
-** This program is part of 'MOOSE', the
-** Messaging Object Oriented Simulation Environment,
-** also known as GENESIS 3 base code.
-** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
-** It is made available under the terms of the
-** GNU General Public License version 2
-** See the file COPYING.LIB for the full notice.
-**********************************************************************/
-
-#ifndef _UNIFORMRNG_CPP
-#define _UNIFORMRNG_CPP
-#include "../basecode/header.h"
-#include "randnum.h"
-#include "UniformRng.h"
-#include "Uniform.h"
-
-const Cinfo* UniformRng::initCinfo()
-{
- static ValueFinfo< UniformRng, double > min(
- "min",
- "The lower bound on the numbers generated ",
- &UniformRng::setMin,
- &UniformRng::getMin);
- static ValueFinfo< UniformRng, double > max(
- "max",
- "The upper bound on the numbers generated",
- &UniformRng::setMax,
- &UniformRng::getMax);
-
- static Finfo * uniformRngFinfos[] = {
- &min,
- &max,
- };
- static string doc[] =
- {
- "Name", "UniformRng",
- "Author", "Subhasis Ray",
- "Description", "Generates pseudorandom number from a unform distribution.",
- };
- static Dinfo< UniformRng > dinfo;
- static Cinfo uniformRngCinfo(
- "UniformRng",
- RandGenerator::initCinfo(),
- uniformRngFinfos,
- sizeof( uniformRngFinfos ) / sizeof( Finfo* ),
- &dinfo,
- doc,
- sizeof( doc ) / sizeof( string ));
- return &uniformRngCinfo;
-}
-
-static const Cinfo* uniformRngCinfo = UniformRng::initCinfo();
-
-double UniformRng::getMin()const
-{
- Uniform * urng = static_cast< Uniform * >(rng_);
- if (urng){
- return urng->getMin();
- }
- return 0.0;
-}
-
-double UniformRng::getMax() const
-{
- Uniform * urng = static_cast< Uniform * >(rng_);
- if (urng){
- return urng->getMax();
- }
- return 0.0;
-}
-
-void UniformRng::setMin(double min)
-{
- Uniform * urng = static_cast<Uniform *> (rng_);
- if (urng){
- urng->setMin(min);
- }
-}
-
-void UniformRng::setMax(double max)
-{
- Uniform * urng = static_cast<Uniform *> (rng_);
- if (urng){
- urng->setMax(max);
- }
-}
-
-UniformRng::UniformRng():RandGenerator()
-{
- rng_ = new Uniform();
-}
-
-void UniformRng::vReinit(const Eref& e, ProcPtr p)
-{
- ; /* no use */
-}
-
-#ifdef DO_UNIT_TESTS
-void testUniformRng()
-{
- cout << "testUniformRng(): yet to be implemented" << endl;
-}
-
-#endif
-#endif
diff --git a/randnum/UniformRng.h b/randnum/UniformRng.h
deleted file mode 100644
index da4d4af07952f84606e0564044300a30f112c8c6..0000000000000000000000000000000000000000
--- a/randnum/UniformRng.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*******************************************************************
- * File: UniformRng.h
- * Description:
- * Author: Subhasis Ray
- * E-mail: ray.subhasis@gmail.com
- * Created: 2008-02-01 11:52:48
- ********************************************************************/
-/**********************************************************************
-** This program is part of 'MOOSE', the
-** Messaging Object Oriented Simulation Environment,
-** also known as GENESIS 3 base code.
-** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS
-** It is made available under the terms of the
-** GNU General Public License version 2
-** See the file COPYING.LIB for the full notice.
-**********************************************************************/
-
-#ifndef _UNIFORMRNG_H
-#define _UNIFORMRNG_H
-
-#include "randnum.h"
-#include "RandGenerator.h"
-
-class UniformRng: public RandGenerator
-{
- public:
- UniformRng();
- virtual ~UniformRng() { ; }
- double getMin() const;
- double getMax() const;
- void setMin(double min);
- void setMax(double max);
- virtual void vReinit(const Eref& e, ProcPtr p);
-
- static const Cinfo * initCinfo();
- private:
- double min_;
- double max_;
-};
-
-
-
-#endif
diff --git a/randnum/mt19937ar.cpp b/randnum/mt19937ar.cpp
deleted file mode 100644
index 3becb14a9a1aa52b9e7e0ea1e7fd706129ed57d8..0000000000000000000000000000000000000000
--- a/randnum/mt19937ar.cpp
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- A C-program for MT19937, with initialization improved 2002/1/26.
- Coded by Takuji Nishimura and Makoto Matsumoto.
-
- Before using, initialize the state by using init_genrand(seed)
- or init_by_array(init_key, key_length).
-
- Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. 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.
-
- 3. The names of its contributors may not 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 OWNER 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.
-
-
- Any feedback is very welcome.
- http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
- email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
-*/
-
-/* Modified slightly for use in MOOSE by Upi Bhalla, NCBS, 2004 */
-#ifdef _WIN32
-#include <Winsock2.h>
-#else
-#define _BSD_SOURCE
-#include <sys/time.h>
-#endif
-#include <stdlib.h>
-#include "randnum.h"
-/* Period parameters */
-#define N 624
-#define M 397
-#define MATRIX_A 0x9908b0dfUL /* constant vector a */
-#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
-#define LOWER_MASK 0x7fffffffUL /* least significant r bits */
-
-static unsigned long mt[N]; /* the array for the state vector */
-static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
-
-/* initializes mt[N] with a seed */
-void init_genrand(unsigned long s)
-{
- mt[0]= s & 0xffffffffUL;
- for (mti=1; mti<N; mti++) {
- mt[mti] =
- (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
- /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
- /* In the previous versions, MSBs of the seed affect */
- /* only MSBs of the array mt[]. */
- /* 2002/01/09 modified by Makoto Matsumoto */
- mt[mti] &= 0xffffffffUL;
- /* for >32 bit machines */
- }
-}
-
-//Add code for gettimeofday
-#ifdef _WIN32
- int gettimeofday( struct timeval* tv, void* timezone ) {
- FILETIME time;
- double timed;
-
- GetSystemTimeAsFileTime( &time );
-
- // Apparently Win32 has units of 1e-7 sec (tenths of microsecs)
- // 4294967296 is 2^32, to shift high word over
- // 11644473600 is the number of seconds between
- // the Win32 epoch 1601-Jan-01 and the Unix epoch 1970-Jan-01
- // Tests found floating point to be 10x faster than 64bit int math.
-
- timed = ((time.dwHighDateTime * 4294967296e-7) - 11644473600.0) +
- (time.dwLowDateTime * 1e-7);
-
- tv->tv_sec = (long) timed;
- tv->tv_usec = (long) ((timed - tv->tv_sec) * 1e6);
-
- return 0;
- }
-#endif
-
-
-
-
-
-/* initialize by an array with array-length */
-/* init_key is the array for initializing keys */
-/* key_length is its length */
-/* slight change for C++, 2004/2/26 */
-void init_by_array(long int init_key[], int key_length)
-{
- int i, j, k;
- init_genrand(19650218UL);
- i=1; j=0;
- k = (N>key_length ? N : key_length);
- for (; k; k--) {
- mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL))
- + init_key[j] + j; /* non linear */
- mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
- i++; j++;
- if (i>=N) { mt[0] = mt[N-1]; i=1; }
- if (j>=key_length) j=0;
- }
- for (k=N-1; k; k--) {
- mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL))
- - i; /* non linear */
- mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
- i++;
- if (i>=N) { mt[0] = mt[N-1]; i=1; }
- }
-
- mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */
-}
-
-/* generates a random number on [0,0xffffffff]-interval */
-unsigned long genrand_int32(void)
-{
- unsigned long y;
- static unsigned long mag01[2]={0x0UL, MATRIX_A};
- /* mag01[x] = x * MATRIX_A for x=0,1 */
-
- if (mti >= N) { /* generate N words at one time */
- int kk;
-
- if (mti == N+1) /* if init_genrand() has not been called, */
- init_genrand(5489UL); /* a default initial seed is used */
-
- for (kk=0;kk<N-M;kk++) {
- y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
- mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
- }
- for (;kk<N-1;kk++) {
- y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
- mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
- }
- y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
- mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
-
- mti = 0;
- }
-
- y = mt[mti++];
-
- /* Tempering */
- y ^= (y >> 11);
- y ^= (y << 7) & 0x9d2c5680UL;
- y ^= (y << 15) & 0xefc60000UL;
- y ^= (y >> 18);
-
- return y;
-}
-#if 0
-/* generates a random number on [0,0x7fffffff]-interval */
-long genrand_int31(void)
-{
- return (long)(genrand_int32()>>1);
-}
-
-/* generates a random number on [0,1]-real-interval */
-double genrand_real1(void)
-{
- return genrand_int32()*(1.0/4294967295.0);
- /* divided by 2^32-1 */
-}
-
-/* generates a random number on [0,1)-real-interval */
-double genrand_real2(void)
-{
- return genrand_int32()*(1.0/4294967296.0);
- /* divided by 2^32 */
-}
-
-/* generates a random number on (0,1)-real-interval */
-double genrand_real3(void)
-{
- return (((double)genrand_int32()) + 0.5)*(1.0/4294967296.0);
- /* divided by 2^32 */
-}
-
-/* generates a random number on [0,1) with 53-bit resolution*/
-double genrand_res53(void)
-{
- unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6;
- return(a*67108864.0+b)*(1.0/9007199254740992.0);
-}
-/* These real versions are due to Isaku Wada, 2002/01/09 added */
-
-/*
-int main(void)
-{
- int i;
- unsigned long init[4]={0x123, 0x234, 0x345, 0x456}, length=4;
- init_by_array(init, length);
- printf("1000 outputs of genrand_int32()\n");
- for (i=0; i<1000; i++) {
- printf("%10lu ", genrand_int32());
- if (i%5==4) printf("\n");
- }
- printf("\n1000 outputs of genrand_real2()\n");
- for (i=0; i<1000; i++) {
- printf("%10.8f ", genrand_real2());
- if (i%5==4) printf("\n");
- }
- return 0;
-}
-*/
-#endif
-
-void mtseed(long seed = 0)
-{
- struct timeval tv;
-
- if (seed == 0) {
- char* hostname = getenv("HOST");
- gettimeofday(&tv, NULL);
- if (hostname != NULL) {
- for (int i = 0; *hostname; hostname++, i++){
- tv.tv_usec += *hostname * i * i * 16;
- }
- }
- long int init[2] = {tv.tv_sec, tv.tv_usec};
- long int length = 2;
- init_by_array(init, length);
- } else {
- // unsigned long init[1] = {seed};
- // unsigned long length = 1;
- // init_by_array(init, length);
- init_genrand( seed );
- }
-}
-
-/* generates a random number on [0,1)-real-interval */
-double mtrand(void)
-{
- return genrand_int32()*(1.0/4294967296.0);
- /* divided by 2^32 */
-}
diff --git a/randnum/randnum.h b/randnum/randnum.h
deleted file mode 100644
index 5af4abda3b2cb0ba70c9b38f5d0b42ffabd65af8..0000000000000000000000000000000000000000
--- a/randnum/randnum.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/**********************************************************************
-** This program is part of 'MOOSE', the
-** Messaging Object Oriented Simulation Environment,
-** copyright (C) 2003-2004 Upinder S. Bhalla. and NCBS
-** It is made available under the terms of the
-** GNU Lesser General Public License version 2.1
-** See the file COPYING.LIB for the full notice.
-** Development of this software was supported by
-** Biophase Simulations Inc, http://www.bpsims.com
-** See the file BIOPHASE.INFO for details.
-**********************************************************************/
-extern double mtrand(void);
-extern void mtseed(long seed);
-extern unsigned long genrand_int32(void);
-
diff --git a/randnum/test_normal_dist.cpp b/randnum/test_normal_dist.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..101a54546532a9e05f211aef054b94e601ea88ad
--- /dev/null
+++ b/randnum/test_normal_dist.cpp
@@ -0,0 +1,63 @@
+/***
+ * Filename: test_normal_dist.cpp
+ *
+ * Description: test script.
+ *
+ * Version: 0.0.1
+ * Created: 2018-08-04
+
+ * Revision: none
+ *
+ * Author: Dilawar Singh <dilawars@ncbs.res.in>
+ * Organization: NCBS Bangalore
+ *
+ * License: GNU GPL2
+ */
+
+
+#include <iostream>
+#include <map>
+#include <iomanip>
+
+#include "Distributions.h"
+#include "../utility/testing_macros.hpp"
+
+
+int test_normal_dist( )
+{
+
+ moose::MOOSE_RANDOM_DEVICE rd;
+ moose::MOOSE_RNG_DEFAULT_ENGINE gen;
+ gen.seed( 10 );
+
+ moose::MOOSE_NORMAL_DISTRIBUTION<double> d(0, 1);
+
+ std::map<int, int> hist{};
+ std::vector<double> dist;
+ for(int n=0; n<100000; ++n)
+ {
+ double x = d(gen);
+ dist.push_back( x );
+ ++hist[ std::round(x) ];
+ }
+
+ for(auto p : hist) {
+ std::cout << std::setw(2)
+ << p.first << ' ' << std::string(p.second/200, '*') << '\n';
+ }
+
+ ASSERT_DOUBLE_EQ( "NORMALDIST", hist[-3], 542 );
+ ASSERT_DOUBLE_EQ( "NORMALDIST", hist[-2], 5987 );
+ ASSERT_DOUBLE_EQ( "NORMALDIST", hist[-1], 24262 );
+ ASSERT_DOUBLE_EQ( "NORMALDIST", hist[0], 38236 );
+ ASSERT_DOUBLE_EQ( "NORMALDIST", hist[1], 24386 );
+ ASSERT_DOUBLE_EQ( "NORMALDIST", hist[2], 6071 );
+
+ return 0;
+}
+
+int main(int argc, const char *argv[])
+{
+ test_normal_dist();
+ return 0;
+}
diff --git a/scheduling/Clock.cpp b/scheduling/Clock.cpp
index dc45989f3a781825554bb42f8958fc98a251f3c1..aad5c0666fa608e09e53c7ce1de7e4b69a297354 100644
--- a/scheduling/Clock.cpp
+++ b/scheduling/Clock.cpp
@@ -30,25 +30,25 @@
*
* The system works like this:
* 1. Assign times to each Tick. This is divided by dt_ and the rounded
- * value is used for the integral multiple. Zero means the tick is not
- * scheduled.
+ * value is used for the integral multiple. Zero means the tick is not
+ * scheduled.
* 2. The process call goes through all active ticks in order every
- * timestep. Each Tick increments its counter and decides if it is
- * time to fire.
+ * timestep. Each Tick increments its counter and decides if it is
+ * time to fire.
* 4. The Reinit call goes through all active ticks in order, just once.
* 5. We connect up the Ticks to their target objects.
* 6. We begin the simulation by calling 'start' or 'step' on the Clock.
- * 'step' executes exactly one timestep (of the minimum dt_),
- * visiting all ticks as above..
- * 'start' executes an integral number of such timesteps.
+ * 'step' executes exactly one timestep (of the minimum dt_),
+ * visiting all ticks as above..
+ * 'start' executes an integral number of such timesteps.
* 7. To interrupt the simulation at some intermediate time, call 'stop'.
- * This lets the system complete its current step.
+ * This lets the system complete its current step.
* 8. To restart the simulation from where it left off, use the same
- * 'start' or 'step' function on the Clock. As all the ticks
- * retain their state, the simulation can resume smoothly.
+ * 'start' or 'step' function on the Clock. As all the ticks
+ * retain their state, the simulation can resume smoothly.
*/
-#include "header.h"
+#include "../basecode/header.h"
#include "Clock.h"
#include "../utility/numutil.h"
#include "../utility/print_function.hpp"
@@ -259,52 +259,52 @@ const Cinfo* Clock::initCinfo()
static Finfo* clockFinfos[] =
{
// Fields
- &dt, // Value
- &runTime, // ReadOnlyValue
- ¤tTime, // ReadOnlyValue
- &nsteps, // ReadOnlyValue
- &numTicks, // ReadOnlyValue
- &stride, // ReadOnlyValue
- ¤tStep, // ReadOnlyValue
- &dts, // ReadOnlyValue
- &isRunning, // ReadOnlyValue
- &tickStep, // LookupValue
- &tickDt, // LookupValue
- &defaultTick, // ReadOnlyLookupValue
- &clockControl, // Shared
- finished(), // Src
- procs[0], // Src
- procs[1], // Src
- procs[2], // Src
- procs[3], // Src
- procs[4], // Src
- procs[5], // Src
- procs[6], // Src
- procs[7], // Src
- procs[8], // Src
- procs[9], // Src
- procs[10], // Src
- procs[11], // Src
- procs[12], // Src
- procs[13], // Src
- procs[14], // Src
- procs[15], // Src
- procs[16], // Src
- procs[17], // Src
- procs[18], // Src
- procs[19], // Src
- procs[20], // Src
- procs[21], // Src
- procs[22], // Src
- procs[23], // Src
- procs[24], // Src
- procs[25], // Src
- procs[26], // Src
- procs[27], // Src
- procs[28], // Src
- procs[29], // Src
- procs[30], // Src
- procs[31], // Src
+ &dt, // Value
+ &runTime, // ReadOnlyValue
+ ¤tTime, // ReadOnlyValue
+ &nsteps, // ReadOnlyValue
+ &numTicks, // ReadOnlyValue
+ &stride, // ReadOnlyValue
+ ¤tStep, // ReadOnlyValue
+ &dts, // ReadOnlyValue
+ &isRunning, // ReadOnlyValue
+ &tickStep, // LookupValue
+ &tickDt, // LookupValue
+ &defaultTick, // ReadOnlyLookupValue
+ &clockControl, // Shared
+ finished(), // Src
+ procs[0], // Src
+ procs[1], // Src
+ procs[2], // Src
+ procs[3], // Src
+ procs[4], // Src
+ procs[5], // Src
+ procs[6], // Src
+ procs[7], // Src
+ procs[8], // Src
+ procs[9], // Src
+ procs[10], // Src
+ procs[11], // Src
+ procs[12], // Src
+ procs[13], // Src
+ procs[14], // Src
+ procs[15], // Src
+ procs[16], // Src
+ procs[17], // Src
+ procs[18], // Src
+ procs[19], // Src
+ procs[20], // Src
+ procs[21], // Src
+ procs[22], // Src
+ procs[23], // Src
+ procs[24], // Src
+ procs[25], // Src
+ procs[26], // Src
+ procs[27], // Src
+ procs[28], // Src
+ procs[29], // Src
+ procs[30], // Src
+ procs[31], // Src
};
static string doc[] =
@@ -360,79 +360,79 @@ const Cinfo* Clock::initCinfo()
" STDPSynHandler 1 50e-6\n"
" GraupnerBrunel2012CaPlasticitySynHandler 1 50e-6\n"
" SeqSynHandler 1 50e-6\n"
- " CaConc 1 50e-6\n"
- " CaConcBase 1 50e-6\n"
- " DifShell 1 50e-6\n"
- " DifShellBase 1 50e-6\n"
- " MMPump 1 50e-6\n"
- " DifBuffer 1 50e-6\n"
- " DifBufferBase 1 50e-6\n"
- " MgBlock 1 50e-6\n"
- " Nernst 1 50e-6\n"
- " RandSpike 1 50e-6\n"
- " ChanBase 2 50e-6\n"
- " IntFire 2 50e-6\n"
- " IntFireBase 2 50e-6\n"
- " LIF 2 50e-6\n"
- " QIF 2 50e-6\n"
- " ExIF 2 50e-6\n"
- " AdExIF 2 50e-6\n"
- " AdThreshIF 2 50e-6\n"
- " IzhIF 2 50e-6\n"
- " IzhikevichNrn 2 50e-6\n"
- " SynChan 2 50e-6\n"
- " NMDAChan 2 50e-6\n"
- " GapJunction 2 50e-6\n"
- " HHChannel 2 50e-6\n"
- " HHChannel2D 2 50e-6\n"
- " Leakage 2 50e-6\n"
- " MarkovChannel 2 50e-6\n"
- " MarkovGslSolver 2 50e-6\n"
- " MarkovRateTable 2 50e-6\n"
- " MarkovSolver 2 50e-6\n"
- " MarkovSolverBase 2 50e-6\n"
- " RC 2 50e-6\n"
- " Compartment (init) 3 50e-6\n"
- " CompartmentBase (init ) 3 50e-6\n"
- " SymCompartment (init) 3 50e-6\n"
- " Compartment 4 50e-6\n"
- " CompartmentBase 4 50e-6\n"
- " SymCompartment 4 50e-6\n"
- " SpikeGen 5 50e-6\n"
- " HSolve 6 50e-6\n"
- " SpikeStats 7 50e-6\n"
- " Table 8 0.1e-3\n"
- " TimeTable 8 0.1e-3\n"
-
- " Dsolve 10 0.01\n"
- " Adaptor 11 0.1\n"
- " Func 12 0.1\n"
- " Function 12 0.1\n"
- " Arith 12 0.1\n"
- " BufPool 13 0.1\n"
- " Pool 13 0.1\n"
- " PoolBase 13 0.1\n"
- " CplxEnzBase 14 0.1\n"
- " Enz 14 0.1\n"
- " EnzBase 14 0.1\n"
- " MMenz 14 0.1\n"
- " Reac 14 0.1\n"
- " ReacBase 14 0.1\n"
- " Gsolve (init) 15 0.1\n"
- " Ksolve (init) 15 0.1\n"
- " Gsolve 16 0.1\n"
- " Ksolve 16 0.1\n"
- " Stats 17 0.1\n"
- " Table2 18 1\n"
- " Streamer 19 10\n"
-
- " HDF5DataWriter 30 1\n"
- " HDF5WriterBase 30 1\n"
- " NSDFWriter 30 1\n"
- " PyRun 30 1\n"
- " PostMaster 31 0.01\n"
- " \n"
- " Note that the other classes are not scheduled at all.",
+ " CaConc 1 50e-6\n"
+ " CaConcBase 1 50e-6\n"
+ " DifShell 1 50e-6\n"
+ " DifShellBase 1 50e-6\n"
+ " MMPump 1 50e-6\n"
+ " DifBuffer 1 50e-6\n"
+ " DifBufferBase 1 50e-6\n"
+ " MgBlock 1 50e-6\n"
+ " Nernst 1 50e-6\n"
+ " RandSpike 1 50e-6\n"
+ " ChanBase 2 50e-6\n"
+ " IntFire 2 50e-6\n"
+ " IntFireBase 2 50e-6\n"
+ " LIF 2 50e-6\n"
+ " QIF 2 50e-6\n"
+ " ExIF 2 50e-6\n"
+ " AdExIF 2 50e-6\n"
+ " AdThreshIF 2 50e-6\n"
+ " IzhIF 2 50e-6\n"
+ " IzhikevichNrn 2 50e-6\n"
+ " SynChan 2 50e-6\n"
+ " NMDAChan 2 50e-6\n"
+ " GapJunction 2 50e-6\n"
+ " HHChannel 2 50e-6\n"
+ " HHChannel2D 2 50e-6\n"
+ " Leakage 2 50e-6\n"
+ " MarkovChannel 2 50e-6\n"
+ " MarkovGslSolver 2 50e-6\n"
+ " MarkovRateTable 2 50e-6\n"
+ " MarkovSolver 2 50e-6\n"
+ " MarkovSolverBase 2 50e-6\n"
+ " RC 2 50e-6\n"
+ " Compartment (init) 3 50e-6\n"
+ " CompartmentBase (init ) 3 50e-6\n"
+ " SymCompartment (init) 3 50e-6\n"
+ " Compartment 4 50e-6\n"
+ " CompartmentBase 4 50e-6\n"
+ " SymCompartment 4 50e-6\n"
+ " SpikeGen 5 50e-6\n"
+ " HSolve 6 50e-6\n"
+ " SpikeStats 7 50e-6\n"
+ " Table 8 0.1e-3\n"
+ " TimeTable 8 0.1e-3\n"
+
+ " Dsolve 10 0.01\n"
+ " Adaptor 11 0.1\n"
+ " Func 12 0.1\n"
+ " Function 12 0.1\n"
+ " Arith 12 0.1\n"
+ " BufPool 13 0.1\n"
+ " Pool 13 0.1\n"
+ " PoolBase 13 0.1\n"
+ " CplxEnzBase 14 0.1\n"
+ " Enz 14 0.1\n"
+ " EnzBase 14 0.1\n"
+ " MMenz 14 0.1\n"
+ " Reac 14 0.1\n"
+ " ReacBase 14 0.1\n"
+ " Gsolve (init) 15 0.1\n"
+ " Ksolve (init) 15 0.1\n"
+ " Gsolve 16 0.1\n"
+ " Ksolve 16 0.1\n"
+ " Stats 17 0.1\n"
+ " Table2 18 1\n"
+ " Streamer 19 10\n"
+
+ " HDF5DataWriter 30 1\n"
+ " HDF5WriterBase 30 1\n"
+ " NSDFWriter 30 1\n"
+ " PyRun 30 1\n"
+ " PostMaster 31 0.01\n"
+ " \n"
+ " Note that the other classes are not scheduled at all.",
};
static Dinfo< Clock > dinfo;
@@ -662,7 +662,7 @@ void Clock::innerReportClock() const
cout << "Dts= ";
for ( unsigned int i = 0; i < ticks_.size(); ++i )
{
- cout << "tick[" << i << "] = " << ticks_[i] << " " <<
+ cout << "tick[" << i << "] = " << ticks_[i] << " " <<
ticks_[i] * dt_ << endl;
}
cout << endl;
@@ -834,24 +834,24 @@ void Clock::handleReinit( const Eref& e )
* Useful function, only I don't need it yet. Was implemented for Dsolve
double Dsolve::findDt( const Eref& e )
{
- // Here is the horrible stuff to traverse the message to get the dt.
- const Finfo* f = Dsolve::initCinfo()->findFinfo( "reinit" );
- const DestFinfo* df = dynamic_cast< const DestFinfo* >( f );
- assert( df );
- unsigned int fid = df->getFid();
- ObjId caller = e.element()->findCaller( fid );
- const Msg* m = Msg::getMsg( caller );
- assert( m );
- vector< string > src = m->getSrcFieldsOnE1();
- assert( src.size() > 0 );
- string temp = src[0].substr( src[0].length() - 1 ); // reinitxx
- unsigned int tick = atoi( temp.c_str() );
- assert( tick < 10 );
- Id clock( 1 );
- assert( clock.element() == m->e1() );
- double dt = LookupField< unsigned int, double >::
- get( clock, "tickDt", tick );
- return dt;
+ // Here is the horrible stuff to traverse the message to get the dt.
+ const Finfo* f = Dsolve::initCinfo()->findFinfo( "reinit" );
+ const DestFinfo* df = dynamic_cast< const DestFinfo* >( f );
+ assert( df );
+ unsigned int fid = df->getFid();
+ ObjId caller = e.element()->findCaller( fid );
+ const Msg* m = Msg::getMsg( caller );
+ assert( m );
+ vector< string > src = m->getSrcFieldsOnE1();
+ assert( src.size() > 0 );
+ string temp = src[0].substr( src[0].length() - 1 ); // reinitxx
+ unsigned int tick = atoi( temp.c_str() );
+ assert( tick < 10 );
+ Id clock( 1 );
+ assert( clock.element() == m->e1() );
+ double dt = LookupField< unsigned int, double >::
+ get( clock, "tickDt", tick );
+ return dt;
}
*/
@@ -1027,7 +1027,7 @@ void Clock::buildDefaultTick()
defaultDt_[19] = 10; // For Streamer
// 20-29 are not assigned.
- defaultDt_[30] = 1; // For the HDF writer
+ defaultDt_[30] = 1; // For the HDF writer
defaultDt_[31] = 0.01; // For the postmaster.
}
diff --git a/shell/Shell.cpp b/shell/Shell.cpp
index e29b318ace7b31b0c439a6c1f18cdf0c1cea282d..775092c634f768c95caa2021c11a878338491720 100644
--- a/shell/Shell.cpp
+++ b/shell/Shell.cpp
@@ -341,7 +341,7 @@ void Shell::doStart( double runtime, bool notify )
*-----------------------------------------------------------------------------*/
vector< ObjId > streamers;
wildcardFind( "/##[TYPE=Streamer]", streamers );
- LOG( moose::debug, "total streamers " << streamers.size( ) );
+ // LOG( moose::debug, "total streamers " << streamers.size( ) );
for( vector<ObjId>::const_iterator itr = streamers.begin()
; itr != streamers.end(); itr++ )
{
diff --git a/synapse/GraupnerBrunel2012CaPlasticitySynHandler.cpp b/synapse/GraupnerBrunel2012CaPlasticitySynHandler.cpp
index 835dc72b7d31f24c95d585567dee6439a33eb3c2..7f78996d341b5d9a800efb90e23b0f0443deed0c 100644
--- a/synapse/GraupnerBrunel2012CaPlasticitySynHandler.cpp
+++ b/synapse/GraupnerBrunel2012CaPlasticitySynHandler.cpp
@@ -7,22 +7,22 @@
** See the file COPYING.LIB for the full notice.
**********************************************************************/
-#include <queue>
-#include "header.h"
+#include "../basecode/header.h"
#include "Synapse.h"
#include "SynEvent.h" // only using the SynEvent class from this
#include "SynHandlerBase.h"
-#include "../randnum/Normal.h" // generate normal randum numbers for noisy weight update
#include "GraupnerBrunel2012CaPlasticitySynHandler.h"
+#include <queue>
+
const Cinfo* GraupnerBrunel2012CaPlasticitySynHandler::initCinfo()
{
- static string doc[] =
- {
- "Name", "GraupnerBrunel2012CaPlasticitySynHandler",
- "Author", "Aditya Gilra",
- "Description",
- "The GraupnerBrunel2012CaPlasticitySynHandler handles synapses"
+ static string doc[] =
+ {
+ "Name", "GraupnerBrunel2012CaPlasticitySynHandler",
+ "Author", "Aditya Gilra",
+ "Description",
+ "The GraupnerBrunel2012CaPlasticitySynHandler handles synapses"
"with Ca-based plasticity as per Higgins et al. 2014 and Graupner and Brunel 2012."
"Note 1:"
" Here, Ca ('chemical Ca') is updated only at each pre-spike, pre-spike+delayD and post-spike!"
@@ -43,8 +43,8 @@ const Cinfo* GraupnerBrunel2012CaPlasticitySynHandler::initCinfo()
" in its own electrical compartment (=spine),"
" only then can you have an 'electrical Ca'"
" corresponding to the 'chemical Ca'."
- "Three priority queues are used to manage pre, post, and pre+delayD spikes."
- };
+ "Three priority queues are used to manage pre, post, and pre+delayD spikes."
+ };
static ValueFinfo< GraupnerBrunel2012CaPlasticitySynHandler, double > Ca(
"Ca",
@@ -54,81 +54,81 @@ const Cinfo* GraupnerBrunel2012CaPlasticitySynHandler::initCinfo()
"when a pre- or post- spike has occured, or at time delayD after a pre-spike."
"Do not use it to control a Ca dependent current, etc."
"See notes in the class Description: all pre-synapses get updated via the same post-synaptic Ca.",
- &GraupnerBrunel2012CaPlasticitySynHandler::setCa,
- &GraupnerBrunel2012CaPlasticitySynHandler::getCa
+ &GraupnerBrunel2012CaPlasticitySynHandler::setCa,
+ &GraupnerBrunel2012CaPlasticitySynHandler::getCa
);
static ValueFinfo< GraupnerBrunel2012CaPlasticitySynHandler, double > CaInit(
"CaInit",
"CaInit is the initial value for Ca",
- &GraupnerBrunel2012CaPlasticitySynHandler::setCaInit,
- &GraupnerBrunel2012CaPlasticitySynHandler::getCaInit
+ &GraupnerBrunel2012CaPlasticitySynHandler::setCaInit,
+ &GraupnerBrunel2012CaPlasticitySynHandler::getCaInit
);
static ValueFinfo< GraupnerBrunel2012CaPlasticitySynHandler, double > tauCa(
"tauCa",
"tauCa is the time constant for decay of Ca",
- &GraupnerBrunel2012CaPlasticitySynHandler::setTauCa,
- &GraupnerBrunel2012CaPlasticitySynHandler::getTauCa
+ &GraupnerBrunel2012CaPlasticitySynHandler::setTauCa,
+ &GraupnerBrunel2012CaPlasticitySynHandler::getTauCa
);
static ValueFinfo< GraupnerBrunel2012CaPlasticitySynHandler, double > tauSyn(
"tauSyn",
"tauSyn is the time constant for synaptic weight evolution equation",
- &GraupnerBrunel2012CaPlasticitySynHandler::setTauSyn,
- &GraupnerBrunel2012CaPlasticitySynHandler::getTauSyn
+ &GraupnerBrunel2012CaPlasticitySynHandler::setTauSyn,
+ &GraupnerBrunel2012CaPlasticitySynHandler::getTauSyn
);
static ValueFinfo< GraupnerBrunel2012CaPlasticitySynHandler, double > CaPre(
"CaPre",
"CaPre is added to Ca on every pre-spike",
- &GraupnerBrunel2012CaPlasticitySynHandler::setCaPre,
- &GraupnerBrunel2012CaPlasticitySynHandler::getCaPre
+ &GraupnerBrunel2012CaPlasticitySynHandler::setCaPre,
+ &GraupnerBrunel2012CaPlasticitySynHandler::getCaPre
);
static ValueFinfo< GraupnerBrunel2012CaPlasticitySynHandler, double > CaPost(
"CaPost",
"CaPost is added to Ca on every post-spike",
- &GraupnerBrunel2012CaPlasticitySynHandler::setCaPost,
- &GraupnerBrunel2012CaPlasticitySynHandler::getCaPost
+ &GraupnerBrunel2012CaPlasticitySynHandler::setCaPost,
+ &GraupnerBrunel2012CaPlasticitySynHandler::getCaPost
);
static ValueFinfo< GraupnerBrunel2012CaPlasticitySynHandler, double > delayD(
"delayD",
"Time delay D after pre-spike, when Ca is increased by Capre."
" delayD represents NMDA rise time.",
- &GraupnerBrunel2012CaPlasticitySynHandler::setDelayD,
- &GraupnerBrunel2012CaPlasticitySynHandler::getDelayD
+ &GraupnerBrunel2012CaPlasticitySynHandler::setDelayD,
+ &GraupnerBrunel2012CaPlasticitySynHandler::getDelayD
);
static ValueFinfo< GraupnerBrunel2012CaPlasticitySynHandler, double > gammaP(
"gammaP",
"gammaP is the potentiation factor for synaptic weight increase if Ca>thetaP",
- &GraupnerBrunel2012CaPlasticitySynHandler::setGammaP,
- &GraupnerBrunel2012CaPlasticitySynHandler::getGammaP
+ &GraupnerBrunel2012CaPlasticitySynHandler::setGammaP,
+ &GraupnerBrunel2012CaPlasticitySynHandler::getGammaP
);
static ValueFinfo< GraupnerBrunel2012CaPlasticitySynHandler, double > gammaD(
"gammaD",
"gammaD is the depression factor for synaptic weight decrease if Ca>thetaD",
- &GraupnerBrunel2012CaPlasticitySynHandler::setGammaD,
- &GraupnerBrunel2012CaPlasticitySynHandler::getGammaD
+ &GraupnerBrunel2012CaPlasticitySynHandler::setGammaD,
+ &GraupnerBrunel2012CaPlasticitySynHandler::getGammaD
);
static ValueFinfo< GraupnerBrunel2012CaPlasticitySynHandler, double > thetaP(
"thetaP",
"Potentiation threshold for Ca"
"User must ensure thetaP>thetaD, else simulation results will be wrong.",
- &GraupnerBrunel2012CaPlasticitySynHandler::setThetaP,
- &GraupnerBrunel2012CaPlasticitySynHandler::getThetaP
+ &GraupnerBrunel2012CaPlasticitySynHandler::setThetaP,
+ &GraupnerBrunel2012CaPlasticitySynHandler::getThetaP
);
static ValueFinfo< GraupnerBrunel2012CaPlasticitySynHandler, double > thetaD(
"thetaD",
"Depression threshold for Ca"
"User must ensure thetaP>thetaD, else simulation results will be wrong.",
- &GraupnerBrunel2012CaPlasticitySynHandler::setThetaD,
- &GraupnerBrunel2012CaPlasticitySynHandler::getThetaD
+ &GraupnerBrunel2012CaPlasticitySynHandler::setThetaD,
+ &GraupnerBrunel2012CaPlasticitySynHandler::getThetaD
);
static ValueFinfo< GraupnerBrunel2012CaPlasticitySynHandler, bool > bistable(
@@ -136,36 +136,36 @@ const Cinfo* GraupnerBrunel2012CaPlasticitySynHandler::initCinfo()
"If true, the synapse is bistable as in GraupnerBrunel2012 paper."
"The effect of potential on the weight update is usually ignorable"
" if Ca is above thetaP and thetaD most of the time.",
- &GraupnerBrunel2012CaPlasticitySynHandler::setBistable,
- &GraupnerBrunel2012CaPlasticitySynHandler::getBistable
+ &GraupnerBrunel2012CaPlasticitySynHandler::setBistable,
+ &GraupnerBrunel2012CaPlasticitySynHandler::getBistable
);
static ValueFinfo< GraupnerBrunel2012CaPlasticitySynHandler, bool > noisy(
"noisy",
"If true, turn noise on as per noiseSD",
- &GraupnerBrunel2012CaPlasticitySynHandler::setNoisy,
- &GraupnerBrunel2012CaPlasticitySynHandler::getNoisy
+ &GraupnerBrunel2012CaPlasticitySynHandler::setNoisy,
+ &GraupnerBrunel2012CaPlasticitySynHandler::getNoisy
);
static ValueFinfo< GraupnerBrunel2012CaPlasticitySynHandler, double > noiseSD(
"noiseSD",
"Standard deviation of noise added to Ca",
- &GraupnerBrunel2012CaPlasticitySynHandler::setNoiseSD,
- &GraupnerBrunel2012CaPlasticitySynHandler::getNoiseSD
+ &GraupnerBrunel2012CaPlasticitySynHandler::setNoiseSD,
+ &GraupnerBrunel2012CaPlasticitySynHandler::getNoiseSD
);
static ValueFinfo< GraupnerBrunel2012CaPlasticitySynHandler, double > weightMax(
"weightMax",
"An upper bound on the weight",
- &GraupnerBrunel2012CaPlasticitySynHandler::setWeightMax,
- &GraupnerBrunel2012CaPlasticitySynHandler::getWeightMax
+ &GraupnerBrunel2012CaPlasticitySynHandler::setWeightMax,
+ &GraupnerBrunel2012CaPlasticitySynHandler::getWeightMax
);
static ValueFinfo< GraupnerBrunel2012CaPlasticitySynHandler, double > weightMin(
"weightMin",
"A lower bound on the weight",
- &GraupnerBrunel2012CaPlasticitySynHandler::setWeightMin,
- &GraupnerBrunel2012CaPlasticitySynHandler::getWeightMin
+ &GraupnerBrunel2012CaPlasticitySynHandler::setWeightMin,
+ &GraupnerBrunel2012CaPlasticitySynHandler::getWeightMin
);
static ValueFinfo< GraupnerBrunel2012CaPlasticitySynHandler, double > weightScale(
@@ -173,237 +173,281 @@ const Cinfo* GraupnerBrunel2012CaPlasticitySynHandler::initCinfo()
"Scale all pre-synaptic weights by weightScale before adding to activation (default 1.0)"
"In the terminology of the paper Higgins et al 2012, weight is synaptic efficacy,"
"while weightScale*weight is what finally is added to activation variable.",
- &GraupnerBrunel2012CaPlasticitySynHandler::setWeightScale,
- &GraupnerBrunel2012CaPlasticitySynHandler::getWeightScale
+ &GraupnerBrunel2012CaPlasticitySynHandler::setWeightScale,
+ &GraupnerBrunel2012CaPlasticitySynHandler::getWeightScale
);
- static DestFinfo addPostSpike( "addPostSpike",
+ static DestFinfo addPostSpike(
+ "addPostSpike",
"Handles arriving spike messages from post-synaptic neuron, inserts into postEvent queue.",
new EpFunc1< GraupnerBrunel2012CaPlasticitySynHandler, \
- double >( &GraupnerBrunel2012CaPlasticitySynHandler::addPostSpike ) );
-
- static FieldElementFinfo< SynHandlerBase, Synapse > synFinfo(
- "synapse",
- "Sets up field Elements for synapse",
- Synapse::initCinfo(),
- &SynHandlerBase::getSynapse,
- &SynHandlerBase::setNumSynapses,
- &SynHandlerBase::getNumSynapses
- );
-
- static Finfo* GraupnerBrunel2012CaPlasticitySynHandlerFinfos[] = {
- &synFinfo, // FieldElement
- &addPostSpike, // DestFinfo
- &Ca, // Field
- &CaInit, // Field
- &tauCa, // Field
- &tauSyn, // Field
- &CaPre, // Field
- &CaPost, // Field
- &delayD, // Field
- &thetaP, // Field
- &thetaD, // Field
- &gammaP, // Field
- &gammaD, // Field
- &weightMax, // Field
- &weightMin, // Field
- &weightScale, // Field
- &noisy, // Field
- &noiseSD, // Field
- &bistable // Field
- };
-
- static Dinfo< GraupnerBrunel2012CaPlasticitySynHandler > dinfo;
- static Cinfo synHandlerCinfo (
- "GraupnerBrunel2012CaPlasticitySynHandler",
- SynHandlerBase::initCinfo(),
- GraupnerBrunel2012CaPlasticitySynHandlerFinfos,
- sizeof( GraupnerBrunel2012CaPlasticitySynHandlerFinfos ) / sizeof ( Finfo* ),
- &dinfo,
- doc,
- sizeof( doc ) / sizeof( string )
- );
-
- return &synHandlerCinfo;
+ double >( &GraupnerBrunel2012CaPlasticitySynHandler::addPostSpike ) );
+
+ static FieldElementFinfo< SynHandlerBase, Synapse > synFinfo(
+ "synapse",
+ "Sets up field Elements for synapse",
+ Synapse::initCinfo(),
+ &SynHandlerBase::getSynapse,
+ &SynHandlerBase::setNumSynapses,
+ &SynHandlerBase::getNumSynapses
+ );
+
+ static Finfo* GraupnerBrunel2012CaPlasticitySynHandlerFinfos[] =
+ {
+ &synFinfo, // FieldElement
+ &addPostSpike, // DestFinfo
+ &Ca, // Field
+ &CaInit, // Field
+ &tauCa, // Field
+ &tauSyn, // Field
+ &CaPre, // Field
+ &CaPost, // Field
+ &delayD, // Field
+ &thetaP, // Field
+ &thetaD, // Field
+ &gammaP, // Field
+ &gammaD, // Field
+ &weightMax, // Field
+ &weightMin, // Field
+ &weightScale, // Field
+ &noisy, // Field
+ &noiseSD, // Field
+ &bistable // Field
+ };
+
+ static Dinfo< GraupnerBrunel2012CaPlasticitySynHandler > dinfo;
+ static Cinfo synHandlerCinfo (
+ "GraupnerBrunel2012CaPlasticitySynHandler",
+ SynHandlerBase::initCinfo(),
+ GraupnerBrunel2012CaPlasticitySynHandlerFinfos,
+ sizeof( GraupnerBrunel2012CaPlasticitySynHandlerFinfos ) / sizeof ( Finfo* ),
+ &dinfo,
+ doc,
+ sizeof( doc ) / sizeof( string )
+ );
+
+ return &synHandlerCinfo;
}
static const Cinfo* GraupnerBrunel2012CaPlasticitySynHandlerCinfo =\
- GraupnerBrunel2012CaPlasticitySynHandler::initCinfo();
+ GraupnerBrunel2012CaPlasticitySynHandler::initCinfo();
GraupnerBrunel2012CaPlasticitySynHandler::GraupnerBrunel2012CaPlasticitySynHandler()
{
- Ca_ = 0.0;
- CaInit_ = 0.0;
- tauCa_ = 1.0;
- tauSyn_ = 1.0;
- CaPre_ = 0.0;
- CaPost_ = 0.0;
- thetaD_ = 0.0;
- thetaP_ = 0.0;
- gammaD_ = 0.0;
- gammaP_ = 0.0;
- delayD_ = 0.0;
- weightMin_ = 0.0;
- weightMax_ = 0.0;
+ Ca_ = 0.0;
+ CaInit_ = 0.0;
+ tauCa_ = 1.0;
+ tauSyn_ = 1.0;
+ CaPre_ = 0.0;
+ CaPost_ = 0.0;
+ thetaD_ = 0.0;
+ thetaP_ = 0.0;
+ gammaD_ = 0.0;
+ gammaP_ = 0.0;
+ delayD_ = 0.0;
+ weightMin_ = 0.0;
+ weightMax_ = 0.0;
weightScale_ = 1.0;
- noisy_ = false;
- noiseSD_ = 0.0;
- bistable_ = true;
- normalGenerator_.setMethod(BOX_MUELLER); // the default ALIAS method is 1000x slower!
+ noisy_ = false;
+ noiseSD_ = 0.0;
+ bistable_ = true;
+ seed_ = 0;
+ dist_ = moose::MOOSE_NORMAL_DISTRIBUTION<double>{0, 1};
+ reinitSeed();
+
+ // std::cout << " Mean " << dist_.mean() << " std " << dist_.stddev() << std::endl;
}
GraupnerBrunel2012CaPlasticitySynHandler::~GraupnerBrunel2012CaPlasticitySynHandler()
-{ ; }
+{
+}
+
+void GraupnerBrunel2012CaPlasticitySynHandler::reinitSeed( void )
+{
+ if( 0 == seed_ )
+ seed_ = moose::getGlobalSeed();
+
+ if( 0 == seed_ )
+ seed_ = rd_();
+
+ MOOSE_DEBUG( "Seed is set to " << seed_ );
+ rng_.seed( seed_ );
+}
-GraupnerBrunel2012CaPlasticitySynHandler& GraupnerBrunel2012CaPlasticitySynHandler::operator=\
- ( const GraupnerBrunel2012CaPlasticitySynHandler& ssh)
+GraupnerBrunel2012CaPlasticitySynHandler&
+ GraupnerBrunel2012CaPlasticitySynHandler::operator=(
+ const GraupnerBrunel2012CaPlasticitySynHandler& ssh
+ )
{
- synapses_ = ssh.synapses_;
- for ( vector< Synapse >::iterator
- i = synapses_.begin(); i != synapses_.end(); ++i )
- i->setHandler( this );
+ synapses_ = ssh.synapses_;
+ for ( vector< Synapse >::iterator
+ i = synapses_.begin(); i != synapses_.end(); ++i )
+ i->setHandler( this );
- // For no apparent reason, priority queues don't have a clear operation.
- while( !events_.empty() )
- events_.pop();
- while( !delayDPreEvents_.empty() )
- events_.pop();
- while( !postEvents_.empty() )
- postEvents_.pop();
+ // For no apparent reason, priority queues don't have a clear operation.
+ while( !events_.empty() )
+ events_.pop();
+ while( !delayDPreEvents_.empty() )
+ events_.pop();
+ while( !postEvents_.empty() )
+ postEvents_.pop();
- return *this;
+ return *this;
}
void GraupnerBrunel2012CaPlasticitySynHandler::vSetNumSynapses( const unsigned int v )
{
- unsigned int prevSize = synapses_.size();
- synapses_.resize( v );
- for ( unsigned int i = prevSize; i < v; ++i )
- synapses_[i].setHandler( this );
+ unsigned int prevSize = synapses_.size();
+ synapses_.resize( v );
+ for ( unsigned int i = prevSize; i < v; ++i )
+ synapses_[i].setHandler( this );
}
unsigned int GraupnerBrunel2012CaPlasticitySynHandler::vGetNumSynapses() const
{
- return synapses_.size();
+ return synapses_.size();
}
Synapse* GraupnerBrunel2012CaPlasticitySynHandler::vGetSynapse( unsigned int i )
{
- static Synapse dummy;
- if ( i < synapses_.size() )
- return &synapses_[i];
- cout << "Warning: GraupnerBrunel2012CaPlasticitySynHandler::getSynapse: index: " << i <<
- " is out of range: " << synapses_.size() << endl;
- return &dummy;
+ static Synapse dummy;
+ if ( i < synapses_.size() )
+ return &synapses_[i];
+ cout << "Warning: GraupnerBrunel2012CaPlasticitySynHandler::getSynapse: index: " << i <<
+ " is out of range: " << synapses_.size() << endl;
+ return &dummy;
}
void GraupnerBrunel2012CaPlasticitySynHandler::addSpike(
- unsigned int index, double time, double weight )
+ unsigned int index, double time, double weight )
{
- assert( index < synapses_.size() );
- events_.push( PreSynEvent( index, time, weight ) );
- delayDPreEvents_.push( PreSynEvent( index, time+delayD_, weight ) );
+ assert( index < synapses_.size() );
+ events_.push( PreSynEvent( index, time, weight ) );
+ delayDPreEvents_.push( PreSynEvent( index, time+delayD_, weight ) );
}
-double GraupnerBrunel2012CaPlasticitySynHandler::getTopSpike(
- unsigned int index ) const
+double GraupnerBrunel2012CaPlasticitySynHandler::getTopSpike(
+ unsigned int index ) const
{
- if ( events_.empty() )
- return 0.0;
- return events_.top().time;
+ if ( events_.empty() )
+ return 0.0;
+ return events_.top().time;
}
void GraupnerBrunel2012CaPlasticitySynHandler::addPostSpike( const Eref& e, double time )
{
- postEvents_.push( PostSynEvent( time ) );
+ postEvents_.push( PostSynEvent( time ) );
}
weightFactors GraupnerBrunel2012CaPlasticitySynHandler::updateCaWeightFactors( double currTime )
{
- double CaOld = Ca_;
- double deltaT = currTime-lastCaUpdateTime_;
- // Update Ca, but CaPre and CaPost are added in vProcess()
- Ca_ *= exp(-deltaT/tauCa_);
- lastCaUpdateTime_ = currTime;
- weightFactors wUp; // by default all are set to 0.0
-
- // calculate/approximate time spent above potentiation and depression thresholds
- // see pg 13 of Higgins et al | October 2014 | Volume 10 | Issue 10 | e1003834 | PLOS Comp Biol
- // starting from bottom condition, going upwards in the algorithm given in above paper
- if (CaOld <= thetaD_) {
- } else if (CaOld <= thetaP_) {
- //cout << "tD<Caold<tP" << "\n";
- if (Ca_ <= thetaD_) {
- wUp.tD = tauCa_*log(CaOld/thetaD_);
- //cout << "Ca<tD" << "\n";
- } else {
- wUp.tD = deltaT;
- //cout << "Ca>tD" << "\n";
- }
- } else {
- //cout << "Caold>tP" << "\n";
- if (Ca_ <= thetaD_) {
- wUp.tP = tauCa_*log(CaOld/thetaP_);
- wUp.tD = tauCa_*log(thetaP_/thetaD_);
- //cout << "Ca<tD" << "\n";
- //cout << "Caold = " << CaOld << "thetaP = " << thetaP_ << "\n";
- } else if (Ca_ <= thetaP_) {
- wUp.tP = tauCa_*log(CaOld/thetaP_);
- wUp.tD = deltaT - wUp.tP;
- //cout << "Ca<tP" << "\n";
- } else {
- wUp.tP = deltaT;
- //cout << "Ca>tP" << "\n";
- }
+ double CaOld = Ca_;
+ double deltaT = currTime-lastCaUpdateTime_;
+ // Update Ca, but CaPre and CaPost are added in vProcess()
+ Ca_ *= exp(-deltaT/tauCa_);
+ lastCaUpdateTime_ = currTime;
+ weightFactors wUp; // by default all are set to 0.0
+
+ // calculate/approximate time spent above potentiation and depression thresholds
+ // see pg 13 of Higgins et al | October 2014 | Volume 10 | Issue 10 | e1003834 | PLOS Comp Biol
+ // starting from bottom condition, going upwards in the algorithm given in above paper
+ if (CaOld <= thetaD_)
+ {
+ }
+ else if (CaOld <= thetaP_)
+ {
+ //cout << "tD<Caold<tP" << "\n";
+ if (Ca_ <= thetaD_)
+ {
+ wUp.tD = tauCa_*log(CaOld/thetaD_);
+ //cout << "Ca<tD" << "\n";
+ }
+ else
+ {
+ wUp.tD = deltaT;
+ //cout << "Ca>tD" << "\n";
+ }
+ }
+ else
+ {
+ //cout << "Caold>tP" << "\n";
+ if (Ca_ <= thetaD_)
+ {
+ wUp.tP = tauCa_*log(CaOld/thetaP_);
+ wUp.tD = tauCa_*log(thetaP_/thetaD_);
+ //cout << "Ca<tD" << "\n";
+ //cout << "Caold = " << CaOld << "thetaP = " << thetaP_ << "\n";
+ }
+ else if (Ca_ <= thetaP_)
+ {
+ wUp.tP = tauCa_*log(CaOld/thetaP_);
+ wUp.tD = deltaT - wUp.tP;
+ //cout << "Ca<tP" << "\n";
+ }
+ else
+ {
+ wUp.tP = deltaT;
+ //cout << "Ca>tP" << "\n";
+ }
+ }
+ wUp.t0 = deltaT - wUp.tP - wUp.tD;
+
+ // Depending on tP and tD, I return A,B,C factors for weight update
+ // (see page 13 of Higgins et al 2014).
+ // A,B,C,D,E are used to compute the weight change for one or multiple synapses
+ // A is weight independent, B,D are weight dependent and C,E are accumulated noise
+ if (wUp.tP > 0)
+ {
+ double gPgD = gammaP_+gammaD_;
+ wUp.A = gammaP_/gPgD*(1.0-exp(-wUp.tP*gPgD/tauSyn_));
+ wUp.B = exp(-wUp.tP*gPgD/tauSyn_);
+ if (noisy_)
+ {
+ wUp.C = noiseSD_ * dist_(rng_) *
+ sqrt( ( 1.0-exp(-2*gPgD*wUp.tP/tauSyn_) ) / gPgD );
+ // cout << " A = " << wUp.A << " B = " << wUp.B << " C = " << wUp.C << "\n";
}
- wUp.t0 = deltaT - wUp.tP - wUp.tD;
-
- // Depending on tP and tD, I return A,B,C factors for weight update
- // (see page 13 of Higgins et al 2014).
- // A,B,C,D,E are used to compute the weight change for one or multiple synapses
- // A is weight independent, B,D are weight dependent and C,E are accumulated noise
- if (wUp.tP > 0) {
- double gPgD = gammaP_+gammaD_;
- wUp.A = gammaP_/gPgD*(1.0-exp(-wUp.tP*gPgD/tauSyn_));
- wUp.B = exp(-wUp.tP*gPgD/tauSyn_);
- if (noisy_) {
- wUp.C = noiseSD_ * normalGenerator_.getNextSample() *
- sqrt( ( 1.0-exp(-2*gPgD*wUp.tP/tauSyn_) ) / gPgD );
- //cout << "A = " << wUp.A << " B = " << wUp.B << " C = " << wUp.C << "\n";
- } else {
- wUp.C = 0.0;
- }
+ else
+ {
+ wUp.C = 0.0;
}
+ }
- if (wUp.tD > 0) {
- wUp.D = exp(-wUp.tD*gammaD_/tauSyn_);
- if (noisy_) {
- wUp.E = noiseSD_ * normalGenerator_.getNextSample() *
- sqrt( ( 1.0-exp(-2*gammaD_*wUp.tD/tauSyn_) ) / 2.0/gammaD_ );
- //cout << "D = " << wUp.D << " E = " << wUp.E << "\n";
- } else{
- wUp.E = 0.0;
- }
+ if (wUp.tD > 0)
+ {
+ wUp.D = exp(-wUp.tD*gammaD_/tauSyn_);
+ if (noisy_)
+ {
+ wUp.E = noiseSD_ * dist_( rng_ ) *
+ sqrt( ( 1.0-exp(-2*gammaD_*wUp.tD/tauSyn_) ) / 2.0/gammaD_ );
+ //cout << "D = " << wUp.D << " E = " << wUp.E << "\n";
+ }
+ else
+ {
+ wUp.E = 0.0;
}
+ }
- //cout << currTime << " tD = " << wUp.tD << " tP = " << wUp.tP << "\n";
- // tP, tD, A, B, C, D, E of wUp
- // are set to 0.0 by default in struct constructor
- return wUp; // return by value, i.e. copies the struct, so wUp going out of scope doesn't matter
- // malloc and returning pointer is more expensive for small structs
- // see: http://stackoverflow.com/questions/9590827/is-it-safe-to-return-a-struct-in-c-c
+ //cout << currTime << " tD = " << wUp.tD << " tP = " << wUp.tP << "\n";
+ // tP, tD, A, B, C, D, E of wUp
+ // are set to 0.0 by default in struct constructor
+ return wUp; // return by value, i.e. copies the struct, so wUp going out of scope doesn't matter
+ // malloc and returning pointer is more expensive for small structs
+ // see: http://stackoverflow.com/questions/9590827/is-it-safe-to-return-a-struct-in-c-c
}
void GraupnerBrunel2012CaPlasticitySynHandler::updateWeight( Synapse* synPtr, weightFactors *wFacPtr )
{
double newWeight = synPtr->getWeight();
//cout << " oldweight = " << newWeight << "\n";
- if (wFacPtr->tP > 0.0) {
+ if (wFacPtr->tP > 0.0)
+ {
newWeight = wFacPtr->A + wFacPtr->B*newWeight + wFacPtr->C;
//cout << " midweight = " << newWeight << "\n";
}
- if (wFacPtr->tD > 0.0) {
+ if (wFacPtr->tD > 0.0)
+ {
newWeight = wFacPtr->D*newWeight + wFacPtr->E; // update the weight again
//cout << " newweight = " << newWeight << "\n";
}
@@ -411,12 +455,16 @@ void GraupnerBrunel2012CaPlasticitySynHandler::updateWeight( Synapse* synPtr, we
// potential is usually ignorable when t0 is small,
// i.e. Ca is mostly above thetaD or thetaP
//cout << "before bistable newWeight = " << newWeight << "\n";
- if (bistable_) {
+ if (bistable_)
+ {
double chi0 = pow((newWeight-0.5),2.0) / (newWeight*(newWeight-1));
double weightDeviation = 0.5*sqrt( 1.0 + 1.0/(chi0*exp(wFacPtr->t0/2.0/tauSyn_)-1.0) );
- if (newWeight<0.5) {
+ if (newWeight<0.5)
+ {
newWeight = 0.5 - weightDeviation;
- } else {
+ }
+ else
+ {
newWeight = 0.5 + weightDeviation;
}
}
@@ -432,18 +480,19 @@ void GraupnerBrunel2012CaPlasticitySynHandler::updateWeight( Synapse* synPtr, we
void GraupnerBrunel2012CaPlasticitySynHandler::vProcess( const Eref& e, ProcPtr p )
{
- double activation = 0.0;
+ double activation = 0.0;
double currTime = p->currTime;
bool CaFactorsUpdated = false; // Ca-decay and weight Factors updation is done only once
- // if any pre-spike, pre-spike+delayD or post-spike occurs
- // Ca is bumped by CaPre and CaPost on
- // pre-spike+delayD and post-spike respectively
- // At the end, if any event above occurred,
- // change all pre-synaptic weights based on Ca
+ // if any pre-spike, pre-spike+delayD or post-spike occurs
+ // Ca is bumped by CaPre and CaPost on
+ // pre-spike+delayD and post-spike respectively
+ // At the end, if any event above occurred,
+ // change all pre-synaptic weights based on Ca
weightFactors wFacs;
// process pre-synaptic spike events for activation, Ca and weight update
- while( !events_.empty() && events_.top().time <= currTime ) {
+ while( !events_.empty() && events_.top().time <= currTime )
+ {
PreSynEvent currEvent = events_.top();
unsigned int synIndex = currEvent.synIndex;
@@ -472,56 +521,63 @@ void GraupnerBrunel2012CaPlasticitySynHandler::vProcess( const Eref& e, ProcPtr
// need to send it divided by dt.
// Can connect activation to SynChan (double exp)
// or to LIF as an impulse to voltage.
- //activation += currEvent.weight * weightScale_ / p->dt;
+ //activation += currEvent.weight * weightScale_ / p->dt;
activation += currSynPtr->getWeight() * weightScale_ / p->dt;
// update only once for this time-step if an event occurs
- if (!CaFactorsUpdated) {
+ if (!CaFactorsUpdated)
+ {
// update Ca and weightFactors
wFacs = updateCaWeightFactors( currTime );
CaFactorsUpdated = true;
}
- events_.pop();
- }
- if ( activation != 0.0 )
- SynHandlerBase::activationOut()->send( e, activation );
+ events_.pop();
+ }
+ if ( activation != 0.0 )
+ SynHandlerBase::activationOut()->send( e, activation );
// process delayed pre-synaptic spike events for Ca and weight update
// delayD after pre-spike accounts for NMDA rise time
- while( !delayDPreEvents_.empty() && delayDPreEvents_.top().time <= currTime ) {
+ while( !delayDPreEvents_.empty() && delayDPreEvents_.top().time <= currTime )
+ {
// Update Ca, and add CaPre
// update only once for this time-step if an event occurs
- if (!CaFactorsUpdated) {
+ if (!CaFactorsUpdated)
+ {
// update Ca and weightFactors
wFacs = updateCaWeightFactors( currTime );
CaFactorsUpdated = true;
}
Ca_ += CaPre_;
- delayDPreEvents_.pop();
- }
+ delayDPreEvents_.pop();
+ }
// process post-synaptic spike events for Ca and weight update
- while( !postEvents_.empty() && postEvents_.top().time <= currTime ) {
+ while( !postEvents_.empty() && postEvents_.top().time <= currTime )
+ {
// update Ca, then add CaPost
// update only once for this time-step if an event occurs
- if (!CaFactorsUpdated) {
+ if (!CaFactorsUpdated)
+ {
// update Ca and weightFactors
wFacs = updateCaWeightFactors( currTime );
CaFactorsUpdated = true;
}
Ca_ += CaPost_;
- postEvents_.pop();
- }
+ postEvents_.pop();
+ }
// If any event has happened, update all pre-synaptic weights
// If you want individual Ca for each pre-synapse
// create individual SynHandlers for each
- if (CaFactorsUpdated) {
+ if (CaFactorsUpdated)
+ {
// Change weight of all synapses
- for (unsigned int i=0; i<synapses_.size(); i++) {
+ for (unsigned int i=0; i<synapses_.size(); i++)
+ {
// Warning, coder! 'Synapse currSyn = synapses_[i];' is wrong,
// it creates a new, shallow-copied object.
// We want only to point to the same object.
@@ -534,199 +590,199 @@ void GraupnerBrunel2012CaPlasticitySynHandler::vProcess( const Eref& e, ProcPtr
void GraupnerBrunel2012CaPlasticitySynHandler::vReinit( const Eref& e, ProcPtr p )
{
- // For no apparent reason, priority queues don't have a clear operation.
- while( !events_.empty() )
- events_.pop();
- while( !delayDPreEvents_.empty() )
- events_.pop();
- while( !postEvents_.empty() )
- postEvents_.pop();
+ // For no apparent reason, priority queues don't have a clear operation.
+ while( !events_.empty() )
+ events_.pop();
+ while( !delayDPreEvents_.empty() )
+ events_.pop();
+ while( !postEvents_.empty() )
+ postEvents_.pop();
Ca_ = CaInit_;
}
unsigned int GraupnerBrunel2012CaPlasticitySynHandler::addSynapse()
{
- unsigned int newSynIndex = synapses_.size();
- synapses_.resize( newSynIndex + 1 );
- synapses_[newSynIndex].setHandler( this );
- return newSynIndex;
+ unsigned int newSynIndex = synapses_.size();
+ synapses_.resize( newSynIndex + 1 );
+ synapses_[newSynIndex].setHandler( this );
+ return newSynIndex;
}
void GraupnerBrunel2012CaPlasticitySynHandler::dropSynapse( unsigned int msgLookup )
{
- assert( msgLookup < synapses_.size() );
- synapses_[msgLookup].setWeight( -1.0 );
+ assert( msgLookup < synapses_.size() );
+ synapses_[msgLookup].setWeight( -1.0 );
}
void GraupnerBrunel2012CaPlasticitySynHandler::setCa( const double v )
{
- Ca_ = v;
+ Ca_ = v;
}
double GraupnerBrunel2012CaPlasticitySynHandler::getCa() const
{
- return Ca_;
+ return Ca_;
}
void GraupnerBrunel2012CaPlasticitySynHandler::setCaInit( const double v )
{
- CaInit_ = v;
+ CaInit_ = v;
}
double GraupnerBrunel2012CaPlasticitySynHandler::getCaInit() const
{
- return CaInit_;
+ return CaInit_;
}
void GraupnerBrunel2012CaPlasticitySynHandler::setCaPre( const double v )
{
- CaPre_ = v;
+ CaPre_ = v;
}
double GraupnerBrunel2012CaPlasticitySynHandler::getCaPre() const
{
- return CaPre_;
+ return CaPre_;
}
void GraupnerBrunel2012CaPlasticitySynHandler::setCaPost( const double v )
{
- CaPost_ = v;
+ CaPost_ = v;
}
double GraupnerBrunel2012CaPlasticitySynHandler::getCaPost() const
{
- return CaPost_;
+ return CaPost_;
}
void GraupnerBrunel2012CaPlasticitySynHandler::setThetaP( const double v )
{
- thetaP_ = v;
+ thetaP_ = v;
}
double GraupnerBrunel2012CaPlasticitySynHandler::getThetaP() const
{
- return thetaP_;
+ return thetaP_;
}
void GraupnerBrunel2012CaPlasticitySynHandler::setThetaD( const double v )
{
- thetaD_ = v;
+ thetaD_ = v;
}
double GraupnerBrunel2012CaPlasticitySynHandler::getThetaD() const
{
- return thetaD_;
+ return thetaD_;
}
void GraupnerBrunel2012CaPlasticitySynHandler::setGammaD( const double v )
{
- gammaD_ = v;
+ gammaD_ = v;
}
double GraupnerBrunel2012CaPlasticitySynHandler::getGammaD() const
{
- return gammaD_;
+ return gammaD_;
}
void GraupnerBrunel2012CaPlasticitySynHandler::setGammaP( const double v )
{
- gammaP_ = v;
+ gammaP_ = v;
}
double GraupnerBrunel2012CaPlasticitySynHandler::getGammaP() const
{
- return gammaP_;
+ return gammaP_;
}
void GraupnerBrunel2012CaPlasticitySynHandler::setDelayD( const double v )
{
- delayD_ = v;
+ delayD_ = v;
}
double GraupnerBrunel2012CaPlasticitySynHandler::getDelayD() const
{
- return delayD_;
+ return delayD_;
}
void GraupnerBrunel2012CaPlasticitySynHandler::setTauCa( const double v )
{
- if ( rangeWarning( "tauCa", v ) ) return;
- tauCa_ = v;
+ if ( rangeWarning( "tauCa", v ) ) return;
+ tauCa_ = v;
}
double GraupnerBrunel2012CaPlasticitySynHandler::getTauCa() const
{
- return tauCa_;
+ return tauCa_;
}
void GraupnerBrunel2012CaPlasticitySynHandler::setTauSyn( const double v )
{
- if ( rangeWarning( "tauSyn", v ) ) return;
- tauSyn_ = v;
+ if ( rangeWarning( "tauSyn", v ) ) return;
+ tauSyn_ = v;
}
double GraupnerBrunel2012CaPlasticitySynHandler::getTauSyn() const
{
- return tauSyn_;
+ return tauSyn_;
}
void GraupnerBrunel2012CaPlasticitySynHandler::setNoisy( const bool v )
{
- noisy_ = v;
+ noisy_ = v;
}
bool GraupnerBrunel2012CaPlasticitySynHandler::getNoisy() const
{
- return noisy_;
+ return noisy_;
}
void GraupnerBrunel2012CaPlasticitySynHandler::setNoiseSD( const double v )
{
- noiseSD_ = v;
+ noiseSD_ = v;
}
double GraupnerBrunel2012CaPlasticitySynHandler::getNoiseSD() const
{
- return noiseSD_;
+ return noiseSD_;
}
void GraupnerBrunel2012CaPlasticitySynHandler::setBistable( const bool v )
{
- bistable_ = v;
+ bistable_ = v;
}
bool GraupnerBrunel2012CaPlasticitySynHandler::getBistable() const
{
- return bistable_;
+ return bistable_;
}
void GraupnerBrunel2012CaPlasticitySynHandler::setWeightMax( const double v )
{
- weightMax_ = v;
+ weightMax_ = v;
}
double GraupnerBrunel2012CaPlasticitySynHandler::getWeightMax() const
{
- return weightMax_;
+ return weightMax_;
}
void GraupnerBrunel2012CaPlasticitySynHandler::setWeightMin( const double v )
{
- weightMin_ = v;
+ weightMin_ = v;
}
double GraupnerBrunel2012CaPlasticitySynHandler::getWeightMin() const
{
- return weightMin_;
+ return weightMin_;
}
void GraupnerBrunel2012CaPlasticitySynHandler::setWeightScale( const double v )
{
- weightScale_ = v;
+ weightScale_ = v;
}
double GraupnerBrunel2012CaPlasticitySynHandler::getWeightScale() const
{
- return weightScale_;
+ return weightScale_;
}
diff --git a/synapse/GraupnerBrunel2012CaPlasticitySynHandler.h b/synapse/GraupnerBrunel2012CaPlasticitySynHandler.h
index f7888602545b6b9742369e12dca5a4fcbbbb44be..936d9e101a1575f4211e17794a541cba170c6227 100644
--- a/synapse/GraupnerBrunel2012CaPlasticitySynHandler.h
+++ b/synapse/GraupnerBrunel2012CaPlasticitySynHandler.h
@@ -10,55 +10,20 @@
#ifndef _GRAUPNER_BRUNEL_2012_CA_PLASTICITY_SYN_HANDLER_H
#define _GRAUPNER_BRUNEL_2012_CA_PLASTICITY_SYN_HANDLER_H
-/*
-class PreSynEvent: public SynEvent
-{
- public:
- PreSynEvent()
- : SynEvent(), // call the parent constructor with default args
- // by default calls without args, so no need really
- synIndex( 0 )
- {}
-
- PreSynEvent( unsigned int i, double t, double w )
- : SynEvent(t,w),// call the parent constructor with given args
- synIndex( i )
- {;}
-
- unsigned int synIndex;
-};
-
-class PostSynEvent
-{
- public:
- PostSynEvent()
- : time( 0.0 )
- {;}
-
- PostSynEvent( double t )
- : time( t )
- {;}
+#include "../basecode/global.h"
+#include "../randnum/RNG.h"
- double time;
-};
+#include <queue>
-struct ComparePostSynEvent
-{
- bool operator()(const PostSynEvent& lhs, const PostSynEvent& rhs) const
- {
- // Note that this is backwards. We want the smallest timestamp
- // on the top of the events priority_queue.
- return lhs.time > rhs.time;
- }
-};
-*/
+using namespace std;
// see pg 13 of Higgins et al | October 2014 | Volume 10 | Issue 10 | e1003834 | PLOS Comp Biol
// tP and tD are times spent above potentiation and depression thresholds
// Depending on tP and tD, I return A,B,C factors for weight update (see pg 13 ref above)
// A,B,C are used to compute the weight change for one or multiple synapses
// A is weight independent, B,D are weight dependent and C,E are accumulated noise
-struct weightFactors {
+struct weightFactors
+{
weightFactors() : tP(0.0), tD(0.0), A(0.0), B(0.0), C(0.0), D(0.0), E(0.0) {};
double tP; // time spent above potentiation threshold (thetaP) between two events
double tD; // time spent between depression and potentiation thresholds between two events
@@ -77,94 +42,106 @@ struct weightFactors {
*/
class GraupnerBrunel2012CaPlasticitySynHandler: public SynHandlerBase
{
- public:
- GraupnerBrunel2012CaPlasticitySynHandler();
- ~GraupnerBrunel2012CaPlasticitySynHandler();
- GraupnerBrunel2012CaPlasticitySynHandler& operator \
- = ( const GraupnerBrunel2012CaPlasticitySynHandler& other );
-
- ////////////////////////////////////////////////////////////////
- // Inherited virtual functions from SynHandlerBase
- ////////////////////////////////////////////////////////////////
- void vSetNumSynapses( unsigned int num );
- unsigned int vGetNumSynapses() const;
- Synapse* vGetSynapse( unsigned int i );
- void vProcess( const Eref& e, ProcPtr p );
- void vReinit( const Eref& e, ProcPtr p );
- /// Adds a new synapse, returns its index.
- unsigned int addSynapse();
- void dropSynapse( unsigned int droppedSynNumber );
- void addSpike( unsigned int index, double time, double weight );
- double getTopSpike( unsigned int index ) const;
- ////////////////////////////////////////////////////////////////
- void addPostSpike( const Eref& e, double time );
-
- void setCa( double v );
- double getCa() const;
- void setCaInit( double v );
- double getCaInit() const;
- void setTauCa( double v );
- double getTauCa() const;
- void setTauSyn( double v );
- double getTauSyn() const;
- void setNoiseSD( double v );
- double getNoiseSD() const;
- void setNoisy( bool v );
- bool getNoisy() const;
- void setBistable( bool v );
- bool getBistable() const;
-
- void setCaPre( double v );
- double getCaPre() const;
- void setCaPost( double v );
- double getCaPost() const;
- void setDelayD( double v );
- double getDelayD() const;
-
- void setThetaD( double v );
- double getThetaD() const;
- void setThetaP( double v );
- double getThetaP() const;
- void setGammaD( double v );
- double getGammaD() const;
- void setGammaP( double v );
- double getGammaP() const;
-
- void setWeightMax( double v );
- double getWeightMax() const;
- void setWeightMin( double v );
- double getWeightMin() const;
- void setWeightScale( double v );
- double getWeightScale() const;
-
- weightFactors updateCaWeightFactors( double currTime );
- void updateWeight( Synapse* synPtr, weightFactors *wFacPtr );
-
- static const Cinfo* initCinfo();
- private:
- vector< Synapse > synapses_;
- priority_queue< PreSynEvent, vector< PreSynEvent >, CompareSynEvent > events_;
- priority_queue< PreSynEvent, vector< PreSynEvent >, CompareSynEvent > delayDPreEvents_;
- priority_queue< PostSynEvent, vector< PostSynEvent >, ComparePostSynEvent > postEvents_;
- double Ca_;
- double CaInit_;
- double tauCa_;
- double tauSyn_;
- double CaPre_;
- double CaPost_;
- double delayD_;
- bool noisy_;
- double noiseSD_;
- bool bistable_;
- double thetaD_;
- double thetaP_;
- double gammaD_;
- double gammaP_;
- double weightMax_;
- double weightMin_;
- double weightScale_;
- double lastCaUpdateTime_;
- Normal normalGenerator_;
+public:
+ GraupnerBrunel2012CaPlasticitySynHandler();
+ ~GraupnerBrunel2012CaPlasticitySynHandler();
+ GraupnerBrunel2012CaPlasticitySynHandler& operator=(
+ const GraupnerBrunel2012CaPlasticitySynHandler& other );
+
+ ////////////////////////////////////////////////////////////////
+ // Inherited virtual functions from SynHandlerBase
+ ////////////////////////////////////////////////////////////////
+ void vSetNumSynapses( unsigned int num );
+ unsigned int vGetNumSynapses() const;
+ Synapse* vGetSynapse( unsigned int i );
+ void vProcess( const Eref& e, ProcPtr p );
+ void vReinit( const Eref& e, ProcPtr p );
+ /// Adds a new synapse, returns its index.
+ unsigned int addSynapse();
+ void dropSynapse( unsigned int droppedSynNumber );
+ void addSpike( unsigned int index, double time, double weight );
+ double getTopSpike( unsigned int index ) const;
+ ////////////////////////////////////////////////////////////////
+ void addPostSpike( const Eref& e, double time );
+
+ void setCa( double v );
+ double getCa() const;
+ void setCaInit( double v );
+ double getCaInit() const;
+ void setTauCa( double v );
+ double getTauCa() const;
+ void setTauSyn( double v );
+ double getTauSyn() const;
+ void setNoiseSD( double v );
+ double getNoiseSD() const;
+ void setNoisy( bool v );
+ bool getNoisy() const;
+ void setBistable( bool v );
+ bool getBistable() const;
+
+ void setCaPre( double v );
+ double getCaPre() const;
+ void setCaPost( double v );
+ double getCaPost() const;
+ void setDelayD( double v );
+ double getDelayD() const;
+
+ void setThetaD( double v );
+ double getThetaD() const;
+ void setThetaP( double v );
+ double getThetaP() const;
+ void setGammaD( double v );
+ double getGammaD() const;
+ void setGammaP( double v );
+ double getGammaP() const;
+
+ void setWeightMax( double v );
+ double getWeightMax() const;
+ void setWeightMin( double v );
+ double getWeightMin() const;
+ void setWeightScale( double v );
+ double getWeightScale() const;
+
+ weightFactors updateCaWeightFactors( double currTime );
+ void updateWeight( Synapse* synPtr, weightFactors *wFacPtr );
+
+ void reinitSeed( );
+
+ static const Cinfo* initCinfo();
+
+private:
+
+ vector< Synapse > synapses_;
+
+ priority_queue< PreSynEvent, vector< PreSynEvent >, CompareSynEvent > events_;
+ priority_queue< PreSynEvent, vector< PreSynEvent >, CompareSynEvent > delayDPreEvents_;
+ priority_queue< PostSynEvent, vector< PostSynEvent >, ComparePostSynEvent > postEvents_;
+
+ double Ca_;
+ double CaInit_;
+ double tauCa_;
+ double tauSyn_;
+ double CaPre_;
+ double CaPost_;
+ double delayD_;
+ bool noisy_;
+ double noiseSD_;
+ bool bistable_;
+ double thetaD_;
+ double thetaP_;
+ double gammaD_;
+ double gammaP_;
+ double weightMax_;
+ double weightMin_;
+ double weightScale_;
+ double lastCaUpdateTime_;
+
+ // NormalRng normalGenerator_;
+ unsigned long seed_;
+ moose::MOOSE_RANDOM_DEVICE rd_;
+ moose::MOOSE_NORMAL_DISTRIBUTION<double> dist_;
+ moose::MOOSE_RNG_DEFAULT_ENGINE rng_;
+
};
#endif // _GRAUPNER_BRUNEL_2012_CA_PLASTICITY_SYN_HANDLER_H
diff --git a/synapse/SimpleSynHandler.h b/synapse/SimpleSynHandler.h
index 22ee6c90e8eb366da221254d9fc6a82dc0c3d0d2..687d8862308f98d3bd1a310219ff1933e941e6d2 100644
--- a/synapse/SimpleSynHandler.h
+++ b/synapse/SimpleSynHandler.h
@@ -10,6 +10,8 @@
#ifndef _SIMPLE_SYN_HANDLER_H
#define _SIMPLE_SYN_HANDLER_H
+#include <queue>
+
/*
class SynEvent
{
diff --git a/synapse/SynHandlerBase.cpp b/synapse/SynHandlerBase.cpp
index 3c30a30bf1702accb1ce7ad378208a1eb51a0afd..6c3251456f1b369cc2ca191505b586b9d0e3da70 100644
--- a/synapse/SynHandlerBase.cpp
+++ b/synapse/SynHandlerBase.cpp
@@ -13,13 +13,14 @@
static const double RANGE = 1.0e-15;
-SrcFinfo1< double >* SynHandlerBase::activationOut() {
- static SrcFinfo1< double > activationOut(
- "activationOut",
- "Sends out level of activation on all synapses converging to "
- "this SynHandler"
- );
- return &activationOut;
+SrcFinfo1< double >* SynHandlerBase::activationOut()
+{
+ static SrcFinfo1< double > activationOut(
+ "activationOut",
+ "Sends out level of activation on all synapses converging to "
+ "this SynHandler"
+ );
+ return &activationOut;
}
/**
@@ -29,60 +30,61 @@ SrcFinfo1< double >* SynHandlerBase::activationOut() {
*/
const Cinfo* SynHandlerBase::initCinfo()
{
- static ValueFinfo< SynHandlerBase, unsigned int > numSynapses(
- "numSynapses",
- "Number of synapses on SynHandler. Duplicate field for num_synapse",
- &SynHandlerBase::setNumSynapses,
- &SynHandlerBase::getNumSynapses
- );
- //////////////////////////////////////////////////////////////////////
- static DestFinfo process( "process",
- "Handles 'process' call. Checks if any spike events are due for"
- "handling at this timestep, and does learning rule stuff if needed",
- new ProcOpFunc< SynHandlerBase >(& SynHandlerBase::process ) );
- static DestFinfo reinit( "reinit",
- "Handles 'reinit' call. Initializes all the synapses.",
- new ProcOpFunc< SynHandlerBase >(& SynHandlerBase::reinit ) );
-
- static Finfo* processShared[] =
- {
- &process, &reinit
- };
- static SharedFinfo proc( "proc",
- "Shared Finfo to receive Process messages from the clock.",
- processShared, sizeof( processShared ) / sizeof( Finfo* )
- );
-
- //////////////////////////////////////////////////////////////////////
- static Finfo* synHandlerFinfos[] = {
- &numSynapses, // Value
- activationOut(), // SrcFinfo
- &proc, // SharedFinfo
- };
-
- static string doc[] =
- {
- "Name", "SynHandlerBase",
- "Author", "Upi Bhalla",
- "Description",
- "Base class for handling synapse arrays converging onto a given "
- "channel or integrate-and-fire neuron. This class provides the "
- "interface for channels/intFires to connect to a range of synapse "
- "types, including simple synapses, synapses with different "
- "plasticity rules, and variants yet to be implemented. "
- };
- static ZeroSizeDinfo< int > dinfo;
- static Cinfo synHandlerCinfo (
- "SynHandlerBase",
- Neutral::initCinfo(),
- synHandlerFinfos,
- sizeof( synHandlerFinfos ) / sizeof ( Finfo* ),
- &dinfo,
- doc,
- sizeof( doc ) / sizeof( string )
- );
-
- return &synHandlerCinfo;
+ static ValueFinfo< SynHandlerBase, unsigned int > numSynapses(
+ "numSynapses",
+ "Number of synapses on SynHandler. Duplicate field for num_synapse",
+ &SynHandlerBase::setNumSynapses,
+ &SynHandlerBase::getNumSynapses
+ );
+ //////////////////////////////////////////////////////////////////////
+ static DestFinfo process( "process",
+ "Handles 'process' call. Checks if any spike events are due for"
+ "handling at this timestep, and does learning rule stuff if needed",
+ new ProcOpFunc< SynHandlerBase >(& SynHandlerBase::process ) );
+ static DestFinfo reinit( "reinit",
+ "Handles 'reinit' call. Initializes all the synapses.",
+ new ProcOpFunc< SynHandlerBase >(& SynHandlerBase::reinit ) );
+
+ static Finfo* processShared[] =
+ {
+ &process, &reinit
+ };
+ static SharedFinfo proc( "proc",
+ "Shared Finfo to receive Process messages from the clock.",
+ processShared, sizeof( processShared ) / sizeof( Finfo* )
+ );
+
+ //////////////////////////////////////////////////////////////////////
+ static Finfo* synHandlerFinfos[] =
+ {
+ &numSynapses, // Value
+ activationOut(), // SrcFinfo
+ &proc, // SharedFinfo
+ };
+
+ static string doc[] =
+ {
+ "Name", "SynHandlerBase",
+ "Author", "Upi Bhalla",
+ "Description",
+ "Base class for handling synapse arrays converging onto a given "
+ "channel or integrate-and-fire neuron. This class provides the "
+ "interface for channels/intFires to connect to a range of synapse "
+ "types, including simple synapses, synapses with different "
+ "plasticity rules, and variants yet to be implemented. "
+ };
+ static ZeroSizeDinfo< int > dinfo;
+ static Cinfo synHandlerCinfo (
+ "SynHandlerBase",
+ Neutral::initCinfo(),
+ synHandlerFinfos,
+ sizeof( synHandlerFinfos ) / sizeof ( Finfo* ),
+ &dinfo,
+ doc,
+ sizeof( doc ) / sizeof( string )
+ );
+
+ return &synHandlerCinfo;
}
static const Cinfo* synHandlerCinfo = SynHandlerBase::initCinfo();
@@ -90,44 +92,49 @@ static const Cinfo* synHandlerCinfo = SynHandlerBase::initCinfo();
////////////////////////////////////////////////////////////////////////
SynHandlerBase::SynHandlerBase()
-{ ; }
+{
+ ;
+}
SynHandlerBase::~SynHandlerBase()
-{ ; }
+{
+ ;
+}
void SynHandlerBase::setNumSynapses( unsigned int num )
{
- vSetNumSynapses( num );
+ vSetNumSynapses( num );
}
unsigned int SynHandlerBase::getNumSynapses() const
{
- return vGetNumSynapses();
+ return vGetNumSynapses();
}
Synapse* SynHandlerBase::getSynapse( unsigned int i )
{
- return vGetSynapse( i );
+ return vGetSynapse( i );
}
void SynHandlerBase::process( const Eref& e, ProcPtr p )
{
- vProcess( e, p );
+ vProcess( e, p );
}
void SynHandlerBase::reinit( const Eref& e, ProcPtr p )
{
- vReinit( e, p );
+ vReinit( e, p );
}
bool SynHandlerBase::rangeWarning( const string& field, double value )
{
- if ( value < RANGE ) {
- cout << "Warning: Ignored attempt to set " << field <<
- " of SynHandler " <<
- // c->target().e->name() <<
- " to less than " << RANGE << endl;
- return 1;
- }
- return 0;
+ if ( value < RANGE )
+ {
+ cout << "Warning: Ignored attempt to set " << field <<
+ " of SynHandler " <<
+ // c->target().e->name() <<
+ " to less than " << RANGE << endl;
+ return 1;
+ }
+ return 0;
}
diff --git a/synapse/SynHandlerBase.h b/synapse/SynHandlerBase.h
index e3b3a3834c9008cff8e217a75c7580aa51d2f4d7..d0d3d43a076d1289b918a6b7887b8778ec6544d9 100644
--- a/synapse/SynHandlerBase.h
+++ b/synapse/SynHandlerBase.h
@@ -21,77 +21,79 @@ class Synapse;
*/
class SynHandlerBase
{
- public:
- SynHandlerBase();
- virtual ~SynHandlerBase();
+public:
+ SynHandlerBase();
+ virtual ~SynHandlerBase();
- ////////////////////////////////////////////////////////////////
- // Field assignment stuff.
- ////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////
+ // Field assignment stuff.
+ ////////////////////////////////////////////////////////////////
- /**
- * Resizes the synapse storage
- */
- void setNumSynapses( unsigned int num );
+ /**
+ * Resizes the synapse storage
+ */
+ void setNumSynapses( unsigned int num );
- /**
- * Returns number of synapses defined.
- */
- unsigned int getNumSynapses() const;
+ /**
+ * Returns number of synapses defined.
+ */
+ unsigned int getNumSynapses() const;
- /**
- * Gets specified synapse
- */
- Synapse* getSynapse( unsigned int i );
- ////////////////////////////////////////////////////////////////
+ /**
+ * Gets specified synapse
+ */
+ Synapse* getSynapse( unsigned int i );
+ ////////////////////////////////////////////////////////////////
- void process( const Eref& e, ProcPtr p );
- void reinit( const Eref& e, ProcPtr p );
+ void process( const Eref& e, ProcPtr p );
+ void reinit( const Eref& e, ProcPtr p );
- /**
- * A utility function to check for assignment to fields that
- * must be > 0
- */
- bool rangeWarning( const string& field, double value );
+ /**
+ * A utility function to check for assignment to fields that
+ * must be > 0
+ */
+ bool rangeWarning( const string& field, double value );
- ////////////////////////////////////////////////////////////////
- /**
- * Adds a new synapse, returns its index. This is
- * triggered by addMsg of inputs to the child synapse. The
- * SynHandler has to ensure that we have enough synapses allocated
- * to handle the new message, and the return value is used so that
- * the new message knows the fieldIndex to send the message to.
- */
- virtual unsigned int addSynapse() = 0;
+ ////////////////////////////////////////////////////////////////
+ /**
+ * Adds a new synapse, returns its index. This is
+ * triggered by addMsg of inputs to the child synapse. The
+ * SynHandler has to ensure that we have enough synapses allocated
+ * to handle the new message, and the return value is used so that
+ * the new message knows the fieldIndex to send the message to.
+ */
+ virtual unsigned int addSynapse() = 0;
- /**
- * Drops an existing synapse, triggered by deleteMsg of an input
- * to the child synapse. This is a little messy because we can't
- * change the indices of the other synapses. The Handler has to
- * figure out how to handle the 'holes' in its array of synapses.
- */
- virtual void dropSynapse( unsigned int droppedSynNumber ) = 0;
+ /**
+ * Drops an existing synapse, triggered by deleteMsg of an input
+ * to the child synapse. This is a little messy because we can't
+ * change the indices of the other synapses. The Handler has to
+ * figure out how to handle the 'holes' in its array of synapses.
+ */
+ virtual void dropSynapse( unsigned int droppedSynNumber ) = 0;
+
+ /**
+ * Record arrival of a new spike event. The 'time' is time for
+ * eventual arrival of the spike, and is typically well in the
+ * future. The index specifies which synapse the spike came to.
+ */
+ virtual void addSpike(
+ unsigned int index, double time, double weight ) = 0;
+ virtual double getTopSpike( unsigned int index ) const = 0;
+ ////////////////////////////////////////////////////////////////
+ // Virtual func definitions for fields.
+ ////////////////////////////////////////////////////////////////
+ virtual void vSetNumSynapses( unsigned int num ) = 0;
+ virtual unsigned int vGetNumSynapses() const = 0;
+ virtual Synapse* vGetSynapse( unsigned int i ) = 0;
+ virtual void vProcess( const Eref& e, ProcPtr p ) = 0;
+ virtual void vReinit( const Eref& e, ProcPtr p ) = 0;
+ ////////////////////////////////////////////////////////////////
+ static SrcFinfo1< double >* activationOut();
+ static const Cinfo* initCinfo();
+
+private:
- /**
- * Record arrival of a new spike event. The 'time' is time for
- * eventual arrival of the spike, and is typically well in the
- * future. The index specifies which synapse the spike came to.
- */
- virtual void addSpike(
- unsigned int index, double time, double weight ) = 0;
- virtual double getTopSpike( unsigned int index ) const = 0;
- ////////////////////////////////////////////////////////////////
- // Virtual func definitions for fields.
- ////////////////////////////////////////////////////////////////
- virtual void vSetNumSynapses( unsigned int num ) = 0;
- virtual unsigned int vGetNumSynapses() const = 0;
- virtual Synapse* vGetSynapse( unsigned int i ) = 0;
- virtual void vProcess( const Eref& e, ProcPtr p ) = 0;
- virtual void vReinit( const Eref& e, ProcPtr p ) = 0;
- ////////////////////////////////////////////////////////////////
- static SrcFinfo1< double >* activationOut();
- static const Cinfo* initCinfo();
- private:
};
#endif // _SYN_HANDLER_BASE_H
diff --git a/synapse/testSynapse.cpp b/synapse/testSynapse.cpp
index 600d7ff3fe913565d4fc4b7dc8f9b52ac73d41ae..427f08b1c7a541411e5f7085a2b72d85e1dedf4f 100644
--- a/synapse/testSynapse.cpp
+++ b/synapse/testSynapse.cpp
@@ -18,7 +18,6 @@
#include "RollingMatrix.h"
#include "SeqSynHandler.h"
#include "../shell/Shell.h"
-#include "../randnum/randnum.h"
double doCorrel( RollingMatrix& rm, vector< vector< double >> & kernel )
{
diff --git a/tests/python/OSC_diff_vols.g b/tests/python/OSC_diff_vols.g
new file mode 100644
index 0000000000000000000000000000000000000000..d7166be273ca0af5e73079b31d625eb311f4dc10
--- /dev/null
+++ b/tests/python/OSC_diff_vols.g
@@ -0,0 +1,219 @@
+//genesis
+// kkit Version 11 flat dumpfile
+
+// Saved on Tue Jan 21 14:05:52 2014
+
+include kkit {argv 1}
+
+FASTDT = 0.0001
+SIMDT = 0.005
+CONTROLDT = 5
+PLOTDT = 10
+MAXTIME = 2500
+TRANSIENT_TIME = 2
+VARIABLE_DT_FLAG = 1
+DEFAULT_VOL = 1e-20
+VERSION = 11.0
+setfield /file/modpath value /home2/bhalla/scripts/modules
+kparms
+
+//genesis
+
+initdump -version 3 -ignoreorphans 1
+simobjdump doqcsinfo filename accessname accesstype transcriber developer \
+ citation species tissue cellcompartment methodology sources \
+ model_implementation model_validation x y z
+simobjdump table input output alloced step_mode stepsize x y z
+simobjdump xtree path script namemode sizescale
+simobjdump xcoredraw xmin xmax ymin ymax
+simobjdump xtext editable
+simobjdump xgraph xmin xmax ymin ymax overlay
+simobjdump xplot pixflags script fg ysquish do_slope wy
+simobjdump group xtree_fg_req xtree_textfg_req plotfield expanded movealone \
+ link savename file version md5sum mod_save_flag x y z
+simobjdump geometry size dim shape outside xtree_fg_req xtree_textfg_req x y \
+ z
+simobjdump kpool DiffConst CoInit Co n nInit mwt nMin vol slave_enable \
+ geomname xtree_fg_req xtree_textfg_req x y z
+simobjdump kreac kf kb notes xtree_fg_req xtree_textfg_req x y z
+simobjdump kenz CoComplexInit CoComplex nComplexInit nComplex vol k1 k2 k3 \
+ keepconc usecomplex notes xtree_fg_req xtree_textfg_req link x y z
+simobjdump stim level1 width1 delay1 level2 width2 delay2 baselevel trig_time \
+ trig_mode notes xtree_fg_req xtree_textfg_req is_running x y z
+simobjdump xtab input output alloced step_mode stepsize notes editfunc \
+ xtree_fg_req xtree_textfg_req baselevel last_x last_y is_running x y z
+simobjdump kchan perm gmax Vm is_active use_nernst notes xtree_fg_req \
+ xtree_textfg_req x y z
+simobjdump transport input output alloced step_mode stepsize dt delay clock \
+ kf xtree_fg_req xtree_textfg_req x y z
+simobjdump proto x y z
+simobjdump text str
+simundump geometry /kinetics/geometry 0 9.9998e-20 3 sphere "" white black 0 \
+ 0 0
+simundump geometry /kinetics/geometry[1] 0 9.9998e-21 3 sphere "" white black \
+ 0 0 0
+simundump geometry /kinetics/geometry[2] 0 1e-20 3 sphere "" white black 0 0 \
+ 0
+simundump text /kinetics/notes 0 ""
+call /kinetics/notes LOAD \
+""
+simundump text /kinetics/geometry/notes 0 ""
+call /kinetics/geometry/notes LOAD \
+""
+simundump text /kinetics/geometry[1]/notes 0 ""
+call /kinetics/geometry[1]/notes LOAD \
+""
+simundump text /kinetics/geometry[2]/notes 0 ""
+call /kinetics/geometry[2]/notes LOAD \
+""
+simundump kreac /kinetics/exo 0 0.005 0 "" white black 3 9 0
+simundump text /kinetics/exo/notes 0 ""
+call /kinetics/exo/notes LOAD \
+""
+simundump kreac /kinetics/endo 0 0.01 0 "" white black -6 11 0
+simundump text /kinetics/endo/notes 0 ""
+call /kinetics/endo/notes LOAD \
+""
+simundump group /kinetics/B 0 yellow black x 0 0 "" Bulk defaultfile.g 0 0 0 \
+ -7 6 0
+simundump text /kinetics/B/notes 0 ""
+call /kinetics/B/notes LOAD \
+""
+simundump kpool /kinetics/B/P 0 0 0.1 0.1 0.6 0.6 0 0 6 0 /kinetics/geometry \
+ 4 yellow -2 2 0
+simundump text /kinetics/B/P/notes 0 ""
+call /kinetics/B/P/notes LOAD \
+""
+simundump kenz /kinetics/B/P/kenz 0 0 0 0 0 6 16.667 4 1 0 0 "" red 4 "" -2 0 \
+ 0
+simundump text /kinetics/B/P/kenz/notes 0 ""
+call /kinetics/B/P/kenz/notes LOAD \
+""
+simundump kreac /kinetics/B/basal 0 0.01 0 "" white yellow -4 -4 0
+simundump text /kinetics/B/basal/notes 0 ""
+call /kinetics/B/basal/notes LOAD \
+""
+simundump kpool /kinetics/B/M 0 0 0 0 0 0 0 0 6 0 /kinetics/geometry 62 \
+ yellow -5 7 0
+simundump text /kinetics/B/M/notes 0 ""
+call /kinetics/B/M/notes LOAD \
+""
+simundump kpool /kinetics/B/M* 0 0 0 0 0 0 0 0 6 0 /kinetics/geometry 28 \
+ yellow 2 2 0
+simundump text /kinetics/B/M*/notes 0 ""
+call /kinetics/B/M*/notes LOAD \
+""
+simundump kenz /kinetics/B/M*/kenz 0 0 0 0 0 59.999 0.41667 2 0.5 0 0 "" red \
+ 28 "" 1 6 0
+simundump text /kinetics/B/M*/kenz/notes 0 ""
+call /kinetics/B/M*/kenz/notes LOAD \
+""
+simundump group /kinetics/A 0 16 black x 0 0 "" PSD defaultfile.g 0 0 0 -5 16 \
+ 0
+simundump text /kinetics/A/notes 0 ""
+call /kinetics/A/notes LOAD \
+""
+simundump kreac /kinetics/A/basal 0 0.01 0 "" white 16 -1 8 0
+simundump text /kinetics/A/basal/notes 0 ""
+call /kinetics/A/basal/notes LOAD \
+""
+simundump kpool /kinetics/A/Stot 0 0 0 1.75 21 0 0 0 12 0 \
+ /kinetics/geometry[2] 41 16 0 24 0
+simundump text /kinetics/A/Stot/notes 0 ""
+call /kinetics/A/Stot/notes LOAD \
+""
+simundump kpool /kinetics/A/P 0 0 0.049999 0.049999 0.59999 0.59999 0 0 12 0 \
+ /kinetics/geometry[1] 3 16 -1 11 0
+simundump text /kinetics/A/P/notes 0 ""
+call /kinetics/A/P/notes LOAD \
+""
+simundump kenz /kinetics/A/P/kenz 0 0 0 0 0 5.9999 16.667 4 1 0 0 "" red 3 "" \
+ -1 13 0
+simundump text /kinetics/A/P/kenz/notes 0 ""
+call /kinetics/A/P/kenz/notes LOAD \
+""
+simundump kpool /kinetics/A/M* 0 0 0 0 0 0 0 0 12 0 /kinetics/geometry 47 16 \
+ 4 19 0
+simundump text /kinetics/A/M*/notes 0 ""
+call /kinetics/A/M*/notes LOAD \
+""
+simundump kenz /kinetics/A/M*/kenz 0 0 0 0 0 5.9999 0.41667 2 0.5 0 0 "" red \
+ 57 "" -1 18 0
+simundump text /kinetics/A/M*/kenz/notes 0 ""
+call /kinetics/A/M*/kenz/notes LOAD \
+""
+simundump kpool /kinetics/A/M 0 0 1.75 1.75 21 21 0 0 12 0 /kinetics/geometry \
+ 53 16 -4 17 0
+simundump text /kinetics/A/M/notes 0 ""
+call /kinetics/A/M/notes LOAD \
+""
+simundump xgraph /graphs/conc1 0 0 2500 0.001 3 0
+simundump xgraph /graphs/conc2 0 0 2500 0 5 0
+simundump xplot /graphs/conc1/M.Co 3 524288 \
+ "delete_plot.w <s> <d>; edit_plot.D <w>" 53 0 0 1
+simundump xplot /graphs/conc1/M*.Co 3 524288 \
+ "delete_plot.w <s> <d>; edit_plot.D <w>" 47 0 0 1
+simundump xplot /graphs/conc2/M.Co 3 524288 \
+ "delete_plot.w <s> <d>; edit_plot.D <w>" 62 0 0 1
+simundump xplot /graphs/conc2/M*.Co 3 524288 \
+ "delete_plot.w <s> <d>; edit_plot.D <w>" 28 0 0 1
+simundump xgraph /moregraphs/conc3 0 0 2500 0 1 0
+simundump xgraph /moregraphs/conc4 0 0 2500 0 1 0
+simundump xcoredraw /edit/draw 0 -9 6 -6 26
+simundump xtree /edit/draw/tree 0 \
+ /kinetics/#[],/kinetics/#[]/#[],/kinetics/#[]/#[]/#[][TYPE!=proto],/kinetics/#[]/#[]/#[][TYPE!=linkinfo]/##[] \
+ "edit_elm.D <v>; drag_from_edit.w <d> <S> <x> <y> <z>" auto 0.6
+simundump xtext /file/notes 0 1
+xtextload /file/notes \
+"21 Jan 2014." \
+"Using " \
+"different volumes for the two compartments, based on OSC_Cspace.g"
+addmsg /kinetics/B/M* /kinetics/exo SUBSTRATE n
+addmsg /kinetics/A/M* /kinetics/exo PRODUCT n
+addmsg /kinetics/A/M /kinetics/endo SUBSTRATE n
+addmsg /kinetics/B/M /kinetics/endo PRODUCT n
+addmsg /kinetics/B/P/kenz /kinetics/B/P REAC eA B
+addmsg /kinetics/B/P /kinetics/B/P/kenz ENZYME n
+addmsg /kinetics/B/M* /kinetics/B/P/kenz SUBSTRATE n
+addmsg /kinetics/B/M /kinetics/B/basal SUBSTRATE n
+addmsg /kinetics/B/M* /kinetics/B/basal PRODUCT n
+addmsg /kinetics/B/basal /kinetics/B/M REAC A B
+addmsg /kinetics/B/P/kenz /kinetics/B/M MM_PRD pA
+addmsg /kinetics/B/M*/kenz /kinetics/B/M REAC sA B
+addmsg /kinetics/endo /kinetics/B/M REAC B A
+addmsg /kinetics/B/basal /kinetics/B/M* REAC B A
+addmsg /kinetics/B/P/kenz /kinetics/B/M* REAC sA B
+addmsg /kinetics/B/M*/kenz /kinetics/B/M* REAC eA B
+addmsg /kinetics/B/M*/kenz /kinetics/B/M* MM_PRD pA
+addmsg /kinetics/exo /kinetics/B/M* REAC A B
+addmsg /kinetics/B/M* /kinetics/B/M*/kenz ENZYME n
+addmsg /kinetics/B/M /kinetics/B/M*/kenz SUBSTRATE n
+addmsg /kinetics/A/M /kinetics/A/basal SUBSTRATE n
+addmsg /kinetics/A/M* /kinetics/A/basal PRODUCT n
+addmsg /kinetics/A/M /kinetics/A/Stot SUMTOTAL n nInit
+addmsg /kinetics/A/M* /kinetics/A/Stot SUMTOTAL n nInit
+addmsg /kinetics/A/M*/kenz /kinetics/A/Stot SUMTOTAL nComplex nComplexInit
+addmsg /kinetics/A/P/kenz /kinetics/A/Stot SUMTOTAL nComplex nComplexInit
+addmsg /kinetics/A/M*/kenz /kinetics/A/Stot SUMTOTAL nComplex nComplexInit
+addmsg /kinetics/A/P/kenz /kinetics/A/P REAC eA B
+addmsg /kinetics/A/P /kinetics/A/P/kenz ENZYME n
+addmsg /kinetics/A/M* /kinetics/A/P/kenz SUBSTRATE n
+addmsg /kinetics/A/M*/kenz /kinetics/A/M* MM_PRD pA
+addmsg /kinetics/A/P/kenz /kinetics/A/M* REAC sA B
+addmsg /kinetics/A/basal /kinetics/A/M* REAC B A
+addmsg /kinetics/A/M*/kenz /kinetics/A/M* REAC eA B
+addmsg /kinetics/exo /kinetics/A/M* REAC B A
+addmsg /kinetics/A/M /kinetics/A/M*/kenz SUBSTRATE n
+addmsg /kinetics/A/M* /kinetics/A/M*/kenz ENZYME n
+addmsg /kinetics/A/M*/kenz /kinetics/A/M REAC sA B
+addmsg /kinetics/A/P/kenz /kinetics/A/M MM_PRD pA
+addmsg /kinetics/A/basal /kinetics/A/M REAC A B
+addmsg /kinetics/endo /kinetics/A/M REAC A B
+addmsg /kinetics/A/M /graphs/conc1/M.Co PLOT Co *M.Co *53
+addmsg /kinetics/A/M* /graphs/conc1/M*.Co PLOT Co *M*.Co *47
+addmsg /kinetics/B/M /graphs/conc2/M.Co PLOT Co *M.Co *62
+addmsg /kinetics/B/M* /graphs/conc2/M*.Co PLOT Co *M*.Co *28
+enddump
+// End of dump
+
+complete_loading
diff --git a/tests/python/fixXreacs.py b/tests/python/fixXreacs.py
new file mode 100644
index 0000000000000000000000000000000000000000..7a68ed9b6c89a0bccf7e95e9b4108270c115b294
--- /dev/null
+++ b/tests/python/fixXreacs.py
@@ -0,0 +1,194 @@
+# -*- coding: utf-8 -*-
+####################################################################
+# fixXreacs.py
+# The program is meant to take a model and reconfigure any cross-compartment
+# reactions so that they are split into portions on either side coupled
+# either by diffusion, or by a reaction-driven translocation process.
+#
+# Copyright (C) Upinder S. Bhalla 2018
+# This program is free software. It is licensed under the terms of
+# GPL version 3 or later at your discretion.
+# This program carries no warranty whatsoever.
+####################################################################
+
+
+import sys
+import moose
+
+msgSeparator = "_xMsg_"
+
+def findCompt( elm ):
+ elm = moose.element( elm )
+ pa = elm.parent
+ while pa.path != '/':
+ if moose.Neutral(pa).isA[ 'ChemCompt' ]:
+ return pa.path
+ pa = pa.parent
+ print( 'Error: No compartment parent found for ' + elm.path )
+ return '/'
+
+# http://stackoverflow.com/q/3844948/
+def checkEqual(lst):
+ return not lst or lst.count(lst[0]) == len(lst)
+
+def findXreacs( basepath, reacType ):
+ reacs = moose.wildcardFind( basepath + '/##[ISA=' + reacType + 'Base]' )
+ ret = []
+ for i in reacs:
+ reacc = findCompt( i )
+ subs = i.neighbors['subOut']
+ prds = i.neighbors['prdOut']
+ subc = [findCompt(j) for j in subs]
+ prdc = [findCompt(j) for j in prds]
+
+ enzc = []
+ if reacType == 'Enz':
+ enzc = [reacc]
+ if not checkEqual( subc + prdc + enzc ):
+ ret.append( [i, reacc, subs, subc, prds, prdc ])
+ return ret
+
+def removeEnzFromPool( pool ):
+ kids = moose.wildcardFind( pool.path + "/#" )
+ for i in kids:
+ if i.isA[ 'EnzBase' ]:
+ moose.delete( i )
+ elif i.isA[ 'Function' ]:
+ moose.delete( i )
+
+# If a pool is not in the same compt as reac, make a proxy in the reac
+# compt, connect it up, and disconnect the one in the old compt.
+def proxify( reac, reacc, direction, pool, poolc ):
+ reacc_elm = moose.element( reacc )
+ reac_elm = moose.element( reac )
+ # Preserve the rates which were set up for the x-compt reacn
+ #moose.showfield( reac )
+ dupname = pool.name + '_xfer_' + moose.element(poolc).name
+ #print "#############", pool, dupname, poolc
+ if moose.exists( reacc + '/' + dupname ):
+ duppool = moose.element( reacc + '/' + dupname )
+ else:
+ # This also deals with cases where the duppool is buffered.
+ duppool = moose.copy(pool, reacc_elm, dupname )
+ duppool.diffConst = 0 # diffusion only happens in original compt
+ removeEnzFromPool( duppool )
+ disconnectReactant( reac, pool, duppool )
+ moose.connect( reac, direction, duppool, 'reac' )
+ #moose.showfield( reac )
+ #moose.showmsg( reac )
+
+def enzProxify( enz, enzc, direction, pool, poolc ):
+ if enzc == poolc:
+ return
+ enze = moose.element( enz )
+ # kcat and k2 are indept of volume, just time^-1
+ km = enze.numKm
+ proxify( enz, enzc, direction, pool, poolc )
+ enze.numKm = km
+
+def reacProxify( reac, reacc, direction, pool, poolc ):
+ if reacc == poolc:
+ return
+ reac_elm = moose.element( reac )
+ kf = reac_elm.numKf
+ kb = reac_elm.numKb
+ proxify( reac, reacc, direction, pool, poolc )
+ reac_elm.numKf = kf
+ reac_elm.numKb = kb
+
+def identifyMsg( src, srcOut, dest ):
+ if src.isA[ 'ReacBase' ] or src.isA[ 'EnzBase' ]:
+ if srcOut == 'subOut':
+ return msgSeparator + src.path + ' sub ' + dest.path + ' reac'
+ if srcOut == 'prdOut':
+ return msgSeparator + src.path + ' prd ' + dest.path + ' reac'
+ return ''
+
+def disconnectReactant( reacOrEnz, reactant, duppool ):
+ outMsgs = reacOrEnz.msgOut
+ infoPath = duppool.path + '/info'
+ if moose.exists( infoPath ):
+ info = moose.element( infoPath )
+ else:
+ info = moose.Annotator( infoPath )
+
+ #moose.le( reactant )
+ notes = ""
+ #moose.showmsg( reacOrEnz )
+ for i in outMsgs:
+ #print "killing msg from {} to {}\nfor {} and {}".format( reacOrEnz.path, reactant.path, i.srcFieldsOnE1[0], i.srcFieldsOnE2[0] )
+ if i.e1 == reactant:
+ msgStr = identifyMsg( i.e2, i.e2.srcFieldsOnE2[0], i.e1 )
+ if len( msgStr ) > 0:
+ notes += msgStr
+ moose.delete( i )
+ elif i.e2 == reactant:
+ msgStr = identifyMsg( i.e1[0], i.srcFieldsOnE1[0], i.e2[0] )
+ if len( msgStr ) > 0:
+ notes += msgStr
+ moose.delete( i )
+ #print "MSGS to rebuild:", notes
+ info.notes += notes
+
+def fixXreacs( basepath ):
+ xr = findXreacs( basepath, 'Reac' )
+ xe = findXreacs( basepath, 'Enz' )
+
+ for i in (xr):
+ reac, reacc, subs, subc, prds, prdc = i
+ for j in range( len( subs )):
+ reacProxify( reac, reacc, 'sub', subs[j], subc[j] )
+ for j in range( len( prds )):
+ reacProxify( reac, reacc, 'prd', prds[j], prdc[j] )
+
+ for i in (xe):
+ reac, reacc, subs, subc, prds, prdc = i
+ for j in range( len( subs )):
+ enzProxify( reac, reacc, 'sub', subs[j], subc[j] )
+ for j in range( len( prds )):
+ enzProxify( reac, reacc, 'prd', prds[j], prdc[j] )
+
+#####################################################################
+
+def getOldRates( msgs ):
+ if len( msgs ) > 1 :
+ m1 = msgs[1].split( msgSeparator )[0]
+ elm = moose.element( m1.split( ' ' )[0] )
+ if elm.isA[ 'ReacBase' ]:
+ return [elm.numKf, elm.numKb]
+ elif elm.isA[ 'EnzBase' ]:
+ return [elm.numKm,]
+ print( "Warning: getOldRates did not have any messages" )
+ return [0,]
+
+def restoreOldRates( oldRates, msgs ):
+ #print oldRates, msgs
+ if len( msgs ) > 1 :
+ m1 = msgs[1].split( msgSeparator )[0]
+ elm = moose.element( m1.split( ' ' )[0] )
+ if elm.isA[ 'ReacBase' ]:
+ elm.numKf = oldRates[0]
+ elm.numKb = oldRates[1]
+ elif elm.isA[ 'enzBase' ]:
+ elm.numKm = oldRates[0]
+
+
+
+def restoreXreacs( basepath ):
+ proxyInfo = moose.wildcardFind( basepath + "/##/#_xfer_#/info" )
+ for i in proxyInfo:
+ msgs = i.notes.split( msgSeparator )
+ oldRates = getOldRates( msgs )
+ #print( "Deleting {}".format( i.parent.path ) )
+ #print msgs
+ moose.delete( i.parent )
+ for j in msgs:
+ if len( j ) > 0:
+ args = j.split( ' ' )
+ assert( len( args ) == 4 )
+ #moose.showfield( args[0] )
+ moose.connect( args[0], args[1], args[2], args[3] )
+ #print( "Reconnecting {}".format( args ) )
+ #moose.showfield( args[0] )
+ restoreOldRates( oldRates, msgs )
+
diff --git a/tests/python/params.py b/tests/python/params.py
index 1feacecc91b9a7de77d801b1bf26722d1196a65f..bd3bacae5b789c1b2ed18745fa3c8e6e912373d1 100644
--- a/tests/python/params.py
+++ b/tests/python/params.py
@@ -1,27 +1,63 @@
# -*- coding: utf-8 -*-
-t_stop = 10
-dend_diameter = 2.2627398e-6
-dend_length = 1.131369936e-6
-Cm = 4.021231698e-12
-Rm = 1865100032
-Em = -0.07100000232
-Vm_0 = -0.0705
-dt = 50e-6
-spines_no = 0
-difshell_no = 2
-difshell_name = "Ca_shell"
-Ca_basal = 50e-6
-Ca_initial = Ca_basal*200
-dca = 200.0e-12
-difbuff_no = 1
-difbuff_name = "Buff"
-btotal = 80.0e-3
-kf = 0.028e6
-kb = 19.6
-d = 66e-12
-inject = 0.1e-9
-gbar = 1
-#MMpump
-km = 0.3e-3
-kcat = 85e-22
-pumps = 1
+"""params.py
+
+Parameters used in this model
+
+These parameters are from paper Miller et. al. "The stability of CaMKII
+switch"
+
+"""
+
+__author__ = "Dilawar Singh"
+__copyright__ = "Copyright 2015, Dilawar Singh and NCBS Bangalore"
+__credits__ = ["NCBS Bangalore"]
+__license__ = "GNU GPL"
+__version__ = "1.0.0"
+__maintainer__ = "Dilawar Singh"
+__email__ = "dilawars@ncbs.res.in"
+__status__ = "Development"
+
+
+run_time = 30
+N_CaMK = 10
+N_PP1 = 100
+num_switch = 1
+voxel_length = 125e-9
+num_voxels = 1
+
+diff_consts = { 'x' : 1e-13, 'y' : 1e-13, 'pp1' : 1e-13 }
+
+conc_i1_free = 0.1e-3
+act_CaN = 1.0
+act_PKA = 1.0
+
+# Michaelis constant of protein phosphatase.
+# 0.4 um to 2.0 uM have been used. Miller uses 0.2 um. The switch shows
+# bistability of these ranges. We have taken the largest Km (or slowest) first
+# step in dephosphorylation.
+K_M = 10e-3
+k_2 = 10.0
+
+# Hill coefficientfor Ca++ activation of CaMKII
+K_H1 = 0.7e-3
+K_H2 = 0.3e-3
+
+k_1 = 1.5
+k_3 = 100e3
+k_4 = 0.001
+K_I = 1e-6
+
+rate_loosex = 0.1
+rate_loosey = 0.1
+rate_gainx = 1
+rate_gainy = 1
+
+turnover_rate = 1/(30*3600.0)
+v_1 = 1.268e-5
+v_2 = 4.36e-3
+phosphatase_inhibit = 280.0
+vi = phosphatase_inhibit
+
+## Calcium input expression.
+ca_basal = 80e-6
+ca_expr = "(fmod(t,4)<2)?{0}:({0}*(1+0.5*rand(-1)))".format( ca_basal )
diff --git a/tests/python/testXchan1.py b/tests/python/testXchan1.py
new file mode 100644
index 0000000000000000000000000000000000000000..1bcc130b6e694a3823ad9be4cef4b88630e81379
--- /dev/null
+++ b/tests/python/testXchan1.py
@@ -0,0 +1,183 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+## This program is part of 'MOOSE', the
+## Messaging Object Oriented Simulation Environment.
+## Copyright (C) 2014 Upinder S. Bhalla. and NCBS
+## It is made available under the terms of the
+## GNU Lesser General Public License version 2.1
+## See the file COPYING.LIB for the full notice.
+## Here test ConcChan. We set up a channel and a pump and run two tests.
+## First we have zero flux through the pump and check that the conc
+## equalizes on both sides of the membrane. Then we change the Kf of
+## the pump to a value designed to give twice the conc In as Out.
+## The system is a 1-voxel cyl compt and an internal endoMesh, having a
+## volume = 1/8 of the cylinder.
+## \
+## COMPT: s ----> / s :ENDO
+## s =chan= s
+## \
+##
+## This becomes:
+## \
+## COMPT: s ----> s_xfer_endo / s :ENDO
+## s =chan= s
+## \
+##
+#########################################################################
+
+import math
+import numpy as np
+import matplotlib.pyplot as plt
+import matplotlib.image as mpimg
+import moose
+print( '[INFO ] Using moose from %s, %s' % (moose.__file__, moose.version()) )
+import fixXreacs
+
+def makeModel():
+ # create container for model
+ num = 1 # number of compartments
+ model = moose.Neutral( '/model' )
+ compartment = moose.CylMesh( '/model/compartment' )
+ compartment.x1 = 1.0e-6 # Set it to a 1 micron single-voxel cylinder
+
+ # create molecules and reactions
+ s = moose.Pool( '/model/compartment/s' )
+ rXfer = moose.Reac( '/model/compartment/rXfer' )
+ #####################################################################
+ # Put in endo compartment. Add molecule s
+ endo = moose.EndoMesh( '/model/endo' )
+ # Note that the chanPool must be on the 'In' compartment.
+ #chanPool = moose.Pool( '/model/compartment/chanPool' )
+ #chan = moose.ConcChan( '/model/compartment/chanPool/chan' )
+ chanPool = moose.Pool( '/model/endo/chanPool' )
+ chan = moose.ConcChan( '/model/endo/chanPool/chan' )
+ endo.isMembraneBound = True
+ endo.surround = compartment
+ es = moose.Pool( '/model/endo/s' )
+ #####################################################################
+ moose.connect( rXfer, 'sub', s, 'reac' )
+ moose.connect( rXfer, 'prd', es, 'reac' )
+ moose.connect( chanPool, 'nOut', chan, 'setNumChan' )
+ moose.connect( chan, 'out', s, 'reac' )
+ moose.connect( chan, 'in', es, 'reac' )
+ volRatio = compartment.volume / endo.volume
+ rXfer.Kf = 0.0 # 0.02/sec
+ rXfer.Kb = 0.0 #
+ s.concInit = 0.001
+ chanPool.nInit = 1000.0
+ # Flux (#/s) = permeability * N * (#out/vol_out - #in/vol_in)
+ chan.permeability = 0.1 * chanPool.volume / chanPool.nInit
+
+ #####################################################################
+ fixXreacs.fixXreacs( '/model' )
+ #fixXreacs.restoreXreacs( '/model' )
+ #fixXreacs.fixXreacs( '/model' )
+ #####################################################################
+
+ # Make solvers
+ ksolve = moose.Ksolve( '/model/compartment/ksolve' )
+ dsolve = moose.Dsolve( '/model/dsolve' )
+ eksolve = moose.Ksolve( '/model/endo/ksolve' )
+ eksolve.method = 'gsl'
+ edsolve = moose.Dsolve( '/model/endo/dsolve' )
+
+ stoich = moose.Stoich( '/model/compartment/stoich' )
+ stoich.compartment = compartment
+ stoich.ksolve = ksolve
+ stoich.dsolve = dsolve
+ stoich.path = "/model/compartment/##"
+ assert( dsolve.numPools == 2 )
+
+ estoich = moose.Stoich( '/model/endo/stoich' )
+ estoich.compartment = endo
+ estoich.ksolve = eksolve
+ estoich.dsolve = edsolve
+ estoich.path = "/model/endo/##"
+ assert( edsolve.numPools == 2 )
+
+ edsolve.buildMeshJunctions( dsolve )
+
+ plot1 = moose.Table2( '/model/plot1' )
+ plot2 = moose.Table2( '/model/plot2' )
+ plot3 = moose.Table2( '/model/plot3' )
+ moose.connect( '/model/plot1', 'requestOut', s, 'getN' )
+ moose.connect( '/model/plot2', 'requestOut', es, 'getN' )
+ moose.connect( '/model/plot3', 'requestOut', '/model/compartment/s_xfer_endo', 'getN' )
+ plot4 = moose.Table2( '/model/plot4' )
+ plot5 = moose.Table2( '/model/plot5' )
+ plot6 = moose.Table2( '/model/plot6' )
+ moose.connect( '/model/plot4', 'requestOut', s, 'getConc' )
+ moose.connect( '/model/plot5', 'requestOut', es, 'getConc' )
+ moose.connect( '/model/plot6', 'requestOut', '/model/compartment/s_xfer_endo', 'getConc' )
+
+def doPlot( ax, i, label ):
+ scale = 1
+ if i > 3:
+ scale = 1000 # Just to plot in uM.
+ plot1 = '/model/plot' + str(i)
+ plot2 = '/model/plot' + str(i+1)
+ plot3 = '/model/plot' + str(i+2)
+ plt.ylabel( label )
+ plt.xlabel( 'time(s)' )
+ v1 = moose.element(plot1).vector * scale
+ v2 = moose.element(plot2).vector * scale
+ v3 = moose.element(plot3).vector * scale
+ ax.plot( v1, label='s' )
+ ax.plot( v2, 'x',label='es' )
+ ax.plot( v3, label='xfer' )
+ ax.plot( np.array( v1 ) + np.array( v2 ), label='sum' )
+ plt.legend()
+
+
+def almostEq( a, b ):
+ #print a, b, (a-b)/(a+b)
+ return abs(a-b)/(a+b) < 5e-5
+
+def main( standalone = False ):
+ runtime = 100
+ displayInterval = 2
+ makeModel()
+ for i in range( 10, 18 ):
+ moose.setClock( i, 0.01 )
+ moose.reinit()
+ moose.start( runtime )
+ s = moose.element( '/model/compartment/s' )
+ es = moose.element( '/model/endo/s' )
+ assert almostEq( s.conc, es.conc ), 'Asserting %g=%g' % (s.conc, es.conc)
+ # We go for concEndo = 2x concOut. Then
+ # We already know volIn = volOut/8
+ # #in/volIn = 2x #out/volOut
+ # #in/volIn = 2x #out/(8*volIn)
+ # so #in = #out/4
+ # From consv, #in + #out = nInit
+ # so 5/4#out = nInit =>
+ # #out = 0.8*nInit; #in = 0.2*nInit
+ #
+ # flux = perm * nChan * (0.8nInit/volOut - 0.2nInit/(volOut/8) ) =
+ # perm * (nChan*nInit/volOut) * (0.8 - 0.2*8) =
+ # perm * (nChan*nInit/volOut) * (-0.8)
+ #
+ # This has to be balanced by flux = numKf * nOut = numKf * 0.8 * nInit
+ # So 0.8*numKf*nInit = 0.8*perm*nChan*nInit/volOut
+
+ # Note that chan.permeability = 0.1*chanPool.volume / chanPool.nInit
+
+ # so numKf = perm*nChan/volOut = (0.1*volIn/nChan)*nChan/volOut=0.1/8
+ #
+ rXfer = moose.element( '/model/compartment/rXfer' )
+ rXfer.numKf = 0.1/8.0
+ moose.start( runtime )
+ assert( almostEq( 2 * s.conc, es.conc ) )
+
+ if standalone:
+ fig = plt.figure( figsize=(12,10) )
+ ax1 = fig.add_subplot(211)
+ doPlot( ax1, 1, '# of molecules' )
+ ax2 = fig.add_subplot(212)
+ doPlot( ax2, 4, 'conc (uM)' )
+ plt.show()
+ moose.delete( '/model' )
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+ main( standalone = True )
diff --git a/tests/python/testXdiff1.py b/tests/python/testXdiff1.py
new file mode 100644
index 0000000000000000000000000000000000000000..bbf73e8715f99c14b74d6dc4b638a61798370213
--- /dev/null
+++ b/tests/python/testXdiff1.py
@@ -0,0 +1,174 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+## This program is part of 'MOOSE', the
+## Messaging Object Oriented Simulation Environment.
+## Copyright (C) 2014 Upinder S. Bhalla. and NCBS
+## It is made available under the terms of the
+## GNU Lesser General Public License version 2.1
+## See the file COPYING.LIB for the full notice.
+## Here test diffusion across a junction. We set up a pump and change its
+## rate to do a check on the calculation of the diffusion rate separate
+## from the verification that diffusion gives equal concs on either side.
+## The system is a ## 1-voxel cyl compt and an internal endoMesh,
+## having a volume = 1/8 of the parent cylinder..
+## \
+## COMPT: s ----> / s :ENDO
+## s =diffn= s
+## \
+##
+## This becomes:
+## \
+## COMPT: s ----> s_xfer_endo / s :ENDO
+# s =diffn= s
+## \
+##
+#########################################################################
+
+
+import math
+import numpy as np
+import matplotlib.pyplot as plt
+import matplotlib.image as mpimg
+import moose
+import fixXreacs
+
+diffConst = 1e-16
+
+def makeModel():
+ # create container for model
+ num = 1 # number of compartments
+ model = moose.Neutral( '/model' )
+ compartment = moose.CylMesh( '/model/compartment' )
+ compartment.x1 = 1.0e-6 # Set it to a 1 micron single-voxel cylinder
+
+ # create molecules and reactions
+ s = moose.Pool( '/model/compartment/s' )
+ rXfer = moose.Reac( '/model/compartment/rXfer' )
+ #####################################################################
+ # Put in endo compartment. Add molecule s
+ endo = moose.EndoMesh( '/model/endo' )
+ endo.isMembraneBound = False
+ endo.surround = compartment
+ es = moose.Pool( '/model/endo/s' )
+ #####################################################################
+ moose.connect( rXfer, 'sub', s, 'reac' )
+ moose.connect( rXfer, 'prd', es, 'reac' )
+ volRatio = compartment.volume / endo.volume
+ #print( "Volume ratio = {}".format( volRatio ) )
+ rXfer.Kf = 0.0 # 0.02/sec
+ rXfer.Kb = 0.0 #
+ s.concInit = 0.001
+ s.diffConst = diffConst
+ es.diffConst = diffConst
+
+ #####################################################################
+ fixXreacs.fixXreacs( '/model' )
+ #fixXreacs.restoreXreacs( '/model' )
+ #fixXreacs.fixXreacs( '/model' )
+ #####################################################################
+
+ # Make solvers
+ ksolve = moose.Ksolve( '/model/compartment/ksolve' )
+ dsolve = moose.Dsolve( '/model/dsolve' )
+ eksolve = moose.Ksolve( '/model/endo/ksolve' )
+ edsolve = moose.Dsolve( '/model/endo/dsolve' )
+
+ stoich = moose.Stoich( '/model/compartment/stoich' )
+ stoich.compartment = compartment
+ stoich.ksolve = ksolve
+ stoich.dsolve = dsolve
+ stoich.path = "/model/compartment/##"
+ assert( dsolve.numPools == 2 )
+
+ estoich = moose.Stoich( '/model/endo/stoich' )
+ estoich.compartment = endo
+ estoich.ksolve = eksolve
+ estoich.dsolve = edsolve
+ estoich.path = "/model/endo/##"
+ assert( edsolve.numPools == 1 )
+
+ edsolve.buildMeshJunctions( dsolve )
+
+ plot1 = moose.Table2( '/model/plot1' )
+ plot2 = moose.Table2( '/model/plot2' )
+ plot3 = moose.Table2( '/model/plot3' )
+ moose.connect( '/model/plot1', 'requestOut', s, 'getN' )
+ moose.connect( '/model/plot2', 'requestOut', es, 'getN' )
+ moose.connect( '/model/plot3', 'requestOut', '/model/compartment/s_xfer_endo', 'getN' )
+ plot4 = moose.Table2( '/model/plot4' )
+ plot5 = moose.Table2( '/model/plot5' )
+ plot6 = moose.Table2( '/model/plot6' )
+ moose.connect( '/model/plot4', 'requestOut', s, 'getConc' )
+ moose.connect( '/model/plot5', 'requestOut', es, 'getConc' )
+ moose.connect( '/model/plot6', 'requestOut', '/model/compartment/s_xfer_endo', 'getConc' )
+
+def doPlot( ax, i, label ):
+ scale = 1
+ if i > 3:
+ scale = 1000 # Just to plot in uM.
+ plot1 = '/model/plot' + str(i)
+ plot2 = '/model/plot' + str(i+1)
+ plot3 = '/model/plot' + str(i+2)
+ plt.ylabel( label )
+ plt.xlabel( 'time(s)' )
+ v1 = moose.element(plot1).vector * scale
+ v2 = moose.element(plot2).vector * scale
+ v3 = moose.element(plot3).vector * scale
+ ax.plot( v1, label='s' )
+ ax.plot( v2, 'x',label='es' )
+ ax.plot( v3, label='xfer' )
+ ax.plot( np.array( v1 ) + np.array( v2 ), label='sum' )
+ plt.legend()
+
+
+def almostEq( a, b ):
+ #print a, b, (a-b)/(a+b)
+ return abs(a-b)/(a+b) < 5e-5
+
+def main( standalone = False ):
+ runtime = 100
+ makeModel()
+ for i in range( 10, 18 ):
+ moose.setClock( i, 0.01 )
+ moose.reinit()
+ moose.start( runtime )
+ s = moose.element( '/model/compartment/s' )
+ es = moose.element( '/model/endo/s' )
+ assert( almostEq( s.conc, es.conc ) )
+ # We go for concEndo = 2x concOut. Then
+ # We already know volIn = volOut/8
+ # #in/volIn = 2x #out/volOut
+ # #in/volIn = 2x #out/(8*volIn)
+ # so #in = #out/4
+ # From consv, #in + #out = nInit
+ # so 5/4#out = nInit =>
+ # #out = 0.8*nInit; #in = 0.2*nInit
+ #
+ # Diffn flux = D * (xa/L) * (0.8nInit/volOut - 0.2nInit/(volOut/8) )
+ # = -D * (xa/L) * (nInit/volOut) * 0.8
+ # We can obtain xa and L from the endo/mesh
+ #
+ # This has to be balanced by flux = numKf * nOut = numKf * 0.8 * nInit
+ # So 0.8*numKf*nInit = 0.8*(D.Xa/L)*(nInit/volOut)
+ # So numKf = D.Xa/(L*volOut)
+ #
+ rXfer = moose.element( '/model/compartment/rXfer' )
+ endo = moose.element( '/model/endo' )
+ compt = moose.element( '/model/compartment' )
+ endoA = endo.aScale * pow( compt.volume, endo.aPower )
+ rXfer.numKf = 2.0*diffConst*endoA/(compt.r0*compt.volume)
+ moose.start( runtime )
+ assert( almostEq( 2 * s.conc, es.conc ) )
+
+ if standalone:
+ fig = plt.figure( figsize=(12,10) )
+ ax1 = fig.add_subplot(211)
+ doPlot( ax1, 1, '# of molecules' )
+ ax2 = fig.add_subplot(212)
+ doPlot( ax2, 4, 'conc (uM)' )
+ plt.show()
+ moose.delete( '/model' )
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+ main( standalone = True )
diff --git a/tests/python/testXenz1.py b/tests/python/testXenz1.py
new file mode 100644
index 0000000000000000000000000000000000000000..b359d44ebfc17abf0928ccff18e1e01964671ebf
--- /dev/null
+++ b/tests/python/testXenz1.py
@@ -0,0 +1,137 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+## This program is part of 'MOOSE', the
+## Messaging Object Oriented Simulation Environment.
+## Copyright (C) 2014 Upinder S. Bhalla. and NCBS
+## It is made available under the terms of the
+## GNU Lesser General Public License version 2.1
+## See the file COPYING.LIB for the full notice.
+##
+## Endo / Compartment
+## \
+## sub--enz-/-----> prd
+## sub<-----\----- prd
+## /
+#########################################################################
+
+
+import math
+import numpy as np
+import matplotlib.pyplot as plt
+import matplotlib.image as mpimg
+import moose
+import fixXreacs
+
+subInit = 0.002
+eInit = 0.001
+Km = 0.001
+kcat = 0.2
+Kf = 0.1
+
+def makeModel():
+ # create container for model
+ num = 1 # number of compartments
+ model = moose.Neutral( '/model' )
+ compartment = moose.CylMesh( '/model/compartment' )
+ compartment.x1 = 1.0e-6 # Set it to a 1 micron single-voxel cylinder
+
+ # create molecules and reactions
+ prd = moose.Pool( '/model/compartment/prd' )
+ rXfer = moose.Reac( '/model/compartment/rXfer' )
+ #####################################################################
+ # Put in endo compartment. Add molecule s
+ endo = moose.EndoMesh( '/model/endo' )
+ endo.isMembraneBound = True
+ endo.surround = compartment
+ sub = moose.Pool( '/model/endo/sub' )
+ enzPool = moose.Pool( '/model/endo/enzPool' )
+ enzPool.concInit = eInit
+ enz = moose.MMenz( '/model/endo/enzPool/enz' )
+ #####################################################################
+ moose.connect( enz, 'sub', sub, 'reac' )
+ moose.connect( enz, 'prd', prd, 'reac' )
+ moose.connect( enzPool, 'nOut', enz, 'enzDest' )
+ moose.connect( rXfer, 'sub', prd, 'reac' )
+ moose.connect( rXfer, 'prd', sub, 'reac' )
+ rXfer.Kf = Kf # 0.04/sec
+ rXfer.Kb = 0.0 # 0.02/sec
+ enz.Km = Km
+ enz.kcat = kcat
+ # v = es.kcat/(s+Km)
+ # v = Kf * conc.
+ #####################################################################
+ fixXreacs.fixXreacs( '/model' )
+ fixXreacs.restoreXreacs( '/model' )
+ fixXreacs.fixXreacs( '/model' )
+ #####################################################################
+
+ # Make solvers
+ ksolve = moose.Ksolve( '/model/compartment/ksolve' )
+ dsolve = moose.Dsolve( '/model/dsolve' )
+ eksolve = moose.Ksolve( '/model/endo/ksolve' )
+ edsolve = moose.Dsolve( '/model/endo/dsolve' )
+
+ stoich = moose.Stoich( '/model/compartment/stoich' )
+ stoich.compartment = compartment
+ stoich.ksolve = ksolve
+ stoich.dsolve = dsolve
+ stoich.path = "/model/compartment/##"
+ assert( dsolve.numPools == 2 )
+ sub.vec.concInit = subInit
+ enzPool.vec.concInit = eInit
+
+ estoich = moose.Stoich( '/model/endo/stoich' )
+ estoich.compartment = endo
+ estoich.ksolve = eksolve
+ estoich.dsolve = edsolve
+ estoich.path = "/model/endo/##"
+ assert( edsolve.numPools == 3 )
+
+ edsolve.buildMeshJunctions( dsolve )
+
+ plot1 = moose.Table2( '/model/plot1' )
+ plot2 = moose.Table2( '/model/plot2' )
+ moose.connect( '/model/plot1', 'requestOut', sub, 'getN' )
+ moose.connect( '/model/plot2', 'requestOut', prd, 'getN' )
+ plot3 = moose.Table2( '/model/plot3' )
+ plot4 = moose.Table2( '/model/plot4' )
+ moose.connect( '/model/plot3', 'requestOut', sub, 'getConc' )
+ moose.connect( '/model/plot4', 'requestOut', prd, 'getConc' )
+
+def doPlot( ax, plot1, plot2, label ):
+ plt.ylabel( label )
+ plt.xlabel( 'time(s)' )
+ v1 = moose.element(plot1).vector
+ v2 = moose.element(plot2).vector
+ ax.plot( v1, label='sub' )
+ ax.plot( v2, label='prd' )
+ ax.plot( np.array( v1 ) + np.array( v2 ), label='sum' )
+ plt.legend()
+
+def almostEq( a, b ):
+ #print a, b, (a-b)/(a+b)
+ return abs(a-b)/(a+b) < 5e-5
+
+def main( standalone = False ):
+ for i in range( 10, 18 ):
+ moose.setClock( i, 0.001 )
+ runtime = 100
+ displayInterval = 2
+ makeModel()
+ moose.reinit()
+ moose.start( runtime )
+ assert( almostEq( moose.element( 'model/compartment/prd' ).n,
+ moose.element( '/model/endo/sub' ).n ) )
+
+ if standalone:
+ fig = plt.figure( figsize=(12,10) )
+ ax1 = fig.add_subplot(211)
+ doPlot( ax1, '/model/plot1', '/model/plot2', '# of molecules' )
+ ax2 = fig.add_subplot(212)
+ doPlot( ax2, '/model/plot3', '/model/plot4', 'conc (mM)' )
+ plt.show()
+ moose.delete( '/model' )
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+ main( standalone = True )
diff --git a/tests/python/testXreacs2.py b/tests/python/testXreacs2.py
new file mode 100644
index 0000000000000000000000000000000000000000..289c2b24670437c9197d05d7fdcf9a8b3f87264a
--- /dev/null
+++ b/tests/python/testXreacs2.py
@@ -0,0 +1,61 @@
+# -*- coding: utf-8 -*-
+import os
+import matplotlib as mpl
+import matplotlib.pyplot as plt
+mpl.rcParams['text.usetex'] = False
+import moose
+import numpy as np
+import fixXreacs
+
+def countCrossings( plot, thresh ):
+ vec = moose.element( plot ).vector
+ #print (vec[:-1] < thresh)
+ return sum( (vec[:-1] < thresh) * (vec[1:] >= thresh ) )
+
+def main( standalone = False ):
+ mfile = os.path.join( os.path.dirname( __file__), 'OSC_diff_vols.g' )
+ runtime = 4000.0
+ modelId = moose.loadModel( mfile, 'model', 'ee' )
+ kin = moose.element( '/model/kinetics' )
+ compt1 = moose.element( '/model/compartment_1' )
+ compt1.x1 += kin.x1
+ compt1.x0 += kin.x1
+ fixXreacs.fixXreacs( '/model' )
+ #fixXreacs.restoreXreacs( '/model' )
+ #fixXreacs.fixXreacs( '/model' )
+
+ ks1 = moose.Ksolve( '/model/kinetics/ksolve' )
+ ds1 = moose.Dsolve( '/model/kinetics/dsolve' )
+ s1 = moose.Stoich( '/model/kinetics/stoich' )
+ s1.compartment = moose.element( '/model/kinetics' )
+ s1.ksolve = ks1
+ s1.dsolve = ds1
+ s1.path = '/model/kinetics/##'
+
+ ks2 = moose.Ksolve( '/model/compartment_1/ksolve' )
+ ds2 = moose.Dsolve( '/model/compartment_1/dsolve' )
+ s2 = moose.Stoich( '/model/compartment_1/stoich' )
+ s2.compartment = moose.element( '/model/compartment_1' )
+ s2.ksolve = ks2
+ s2.dsolve = ds2
+ s2.path = '/model/compartment_1/##'
+
+ ds2.buildMeshJunctions( ds1 )
+
+ moose.reinit()
+ moose.start( runtime )
+ # I don't have an analytic way to assess oscillations
+ assert( countCrossings( '/model/graphs/conc2/M.Co', 0.001 ) == 4 )
+
+ if standalone:
+ # Display all plots.
+ for x in moose.wildcardFind( '/model/#graphs/conc#/#' ):
+ t = np.arange( 0, x.vector.size, 1 ) * x.dt
+ plt.plot( t, x.vector, label=x.name )
+ plt.legend()
+ plt.show()
+ moose.delete( '/model' )
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+ main( standalone = True )
diff --git a/tests/python/testXreacs3.py b/tests/python/testXreacs3.py
new file mode 100644
index 0000000000000000000000000000000000000000..4e5ef170d23a2acf315fff969eab69f63bc1f999
--- /dev/null
+++ b/tests/python/testXreacs3.py
@@ -0,0 +1,132 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+## This program is part of 'MOOSE', the
+## Messaging Object Oriented Simulation Environment.
+## Copyright (C) 2014 Upinder S. Bhalla. and NCBS
+## It is made available under the terms of the
+## GNU Lesser General Public License version 2.1
+## See the file COPYING.LIB for the full notice.
+## Here we set up equal Kf and Kb in a reversible reaction across a
+## 1-voxel cyl compt and an internal endoMesh, having a smaller volume.
+## \
+## COMPT: s <===> / s :ENDO
+## \
+##
+## This becomes:
+## \
+## COMPT: s <===> s_xfer_endo / s :ENDO
+## \
+##
+#########################################################################
+
+
+import math
+import numpy as np
+import matplotlib.pyplot as plt
+import matplotlib.image as mpimg
+import moose
+import fixXreacs
+
+def makeModel():
+ # create container for model
+ num = 1 # number of compartments
+ model = moose.Neutral( '/model' )
+ compartment = moose.CylMesh( '/model/compartment' )
+ compartment.x1 = 1.0e-6 # Set it to a 1 micron single-voxel cylinder
+
+ # create molecules and reactions
+ s = moose.Pool( '/model/compartment/s' )
+ rXfer = moose.Reac( '/model/compartment/rXfer' )
+ #####################################################################
+ # Put in endo compartment. Add molecule s
+ endo = moose.EndoMesh( '/model/endo' )
+ endo.isMembraneBound = True
+ endo.surround = compartment
+ es = moose.Pool( '/model/endo/s' )
+ #####################################################################
+ moose.connect( rXfer, 'sub', s, 'reac' )
+ moose.connect( rXfer, 'prd', es, 'reac' )
+ volRatio = compartment.volume / endo.volume
+ rXfer.Kf = 0.02 # 0.01/sec
+ rXfer.Kb = 0.02 # 1/sec
+
+ #####################################################################
+ fixXreacs.fixXreacs( '/model' )
+ fixXreacs.restoreXreacs( '/model' )
+ fixXreacs.fixXreacs( '/model' )
+ #####################################################################
+
+ # Make solvers
+ ksolve = moose.Ksolve( '/model/compartment/ksolve' )
+ dsolve = moose.Dsolve( '/model/dsolve' )
+ eksolve = moose.Ksolve( '/model/endo/ksolve' )
+ edsolve = moose.Dsolve( '/model/endo/dsolve' )
+
+ stoich = moose.Stoich( '/model/compartment/stoich' )
+ stoich.compartment = compartment
+ stoich.ksolve = ksolve
+ stoich.dsolve = dsolve
+ stoich.path = "/model/compartment/##"
+ assert( dsolve.numPools == 2 )
+ s.vec.concInit = [1]*num
+
+ estoich = moose.Stoich( '/model/endo/stoich' )
+ estoich.compartment = endo
+ estoich.ksolve = eksolve
+ estoich.dsolve = edsolve
+ estoich.path = "/model/endo/##"
+ assert( edsolve.numPools == 1 )
+
+ edsolve.buildMeshJunctions( dsolve )
+
+ plot1 = moose.Table2( '/model/plot1' )
+ plot2 = moose.Table2( '/model/plot2' )
+ plot3 = moose.Table2( '/model/plot3' )
+ moose.connect( '/model/plot1', 'requestOut', s, 'getN' )
+ moose.connect( '/model/plot2', 'requestOut', es, 'getN' )
+ moose.connect( '/model/plot3', 'requestOut', '/model/compartment/s_xfer_endo', 'getN' )
+ plot4 = moose.Table2( '/model/plot4' )
+ plot5 = moose.Table2( '/model/plot5' )
+ plot6 = moose.Table2( '/model/plot6' )
+ moose.connect( '/model/plot4', 'requestOut', s, 'getConc' )
+ moose.connect( '/model/plot5', 'requestOut', es, 'getConc' )
+ moose.connect( '/model/plot6', 'requestOut', '/model/compartment/s_xfer_endo', 'getConc' )
+
+def doPlot( ax, i, label ):
+ plot1 = '/model/plot' + str(i)
+ plot2 = '/model/plot' + str(i+1)
+ plot3 = '/model/plot' + str(i+2)
+ plt.ylabel( label )
+ plt.xlabel( 'time(s)' )
+ v1 = moose.element(plot1).vector
+ v2 = moose.element(plot2).vector
+ v3 = moose.element(plot3).vector
+ ax.plot( v1, label='s' )
+ ax.plot( v2, 'x',label='es' )
+ ax.plot( v3, label='xfer' )
+ ax.plot( np.array( v1 ) + np.array( v2 ), label='sum' )
+ plt.legend()
+
+def almostEq( a, b ):
+ return abs(a-b)/(a+b) < 5e-5
+
+def main( standalone = False ):
+ runtime = 100
+ makeModel()
+ moose.reinit()
+ moose.start( runtime )
+ assert( almostEq( moose.element( 'model/compartment/s' ).conc,
+ moose.element( '/model/endo/s' ).conc ) )
+
+ if standalone:
+ fig = plt.figure( figsize=(12,10) )
+ ax1 = fig.add_subplot(211)
+ doPlot( ax1, 1, '# of molecules' )
+ ax2 = fig.add_subplot(212)
+ doPlot( ax2, 4, 'conc (mM)' )
+ plt.show()
+ moose.delete( '/model' )
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+ main( standalone = True )
diff --git a/tests/python/testXreacs4.py b/tests/python/testXreacs4.py
new file mode 100644
index 0000000000000000000000000000000000000000..4fd440076aede4ec9f14e60f8f7dbb8b8e0c8ee2
--- /dev/null
+++ b/tests/python/testXreacs4.py
@@ -0,0 +1,114 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+## This program is part of 'MOOSE', the
+## Messaging Object Oriented Simulation Environment.
+## Copyright (C) 2014 Upinder S. Bhalla. and NCBS
+## It is made available under the terms of the
+## GNU Lesser General Public License version 2.1
+## See the file COPYING.LIB for the full notice.
+#########################################################################
+
+
+import math
+import numpy as np
+import matplotlib.pyplot as plt
+import matplotlib.image as mpimg
+import moose
+import fixXreacs
+
+def makeModel():
+ # create container for model
+ num = 1 # number of compartments
+ model = moose.Neutral( '/model' )
+ compartment = moose.CylMesh( '/model/compartment' )
+ compartment.x1 = 1.0e-6 # Set it to a 1 micron single-voxel cylinder
+
+ # create molecules and reactions
+ s = moose.Pool( '/model/compartment/s' )
+ rXfer = moose.Reac( '/model/compartment/rXfer' )
+ #####################################################################
+ # Put in endo compartment. Add molecule s
+ endo = moose.EndoMesh( '/model/endo' )
+ endo.isMembraneBound = True
+ endo.surround = compartment
+ es = moose.Pool( '/model/endo/s' )
+ #####################################################################
+ moose.connect( rXfer, 'sub', s, 'reac' )
+ moose.connect( rXfer, 'prd', es, 'reac' )
+ volRatio = compartment.volume / endo.volume
+ rXfer.Kf = 0.04 # 0.04/sec
+ rXfer.Kb = 0.02 # 0.02/sec
+
+ #####################################################################
+ fixXreacs.fixXreacs( '/model' )
+ #fixXreacs.restoreXreacs( '/model' )
+ #fixXreacs.fixXreacs( '/model' )
+ #####################################################################
+
+ # Make solvers
+ ksolve = moose.Ksolve( '/model/compartment/ksolve' )
+ dsolve = moose.Dsolve( '/model/dsolve' )
+ eksolve = moose.Ksolve( '/model/endo/ksolve' )
+ edsolve = moose.Dsolve( '/model/endo/dsolve' )
+
+ stoich = moose.Stoich( '/model/compartment/stoich' )
+ stoich.compartment = compartment
+ stoich.ksolve = ksolve
+ stoich.dsolve = dsolve
+ stoich.path = "/model/compartment/##"
+ assert( dsolve.numPools == 2 )
+ s.vec.concInit = [1]*num
+
+ estoich = moose.Stoich( '/model/endo/stoich' )
+ estoich.compartment = endo
+ estoich.ksolve = eksolve
+ estoich.dsolve = edsolve
+ estoich.path = "/model/endo/##"
+ assert( edsolve.numPools == 1 )
+
+ edsolve.buildMeshJunctions( dsolve )
+
+ plot1 = moose.Table2( '/model/plot1' )
+ plot2 = moose.Table2( '/model/plot2' )
+ moose.connect( '/model/plot1', 'requestOut', s, 'getN' )
+ moose.connect( '/model/plot2', 'requestOut', es, 'getN' )
+ plot3 = moose.Table2( '/model/plot3' )
+ plot4 = moose.Table2( '/model/plot4' )
+ moose.connect( '/model/plot3', 'requestOut', s, 'getConc' )
+ moose.connect( '/model/plot4', 'requestOut', es, 'getConc' )
+
+def doPlot( ax, plot1, plot2, label ):
+ plt.ylabel( label )
+ plt.xlabel( 'time(s)' )
+ v1 = moose.element(plot1).vector
+ v2 = moose.element(plot2).vector
+ ax.plot( v1, label='s' )
+ ax.plot( v2, label='es' )
+ ax.plot( np.array( v1 ) + np.array( v2 ), label='sum' )
+ plt.legend()
+
+def almostEq( a, b ):
+ return abs(a-b)/(a+b) < 5e-5
+
+def main( standalone = False ):
+ runtime = 100
+ displayInterval = 2
+ makeModel()
+ moose.reinit()
+ moose.start( runtime )
+ assert( almostEq( 2.0 * moose.element( 'model/compartment/s' ).conc,
+ moose.element( '/model/endo/s' ).conc ) )
+
+ if standalone:
+ fig = plt.figure( figsize=(12,10) )
+ ax1 = fig.add_subplot(211)
+ doPlot( ax1, '/model/plot1', '/model/plot2', '# of molecules' )
+ ax2 = fig.add_subplot(212)
+ doPlot( ax2, '/model/plot3', '/model/plot4', 'conc (mM)' )
+ plt.show()
+
+ moose.delete( '/model' )
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+ main( standalone = True )
diff --git a/tests/python/testXreacs4a.py b/tests/python/testXreacs4a.py
new file mode 100644
index 0000000000000000000000000000000000000000..2fe009e9e67759f3cebb95152b2da48052ebed8e
--- /dev/null
+++ b/tests/python/testXreacs4a.py
@@ -0,0 +1,114 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+## This program is part of 'MOOSE', the
+## Messaging Object Oriented Simulation Environment.
+## Copyright (C) 2014 Upinder S. Bhalla. and NCBS
+## It is made available under the terms of the
+## GNU Lesser General Public License version 2.1
+## See the file COPYING.LIB for the full notice.
+#########################################################################
+
+
+import math
+import numpy as np
+import matplotlib.pyplot as plt
+import matplotlib.image as mpimg
+import moose
+import fixXreacs
+
+def makeModel():
+ # create container for model
+ num = 1 # number of compartments
+ model = moose.Neutral( '/model' )
+ compartment = moose.CylMesh( '/model/compartment' )
+ compartment.x1 = 1.0e-6 # Set it to a 1 micron single-voxel cylinder
+
+ # create molecules and reactions
+ s = moose.Pool( '/model/compartment/s' )
+ #####################################################################
+ # Put in endo compartment. Add molecule s
+ endo = moose.EndoMesh( '/model/endo' )
+ endo.isMembraneBound = True
+ endo.surround = compartment
+ es = moose.Pool( '/model/endo/s' )
+ rXfer = moose.Reac( '/model/endo/rXfer' )
+ #####################################################################
+ moose.connect( rXfer, 'sub', s, 'reac' )
+ moose.connect( rXfer, 'prd', es, 'reac' )
+ volRatio = compartment.volume / endo.volume
+ rXfer.Kf = 0.04 # 0.04/sec
+ rXfer.Kb = 0.02 # 0.02/sec
+
+ #####################################################################
+ fixXreacs.fixXreacs( '/model' )
+ #fixXreacs.restoreXreacs( '/model' )
+ #fixXreacs.fixXreacs( '/model' )
+ #####################################################################
+
+ # Make solvers
+ ksolve = moose.Ksolve( '/model/compartment/ksolve' )
+ dsolve = moose.Dsolve( '/model/dsolve' )
+ eksolve = moose.Ksolve( '/model/endo/ksolve' )
+ edsolve = moose.Dsolve( '/model/endo/dsolve' )
+
+ stoich = moose.Stoich( '/model/compartment/stoich' )
+ stoich.compartment = compartment
+ stoich.ksolve = ksolve
+ stoich.dsolve = dsolve
+ stoich.path = "/model/compartment/##"
+ assert( dsolve.numPools == 1 )
+ s.vec.concInit = [1]*num
+
+ estoich = moose.Stoich( '/model/endo/stoich' )
+ estoich.compartment = endo
+ estoich.ksolve = eksolve
+ estoich.dsolve = edsolve
+ estoich.path = "/model/endo/##"
+ assert( edsolve.numPools == 2 )
+
+ edsolve.buildMeshJunctions( dsolve )
+
+ plot1 = moose.Table2( '/model/plot1' )
+ plot2 = moose.Table2( '/model/plot2' )
+ moose.connect( '/model/plot1', 'requestOut', s, 'getN' )
+ moose.connect( '/model/plot2', 'requestOut', es, 'getN' )
+ plot3 = moose.Table2( '/model/plot3' )
+ plot4 = moose.Table2( '/model/plot4' )
+ moose.connect( '/model/plot3', 'requestOut', s, 'getConc' )
+ moose.connect( '/model/plot4', 'requestOut', es, 'getConc' )
+
+def doPlot( ax, plot1, plot2, label ):
+ plt.ylabel( label )
+ plt.xlabel( 'time(s)' )
+ v1 = moose.element(plot1).vector
+ v2 = moose.element(plot2).vector
+ ax.plot( v1, label='s' )
+ ax.plot( v2, label='es' )
+ ax.plot( np.array( v1 ) + np.array( v2 ), label='sum' )
+ plt.legend()
+
+def almostEq( a, b ):
+ return abs(a-b)/(a+b) < 5e-5
+
+def main( standalone = False ):
+ runtime = 200
+ displayInterval = 2
+ makeModel()
+ moose.reinit()
+ moose.start( runtime )
+ assert( almostEq( 2.0 * moose.element( 'model/compartment/s' ).conc,
+ moose.element( '/model/endo/s' ).conc ) )
+
+ if standalone:
+ fig = plt.figure( figsize=(12,10) )
+ ax1 = fig.add_subplot(211)
+ doPlot( ax1, '/model/plot1', '/model/plot2', '# of molecules' )
+ ax2 = fig.add_subplot(212)
+ doPlot( ax2, '/model/plot3', '/model/plot4', 'conc (mM)' )
+ plt.show()
+ moose.delete( '/model' )
+
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+ main( standalone = True )
diff --git a/tests/python/testXreacs5.py b/tests/python/testXreacs5.py
new file mode 100644
index 0000000000000000000000000000000000000000..e46bc45906757f85b060b427a84856a57ed24244
--- /dev/null
+++ b/tests/python/testXreacs5.py
@@ -0,0 +1,120 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+## This program is part of 'MOOSE', the
+## Messaging Object Oriented Simulation Environment.
+## Copyright (C) 2014 Upinder S. Bhalla. and NCBS
+## It is made available under the terms of the
+## GNU Lesser General Public License version 2.1
+## See the file COPYING.LIB for the full notice.
+#########################################################################
+
+
+import math
+import numpy as np
+import matplotlib.pyplot as plt
+import matplotlib.image as mpimg
+import moose
+import fixXreacs
+
+def makeModel():
+ # create container for model
+ num = 1 # number of compartments
+ model = moose.Neutral( '/model' )
+ compartment = moose.CylMesh( '/model/compartment' )
+ compartment.x1 = 1.0e-6 # Set it to a 1 micron single-voxel cylinder
+
+ # create molecules and reactions
+ s = moose.Pool( '/model/compartment/s' )
+ rXfer = moose.Reac( '/model/compartment/rXfer' )
+ #####################################################################
+ # Put in endo compartment. Add molecule s
+ endo = moose.EndoMesh( '/model/endo' )
+ endo.isMembraneBound = True
+ endo.surround = compartment
+ es = moose.Pool( '/model/endo/s' )
+ erXfer = moose.Reac( '/model/endo/erXfer' )
+ #####################################################################
+ moose.connect( erXfer, 'sub', es, 'reac' )
+ moose.connect( erXfer, 'prd', s, 'reac' )
+ moose.connect( rXfer, 'sub', s, 'reac' )
+ moose.connect( rXfer, 'prd', es, 'reac' )
+ rXfer.Kf = 0.04 # 0.04/sec
+ rXfer.Kb = 0.0 # 0.00/sec
+ erXfer.Kf = 0.16 # 0.16/sec
+ erXfer.Kb = 0.0 # 0.00/sec
+
+ #####################################################################
+ fixXreacs.fixXreacs( '/model' )
+ fixXreacs.restoreXreacs( '/model' )
+ fixXreacs.fixXreacs( '/model' )
+ #####################################################################
+
+ # Make solvers
+ ksolve = moose.Ksolve( '/model/compartment/ksolve' )
+ dsolve = moose.Dsolve( '/model/dsolve' )
+ eksolve = moose.Ksolve( '/model/endo/ksolve' )
+ edsolve = moose.Dsolve( '/model/endo/dsolve' )
+
+ stoich = moose.Stoich( '/model/compartment/stoich' )
+ stoich.compartment = compartment
+ stoich.ksolve = ksolve
+ stoich.dsolve = dsolve
+ stoich.path = "/model/compartment/##"
+ assert( dsolve.numPools == 2 )
+ s.vec.concInit = [1]*num
+
+ estoich = moose.Stoich( '/model/endo/stoich' )
+ estoich.compartment = endo
+ estoich.ksolve = eksolve
+ estoich.dsolve = edsolve
+ estoich.path = "/model/endo/##"
+ assert( edsolve.numPools == 2 )
+
+ edsolve.buildMeshJunctions( dsolve )
+
+ plot1 = moose.Table2( '/model/plot1' )
+ plot2 = moose.Table2( '/model/plot2' )
+ moose.connect( '/model/plot1', 'requestOut', s, 'getN' )
+ moose.connect( '/model/plot2', 'requestOut', es, 'getN' )
+ plot3 = moose.Table2( '/model/plot3' )
+ plot4 = moose.Table2( '/model/plot4' )
+ moose.connect( '/model/plot3', 'requestOut', s, 'getConc' )
+ moose.connect( '/model/plot4', 'requestOut', es, 'getConc' )
+
+def doPlot( ax, plot1, plot2, label ):
+ plt.ylabel( label )
+ plt.xlabel( 'time(s)' )
+ v1 = moose.element(plot1).vector
+ v2 = moose.element(plot2).vector
+ ax.plot( v1, label='s' )
+ ax.plot( v2, label='es' )
+ ax.plot( np.array( v1 ) + np.array( v2 ), label='sum' )
+ plt.legend()
+
+def almostEq( a, b ):
+ #print a, b, (a-b)/(a+b)
+ return abs(a-b)/(a+b) < 5e-5
+
+def main( standalone = False ):
+ for i in range( 10, 18):
+ moose.setClock( i, 0.001 )
+ runtime = 100
+ makeModel()
+ moose.reinit()
+ moose.start( runtime )
+
+ assert( almostEq( 2.0 * moose.element( 'model/compartment/s' ).conc,
+ moose.element( '/model/endo/s' ).conc ) )
+
+ if standalone:
+ fig = plt.figure( figsize=(12,10) )
+ ax1 = fig.add_subplot(211)
+ doPlot( ax1, '/model/plot1', '/model/plot2', '# of molecules' )
+ ax2 = fig.add_subplot(212)
+ doPlot( ax2, '/model/plot3', '/model/plot4', 'conc (mM)' )
+ plt.show()
+ moose.delete( '/model' )
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+ main( standalone = True )
diff --git a/tests/python/testXreacs5a.py b/tests/python/testXreacs5a.py
new file mode 100644
index 0000000000000000000000000000000000000000..330419ea1cae499105e168c6324b2f9b318e2053
--- /dev/null
+++ b/tests/python/testXreacs5a.py
@@ -0,0 +1,120 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+## This program is part of 'MOOSE', the
+## Messaging Object Oriented Simulation Environment.
+## Copyright (C) 2014 Upinder S. Bhalla. and NCBS
+## It is made available under the terms of the
+## GNU Lesser General Public License version 2.1
+## See the file COPYING.LIB for the full notice.
+#########################################################################
+
+
+import math
+import numpy as np
+import matplotlib.pyplot as plt
+import matplotlib.image as mpimg
+import moose
+import fixXreacs
+
+def makeModel():
+ # create container for model
+ num = 1 # number of compartments
+ model = moose.Neutral( '/model' )
+ compartment = moose.CylMesh( '/model/compartment' )
+ compartment.x1 = 1.0e-6 # Set it to a 1 micron single-voxel cylinder
+
+ # create molecules and reactions
+ s = moose.Pool( '/model/compartment/s' )
+ rXfer = moose.Reac( '/model/compartment/rXfer' )
+ #####################################################################
+ # Put in endo compartment. Add molecule s
+ endo = moose.EndoMesh( '/model/endo' )
+ endo.isMembraneBound = True
+ endo.surround = compartment
+ es = moose.Pool( '/model/endo/s' )
+ erXfer = moose.Reac( '/model/compartment/erXfer' )
+ #####################################################################
+ moose.connect( erXfer, 'sub', es, 'reac' )
+ moose.connect( erXfer, 'prd', s, 'reac' )
+ moose.connect( rXfer, 'sub', s, 'reac' )
+ moose.connect( rXfer, 'prd', es, 'reac' )
+ rXfer.Kf = 0.04 # 0.04/sec
+ rXfer.Kb = 0.0 # 0.02/sec
+ erXfer.Kf = 0.02 # 0.04/sec
+ erXfer.Kb = 0.0 # 0.02/sec
+
+ #####################################################################
+ fixXreacs.fixXreacs( '/model' )
+ fixXreacs.restoreXreacs( '/model' )
+ fixXreacs.fixXreacs( '/model' )
+ #####################################################################
+ rx = moose.element( '/model/compartment/rXfer' )
+ erx = moose.element( '/model/compartment/erXfer' )
+
+ # Make solvers
+ ksolve = moose.Ksolve( '/model/compartment/ksolve' )
+ dsolve = moose.Dsolve( '/model/dsolve' )
+ eksolve = moose.Ksolve( '/model/endo/ksolve' )
+ edsolve = moose.Dsolve( '/model/endo/dsolve' )
+
+ stoich = moose.Stoich( '/model/compartment/stoich' )
+ stoich.compartment = compartment
+ stoich.ksolve = ksolve
+ stoich.dsolve = dsolve
+ stoich.path = "/model/compartment/##"
+ assert( dsolve.numPools == 2 )
+ s.vec.concInit = [1]*num
+
+ estoich = moose.Stoich( '/model/endo/stoich' )
+ estoich.compartment = endo
+ estoich.ksolve = eksolve
+ estoich.dsolve = edsolve
+ estoich.path = "/model/endo/##"
+ assert( edsolve.numPools == 1 )
+
+ edsolve.buildMeshJunctions( dsolve )
+
+ plot1 = moose.Table2( '/model/plot1' )
+ plot2 = moose.Table2( '/model/plot2' )
+ moose.connect( '/model/plot1', 'requestOut', s, 'getN' )
+ moose.connect( '/model/plot2', 'requestOut', es, 'getN' )
+ plot3 = moose.Table2( '/model/plot3' )
+ plot4 = moose.Table2( '/model/plot4' )
+ moose.connect( '/model/plot3', 'requestOut', s, 'getConc' )
+ moose.connect( '/model/plot4', 'requestOut', es, 'getConc' )
+
+def doPlot( ax, plot1, plot2, label ):
+ plt.ylabel( label )
+ plt.xlabel( 'time(s)' )
+ v1 = moose.element(plot1).vector
+ v2 = moose.element(plot2).vector
+ ax.plot( v1, label='s' )
+ ax.plot( v2, label='es' )
+ ax.plot( np.array( v1 ) + np.array( v2 ), label='sum' )
+ plt.legend()
+
+def almostEq( a, b ):
+ return abs(a-b)/(a+b) < 5e-5
+
+def main( standalone = False ):
+ runtime = 200
+ displayInterval = 2
+ makeModel()
+ moose.reinit()
+ moose.start( runtime )
+
+ assert( almostEq( 2.0 * moose.element( 'model/compartment/s' ).n,
+ moose.element( '/model/endo/s' ).n ) )
+
+ if standalone:
+ fig = plt.figure( figsize=(12,10) )
+ ax1 = fig.add_subplot(211)
+ doPlot( ax1, '/model/plot1', '/model/plot2', '# of molecules' )
+ ax2 = fig.add_subplot(212)
+ doPlot( ax2, '/model/plot3', '/model/plot4', 'conc (mM)' )
+ plt.show()
+ moose.delete( '/model' )
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+ main( standalone = True )
diff --git a/tests/python/testXreacs6.py b/tests/python/testXreacs6.py
new file mode 100644
index 0000000000000000000000000000000000000000..7edb514d9185d6cf3aeba3f8d8280362801950da
--- /dev/null
+++ b/tests/python/testXreacs6.py
@@ -0,0 +1,120 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+## This program is part of 'MOOSE', the
+## Messaging Object Oriented Simulation Environment.
+## Copyright (C) 2018 Upinder S. Bhalla. and NCBS
+## It is made available under the terms of the
+## GNU General Public License version 3 or later.
+## See the file COPYING.LIB for the full notice.
+#########################################################################
+
+
+import math
+import numpy as np
+import matplotlib.pyplot as plt
+import matplotlib.image as mpimg
+import moose
+import fixXreacs
+
+def makeModel():
+ # create container for model
+ num = 1 # number of compartments
+ model = moose.Neutral( '/model' )
+ compartment = moose.CylMesh( '/model/compartment' )
+ compartment.x1 = 1.0e-6 # Set it to a 1 micron single-voxel cylinder
+
+ # create molecules and reactions
+ s = moose.Pool( '/model/compartment/s' )
+ t = moose.Pool( '/model/compartment/t' )
+ rXfer = moose.Reac( '/model/compartment/rXfer' )
+ #####################################################################
+ # Put in endo compartment. Add molecule s
+ endo = moose.EndoMesh( '/model/endo' )
+ endo.isMembraneBound = True
+ endo.surround = compartment
+ es = moose.Pool( '/model/endo/s' )
+ et = moose.Pool( '/model/endo/t' )
+ #####################################################################
+ moose.connect( rXfer, 'sub', s, 'reac' )
+ moose.connect( rXfer, 'sub', t, 'reac' )
+ moose.connect( rXfer, 'prd', es, 'reac' )
+ moose.connect( rXfer, 'prd', et, 'reac' )
+ rXfer.Kf = 0.02 # 0.02/mM/sec
+ rXfer.Kb = 0.02 # 0.02/mM/sec
+
+ #####################################################################
+ fixXreacs.fixXreacs( '/model' )
+ #fixXreacs.restoreXreacs( '/model' )
+ #fixXreacs.fixXreacs( '/model' )
+ #####################################################################
+ # Make solvers
+ ksolve = moose.Ksolve( '/model/compartment/ksolve' )
+ dsolve = moose.Dsolve( '/model/dsolve' )
+ eksolve = moose.Ksolve( '/model/endo/ksolve' )
+ edsolve = moose.Dsolve( '/model/endo/dsolve' )
+
+ stoich = moose.Stoich( '/model/compartment/stoich' )
+ stoich.compartment = compartment
+ stoich.ksolve = ksolve
+ stoich.dsolve = dsolve
+ stoich.path = "/model/compartment/##"
+ assert( dsolve.numPools == 4 )
+ s.vec.concInit = [1]*num
+ t.vec.concInit = [1]*num
+
+ estoich = moose.Stoich( '/model/endo/stoich' )
+ estoich.compartment = endo
+ estoich.ksolve = eksolve
+ estoich.dsolve = edsolve
+ estoich.path = "/model/endo/##"
+ assert( edsolve.numPools == 2 )
+
+ edsolve.buildMeshJunctions( dsolve )
+
+ plot1 = moose.Table2( '/model/plot1' )
+ plot2 = moose.Table2( '/model/plot2' )
+ moose.connect( '/model/plot1', 'requestOut', s, 'getN' )
+ moose.connect( '/model/plot2', 'requestOut', es, 'getN' )
+ plot3 = moose.Table2( '/model/plot3' )
+ plot4 = moose.Table2( '/model/plot4' )
+ moose.connect( '/model/plot3', 'requestOut', s, 'getConc' )
+ moose.connect( '/model/plot4', 'requestOut', es, 'getConc' )
+
+def doPlot( ax, plot1, plot2, label ):
+ plt.ylabel( label )
+ plt.xlabel( 'time(s)' )
+ v1 = moose.element(plot1).vector
+ v2 = moose.element(plot2).vector
+ ax.plot( v1, label='s' )
+ ax.plot( v2, label='es' )
+ ax.plot( np.array( v1 ) + np.array( v2 ), label='sum' )
+ plt.legend()
+
+def almostEq( a, b ):
+ #print a, b, (a-b)/(a+b)
+ return abs(a-b)/(a+b) < 5e-5
+
+def main( standalone = False ):
+ for i in range( 10, 18):
+ moose.setClock( i, 0.01 )
+ runtime = 100
+ displayInterval = 2
+ makeModel()
+ moose.reinit()
+ moose.start( runtime )
+
+ assert( almostEq( moose.element( 'model/compartment/s' ).conc,
+ moose.element( '/model/endo/s' ).conc ) )
+
+ if standalone:
+ fig = plt.figure( figsize=(12,10) )
+ ax1 = fig.add_subplot(211)
+ doPlot( ax1, '/model/plot1', '/model/plot2', '# of molecules' )
+ ax2 = fig.add_subplot(212)
+ doPlot( ax2, '/model/plot3', '/model/plot4', 'conc (mM)' )
+ plt.show()
+ moose.delete( '/model' )
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+ main( standalone = True )
diff --git a/tests/python/testXreacs7.py b/tests/python/testXreacs7.py
new file mode 100644
index 0000000000000000000000000000000000000000..b55de2686be921c2deb174c4149ba2091d545f56
--- /dev/null
+++ b/tests/python/testXreacs7.py
@@ -0,0 +1,137 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+## This program is part of 'MOOSE', the
+## Messaging Object Oriented Simulation Environment.
+## Copyright (C) 2018 Upinder S. Bhalla. and NCBS
+## It is made available under the terms of the
+## GNU General Public License version 3 or later.
+## See the file COPYING.LIB for the full notice.
+##
+## This file makes u + t <=====> s where u is in a different compt from t,s
+#########################################################################
+
+
+import math
+import numpy as np
+import matplotlib.pyplot as plt
+import matplotlib.image as mpimg
+import moose
+import fixXreacs
+
+def makeModel():
+ # create container for model
+ num = 1 # number of compartments
+ model = moose.Neutral( '/model' )
+ compartment = moose.CylMesh( '/model/compartment' )
+ compartment.x1 = 1.0e-6 # Set it to a 1 micron single-voxel cylinder
+
+ # create molecules and reactions
+ u = moose.Pool( '/model/compartment/u' )
+ #####################################################################
+ # Put in endo compartment. Add molecule s
+ endo = moose.EndoMesh( '/model/endo' )
+ endo.isMembraneBound = True
+ endo.surround = compartment
+ rXfer = moose.Reac( '/model/endo/rXfer' )
+ et = moose.Pool( '/model/endo/t' )
+ es = moose.Pool( '/model/endo/s' )
+ #####################################################################
+ moose.connect( rXfer, 'sub', u, 'reac' )
+ moose.connect( rXfer, 'sub', et, 'reac' )
+ moose.connect( rXfer, 'prd', es, 'reac' )
+ u.concInit = 1.0
+ et.concInit = 1.0
+
+ #####################################################################
+ # [u0] = 1 in compt, [t0] = 1 in endo, [s0] = 0
+ # [u] + [s]/8 = [u0] ; [t] + [s] = [t0]; nu + ns = nu0, nt + ns = nt0
+ # At equil, numKf*nu*nt = numKb*ns
+ # Express all # in terms of ns.
+ # nu = nu0-ns; nt = nt0-ns Also, nu0 = 8*nt0
+ # So numKf*(nu0-ns)*(nt0-ns) = numKb*ns
+ # Target level is nt = ns = nt0/2
+ # So numKf*( 8nt0 - nt0/2)*nt0/2 = numKb*nt0/2
+ # So 7.5*nt0 = numKb/numKf
+ rXfer.numKb = 0.1
+ rXfer.numKf = 0.1/(7.5 * et.nInit)
+ #print( "Rates = {}, {}".format( rXfer.Kf, rXfer.Kb ))
+ #####################################################################
+ fixXreacs.fixXreacs( '/model' )
+ #fixXreacs.restoreXreacs( '/model' )
+ #fixXreacs.fixXreacs( '/model' )
+ #####################################################################
+
+ # Make solvers
+ ksolve = moose.Ksolve( '/model/compartment/ksolve' )
+ dsolve = moose.Dsolve( '/model/compartment/dsolve' )
+ eksolve = moose.Ksolve( '/model/endo/ksolve' )
+ edsolve = moose.Dsolve( '/model/endo/dsolve' )
+
+ stoich = moose.Stoich( '/model/compartment/stoich' )
+ stoich.compartment = compartment
+ stoich.ksolve = ksolve
+ stoich.dsolve = dsolve
+ stoich.path = "/model/compartment/##"
+ assert( dsolve.numPools == 1 )
+
+ estoich = moose.Stoich( '/model/endo/stoich' )
+ estoich.compartment = endo
+ estoich.ksolve = eksolve
+ estoich.dsolve = edsolve
+ estoich.path = "/model/endo/##"
+ assert( edsolve.numPools == 3 )
+
+ edsolve.buildMeshJunctions( dsolve )
+
+ plot1 = moose.Table2( '/model/plot1' )
+ plot2 = moose.Table2( '/model/plot2' )
+ plot3 = moose.Table2( '/model/plot3' )
+ moose.connect( '/model/plot1', 'requestOut', u, 'getN' )
+ moose.connect( '/model/plot2', 'requestOut', et, 'getN' )
+ moose.connect( '/model/plot3', 'requestOut', es, 'getN' )
+ plot4 = moose.Table2( '/model/plot4' )
+ plot5 = moose.Table2( '/model/plot5' )
+ plot6 = moose.Table2( '/model/plot6' )
+ moose.connect( '/model/plot4', 'requestOut', u, 'getConc' )
+ moose.connect( '/model/plot5', 'requestOut', et, 'getConc' )
+ moose.connect( '/model/plot6', 'requestOut', es, 'getConc' )
+
+def doPlot( ax, i, label ):
+ plt.ylabel( label )
+ plt.xlabel( 'time(s)' )
+ v1 = moose.element('/model/plot' + str(i)).vector
+ v2 = moose.element('/model/plot' + str(i+1)).vector
+ v3 = moose.element('/model/plot' + str(i+2)).vector
+ ax.plot( v1, label='u' )
+ ax.plot( v2, label='et' )
+ ax.plot( v3, label='es' )
+ ax.plot( np.array( v1 ) + np.array( v3 ), label='sum' )
+ plt.legend()
+
+def almostEq( a, b ):
+ #print a, b, (a-b)/(a+b)
+ return abs(a-b)/(a+b) < 5e-5
+
+def main( standalone = False ):
+ runtime = 100
+ displayInterval = 2
+ makeModel()
+ moose.reinit()
+ moose.start( runtime )
+
+ assert( almostEq( moose.element( 'model/endo/t' ).conc,
+ moose.element( '/model/endo/s' ).conc ) )
+
+ if standalone:
+ fig = plt.figure( figsize=(12,10) )
+ ax1 = fig.add_subplot(211)
+ doPlot( ax1, 1, '# of molecules' )
+ ax2 = fig.add_subplot(212)
+ doPlot( ax2, 4, 'conc (mM)' )
+ plt.show()
+
+ moose.delete( '/model' )
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+ main( standalone = True )
diff --git a/tests/python/testXreacs8.py b/tests/python/testXreacs8.py
new file mode 100644
index 0000000000000000000000000000000000000000..58dc5cf418b5e170628e89dfec83af672398efe2
--- /dev/null
+++ b/tests/python/testXreacs8.py
@@ -0,0 +1,134 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+## This program is part of 'MOOSE', the
+## Messaging Object Oriented Simulation Environment.
+## Copyright (C) 2014 Upinder S. Bhalla. and NCBS
+## It is made available under the terms of the
+## GNU Lesser General Public License version 2.1
+## See the file COPYING.LIB for the full notice.
+## Here we set up equal Kf and Kb in a reversible reaction across a
+## 1-voxel cyl compt and an internal endoMesh, having a smaller volume.
+## \
+## COMPT: 2 s <===> / 2 s :ENDO
+## \
+##
+## This becomes:
+## \
+## COMPT: 2 s <===> 2 s_xfer_endo / 2s :ENDO
+## \
+##
+#########################################################################
+
+
+import math
+import numpy as np
+import matplotlib.pyplot as plt
+import matplotlib.image as mpimg
+import moose
+import fixXreacs
+
+def makeModel():
+ # create container for model
+ num = 1 # number of compartments
+ model = moose.Neutral( '/model' )
+ compartment = moose.CylMesh( '/model/compartment' )
+ compartment.x1 = 1.0e-6 # Set it to a 1 micron single-voxel cylinder
+
+ # create molecules and reactions
+ s = moose.Pool( '/model/compartment/s' )
+ rXfer = moose.Reac( '/model/compartment/rXfer' )
+ #####################################################################
+ # Put in endo compartment. Add molecule s
+ endo = moose.EndoMesh( '/model/endo' )
+ endo.isMembraneBound = True
+ endo.surround = compartment
+ es = moose.Pool( '/model/endo/s' )
+ #####################################################################
+ moose.connect( rXfer, 'sub', s, 'reac' )
+ moose.connect( rXfer, 'sub', s, 'reac' )
+ moose.connect( rXfer, 'prd', es, 'reac' )
+ moose.connect( rXfer, 'prd', es, 'reac' )
+ rXfer.Kf = 0.01 # 0.01/sec
+ rXfer.Kb = 0.01 # 0.01/sec
+
+ #####################################################################
+ fixXreacs.fixXreacs( '/model' )
+ fixXreacs.restoreXreacs( '/model' )
+ fixXreacs.fixXreacs( '/model' )
+ #####################################################################
+
+ # Make solvers
+ ksolve = moose.Ksolve( '/model/compartment/ksolve' )
+ dsolve = moose.Dsolve( '/model/dsolve' )
+ eksolve = moose.Ksolve( '/model/endo/ksolve' )
+ edsolve = moose.Dsolve( '/model/endo/dsolve' )
+
+ stoich = moose.Stoich( '/model/compartment/stoich' )
+ stoich.compartment = compartment
+ stoich.ksolve = ksolve
+ stoich.dsolve = dsolve
+ stoich.path = "/model/compartment/##"
+ assert( dsolve.numPools == 2 )
+ s.vec.concInit = [1]*num
+
+ estoich = moose.Stoich( '/model/endo/stoich' )
+ estoich.compartment = endo
+ estoich.ksolve = eksolve
+ estoich.dsolve = edsolve
+ estoich.path = "/model/endo/##"
+ assert( edsolve.numPools == 1 )
+
+ edsolve.buildMeshJunctions( dsolve )
+
+ plot1 = moose.Table2( '/model/plot1' )
+ plot2 = moose.Table2( '/model/plot2' )
+ plot3 = moose.Table2( '/model/plot3' )
+ moose.connect( '/model/plot1', 'requestOut', s, 'getN' )
+ moose.connect( '/model/plot2', 'requestOut', es, 'getN' )
+ moose.connect( '/model/plot3', 'requestOut', '/model/compartment/s_xfer_endo', 'getN' )
+ plot4 = moose.Table2( '/model/plot4' )
+ plot5 = moose.Table2( '/model/plot5' )
+ plot6 = moose.Table2( '/model/plot6' )
+ moose.connect( '/model/plot4', 'requestOut', s, 'getConc' )
+ moose.connect( '/model/plot5', 'requestOut', es, 'getConc' )
+ moose.connect( '/model/plot6', 'requestOut', '/model/compartment/s_xfer_endo', 'getConc' )
+
+def doPlot( ax, i, label ):
+ plot1 = '/model/plot' + str(i)
+ plot2 = '/model/plot' + str(i+1)
+ plot3 = '/model/plot' + str(i+2)
+ plt.ylabel( label )
+ plt.xlabel( 'time(s)' )
+ v1 = moose.element(plot1).vector
+ v2 = moose.element(plot2).vector
+ v3 = moose.element(plot3).vector
+ ax.plot( v1, label='s' )
+ ax.plot( v2, 'x',label='es' )
+ ax.plot( v3, label='xfer' )
+ ax.plot( np.array( v1 ) + np.array( v2 ), label='sum' )
+ plt.legend()
+
+def almostEq( a, b ):
+ return abs(a-b)/(a+b) < 5e-5
+
+def main( standalone = False ):
+ runtime = 100
+ makeModel()
+ moose.reinit()
+ moose.start( runtime )
+ assert( almostEq( moose.element( 'model/compartment/s' ).conc,
+ moose.element( '/model/endo/s' ).conc ) )
+
+ if standalone:
+ fig = plt.figure( figsize=(12,10) )
+ ax1 = fig.add_subplot(211)
+ doPlot( ax1, 1, '# of molecules' )
+ ax2 = fig.add_subplot(212)
+ doPlot( ax2, 4, 'conc (mM)' )
+ plt.show()
+ moose.delete( '/model' )
+
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+ main( standalone = True )
diff --git a/tests/python/test_GraupnerBrunel2012_STDPfromCaPlasticity.py b/tests/python/test_GraupnerBrunel2012_STDPfromCaPlasticity.py
new file mode 100644
index 0000000000000000000000000000000000000000..73aa8c9e50367b711761d7c0aa4b08d8569195df
--- /dev/null
+++ b/tests/python/test_GraupnerBrunel2012_STDPfromCaPlasticity.py
@@ -0,0 +1,228 @@
+# -*- coding: utf-8 -*-
+# This script is modified version of GraupnerBrunel2012 model by Aditya Gilra.
+# Modification is following:
+# - Added global seed.
+# - Removed some messages.
+# - Added assertion.
+#
+# NOTE: This script is used for testing random number generators on various
+# platform. This should not be used in any tutorial or scientific demo.
+
+import matplotlib as mpl
+mpl.use('Agg')
+import moose
+print( 'Using moose from %s' % moose.__file__ )
+import numpy as np
+
+moose.seed( 10 )
+
+def main():
+ """
+ Simulate a pseudo-STDP protocol and plot the STDP kernel
+ that emerges from Ca plasticity of Graupner and Brunel 2012.
+
+ Author: Aditya Gilra, NCBS, Bangalore, October, 2014.
+ """
+
+ # ###########################################
+ # Neuron models
+ # ###########################################
+
+ ## Leaky integrate and fire neuron
+ Vrest = -65e-3 # V # resting potential
+ Vt_base = -45e-3 # V # threshold
+ Vreset = -55e-3 # V # in current steps, Vreset is same as pedestal
+ R = 1e8 # Ohm
+ tau = 10e-3 # s
+ refrT = 2e-3 # s
+
+ # ###########################################
+ # Initialize neuron group
+ # ###########################################
+
+ ## two neurons: index 0 will be presynaptic, 1 will be postsynaptic
+ network = moose.LIF( 'network', 2 );
+ moose.le( '/network' )
+ network.vec.Em = Vrest
+ network.vec.thresh = Vt_base
+ network.vec.refractoryPeriod = refrT
+ network.vec.Rm = R
+ network.vec.vReset = Vreset
+ network.vec.Cm = tau/R
+ network.vec.inject = 0.
+ network.vec.initVm = Vrest
+
+ tauCa = 20e-3
+ tauSyn = 150.0
+ CaPre = 1.0
+ CaPost = 2.0
+ delayD = 13.7e-3
+ thetaD = 1.0
+ thetaP = 1.3
+ gammaD = 200.0
+ gammaP = 321.808
+ J = 5e-3 # V
+ weight = 0.5
+ bistable = True
+
+ syn = moose.GraupnerBrunel2012CaPlasticitySynHandler( '/network/syn' )
+ syn.numSynapses = 1
+ moose.connect( syn, 'activationOut', network.vec[1], 'activation' )
+
+ # synapse from presynaptic neuron
+ moose.connect( network.vec[0],'spikeOut', syn.synapse[0], 'addSpike')
+
+ # post-synaptic spikes also needed for STDP
+ moose.connect( network.vec[1], 'spikeOut', syn, 'addPostSpike')
+
+ syn.synapse[0].delay = 0.0
+ syn.synapse[0].weight = weight
+ syn.CaInit = 0.0
+ syn.tauCa = tauCa
+ syn.tauSyn = tauSyn
+ syn.CaPre = CaPre
+ syn.CaPost = CaPost
+ syn.delayD = delayD
+ syn.thetaD = thetaD
+ syn.thetaP = thetaP
+ syn.gammaD = gammaD
+ syn.gammaP = gammaP
+ syn.weightScale = J
+ syn.weightMax = 1.0
+ syn.weightMin = 0.
+
+ syn.noisy = True
+ syn.noiseSD = 1.3333
+ syn.bistable = bistable
+
+ # ###########################################
+ # Setting up tables
+ # ###########################################
+
+ Vms = moose.Table( '/plotVms', 2 )
+ moose.connect( network, 'VmOut', Vms, 'input', 'OneToOne')
+ spikes = moose.Table( '/plotSpikes', 2 )
+ moose.connect( network, 'spikeOut', spikes, 'input', 'OneToOne')
+ CaTable = moose.Table( '/plotCa', 1 )
+ moose.connect( CaTable, 'requestOut', syn, 'getCa')
+ WtTable = moose.Table( '/plotWeight', 1 )
+ moose.connect( WtTable, 'requestOut', syn.synapse[0], 'getWeight')
+
+ dt = 1e-3
+ moose.useClock( 0, '/network/syn', 'process' )
+ moose.useClock( 1, '/network', 'process' )
+ moose.useClock( 2, '/plotSpikes', 'process' )
+ moose.useClock( 3, '/plotVms', 'process' )
+ moose.useClock( 3, '/plotCa', 'process' )
+ moose.useClock( 3, '/plotWeight', 'process' )
+ moose.setClock( 0, dt )
+ moose.setClock( 1, dt )
+ moose.setClock( 2, dt )
+ moose.setClock( 3, dt )
+ moose.setClock( 9, dt )
+ moose.reinit()
+
+ # function to make the aPlus and aMinus settle to equilibrium values
+ settletime = 10e-3 # s
+ def reset_settle():
+ """ Call this between every pre-post pair
+ to reset the neurons and make them settle to rest.
+ """
+ syn.synapse[0].weight = weight
+ syn.Ca = 0.0
+ moose.start(settletime)
+ # Ca gets a jump at pre-spike+delayD
+ # So this event can occur during settletime
+ # So set Ca and weight once more after settletime
+ syn.synapse[0].weight = weight
+ syn.Ca = 0.0
+
+ # function to inject a sharp current pulse to make neuron spike
+ # immediately at a given time step
+ def make_neuron_spike(nrnidx,I=1e-7,duration=1e-3):
+ """ Inject a brief current pulse to
+ make a neuron spike
+ """
+ network.vec[nrnidx].inject = I
+ moose.start(duration)
+ network.vec[nrnidx].inject = 0.
+
+ dwlist_neg = []
+ ddt = 10e-3 # s
+ # since CaPlasticitySynHandler is event based
+ # multiple pairs are needed for Ca to be registered above threshold
+ # Values from Fig 2, last line of legend
+ numpairs = 60 # number of spike parts per deltat
+ t_between_pairs = 1.0 # time between each spike pair
+ t_extent = 100e-3 # s # STDP kernel extent,
+ # t_extent > t_between_pairs/2 inverts pre-post pairing!
+ # dt = tpost - tpre
+ # negative dt corresponds to post before pre
+ print('-----------------------------------------------')
+ for deltat in np.arange(t_extent,0.0,-ddt):
+ reset_settle()
+ for i in range(numpairs):
+ # post neuron spike
+ make_neuron_spike(1)
+ moose.start(deltat)
+ # pre neuron spike after deltat
+ make_neuron_spike(0)
+ moose.start(t_between_pairs) # weight changes after pre-spike+delayD
+ # must run for at least delayD after pre-spike
+ dw = ( syn.synapse[0].weight - weight ) / weight
+ print(('post before pre, dt = %1.3f s, dw/w = %1.3f'%(-deltat,dw)))
+ dwlist_neg.append(dw)
+
+ print('-----------------------------------------------')
+ # positive dt corresponds to pre before post
+ dwlist_pos = []
+ for deltat in np.arange(ddt,t_extent+ddt,ddt):
+ reset_settle()
+ for i in range(numpairs):
+ # pre neuron spike
+ make_neuron_spike(0)
+ moose.start(deltat)
+ # post neuron spike after deltat
+ make_neuron_spike(1)
+ moose.start(t_between_pairs)
+ dw = ( syn.synapse[0].weight - weight ) / weight
+ print(('pre before post, dt = %1.3f s, dw/w = %1.3f'%(deltat,dw)))
+ dwlist_pos.append(dw)
+
+ Vmseries0 = Vms.vec[0].vector
+ numsteps = len(Vmseries0)
+
+ for t in spikes.vec[0].vector:
+ Vmseries0[int(t/dt)-1] = 30e-3 # V
+
+ Vmseries1 = Vms.vec[1].vector
+
+ for t in spikes.vec[1].vector:
+ Vmseries1[int(t/dt)-1] = 30e-3 # V
+
+ timeseries = np.linspace(0.,200*numsteps*dt,numsteps)
+
+ # STDP curve
+ up, sp = np.mean( dwlist_pos ), np.std( dwlist_pos )
+ un, sn = np.mean( dwlist_neg ), np.std( dwlist_neg )
+
+ expected = [0.32476025611655324, 0.22658173497286094,
+ 0.02706212384326734, -0.2176119329016457, -0.17349820098625146,
+ -0.049000627347906, 0.10942145078777199, 0.015381955378225953,
+ 0.004742824127517586, -0.12298343312253879]
+ assert np.isclose(dwlist_pos[1:], expected[1:]).all(), "Got %s \nexpected %s" % (dwlist_pos, expected)
+
+ expected = [-0.07871282492831622, 0.11915009122888964,
+ -0.028510348966579557, 0.11812233585111875, 0.05098143255634335,
+ -0.2303047508248669, 0.18033418630802123, -0.019377885225611347,
+ -0.06038610826728241, 0.06575882890278106]
+ assert np.isclose(dwlist_neg[1:], expected[1:]).all(), "Got %s\nexpected %s" % (dwlist_neg,
+ expected)
+
+
+ got = (up, sp)
+ expNew = (0.014485615086785508, 0.16206703949072981)
+ assert np.isclose(got, expNew).all(), 'Expected: %s, Got: %s' % (str(expNew), str(got))
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/python/test_Xchan1.py b/tests/python/test_Xchan1.py
new file mode 100644
index 0000000000000000000000000000000000000000..35fc56f647a36ebebe6c33841eca6c9371bbd4cb
--- /dev/null
+++ b/tests/python/test_Xchan1.py
@@ -0,0 +1,153 @@
+#########################################################################
+## This program is part of 'MOOSE', the
+## Messaging Object Oriented Simulation Environment.
+## Copyright (C) 2014 Upinder S. Bhalla. and NCBS
+## It is made available under the terms of the
+## GNU Lesser General Public License version 2.1
+## See the file COPYING.LIB for the full notice.
+## Here test ConcChan. We set up a channel and a pump and run two tests.
+## First we have zero flux through the pump and check that the conc
+## equalizes on both sides of the membrane. Then we change the Kf of
+## the pump to a value designed to give twice the conc In as Out.
+## The system is a 1-voxel cyl compt and an internal endoMesh, having a
+## volume = 1/8 of the cylinder.
+## \
+## COMPT: s ----> / s :ENDO
+## s =chan= s
+## \
+##
+## This becomes:
+## \
+## COMPT: s ----> s_xfer_endo / s :ENDO
+## s =chan= s
+## \
+##
+#########################################################################
+
+
+import math
+import numpy as np
+import moose
+import fixXreacs
+
+def makeModel():
+ # create container for model
+ num = 1 # number of compartments
+ model = moose.Neutral( '/model' )
+ compartment = moose.CylMesh( '/model/compartment' )
+ compartment.x1 = 1.0e-6 # Set it to a 1 micron single-voxel cylinder
+
+ # create molecules and reactions
+ s = moose.Pool( '/model/compartment/s' )
+ rXfer = moose.Reac( '/model/compartment/rXfer' )
+ #####################################################################
+ # Put in endo compartment. Add molecule s
+ endo = moose.EndoMesh( '/model/endo' )
+ # Note that the chanPool must be on the 'In' compartment.
+ #chanPool = moose.Pool( '/model/compartment/chanPool' )
+ #chan = moose.ConcChan( '/model/compartment/chanPool/chan' )
+ chanPool = moose.Pool( '/model/endo/chanPool' )
+ chan = moose.ConcChan( '/model/endo/chanPool/chan' )
+ endo.isMembraneBound = True
+ endo.surround = compartment
+ es = moose.Pool( '/model/endo/s' )
+ #####################################################################
+ moose.connect( rXfer, 'sub', s, 'reac' )
+ moose.connect( rXfer, 'prd', es, 'reac' )
+ moose.connect( chanPool, 'nOut', chan, 'setNumChan' )
+ moose.connect( chan, 'out', s, 'reac' )
+ moose.connect( chan, 'in', es, 'reac' )
+ volRatio = compartment.volume / endo.volume
+ rXfer.Kf = 0.0 # 0.02/sec
+ rXfer.Kb = 0.0 #
+ s.concInit = 0.001
+ chanPool.nInit = 1000.0
+ # Flux (mM/s) = permeability * N * (conc_out - conc_in )
+ chan.permeability = 0.1 * chanPool.volume * 6.022e23 / chanPool.nInit
+
+ #####################################################################
+ fixXreacs.fixXreacs( '/model' )
+ #fixXreacs.restoreXreacs( '/model' )
+ #fixXreacs.fixXreacs( '/model' )
+ #####################################################################
+
+ # Make solvers
+ ksolve = moose.Ksolve( '/model/compartment/ksolve' )
+ dsolve = moose.Dsolve( '/model/dsolve' )
+ eksolve = moose.Ksolve( '/model/endo/ksolve' )
+ edsolve = moose.Dsolve( '/model/endo/dsolve' )
+
+ stoich = moose.Stoich( '/model/compartment/stoich' )
+ stoich.compartment = compartment
+ stoich.ksolve = ksolve
+ stoich.dsolve = dsolve
+ stoich.path = "/model/compartment/##"
+ assert( dsolve.numPools == 2 )
+
+ estoich = moose.Stoich( '/model/endo/stoich' )
+ estoich.compartment = endo
+ estoich.ksolve = eksolve
+ estoich.dsolve = edsolve
+ estoich.path = "/model/endo/##"
+ assert( edsolve.numPools == 2 )
+
+ edsolve.buildMeshJunctions( dsolve )
+
+ plot1 = moose.Table2( '/model/plot1' )
+ plot2 = moose.Table2( '/model/plot2' )
+ plot3 = moose.Table2( '/model/plot3' )
+ moose.connect( '/model/plot1', 'requestOut', s, 'getN' )
+ moose.connect( '/model/plot2', 'requestOut', es, 'getN' )
+ moose.connect( '/model/plot3', 'requestOut', '/model/compartment/s_xfer_endo', 'getN' )
+ plot4 = moose.Table2( '/model/plot4' )
+ plot5 = moose.Table2( '/model/plot5' )
+ plot6 = moose.Table2( '/model/plot6' )
+ moose.connect( '/model/plot4', 'requestOut', s, 'getConc' )
+ moose.connect( '/model/plot5', 'requestOut', es, 'getConc' )
+ moose.connect( '/model/plot6', 'requestOut', '/model/compartment/s_xfer_endo', 'getConc' )
+
+
+def almostEq( a, b ):
+ #print a, b, (a-b)/(a+b)
+ return abs(a-b)/(a+b) < 5e-5
+
+def main( standalone = False ):
+ runtime = 100
+ displayInterval = 2
+ makeModel()
+ for i in range( 10, 18 ):
+ moose.setClock( i, 0.01 )
+ moose.reinit()
+ moose.start( runtime )
+ s = moose.element( '/model/compartment/s' )
+ es = moose.element( '/model/endo/s' )
+ assert( almostEq( s.conc, es.conc ) )
+ # We go for concEndo = 2x concOut. Then
+ # We already know volIn = volOut/8
+ # #in/volIn = 2x #out/volOut
+ # #in/volIn = 2x #out/(8*volIn)
+ # so #in = #out/4
+ # From consv, #in + #out = nInit
+ # so 5/4#out = nInit =>
+ # #out = 0.8*nInit; #in = 0.2*nInit
+ #
+ # flux = perm * nChan * (0.8nInit/volOut - 0.2nInit/(volOut/8) ) =
+ # perm * (nChan*nInit/volOut) * (0.8 - 0.2*8) =
+ # perm * (nChan*nInit/volOut) * (-0.8)
+ #
+ # This has to be balanced by flux = numKf * nOut = numKf * 0.8 * nInit
+ # So 0.8*numKf*nInit = 0.8*perm*nChan*nInit/volOut
+
+ # Note that chan.permeability = 0.1*chanPool.volume / chanPool.nInit
+
+ # so numKf = perm*nChan/volOut = (0.1*volIn/nChan)*nChan/volOut=0.1/8
+ #
+ rXfer = moose.element( '/model/compartment/rXfer' )
+ rXfer.numKf = 0.1/8.0
+ moose.start( runtime )
+ assert( almostEq( 2 * s.conc, es.conc ) )
+ moose.delete( '/model' )
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+ main( standalone = True )
diff --git a/tests/python/test_Xdiff1.py b/tests/python/test_Xdiff1.py
new file mode 100644
index 0000000000000000000000000000000000000000..fc9df5d8879755578e9e69588681731a470408e4
--- /dev/null
+++ b/tests/python/test_Xdiff1.py
@@ -0,0 +1,129 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+## This program is part of 'MOOSE', the
+## Messaging Object Oriented Simulation Environment.
+## Copyright (C) 2014 Upinder S. Bhalla. and NCBS
+## It is made available under the terms of the
+## GNU Lesser General Public License version 2.1
+## See the file COPYING.LIB for the full notice.
+## Here test diffusion across a junction. We set up a pump and change its
+## rate to do a check on the calculation of the diffusion rate separate
+## from the verification that diffusion gives equal concs on either side.
+## The system is a ## 1-voxel cyl compt and an internal endoMesh,
+## having a volume = 1/8 of the parent cylinder..
+## \
+## COMPT: s ----> / s :ENDO
+## s =diffn= s
+## \
+##
+## This becomes:
+## \
+## COMPT: s ----> s_xfer_endo / s :ENDO
+# s =diffn= s
+## \
+##
+#########################################################################
+
+
+import math
+import numpy as np
+import moose
+print( '[INFO] Using moose from %s, %s' % (moose.__file__, moose.version()) )
+import fixXreacs
+
+diffConst = 1e-16
+
+def makeModel():
+ # create container for model
+ num = 1 # number of compartments
+ model = moose.Neutral( '/model' )
+ compartment = moose.CylMesh( '/model/compartment' )
+ compartment.x1 = 1.0e-6 # Set it to a 1 micron single-voxel cylinder
+
+ # create molecules and reactions
+ s = moose.Pool( '/model/compartment/s' )
+ rXfer = moose.Reac( '/model/compartment/rXfer' )
+ #####################################################################
+ # Put in endo compartment. Add molecule s
+ endo = moose.EndoMesh( '/model/endo' )
+ endo.isMembraneBound = False
+ endo.surround = compartment
+ es = moose.Pool( '/model/endo/s' )
+ #####################################################################
+ moose.connect( rXfer, 'sub', s, 'reac' )
+ moose.connect( rXfer, 'prd', es, 'reac' )
+ volRatio = compartment.volume / endo.volume
+ #print( "Volume ratio = {}".format( volRatio ) )
+ rXfer.Kf = 0.0 # 0.02/sec
+ rXfer.Kb = 0.0 #
+ s.concInit = 0.001
+ s.diffConst = diffConst
+ es.diffConst = diffConst
+
+ #####################################################################
+ fixXreacs.fixXreacs( '/model' )
+ #fixXreacs.restoreXreacs( '/model' )
+ #fixXreacs.fixXreacs( '/model' )
+ #####################################################################
+
+ # Make solvers
+ ksolve = moose.Ksolve( '/model/compartment/ksolve' )
+ dsolve = moose.Dsolve( '/model/dsolve' )
+ eksolve = moose.Ksolve( '/model/endo/ksolve' )
+ edsolve = moose.Dsolve( '/model/endo/dsolve' )
+
+ stoich = moose.Stoich( '/model/compartment/stoich' )
+ stoich.compartment = compartment
+ stoich.ksolve = ksolve
+ stoich.dsolve = dsolve
+ stoich.path = "/model/compartment/##"
+ assert( dsolve.numPools == 2 )
+
+ estoich = moose.Stoich( '/model/endo/stoich' )
+ estoich.compartment = endo
+ estoich.ksolve = eksolve
+ estoich.dsolve = edsolve
+ estoich.path = "/model/endo/##"
+ assert( edsolve.numPools == 1 )
+
+ edsolve.buildMeshJunctions( dsolve )
+
+ plot1 = moose.Table2( '/model/plot1' )
+ plot2 = moose.Table2( '/model/plot2' )
+ plot3 = moose.Table2( '/model/plot3' )
+ moose.connect( '/model/plot1', 'requestOut', s, 'getN' )
+ moose.connect( '/model/plot2', 'requestOut', es, 'getN' )
+ moose.connect( '/model/plot3', 'requestOut', '/model/compartment/s_xfer_endo', 'getN' )
+ plot4 = moose.Table2( '/model/plot4' )
+ plot5 = moose.Table2( '/model/plot5' )
+ plot6 = moose.Table2( '/model/plot6' )
+ moose.connect( '/model/plot4', 'requestOut', s, 'getConc' )
+ moose.connect( '/model/plot5', 'requestOut', es, 'getConc' )
+ moose.connect( '/model/plot6', 'requestOut', '/model/compartment/s_xfer_endo', 'getConc' )
+
+def almostEq( a, b ):
+ # print( a, b, (a-b)/(a+b) )
+ return abs(a-b)/(a+b) < 6e-5
+
+def main( standalone = False ):
+ runtime = 100
+ makeModel()
+ for i in range( 10, 18 ):
+ moose.setClock( i, 0.01 )
+ moose.reinit()
+ moose.start( runtime, 1 )
+ s = moose.element( '/model/compartment/s' )
+ es = moose.element( '/model/endo/s' )
+ assert( almostEq( s.conc, es.conc ) )
+ rXfer = moose.element( '/model/compartment/rXfer' )
+ endo = moose.element( '/model/endo' )
+ compt = moose.element( '/model/compartment' )
+ endoA = endo.aScale * pow( compt.volume, endo.aPower )
+ rXfer.numKf = 2.0*diffConst*endoA/(compt.r0*compt.volume)
+ moose.start( runtime )
+ assert almostEq( 2 * s.conc, es.conc ), "%g=?%g" % (2*s.conc, es.conc)
+ moose.delete( '/model' )
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+ main( standalone = True )
diff --git a/tests/python/test_Xenz1.py b/tests/python/test_Xenz1.py
new file mode 100644
index 0000000000000000000000000000000000000000..c7463ad47aa9f6d77484af09bdd7f46fbea5fd29
--- /dev/null
+++ b/tests/python/test_Xenz1.py
@@ -0,0 +1,117 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+## This program is part of 'MOOSE', the
+## Messaging Object Oriented Simulation Environment.
+## Copyright (C) 2014 Upinder S. Bhalla. and NCBS
+## It is made available under the terms of the
+## GNU Lesser General Public License version 2.1
+## See the file COPYING.LIB for the full notice.
+##
+## Endo / Compartment
+## \
+## sub--enz-/-----> prd
+## sub<-----\----- prd
+## /
+#########################################################################
+
+
+import math
+import numpy as np
+import moose
+import fixXreacs
+
+subInit = 0.002
+eInit = 0.001
+Km = 0.001
+kcat = 0.2
+Kf = 0.1
+
+def makeModel():
+ # create container for model
+ num = 1 # number of compartments
+ model = moose.Neutral( '/model' )
+ compartment = moose.CylMesh( '/model/compartment' )
+ compartment.x1 = 1.0e-6 # Set it to a 1 micron single-voxel cylinder
+
+ # create molecules and reactions
+ prd = moose.Pool( '/model/compartment/prd' )
+ rXfer = moose.Reac( '/model/compartment/rXfer' )
+ #####################################################################
+ # Put in endo compartment. Add molecule s
+ endo = moose.EndoMesh( '/model/endo' )
+ endo.isMembraneBound = True
+ endo.surround = compartment
+ sub = moose.Pool( '/model/endo/sub' )
+ enzPool = moose.Pool( '/model/endo/enzPool' )
+ enzPool.concInit = eInit
+ enz = moose.MMenz( '/model/endo/enzPool/enz' )
+ #####################################################################
+ moose.connect( enz, 'sub', sub, 'reac' )
+ moose.connect( enz, 'prd', prd, 'reac' )
+ moose.connect( enzPool, 'nOut', enz, 'enzDest' )
+ moose.connect( rXfer, 'sub', prd, 'reac' )
+ moose.connect( rXfer, 'prd', sub, 'reac' )
+ rXfer.Kf = Kf # 0.04/sec
+ rXfer.Kb = 0.0 # 0.02/sec
+ enz.Km = Km
+ enz.kcat = kcat
+ # v = es.kcat/(s+Km)
+ # v = Kf * conc.
+ #####################################################################
+ fixXreacs.fixXreacs( '/model' )
+ fixXreacs.restoreXreacs( '/model' )
+ fixXreacs.fixXreacs( '/model' )
+ #####################################################################
+
+ # Make solvers
+ ksolve = moose.Ksolve( '/model/compartment/ksolve' )
+ dsolve = moose.Dsolve( '/model/dsolve' )
+ eksolve = moose.Ksolve( '/model/endo/ksolve' )
+ edsolve = moose.Dsolve( '/model/endo/dsolve' )
+
+ stoich = moose.Stoich( '/model/compartment/stoich' )
+ stoich.compartment = compartment
+ stoich.ksolve = ksolve
+ stoich.dsolve = dsolve
+ stoich.path = "/model/compartment/##"
+ assert( dsolve.numPools == 2 )
+ sub.vec.concInit = subInit
+ enzPool.vec.concInit = eInit
+
+ estoich = moose.Stoich( '/model/endo/stoich' )
+ estoich.compartment = endo
+ estoich.ksolve = eksolve
+ estoich.dsolve = edsolve
+ estoich.path = "/model/endo/##"
+ assert( edsolve.numPools == 3 )
+
+ edsolve.buildMeshJunctions( dsolve )
+
+ plot1 = moose.Table2( '/model/plot1' )
+ plot2 = moose.Table2( '/model/plot2' )
+ moose.connect( '/model/plot1', 'requestOut', sub, 'getN' )
+ moose.connect( '/model/plot2', 'requestOut', prd, 'getN' )
+ plot3 = moose.Table2( '/model/plot3' )
+ plot4 = moose.Table2( '/model/plot4' )
+ moose.connect( '/model/plot3', 'requestOut', sub, 'getConc' )
+ moose.connect( '/model/plot4', 'requestOut', prd, 'getConc' )
+
+def almostEq( a, b ):
+ #print a, b, (a-b)/(a+b)
+ return abs(a-b)/(a+b) < 5e-5
+
+def main( standalone = False ):
+ for i in range( 10, 18 ):
+ moose.setClock( i, 0.001 )
+ runtime = 100
+ displayInterval = 2
+ makeModel()
+ moose.reinit()
+ moose.start( runtime )
+ assert( almostEq( moose.element( 'model/compartment/prd' ).n,
+ moose.element( '/model/endo/sub' ).n ) )
+ moose.delete( '/model' )
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+ main( standalone = True )
diff --git a/tests/python/test_Xreacs2.py b/tests/python/test_Xreacs2.py
new file mode 100644
index 0000000000000000000000000000000000000000..1b1e73026b1c48c5049ac2bd54187c5d423ab1ee
--- /dev/null
+++ b/tests/python/test_Xreacs2.py
@@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*-
+import os
+import sys
+import moose
+import numpy as np
+import fixXreacs
+
+def countCrossings( plot, thresh ):
+ vec = moose.element( plot ).vector
+ #print (vec[:-1] < thresh)
+ return sum( (vec[:-1] < thresh) * (vec[1:] >= thresh ) )
+
+def main( standalone = False ):
+ mfile = os.path.join( os.path.dirname( __file__), 'OSC_diff_vols.g' )
+ runtime = 4000.0
+ modelId = moose.loadModel( mfile, 'model', 'ee' )
+ kin = moose.element( '/model/kinetics' )
+ compt1 = moose.element( '/model/compartment_1' )
+ compt1.x1 += kin.x1
+ compt1.x0 += kin.x1
+ fixXreacs.fixXreacs( '/model' )
+ #fixXreacs.restoreXreacs( '/model' )
+ #fixXreacs.fixXreacs( '/model' )
+
+ ks1 = moose.Ksolve( '/model/kinetics/ksolve' )
+ ds1 = moose.Dsolve( '/model/kinetics/dsolve' )
+ s1 = moose.Stoich( '/model/kinetics/stoich' )
+ s1.compartment = moose.element( '/model/kinetics' )
+ s1.ksolve = ks1
+ s1.dsolve = ds1
+ s1.path = '/model/kinetics/##'
+
+ ks2 = moose.Ksolve( '/model/compartment_1/ksolve' )
+ ds2 = moose.Dsolve( '/model/compartment_1/dsolve' )
+ s2 = moose.Stoich( '/model/compartment_1/stoich' )
+ s2.compartment = moose.element( '/model/compartment_1' )
+ s2.ksolve = ks2
+ s2.dsolve = ds2
+ s2.path = '/model/compartment_1/##'
+
+ ds2.buildMeshJunctions( ds1 )
+
+ moose.reinit()
+ moose.start( runtime )
+ # I don't have an analytic way to assess oscillations
+ assert( countCrossings( '/model/graphs/conc2/M.Co', 0.001 ) == 4 )
+ moose.delete( '/model' )
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+ main( standalone = True )
diff --git a/tests/python/test_Xreacs3.py b/tests/python/test_Xreacs3.py
new file mode 100644
index 0000000000000000000000000000000000000000..53cd7600b05a55a31d60321fed6891baf3b9e3bf
--- /dev/null
+++ b/tests/python/test_Xreacs3.py
@@ -0,0 +1,107 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+## This program is part of 'MOOSE', the
+## Messaging Object Oriented Simulation Environment.
+## Copyright (C) 2014 Upinder S. Bhalla. and NCBS
+## It is made available under the terms of the
+## GNU Lesser General Public License version 2.1
+## See the file COPYING.LIB for the full notice.
+## Here we set up equal Kf and Kb in a reversible reaction across a
+## 1-voxel cyl compt and an internal endoMesh, having a smaller volume.
+## \
+## COMPT: s <===> / s :ENDO
+## \
+##
+## This becomes:
+## \
+## COMPT: s <===> s_xfer_endo / s :ENDO
+## \
+##
+#########################################################################
+
+
+import math
+import numpy as np
+import moose
+import fixXreacs
+
+def makeModel():
+ # create container for model
+ num = 1 # number of compartments
+ model = moose.Neutral( '/model' )
+ compartment = moose.CylMesh( '/model/compartment' )
+ compartment.x1 = 1.0e-6 # Set it to a 1 micron single-voxel cylinder
+
+ # create molecules and reactions
+ s = moose.Pool( '/model/compartment/s' )
+ rXfer = moose.Reac( '/model/compartment/rXfer' )
+ #####################################################################
+ # Put in endo compartment. Add molecule s
+ endo = moose.EndoMesh( '/model/endo' )
+ endo.isMembraneBound = True
+ endo.surround = compartment
+ es = moose.Pool( '/model/endo/s' )
+ #####################################################################
+ moose.connect( rXfer, 'sub', s, 'reac' )
+ moose.connect( rXfer, 'prd', es, 'reac' )
+ volRatio = compartment.volume / endo.volume
+ rXfer.Kf = 0.02 # 0.01/sec
+ rXfer.Kb = 0.02 # 1/sec
+
+ #####################################################################
+ fixXreacs.fixXreacs( '/model' )
+ fixXreacs.restoreXreacs( '/model' )
+ fixXreacs.fixXreacs( '/model' )
+ #####################################################################
+
+ # Make solvers
+ ksolve = moose.Ksolve( '/model/compartment/ksolve' )
+ dsolve = moose.Dsolve( '/model/dsolve' )
+ eksolve = moose.Ksolve( '/model/endo/ksolve' )
+ edsolve = moose.Dsolve( '/model/endo/dsolve' )
+
+ stoich = moose.Stoich( '/model/compartment/stoich' )
+ stoich.compartment = compartment
+ stoich.ksolve = ksolve
+ stoich.dsolve = dsolve
+ stoich.path = "/model/compartment/##"
+ assert( dsolve.numPools == 2 )
+ s.vec.concInit = [1]*num
+
+ estoich = moose.Stoich( '/model/endo/stoich' )
+ estoich.compartment = endo
+ estoich.ksolve = eksolve
+ estoich.dsolve = edsolve
+ estoich.path = "/model/endo/##"
+ assert( edsolve.numPools == 1 )
+
+ edsolve.buildMeshJunctions( dsolve )
+
+ plot1 = moose.Table2( '/model/plot1' )
+ plot2 = moose.Table2( '/model/plot2' )
+ plot3 = moose.Table2( '/model/plot3' )
+ moose.connect( '/model/plot1', 'requestOut', s, 'getN' )
+ moose.connect( '/model/plot2', 'requestOut', es, 'getN' )
+ moose.connect( '/model/plot3', 'requestOut', '/model/compartment/s_xfer_endo', 'getN' )
+ plot4 = moose.Table2( '/model/plot4' )
+ plot5 = moose.Table2( '/model/plot5' )
+ plot6 = moose.Table2( '/model/plot6' )
+ moose.connect( '/model/plot4', 'requestOut', s, 'getConc' )
+ moose.connect( '/model/plot5', 'requestOut', es, 'getConc' )
+ moose.connect( '/model/plot6', 'requestOut', '/model/compartment/s_xfer_endo', 'getConc' )
+
+def almostEq( a, b ):
+ return abs(a-b)/(a+b) < 5e-5
+
+def main( standalone = False ):
+ runtime = 100
+ makeModel()
+ moose.reinit()
+ moose.start( runtime )
+ assert( almostEq( moose.element( 'model/compartment/s' ).conc,
+ moose.element( '/model/endo/s' ).conc ) )
+ moose.delete( '/model' )
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+ main( standalone = True )
diff --git a/tests/python/test_Xreacs4.py b/tests/python/test_Xreacs4.py
new file mode 100644
index 0000000000000000000000000000000000000000..c655e4e5fe9727ed9e055887c006768924e27e47
--- /dev/null
+++ b/tests/python/test_Xreacs4.py
@@ -0,0 +1,93 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+## This program is part of 'MOOSE', the
+## Messaging Object Oriented Simulation Environment.
+## Copyright (C) 2014 Upinder S. Bhalla. and NCBS
+## It is made available under the terms of the
+## GNU Lesser General Public License version 2.1
+## See the file COPYING.LIB for the full notice.
+#########################################################################
+
+
+import math
+import numpy as np
+import moose
+import fixXreacs
+
+def makeModel():
+ # create container for model
+ num = 1 # number of compartments
+ model = moose.Neutral( '/model' )
+ compartment = moose.CylMesh( '/model/compartment' )
+ compartment.x1 = 1.0e-6 # Set it to a 1 micron single-voxel cylinder
+
+ # create molecules and reactions
+ s = moose.Pool( '/model/compartment/s' )
+ rXfer = moose.Reac( '/model/compartment/rXfer' )
+ #####################################################################
+ # Put in endo compartment. Add molecule s
+ endo = moose.EndoMesh( '/model/endo' )
+ endo.isMembraneBound = True
+ endo.surround = compartment
+ es = moose.Pool( '/model/endo/s' )
+ #####################################################################
+ moose.connect( rXfer, 'sub', s, 'reac' )
+ moose.connect( rXfer, 'prd', es, 'reac' )
+ volRatio = compartment.volume / endo.volume
+ rXfer.Kf = 0.04 # 0.04/sec
+ rXfer.Kb = 0.02 # 0.02/sec
+
+ #####################################################################
+ fixXreacs.fixXreacs( '/model' )
+ #fixXreacs.restoreXreacs( '/model' )
+ #fixXreacs.fixXreacs( '/model' )
+ #####################################################################
+
+ # Make solvers
+ ksolve = moose.Ksolve( '/model/compartment/ksolve' )
+ dsolve = moose.Dsolve( '/model/dsolve' )
+ eksolve = moose.Ksolve( '/model/endo/ksolve' )
+ edsolve = moose.Dsolve( '/model/endo/dsolve' )
+
+ stoich = moose.Stoich( '/model/compartment/stoich' )
+ stoich.compartment = compartment
+ stoich.ksolve = ksolve
+ stoich.dsolve = dsolve
+ stoich.path = "/model/compartment/##"
+ assert( dsolve.numPools == 2 )
+ s.vec.concInit = [1]*num
+
+ estoich = moose.Stoich( '/model/endo/stoich' )
+ estoich.compartment = endo
+ estoich.ksolve = eksolve
+ estoich.dsolve = edsolve
+ estoich.path = "/model/endo/##"
+ assert( edsolve.numPools == 1 )
+
+ edsolve.buildMeshJunctions( dsolve )
+
+ plot1 = moose.Table2( '/model/plot1' )
+ plot2 = moose.Table2( '/model/plot2' )
+ moose.connect( '/model/plot1', 'requestOut', s, 'getN' )
+ moose.connect( '/model/plot2', 'requestOut', es, 'getN' )
+ plot3 = moose.Table2( '/model/plot3' )
+ plot4 = moose.Table2( '/model/plot4' )
+ moose.connect( '/model/plot3', 'requestOut', s, 'getConc' )
+ moose.connect( '/model/plot4', 'requestOut', es, 'getConc' )
+
+def almostEq( a, b ):
+ return abs(a-b)/(a+b) < 5e-5
+
+def main( standalone = False ):
+ runtime = 100
+ displayInterval = 2
+ makeModel()
+ moose.reinit()
+ moose.start( runtime )
+ assert( almostEq( 2.0 * moose.element( 'model/compartment/s' ).conc,
+ moose.element( '/model/endo/s' ).conc ) )
+ moose.delete( '/model' )
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+ main( standalone = True )
diff --git a/tests/python/test_Xreacs4a.py b/tests/python/test_Xreacs4a.py
new file mode 100644
index 0000000000000000000000000000000000000000..73c6d54746c88d36238904116547f73969eed6b5
--- /dev/null
+++ b/tests/python/test_Xreacs4a.py
@@ -0,0 +1,94 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+## This program is part of 'MOOSE', the
+## Messaging Object Oriented Simulation Environment.
+## Copyright (C) 2014 Upinder S. Bhalla. and NCBS
+## It is made available under the terms of the
+## GNU Lesser General Public License version 2.1
+## See the file COPYING.LIB for the full notice.
+#########################################################################
+
+
+import math
+import numpy as np
+import moose
+import fixXreacs
+
+def makeModel():
+ # create container for model
+ num = 1 # number of compartments
+ model = moose.Neutral( '/model' )
+ compartment = moose.CylMesh( '/model/compartment' )
+ compartment.x1 = 1.0e-6 # Set it to a 1 micron single-voxel cylinder
+
+ # create molecules and reactions
+ s = moose.Pool( '/model/compartment/s' )
+ #####################################################################
+ # Put in endo compartment. Add molecule s
+ endo = moose.EndoMesh( '/model/endo' )
+ endo.isMembraneBound = True
+ endo.surround = compartment
+ es = moose.Pool( '/model/endo/s' )
+ rXfer = moose.Reac( '/model/endo/rXfer' )
+ #####################################################################
+ moose.connect( rXfer, 'sub', s, 'reac' )
+ moose.connect( rXfer, 'prd', es, 'reac' )
+ volRatio = compartment.volume / endo.volume
+ rXfer.Kf = 0.04 # 0.04/sec
+ rXfer.Kb = 0.02 # 0.02/sec
+
+ #####################################################################
+ fixXreacs.fixXreacs( '/model' )
+ #fixXreacs.restoreXreacs( '/model' )
+ #fixXreacs.fixXreacs( '/model' )
+ #####################################################################
+
+ # Make solvers
+ ksolve = moose.Ksolve( '/model/compartment/ksolve' )
+ dsolve = moose.Dsolve( '/model/dsolve' )
+ eksolve = moose.Ksolve( '/model/endo/ksolve' )
+ edsolve = moose.Dsolve( '/model/endo/dsolve' )
+
+ stoich = moose.Stoich( '/model/compartment/stoich' )
+ stoich.compartment = compartment
+ stoich.ksolve = ksolve
+ stoich.dsolve = dsolve
+ stoich.path = "/model/compartment/##"
+ assert( dsolve.numPools == 1 )
+ s.vec.concInit = [1]*num
+
+ estoich = moose.Stoich( '/model/endo/stoich' )
+ estoich.compartment = endo
+ estoich.ksolve = eksolve
+ estoich.dsolve = edsolve
+ estoich.path = "/model/endo/##"
+ assert( edsolve.numPools == 2 )
+
+ edsolve.buildMeshJunctions( dsolve )
+
+ plot1 = moose.Table2( '/model/plot1' )
+ plot2 = moose.Table2( '/model/plot2' )
+ moose.connect( '/model/plot1', 'requestOut', s, 'getN' )
+ moose.connect( '/model/plot2', 'requestOut', es, 'getN' )
+ plot3 = moose.Table2( '/model/plot3' )
+ plot4 = moose.Table2( '/model/plot4' )
+ moose.connect( '/model/plot3', 'requestOut', s, 'getConc' )
+ moose.connect( '/model/plot4', 'requestOut', es, 'getConc' )
+
+def almostEq( a, b ):
+ return abs(a-b)/(a+b) < 5e-5
+
+def main( standalone = False ):
+ runtime = 200
+ displayInterval = 2
+ makeModel()
+ moose.reinit()
+ moose.start( runtime )
+ assert( almostEq( 2.0 * moose.element( 'model/compartment/s' ).conc,
+ moose.element( '/model/endo/s' ).conc ) )
+ moose.delete( '/model' )
+
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+ main( standalone = True )
diff --git a/tests/python/test_Xreacs5.py b/tests/python/test_Xreacs5.py
new file mode 100644
index 0000000000000000000000000000000000000000..4dde2a47f1b673fbe9065d0f81fff2493e08a195
--- /dev/null
+++ b/tests/python/test_Xreacs5.py
@@ -0,0 +1,101 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+## This program is part of 'MOOSE', the
+## Messaging Object Oriented Simulation Environment.
+## Copyright (C) 2014 Upinder S. Bhalla. and NCBS
+## It is made available under the terms of the
+## GNU Lesser General Public License version 2.1
+## See the file COPYING.LIB for the full notice.
+#########################################################################
+
+
+import math
+import numpy as np
+import moose
+import fixXreacs
+
+def makeModel():
+ # create container for model
+ num = 1 # number of compartments
+ model = moose.Neutral( '/model' )
+ compartment = moose.CylMesh( '/model/compartment' )
+ compartment.x1 = 1.0e-6 # Set it to a 1 micron single-voxel cylinder
+
+ # create molecules and reactions
+ s = moose.Pool( '/model/compartment/s' )
+ rXfer = moose.Reac( '/model/compartment/rXfer' )
+ #####################################################################
+ # Put in endo compartment. Add molecule s
+ endo = moose.EndoMesh( '/model/endo' )
+ endo.isMembraneBound = True
+ endo.surround = compartment
+ es = moose.Pool( '/model/endo/s' )
+ erXfer = moose.Reac( '/model/endo/erXfer' )
+ #####################################################################
+ moose.connect( erXfer, 'sub', es, 'reac' )
+ moose.connect( erXfer, 'prd', s, 'reac' )
+ moose.connect( rXfer, 'sub', s, 'reac' )
+ moose.connect( rXfer, 'prd', es, 'reac' )
+ rXfer.Kf = 0.04 # 0.04/sec
+ rXfer.Kb = 0.0 # 0.00/sec
+ erXfer.Kf = 0.16 # 0.16/sec
+ erXfer.Kb = 0.0 # 0.00/sec
+
+ #####################################################################
+ fixXreacs.fixXreacs( '/model' )
+ fixXreacs.restoreXreacs( '/model' )
+ fixXreacs.fixXreacs( '/model' )
+ #####################################################################
+
+ # Make solvers
+ ksolve = moose.Ksolve( '/model/compartment/ksolve' )
+ dsolve = moose.Dsolve( '/model/dsolve' )
+ eksolve = moose.Ksolve( '/model/endo/ksolve' )
+ edsolve = moose.Dsolve( '/model/endo/dsolve' )
+
+ stoich = moose.Stoich( '/model/compartment/stoich' )
+ stoich.compartment = compartment
+ stoich.ksolve = ksolve
+ stoich.dsolve = dsolve
+ stoich.path = "/model/compartment/##"
+ assert( dsolve.numPools == 2 )
+ s.vec.concInit = [1]*num
+
+ estoich = moose.Stoich( '/model/endo/stoich' )
+ estoich.compartment = endo
+ estoich.ksolve = eksolve
+ estoich.dsolve = edsolve
+ estoich.path = "/model/endo/##"
+ assert( edsolve.numPools == 2 )
+
+ edsolve.buildMeshJunctions( dsolve )
+
+ plot1 = moose.Table2( '/model/plot1' )
+ plot2 = moose.Table2( '/model/plot2' )
+ moose.connect( '/model/plot1', 'requestOut', s, 'getN' )
+ moose.connect( '/model/plot2', 'requestOut', es, 'getN' )
+ plot3 = moose.Table2( '/model/plot3' )
+ plot4 = moose.Table2( '/model/plot4' )
+ moose.connect( '/model/plot3', 'requestOut', s, 'getConc' )
+ moose.connect( '/model/plot4', 'requestOut', es, 'getConc' )
+
+def almostEq( a, b ):
+ #print a, b, (a-b)/(a+b)
+ return abs(a-b)/(a+b) < 5e-5
+
+def main( standalone = False ):
+ for i in range( 10, 18):
+ moose.setClock( i, 0.001 )
+ runtime = 100
+ makeModel()
+ moose.reinit()
+ moose.start( runtime )
+
+ assert( almostEq( 2.0 * moose.element( 'model/compartment/s' ).conc,
+ moose.element( '/model/endo/s' ).conc ) )
+
+ moose.delete( '/model' )
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+ main( standalone = True )
diff --git a/tests/python/test_Xreacs5a.py b/tests/python/test_Xreacs5a.py
new file mode 100644
index 0000000000000000000000000000000000000000..126f918238b6019a65ca0f4052aadb8f1b258be3
--- /dev/null
+++ b/tests/python/test_Xreacs5a.py
@@ -0,0 +1,99 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+## This program is part of 'MOOSE', the
+## Messaging Object Oriented Simulation Environment.
+## Copyright (C) 2014 Upinder S. Bhalla. and NCBS
+## It is made available under the terms of the
+## GNU Lesser General Public License version 2.1
+## See the file COPYING.LIB for the full notice.
+#########################################################################
+
+
+import math
+import numpy as np
+import moose
+import fixXreacs
+
+def makeModel():
+ # create container for model
+ num = 1 # number of compartments
+ model = moose.Neutral( '/model' )
+ compartment = moose.CylMesh( '/model/compartment' )
+ compartment.x1 = 1.0e-6 # Set it to a 1 micron single-voxel cylinder
+
+ # create molecules and reactions
+ s = moose.Pool( '/model/compartment/s' )
+ rXfer = moose.Reac( '/model/compartment/rXfer' )
+ #####################################################################
+ # Put in endo compartment. Add molecule s
+ endo = moose.EndoMesh( '/model/endo' )
+ endo.isMembraneBound = True
+ endo.surround = compartment
+ es = moose.Pool( '/model/endo/s' )
+ erXfer = moose.Reac( '/model/compartment/erXfer' )
+ #####################################################################
+ moose.connect( erXfer, 'sub', es, 'reac' )
+ moose.connect( erXfer, 'prd', s, 'reac' )
+ moose.connect( rXfer, 'sub', s, 'reac' )
+ moose.connect( rXfer, 'prd', es, 'reac' )
+ rXfer.Kf = 0.04 # 0.04/sec
+ rXfer.Kb = 0.0 # 0.02/sec
+ erXfer.Kf = 0.02 # 0.04/sec
+ erXfer.Kb = 0.0 # 0.02/sec
+
+ #####################################################################
+ fixXreacs.fixXreacs( '/model' )
+ fixXreacs.restoreXreacs( '/model' )
+ fixXreacs.fixXreacs( '/model' )
+ #####################################################################
+ rx = moose.element( '/model/compartment/rXfer' )
+ erx = moose.element( '/model/compartment/erXfer' )
+
+ # Make solvers
+ ksolve = moose.Ksolve( '/model/compartment/ksolve' )
+ dsolve = moose.Dsolve( '/model/dsolve' )
+ eksolve = moose.Ksolve( '/model/endo/ksolve' )
+ edsolve = moose.Dsolve( '/model/endo/dsolve' )
+
+ stoich = moose.Stoich( '/model/compartment/stoich' )
+ stoich.compartment = compartment
+ stoich.ksolve = ksolve
+ stoich.dsolve = dsolve
+ stoich.path = "/model/compartment/##"
+ assert( dsolve.numPools == 2 )
+ s.vec.concInit = [1]*num
+
+ estoich = moose.Stoich( '/model/endo/stoich' )
+ estoich.compartment = endo
+ estoich.ksolve = eksolve
+ estoich.dsolve = edsolve
+ estoich.path = "/model/endo/##"
+ assert( edsolve.numPools == 1 )
+
+ edsolve.buildMeshJunctions( dsolve )
+
+ plot1 = moose.Table2( '/model/plot1' )
+ plot2 = moose.Table2( '/model/plot2' )
+ moose.connect( '/model/plot1', 'requestOut', s, 'getN' )
+ moose.connect( '/model/plot2', 'requestOut', es, 'getN' )
+ plot3 = moose.Table2( '/model/plot3' )
+ plot4 = moose.Table2( '/model/plot4' )
+ moose.connect( '/model/plot3', 'requestOut', s, 'getConc' )
+ moose.connect( '/model/plot4', 'requestOut', es, 'getConc' )
+
+def almostEq( a, b ):
+ return abs(a-b)/(a+b) < 5e-5
+
+def main( standalone = False ):
+ runtime = 200
+ displayInterval = 2
+ makeModel()
+ moose.reinit()
+ moose.start( runtime )
+ assert( almostEq( 2.0 * moose.element( 'model/compartment/s' ).n,
+ moose.element( '/model/endo/s' ).n ) )
+ moose.delete( '/model' )
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+ main( standalone = True )
diff --git a/tests/python/test_Xreacs6.py b/tests/python/test_Xreacs6.py
new file mode 100644
index 0000000000000000000000000000000000000000..35f21c5be50c28cc7593795b9a0645020c9ff1ed
--- /dev/null
+++ b/tests/python/test_Xreacs6.py
@@ -0,0 +1,99 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+## This program is part of 'MOOSE', the
+## Messaging Object Oriented Simulation Environment.
+## Copyright (C) 2018 Upinder S. Bhalla. and NCBS
+## It is made available under the terms of the
+## GNU General Public License version 3 or later.
+## See the file COPYING.LIB for the full notice.
+#########################################################################
+
+
+import math
+import numpy as np
+import moose
+import fixXreacs
+
+def makeModel():
+ # create container for model
+ num = 1 # number of compartments
+ model = moose.Neutral( '/model' )
+ compartment = moose.CylMesh( '/model/compartment' )
+ compartment.x1 = 1.0e-6 # Set it to a 1 micron single-voxel cylinder
+
+ # create molecules and reactions
+ s = moose.Pool( '/model/compartment/s' )
+ t = moose.Pool( '/model/compartment/t' )
+ rXfer = moose.Reac( '/model/compartment/rXfer' )
+ #####################################################################
+ # Put in endo compartment. Add molecule s
+ endo = moose.EndoMesh( '/model/endo' )
+ endo.isMembraneBound = True
+ endo.surround = compartment
+ es = moose.Pool( '/model/endo/s' )
+ et = moose.Pool( '/model/endo/t' )
+ #####################################################################
+ moose.connect( rXfer, 'sub', s, 'reac' )
+ moose.connect( rXfer, 'sub', t, 'reac' )
+ moose.connect( rXfer, 'prd', es, 'reac' )
+ moose.connect( rXfer, 'prd', et, 'reac' )
+ rXfer.Kf = 0.02 # 0.02/mM/sec
+ rXfer.Kb = 0.02 # 0.02/mM/sec
+
+ #####################################################################
+ fixXreacs.fixXreacs( '/model' )
+ #fixXreacs.restoreXreacs( '/model' )
+ #fixXreacs.fixXreacs( '/model' )
+ #####################################################################
+ # Make solvers
+ ksolve = moose.Ksolve( '/model/compartment/ksolve' )
+ dsolve = moose.Dsolve( '/model/dsolve' )
+ eksolve = moose.Ksolve( '/model/endo/ksolve' )
+ edsolve = moose.Dsolve( '/model/endo/dsolve' )
+
+ stoich = moose.Stoich( '/model/compartment/stoich' )
+ stoich.compartment = compartment
+ stoich.ksolve = ksolve
+ stoich.dsolve = dsolve
+ stoich.path = "/model/compartment/##"
+ assert( dsolve.numPools == 4 )
+ s.vec.concInit = [1]*num
+ t.vec.concInit = [1]*num
+
+ estoich = moose.Stoich( '/model/endo/stoich' )
+ estoich.compartment = endo
+ estoich.ksolve = eksolve
+ estoich.dsolve = edsolve
+ estoich.path = "/model/endo/##"
+ assert( edsolve.numPools == 2 )
+
+ edsolve.buildMeshJunctions( dsolve )
+
+ plot1 = moose.Table2( '/model/plot1' )
+ plot2 = moose.Table2( '/model/plot2' )
+ moose.connect( '/model/plot1', 'requestOut', s, 'getN' )
+ moose.connect( '/model/plot2', 'requestOut', es, 'getN' )
+ plot3 = moose.Table2( '/model/plot3' )
+ plot4 = moose.Table2( '/model/plot4' )
+ moose.connect( '/model/plot3', 'requestOut', s, 'getConc' )
+ moose.connect( '/model/plot4', 'requestOut', es, 'getConc' )
+
+def almostEq( a, b ):
+ #print a, b, (a-b)/(a+b)
+ return abs(a-b)/(a+b) < 5e-5
+
+def main( standalone = False ):
+ for i in range( 10, 18):
+ moose.setClock( i, 0.01 )
+ runtime = 100
+ displayInterval = 2
+ makeModel()
+ moose.reinit()
+ moose.start( runtime )
+ assert( almostEq( moose.element( 'model/compartment/s' ).conc,
+ moose.element( '/model/endo/s' ).conc ) )
+ moose.delete( '/model' )
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+ main( standalone = True )
diff --git a/tests/python/test_Xreacs7.py b/tests/python/test_Xreacs7.py
new file mode 100644
index 0000000000000000000000000000000000000000..913a7a1cc791ac674967bc9360f5f5cdd083afe7
--- /dev/null
+++ b/tests/python/test_Xreacs7.py
@@ -0,0 +1,114 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+## This program is part of 'MOOSE', the
+## Messaging Object Oriented Simulation Environment.
+## Copyright (C) 2018 Upinder S. Bhalla. and NCBS
+## It is made available under the terms of the
+## GNU General Public License version 3 or later.
+## See the file COPYING.LIB for the full notice.
+##
+## This file makes u + t <=====> s where u is in a different compt from t,s
+#########################################################################
+
+
+import math
+import numpy as np
+import moose
+import fixXreacs
+
+def makeModel():
+ # create container for model
+ num = 1 # number of compartments
+ model = moose.Neutral( '/model' )
+ compartment = moose.CylMesh( '/model/compartment' )
+ compartment.x1 = 1.0e-6 # Set it to a 1 micron single-voxel cylinder
+
+ # create molecules and reactions
+ u = moose.Pool( '/model/compartment/u' )
+ #####################################################################
+ # Put in endo compartment. Add molecule s
+ endo = moose.EndoMesh( '/model/endo' )
+ endo.isMembraneBound = True
+ endo.surround = compartment
+ rXfer = moose.Reac( '/model/endo/rXfer' )
+ et = moose.Pool( '/model/endo/t' )
+ es = moose.Pool( '/model/endo/s' )
+ #####################################################################
+ moose.connect( rXfer, 'sub', u, 'reac' )
+ moose.connect( rXfer, 'sub', et, 'reac' )
+ moose.connect( rXfer, 'prd', es, 'reac' )
+ u.concInit = 1.0
+ et.concInit = 1.0
+
+ #####################################################################
+ # [u0] = 1 in compt, [t0] = 1 in endo, [s0] = 0
+ # [u] + [s]/8 = [u0] ; [t] + [s] = [t0]; nu + ns = nu0, nt + ns = nt0
+ # At equil, numKf*nu*nt = numKb*ns
+ # Express all # in terms of ns.
+ # nu = nu0-ns; nt = nt0-ns Also, nu0 = 8*nt0
+ # So numKf*(nu0-ns)*(nt0-ns) = numKb*ns
+ # Target level is nt = ns = nt0/2
+ # So numKf*( 8nt0 - nt0/2)*nt0/2 = numKb*nt0/2
+ # So 7.5*nt0 = numKb/numKf
+ rXfer.numKb = 0.1
+ rXfer.numKf = 0.1/(7.5 * et.nInit)
+ #print( "Rates = {}, {}".format( rXfer.Kf, rXfer.Kb ))
+ #####################################################################
+ fixXreacs.fixXreacs( '/model' )
+ #fixXreacs.restoreXreacs( '/model' )
+ #fixXreacs.fixXreacs( '/model' )
+ #####################################################################
+
+ # Make solvers
+ ksolve = moose.Ksolve( '/model/compartment/ksolve' )
+ dsolve = moose.Dsolve( '/model/compartment/dsolve' )
+ eksolve = moose.Ksolve( '/model/endo/ksolve' )
+ edsolve = moose.Dsolve( '/model/endo/dsolve' )
+
+ stoich = moose.Stoich( '/model/compartment/stoich' )
+ stoich.compartment = compartment
+ stoich.ksolve = ksolve
+ stoich.dsolve = dsolve
+ stoich.path = "/model/compartment/##"
+ assert( dsolve.numPools == 1 )
+
+ estoich = moose.Stoich( '/model/endo/stoich' )
+ estoich.compartment = endo
+ estoich.ksolve = eksolve
+ estoich.dsolve = edsolve
+ estoich.path = "/model/endo/##"
+ assert( edsolve.numPools == 3 )
+
+ edsolve.buildMeshJunctions( dsolve )
+
+ plot1 = moose.Table2( '/model/plot1' )
+ plot2 = moose.Table2( '/model/plot2' )
+ plot3 = moose.Table2( '/model/plot3' )
+ moose.connect( '/model/plot1', 'requestOut', u, 'getN' )
+ moose.connect( '/model/plot2', 'requestOut', et, 'getN' )
+ moose.connect( '/model/plot3', 'requestOut', es, 'getN' )
+ plot4 = moose.Table2( '/model/plot4' )
+ plot5 = moose.Table2( '/model/plot5' )
+ plot6 = moose.Table2( '/model/plot6' )
+ moose.connect( '/model/plot4', 'requestOut', u, 'getConc' )
+ moose.connect( '/model/plot5', 'requestOut', et, 'getConc' )
+ moose.connect( '/model/plot6', 'requestOut', es, 'getConc' )
+
+def almostEq( a, b ):
+ #print a, b, (a-b)/(a+b)
+ return abs(a-b)/(a+b) < 5e-5
+
+def main( standalone = False ):
+ runtime = 100
+ displayInterval = 2
+ makeModel()
+ moose.reinit()
+ moose.start( runtime )
+
+ assert( almostEq( moose.element( 'model/endo/t' ).conc,
+ moose.element( '/model/endo/s' ).conc ) )
+ moose.delete( '/model' )
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+ main( standalone = True )
diff --git a/tests/python/test_Xreacs8.py b/tests/python/test_Xreacs8.py
new file mode 100644
index 0000000000000000000000000000000000000000..15bb0f01a4a95687085d7eb3f39729d4207b3b3a
--- /dev/null
+++ b/tests/python/test_Xreacs8.py
@@ -0,0 +1,109 @@
+# -*- coding: utf-8 -*-
+#########################################################################
+## This program is part of 'MOOSE', the
+## Messaging Object Oriented Simulation Environment.
+## Copyright (C) 2014 Upinder S. Bhalla. and NCBS
+## It is made available under the terms of the
+## GNU Lesser General Public License version 2.1
+## See the file COPYING.LIB for the full notice.
+## Here we set up equal Kf and Kb in a reversible reaction across a
+## 1-voxel cyl compt and an internal endoMesh, having a smaller volume.
+## \
+## COMPT: 2 s <===> / 2 s :ENDO
+## \
+##
+## This becomes:
+## \
+## COMPT: 2 s <===> 2 s_xfer_endo / 2s :ENDO
+## \
+##
+#########################################################################
+
+
+import math
+import numpy as np
+import moose
+import fixXreacs
+
+def makeModel():
+ # create container for model
+ num = 1 # number of compartments
+ model = moose.Neutral( '/model' )
+ compartment = moose.CylMesh( '/model/compartment' )
+ compartment.x1 = 1.0e-6 # Set it to a 1 micron single-voxel cylinder
+
+ # create molecules and reactions
+ s = moose.Pool( '/model/compartment/s' )
+ rXfer = moose.Reac( '/model/compartment/rXfer' )
+ #####################################################################
+ # Put in endo compartment. Add molecule s
+ endo = moose.EndoMesh( '/model/endo' )
+ endo.isMembraneBound = True
+ endo.surround = compartment
+ es = moose.Pool( '/model/endo/s' )
+ #####################################################################
+ moose.connect( rXfer, 'sub', s, 'reac' )
+ moose.connect( rXfer, 'sub', s, 'reac' )
+ moose.connect( rXfer, 'prd', es, 'reac' )
+ moose.connect( rXfer, 'prd', es, 'reac' )
+ rXfer.Kf = 0.01 # 0.01/sec
+ rXfer.Kb = 0.01 # 0.01/sec
+
+ #####################################################################
+ fixXreacs.fixXreacs( '/model' )
+ fixXreacs.restoreXreacs( '/model' )
+ fixXreacs.fixXreacs( '/model' )
+ #####################################################################
+
+ # Make solvers
+ ksolve = moose.Ksolve( '/model/compartment/ksolve' )
+ dsolve = moose.Dsolve( '/model/dsolve' )
+ eksolve = moose.Ksolve( '/model/endo/ksolve' )
+ edsolve = moose.Dsolve( '/model/endo/dsolve' )
+
+ stoich = moose.Stoich( '/model/compartment/stoich' )
+ stoich.compartment = compartment
+ stoich.ksolve = ksolve
+ stoich.dsolve = dsolve
+ stoich.path = "/model/compartment/##"
+ assert( dsolve.numPools == 2 )
+ s.vec.concInit = [1]*num
+
+ estoich = moose.Stoich( '/model/endo/stoich' )
+ estoich.compartment = endo
+ estoich.ksolve = eksolve
+ estoich.dsolve = edsolve
+ estoich.path = "/model/endo/##"
+ assert( edsolve.numPools == 1 )
+
+ edsolve.buildMeshJunctions( dsolve )
+
+ plot1 = moose.Table2( '/model/plot1' )
+ plot2 = moose.Table2( '/model/plot2' )
+ plot3 = moose.Table2( '/model/plot3' )
+ moose.connect( '/model/plot1', 'requestOut', s, 'getN' )
+ moose.connect( '/model/plot2', 'requestOut', es, 'getN' )
+ moose.connect( '/model/plot3', 'requestOut', '/model/compartment/s_xfer_endo', 'getN' )
+ plot4 = moose.Table2( '/model/plot4' )
+ plot5 = moose.Table2( '/model/plot5' )
+ plot6 = moose.Table2( '/model/plot6' )
+ moose.connect( '/model/plot4', 'requestOut', s, 'getConc' )
+ moose.connect( '/model/plot5', 'requestOut', es, 'getConc' )
+ moose.connect( '/model/plot6', 'requestOut', '/model/compartment/s_xfer_endo', 'getConc' )
+
+def almostEq( a, b ):
+ return abs(a-b)/(a+b) < 5e-5
+
+def main( standalone = False ):
+ runtime = 100
+ makeModel()
+ moose.reinit()
+ moose.start( runtime )
+ assert( almostEq( moose.element( 'model/compartment/s' ).conc,
+ moose.element( '/model/endo/s' ).conc ) )
+ moose.delete( '/model' )
+
+
+# Run the 'main' if this script is executed standalone.
+if __name__ == '__main__':
+ main( standalone = True )
diff --git a/tests/python/test_connectionLists.py b/tests/python/test_connectionLists.py
index 057cd5a47749d474f6fb05e1c2e2d987f6b69367..fcd7786725615960e1d93b02834c3b9b189af151 100644
--- a/tests/python/test_connectionLists.py
+++ b/tests/python/test_connectionLists.py
@@ -66,8 +66,14 @@ def makeGlobalBalanceNetwork():
inhibMatrix.setRandomConnectivity(
params['stimToInhProb'], params['stimToInhSeed'] )
cl = inhibMatrix.connectionList
- expectedCl = [ 1,4,13,13,26,42,52,56,80,82,95,97,4,9,0,9,4,8,0,6,1,6,6,7]
- assert list(cl) == expectedCl, "Expected %s, got %s" % (expectedCl, cl )
+
+ # This can change when random-number generator changes.
+ # This was before we used c++11 <random> to generate random numbers. This
+ # test has changes on Tuesday 31 July 2018 11:12:35 AM IST
+ # expectedCl = [ 1,4,13,13,26,42,52,56,80,82,95,97,4,9,0,9,4,8,0,6,1,6,6,7]
+ expectedCl=[0,6,47,50,56,67,98,2,0,3,5,4,8,3]
+
+ assert list(cl) == expectedCl, "Expected %s, got %s" % (expectedCl, cl)
temp = moose.connect( stim, 'spikeOut', ov, 'addSpike', 'Sparse' )
excMatrix = moose.element( temp )
@@ -80,7 +86,9 @@ def makeGlobalBalanceNetwork():
params['inhToOutProb'], params['inhToOutSeed'] )
# print("ConnMtxEntries: ", inhibMatrix.numEntries, excMatrix.numEntries, negFFMatrix.numEntries)
- assert (12, 57, 48) == (inhibMatrix.numEntries, excMatrix.numEntries, negFFMatrix.numEntries)
+ got = (inhibMatrix.numEntries, excMatrix.numEntries, negFFMatrix.numEntries)
+ expected = (7, 62, 55)
+ assert expected == got, "Expected %s, Got %s" % (expected,got)
cl = negFFMatrix.connectionList
numInhSyns = [ ]
@@ -93,7 +101,9 @@ def makeGlobalBalanceNetwork():
if i.synapse.num > 0:
i.synapse.weight = params['wtStimToInh']
- assert numInhSyns == [2,1,0,0,2,0,3,1,1,2]
+ # expected = [2,1,0,0,2,0,3,1,1,2]
+ expected = [1, 0, 1, 2, 1, 1, 0, 0, 1, 0]
+ assert numInhSyns == expected, "Expected %s, got %s" % (expected,numInhSyns)
for i in moose.vec( outsyn ):
nov += i.synapse.num
@@ -105,12 +115,12 @@ def makeGlobalBalanceNetwork():
if i.synapse.num > 0:
i.synapse.weight = params['wtInhToOut']
- # print("SUMS: ", sum( iv.numField ), sum( ov.numField ), sum( oiv.numField ))
- assert [4,49,9] == [sum( iv.numField ), sum( ov.numField ), sum( oiv.numField )]
- # print("SUMS2: ", niv, nov, noiv)
- assert [12,57,48] == [ niv, nov, noiv ]
- # print("SUMS3: ", sum( insyn.vec.numSynapses ), sum( outsyn.vec.numSynapses ), sum( outInhSyn.vec.numSynapses ))
- assert [12, 57, 48 ] == [ sum( insyn.vec.numSynapses ), sum( outsyn.vec.numSynapses ), sum( outInhSyn.vec.numSynapses ) ]
+ print("SUMS: ", sum( iv.numField ), sum( ov.numField ), sum( oiv.numField ))
+ assert [1, 64, 25] == [sum( iv.numField ), sum( ov.numField ), sum( oiv.numField )]
+ print("SUMS2: ", niv, nov, noiv)
+ assert [7, 62, 55] == [ niv, nov, noiv ]
+ print("SUMS3: ", sum( insyn.vec.numSynapses ), sum( outsyn.vec.numSynapses ), sum( outInhSyn.vec.numSynapses ))
+ assert [7,62,55] == [ sum( insyn.vec.numSynapses ), sum( outsyn.vec.numSynapses ), sum( outInhSyn.vec.numSynapses ) ]
# print(oiv.numField)
# print(insyn.vec[1].synapse.num)
diff --git a/tests/python/test_difshells.py b/tests/python/test_difshells.py
index 4ba00d8a59d15fc53de39e4bd3b07c34b0eff0d8..d9e29fe5d032b8a876a8cb0beeb2850e6b8bb0ab 100644
--- a/tests/python/test_difshells.py
+++ b/tests/python/test_difshells.py
@@ -1,10 +1,36 @@
# -*- coding: utf-8 -*-
import moose
+print( 'Using moose from %s. VERSION=%s' % (moose.__file__, moose.__version__) )
import numpy as np
import chan_proto
import param_chan
-from params import *
+t_stop = 10
+dend_diameter = 2.2627398e-6
+dend_length = 1.131369936e-6
+Cm = 4.021231698e-12
+Rm = 1865100032
+Em = -0.07100000232
+Vm_0 = -0.0705
+dt = 50e-6
+spines_no = 0
+difshell_no = 2
+difshell_name = "Ca_shell"
+Ca_basal = 50e-6
+Ca_initial = Ca_basal*200
+dca = 200.0e-12
+difbuff_no = 1
+difbuff_name = "Buff"
+btotal = 80.0e-3
+kf = 0.028e6
+kb = 19.6
+d = 66e-12
+inject = 0.1e-9
+gbar = 1
+#MMpump
+km = 0.3e-3
+kcat = 85e-22
+pumps = 1
def linoid(x, param):
den = (param[2] + np.exp((V + param[3]) / param[4]))
@@ -93,7 +119,6 @@ def addOneChan(chanpath, gbar,comp):
moose.connect(chan, "channelOut", comp, "handleChannel")
return chan
-
if __name__ == '__main__':
lib = moose.Neutral('/library')
for tick in range(0, 7):
diff --git a/tests/python/test_kkit.py b/tests/python/test_kkit.py
index ba194d63c44f58abb5f0c1d8a3235bed5f42f92e..0b7c37583ace6fbd5c61d8425dad5e69314a8f43 100644
--- a/tests/python/test_kkit.py
+++ b/tests/python/test_kkit.py
@@ -24,7 +24,7 @@ def main():
if ( len( sys.argv ) == 4 ):
solver = sys.argv[3]
modelId = moose.loadModel( mfile, 'model')
- moose.mooseaddChemSolver('model',solver)
+ moose.mooseAddChemSolver('model',solver)
# Increase volume so that the stochastic solver gssa
# gives an interesting output
diff --git a/tests/python/test_muparser.py b/tests/python/test_muparser.py
index 7adf0e26757604cb78cb53983cd5399fce2fa7a0..d5f92311f14fd73c03cca91bfcb256fb27ad7bd6 100644
--- a/tests/python/test_muparser.py
+++ b/tests/python/test_muparser.py
@@ -8,6 +8,8 @@ Modified from https://elifesciences.org/articles/25827 , Fig4.py
import sys
import os
import numpy as np
+import matplotlib as mpl
+mpl.use('Agg')
import sys
import numpy as np
import moose
diff --git a/tests/python/test_negative_value_flag.py b/tests/python/test_negative_value_flag.py
index 7b073975de42881f5abab9f8cb4f40c6f029e12f..70861540478ea85c89b2626ce5aebc41b2954abf 100644
--- a/tests/python/test_negative_value_flag.py
+++ b/tests/python/test_negative_value_flag.py
@@ -36,7 +36,7 @@ def main():
solver = sys.argv[3]
modelId = moose.loadModel( mfile, 'model')
- moose.mooseaddChemSolver('model',solver)
+ moose.mooseAddChemSolver('model',solver)
moose.element( '/model/kinetics/neuroNOS/nNOS.arg' ).concInit = 0.1
moose.reinit()
moose.start( runtime )
diff --git a/tests/python/test_neuroml2.py b/tests/python/test_neuroml2.py
index 5155515d12e139bef053aaba01f3b9b2c219b387..8460c092195f22de18a256cc7371045a8e0a192c 100644
--- a/tests/python/test_neuroml2.py
+++ b/tests/python/test_neuroml2.py
@@ -1,43 +1,7 @@
# -*- coding: utf-8 -*-
# test_neurom2.py, modified from run_cell.py
-# Description:
-# Author:
# Maintainer: P Gleeson, Dilawar Singh
-# Version:
-# URL:
-# Keywords:
-# Compatibility:
-#
-#
-
-# Commentary:
-#
-#
-#
-#
-
-# Change log:
-#
-#
-#
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 3, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street, Fifth
-# Floor, Boston, MA 02110-1301, USA.
-#
-#
-
+# This test is not robust.
# Code:
from __future__ import absolute_import, print_function, division
@@ -49,7 +13,7 @@ import os
import numpy as np
SCRIPT_DIR = os.path.dirname( os.path.realpath( __file__ ) )
-
+
def run( nogui = True ):
global SCRIPT_DIR
filename = os.path.join(SCRIPT_DIR, 'test_files/passiveCell.nml' )
@@ -57,26 +21,25 @@ def run( nogui = True ):
nml = moose.mooseReadNML2( filename )
if not nml:
mu.warn( "Failed to parse NML2 file" )
- return
+ return
assert nml, "Expecting NML2 object"
msoma = nml.getComp(nml.doc.networks[0].populations[0].id,0,0)
data = moose.Neutral('/data')
pg = nml.getInput('pulseGen1')
-
+
inj = moose.Table('%s/pulse' % (data.path))
moose.connect(inj, 'requestOut', pg, 'getOutputValue')
-
-
+
vm = moose.Table('%s/Vm' % (data.path))
moose.connect(vm, 'requestOut', msoma, 'getVm')
-
+
simtime = 150e-3
moose.reinit()
moose.start(simtime)
print("Finished simulation!")
t = np.linspace(0, simtime, len(vm.vector))
- yvec = vm.vector
+ yvec = vm.vector
injvec = inj.vector * 1e12
m1, u1 = np.mean( yvec ), np.std( yvec )
m2, u2 = np.mean( injvec ), np.std( injvec )
diff --git a/tests/python/test_random_num.py b/tests/python/test_random_num.py
new file mode 100644
index 0000000000000000000000000000000000000000..9be47e932b72742ea5c357e5c74cea94e92141db
--- /dev/null
+++ b/tests/python/test_random_num.py
@@ -0,0 +1,59 @@
+# -*- coding: utf-8 -*-
+"""test_random_num.py:
+
+"""
+
+__author__ = "Dilawar Singh"
+__copyright__ = "Copyright 2017-, Dilawar Singh"
+__version__ = "1.0.0"
+__maintainer__ = "Dilawar Singh"
+__email__ = "dilawars@ncbs.res.in"
+__status__ = "Development"
+
+import sys
+import os
+import numpy as np
+import moose
+
+try:
+ reload
+except NameError:
+ # Python 3
+ from imp import reload
+
+def unequal():
+ rand1, rand2 = [], []
+ N = 10
+ for i in range( N ):
+ x = moose.rand()
+ rand1.append( x )
+ reload( moose )
+ for i in range( N ):
+ x = moose.rand()
+ rand2.append( x )
+
+ assert not np.equal( rand1, rand2 ).all()
+
+def equal():
+ rand1, rand2 = [], []
+ N = 10
+ moose.seed( 10 )
+ for i in range( N ):
+ x = moose.rand()
+ rand1.append( x )
+
+ reload( moose )
+ moose.seed( 10 )
+ for i in range( N ):
+ x = moose.rand()
+ rand2.append( x )
+
+ assert np.equal( rand1, rand2 ).all()
+
+def main( ):
+ unequal()
+ equal()
+
+if __name__ == '__main__':
+ main()
+
diff --git a/tests/python/test_rdesigneur.py b/tests/python/test_rdesigneur.py
index 2972a3c06f71ae4f1312fbdae1282e84fe136bae..f53ac93f15bf7d92dae83afb57b112eb2dbfa152 100644
--- a/tests/python/test_rdesigneur.py
+++ b/tests/python/test_rdesigneur.py
@@ -11,6 +11,8 @@ __status__ = "Development"
import sys
import os
+import matplotlib as mpl
+mpl.use('Agg')
import numpy as np
import moose
import rdesigneur as rd
diff --git a/tests/python/test_utils.py b/tests/python/test_utils.py
deleted file mode 100644
index a57633b84eb83766bbe848312947c472b0b7ee5a..0000000000000000000000000000000000000000
--- a/tests/python/test_utils.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-import moose
-import moose.utils as mu
-
-def main( ):
- print( dir( mu ) )
- mu.info( 'Hellow' )
-
-if __name__ == '__main__':
- main()
diff --git a/utility/Annotator.cpp b/utility/Annotator.cpp
index 184ab6b668df8c1dfd06ce405b2182a3fc6e63ea..8dca2186f3cce73ad9db840ba7661c6e04f608ac 100644
--- a/utility/Annotator.cpp
+++ b/utility/Annotator.cpp
@@ -118,7 +118,7 @@ static const Cinfo* annotatorCinfo = Annotator::initCinfo();
Annotator::Annotator()
: x_( 0.0 ), y_( 0.0 ), z_( 0.0 ),
notes_( "" ), color_( "white" ), textColor_( "black" ),
- icon_( "sphere" ),solver_( "gsl"),runtime_(100.0),dirpath_(""),modeltype_("")
+ icon_( "sphere" ),solver_( "ee"),runtime_(100.0),dirpath_(""),modeltype_("")
{
;
}
diff --git a/utility/cnpy.cpp b/utility/cnpy.cpp
index 4acc65580e111f05df03dcbfb3518173df9cd61e..131df10ce2794a27e20e46964cefe6ea64285a95 100644
--- a/utility/cnpy.cpp
+++ b/utility/cnpy.cpp
@@ -85,7 +85,11 @@ bool is_valid_numpy_file( FILE* fp )
{
assert( fp );
char buffer[__pre__size__];
- fread( buffer, sizeof(char), __pre__size__, fp );
+ size_t nr = fread( buffer, sizeof(char), __pre__size__, fp );
+
+ if( 0 == nr )
+ return false;
+
bool equal = true;
// Check for equality
for(size_t i = 0; i < __pre__size__; i++ )
diff --git a/utility/matrix_util.cpp b/utility/matrix_util.cpp
index 7db63a81721337d3b87fbb71d083d066d53d47bd..fecb4a4b92bd71fc2e1e35aca87278eaf9330bab 100644
--- a/utility/matrix_util.cpp
+++ b/utility/matrix_util.cpp
@@ -17,7 +17,7 @@
* =====================================================================================
*/
-#ifdef USE_BOOST
+#ifdef USE_BOOST_ODE
#include "matrix_util.h"
@@ -119,4 +119,4 @@ unsigned int rankUsingBoost( ublas::matrix<value_type>& U )
return i + 1;
}
-#endif /* ----- not USE_BOOST ----- */
+#endif /* ----- not USE_BOOST_ODE ----- */
diff --git a/utility/matrix_util.h b/utility/matrix_util.h
index 9b232abbc1f86cbba76ac8bd02afc68f2b04a0c6..092dd0c3b258972428c33dd67efea1a79a4f2454 100644
--- a/utility/matrix_util.h
+++ b/utility/matrix_util.h
@@ -19,7 +19,7 @@
#ifndef matrix_util_INC
#define matrix_util_INC
-#ifdef USE_BOOST
+#ifdef USE_BOOST_ODE
#include <boost/numeric/ublas/matrix.hpp>
#include "boost/numeric/bindings/lapack/lapack.hpp"
diff --git a/utility/print_function.hpp b/utility/print_function.hpp
index 5a1863ad375e33db482ce20e3ad793281c801b30..d3a9e8882e1b367fa00ca04d8d7922e73158e20c 100644
--- a/utility/print_function.hpp
+++ b/utility/print_function.hpp
@@ -53,8 +53,22 @@
using namespace std;
-namespace moose {
+/* --------------------------------------------------------------------------*/
+/**
+ * @Synopsis Macros
+ */
+/* ----------------------------------------------------------------------------*/
+#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
+#ifdef NDEBUG
+#define MOOSE_DEBUG( a ) { \
+ stringstream ss; ss << a; \
+ cout << "DEBUG: " << __FILENAME__ << ":" << __LINE__ << "| " << ss.str(); \
+ }
+#else
+#define MOOSE_DEBUG( a ) {}
+#endif
+namespace moose {
/**
* @brief Enumerate type for debug and log.
@@ -134,6 +148,7 @@ namespace moose {
return ss.str();
}
+ // Not print it when built for release.
inline string debugPrint(string msg, string prefix = "DEBUG"
, string color=T_RESET, unsigned debugLevel = 0
)
@@ -211,6 +226,15 @@ namespace moose {
moose::__dump__(msg, moose::warning );
}
+ inline void showDebug( const string msg )
+ {
+#ifdef DISABLE_DEBUG
+
+#else
+ moose::__dump__(msg, moose::debug );
+#endif
+ }
+
inline void showError( string msg )
{
moose::__dump__( msg, moose::error );
diff --git a/utility/strutil.cpp b/utility/strutil.cpp
index 399d2d71ccf0b0babd2e810b03ec60e8c373e313..da5ee41f3516092a294567923297289fd92f8c5e 100644
--- a/utility/strutil.cpp
+++ b/utility/strutil.cpp
@@ -12,38 +12,39 @@
using namespace std;
-namespace moose {
+namespace moose
+{
// Adapted from code available on oopweb.com
-void tokenize(
- const string& str,
- const string& delimiters,
- vector< string >& tokens )
+void tokenize( const string& str, const string& delimiters, vector< string >& tokens )
{
- // Token boundaries
- string::size_type begin = str.find_first_not_of( delimiters, 0 );
- string::size_type end = str.find_first_of( delimiters, begin );
-
- while ( string::npos != begin || string::npos != end )
- {
- // Found a token, add it to the vector.
- tokens.push_back( str.substr( begin, end - begin ) );
-
- // Update boundaries
- begin = str.find_first_not_of( delimiters, end );
- end = str.find_first_of( delimiters, begin );
- }
+ // Token boundaries
+ string::size_type begin = str.find_first_not_of( delimiters, 0 );
+ string::size_type end = str.find_first_of( delimiters, begin );
+
+ while ( string::npos != begin || string::npos != end )
+ {
+ // Found a token, add it to the vector.
+ tokens.push_back( str.substr( begin, end - begin ) );
+
+ // Update boundaries
+ begin = str.find_first_not_of( delimiters, end );
+ end = str.find_first_of( delimiters, begin );
+ }
}
string& clean_type_name(string& arg)
{
- for (size_t pos = arg.find(' '); pos != string::npos; pos = arg.find(' ')){
+ for (size_t pos = arg.find(' '); pos != string::npos; pos = arg.find(' '))
+ {
arg.replace(pos, 1, 1, '_');
}
- for (size_t pos = arg.find('<'); pos != string::npos; pos = arg.find('<')){
+ for (size_t pos = arg.find('<'); pos != string::npos; pos = arg.find('<'))
+ {
arg.replace(pos, 1, 1, '_');
}
- for (size_t pos = arg.find('>'); pos != string::npos; pos = arg.find('>')){
+ for (size_t pos = arg.find('>'); pos != string::npos; pos = arg.find('>'))
+ {
arg.replace(pos, 1, 1, '_');
}
return arg;
@@ -72,20 +73,16 @@ std::string fix(const std::string userPath, const string& delimiters)
string trimmedPath = trim(userPath, delimiters);
string fixedPath;
+ char prev = 0;
// In this loop, we check if there are more than one '/' together. If yes,
// then accept only first one and reject other.
for(unsigned int i = 0; i < trimmedPath.size(); ++i)
{
const char c = trimmedPath[i];
- if('/' == c)
- {
- if('/' != fixedPath[fixedPath.size()-1])
- fixedPath.push_back(c);
- }
- else
+ if(c != '/' || c != prev)
fixedPath.push_back(c);
-
+ prev = c;
}
return fixedPath;
}
@@ -94,36 +91,36 @@ int testTrim()
{
std::string testStrings [] =
- {
- " space at beginning",
- "space at end ",
- " space at both sides ",
- "\ttab at beginning",
- "tab at end\t",
- "\ttab at both sides\t",
- "\nnewline at beginning",
- "newline at end\n",
- "\nnewline at both sides\n",
- "\n\tnewline and tab at beginning",
- "space and tab at end \t",
- " \rtab and return at both sides \r"
- };
+ {
+ " space at beginning",
+ "space at end ",
+ " space at both sides ",
+ "\ttab at beginning",
+ "tab at end\t",
+ "\ttab at both sides\t",
+ "\nnewline at beginning",
+ "newline at end\n",
+ "\nnewline at both sides\n",
+ "\n\tnewline and tab at beginning",
+ "space and tab at end \t",
+ " \rtab and return at both sides \r"
+ };
std::string results[] =
- {
- "space at beginning",
- "space at end",
- "space at both sides",
- "tab at beginning",
- "tab at end",
- "tab at both sides",
- "newline at beginning",
- "newline at end",
- "newline at both sides",
- "newline and tab at beginning",
- "space and tab at end",
- "tab and return at both sides"
- };
+ {
+ "space at beginning",
+ "space at end",
+ "space at both sides",
+ "tab at beginning",
+ "tab at end",
+ "tab at both sides",
+ "newline at beginning",
+ "newline at end",
+ "newline at both sides",
+ "newline and tab at beginning",
+ "space and tab at end",
+ "tab and return at both sides"
+ };
bool success = true;
@@ -140,7 +137,8 @@ int testTrim()
bool endswith(const string & full, const string & ending)
{
- if (full.length() < ending.length()){
+ if (full.length() < ending.length())
+ {
return false;
}
return (0 == full.compare(full.length() - ending.length(), ending.length(), ending));
@@ -159,4 +157,22 @@ int strncasecmp( const string& a, const string& b, size_t n)
return 0;
}
+// This function is modification of this solution:
+// https://stackoverflow.com/a/440240/1805129
+string random_string( const unsigned len )
+{
+ static const char alphanum[] =
+ "0123456789"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz";
+
+ string s(len, '_' );
+ for (unsigned i = 0; i < len; ++i)
+ {
+ s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
+ }
+
+ return s;
+}
+
}
diff --git a/utility/strutil.h b/utility/strutil.h
index d6f48bfd7a85ba15d16c6202f12fbc5e1fd061d5..a5b1760b2c278fe7abde7aeaf52eab27e59bb38a 100644
--- a/utility/strutil.h
+++ b/utility/strutil.h
@@ -48,16 +48,10 @@ namespace moose
*/
int strncasecmp( const std::string& a, const std::string& b, size_t n);
-
- // TODO: other std::string utilities to add
- // /** Trim leading and trailing whitespace and replace convert any two or more consecutive whitespace inside the std::string by a single 'blank' character. */
- // std::string fulltrim(std::string& myString) const;
- // /** Convert to uppercase */
- // std::string upcase(std::string& myString) const;
- // /** Convert to lowercase */
- // std::string downcase(std::string & myString);
- // Maybe a implement regular expression search - reinventing wheel - but no standard way without using some bloated library.
-
+ /**
+ * Generate random string of given length.
+ */
+ std::string random_string( const unsigned size );
}
#endif //_STRINGUTIL_H
diff --git a/utility/testing_macros.hpp b/utility/testing_macros.hpp
index 5d55dffca4ae9e4035dd028f6246fbc0e79abd02..87189889de3cc029dcd1bbded2972f5a6a693773 100644
--- a/utility/testing_macros.hpp
+++ b/utility/testing_macros.hpp
@@ -47,7 +47,7 @@ static ostringstream assertStream;
assertStream.str(""); \
LOCATION( assertStream ); \
assertStream << msg << endl; \
- __dump__(assertStream.str(), "EXPECT_FAILURE"); \
+ moose::__dump__(assertStream.str(), moose::failed); \
}
#define EXPECT_FALSE( condition, msg) \
@@ -55,7 +55,7 @@ static ostringstream assertStream;
assertStream.str(""); \
LOCATION( assertStream ); \
assertStream << msg << endl; \
- __dump__(assertStream.str(), "EXPECT_FAILURE"); \
+ moose::__dump__(assertStream.str(), moose::failed); \
}
#define EXPECT_EQ(a, b, token) \
@@ -64,7 +64,7 @@ static ostringstream assertStream;
LOCATION(assertStream) \
assertStream << "Expected " << b << ", received " << a ; \
assertStream << token; \
- __dump__(assertStream.str(), "EXPECT_FAILURE"); \
+ moose::__dump__(assertStream.str(), moose::failed); \
}
#define EXPECT_NEQ(a, b, token) \
@@ -73,7 +73,7 @@ static ostringstream assertStream;
LOCATION(assertStream); \
assertStream << "Not expected " << a << endl; \
assertStream << token << endl; \
- __dump__(assertStream.str(), "EXPECT_FAILURE"); \
+ moose::__dump__(assertStream.str(), moose::failed); \
}
#define EXPECT_GT(a, b, token) \
@@ -82,7 +82,7 @@ static ostringstream assertStream;
LOCATION(assertStream); \
assertStream << "Expected greater than " << a << ", received " << b << endl; \
assertStream << token << endl; \
- __dump__(assertStream.str(), "EXPECT_FAILURE"); \
+ moose::__dump__(assertStream.str(), moose::failed); \
}
#define EXPECT_GTE(a, b, token) \
@@ -92,7 +92,7 @@ static ostringstream assertStream;
assertStream << "Expected greater than or equal to " << a \
<< ", received " << b << endl; \
assertStream << token << endl; \
- __dump__(assertStream.str(), "EXPECT_FAILURE"); \
+ moose::__dump__(assertStream.str(), moose::failed); \
}
#define EXPECT_LT(a, b, token) \
@@ -101,7 +101,7 @@ static ostringstream assertStream;
LOCATION(assertStream); \
assertStream << "Expected less than " << a << ", received " << b << endl; \
assertStream << token << endl; \
- __dump__(assertStream.str(), "EXPECT_FAILURE"); \
+ moose::__dump__(assertStream.str(), moose::failed); \
}
#define EXPECT_LTE(a, b, token) \
@@ -111,7 +111,7 @@ static ostringstream assertStream;
assertStream << "Expected less than or equal to " << a \
<< ", received " << b << endl; \
assertStream << token << endl; \
- __dump__(assertStream.str(), "EXPECT_FAILURE"); \
+ moose::__dump__(assertStream.str(), moose::failed); \
}
#define ASSERT_TRUE( condition, msg) \
@@ -150,7 +150,7 @@ static ostringstream assertStream;
if(! doubleEq(a, b) ) { \
assertStream.str(""); \
LOCATION(assertStream); \
- assertStream << "Expected " << b << ", received " << a << endl; \
+ assertStream << "Expected " << std::fixed << b << ", received " << a << endl; \
assertStream << token; \
moose::__dump__(assertStream.str(), moose::failed); \
throw std::runtime_error( "float equality test failed" ); \
diff --git a/utility/utility.h b/utility/utility.h
index 303de2774031b16a9fbd6c715f89ef568ca19c4e..4d5510186b9b682233feca04b3487979728cee7c 100644
--- a/utility/utility.h
+++ b/utility/utility.h
@@ -1,7 +1,5 @@
// utility.h ---
-//
-// Filename: utility.h
-// Description:
+// Description: Some utility function.
// Author: Subhasis Ray
// Maintainer:
// Copyright (C) 2010 Subhasis Ray, all rights reserved.
@@ -10,29 +8,14 @@
// Last-Updated: Tue Jul 23 12:48:17 2013 (+0530)
// By: subha
// Update #: 19
-// URL:
-// Keywords:
-// Compatibility:
-//
-//
-
-// Commentary:
-//
-//
-//
-//
-
-// Change log:
-//
-//
-//
-
-// Code:
#ifndef _UTILITY_H
+
#include "strutil.h"
-namespace moose {
+// See types.cpp file for definitions.
+namespace moose
+{
char shortType(std::string type);
char innerType(char typecode);
@@ -55,6 +38,5 @@ namespace moose {
#endif // !_UTILITY_H
-
//
// utility.h ends here