From cb153fa53a4496b5bbf0da746a0936a467125e06 Mon Sep 17 00:00:00 2001 From: Dilawar Singh <dilawars@ncbs.res.in> Date: Sun, 11 Nov 2018 08:48:58 +0530 Subject: [PATCH] Squashed 'moose-core/' changes from d229eba6b..e5868beb9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit e5868beb9 Merge pull request #329 from upibhalla/master a56b7e883 Fix to rdesigneurProtos so that the classic HH Na and K_DR channels now work properly. 0bdebdf6f Merge pull request #328 from upibhalla/master bc3ff9ccd Got rid of printf debug line 788bce98b Merge branch 'master' of https://github.com/upibhalla/moose-core b8eeb9d5f Merge branch 'master' of https://github.com/BhallaLab/moose-core 47ee21c36 Fixes to rdesigneur so that chemProto without chemDistrib will not fail confusingly. 50f03b860 Fixes to EndoMesh (#327) 552ca01a1 Merge branch 'master' into master 905c98332 Merge pull request #323 from hrani/master aca01be2e Fixed numDimentions to 3 12e429d47 Merge branch 'master' of https://github.com/BhallaLab/moose-core 1f91c76fc Added dummy CubeMesh as default parent for EndoMesh to avert segvs on several methods 5a8ec044e Merge branch 'master' into master e4c19935e Merge pull request #324 from upibhalla/master 0327eb9e7 Fixed test_Xchan1.py to match bugfix for Dsolve. 2e2227649 Merge branch 'master' of https://github.com/BhallaLab/moose-core 182e95c52 Bugfix for ConcChan to correct scaling for permeability to SI units of millimolar 865e99dbb Merge branch 'master' of http://github.com/hrani/moose-core 70f116ad9 cleanup in print statement 83afd0fe3 Merge branch 'master' into master 9b0569b93 while reading the sbml model validator can be switched off 5b0bbe1be Merge pull request #322 from hrani/master 05eba8faa Channel are written back to genesis and zeroth voxel moose object is written for both cubeMesh or CylMesh 53cbe3656 reading info field for channel from kkit file (#321) ba88932fb CylMesh are written to SBML with annotation field and only zeroth ele… (#318) f917df152 Merge pull request #319 from dilawar/master 637583439 Works after disabling alpha and beta properties. 0b208c8c9 Now user can pass verbose option to mooseReadNML2 556ebef64 Hotfix. If self.network not found, sett the temperate to 25 deg C. 7c86d4ebc Merge branch 'master' of https://github.com/BhallaLab/moose-core 3a655cd06 Minor typo in warning report for Dsolve b4637b21a Merge pull request #317 from upibhalla/master d6e35de32 Merge branch 'master' into master ecfca8401 Update README.md (#312) f66ba9003 Merge branch 'master' of https://github.com/BhallaLab/moose-core 51dd77625 Rdesigneur passiveDistrib modified to handle legacy commands 5d20e0433 corrected the spell of CyclMesh-->CylMesh, negating the yaxis for kkit is corrected as now saving the value of scene coOrdinates (#313) a8769f2c4 Update CMakeLists.txt f0e4db0e9 Fixes to build failure on OSX because cmake does not MACOSX but APPLE on (#316) 2fb51c9a5 Hotfix: Neuroml2 fixes. (#315) e46429530 Merge pull request #314 from upibhalla/master b57a6d0df Merge branch 'master' into master d2749931d Build System Tweaks (#309) 293d44144 Some fixes to Ca-dependent channel prototypes in rdesigneur. 88bcf0797 Merge pull request #311 from upibhalla/master aaf589ab2 Merge branch 'master' of https://github.com/BhallaLab/moose-core 0909ceb32 Fixes as suggested by PyLint. Added a target pylint in cmake file. (#308) cdbf917b2 Merge branch 'master' of https://github.com/BhallaLab/moose-core 79e2d65f5 hotfix for running Boost, Added NMDAR to rdesigneurProtos. eb4e83662 Fixed boost segfault with dense solver. Also remove GSL specific attrib from the test. (#310) 8463cc73e Update setup.cmake.py (#307) 8c38fc6d6 Removed deprecated warnings from neuroml2 reader (#305) 6df4332d2 Fixes to BOOST based steadystate solver (#306) 99dd7d250 Merge pull request #302 from BhallaLab/chhennapoda 86c424452 Merge branch 'master' into chhennapoda ec06b242a HotFix: Fix regression in StreadyState solver caused by #293. (#304) 6b79f6701 prefer .so suffix over CPython version specific suffix . this way a wheel compiled by any version of python3 will work with any python3. 92da6a7fb removed python-libsbml from install dependencies; added matplotlib. sbml and neuroml packages should be installed by user and not automatically. They may not be available for all distribution of python on all OSes. e2bc19c0e Merge branch 'master' into chhennapoda 385a5cf0a Merge pull request #303 from upibhalla/master 080767c5a Fixes to rdesigneur due to bad merge. Cleanup on rmoogli 62f8bc89e Tweak to Neuron.cpp so it can handle insertion of spines with uniform spacing. b6088109b Fixes for linux. 406fee2a0 Temp commit to test on OSX. cc3c604b9 Merge branch 'master' into chhennapoda 342092829 Update moose_test.py (#301) 61f4f6684 show timeout in moose.test() . abf822c4a with python2, just test with GSL. Build python3 first. 088c61673 Made changes to build system so that pymoose directory can be built in isolation. Build system is bit more module. Ideally I should make sure that each subdirectory can built in isolation. 3c0ff2790 Few changes to build with python3.6. 5d688f63d Use option --relative in setup.py and tell cmake not to look into usr prefix anymore. 1f3fe9fc3 Merge branch 'chhennapoda' of github.com:BhallaLab/moose-core into chhennapoda 3e19983c8 removed unneeded library which is never used. c2fbab872 cmake related changes to build on centos5 (manylinux docker image). f1230f151 Merge branch 'master' of https://github.com/upibhalla/moose-core 23a2892cc Merge branch 'master' of https://github.com/BhallaLab/moose-core 8a835c133 minor bugfix to rdesigneur 6ef1d567e Merge branch 'master' into master a9a2e758f Merge branch 'master' of https://github.com/BhallaLab/moose-core 5e1294d99 Further updates to rdesigneur for argument handling a702bded5 Put in kwargs based specification of plotList, stimList and moogList. Folded savePlots into plotList but not yet tested. git-subtree-dir: moose-core git-subtree-split: e5868beb97afcb778d6a945c38e80300c953b39a --- .travis.yml | 20 +- .travis/run_pylint.sh | 36 + .travis/travis_build_linux.sh | 22 +- .travis/travis_build_osx.sh | 10 +- .travis/travis_prepare_linux.sh | 20 +- CMakeLists.txt | 192 +- CheckCXXCompiler.cmake | 12 +- README.md | 12 +- basecode/CMakeLists.txt | 4 +- basecode/Cinfo.cpp | 8 - basecode/Conv.h | 2 +- basecode/Eref.h | 13 - basecode/SrcFinfo.h | 7 - basecode/header.h | 9 - basecode/main.cpp | 14 - benchmarks/CMakeLists.txt | 6 +- benchmarks/kineticMarks.cpp | 2 +- biophysics/CMakeLists.txt | 88 +- biophysics/CaConc.cpp | 3 +- biophysics/CaConcBase.cpp | 4 +- biophysics/ChanBase.cpp | 4 +- biophysics/ChanCommon.cpp | 68 +- biophysics/ChanCommon.h | 143 +- biophysics/CompartmentBase.cpp | 4 +- biophysics/CompartmentDataHolder.cpp | 2 +- biophysics/DifBuffer.cpp | 4 +- biophysics/DifBufferBase.cpp | 4 +- biophysics/DifShell.cpp | 2 +- biophysics/DifShellBase.cpp | 4 +- biophysics/GapJunction.cpp | 2 +- biophysics/HHChannel.cpp | 4 +- biophysics/HHChannel2D.cpp | 4 +- biophysics/HHChannelBase.cpp | 4 +- biophysics/HHGate.cpp | 4 +- biophysics/HHGate2D.cpp | 4 +- biophysics/IntFire.cpp | 2 +- biophysics/IzhikevichNrn.cpp | 2 +- biophysics/Leakage.cpp | 21 +- biophysics/Leakage.h | 2 +- biophysics/MMPump.cpp | 4 +- biophysics/MarkovChannel.cpp | 2 +- biophysics/MarkovGslSolver.cpp | 2 +- biophysics/MarkovRateTable.cpp | 2 +- biophysics/MarkovSolver.cpp | 4 +- biophysics/MarkovSolverBase.cpp | 4 +- biophysics/MatrixOps.cpp | 2 +- biophysics/MgBlock.cpp | 2 +- biophysics/NMDAChan.cpp | 4 +- biophysics/Nernst.cpp | 2 +- biophysics/Neuron.cpp | 46 +- biophysics/ReadCell.cpp | 2 +- biophysics/ReadSwc.cpp | 2 +- biophysics/SpikeGen.cpp | 2 +- biophysics/Spine.cpp | 4 +- biophysics/SymCompartment.cpp | 2 +- biophysics/SynChan.cpp | 2 +- biophysics/VClamp.cpp | 4 +- biophysics/VectorTable.cpp | 2 +- builtins/Arith.cpp | 2 +- builtins/CMakeLists.txt | 23 +- builtins/Func.cpp | 2 +- builtins/Func.h | 2 +- builtins/Function.cpp | 4 +- builtins/Function.h | 10 +- builtins/Group.cpp | 2 +- builtins/Interpol.cpp | 2 +- builtins/Interpol2D.cpp | 2 +- builtins/Mstring.cpp | 2 +- builtins/SpikeStats.cpp | 2 +- builtins/Stats.cpp | 2 +- builtins/StimulusTable.cpp | 2 +- builtins/Streamer.cpp | 8 +- builtins/StreamerBase.cpp | 4 +- builtins/Table.cpp | 6 +- builtins/TableBase.cpp | 2 +- builtins/TimeTable.cpp | 2 +- builtins/Variable.cpp | 2 +- builtins/testBuiltins.cpp | 10 +- cmake_modules/FindNumPy.cmake | 2 +- device/CMakeLists.txt | 4 +- device/PulseGen.cpp | 2 +- diffusion/CMakeLists.txt | 4 +- diffusion/DiffPoolVec.cpp | 2 +- diffusion/Dsolve.cpp | 24 +- diffusion/standaloneTestFastElim.cpp | 1000 ++++---- diffusion/testDiffusion.cpp | 2 +- examples/CMakeLists.txt | 4 +- examples/Ex.cpp | 6 +- examples/Example.cpp | 13 +- examples/Example.h | 4 + external/muparser/include/muParser.h | 2 +- external/muparser/src/muParser.cpp | 4 +- external/tinyxml/CMakeLists.txt | 2 - external/tinyxml/tinyxml2.cpp | 2186 ----------------- external/tinyxml/tinyxml2.h | 2076 ---------------- external/xgetopt/XGetopt.cpp | 219 -- external/xgetopt/XGetopt.h | 23 - hsolve/CMakeLists.txt | 5 +- hsolve/Cell.cpp | 10 +- hsolve/HSolve.cpp | 2 +- hsolve/HSolveActive.cpp | 36 +- hsolve/HSolveInterface.cpp | 2 +- hsolve/HSolveStruct.cpp | 2 +- hsolve/HinesMatrix.cpp | 2 +- hsolve/ZombieCaConc.cpp | 2 +- hsolve/ZombieCompartment.h | 6 +- hsolve/ZombieHHChannel.h | 4 +- intfire/AdExIF.cpp | 4 +- intfire/AdThreshIF.cpp | 4 +- intfire/CMakeLists.txt | 3 +- intfire/ExIF.cpp | 4 +- intfire/IzhIF.cpp | 4 +- intfire/QIF.cpp | 4 +- intfire/testIntFire.cpp | 2 +- kinetics/CMakeLists.txt | 38 +- kinetics/ConcChan.cpp | 2 +- kinetics/CplxEnzBase.cpp | 4 +- kinetics/Enz.cpp | 4 +- kinetics/EnzBase.cpp | 4 +- kinetics/MMenz.cpp | 4 +- kinetics/PoolBase.cpp | 4 +- kinetics/Reac.cpp | 4 +- kinetics/ReacBase.cpp | 4 +- kinetics/ReadCspace.cpp | 2 +- kinetics/ReadKkit.cpp | 3 +- kinetics/Species.cpp | 2 +- kinetics/WriteKkit.cpp | 2 +- kinetics/lookupVolumeFromMesh.cpp | 8 +- kinetics/testKinetics.cpp | 2 +- ksolve/CMakeLists.txt | 57 +- ksolve/FuncTerm.cpp | 2 +- ksolve/FuncTerm.h | 2 +- ksolve/Gsolve.cpp | 2 +- ksolve/Gsolve.h | 2 - ksolve/GssaVoxelPools.cpp | 12 +- ksolve/KinSparseMatrix.cpp | 4 +- ksolve/Ksolve.cpp | 18 +- ksolve/NonlinearSystem.h | 200 +- ksolve/OdeSystem.h | 9 +- ksolve/RateTerm.cpp | 4 +- ksolve/SteadyStateBoost.cpp | 242 +- ksolve/SteadyStateGsl.cpp | 141 +- ksolve/Stoich.cpp | 16 +- ksolve/VoxelPools.cpp | 182 +- ksolve/VoxelPools.h | 4 +- ksolve/VoxelPoolsBase.cpp | 5 +- ksolve/ZombieBufPool.cpp | 6 +- ksolve/ZombieEnz.cpp | 11 +- ksolve/ZombieFunction.cpp | 12 +- ksolve/ZombieMMenz.cpp | 9 +- ksolve/ZombiePool.cpp | 6 +- ksolve/ZombiePoolInterface.cpp | 4 +- ksolve/ZombieReac.cpp | 8 +- ksolve/testKsolve.cpp | 7 +- mesh/CMakeLists.txt | 7 +- mesh/ChemCompt.cpp | 6 +- mesh/CubeMesh.cpp | 6 +- mesh/CylBase.cpp | 9 +- mesh/CylMesh.cpp | 6 +- mesh/EndoMesh.cpp | 13 +- mesh/MeshCompt.cpp | 4 +- mesh/MeshEntry.cpp | 4 +- mesh/NeuroMesh.cpp | 8 +- mesh/NeuroNode.cpp | 4 +- mesh/PsdMesh.cpp | 8 +- mesh/SpineEntry.cpp | 2 +- mesh/SpineMesh.cpp | 8 +- mesh/testMesh.cpp | 8 +- mpi/CMakeLists.txt | 3 +- mpi/PostMaster.cpp | 2 +- msg/CMakeLists.txt | 3 +- msg/DiagonalMsg.cpp | 2 +- msg/Msg.cpp | 6 +- msg/OneToAllMsg.cpp | 2 +- msg/OneToOneDataIndexMsg.cpp | 2 +- msg/OneToOneMsg.cpp | 2 +- msg/SingleMsg.cpp | 2 +- msg/testMsg.cpp | 2 +- pymoose/CMakeLists.txt | 109 +- pymoose/moosemodule.cpp | 2 +- pymoose/pymooseinit.cpp | 19 +- python/moose/OrderedDict.py | 1 - python/moose/SBML/readSBML.py | 10 +- python/moose/SBML/validation.py | 1 + python/moose/SBML/writeSBML.py | 84 +- python/moose/__init__.py | 11 +- python/moose/chemMerge/merge.py | 10 - python/moose/chemUtil/chemConnectUtil.py | 15 +- python/moose/fixXreacs.py | 70 +- python/moose/genesis/writeKkit.py | 123 +- python/moose/hdfutil.py | 32 +- python/moose/moose.py | 111 +- python/moose/moose_test.py | 6 +- python/moose/neuroml/ChannelML.py | 26 +- python/moose/neuroml/MorphML.py | 13 +- python/moose/neuroml/NetworkML.py | 4 +- python/moose/neuroml/NeuroML.py | 47 +- python/moose/neuroml2/converter.py | 207 -- python/moose/neuroml2/hhfit.py | 2 +- python/moose/neuroml2/reader.py | 257 +- python/moose/neuroml2/run_cell.py | 17 +- python/moose/neuroml2/run_hhcell.py | 16 +- python/moose/plot_utils.py | 7 +- python/moose/utils.py | 21 +- python/rdesigneur/rdesigneur.py | 473 ++-- python/rdesigneur/rdesigneurProtos.py | 72 +- python/rdesigneur/rmoogli.py | 2 +- python/setup.cmake.py | 13 +- scheduling/CMakeLists.txt | 6 +- scheduling/testScheduling.cpp | 8 +- setup.py | 172 -- shell/CMakeLists.txt | 28 +- shell/LoadModels.cpp | 2 +- shell/Neutral.cpp | 8 +- shell/SaveModels.cpp | 2 +- shell/Shell.cpp | 22 +- shell/Shell.h | 2 - shell/ShellCopy.cpp | 4 +- shell/ShellThreads.cpp | 4 +- shell/Wildcard.cpp | 4 +- shell/testShell.cpp | 10 +- signeur/Adaptor.cpp | 2 +- signeur/CMakeLists.txt | 4 +- synapse/CMakeLists.txt | 4 +- synapse/STDPSynHandler.cpp | 2 +- synapse/STDPSynapse.cpp | 2 +- synapse/SeqSynHandler.cpp | 6 +- synapse/SimpleSynHandler.cpp | 2 +- synapse/SynHandlerBase.cpp | 2 +- synapse/Synapse.cpp | 4 +- .../moose_vs_neuron/rallpack3/moose_sim.py | 10 - tests/python/abstrModelEqns9.py | 10 +- tests/python/chem_models/19085.cspace | 1 + tests/python/testXchan1.py | 2 - tests/python/testXdiff1.py | 2 - tests/python/testXenz1.py | 2 - tests/python/testXreacs2.py | 2 - tests/python/testXreacs3.py | 2 - tests/python/testXreacs4.py | 2 - tests/python/testXreacs4a.py | 2 - tests/python/testXreacs5.py | 2 - tests/python/testXreacs5a.py | 2 - tests/python/testXreacs6.py | 2 - tests/python/testXreacs7.py | 2 - tests/python/testXreacs8.py | 2 - ...GraupnerBrunel2012_STDPfromCaPlasticity.py | 2 - tests/python/test_Xchan1.py | 2 +- tests/python/test_Xreacs2.py | 6 +- tests/python/test_dose_response.py | 116 + tests/python/test_kkit.py | 1 - tests/python/test_moose_attribs.py | 67 + tests/python/test_muparser.py | 5 - tests/python/test_neuroml2.py | 13 + tests/python/test_rdesigneur.py | 2 - .../test_rdesigneur_random_syn_input.py | 46 + tests/python/test_steady_state_solver.py | 152 ++ tests/python/testdisabled_dose_response.py | 106 + utility/Annotator.cpp | 2 +- utility/CMakeLists.txt | 5 +- utility/cnpy.hpp | 2 +- utility/print_function.hpp | 9 +- wheels/Dockerfile | 17 - wheels/build_wheels.sh | 46 - 263 files changed, 3035 insertions(+), 7489 deletions(-) create mode 100755 .travis/run_pylint.sh delete mode 100644 external/tinyxml/CMakeLists.txt delete mode 100644 external/tinyxml/tinyxml2.cpp delete mode 100644 external/tinyxml/tinyxml2.h delete mode 100644 external/xgetopt/XGetopt.cpp delete mode 100644 external/xgetopt/XGetopt.h delete mode 100644 python/moose/neuroml2/converter.py delete mode 100755 setup.py create mode 100644 tests/python/chem_models/19085.cspace create mode 100644 tests/python/test_dose_response.py create mode 100644 tests/python/test_moose_attribs.py create mode 100644 tests/python/test_rdesigneur_random_syn_input.py create mode 100644 tests/python/test_steady_state_solver.py create mode 100644 tests/python/testdisabled_dose_response.py delete mode 100644 wheels/Dockerfile delete mode 100755 wheels/build_wheels.sh diff --git a/.travis.yml b/.travis.yml index a89ee791..e6912225 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,14 @@ language: cpp sudo: required -group: edge - +group: travis_lts +dist: xenial os: -- linux -- osx + - linux + - osx + +osx_image: xcode10 + notifications: email: recipients: @@ -20,22 +23,17 @@ addons: update: true before_script: -- echo "OSX related" - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then nvm get head || true; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./.travis/travis_prepare_osx.sh; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo ./.travis/travis_prepare_linux.sh; fi before_script: -- echo "OSX related" - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then nvm get head || true; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./.travis/travis_prepare_osx.sh; fi -- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo ./.travis/travis_prepare_linux.sh; - fi -script: +- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo ./.travis/travis_prepare_linux.sh; fi -- python2 -m compileall -q . || echo "Python2 not found" -- if type python3 > /dev/null; then python3 -m compileall -q . ; fi +script: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./.travis/travis_build_osx.sh; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./.travis/travis_build_linux.sh; fi diff --git a/.travis/run_pylint.sh b/.travis/run_pylint.sh new file mode 100755 index 00000000..91d39812 --- /dev/null +++ b/.travis/run_pylint.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +set -e +python3 -m pip install pylint --user +PYLINT="python3 -m pylint -E \ + --disable=no-member --disable=no-name-in-module \ + --disable=invalid-unary-operand-type \ + --disable=import-error \ + " +function do_pylint() { + echo "Checking $1" + DIR=$(dirname $1) + SNAME=$(basename $1) + ( + cd $DIR + $PYLINT $@ $SNAME + ) +} + +FILES=$(find . -type f -name "*.py" | shuf) +N=4 +i=0 +for f in $FILES; do + #i=$((i+1)) + #if [ $i -eq $N ]; then + # i=0 + # wait; + #fi + # do_pylint "$f" + echo "Checking $f" + DIR=$(dirname $f) + SNAME=$(basename $f) + ( + cd $DIR + $PYLINT $@ $SNAME + ) +done diff --git a/.travis/travis_build_linux.sh b/.travis/travis_build_linux.sh index 3352c2f0..9cbc8075 100755 --- a/.travis/travis_build_linux.sh +++ b/.travis/travis_build_linux.sh @@ -40,36 +40,34 @@ unset PYTHONPATH $PYTHON2 -m compileall -q . if type $PYTHON3 > /dev/null; then $PYTHON3 -m compileall -q . ; fi +# Python2 and GSL. echo "Currently in `pwd`" ( mkdir -p _GSL_BUILD && cd _GSL_BUILD cmake -DDEBUG=ON -DPYTHON_EXECUTABLE="$PYTHON2" .. - $MAKE && ctest --output-on-failure + $MAKE && ctest --output-on-failure 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_ODE=ON -DDEBUG=ON -DPYTHON_EXECUTABLE="$PYTHON2" .. - $MAKE && ctest --output-on-failure -) - -# This is only applicable on linux build. +# Python3 with GSL and BOOST. This should be the only build after we drop +# python2 support. echo "Python3: Removed python2-networkx and install python3" if type $PYTHON3 > /dev/null; then sudo apt-get remove -qq python-networkx || echo "Error with apt" sudo apt-get install -qq python3-networkx || echo "Error with apt" + # GSL. ( mkdir -p _GSL_BUILD2 && cd _GSL_BUILD2 && \ - cmake -DPYTHON_EXECUTABLE="$PYTHON3" .. - $MAKE && ctest --output-on-failure + cmake -DPYTHON_EXECUTABLE="$PYTHON3" -DDEBUG=ON .. + $MAKE && ctest --output-on-failure ) + + # BOOST ( mkdir -p _BOOST_BUILD2 && cd _BOOST_BUILD2 && \ cmake -DWITH_BOOST_ODE=ON -DPYTHON_EXECUTABLE="$PYTHON3" .. - $MAKE && ctest --output-on-failure + $MAKE && ctest --output-on-failure ) echo "All done" else diff --git a/.travis/travis_build_osx.sh b/.travis/travis_build_osx.sh index 814f6af5..7e947674 100755 --- a/.travis/travis_build_osx.sh +++ b/.travis/travis_build_osx.sh @@ -23,12 +23,18 @@ 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 + PATH=/usr/local/bin:/usr/bin:$PATH + + # Get pylint + python -m pip install pylint --user + python -m pip install python-libsbml --user + python -m pip install pyneuroml --user + mkdir -p _GSL_BUILD && cd _GSL_BUILD \ && cmake -DDEBUG=ON \ -DPYTHON_EXECUTABLE=`which python` .. + make pylint -j3 make && ctest --output-on-failure cd .. # Now with boost. diff --git a/.travis/travis_prepare_linux.sh b/.travis/travis_prepare_linux.sh index 484f1a4e..37f5dd33 100755 --- a/.travis/travis_prepare_linux.sh +++ b/.travis/travis_prepare_linux.sh @@ -10,7 +10,7 @@ # OPTIONS: --- # REQUIREMENTS: --- # BUGS: --- -# NOTES: --- +# NOTES: Always run with sudo permission. # AUTHOR: Dilawar Singh (), dilawars@ncbs.res.in # ORGANIZATION: NCBS Bangalore # CREATED: 01/02/2017 10:10:02 AM @@ -21,15 +21,25 @@ set -o nounset # Treat unset variables as an error set +e # Let installation fail in some command apt-get install -qq libxml2-dev libbz2-dev -apt-get install -qq libhdf5-serial-dev apt-get install -qq make cmake apt-get install -qq python-numpy python-matplotlib python-networkx python-pip +apt-get install -qq python3-lxml python-lxml apt-get install -qq python3-numpy python3-matplotlib python3-dev -apt-get install -qq libboost-all-dev -apt-get install -qq libgsl0-dev apt-get install -qq python-pip python3-pip +apt-get install -qq python-tk python3-tk apt-get install -qq libgraphviz-dev +# Gsl +apt-get install -qq libgsl0-dev || apt-get install -qq libgsl-dev + +# Boost related. +apt-get install -qq liblapack-dev +apt-get install -qq libboost-all-dev + # Dependencies for NML2 apt-get install -qq python-scipy python3-scipy -#pip install pyNeuroML libNeuroML +apt-get install -qq python-lxml python3-lxml +apt-get install -qq python-setuptools python3-setuptools +apt-get install -qq python-tornado python3-tornado +/usr/bin/python2 -m pip install pyNeuroML libNeuroML +/usr/bin/python3 -m pip install pyNeuroML libNeuroML diff --git a/CMakeLists.txt b/CMakeLists.txt index 3bfb7fc8..ec094e58 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,16 +66,9 @@ add_custom_target(uninstall # This is for testing purpose. link_directories(${CMAKE_CURRENT_BINARY_DIR}) -################################# OS Specific ################################## -message(STATUS "Operating system: ${CMAKE_SYSTEM_NAME}") -if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - CMAKE_POLICY(SET CMP0042 NEW) - set(MACOSX TRUE) -else() - set(MACOSX FALSE) -endif() - ################################ CMAKE OPTIONS ################################## +option(WITH_NSDF "Enable NSDF support. Requires hdf5" OFF ) + 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) @@ -104,9 +97,10 @@ else() message(STATUS "Building for Release/No unit tests.") set(CMAKE_BUILD_TYPE Release) add_definitions(-UDO_UNIT_TESTS -O3 -DDISABLE_DEBUG) - # Treat all warnings as errors. Some the warnings are disabled in - # CheckCXXCompiler.cmake . - add_definitions(-Werror) + + # DO NOT Treat all warnings as errors. With some compilers and newer versions + # this often causes headache. + # add_definitions(-Werror) endif() if(GPROF AND "${CMAKE_BUILD_TYPE}" STREQUAL "Debug") @@ -130,6 +124,7 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ) if(WITH_BOOST) set(WITH_BOOST_ODE ON) + set(WITH_GSL OFF) endif(WITH_BOOST) # If using BOOST ODE2 library to solve ODE system, then don't use GSL. @@ -186,68 +181,71 @@ if(WITH_BOOST_ODE) add_definitions(-DUSE_BOOST_ODE -UUSE_GSL) endif() - -find_package(HDF5 COMPONENTS CXX HL) -if(NOT HDF5_FOUND) - message( - "==================================================================\n" - " HDF5 not found. Disabling support. Required for nsdf. \n\n" - " If you need hdf5 support, please install hdf5-dev or hdf5-devel\n" - " package or equivalent.\n\n" - " $ sudo apt-get install libhdf5-dev \n" - " $ sudo yum install libhdf5-devel \n" - " $ brew install hdf5 \n\n" - " Otherwise, continue with 'make' and 'make install' \n" - " If you install hdf5 to non-standard path, export environment \n" - " variable HDF5_ROOT to the location. Rerun cmake \n" - "================================================================ \n" - ) -endif(NOT HDF5_FOUND) - -if(HDF5_FOUND) - include_directories( ${HDF5_INCLUDE_DIRS} ) - add_definitions( -DUSE_HDF5 ) - if(HDF5_USE_STATIC_LIBRARIES) - message(STATUS "Finding static HDF5 libraries in $ENV{HDF5_ROOT}") - find_library(HDF5_CXX_LIBRARIES NAMES libhdf5.a - PATHS $ENV{HDF5_ROOT}/lib $ENV{HDF5_ROOT}/lib64 - ) - find_library(HDF5_HL_LIBRARIES NAMES libhdf5_hl.a - PATHS $ENV{HDF5_ROOT}/lib $ENV{HDF5_ROOT}/lib64 +# NSDF5 support. Disabled by default. +if(WITH_NSDF) + find_package(HDF5 COMPONENTS CXX HL) + if(NOT HDF5_FOUND) + message( + "==================================================================\n" + " HDF5 not found. Disabling NSDF support.\n\n" + " If you need NSDF support, please install hdf5-dev or hdf5-devel\n" + " package or equivalent.\n\n" + " $ sudo apt-get install libhdf5-dev \n" + " $ sudo yum install libhdf5-devel \n" + " $ brew install hdf5 \n\n" + " Otherwise, continue with 'make' and 'make install' \n" + " If you install hdf5 to non-standard path, export environment \n" + " variable HDF5_ROOT to the location. Rerun cmake \n" + "================================================================ \n" ) - set(HDF5_LIBRARIES ${HDF5_CXX_LIBRARIES} ${HDF5_HL_LIBRARIES}) + endif(NOT HDF5_FOUND) + + if(HDF5_FOUND) + include_directories( ${HDF5_INCLUDE_DIRS} ) + add_definitions( -DUSE_HDF5 -DENABLE_NSDF ) + if(HDF5_USE_STATIC_LIBRARIES) + message(STATUS "Finding static HDF5 libraries in $ENV{HDF5_ROOT}") + find_library(HDF5_CXX_LIBRARIES NAMES libhdf5.a + PATHS $ENV{HDF5_ROOT}/lib $ENV{HDF5_ROOT}/lib64 + ) + find_library(HDF5_HL_LIBRARIES NAMES libhdf5_hl.a + PATHS $ENV{HDF5_ROOT}/lib $ENV{HDF5_ROOT}/lib64 + ) + set(HDF5_LIBRARIES ${HDF5_CXX_LIBRARIES} ${HDF5_HL_LIBRARIES}) + endif() + + + # Make sure, HDF5_HL_LIBRARIES are set. The COMPONENTS in find_package may + # or may not work. See BhallaLab/moose-core#163. + if(NOT HDF5_HL_LIBRARIES) + set(HDF5_HL_LIBRARIES ${HDF5_HL_LIBRARIES}) + endif(NOT HDF5_HL_LIBRARIES) + list(APPEND HDF5_LIBRARIES ${HDF5_HL_LIBRARIES}) + + # message(STATUS "MOOSE will use following HDF5 ${HDF5_LIBRARIES}" ) + foreach(HDF5_LIB ${HDF5_LIBRARIES}) + if(HDF5_LIB) + get_filename_component( HDF5_LIB_EXT ${HDF5_LIB} EXT ) + if(HDF5_LIB_EXT) + if(${HDF5_LIB_EXT} STREQUAL ".a") + list(APPEND STATIC_LIBRARIES ${HDF5_LIB} ) + else( ) + list(APPEND SYSTEM_SHARED_LIBS ${HDF5_LIB} ) + endif( ) + endif() + endif( ) + endforeach( ) + else( HDF5_FOUND ) + message(STATUS "HDF5 is not found" ) + endif( HDF5_FOUND ) + # This is a fix for new HDF5 package on Debian/Ubuntu which installs hdf5 + # headers in non-standard path. issue #80. + if(HDF5_LIBRARY_DIRS) + set_target_properties( libmoose PROPERTIES LINK_FLAGS "-L${HDF5_LIBRARY_DIRS}" ) endif() - - - # Make sure, HDF5_HL_LIBRARIES are set. The COMPONENTS in find_package may - # or may not work. See BhallaLab/moose-core#163. - if(NOT HDF5_HL_LIBRARIES) - set(HDF5_HL_LIBRARIES ${HDF5_HL_LIBRARIES}) - endif(NOT HDF5_HL_LIBRARIES) - list(APPEND HDF5_LIBRARIES ${HDF5_HL_LIBRARIES}) - - message(STATUS "MOOSE will use following HDF5 ${HDF5_LIBRARIES}" ) - foreach(HDF5_LIB ${HDF5_LIBRARIES}) - if(HDF5_LIB) - get_filename_component( HDF5_LIB_EXT ${HDF5_LIB} EXT ) - if(HDF5_LIB_EXT) - if(${HDF5_LIB_EXT} STREQUAL ".a") - list(APPEND STATIC_LIBRARIES ${HDF5_LIB} ) - else( ) - list(APPEND SYSTEM_SHARED_LIBS ${HDF5_LIB} ) - endif( ) - endif() - endif( ) - endforeach( ) -else( HDF5_FOUND ) - message(STATUS "HDF5 is not found" ) -endif( HDF5_FOUND ) - -# This is a fix for new HDF5 package on Debian/Ubuntu which installs hdf5 -# headers in non-standard path. issue #80. -if(HDF5_LIBRARY_DIRS) - set_target_properties( libmoose PROPERTIES LINK_FLAGS "-L${HDF5_LIBRARY_DIRS}" ) -endif() +else(WITH_NSDF) + message(STATUS "NSDF support is disabled" ) +endif(WITH_NSDF) # Openmpi if(WITH_MPI) @@ -280,7 +278,7 @@ if(WITH_GSL) message( STATUS "Using static libraries ${GSL_STATIC_LIBRARIES}" ) list(APPEND STATIC_LIBRARIES ${GSL_STATIC_LIBRARIES}) else( ) - message(STATUS "Using gsl libraries: ${GSL_LIBRARIES}") + # message(DEBUG "Using gsl libraries: ${GSL_LIBRARIES}") foreach(GSL_LIB ${GSL_LIBRARIES} ) if(GSL_LIB) get_filename_component( GSL_LIB_EXT ${GSL_LIB} EXT ) @@ -355,9 +353,18 @@ if(SYSTEM_SHARED_LIBS) list(REMOVE_DUPLICATES SYSTEM_SHARED_LIBS) endif( ) +# cmake --help-policy CMP0042. Also in pymoose/CMakeLists.txt +# More details: +# https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/RPATH-handling +# especially section 'Mac OS X and the RPATH' +# Switching is OFF since all libraries are statically linked in module. +if(APPLE) + set_target_properties( libmoose PROPERTIES MACOSX_RPATH OFF) +endif(APPLE) + # MAC linker does not understand many of gnu-ld options. -message( STATUS "Shared libs: ${SYSTEM_SHARED_LIBS}") -if(MACOSX) +# message( DEBUG "Shared libs: ${SYSTEM_SHARED_LIBS}") +if(APPLE) target_link_libraries(libmoose "-Wl,-all_load" ${MOOSE_LIBRARIES} @@ -368,7 +375,7 @@ if(MACOSX) ${SYSTEM_SHARED_LIBS} ${CMAKE_DL_LIBS} ) -ELSE(MACOSX) +else(APPLE) target_link_libraries(libmoose "-Wl,--whole-archive" ${MOOSE_LIBRARIES} @@ -376,7 +383,7 @@ ELSE(MACOSX) "-Wl,--no-whole-archive" ${SYSTEM_SHARED_LIBS} ) -endif(MACOSX) +endif(APPLE) add_dependencies(moose.bin libmoose) target_link_libraries(moose.bin moose ${CMAKE_DL_LIBS}) @@ -430,10 +437,11 @@ set(PYMOOSE_BDIST_FILE ${PYMOOSE_BDIST_DIR}/pymoose-${VERSION_MOOSE}.${_platform message(STATUS "binary distribution file ${PYMOOSE_BDIST_FILE}") add_custom_target(bdist ALL DEPENDS ${PYMOOSE_BDIST_FILE} ) -# Any command using setup.cmake.py must run in the same directory. +# Any command using setup.cmake.py must run in the same directory. Use option +# `--relative` to prefix is aways fixed. add_custom_command( OUTPUT ${PYMOOSE_BDIST_FILE} COMMAND ${PYTHON_EXECUTABLE} setup.cmake.py bdist_dumb -p ${_platform} - -d ${PYMOOSE_BDIST_DIR} + -d ${PYMOOSE_BDIST_DIR} --relative WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/python COMMENT "bdist is saved to ${PYMOOSE_BDIST_DIR}" VERBATIM @@ -462,8 +470,8 @@ add_dependencies( copy_pymoose _moose ) install(TARGETS moose.bin DESTINATION bin CONFIGURATIONS Debug) install(TARGETS libmoose DESTINATION lib CONFIGURATIONS Debug) -# install pymoose bdist. The bdist comes with predefined /usr; remove it. -install(DIRECTORY ${PYMOOSE_BDIST_INSTALL_DIR}/usr/ +# install pymoose bdist. +install(DIRECTORY ${PYMOOSE_BDIST_INSTALL_DIR}/ DESTINATION ${CMAKE_INSTALL_PREFIX} CONFIGURATIONS Release Debug ) @@ -511,5 +519,27 @@ foreach( _test_script ${PY_TEST_SCRIPTS} ) ) endforeach( ) +# add pylint target. +set(PYSCRIPTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/python ) +file(GLOB_RECURSE PY_SCRIPTS "python/*.py") +add_custom_target( pylint ) +foreach( _py_script ${PY_SCRIPTS} ) + get_filename_component( _py_name ${_py_script} NAME_WE) + file( READ ${_py_script} pytext) + string(MD5 _md5 "${pytext}") + set(TGT_NAME "${_py_name}-${_md5}" ) + set(PYLINT_OPTIONS --disable=no-member --disable=no-name-in-module + --disable=invalid-unary-operand-type + --disable=import-error + --disable=no-method-argument + ) + add_custom_target( ${TGT_NAME} + COMMAND ${PYTHON_EXECUTABLE} -m pylint -E ${PYLINT_OPTIONS} ${_py_script} + COMMENT "Running pylint on ${_py_script}" + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + ) + add_dependencies(pylint ${TGT_NAME} ) +endforeach( ) + ############################ CPACK ###################################### include(${CMAKE_CURRENT_SOURCE_DIR}/cmake_moose_cpack.cmake) diff --git a/CheckCXXCompiler.cmake b/CheckCXXCompiler.cmake index c6173acb..b1520579 100644 --- a/CheckCXXCompiler.cmake +++ b/CheckCXXCompiler.cmake @@ -1,5 +1,8 @@ -########################### COMPILER MACROS ##################################### +if(COMPILER_IS_TESTED) + return() +endif() +########################### COMPILER MACROS ##################################### include(CheckCXXCompilerFlag) CHECK_CXX_COMPILER_FLAG( "-std=c++11" COMPILER_SUPPORTS_CXX11 ) CHECK_CXX_COMPILER_FLAG( "-std=c++0x" COMPILER_SUPPORTS_CXX0X ) @@ -15,6 +18,8 @@ add_definitions(-Wall ) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") add_definitions( -Wno-unused-local-typedefs ) +elseif(("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") OR ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")) + add_definitions( -Wno-unused-local-typedef ) endif() @@ -32,12 +37,11 @@ if(COMPILER_SUPPORT_UNUSED_BUT_SET_VARIABLE_NO_WARN) endif(COMPILER_SUPPORT_UNUSED_BUT_SET_VARIABLE_NO_WARN) if(COMPILER_SUPPORTS_CXX11) - message(STATUS "Your compiler supports c++11 features. Enabling it") 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++" ) - message(STATUS "NOTE: Making clang to inline more aggresively" ) + # message(STATUS "NOTE: Making clang to inline more aggresively" ) add_definitions( -mllvm -inline-threshold=1000 ) endif(APPLE) else(COMPILER_SUPPORTS_CXX11) @@ -48,4 +52,4 @@ else(COMPILER_SUPPORTS_CXX11) ") endif(COMPILER_SUPPORTS_CXX11) - +set(COMPILER_IS_TESTED ON) diff --git a/README.md b/README.md index 6e5ed75a..6d24f263 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,19 @@ -[](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) +[](https://travis-ci.org/BhallaLab/moose-core) | [](https://badge.fury.io/py/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 . -# Download and Install +# Installation This repository is sufficient for using MOOSE as a python module. We provide python package via `pip`. $ pip install pymoose --user -`pymoose` is part of [MOOSE simulator](https://github.com/BhallaLab/moose). We also provide linux packages of -MOOSE simlulator. It can be downloaded from [Open Build Service](https://software.opensuse.org//download.html?project=home%3Amoose&package=moose). -In addition to `pymoose`, it also contain a `GUI` to create and visualize chemical network, and `moogli`, a visualizer of neural activity. +To install `nightly` build: + + $ pip install pymoose --user --pre --upgrde + +Have a look at examples, tutorials and demo here https://github.com/BhallaLab/moose-examples. # Build diff --git a/basecode/CMakeLists.txt b/basecode/CMakeLists.txt index 7fb64829..c166bfd2 100644 --- a/basecode/CMakeLists.txt +++ b/basecode/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 2.6) -include_directories(../msg) +cmake_minimum_required(VERSION 2.8) +include( ${CMAKE_CURRENT_SOURCE_DIR}/../CheckCXXCompiler.cmake ) add_library(basecode consts.cpp Element.cpp diff --git a/basecode/Cinfo.cpp b/basecode/Cinfo.cpp index d373cf71..cbbe2eb2 100644 --- a/basecode/Cinfo.cpp +++ b/basecode/Cinfo.cpp @@ -202,14 +202,6 @@ const Cinfo* Cinfo::find( const string& name ) map<string, Cinfo*>::iterator i = cinfoMap().find(name); if ( i != cinfoMap().end() ) return i->second; - -#ifdef RESULT_CHECK - stringstream ss; - ss << "+ " << name << " not found. Available names are " << endl; - ss << mapToString<string, Cinfo*>( cinfoMap() ); - dump(ss.str(), "DEBUG"); -#endif /* ----- not RESULT_CHECK ----- */ - return 0; } diff --git a/basecode/Conv.h b/basecode/Conv.h index 1f14ad70..e19fccab 100644 --- a/basecode/Conv.h +++ b/basecode/Conv.h @@ -9,7 +9,7 @@ #ifndef _CONV_H #define _CONV_H -#include <string> +#include <cstring> /** * This set of templates defines converters. The conversions are from diff --git a/basecode/Eref.h b/basecode/Eref.h index f3014fb2..bb71ce25 100644 --- a/basecode/Eref.h +++ b/basecode/Eref.h @@ -10,19 +10,6 @@ #ifndef _EREF_H #define _EREF_H -#ifdef CYMOOSE - -#include <iostream> -#include <vector> -using namespace std; - -class Element; -class Id; -class ObjId; -class MsgDigest; - -#endif /* ----- CYMOOSE ----- */ - class Eref { public: diff --git a/basecode/SrcFinfo.h b/basecode/SrcFinfo.h index 0a3b6d71..9d521c16 100644 --- a/basecode/SrcFinfo.h +++ b/basecode/SrcFinfo.h @@ -9,13 +9,6 @@ #ifndef _SRC_FINFO_H #define _SRC_FINFO_H -#ifdef CYMOOSE - -#include "../basecode/Finfo.h" -#include "../basecode/header.h" - -#endif /* ----- CYMOOSE ----- */ - /** * This set of classes define Message Sources. Their main job is to supply * a type-safe send operation, and to provide typechecking for it. diff --git a/basecode/header.h b/basecode/header.h index 595b7f26..22cb6fc2 100644 --- a/basecode/header.h +++ b/basecode/header.h @@ -20,20 +20,11 @@ #include <iostream> #include <sstream> #include <typeinfo> // used in Conv.h to extract compiler independent typeid -#include <climits> // Required for g++ 4.3.2 -#include <cstring> // Required for g++ 4.3.2 -#include <cstdlib> // Required for g++ 4.3.2 -// Used for INT_MAX and UINT_MAX, but may be done within the compiler -// #include <limits.h> -// #include <cassert> using namespace std; -#ifndef MOOSE_VERSION -#define MOOSE_VERSION "3.0.2" -#endif /** * Looks up and uniquely identifies functions, on a per-Cinfo basis. diff --git a/basecode/main.cpp b/basecode/main.cpp index cde0f33d..dc194c08 100644 --- a/basecode/main.cpp +++ b/basecode/main.cpp @@ -10,18 +10,10 @@ #include "header.h" #include "SparseMatrix.h" -#ifndef WIN32 -#include <sys/time.h> -#else #include <time.h> -#endif #include <math.h> #include <queue> -#ifdef WIN32 -#include "../external/xgetopt/XGetopt.h" -#else #include <unistd.h> // for getopt -#endif #include "../scheduling/Clock.h" #include "../msg/DiagonalMsg.h" #include "../msg/SparseMsg.h" @@ -93,12 +85,6 @@ extern void mooseBenchmarks( unsigned int option ); unsigned int getNumCores() { unsigned int numCPU = 0; -#ifdef WIN_32 - SYSTEM_INFO sysinfo; - GetSystemInfo( &sysinfo ); - - numCPU = sysinfo.dwNumberOfProcessors; -#endif #ifdef LINUX numCPU = sysconf( _SC_NPROCESSORS_ONLN ); diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt index 84b460a3..ab846b73 100644 --- a/benchmarks/CMakeLists.txt +++ b/benchmarks/CMakeLists.txt @@ -1,5 +1,7 @@ -include_directories(../msg) -include_directories(../basecode) +cmake_minimum_required(VERSION 2.8) + +include( ${CMAKE_CURRENT_SOURCE_DIR}/../CheckCXXCompiler.cmake ) + add_library(benchmarks benchmarks.cpp kineticMarks.cpp diff --git a/benchmarks/kineticMarks.cpp b/benchmarks/kineticMarks.cpp index a8e87741..370cb000 100644 --- a/benchmarks/kineticMarks.cpp +++ b/benchmarks/kineticMarks.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "../shell/Shell.h" /// Small model, long runtime. diff --git a/biophysics/CMakeLists.txt b/biophysics/CMakeLists.txt index 91444ada..390117a9 100644 --- a/biophysics/CMakeLists.txt +++ b/biophysics/CMakeLists.txt @@ -1,53 +1,53 @@ -include_directories(../basecode ../synapse ../utility ../) -include_directories(../external/muparser/include) +cmake_minimum_required(VERSION 2.8) +include(${CMAKE_CURRENT_SOURCE_DIR}/../CheckCXXCompiler.cmake) if(WITH_GSL) include_directories(${GSL_INCLUDE_DIRS}) endif(WITH_GSL) set(BIOPHYSICS_SRCS - IntFire.cpp - SpikeGen.cpp - RandSpike.cpp - CompartmentDataHolder.cpp - CompartmentBase.cpp - Compartment.cpp - SymCompartment.cpp - GapJunction.cpp - ChanBase.cpp - ChanCommon.cpp - HHChannel.cpp - HHChannelBase.cpp - HHChannel2D.cpp - HHGate.cpp - HHGate2D.cpp - HHChannel2D.cpp - CaConcBase.cpp - CaConc.cpp - MgBlock.cpp - Nernst.cpp - Neuron.cpp - ReadCell.cpp - SwcSegment.cpp - ReadSwc.cpp - SynChan.cpp - NMDAChan.cpp - testBiophysics.cpp - IzhikevichNrn.cpp - DifShellBase.cpp - DifShell.cpp - DifBufferBase.cpp - DifBuffer.cpp - MMPump.cpp - Leakage.cpp - VectorTable.cpp - MarkovRateTable.cpp - MarkovChannel.cpp - MatrixOps.cpp - MarkovSolverBase.cpp - MarkovSolver.cpp - VClamp.cpp - Spine.cpp + IntFire.cpp + SpikeGen.cpp + RandSpike.cpp + CompartmentDataHolder.cpp + CompartmentBase.cpp + Compartment.cpp + SymCompartment.cpp + GapJunction.cpp + ChanBase.cpp + ChanCommon.cpp + HHChannel.cpp + HHChannelBase.cpp + HHChannel2D.cpp + HHGate.cpp + HHGate2D.cpp + HHChannel2D.cpp + CaConcBase.cpp + CaConc.cpp + MgBlock.cpp + Nernst.cpp + Neuron.cpp + ReadCell.cpp + SwcSegment.cpp + ReadSwc.cpp + SynChan.cpp + NMDAChan.cpp + testBiophysics.cpp + IzhikevichNrn.cpp + DifShellBase.cpp + DifShell.cpp + DifBufferBase.cpp + DifBuffer.cpp + MMPump.cpp + Leakage.cpp + VectorTable.cpp + MarkovRateTable.cpp + MarkovChannel.cpp + MatrixOps.cpp + MarkovSolverBase.cpp + MarkovSolver.cpp + VClamp.cpp + Spine.cpp ) if(WITH_GSL) diff --git a/biophysics/CaConc.cpp b/biophysics/CaConc.cpp index 40f3bf2b..91dd8fce 100644 --- a/biophysics/CaConc.cpp +++ b/biophysics/CaConc.cpp @@ -7,8 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -// #include <cfloat> -#include "header.h" +#include "../basecode/header.h" #include "CaConcBase.h" #include "CaConc.h" diff --git a/biophysics/CaConcBase.cpp b/biophysics/CaConcBase.cpp index f569cbae..c95c386a 100644 --- a/biophysics/CaConcBase.cpp +++ b/biophysics/CaConcBase.cpp @@ -8,8 +8,8 @@ **********************************************************************/ // #include <cfloat> -#include "header.h" -#include "ElementValueFinfo.h" +#include "../basecode/header.h" +#include "../basecode/ElementValueFinfo.h" #include "CaConcBase.h" /////////////////////////////////////////////////////// diff --git a/biophysics/ChanBase.cpp b/biophysics/ChanBase.cpp index b483dbcb..02f2ba58 100644 --- a/biophysics/ChanBase.cpp +++ b/biophysics/ChanBase.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 "ChanBase.h" SrcFinfo1< double >* ChanBase::permeability() diff --git a/biophysics/ChanCommon.cpp b/biophysics/ChanCommon.cpp index 9a015e4f..a65282e7 100644 --- a/biophysics/ChanCommon.cpp +++ b/biophysics/ChanCommon.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "ChanBase.h" #include "ChanCommon.h" @@ -15,17 +15,19 @@ // Constructor /////////////////////////////////////////////////// ChanCommon::ChanCommon() - : - Vm_( 0.0 ), - Gbar_( 0.0 ), modulation_( 1.0 ), - Ek_( 0.0 ), - Gk_( 0.0 ), Ik_( 0.0 ) + : + Vm_( 0.0 ), + Gbar_( 0.0 ), modulation_( 1.0 ), + Ek_( 0.0 ), + Gk_( 0.0 ), Ik_( 0.0 ) { - ; + ; } ChanCommon::~ChanCommon() -{;} +{ + ; +} /////////////////////////////////////////////////// // Field function definitions @@ -33,54 +35,54 @@ ChanCommon::~ChanCommon() void ChanCommon::vSetGbar( const Eref& e, double Gbar ) { - Gbar_ = Gbar; + Gbar_ = Gbar; } double ChanCommon::vGetGbar( const Eref& e ) const { - return Gbar_; + return Gbar_; } void ChanCommon::vSetModulation( const Eref& e, double modulation ) { - modulation_ = modulation; + modulation_ = modulation; } double ChanCommon::vGetModulation( const Eref& e ) const { - return modulation_; + return modulation_; } double ChanCommon::getModulation() const { - return modulation_; + return modulation_; } void ChanCommon::vSetEk( const Eref& e, double Ek ) { - Ek_ = Ek; + Ek_ = Ek; } double ChanCommon::vGetEk( const Eref& e ) const { - return Ek_; + return Ek_; } void ChanCommon::vSetGk( const Eref& e, double Gk ) { - Gk_ = Gk; + Gk_ = Gk; } double ChanCommon::vGetGk( const Eref& e ) const { - return Gk_; + return Gk_; } void ChanCommon::vSetIk( const Eref& e, double Ik ) { - Ik_ = Ik; + Ik_ = Ik; } double ChanCommon::vGetIk( const Eref& e ) const { - return Ik_; + return Ik_; } /////////////////////////////////////////////////// @@ -89,7 +91,7 @@ double ChanCommon::vGetIk( const Eref& e ) const void ChanCommon::vHandleVm( double Vm ) { - Vm_ = Vm; + Vm_ = Vm; } /////////////////////////////////////////////////// @@ -99,34 +101,34 @@ void ChanCommon::vHandleVm( double Vm ) void ChanCommon::sendProcessMsgs( const Eref& e, const ProcPtr info ) { - ChanBase::channelOut()->send( e, Gk_, Ek_ ); - // This is used if the channel connects up to a conc pool and - // handles influx of ions giving rise to a concentration change. - ChanBase::IkOut()->send( e, Ik_ ); - // Needed by GHK-type objects - ChanBase::permeability()->send( e, Gk_ ); + ChanBase::channelOut()->send( e, Gk_, Ek_ ); + // This is used if the channel connects up to a conc pool and + // handles influx of ions giving rise to a concentration change. + ChanBase::IkOut()->send( e, Ik_ ); + // Needed by GHK-type objects + ChanBase::permeability()->send( e, Gk_ ); } void ChanCommon::sendReinitMsgs( const Eref& e, const ProcPtr info ) { - ChanBase::channelOut()->send( e, Gk_, Ek_ ); - ChanBase::IkOut()->send( e, Ik_ ); - // Needed by GHK-type objects - ChanBase::permeability()->send( e, Gk_ ); + ChanBase::channelOut()->send( e, Gk_, Ek_ ); + ChanBase::IkOut()->send( e, Ik_ ); + // Needed by GHK-type objects + ChanBase::permeability()->send( e, Gk_ ); } void ChanCommon::updateIk() { - Ik_ = ( Ek_ - Vm_ ) * Gk_; + Ik_ = ( Ek_ - Vm_ ) * Gk_; } double ChanCommon::getVm() const { - return Vm_; + return Vm_; } double ChanCommon::getGbar() const { - return Gbar_; + return Gbar_; } diff --git a/biophysics/ChanCommon.h b/biophysics/ChanCommon.h index 007c2f37..50725bb6 100644 --- a/biophysics/ChanCommon.h +++ b/biophysics/ChanCommon.h @@ -20,78 +20,75 @@ class ChanCommon: public virtual ChanBase { - public: - ChanCommon(); - ~ChanCommon(); - - ///////////////////////////////////////////////////////////// - // Value field access function definitions - ///////////////////////////////////////////////////////////// - - void vSetGbar( const Eref& e, double Gbar ); - double vGetGbar( const Eref& e ) const; - void vSetModulation( const Eref& e, double modulation ); - double vGetModulation( const Eref& e ) const; - double getModulation() const; - void vSetEk( const Eref& e, double Ek ); - double vGetEk( const Eref& e ) const; - void vSetGk( const Eref& e, double Gk ); - double vGetGk( const Eref& e ) const; - /// Ik is read-only for MOOSE, but we provide the set - /// func for derived classes to update it. - void vSetIk( const Eref& e, double Ic ); - double vGetIk( const Eref& e ) const; - - ///////////////////////////////////////////////////////////// - // Dest function definitions - ///////////////////////////////////////////////////////////// - - /** - * Assign the local Vm_ to the incoming Vm from the compartment - */ - void vHandleVm( double Vm ); - - ///////////////////////////////////////////////////////////// - /** - * This function sends out the messages expected of a channel, - * after process. Used as a utility by various derived classes. - */ - void sendProcessMsgs( const Eref& e, const ProcPtr info ); - void sendReinitMsgs( const Eref& e, const ProcPtr info ); - - ///////////////////////////////////////////////////////////// - - /** - * Utility function for a common computation using local variables - */ - void updateIk(); - - - /// Utility function to access Vm - double getVm() const; - - /// Utility function to acces Gbar - double getGbar() const; - - /// Specify the Class Info static variable for initialization. - static const Cinfo* initCinfo(); - protected: - /// Vm_ is input variable from compartment, used for most rates - double Vm_; - - private: - /// Channel maximal conductance - double Gbar_; - /// Channel modulation. Scales conductance. - double modulation_; - /// Reversal potential of channel - double Ek_; - - /// Channel actual conductance depending on opening of gates. - double Gk_; - /// Channel current - double Ik_; +public: + ChanCommon(); + ~ChanCommon(); + + ///////////////////////////////////////////////////////////// + // Value field access function definitions + ///////////////////////////////////////////////////////////// + + void vSetGbar( const Eref& e, double Gbar ); + double vGetGbar( const Eref& e ) const; + void vSetModulation( const Eref& e, double modulation ); + double vGetModulation( const Eref& e ) const; + double getModulation() const; + void vSetEk( const Eref& e, double Ek ); + double vGetEk( const Eref& e ) const; + void vSetGk( const Eref& e, double Gk ); + double vGetGk( const Eref& e ) const; + /// Ik is read-only for MOOSE, but we provide the set + /// func for derived classes to update it. + void vSetIk( const Eref& e, double Ic ); + double vGetIk( const Eref& e ) const; + + ///////////////////////////////////////////////////////////// + // Dest function definitions + ///////////////////////////////////////////////////////////// + + /** + * Assign the local Vm_ to the incoming Vm from the compartment + */ + void vHandleVm( double Vm ); + + ///////////////////////////////////////////////////////////// + /** + * This function sends out the messages expected of a channel, + * after process. Used as a utility by various derived classes. + */ + void sendProcessMsgs( const Eref& e, const ProcPtr info ); + void sendReinitMsgs( const Eref& e, const ProcPtr info ); + + ///////////////////////////////////////////////////////////// + + /** + * Utility function for a common computation using local variables + */ + void updateIk(); + + /// Utility function to access Vm + double getVm() const; + + /// Utility function to acces Gbar + double getGbar() const; + + /// Specify the Class Info static variable for initialization. + static const Cinfo* initCinfo(); +protected: + /// Vm_ is input variable from compartment, used for most rates + double Vm_; + +private: + /// Channel maximal conductance + double Gbar_; + /// Channel modulation. Scales conductance. + double modulation_; + /// Reversal potential of channel + double Ek_; + + /// Channel actual conductance depending on opening of gates. + double Gk_; + /// Channel current + double Ik_; }; - - #endif // _ChanCommon_h diff --git a/biophysics/CompartmentBase.cpp b/biophysics/CompartmentBase.cpp index 795acb5a..2085589c 100644 --- a/biophysics/CompartmentBase.cpp +++ b/biophysics/CompartmentBase.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 "CompartmentBase.h" #include "CompartmentDataHolder.h" #include "../shell/Wildcard.h" diff --git a/biophysics/CompartmentDataHolder.cpp b/biophysics/CompartmentDataHolder.cpp index 88940dc4..e1c70eba 100644 --- a/biophysics/CompartmentDataHolder.cpp +++ b/biophysics/CompartmentDataHolder.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" #include "CompartmentBase.h" #include "CompartmentDataHolder.h" // static func diff --git a/biophysics/DifBuffer.cpp b/biophysics/DifBuffer.cpp index 7e34e8a5..04e170f0 100644 --- a/biophysics/DifBuffer.cpp +++ b/biophysics/DifBuffer.cpp @@ -45,10 +45,10 @@ // Code: -#include "header.h" +#include "../basecode/header.h" #include "DifBufferBase.h" #include "DifBuffer.h" -#include "ElementValueFinfo.h" +#include "../basecode/ElementValueFinfo.h" #include "../utility/numutil.h" #include <cmath> const double DifBuffer::EPSILON = 1.0e-10; diff --git a/biophysics/DifBufferBase.cpp b/biophysics/DifBufferBase.cpp index 1be36d79..6e5bd8ae 100644 --- a/biophysics/DifBufferBase.cpp +++ b/biophysics/DifBufferBase.cpp @@ -1,6 +1,6 @@ -#include "header.h" +#include "../basecode/header.h" #include "DifBufferBase.h" -#include "ElementValueFinfo.h" +#include "../basecode/ElementValueFinfo.h" #include "../utility/numutil.h" #include <cmath> diff --git a/biophysics/DifShell.cpp b/biophysics/DifShell.cpp index c094d8c4..c24c9658 100644 --- a/biophysics/DifShell.cpp +++ b/biophysics/DifShell.cpp @@ -8,7 +8,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "DifShellBase.h" #include "DifShell.h" diff --git a/biophysics/DifShellBase.cpp b/biophysics/DifShellBase.cpp index d6b6ed20..9742d839 100644 --- a/biophysics/DifShellBase.cpp +++ b/biophysics/DifShellBase.cpp @@ -8,9 +8,9 @@ ** See the file COPYING.LIB for the full notice. ****/ -#include "header.h" +#include "../basecode/header.h" #include "DifShellBase.h" -#include "ElementValueFinfo.h" +#include "../basecode/ElementValueFinfo.h" SrcFinfo1< double >* DifShellBase::concentrationOut() { diff --git a/biophysics/GapJunction.cpp b/biophysics/GapJunction.cpp index d7d88768..cfdda6c3 100644 --- a/biophysics/GapJunction.cpp +++ b/biophysics/GapJunction.cpp @@ -45,7 +45,7 @@ // Code: -#include "header.h" +#include "../basecode/header.h" #include "GapJunction.h" static SrcFinfo2< double, double >* channel1Out() diff --git a/biophysics/HHChannel.cpp b/biophysics/HHChannel.cpp index 87453e97..e7c72b5a 100644 --- a/biophysics/HHChannel.cpp +++ b/biophysics/HHChannel.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 "HHGate.h" #include "ChanBase.h" #include "ChanCommon.h" diff --git a/biophysics/HHChannel2D.cpp b/biophysics/HHChannel2D.cpp index f937f692..d0d2cf02 100644 --- a/biophysics/HHChannel2D.cpp +++ b/biophysics/HHChannel2D.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 "../builtins/Interpol2D.h" #include "ChanBase.h" #include "ChanCommon.h" diff --git a/biophysics/HHChannelBase.cpp b/biophysics/HHChannelBase.cpp index 147bb6e8..91813380 100644 --- a/biophysics/HHChannelBase.cpp +++ b/biophysics/HHChannelBase.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 "HHGate.h" #include "ChanBase.h" #include "HHChannelBase.h" diff --git a/biophysics/HHGate.cpp b/biophysics/HHGate.cpp index 64140728..0e8ca584 100644 --- a/biophysics/HHGate.cpp +++ b/biophysics/HHGate.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 "HHGate.h" static const double SINGULARITY = 1.0e-6; diff --git a/biophysics/HHGate2D.cpp b/biophysics/HHGate2D.cpp index e0628095..c3c88138 100644 --- a/biophysics/HHGate2D.cpp +++ b/biophysics/HHGate2D.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 "../builtins/Interpol2D.h" #include "HHGate2D.h" diff --git a/biophysics/IntFire.cpp b/biophysics/IntFire.cpp index 990e62d7..04acbd29 100644 --- a/biophysics/IntFire.cpp +++ b/biophysics/IntFire.cpp @@ -8,7 +8,7 @@ **********************************************************************/ #include <queue> -#include "header.h" +#include "../basecode/header.h" #include "IntFire.h" static SrcFinfo1< double > *spikeOut() { diff --git a/biophysics/IzhikevichNrn.cpp b/biophysics/IzhikevichNrn.cpp index 0a8ac0ed..89f78696 100644 --- a/biophysics/IzhikevichNrn.cpp +++ b/biophysics/IzhikevichNrn.cpp @@ -28,7 +28,7 @@ // Code: -#include "header.h" +#include "../basecode/header.h" #include "IzhikevichNrn.h" diff --git a/biophysics/Leakage.cpp b/biophysics/Leakage.cpp index ae78b6ee..bd52d20f 100644 --- a/biophysics/Leakage.cpp +++ b/biophysics/Leakage.cpp @@ -45,14 +45,15 @@ // Code: -#include "header.h" +#include "../basecode/header.h" #include "ChanBase.h" #include "ChanCommon.h" #include "Leakage.h" const Cinfo* Leakage::initCinfo() { - static string doc[] = { + static string doc[] = + { "Name", "Leakage", "Author", "Subhasis Ray, 2009, Upi Bhalla 2014 NCBS", "Description", "Leakage: Passive leakage channel." @@ -63,8 +64,8 @@ const Cinfo* Leakage::initCinfo() static Cinfo LeakageCinfo( "Leakage", ChanBase::initCinfo(), - 0, - 0, + 0, + 0, &dinfo, doc, sizeof( doc ) / sizeof( string )); @@ -88,22 +89,22 @@ Leakage::~Leakage() void Leakage::vProcess( const Eref & e, ProcPtr p ) { - ChanCommon::vSetGk( e, this->vGetGbar( e ) * this->vGetModulation( e )); - updateIk(); + ChanCommon::vSetGk( e, this->vGetGbar( e ) * this->vGetModulation( e )); + updateIk(); sendProcessMsgs(e, p); } void Leakage::vReinit( const Eref & e, ProcPtr p ) { - ChanCommon::vSetGk( e, this->vGetGbar( e ) * this->vGetModulation( e )); - updateIk(); + ChanCommon::vSetGk( e, this->vGetGbar( e ) * this->vGetModulation( e )); + updateIk(); sendReinitMsgs(e, p); } void Leakage::vSetGbar( const Eref& e, double gbar ) { - ChanCommon::vSetGk( e, gbar * this->vGetModulation( e ) ); - ChanCommon::vSetGbar( e, gbar ); + ChanCommon::vSetGk( e, gbar * this->vGetModulation( e ) ); + ChanCommon::vSetGbar( e, gbar ); } // diff --git a/biophysics/Leakage.h b/biophysics/Leakage.h index 959b5327..3b20eaf7 100644 --- a/biophysics/Leakage.h +++ b/biophysics/Leakage.h @@ -51,7 +51,7 @@ class Leakage: public ChanCommon { - public: +public: Leakage(); ~Leakage(); void vProcess( const Eref & e, ProcPtr p ); diff --git a/biophysics/MMPump.cpp b/biophysics/MMPump.cpp index e6c0dd76..8c4e7423 100644 --- a/biophysics/MMPump.cpp +++ b/biophysics/MMPump.cpp @@ -1,6 +1,6 @@ -#include "header.h" +#include "../basecode/header.h" #include "MMPump.h" -#include "ElementValueFinfo.h" +#include "../basecode/ElementValueFinfo.h" #include "../utility/numutil.h" #include <cmath> diff --git a/biophysics/MarkovChannel.cpp b/biophysics/MarkovChannel.cpp index ab601ca8..a79b17b4 100644 --- a/biophysics/MarkovChannel.cpp +++ b/biophysics/MarkovChannel.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "VectorTable.h" #include "../builtins/Interpol2D.h" #include "MarkovRateTable.h" diff --git a/biophysics/MarkovGslSolver.cpp b/biophysics/MarkovGslSolver.cpp index 0260215a..ca90e7a3 100644 --- a/biophysics/MarkovGslSolver.cpp +++ b/biophysics/MarkovGslSolver.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include <gsl/gsl_errno.h> #include <gsl/gsl_odeiv.h> #include "MarkovGslSolver.h" diff --git a/biophysics/MarkovRateTable.cpp b/biophysics/MarkovRateTable.cpp index 12dbe32f..5bcaf532 100644 --- a/biophysics/MarkovRateTable.cpp +++ b/biophysics/MarkovRateTable.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ #include <iomanip> -#include "header.h" +#include "../basecode/header.h" #include "VectorTable.h" #include "../builtins/Interpol2D.h" #include "MarkovRateTable.h" diff --git a/biophysics/MarkovSolver.cpp b/biophysics/MarkovSolver.cpp index 0c877950..3f1a0e00 100644 --- a/biophysics/MarkovSolver.cpp +++ b/biophysics/MarkovSolver.cpp @@ -7,8 +7,8 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include <float.h> //Needed for DBL_MAX and DBL_MIN -#include "header.h" +#include <cfloat> //Needed for DBL_MAX and DBL_MIN +#include "../basecode/header.h" #include "MatrixOps.h" #include "VectorTable.h" diff --git a/biophysics/MarkovSolverBase.cpp b/biophysics/MarkovSolverBase.cpp index bcf5ccf4..6d57f1fc 100644 --- a/biophysics/MarkovSolverBase.cpp +++ b/biophysics/MarkovSolverBase.cpp @@ -7,8 +7,8 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include <float.h> //Needed for DBL_MAX and DBL_MIN -#include "header.h" +#include <cfloat> +#include "../basecode/header.h" #include "MatrixOps.h" #include "VectorTable.h" diff --git a/biophysics/MatrixOps.cpp b/biophysics/MatrixOps.cpp index f0f478c3..d251cf54 100644 --- a/biophysics/MatrixOps.cpp +++ b/biophysics/MatrixOps.cpp @@ -8,7 +8,7 @@ **********************************************************************/ #include <vector> #include <math.h> -#include "doubleEq.h" +#include "../basecode/doubleEq.h" #include <iostream> #include "MatrixOps.h" diff --git a/biophysics/MgBlock.cpp b/biophysics/MgBlock.cpp index a070e7aa..ace49df1 100644 --- a/biophysics/MgBlock.cpp +++ b/biophysics/MgBlock.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "ChanBase.h" #include "ChanCommon.h" #include "MgBlock.h" diff --git a/biophysics/NMDAChan.cpp b/biophysics/NMDAChan.cpp index 7699ab16..1544d730 100644 --- a/biophysics/NMDAChan.cpp +++ b/biophysics/NMDAChan.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 "ChanBase.h" #include "ChanCommon.h" #include "SynChan.h" diff --git a/biophysics/Nernst.cpp b/biophysics/Nernst.cpp index 3ffb36ae..01104201 100644 --- a/biophysics/Nernst.cpp +++ b/biophysics/Nernst.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "Nernst.h" const double Nernst::R_OVER_F = 8.6171458e-5; diff --git a/biophysics/Neuron.cpp b/biophysics/Neuron.cpp index aa867591..15ec8e60 100644 --- a/biophysics/Neuron.cpp +++ b/biophysics/Neuron.cpp @@ -7,19 +7,19 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" -#include "ElementValueFinfo.h" -#include "LookupElementValueFinfo.h" -#include "shell/Shell.h" -#include "shell/Wildcard.h" +#include "../basecode/header.h" +#include "../basecode/ElementValueFinfo.h" +#include "../basecode/LookupElementValueFinfo.h" +#include "../shell/Shell.h" +#include "../shell/Wildcard.h" #include "ReadCell.h" -#include "utility/Vec.h" +#include "../utility/Vec.h" #include "SwcSegment.h" #include "Spine.h" #include "Neuron.h" -#include "basecode/global.h" +#include "../basecode/global.h" -#include "muParser.h" +#include "../external/muparser/include/muParser.h" class nuParser: public mu::Parser { @@ -315,11 +315,17 @@ const Cinfo* Neuron::initCinfo() "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 " + "then the system will 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", + "angle, angleDistrib \n" + "minSpacing sets the granularity of sampling (typically about 0.1*" + "spacing) for the usual case where spines are spaced randomly. " + "If minSpacing < 0 then the spines are spaced equally at " + "'spacing', unless the dendritic segment length is smaller than " + "'spacing'. In that case it falls back to the regular random " + "placement method.", &Neuron::setSpineDistribution, &Neuron::getSpineDistribution ); @@ -1788,6 +1794,19 @@ static void addPos( unsigned int segIndex, unsigned int eIndex, vector< unsigned int >& elistIndex, vector< double >& pos ) { + if ( minSpacing < 0.0 ) { + // Use uniform spacing + for ( double position = spacing * 0.5; + position < dendLength; position += spacing ) { + seglistIndex.push_back( segIndex ); + elistIndex.push_back( eIndex ); + pos.push_back( position ); + } + if ( dendLength > spacing * 0.5 ) + return; + // If the dend length is too small for regular placement, + // fall back to using probability to decide if segment gets spine + } if ( minSpacing < spacing * 0.1 && minSpacing < 1e-7 ) minSpacing = spacing * 0.1; if ( minSpacing > spacing * 0.5 ) @@ -1860,13 +1879,6 @@ void Neuron::makeSpacingDistrib( const vector< ObjId >& elist, { 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() ) diff --git a/biophysics/ReadCell.cpp b/biophysics/ReadCell.cpp index 2a35b98c..d900e5a3 100644 --- a/biophysics/ReadCell.cpp +++ b/biophysics/ReadCell.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "../shell/Shell.h" #include "ReadCell.h" #include "../utility/utility.h" diff --git a/biophysics/ReadSwc.cpp b/biophysics/ReadSwc.cpp index 22cc98c8..9329ed51 100644 --- a/biophysics/ReadSwc.cpp +++ b/biophysics/ReadSwc.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "../shell/Shell.h" #include "../utility/Vec.h" #include "SwcSegment.h" diff --git a/biophysics/SpikeGen.cpp b/biophysics/SpikeGen.cpp index dad12260..3fe04809 100644 --- a/biophysics/SpikeGen.cpp +++ b/biophysics/SpikeGen.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "SpikeGen.h" /////////////////////////////////////////////////////// diff --git a/biophysics/Spine.cpp b/biophysics/Spine.cpp index 03ca6eac..d3da2e1a 100644 --- a/biophysics/Spine.cpp +++ b/biophysics/Spine.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 "../utility/Vec.h" #include "SwcSegment.h" #include "Spine.h" diff --git a/biophysics/SymCompartment.cpp b/biophysics/SymCompartment.cpp index 11d2a07f..b71df59b 100644 --- a/biophysics/SymCompartment.cpp +++ b/biophysics/SymCompartment.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "CompartmentBase.h" #include "Compartment.h" diff --git a/biophysics/SynChan.cpp b/biophysics/SynChan.cpp index 4fd207c5..4ce9a3b7 100644 --- a/biophysics/SynChan.cpp +++ b/biophysics/SynChan.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "ChanBase.h" #include "ChanCommon.h" #include "SynChan.h" diff --git a/biophysics/VClamp.cpp b/biophysics/VClamp.cpp index b28218d5..cd0760ff 100644 --- a/biophysics/VClamp.cpp +++ b/biophysics/VClamp.cpp @@ -45,8 +45,8 @@ // Code: -#include "header.h" -#include "Dinfo.h" +#include "../basecode/header.h" +#include "../basecode/Dinfo.h" #include "VClamp.h" using namespace moose; diff --git a/biophysics/VectorTable.cpp b/biophysics/VectorTable.cpp index ef66a926..cbb8c96d 100644 --- a/biophysics/VectorTable.cpp +++ b/biophysics/VectorTable.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" #include "VectorTable.h" #define INIT_XMIN 0 diff --git a/builtins/Arith.cpp b/builtins/Arith.cpp index ae5166bf..6e091ecd 100644 --- a/builtins/Arith.cpp +++ b/builtins/Arith.cpp @@ -8,7 +8,7 @@ **********************************************************************/ #include <queue> -#include "header.h" +#include "../basecode/header.h" #include "Arith.h" static SrcFinfo1< double > *output() { diff --git a/builtins/CMakeLists.txt b/builtins/CMakeLists.txt index bbc4ab70..9c226011 100644 --- a/builtins/CMakeLists.txt +++ b/builtins/CMakeLists.txt @@ -1,9 +1,7 @@ -include_directories( ${CMAKE_SOURCE_DIR}/msg ) -include_directories( ${CMAKE_SOURCE_DIR}/basecode ) -include_directories( ${CMAKE_SOURCE_DIR}/external/muparser/include ) -include_directories( ${CMAKE_SOURCE_DIR}/scheduling ) +cmake_minimum_required(VERSION 2.8) +include( ${CMAKE_CURRENT_SOURCE_DIR}/../CheckCXXCompiler.cmake ) -add_library(moose_builtins +set(SRCS Arith.cpp Group.cpp Mstring.cpp @@ -20,10 +18,17 @@ add_library(moose_builtins Streamer.cpp Stats.cpp Interpol2D.cpp - HDF5WriterBase.cpp - NSDFWriter.cpp - HDF5DataWriter.cpp SpikeStats.cpp testBuiltins.cpp - testNSDF.cpp ) + +if(WITH_NSDF AND HDF5_FOUND) + list(APPEND SRCS + HDF5WriterBase.cpp + NSDFWriter.cpp + HDF5DataWriter.cpp + testNSDF.cpp + ) +endif() + +add_library(moose_builtins ${SRCS} ) diff --git a/builtins/Func.cpp b/builtins/Func.cpp index c8c6624d..7408ded3 100644 --- a/builtins/Func.cpp +++ b/builtins/Func.cpp @@ -45,7 +45,7 @@ // Code: -#include "header.h" +#include "../basecode/header.h" #include "../utility/utility.h" #include "../utility/numutil.h" #include "Func.h" diff --git a/builtins/Func.h b/builtins/Func.h index 9c2ee784..4ca6d097 100644 --- a/builtins/Func.h +++ b/builtins/Func.h @@ -47,7 +47,7 @@ #ifndef _FUNC_H #define _FUNC_H -#include "muParser.h" +#include "../external/muparser/include/muParser.h" /** Simple function parser and evaluator for MOOSE. This can take a mathematical expression in standard C form and a list of variables values and diff --git a/builtins/Function.cpp b/builtins/Function.cpp index 8c82c64b..3883b699 100644 --- a/builtins/Function.cpp +++ b/builtins/Function.cpp @@ -45,13 +45,13 @@ // Code: -#include "header.h" +#include "../basecode/header.h" #include "../utility/utility.h" #include "../utility/numutil.h" #include "Variable.h" #include "Function.h" -#include "ElementValueFinfo.h" +#include "../basecode/ElementValueFinfo.h" #define PARSER_MAXVARS 100 diff --git a/builtins/Function.h b/builtins/Function.h index 8f50957b..6a9fff3f 100644 --- a/builtins/Function.h +++ b/builtins/Function.h @@ -48,7 +48,7 @@ #ifndef _MOOSE_FUNCTION_H_ #define _MOOSE_FUNCTION_H_ -#include "muParser.h" +#include "../external/muparser/include/muParser.h" /** Simple function parser and evaluator for MOOSE. This can take a mathematical @@ -149,11 +149,11 @@ protected: bool _useTrigger; bool _doEvalAtReinit; - // this stores variables received via incoming messages, identifiers of + // this stores variables received via incoming messages, identifiers of // the form x{i} are included in this vector<Variable *> _varbuf; - // this stores variable values pulled by sending request. identifiers of + // this stores variable values pulled by sending request. identifiers of // the form y{i} are included in this vector< double * > _pullbuf; map< string, double *> _constbuf; // for constants @@ -163,7 +163,9 @@ protected: void _clearBuffer(); void _showError(mu::Parser::exception_type &e) const; - char* _stoich; // Used by kinetic solvers when this is zombified. + + // Used by kinetic solvers when this is zombified. + char* _stoich; }; diff --git a/builtins/Group.cpp b/builtins/Group.cpp index 2a0db02f..b15cb223 100644 --- a/builtins/Group.cpp +++ b/builtins/Group.cpp @@ -8,7 +8,7 @@ **********************************************************************/ #include <queue> -#include "header.h" +#include "../basecode/header.h" #include "Group.h" ////////////////////////////////////////////////////////////// diff --git a/builtins/Interpol.cpp b/builtins/Interpol.cpp index ee84e447..b7443ab8 100644 --- a/builtins/Interpol.cpp +++ b/builtins/Interpol.cpp @@ -45,7 +45,7 @@ // -#include "header.h" +#include "../basecode/header.h" #include "../utility/numutil.h" #include "TableBase.h" #include "Interpol.h" diff --git a/builtins/Interpol2D.cpp b/builtins/Interpol2D.cpp index de5b6a6d..a35fe86a 100644 --- a/builtins/Interpol2D.cpp +++ b/builtins/Interpol2D.cpp @@ -9,7 +9,7 @@ #include <fstream> #include <sstream> -#include "header.h" +#include "../basecode/header.h" #include "../utility/strutil.h" #include "Interpol2D.h" diff --git a/builtins/Mstring.cpp b/builtins/Mstring.cpp index 3b3e2068..f19b805e 100644 --- a/builtins/Mstring.cpp +++ b/builtins/Mstring.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" #include "Mstring.h" const Cinfo* Mstring::initCinfo() diff --git a/builtins/SpikeStats.cpp b/builtins/SpikeStats.cpp index 544d843f..24c5a429 100644 --- a/builtins/SpikeStats.cpp +++ b/builtins/SpikeStats.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "Stats.h" #include "SpikeStats.h" diff --git a/builtins/Stats.cpp b/builtins/Stats.cpp index cc2f94b3..5c1ab3ab 100644 --- a/builtins/Stats.cpp +++ b/builtins/Stats.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "Stats.h" static SrcFinfo1< vector< double >* > *requestOut() { diff --git a/builtins/StimulusTable.cpp b/builtins/StimulusTable.cpp index 00b442f7..c5068fdb 100644 --- a/builtins/StimulusTable.cpp +++ b/builtins/StimulusTable.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include <fstream> #include "TableBase.h" #include "StimulusTable.h" diff --git a/builtins/Streamer.cpp b/builtins/Streamer.cpp index dd9c0bf2..5ecde621 100644 --- a/builtins/Streamer.cpp +++ b/builtins/Streamer.cpp @@ -17,11 +17,11 @@ #include <algorithm> #include <sstream> -#include "global.h" -#include "header.h" +#include "../basecode/global.h" +#include "../basecode/header.h" #include "Streamer.h" -#include "Clock.h" -#include "utility/utility.h" +#include "../scheduling/Clock.h" +#include "../utility/utility.h" #include "../shell/Shell.h" diff --git a/builtins/StreamerBase.cpp b/builtins/StreamerBase.cpp index be264dd0..cb436b99 100644 --- a/builtins/StreamerBase.cpp +++ b/builtins/StreamerBase.cpp @@ -15,8 +15,8 @@ */ -#include "global.h" -#include "header.h" +#include "../basecode/global.h" +#include "../basecode/header.h" #include "StreamerBase.h" #include "../scheduling/Clock.h" diff --git a/builtins/Table.cpp b/builtins/Table.cpp index c82c6a8d..f5a6b771 100644 --- a/builtins/Table.cpp +++ b/builtins/Table.cpp @@ -7,13 +7,13 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" -#include "global.h" +#include "../basecode/header.h" +#include "../basecode/global.h" #include <fstream> #include "TableBase.h" #include "Table.h" -#include "Clock.h" +#include "../scheduling/Clock.h" #include "StreamerBase.h" // Write to numpy arrays. diff --git a/builtins/TableBase.cpp b/builtins/TableBase.cpp index f5c11e75..e4467c6f 100644 --- a/builtins/TableBase.cpp +++ b/builtins/TableBase.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include <fstream> #include "../utility/strutil.h" #include "TableBase.h" diff --git a/builtins/TimeTable.cpp b/builtins/TimeTable.cpp index d2ebdb80..ec9a7bf2 100644 --- a/builtins/TimeTable.cpp +++ b/builtins/TimeTable.cpp @@ -9,7 +9,7 @@ **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include <fstream> #include "TableBase.h" #include "TimeTable.h" diff --git a/builtins/Variable.cpp b/builtins/Variable.cpp index bfeb6995..6233e248 100644 --- a/builtins/Variable.cpp +++ b/builtins/Variable.cpp @@ -45,7 +45,7 @@ // Code: -#include "header.h" +#include "../basecode/header.h" #include "Variable.h" #include "Function.h" diff --git a/builtins/testBuiltins.cpp b/builtins/testBuiltins.cpp index c301a6a2..d94f4ecf 100644 --- a/builtins/testBuiltins.cpp +++ b/builtins/testBuiltins.cpp @@ -7,9 +7,9 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" -#include "DiagonalMsg.h" -#include "OneToAllMsg.h" +#include "../basecode/header.h" +#include "../msg/DiagonalMsg.h" +#include "../msg/OneToAllMsg.h" #include "../scheduling/Clock.h" #include "Arith.h" #include "TableBase.h" @@ -18,7 +18,9 @@ #include "../shell/Shell.h" +#ifdef ENABLE_NSDF extern void testNSDF(); +#endif void testArith() { @@ -425,7 +427,9 @@ void testBuiltins() { testArith(); testTable(); +#if ENABLE_NSDF testNSDF(); +#endif } void testBuiltinsProcess() diff --git a/cmake_modules/FindNumPy.cmake b/cmake_modules/FindNumPy.cmake index 5de7901e..285b4730 100644 --- a/cmake_modules/FindNumPy.cmake +++ b/cmake_modules/FindNumPy.cmake @@ -40,7 +40,7 @@ # Finding NumPy involves calling the Python interpreter -message( STATUS "Using python ${PYTHON_EXECUTABLE} to locate numpy" ) +message( STATUS "Using ${PYTHON_EXECUTABLE} to locate numpy" ) execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import numpy as n; print(n.__version__); print(n.get_include());" RESULT_VARIABLE _NUMPY_SEARCH_SUCCESS diff --git a/device/CMakeLists.txt b/device/CMakeLists.txt index 564ae44c..01b5bc9b 100644 --- a/device/CMakeLists.txt +++ b/device/CMakeLists.txt @@ -1,5 +1,5 @@ -include_directories(../msg) -include_directories(../basecode) +cmake_minimum_required(VERSION 2.8) +include( ${CMAKE_CURRENT_SOURCE_DIR}/../CheckCXXCompiler.cmake) add_library(device PulseGen.cpp DiffAmp.cpp diff --git a/device/PulseGen.cpp b/device/PulseGen.cpp index 20a10af5..b98a4981 100644 --- a/device/PulseGen.cpp +++ b/device/PulseGen.cpp @@ -29,7 +29,7 @@ // Code: -#include "header.h" +#include "../basecode/header.h" #include "PulseGen.h" static SrcFinfo1< double >* outputOut() diff --git a/diffusion/CMakeLists.txt b/diffusion/CMakeLists.txt index b084c506..95c1ebf0 100644 --- a/diffusion/CMakeLists.txt +++ b/diffusion/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 2.6) -include_directories(../basecode ../utility ../ksolve) +cmake_minimum_required(VERSION 2.8) +include( ${CMAKE_CURRENT_SOURCE_DIR}/../CheckCXXCompiler.cmake) include_directories(${GSL_INCLUDE_DIRS}) add_library(diffusion FastMatrixElim.cpp diff --git a/diffusion/DiffPoolVec.cpp b/diffusion/DiffPoolVec.cpp index d8a9208d..536d7dd7 100644 --- a/diffusion/DiffPoolVec.cpp +++ b/diffusion/DiffPoolVec.cpp @@ -14,7 +14,7 @@ #include <iostream> using namespace std; -#include "SparseMatrix.h" +#include "../basecode/SparseMatrix.h" #include "DiffPoolVec.h" /** diff --git a/diffusion/Dsolve.cpp b/diffusion/Dsolve.cpp index c1428146..9f1fc45a 100644 --- a/diffusion/Dsolve.cpp +++ b/diffusion/Dsolve.cpp @@ -7,14 +7,14 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" -#include "ElementValueFinfo.h" -#include "SparseMatrix.h" -#include "KinSparseMatrix.h" -#include "VoxelPoolsBase.h" +#include "../basecode/header.h" +#include "../basecode/ElementValueFinfo.h" +#include "../basecode/SparseMatrix.h" +#include "../ksolve/KinSparseMatrix.h" +#include "../ksolve/VoxelPoolsBase.h" #include "../mesh/VoxelJunction.h" -#include "XferInfo.h" -#include "ZombiePoolInterface.h" +#include "../ksolve/XferInfo.h" +#include "../ksolve/ZombiePoolInterface.h" #include "../kinetics/ConcChan.h" #include "DiffPoolVec.h" #include "ConcChanInfo.h" @@ -422,7 +422,9 @@ void Dsolve::calcJnChan( const DiffJunction& jn, Dsolve* other, double dt ) double lastN = myN; double otherN = otherDv.getN( j->second ); double chanN = chanDv.getN( j->first ); - double perm = myChan.permeability * chanN / NA; + // Stick in a conversion factor for the myN and otherN into + // concentrations. Note that SI is millimolar. + double perm = myChan.permeability * chanN * 1000.0 / NA; myN = integ( myN, perm * myN/j->firstVol, perm * otherN/j->secondVol, dt ); otherN += lastN - myN; // Mass consv @@ -459,7 +461,9 @@ void Dsolve::calcOtherJnChan( const DiffJunction& jn, Dsolve* other, double dt ) double lastN = myN; double otherN = otherDv.getN( j->second ); double chanN = chanDv.getN( j->second ); - double perm = otherChan.permeability * chanN / NA; + // Stick in a conversion factor for the myN and otherN into + // concentrations. Note that SI is millimolar. + double perm = otherChan.permeability * chanN * 1000.0 / NA; myN = integ( myN, perm * myN/j->firstVol, perm * otherN/j->secondVol, dt ); otherN += lastN - myN; // Mass consv @@ -1130,7 +1134,7 @@ double Dsolve::getNinit( const Eref& e ) const { return pools_[ pid ].getNinit( vox ); } - cout << "Warning: Dsolve::setNinit: Eref " << e << " out of range " << + cout << "Warning: Dsolve::getNinit: Eref " << e << " out of range " << pools_.size() << ", " << numVoxels_ << "\n"; return 0.0; } diff --git a/diffusion/standaloneTestFastElim.cpp b/diffusion/standaloneTestFastElim.cpp index 9e4eb675..35b56b10 100644 --- a/diffusion/standaloneTestFastElim.cpp +++ b/diffusion/standaloneTestFastElim.cpp @@ -18,60 +18,61 @@ const unsigned int SM_MAX_COLUMNS = 200000; const unsigned int SM_RESERVE = 8; void sortByColumn( - vector< unsigned int >& col, vector< double >& entry ); + vector< unsigned int >& col, vector< double >& entry ); void testSorting(); class Unroll { - public: - Unroll( double diag, double off, unsigned int i, unsigned int j ) - : - diagVal( diag ), - offDiagVal( off ), - row( i ), - col( j ) - {;} - double diagVal; - double offDiagVal; - unsigned int row; // On which the diagonal is located - unsigned int col; // Col on which the offDiagVal is located. +public: + Unroll( double diag, double off, unsigned int i, unsigned int j ) + : + diagVal( diag ), + offDiagVal( off ), + row( i ), + col( j ) + {;} + double diagVal; + double offDiagVal; + unsigned int row; // On which the diagonal is located + unsigned int col; // Col on which the offDiagVal is located. }; class FastElim: public SparseMatrix< double > { - public: - void makeTestMatrix( const double* test, unsigned int numCompts ); - /* - void rowElim( unsigned int row1, unsigned int row2, - vector< double >& rhs ); - */ - void buildForwardElim( vector< unsigned int >& diag, - vector< Triplet< double > >& fops ); - void buildBackwardSub( vector< unsigned int >& diag, - vector< Triplet< double > >& bops, vector< double >& diagVal ); - ///////////////////////////////////////////////////////////// - // Here we do stuff to set up the Hines ordering of the matrix. - ///////////////////////////////////////////////////////////// - bool hinesReorder( const vector< unsigned int >& parentVoxel ); - const double* allEntries() const; - void shuffleRows( - const vector< unsigned int >& lookupOldRowFromNew ); - /* - bool hinesReorder(); - void extractTwig( unsigned int i, - vector< unsigned int >& rowReorder, - vector< bool >& extracted ); - void findClosedEnds( - vector< unsigned int >& rowReorder, - vector< bool >& extracted ); - void extractClosedEnds( unsigned int i, - vector< unsigned int >& rowReorder, - vector< bool >& extracted ); - */ +public: + void makeTestMatrix( const double* test, unsigned int numCompts ); + /* + void rowElim( unsigned int row1, unsigned int row2, + vector< double >& rhs ); + */ + void buildForwardElim( vector< unsigned int >& diag, + vector< Triplet< double > >& fops ); + void buildBackwardSub( vector< unsigned int >& diag, + vector< Triplet< double > >& bops, vector< double >& diagVal ); + ///////////////////////////////////////////////////////////// + // Here we do stuff to set up the Hines ordering of the matrix. + ///////////////////////////////////////////////////////////// + bool hinesReorder( const vector< unsigned int >& parentVoxel ); + const double* allEntries() const; + void shuffleRows( + const vector< unsigned int >& lookupOldRowFromNew ); + /* + bool hinesReorder(); + void extractTwig( unsigned int i, + vector< unsigned int >& rowReorder, + vector< bool >& extracted ); + void findClosedEnds( + vector< unsigned int >& rowReorder, + vector< bool >& extracted ); + void extractClosedEnds( unsigned int i, + vector< unsigned int >& rowReorder, + vector< bool >& extracted ); + */ }; -const double* FastElim::allEntries() const { - return &N_[0]; +const double* FastElim::allEntries() const +{ + return &N_[0]; } // @@ -84,99 +85,111 @@ const double* FastElim::allEntries() const { */ bool FastElim::hinesReorder( const vector< unsigned int >& parentVoxel ) { - // First we fill in the vector that specifies the old row number - // assigned to each row of the reordered matrix. - assert( parentVoxel.size() == nrows_ ); - vector< unsigned int > numKids( nrows_, 0 ); - vector< unsigned int > lookupOldRowFromNew; - vector< bool > rowPending( nrows_, true ); - unsigned int numDone = 0; - for ( unsigned int i = 0; i < nrows_; ++i ) { - if ( parentVoxel[i] != -1 ) - numKids[ parentVoxel[i] ]++; - } - while ( numDone < nrows_ ) { - for ( unsigned int i = 0; i < nrows_; ++i ) { - if ( rowPending[i] && numKids[i] == 0 ) { - lookupOldRowFromNew.push_back( i ); - rowPending[i] = false; - numDone++; - unsigned int pa = parentVoxel[i]; - // Unsure what the root parent is. Assume it is -1 - while ( pa != -1 && numKids[pa] == 1 ) { - assert( rowPending[pa] ); - rowPending[pa] = false; - numDone++; - lookupOldRowFromNew.push_back( pa ); - pa = parentVoxel[pa]; - } - if ( pa != -1 ) { - assert( numKids[pa] > 0 ); - numKids[pa]--; - } - } - } - } - - cout << setprecision(4); - cout << "oldRowFromNew= {" ; - for ( int i = 0; i < nrows_; ++i ) - cout << lookupOldRowFromNew[i] << ", "; - cout << "}\n"; - // Then we fill in the reordered matrix. Note we need to reorder - // columns too. - shuffleRows( lookupOldRowFromNew ); + // First we fill in the vector that specifies the old row number + // assigned to each row of the reordered matrix. + assert( parentVoxel.size() == nrows_ ); + vector< unsigned int > numKids( nrows_, 0 ); + vector< unsigned int > lookupOldRowFromNew; + vector< bool > rowPending( nrows_, true ); + unsigned int numDone = 0; + for ( unsigned int i = 0; i < nrows_; ++i ) + { + if ( parentVoxel[i] != -1 ) + numKids[ parentVoxel[i] ]++; + } + while ( numDone < nrows_ ) + { + for ( unsigned int i = 0; i < nrows_; ++i ) + { + if ( rowPending[i] && numKids[i] == 0 ) + { + lookupOldRowFromNew.push_back( i ); + rowPending[i] = false; + numDone++; + unsigned int pa = parentVoxel[i]; + // Unsure what the root parent is. Assume it is -1 + while ( pa != -1 && numKids[pa] == 1 ) + { + assert( rowPending[pa] ); + rowPending[pa] = false; + numDone++; + lookupOldRowFromNew.push_back( pa ); + pa = parentVoxel[pa]; + } + if ( pa != -1 ) + { + assert( numKids[pa] > 0 ); + numKids[pa]--; + } + } + } + } + + cout << setprecision(4); + cout << "oldRowFromNew= {" ; + for ( int i = 0; i < nrows_; ++i ) + cout << lookupOldRowFromNew[i] << ", "; + cout << "}\n"; + // Then we fill in the reordered matrix. Note we need to reorder + // columns too. + shuffleRows( lookupOldRowFromNew ); + return true; } // Fill in the reordered matrix. Note we need to reorder columns too. void FastElim::shuffleRows( - const vector< unsigned int >& lookupOldRowFromNew ) + const vector< unsigned int >& lookupOldRowFromNew ) { - vector< unsigned int > lookupNewRowFromOld( nrows_ ); - for ( unsigned int i = 0; i < nrows_; ++i ) - lookupNewRowFromOld[ lookupOldRowFromNew[i] ] = i; - - FastElim temp = *this; - clear(); - setSize( temp.nrows_, temp.nrows_ ); - for ( unsigned int i = 0; i < lookupOldRowFromNew.size(); ++i ) { - vector< unsigned int > c; - vector< double > e; - unsigned int num = temp.getRow( lookupOldRowFromNew[i], e, c ); - vector< unsigned int > newc( num ); - vector< double > newe( num ); - for ( unsigned int j = 0; j < num; ++j ) { - newc[j] = lookupNewRowFromOld[ c[j] ]; - newe[j] = e[j]; - } - // Now we need to sort the new row entries in increasing col order. - /* - sortByColumn( newc, newe ); - addRow( i, newe, newc ); - */ - sortByColumn( newc, e ); - addRow( i, e, newc ); - } + vector< unsigned int > lookupNewRowFromOld( nrows_ ); + for ( unsigned int i = 0; i < nrows_; ++i ) + lookupNewRowFromOld[ lookupOldRowFromNew[i] ] = i; + + FastElim temp = *this; + clear(); + setSize( temp.nrows_, temp.nrows_ ); + for ( unsigned int i = 0; i < lookupOldRowFromNew.size(); ++i ) + { + vector< unsigned int > c; + vector< double > e; + unsigned int num = temp.getRow( lookupOldRowFromNew[i], e, c ); + vector< unsigned int > newc( num ); + vector< double > newe( num ); + for ( unsigned int j = 0; j < num; ++j ) + { + newc[j] = lookupNewRowFromOld[ c[j] ]; + newe[j] = e[j]; + } + // Now we need to sort the new row entries in increasing col order. + /* + sortByColumn( newc, newe ); + addRow( i, newe, newc ); + */ + sortByColumn( newc, e ); + addRow( i, e, newc ); + } } void sortByColumn( vector< unsigned int >& col, vector< double >& entry ) { - unsigned int num = col.size(); - assert( num == entry.size() ); - // Stupid bubble sort, as we only have up to 5 entries and need to - // sort both the col and reorder the entries by the same sequence. - for ( unsigned int i = 0; i < num; ++i ) { - for ( unsigned int j = 1; j < num; ++j ) { - if ( col[j] < col[j-1] ) { - unsigned int temp = col[j]; - col[j] = col[j-1]; - col[j-1] = temp; - double v = entry[j]; - entry[j] = entry[j-1]; - entry[j-1] = v; - } - } - } + unsigned int num = col.size(); + assert( num == entry.size() ); + // Stupid bubble sort, as we only have up to 5 entries and need to + // sort both the col and reorder the entries by the same sequence. + for ( unsigned int i = 0; i < num; ++i ) + { + for ( unsigned int j = 1; j < num; ++j ) + { + if ( col[j] < col[j-1] ) + { + unsigned int temp = col[j]; + col[j] = col[j-1]; + col[j-1] = temp; + double v = entry[j]; + entry[j] = entry[j-1]; + entry[j-1] = v; + } + } + } } /* @@ -254,20 +267,25 @@ void FastElim::rowElim( unsigned int row1, unsigned int row2, void FastElim::makeTestMatrix( const double* test, unsigned int numCompts ) { - setSize( numCompts, numCompts ); - vector< double > row( numCompts, ~0 ); - unsigned int i = 1; - for ( unsigned int i = 0; i < numCompts; ++i ) { - for ( unsigned int j = 0; j < numCompts; ++j ) { - unsigned int k = i * numCompts + j; - if ( test[k] < 0.1 ) { - } else { - N_.push_back( test[k] ); - colIndex_.push_back( j ); - } - } - rowStart_[i + 1] = N_.size(); - } + setSize( numCompts, numCompts ); + vector< double > row( numCompts, ~0 ); + unsigned int i = 1; + for ( unsigned int i = 0; i < numCompts; ++i ) + { + for ( unsigned int j = 0; j < numCompts; ++j ) + { + unsigned int k = i * numCompts + j; + if ( test[k] < 0.1 ) + { + } + else + { + N_.push_back( test[k] ); + colIndex_.push_back( j ); + } + } + rowStart_[i + 1] = N_.size(); + } } /* @@ -284,60 +302,73 @@ back-substitution. * rows, if any, on branches. */ void FastElim::buildForwardElim( vector< unsigned int >& diag, - vector< Triplet< double > >& fops ) + vector< Triplet< double > >& fops ) { - vector< vector< unsigned int > > rowsToElim( nrows_ ); - diag.clear(); - for ( unsigned int i = 0; i < nrows_; ++i ) { - unsigned int rs = rowStart_[i]; - unsigned int re = rowStart_[i+1]; - for ( unsigned int j = rs; j < re; ++j ) { - unsigned int k = colIndex_[j]; - if ( k == i ) { - diag.push_back(j); - } else if ( k > i ) { - rowsToElim[ i ].push_back( k ); - } - } - } - for ( unsigned int i = 0; i < nrows_; ++i ) { - double d = N_[diag[i]]; - unsigned int diagend = rowStart_[ i + 1 ]; - assert( diag[i] < diagend ); - vector< unsigned int >& elim = rowsToElim[i]; - for ( unsigned int j = 0; j < elim.size(); ++j ) { - unsigned int erow = elim[j]; - if ( erow == i ) continue; - unsigned int rs = rowStart_[ erow ]; - unsigned int re = rowStart_[ erow+1 ]; - // assert( colIndex_[rs] == i ); - double ratio = get( erow, i ) / d; - // double ratio = N_[rs]/N_[diag[i]]; - for ( unsigned int k = diag[i]+1; k < diagend; ++k ) { - unsigned int col = colIndex_[k]; - // findElimEntry, subtract it out. - for ( unsigned int q = rs; q < re; ++q ) { - if ( colIndex_[q] == col ) { - N_[q] -= N_[k] * ratio; - } - } - } - fops.push_back( Triplet< double >( ratio, i, erow) ); - } - } - for ( unsigned int i = 0; i < rowsToElim.size(); ++i ) { - cout << i << " : "; - for ( unsigned int j = 0; j < rowsToElim[i].size(); ++j ) { - cout << rowsToElim[i][j] << " "; - } - cout << endl; - } - for ( unsigned int i = 0; i < fops.size(); ++i ) { - cout << "fops[" << i << "]= " << fops[i].b_ << " " << fops[i].c_ << - " " << fops[i].a_ << endl; - } - /* - */ + vector< vector< unsigned int > > rowsToElim( nrows_ ); + diag.clear(); + for ( unsigned int i = 0; i < nrows_; ++i ) + { + unsigned int rs = rowStart_[i]; + unsigned int re = rowStart_[i+1]; + for ( unsigned int j = rs; j < re; ++j ) + { + unsigned int k = colIndex_[j]; + if ( k == i ) + { + diag.push_back(j); + } + else if ( k > i ) + { + rowsToElim[ i ].push_back( k ); + } + } + } + for ( unsigned int i = 0; i < nrows_; ++i ) + { + double d = N_[diag[i]]; + unsigned int diagend = rowStart_[ i + 1 ]; + assert( diag[i] < diagend ); + vector< unsigned int >& elim = rowsToElim[i]; + for ( unsigned int j = 0; j < elim.size(); ++j ) + { + unsigned int erow = elim[j]; + if ( erow == i ) continue; + unsigned int rs = rowStart_[ erow ]; + unsigned int re = rowStart_[ erow+1 ]; + // assert( colIndex_[rs] == i ); + double ratio = get( erow, i ) / d; + // double ratio = N_[rs]/N_[diag[i]]; + for ( unsigned int k = diag[i]+1; k < diagend; ++k ) + { + unsigned int col = colIndex_[k]; + // findElimEntry, subtract it out. + for ( unsigned int q = rs; q < re; ++q ) + { + if ( colIndex_[q] == col ) + { + N_[q] -= N_[k] * ratio; + } + } + } + fops.push_back( Triplet< double >( ratio, i, erow) ); + } + } + for ( unsigned int i = 0; i < rowsToElim.size(); ++i ) + { + cout << i << " : "; + for ( unsigned int j = 0; j < rowsToElim[i].size(); ++j ) + { + cout << rowsToElim[i][j] << " "; + } + cout << endl; + } + for ( unsigned int i = 0; i < fops.size(); ++i ) + { + cout << "fops[" << i << "]= " << fops[i].b_ << " " << fops[i].c_ << + " " << fops[i].a_ << endl; + } + /* + */ } /** @@ -350,307 +381,320 @@ void FastElim::buildForwardElim( vector< unsigned int >& diag, * RHS[row] = ( RHS[row] - offDiagVal * RHS[col] ) / diagVal */ void FastElim::buildBackwardSub( vector< unsigned int >& diag, - vector< Triplet< double > >& bops, vector< double >& diagVal ) + vector< Triplet< double > >& bops, vector< double >& diagVal ) { - // This vec tells the routine which rows below have to be back-subbed. - // This includes the rows if any in the tridiagonal band and also - // rows, if any, on branches. - vector< vector< unsigned int > > rowsToSub( nrows_ ); - - for ( unsigned int i = 0; i < nrows_; ++i ) { - unsigned int d = diag[i] + 1; - unsigned int re = rowStart_[i+1]; - for ( unsigned int j = d; j < re; ++j ) { - unsigned int k = colIndex_[j]; - // At this point the row to sub is at (i, k). We need to go down - // to the (k,k) diagonal to sub it out. - rowsToSub[ k ].push_back( i ); - } - } - for ( unsigned int i = 0; i < rowsToSub.size(); ++i ) { - cout << i << " : "; - for ( unsigned int j = 0; j < rowsToSub[i].size(); ++j ) { - cout << rowsToSub[i][j] << " "; - } - cout << endl; - } - - diagVal.resize( 0 ); - // Fill in the diagonal terms. Here we do all entries. - for ( unsigned int i = 0; i != nrows_ ; ++i ) { - diagVal.push_back( 1.0 / N_[diag[i]] ); - } - - // Fill in the back-sub operations. Note we don't need to check zero. - for ( unsigned int i = nrows_-1; i != 0 ; --i ) { - for ( unsigned int j = rowsToSub[i].size() - 1; j != -1; --j ) { - unsigned int k = rowsToSub[i][j]; - double val = get( k, i ); //k is the row to go, i is the diag. - bops.push_back( Triplet< double >( val * diagVal[i], i, k ) ); - } - } - - for ( unsigned int i = 0; i < bops.size(); ++i ) { - cout << i << ": " << bops[i].a_ << " " << - bops[i].b_ << " " << // diagonal index - bops[i].c_ << " " << // off-diagonal index - 1.0 / diagVal[bops[i].b_] << // diagonal value. - endl; - } + // This vec tells the routine which rows below have to be back-subbed. + // This includes the rows if any in the tridiagonal band and also + // rows, if any, on branches. + vector< vector< unsigned int > > rowsToSub( nrows_ ); + + for ( unsigned int i = 0; i < nrows_; ++i ) + { + unsigned int d = diag[i] + 1; + unsigned int re = rowStart_[i+1]; + for ( unsigned int j = d; j < re; ++j ) + { + unsigned int k = colIndex_[j]; + // At this point the row to sub is at (i, k). We need to go down + // to the (k,k) diagonal to sub it out. + rowsToSub[ k ].push_back( i ); + } + } + for ( unsigned int i = 0; i < rowsToSub.size(); ++i ) + { + cout << i << " : "; + for ( unsigned int j = 0; j < rowsToSub[i].size(); ++j ) + { + cout << rowsToSub[i][j] << " "; + } + cout << endl; + } + + diagVal.resize( 0 ); + // Fill in the diagonal terms. Here we do all entries. + for ( unsigned int i = 0; i != nrows_ ; ++i ) + { + diagVal.push_back( 1.0 / N_[diag[i]] ); + } + + // Fill in the back-sub operations. Note we don't need to check zero. + for ( unsigned int i = nrows_-1; i != 0 ; --i ) + { + for ( unsigned int j = rowsToSub[i].size() - 1; j != -1; --j ) + { + unsigned int k = rowsToSub[i][j]; + double val = get( k, i ); //k is the row to go, i is the diag. + bops.push_back( Triplet< double >( val * diagVal[i], i, k ) ); + } + } + + for ( unsigned int i = 0; i < bops.size(); ++i ) + { + cout << i << ": " << bops[i].a_ << " " << + bops[i].b_ << " " << // diagonal index + bops[i].c_ << " " << // off-diagonal index + 1.0 / diagVal[bops[i].b_] << // diagonal value. + endl; + } } void advance( vector< double >& y, - const vector< Triplet< double > >& ops, // has both fops and bops. - const vector< double >& diagVal ) + const vector< Triplet< double > >& ops, // has both fops and bops. + const vector< double >& diagVal ) { - for ( vector< Triplet< double > >::const_iterator - i = ops.begin(); i != ops.end(); ++i ) - y[i->c_] -= y[i->b_] * i->a_; - - assert( y.size() == diagVal.size() ); - vector< double >::iterator iy = y.begin(); - for ( vector< double >::const_iterator - i = diagVal.begin(); i != diagVal.end(); ++i ) - *iy++ *= *i; + for ( vector< Triplet< double > >::const_iterator + i = ops.begin(); i != ops.end(); ++i ) + y[i->c_] -= y[i->b_] * i->a_; + + assert( y.size() == diagVal.size() ); + vector< double >::iterator iy = y.begin(); + for ( vector< double >::const_iterator + i = diagVal.begin(); i != diagVal.end(); ++i ) + *iy++ *= *i; } double checkAns( - const double* m, unsigned int numCompts, - const double* ans, const double* rhs ) + const double* m, unsigned int numCompts, + const double* ans, const double* rhs ) { - vector< double > check( numCompts, 0.0 ); - for ( unsigned int i = 0; i < numCompts; ++i ) { - for ( unsigned int j = 0; j < numCompts; ++j ) - check[i] += m[i*numCompts + j] * ans[j]; - } - double ret = 0.0; - for ( unsigned int i = 0; i < numCompts; ++i ) - ret += (check[i] - rhs[i]) * (check[i] - rhs[i] ); - return ret; + vector< double > check( numCompts, 0.0 ); + for ( unsigned int i = 0; i < numCompts; ++i ) + { + for ( unsigned int j = 0; j < numCompts; ++j ) + check[i] += m[i*numCompts + j] * ans[j]; + } + double ret = 0.0; + for ( unsigned int i = 0; i < numCompts; ++i ) + ret += (check[i] - rhs[i]) * (check[i] - rhs[i] ); + return ret; } -main() +int main() { -/* -2 11 - 1 4 - 3 10 - 9 5 - 6 - 7 - 8 - - 1 2 3 4 5 6 7 8 9 10 11 -1 x x x x -2 x x -3 x x x x -4 x x x x -5 x x x x -6 x x x x -7 x x x -8 x x -9 x x x x -10 x x -11 x x - static double test[] = { - 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, - 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 7, 0, 8, 9, 0, 0, 0, 0, 10, 0, 0, - 11, 0, 12, 13, 0, 0, 0, 0, 0, 0, 14, - 0, 0, 0, 0, 15, 16, 0, 0, 17, 18, 0, - 0, 0, 0, 0, 19, 20, 21, 0, 22, 0, 0, - 0, 0, 0, 0, 0, 23, 24, 25, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 26, 27, 0, 0, 0, - 0, 0, 28, 0, 29, 30, 0, 0, 31, 0, 0, - 0, 0, 0, 0, 32, 0, 0, 0, 0, 33, 0, - 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 35, - }; - const unsigned int numCompts = 11; -// static unsigned int parents[] = { 3,1,9,3,6,7,8,-1,6,5,4 }; - static unsigned int parents[] = { 2,0,8,2,5,6,7,-1,5,4,3 }; -*/ - -/* -1 3 - 2 4 - 7 5 - 8 6 - 9 - 10 - 11 - - 1 2 3 4 5 6 7 8 9 10 11 -1 x x -2 x x x -3 x x -4 x x x -5 x x -6 x x x -7 x x x x -8 x x x -9 x x x x -10 x x x -11 x x - static double test[] = { - 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3, 4, 0, 0, 0, 0, 5, 0, 0, 0, 0, - 0, 0, 6, 7, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 8, 9, 0, 0, 10, 0, 0, 0, 0, - 0, 0, 0, 0, 11, 12, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 13, 14, 0, 0, 15, 0, 0, - 0, 16, 0, 17, 0, 0, 18, 19, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 20, 21, 22, 0, 0, - 0, 0, 0, 0, 0, 23, 0, 24, 25, 26, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 27, 28, 29, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, - }; - const unsigned int numCompts = 11; - static unsigned int parents[] = { 1,6,3,6,5,8,7,8,9,10,-1}; -*/ - -/* -Linear cable, 12 segments. -*/ - - static double test[] = { - 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 10, 11, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 12, 13, 14, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 15, 16, 17, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 18, 19, 20, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 21, 22, 23, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 24, 25, 26, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 27, 28, 29, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 32, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 34, - }; - const unsigned int numCompts = 12; - static unsigned int parents[] = { 1,2,3,4,5,6,7,8,9,10,11,-1}; - - /* - static double test[] = { - 1, 2, - 3, 4 - }; - const unsigned int numCompts = 2; - static double test[] = { - 1, 2, 0, 0, - 3, 4, 5, 0, - 0, 6, 7, 8, - 0, 0, 9, 10 - }; - const unsigned int numCompts = 4; - static double test[] = { - 1, 2, 0, 0, 0, 0, - 3, 4, 5, 0, 0, 0, - 0, 6, 7, 8, 0, 0, - 0, 0, 9, 10, 11, 0, - 0, 0, 0, 12, 13, 14, - 0, 0, 0, 0, 15, 16, - }; - const unsigned int numCompts = 6; - static double test[] = { - 1, 2, 0, 0, 0, 0, - 3, 4, 0, 0, 1, 0, - 0, 0, 7, 8, 0, 0, - 0, 0, 9, 10, 11, 0, - 0, 1, 0, 12, 13, 14, - 0, 0, 0, 0, 15, 16, - }; - const unsigned int numCompts = 6; - */ - // testSorting(); // seems to work fine. - FastElim fe; - vector< Triplet< double > > fops; - vector< Unroll > bops; - fe.makeTestMatrix( test, numCompts ); - fe.print(); - cout << endl << endl; - vector< unsigned int > parentVoxel; - parentVoxel.insert( parentVoxel.begin(), &parents[0], &parents[numCompts] ); - fe.hinesReorder( parentVoxel ); - /* - */ - /* - vector< unsigned int > shuf; - for ( unsigned int i = 0; i < numCompts; ++i ) - shuf.push_back( i ); - shuf[0] = 1; - shuf[1] = 0; - fe.shuffleRows( shuf ); - */ - fe.print(); - cout << endl << endl; - FastElim foo = fe; - - vector< unsigned int > diag; - vector< double > diagVal; - fe.buildForwardElim( diag, fops ); - fe.print(); - fe.buildBackwardSub( diag, fops, diagVal ); - vector< double > y( numCompts, 1.0 ); - vector< double > ones( numCompts, 1.0 ); - advance( y, fops, diagVal ); - for ( int i = 0; i < numCompts; ++i ) - cout << "y" << i << "]= " << y[i] << endl; - - // Here we verify the answer - - vector< double > alle; - for( unsigned int i = 0; i < numCompts; ++i ) { - for( unsigned int j = 0; j < numCompts; ++j ) { - alle.push_back( foo.get( i, j ) ); - } - } - cout << "myCode: " << - checkAns( &alle[0], numCompts, &y[0], &ones[0] ) << endl; - - - - ///////////////////////////////////////////////////////////////////// - // Here we do the gsl test. - vector< double > temp( &test[0], &test[numCompts*numCompts] ); - gsl_matrix_view m = gsl_matrix_view_array( &temp[0], numCompts, numCompts ); - - vector< double > z( numCompts, 1.0 ); - gsl_vector_view b = gsl_vector_view_array( &z[0], numCompts ); - gsl_vector* x = gsl_vector_alloc( numCompts ); - int s; - gsl_permutation* p = gsl_permutation_alloc( numCompts ); - gsl_linalg_LU_decomp( &m.matrix, p, &s ); - gsl_linalg_LU_solve( &m.matrix, p, &b.vector, x); - vector< double > gslAns( numCompts ); - for ( int i = 0; i < numCompts; ++i ) { - gslAns[i] = gsl_vector_get( x, i ); - cout << "x[" << i << "]= " << gslAns[i] << endl; - } - /* - */ - cout << "GSL: " << checkAns( test, numCompts, &gslAns[0], &ones[0] ) << endl; - gsl_vector_free( x ); - - + /* + 2 11 + 1 4 + 3 10 + 9 5 + 6 + 7 + 8 + + 1 2 3 4 5 6 7 8 9 10 11 + 1 x x x x + 2 x x + 3 x x x x + 4 x x x x + 5 x x x x + 6 x x x x + 7 x x x + 8 x x + 9 x x x x + 10 x x + 11 x x + static double test[] = { + 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, + 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 8, 9, 0, 0, 0, 0, 10, 0, 0, + 11, 0, 12, 13, 0, 0, 0, 0, 0, 0, 14, + 0, 0, 0, 0, 15, 16, 0, 0, 17, 18, 0, + 0, 0, 0, 0, 19, 20, 21, 0, 22, 0, 0, + 0, 0, 0, 0, 0, 23, 24, 25, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 26, 27, 0, 0, 0, + 0, 0, 28, 0, 29, 30, 0, 0, 31, 0, 0, + 0, 0, 0, 0, 32, 0, 0, 0, 0, 33, 0, + 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 35, + }; + const unsigned int numCompts = 11; + // static unsigned int parents[] = { 3,1,9,3,6,7,8,-1,6,5,4 }; + static unsigned int parents[] = { 2,0,8,2,5,6,7,-1,5,4,3 }; + */ + + /* + 1 3 + 2 4 + 7 5 + 8 6 + 9 + 10 + 11 + + 1 2 3 4 5 6 7 8 9 10 11 + 1 x x + 2 x x x + 3 x x + 4 x x x + 5 x x + 6 x x x + 7 x x x x + 8 x x x + 9 x x x x + 10 x x x + 11 x x + static double test[] = { + 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 4, 0, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 6, 7, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 8, 9, 0, 0, 10, 0, 0, 0, 0, + 0, 0, 0, 0, 11, 12, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 13, 14, 0, 0, 15, 0, 0, + 0, 16, 0, 17, 0, 0, 18, 19, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 20, 21, 22, 0, 0, + 0, 0, 0, 0, 0, 23, 0, 24, 25, 26, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 27, 28, 29, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, + }; + const unsigned int numCompts = 11; + static unsigned int parents[] = { 1,6,3,6,5,8,7,8,9,10,-1}; + */ + + /* + Linear cable, 12 segments. + */ + + static double test[] = + { + 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 10, 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 12, 13, 14, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 15, 16, 17, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 18, 19, 20, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 21, 22, 23, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 24, 25, 26, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 27, 28, 29, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 34, + }; + const unsigned int numCompts = 12; + static int parents[] = { 1,2,3,4,5,6,7,8,9,10,11,-1}; + + /* + static double test[] = { + 1, 2, + 3, 4 + }; + const unsigned int numCompts = 2; + static double test[] = { + 1, 2, 0, 0, + 3, 4, 5, 0, + 0, 6, 7, 8, + 0, 0, 9, 10 + }; + const unsigned int numCompts = 4; + static double test[] = { + 1, 2, 0, 0, 0, 0, + 3, 4, 5, 0, 0, 0, + 0, 6, 7, 8, 0, 0, + 0, 0, 9, 10, 11, 0, + 0, 0, 0, 12, 13, 14, + 0, 0, 0, 0, 15, 16, + }; + const unsigned int numCompts = 6; + static double test[] = { + 1, 2, 0, 0, 0, 0, + 3, 4, 0, 0, 1, 0, + 0, 0, 7, 8, 0, 0, + 0, 0, 9, 10, 11, 0, + 0, 1, 0, 12, 13, 14, + 0, 0, 0, 0, 15, 16, + }; + const unsigned int numCompts = 6; + */ + // testSorting(); // seems to work fine. + FastElim fe; + vector< Triplet< double > > fops; + vector< Unroll > bops; + fe.makeTestMatrix( test, numCompts ); + fe.print(); + cout << endl << endl; + vector< unsigned int > parentVoxel; + parentVoxel.insert( parentVoxel.begin(), &parents[0], &parents[numCompts] ); + fe.hinesReorder( parentVoxel ); + /* + */ + /* + vector< unsigned int > shuf; + for ( unsigned int i = 0; i < numCompts; ++i ) + shuf.push_back( i ); + shuf[0] = 1; + shuf[1] = 0; + fe.shuffleRows( shuf ); + */ + fe.print(); + cout << endl << endl; + FastElim foo = fe; + + vector< unsigned int > diag; + vector< double > diagVal; + fe.buildForwardElim( diag, fops ); + fe.print(); + fe.buildBackwardSub( diag, fops, diagVal ); + vector< double > y( numCompts, 1.0 ); + vector< double > ones( numCompts, 1.0 ); + advance( y, fops, diagVal ); + for ( int i = 0; i < numCompts; ++i ) + cout << "y" << i << "]= " << y[i] << endl; + + // Here we verify the answer + + vector< double > alle; + for( unsigned int i = 0; i < numCompts; ++i ) + { + for( unsigned int j = 0; j < numCompts; ++j ) + { + alle.push_back( foo.get( i, j ) ); + } + } + cout << "myCode: " << + checkAns( &alle[0], numCompts, &y[0], &ones[0] ) << endl; + + + + ///////////////////////////////////////////////////////////////////// + // Here we do the gsl test. + vector< double > temp( &test[0], &test[numCompts*numCompts] ); + gsl_matrix_view m = gsl_matrix_view_array( &temp[0], numCompts, numCompts ); + + vector< double > z( numCompts, 1.0 ); + gsl_vector_view b = gsl_vector_view_array( &z[0], numCompts ); + gsl_vector* x = gsl_vector_alloc( numCompts ); + int s; + gsl_permutation* p = gsl_permutation_alloc( numCompts ); + gsl_linalg_LU_decomp( &m.matrix, p, &s ); + gsl_linalg_LU_solve( &m.matrix, p, &b.vector, x); + vector< double > gslAns( numCompts ); + for ( int i = 0; i < numCompts; ++i ) + { + gslAns[i] = gsl_vector_get( x, i ); + cout << "x[" << i << "]= " << gslAns[i] << endl; + } + /* + */ + cout << "GSL: " << checkAns( test, numCompts, &gslAns[0], &ones[0] ) << endl; + gsl_vector_free( x ); + return 0; } void testSorting() { - static unsigned int k[] = {20,40,60,80,100,10,30,50,70,90}; - static double d[] = {1,2,3,4,5,6,7,8,9,10}; - vector< unsigned int > col; - col.insert( col.begin(), k, k+10); - vector< double > entry; - entry.insert( entry.begin(), d, d+10); - sortByColumn( col, entry ); - cout << "testing sorting\n"; - for ( int i = 0; i < col.size(); ++i ) { - cout << "d[" << i << "]= " << k[i] << - ", col[" << i << "]= " << col[i] << ", e=" << entry[i] << endl; - } - cout << endl; + static unsigned int k[] = {20,40,60,80,100,10,30,50,70,90}; + static double d[] = {1,2,3,4,5,6,7,8,9,10}; + vector< unsigned int > col; + col.insert( col.begin(), k, k+10); + vector< double > entry; + entry.insert( entry.begin(), d, d+10); + sortByColumn( col, entry ); + cout << "testing sorting\n"; + for ( int i = 0; i < col.size(); ++i ) + { + cout << "d[" << i << "]= " << k[i] << + ", col[" << i << "]= " << col[i] << ", e=" << entry[i] << endl; + } + cout << endl; } diff --git a/diffusion/testDiffusion.cpp b/diffusion/testDiffusion.cpp index f887cff1..b4ad4170 100644 --- a/diffusion/testDiffusion.cpp +++ b/diffusion/testDiffusion.cpp @@ -19,7 +19,7 @@ using namespace std; #ifdef USE_GSL #include <gsl/gsl_linalg.h> #endif -#include "header.h" +#include "../basecode/header.h" #include "../basecode/SparseMatrix.h" #include "FastMatrixElim.h" #include "../shell/Shell.h" diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index b1b3231f..d3a64a16 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 2.6) -include_directories(../basecode) +cmake_minimum_required(VERSION 2.8) +include( ${CMAKE_CURRENT_SOURCE_DIR}/../CheckCXXCompiler.cmake) ADD_LIBRARY(examples Example.cpp Ex.cpp diff --git a/examples/Ex.cpp b/examples/Ex.cpp index 761bb4f7..2554e468 100644 --- a/examples/Ex.cpp +++ b/examples/Ex.cpp @@ -1,6 +1,6 @@ -#include "header.h" -#include "ElementValueFinfo.h" -#include "LookupElementValueFinfo.h" +#include "../basecode/header.h" +#include "../basecode/ElementValueFinfo.h" +#include "../basecode/LookupElementValueFinfo.h" #include "Ex.h" Ex::Ex() diff --git a/examples/Example.cpp b/examples/Example.cpp index 9f9609f8..5f083b28 100644 --- a/examples/Example.cpp +++ b/examples/Example.cpp @@ -1,8 +1,7 @@ -#include "header.h" +#include "../basecode/header.h" #include "Example.h" -#include "ElementValueFinfo.h" -#include "LookupElementValueFinfo.h" -#include <stdio.h> +#include "../basecode/ElementValueFinfo.h" +#include "../basecode/LookupElementValueFinfo.h" static SrcFinfo1< double > *output() { static SrcFinfo1< double > output( @@ -90,9 +89,9 @@ const Cinfo* Example::initCinfo(){ static const Cinfo* exampleCinfo = Example::initCinfo(); Example::Example() - : - output_( 0.0 ), - x_( 0.0 ), y_( 0.0 ) + : x_( 0.0 ) + , y_( 0.0 ) + , output_( 0.0 ) { ; } diff --git a/examples/Example.h b/examples/Example.h index e643506d..1d3ff683 100644 --- a/examples/Example.h +++ b/examples/Example.h @@ -1,3 +1,5 @@ +#ifndef EXAMPLE_H +#endif /* end of include guard: EXAMPLE_H */ class Example { private: @@ -25,3 +27,5 @@ class Example { static const Cinfo* initCinfo(); }; + +#define EXAMPLE_H diff --git a/external/muparser/include/muParser.h b/external/muparser/include/muParser.h index a4a678e2..653cd44a 100644 --- a/external/muparser/include/muParser.h +++ b/external/muparser/include/muParser.h @@ -33,7 +33,7 @@ #include "muParserTemplateMagic.h" // Get the random number generator type from here. -#include "randnum/RNG.h" +#include "../../../randnum/RNG.h" extern moose::RNG<double> rng; diff --git a/external/muparser/src/muParser.cpp b/external/muparser/src/muParser.cpp index 4d89e6f7..65a1f314 100644 --- a/external/muparser/src/muParser.cpp +++ b/external/muparser/src/muParser.cpp @@ -23,8 +23,8 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "muParser.h" -#include "muParserTemplateMagic.h" +#include "../include/muParser.h" +#include "../include/muParserTemplateMagic.h" //--- Standard includes ------------------------------------------------------------------------ #include <cmath> diff --git a/external/tinyxml/CMakeLists.txt b/external/tinyxml/CMakeLists.txt deleted file mode 100644 index 56699253..00000000 --- a/external/tinyxml/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -cmake_minimum_required(VERSION 2.6) -add_library(tinyxml tinyxml2.cpp) diff --git a/external/tinyxml/tinyxml2.cpp b/external/tinyxml/tinyxml2.cpp deleted file mode 100644 index df52a91a..00000000 --- a/external/tinyxml/tinyxml2.cpp +++ /dev/null @@ -1,2186 +0,0 @@ -/* -Original code by Lee Thomason (www.grinninglizard.com) - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - -#include "tinyxml2.h" - -#include <new> // yes, this one new style header, is in the Android SDK. -# ifdef ANDROID_NDK -# include <stddef.h> -#else -# include <cstddef> -#endif - -static const char LINE_FEED = (char)0x0a; // all line endings are normalized to LF -static const char LF = LINE_FEED; -static const char CARRIAGE_RETURN = (char)0x0d; // CR gets filtered out -static const char CR = CARRIAGE_RETURN; -static const char SINGLE_QUOTE = '\''; -static const char DOUBLE_QUOTE = '\"'; - -// Bunch of unicode info at: -// http://www.unicode.org/faq/utf_bom.html -// ef bb bf (Microsoft "lead bytes") - designates UTF-8 - -static const unsigned char TIXML_UTF_LEAD_0 = 0xefU; -static const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; -static const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; - - -#define DELETE_NODE( node ) { \ - if ( node ) { \ - MemPool* pool = node->_memPool; \ - node->~XMLNode(); \ - pool->Free( node ); \ - } \ - } -#define DELETE_ATTRIBUTE( attrib ) { \ - if ( attrib ) { \ - MemPool* pool = attrib->_memPool; \ - attrib->~XMLAttribute(); \ - pool->Free( attrib ); \ - } \ - } - -namespace tinyxml2 -{ - -struct Entity { - const char* pattern; - int length; - char value; -}; - -static const int NUM_ENTITIES = 5; -static const Entity entities[NUM_ENTITIES] = { - { "quot", 4, DOUBLE_QUOTE }, - { "amp", 3, '&' }, - { "apos", 4, SINGLE_QUOTE }, - { "lt", 2, '<' }, - { "gt", 2, '>' } -}; - - -StrPair::~StrPair() -{ - Reset(); -} - - -void StrPair::Reset() -{ - if ( _flags & NEEDS_DELETE ) { - delete [] _start; - } - _flags = 0; - _start = 0; - _end = 0; -} - - -void StrPair::SetStr( const char* str, int flags ) -{ - Reset(); - size_t len = strlen( str ); - _start = new char[ len+1 ]; - memcpy( _start, str, len+1 ); - _end = _start + len; - _flags = flags | NEEDS_DELETE; -} - - -char* StrPair::ParseText( char* p, const char* endTag, int strFlags ) -{ - TIXMLASSERT( endTag && *endTag ); - - char* start = p; // fixme: hides a member - char endChar = *endTag; - size_t length = strlen( endTag ); - - // Inner loop of text parsing. - while ( *p ) { - if ( *p == endChar && strncmp( p, endTag, length ) == 0 ) { - Set( start, p, strFlags ); - return p + length; - } - ++p; - } - return 0; -} - - -char* StrPair::ParseName( char* p ) -{ - char* start = p; - - if ( !start || !(*start) ) { - return 0; - } - - while( *p && ( p == start ? XMLUtil::IsNameStartChar( *p ) : XMLUtil::IsNameChar( *p ) )) { - ++p; - } - - if ( p > start ) { - Set( start, p, 0 ); - return p; - } - return 0; -} - - -void StrPair::CollapseWhitespace() -{ - // Trim leading space. - _start = XMLUtil::SkipWhiteSpace( _start ); - - if ( _start && *_start ) { - char* p = _start; // the read pointer - char* q = _start; // the write pointer - - while( *p ) { - if ( XMLUtil::IsWhiteSpace( *p )) { - p = XMLUtil::SkipWhiteSpace( p ); - if ( *p == 0 ) { - break; // don't write to q; this trims the trailing space. - } - *q = ' '; - ++q; - } - *q = *p; - ++q; - ++p; - } - *q = 0; - } -} - - -const char* StrPair::GetStr() -{ - if ( _flags & NEEDS_FLUSH ) { - *_end = 0; - _flags ^= NEEDS_FLUSH; - - if ( _flags ) { - char* p = _start; // the read pointer - char* q = _start; // the write pointer - - while( p < _end ) { - if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == CR ) { - // CR-LF pair becomes LF - // CR alone becomes LF - // LF-CR becomes LF - if ( *(p+1) == LF ) { - p += 2; - } - else { - ++p; - } - *q++ = LF; - } - else if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == LF ) { - if ( *(p+1) == CR ) { - p += 2; - } - else { - ++p; - } - *q++ = LF; - } - else if ( (_flags & NEEDS_ENTITY_PROCESSING) && *p == '&' ) { - // Entities handled by tinyXML2: - // - special entities in the entity table [in/out] - // - numeric character reference [in] - // 中 or 中 - - if ( *(p+1) == '#' ) { - char buf[10] = { 0 }; - int len; - p = const_cast<char*>( XMLUtil::GetCharacterRef( p, buf, &len ) ); - for( int i=0; i<len; ++i ) { - *q++ = buf[i]; - } - TIXMLASSERT( q <= p ); - } - else { - int i=0; - for(; i<NUM_ENTITIES; ++i ) { - if ( strncmp( p+1, entities[i].pattern, entities[i].length ) == 0 - && *(p+entities[i].length+1) == ';' ) { - // Found an entity convert; - *q = entities[i].value; - ++q; - p += entities[i].length + 2; - break; - } - } - if ( i == NUM_ENTITIES ) { - // fixme: treat as error? - ++p; - ++q; - } - } - } - else { - *q = *p; - ++p; - ++q; - } - } - *q = 0; - } - // The loop below has plenty going on, and this - // is a less useful mode. Break it out. - if ( _flags & COLLAPSE_WHITESPACE ) { - CollapseWhitespace(); - } - _flags = (_flags & NEEDS_DELETE); - } - return _start; -} - - - - -// --------- XMLUtil ----------- // - -const char* XMLUtil::ReadBOM( const char* p, bool* bom ) -{ - *bom = false; - const unsigned char* pu = reinterpret_cast<const unsigned char*>(p); - // Check for BOM: - if ( *(pu+0) == TIXML_UTF_LEAD_0 - && *(pu+1) == TIXML_UTF_LEAD_1 - && *(pu+2) == TIXML_UTF_LEAD_2 ) { - *bom = true; - p += 3; - } - return p; -} - - -void XMLUtil::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) -{ - const unsigned long BYTE_MASK = 0xBF; - const unsigned long BYTE_MARK = 0x80; - const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - - if (input < 0x80) { - *length = 1; - } - else if ( input < 0x800 ) { - *length = 2; - } - else if ( input < 0x10000 ) { - *length = 3; - } - else if ( input < 0x200000 ) { - *length = 4; - } - else { - *length = 0; // This code won't covert this correctly anyway. - return; - } - - output += *length; - - // Scary scary fall throughs. - switch (*length) { - case 4: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - case 3: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - case 2: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - case 1: - --output; - *output = (char)(input | FIRST_BYTE_MARK[*length]); - default: - break; - } -} - - -const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length ) -{ - // Presume an entity, and pull it out. - *length = 0; - - if ( *(p+1) == '#' && *(p+2) ) { - unsigned long ucs = 0; - ptrdiff_t delta = 0; - unsigned mult = 1; - - if ( *(p+2) == 'x' ) { - // Hexadecimal. - if ( !*(p+3) ) { - return 0; - } - - const char* q = p+3; - q = strchr( q, ';' ); - - if ( !q || !*q ) { - return 0; - } - - delta = q-p; - --q; - - while ( *q != 'x' ) { - if ( *q >= '0' && *q <= '9' ) { - ucs += mult * (*q - '0'); - } - else if ( *q >= 'a' && *q <= 'f' ) { - ucs += mult * (*q - 'a' + 10); - } - else if ( *q >= 'A' && *q <= 'F' ) { - ucs += mult * (*q - 'A' + 10 ); - } - else { - return 0; - } - mult *= 16; - --q; - } - } - else { - // Decimal. - if ( !*(p+2) ) { - return 0; - } - - const char* q = p+2; - q = strchr( q, ';' ); - - if ( !q || !*q ) { - return 0; - } - - delta = q-p; - --q; - - while ( *q != '#' ) { - if ( *q >= '0' && *q <= '9' ) { - ucs += mult * (*q - '0'); - } - else { - return 0; - } - mult *= 10; - --q; - } - } - // convert the UCS to UTF-8 - ConvertUTF32ToUTF8( ucs, value, length ); - return p + delta + 1; - } - return p+1; -} - - -void XMLUtil::ToStr( int v, char* buffer, int bufferSize ) -{ - TIXML_SNPRINTF( buffer, bufferSize, "%d", v ); -} - - -void XMLUtil::ToStr( unsigned v, char* buffer, int bufferSize ) -{ - TIXML_SNPRINTF( buffer, bufferSize, "%u", v ); -} - - -void XMLUtil::ToStr( bool v, char* buffer, int bufferSize ) -{ - TIXML_SNPRINTF( buffer, bufferSize, "%d", v ? 1 : 0 ); -} - -/* - ToStr() of a number is a very tricky topic. - https://github.com/leethomason/tinyxml2/issues/106 -*/ -void XMLUtil::ToStr( float v, char* buffer, int bufferSize ) -{ - TIXML_SNPRINTF( buffer, bufferSize, "%.8g", v ); -} - - -void XMLUtil::ToStr( double v, char* buffer, int bufferSize ) -{ - TIXML_SNPRINTF( buffer, bufferSize, "%.17g", v ); -} - - -bool XMLUtil::ToInt( const char* str, int* value ) -{ - if ( TIXML_SSCANF( str, "%d", value ) == 1 ) { - return true; - } - return false; -} - -bool XMLUtil::ToUnsigned( const char* str, unsigned *value ) -{ - if ( TIXML_SSCANF( str, "%u", value ) == 1 ) { - return true; - } - return false; -} - -bool XMLUtil::ToBool( const char* str, bool* value ) -{ - int ival = 0; - if ( ToInt( str, &ival )) { - *value = (ival==0) ? false : true; - return true; - } - if ( StringEqual( str, "true" ) ) { - *value = true; - return true; - } - else if ( StringEqual( str, "false" ) ) { - *value = false; - return true; - } - return false; -} - - -bool XMLUtil::ToFloat( const char* str, float* value ) -{ - if ( TIXML_SSCANF( str, "%f", value ) == 1 ) { - return true; - } - return false; -} - -bool XMLUtil::ToDouble( const char* str, double* value ) -{ - if ( TIXML_SSCANF( str, "%lf", value ) == 1 ) { - return true; - } - return false; -} - - -char* XMLDocument::Identify( char* p, XMLNode** node ) -{ - XMLNode* returnNode = 0; - char* start = p; - p = XMLUtil::SkipWhiteSpace( p ); - if( !p || !*p ) { - return p; - } - - // What is this thing? - // These strings define the matching patters: - static const char* xmlHeader = { "<?" }; - static const char* commentHeader = { "<!--" }; - static const char* dtdHeader = { "<!" }; - static const char* cdataHeader = { "<![CDATA[" }; - static const char* elementHeader = { "<" }; // and a header for everything else; check last. - - static const int xmlHeaderLen = 2; - static const int commentHeaderLen = 4; - static const int dtdHeaderLen = 2; - static const int cdataHeaderLen = 9; - static const int elementHeaderLen = 1; - -#if defined(_MSC_VER) -#pragma warning ( push ) -#pragma warning ( disable : 4127 ) -#endif - TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLUnknown ) ); // use same memory pool - TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLDeclaration ) ); // use same memory pool -#if defined(_MSC_VER) -#pragma warning (pop) -#endif - if ( XMLUtil::StringEqual( p, xmlHeader, xmlHeaderLen ) ) { - returnNode = new (_commentPool.Alloc()) XMLDeclaration( this ); - returnNode->_memPool = &_commentPool; - p += xmlHeaderLen; - } - else if ( XMLUtil::StringEqual( p, commentHeader, commentHeaderLen ) ) { - returnNode = new (_commentPool.Alloc()) XMLComment( this ); - returnNode->_memPool = &_commentPool; - p += commentHeaderLen; - } - else if ( XMLUtil::StringEqual( p, cdataHeader, cdataHeaderLen ) ) { - XMLText* text = new (_textPool.Alloc()) XMLText( this ); - returnNode = text; - returnNode->_memPool = &_textPool; - p += cdataHeaderLen; - text->SetCData( true ); - } - else if ( XMLUtil::StringEqual( p, dtdHeader, dtdHeaderLen ) ) { - returnNode = new (_commentPool.Alloc()) XMLUnknown( this ); - returnNode->_memPool = &_commentPool; - p += dtdHeaderLen; - } - else if ( XMLUtil::StringEqual( p, elementHeader, elementHeaderLen ) ) { - returnNode = new (_elementPool.Alloc()) XMLElement( this ); - returnNode->_memPool = &_elementPool; - p += elementHeaderLen; - } - else { - returnNode = new (_textPool.Alloc()) XMLText( this ); - returnNode->_memPool = &_textPool; - p = start; // Back it up, all the text counts. - } - - *node = returnNode; - return p; -} - - -bool XMLDocument::Accept( XMLVisitor* visitor ) const -{ - if ( visitor->VisitEnter( *this ) ) { - for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() ) { - if ( !node->Accept( visitor ) ) { - break; - } - } - } - return visitor->VisitExit( *this ); -} - - -// --------- XMLNode ----------- // - -XMLNode::XMLNode( XMLDocument* doc ) : - _document( doc ), - _parent( 0 ), - _firstChild( 0 ), _lastChild( 0 ), - _prev( 0 ), _next( 0 ), - _memPool( 0 ) -{ -} - - -XMLNode::~XMLNode() -{ - DeleteChildren(); - if ( _parent ) { - _parent->Unlink( this ); - } -} - -const char* XMLNode::Value() const -{ - return _value.GetStr(); -} - -void XMLNode::SetValue( const char* str, bool staticMem ) -{ - if ( staticMem ) { - _value.SetInternedStr( str ); - } - else { - _value.SetStr( str ); - } -} - - -void XMLNode::DeleteChildren() -{ - while( _firstChild ) { - XMLNode* node = _firstChild; - Unlink( node ); - - DELETE_NODE( node ); - } - _firstChild = _lastChild = 0; -} - - -void XMLNode::Unlink( XMLNode* child ) -{ - if ( child == _firstChild ) { - _firstChild = _firstChild->_next; - } - if ( child == _lastChild ) { - _lastChild = _lastChild->_prev; - } - - if ( child->_prev ) { - child->_prev->_next = child->_next; - } - if ( child->_next ) { - child->_next->_prev = child->_prev; - } - child->_parent = 0; -} - - -void XMLNode::DeleteChild( XMLNode* node ) -{ - TIXMLASSERT( node->_parent == this ); - DELETE_NODE( node ); -} - - -XMLNode* XMLNode::InsertEndChild( XMLNode* addThis ) -{ - if (addThis->_document != _document) - return 0; - - if (addThis->_parent) - addThis->_parent->Unlink( addThis ); - else - addThis->_memPool->SetTracked(); - - if ( _lastChild ) { - TIXMLASSERT( _firstChild ); - TIXMLASSERT( _lastChild->_next == 0 ); - _lastChild->_next = addThis; - addThis->_prev = _lastChild; - _lastChild = addThis; - - addThis->_next = 0; - } - else { - TIXMLASSERT( _firstChild == 0 ); - _firstChild = _lastChild = addThis; - - addThis->_prev = 0; - addThis->_next = 0; - } - addThis->_parent = this; - return addThis; -} - - -XMLNode* XMLNode::InsertFirstChild( XMLNode* addThis ) -{ - if (addThis->_document != _document) - return 0; - - if (addThis->_parent) - addThis->_parent->Unlink( addThis ); - else - addThis->_memPool->SetTracked(); - - if ( _firstChild ) { - TIXMLASSERT( _lastChild ); - TIXMLASSERT( _firstChild->_prev == 0 ); - - _firstChild->_prev = addThis; - addThis->_next = _firstChild; - _firstChild = addThis; - - addThis->_prev = 0; - } - else { - TIXMLASSERT( _lastChild == 0 ); - _firstChild = _lastChild = addThis; - - addThis->_prev = 0; - addThis->_next = 0; - } - addThis->_parent = this; - return addThis; -} - - -XMLNode* XMLNode::InsertAfterChild( XMLNode* afterThis, XMLNode* addThis ) -{ - if (addThis->_document != _document) - return 0; - - TIXMLASSERT( afterThis->_parent == this ); - - if ( afterThis->_parent != this ) { - return 0; - } - - if ( afterThis->_next == 0 ) { - // The last node or the only node. - return InsertEndChild( addThis ); - } - if (addThis->_parent) - addThis->_parent->Unlink( addThis ); - else - addThis->_memPool->SetTracked(); - addThis->_prev = afterThis; - addThis->_next = afterThis->_next; - afterThis->_next->_prev = addThis; - afterThis->_next = addThis; - addThis->_parent = this; - return addThis; -} - - - - -const XMLElement* XMLNode::FirstChildElement( const char* value ) const -{ - for( XMLNode* node=_firstChild; node; node=node->_next ) { - XMLElement* element = node->ToElement(); - if ( element ) { - if ( !value || XMLUtil::StringEqual( element->Name(), value ) ) { - return element; - } - } - } - return 0; -} - - -const XMLElement* XMLNode::LastChildElement( const char* value ) const -{ - for( XMLNode* node=_lastChild; node; node=node->_prev ) { - XMLElement* element = node->ToElement(); - if ( element ) { - if ( !value || XMLUtil::StringEqual( element->Name(), value ) ) { - return element; - } - } - } - return 0; -} - - -const XMLElement* XMLNode::NextSiblingElement( const char* value ) const -{ - for( XMLNode* element=this->_next; element; element = element->_next ) { - if ( element->ToElement() - && (!value || XMLUtil::StringEqual( value, element->Value() ))) { - return element->ToElement(); - } - } - return 0; -} - - -const XMLElement* XMLNode::PreviousSiblingElement( const char* value ) const -{ - for( XMLNode* element=_prev; element; element = element->_prev ) { - if ( element->ToElement() - && (!value || XMLUtil::StringEqual( value, element->Value() ))) { - return element->ToElement(); - } - } - return 0; -} - - -char* XMLNode::ParseDeep( char* p, StrPair* parentEnd ) -{ - // This is a recursive method, but thinking about it "at the current level" - // it is a pretty simple flat list: - // <foo/> - // <!-- comment --> - // - // With a special case: - // <foo> - // </foo> - // <!-- comment --> - // - // Where the closing element (/foo) *must* be the next thing after the opening - // element, and the names must match. BUT the tricky bit is that the closing - // element will be read by the child. - // - // 'endTag' is the end tag for this node, it is returned by a call to a child. - // 'parentEnd' is the end tag for the parent, which is filled in and returned. - - while( p && *p ) { - XMLNode* node = 0; - - p = _document->Identify( p, &node ); - if ( p == 0 || node == 0 ) { - break; - } - - StrPair endTag; - p = node->ParseDeep( p, &endTag ); - if ( !p ) { - DELETE_NODE( node ); - node = 0; - if ( !_document->Error() ) { - _document->SetError( XML_ERROR_PARSING, 0, 0 ); - } - break; - } - - // We read the end tag. Return it to the parent. - if ( node->ToElement() && node->ToElement()->ClosingType() == XMLElement::CLOSING ) { - if ( parentEnd ) { - *parentEnd = static_cast<XMLElement*>(node)->_value; - } - node->_memPool->SetTracked(); // created and then immediately deleted. - DELETE_NODE( node ); - return p; - } - - // Handle an end tag returned to this level. - // And handle a bunch of annoying errors. - XMLElement* ele = node->ToElement(); - if ( ele ) { - if ( endTag.Empty() && ele->ClosingType() == XMLElement::OPEN ) { - _document->SetError( XML_ERROR_MISMATCHED_ELEMENT, node->Value(), 0 ); - p = 0; - } - else if ( !endTag.Empty() && ele->ClosingType() != XMLElement::OPEN ) { - _document->SetError( XML_ERROR_MISMATCHED_ELEMENT, node->Value(), 0 ); - p = 0; - } - else if ( !endTag.Empty() ) { - if ( !XMLUtil::StringEqual( endTag.GetStr(), node->Value() )) { - _document->SetError( XML_ERROR_MISMATCHED_ELEMENT, node->Value(), 0 ); - p = 0; - } - } - } - if ( p == 0 ) { - DELETE_NODE( node ); - node = 0; - } - if ( node ) { - this->InsertEndChild( node ); - } - } - return 0; -} - -// --------- XMLText ---------- // -char* XMLText::ParseDeep( char* p, StrPair* ) -{ - const char* start = p; - if ( this->CData() ) { - p = _value.ParseText( p, "]]>", StrPair::NEEDS_NEWLINE_NORMALIZATION ); - if ( !p ) { - _document->SetError( XML_ERROR_PARSING_CDATA, start, 0 ); - } - return p; - } - else { - int flags = _document->ProcessEntities() ? StrPair::TEXT_ELEMENT : StrPair::TEXT_ELEMENT_LEAVE_ENTITIES; - if ( _document->WhitespaceMode() == COLLAPSE_WHITESPACE ) { - flags |= StrPair::COLLAPSE_WHITESPACE; - } - - p = _value.ParseText( p, "<", flags ); - if ( !p ) { - _document->SetError( XML_ERROR_PARSING_TEXT, start, 0 ); - } - if ( p && *p ) { - return p-1; - } - } - return 0; -} - - -XMLNode* XMLText::ShallowClone( XMLDocument* doc ) const -{ - if ( !doc ) { - doc = _document; - } - XMLText* text = doc->NewText( Value() ); // fixme: this will always allocate memory. Intern? - text->SetCData( this->CData() ); - return text; -} - - -bool XMLText::ShallowEqual( const XMLNode* compare ) const -{ - return ( compare->ToText() && XMLUtil::StringEqual( compare->ToText()->Value(), Value() )); -} - - -bool XMLText::Accept( XMLVisitor* visitor ) const -{ - return visitor->Visit( *this ); -} - - -// --------- XMLComment ---------- // - -XMLComment::XMLComment( XMLDocument* doc ) : XMLNode( doc ) -{ -} - - -XMLComment::~XMLComment() -{ -} - - -char* XMLComment::ParseDeep( char* p, StrPair* ) -{ - // Comment parses as text. - const char* start = p; - p = _value.ParseText( p, "-->", StrPair::COMMENT ); - if ( p == 0 ) { - _document->SetError( XML_ERROR_PARSING_COMMENT, start, 0 ); - } - return p; -} - - -XMLNode* XMLComment::ShallowClone( XMLDocument* doc ) const -{ - if ( !doc ) { - doc = _document; - } - XMLComment* comment = doc->NewComment( Value() ); // fixme: this will always allocate memory. Intern? - return comment; -} - - -bool XMLComment::ShallowEqual( const XMLNode* compare ) const -{ - return ( compare->ToComment() && XMLUtil::StringEqual( compare->ToComment()->Value(), Value() )); -} - - -bool XMLComment::Accept( XMLVisitor* visitor ) const -{ - return visitor->Visit( *this ); -} - - -// --------- XMLDeclaration ---------- // - -XMLDeclaration::XMLDeclaration( XMLDocument* doc ) : XMLNode( doc ) -{ -} - - -XMLDeclaration::~XMLDeclaration() -{ - //printf( "~XMLDeclaration\n" ); -} - - -char* XMLDeclaration::ParseDeep( char* p, StrPair* ) -{ - // Declaration parses as text. - const char* start = p; - p = _value.ParseText( p, "?>", StrPair::NEEDS_NEWLINE_NORMALIZATION ); - if ( p == 0 ) { - _document->SetError( XML_ERROR_PARSING_DECLARATION, start, 0 ); - } - return p; -} - - -XMLNode* XMLDeclaration::ShallowClone( XMLDocument* doc ) const -{ - if ( !doc ) { - doc = _document; - } - XMLDeclaration* dec = doc->NewDeclaration( Value() ); // fixme: this will always allocate memory. Intern? - return dec; -} - - -bool XMLDeclaration::ShallowEqual( const XMLNode* compare ) const -{ - return ( compare->ToDeclaration() && XMLUtil::StringEqual( compare->ToDeclaration()->Value(), Value() )); -} - - - -bool XMLDeclaration::Accept( XMLVisitor* visitor ) const -{ - return visitor->Visit( *this ); -} - -// --------- XMLUnknown ---------- // - -XMLUnknown::XMLUnknown( XMLDocument* doc ) : XMLNode( doc ) -{ -} - - -XMLUnknown::~XMLUnknown() -{ -} - - -char* XMLUnknown::ParseDeep( char* p, StrPair* ) -{ - // Unknown parses as text. - const char* start = p; - - p = _value.ParseText( p, ">", StrPair::NEEDS_NEWLINE_NORMALIZATION ); - if ( !p ) { - _document->SetError( XML_ERROR_PARSING_UNKNOWN, start, 0 ); - } - return p; -} - - -XMLNode* XMLUnknown::ShallowClone( XMLDocument* doc ) const -{ - if ( !doc ) { - doc = _document; - } - XMLUnknown* text = doc->NewUnknown( Value() ); // fixme: this will always allocate memory. Intern? - return text; -} - - -bool XMLUnknown::ShallowEqual( const XMLNode* compare ) const -{ - return ( compare->ToUnknown() && XMLUtil::StringEqual( compare->ToUnknown()->Value(), Value() )); -} - - -bool XMLUnknown::Accept( XMLVisitor* visitor ) const -{ - return visitor->Visit( *this ); -} - -// --------- XMLAttribute ---------- // - -const char* XMLAttribute::Name() const -{ - return _name.GetStr(); -} - -const char* XMLAttribute::Value() const -{ - return _value.GetStr(); -} - -char* XMLAttribute::ParseDeep( char* p, bool processEntities ) -{ - // Parse using the name rules: bug fix, was using ParseText before - p = _name.ParseName( p ); - if ( !p || !*p ) { - return 0; - } - - // Skip white space before = - p = XMLUtil::SkipWhiteSpace( p ); - if ( !p || *p != '=' ) { - return 0; - } - - ++p; // move up to opening quote - p = XMLUtil::SkipWhiteSpace( p ); - if ( *p != '\"' && *p != '\'' ) { - return 0; - } - - char endTag[2] = { *p, 0 }; - ++p; // move past opening quote - - p = _value.ParseText( p, endTag, processEntities ? StrPair::ATTRIBUTE_VALUE : StrPair::ATTRIBUTE_VALUE_LEAVE_ENTITIES ); - return p; -} - - -void XMLAttribute::SetName( const char* n ) -{ - _name.SetStr( n ); -} - - -XMLError XMLAttribute::QueryIntValue( int* value ) const -{ - if ( XMLUtil::ToInt( Value(), value )) { - return XML_NO_ERROR; - } - return XML_WRONG_ATTRIBUTE_TYPE; -} - - -XMLError XMLAttribute::QueryUnsignedValue( unsigned int* value ) const -{ - if ( XMLUtil::ToUnsigned( Value(), value )) { - return XML_NO_ERROR; - } - return XML_WRONG_ATTRIBUTE_TYPE; -} - - -XMLError XMLAttribute::QueryBoolValue( bool* value ) const -{ - if ( XMLUtil::ToBool( Value(), value )) { - return XML_NO_ERROR; - } - return XML_WRONG_ATTRIBUTE_TYPE; -} - - -XMLError XMLAttribute::QueryFloatValue( float* value ) const -{ - if ( XMLUtil::ToFloat( Value(), value )) { - return XML_NO_ERROR; - } - return XML_WRONG_ATTRIBUTE_TYPE; -} - - -XMLError XMLAttribute::QueryDoubleValue( double* value ) const -{ - if ( XMLUtil::ToDouble( Value(), value )) { - return XML_NO_ERROR; - } - return XML_WRONG_ATTRIBUTE_TYPE; -} - - -void XMLAttribute::SetAttribute( const char* v ) -{ - _value.SetStr( v ); -} - - -void XMLAttribute::SetAttribute( int v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - _value.SetStr( buf ); -} - - -void XMLAttribute::SetAttribute( unsigned v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - _value.SetStr( buf ); -} - - -void XMLAttribute::SetAttribute( bool v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - _value.SetStr( buf ); -} - -void XMLAttribute::SetAttribute( double v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - _value.SetStr( buf ); -} - -void XMLAttribute::SetAttribute( float v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - _value.SetStr( buf ); -} - - -// --------- XMLElement ---------- // -XMLElement::XMLElement( XMLDocument* doc ) : XMLNode( doc ), - _closingType( 0 ), - _rootAttribute( 0 ) -{ -} - - -XMLElement::~XMLElement() -{ - while( _rootAttribute ) { - XMLAttribute* next = _rootAttribute->_next; - DELETE_ATTRIBUTE( _rootAttribute ); - _rootAttribute = next; - } -} - - -XMLAttribute* XMLElement::FindAttribute( const char* name ) -{ - XMLAttribute* a = 0; - for( a=_rootAttribute; a; a = a->_next ) { - if ( XMLUtil::StringEqual( a->Name(), name ) ) { - return a; - } - } - return 0; -} - - -const XMLAttribute* XMLElement::FindAttribute( const char* name ) const -{ - XMLAttribute* a = 0; - for( a=_rootAttribute; a; a = a->_next ) { - if ( XMLUtil::StringEqual( a->Name(), name ) ) { - return a; - } - } - return 0; -} - - -const char* XMLElement::Attribute( const char* name, const char* value ) const -{ - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return 0; - } - if ( !value || XMLUtil::StringEqual( a->Value(), value )) { - return a->Value(); - } - return 0; -} - - -const char* XMLElement::GetText() const -{ - if ( FirstChild() && FirstChild()->ToText() ) { - return FirstChild()->ToText()->Value(); - } - return 0; -} - - -void XMLElement::SetText( const char* inText ) -{ - if ( FirstChild() && FirstChild()->ToText() ) - FirstChild()->SetValue( inText ); - else { - XMLText* theText = GetDocument()->NewText( inText ); - InsertFirstChild( theText ); - } -} - - -void XMLElement::SetText( int v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - SetText( buf ); -} - - -void XMLElement::SetText( unsigned v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - SetText( buf ); -} - - -void XMLElement::SetText( bool v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - SetText( buf ); -} - - -void XMLElement::SetText( float v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - SetText( buf ); -} - - -void XMLElement::SetText( double v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - SetText( buf ); -} - - -XMLError XMLElement::QueryIntText( int* ival ) const -{ - if ( FirstChild() && FirstChild()->ToText() ) { - const char* t = FirstChild()->ToText()->Value(); - if ( XMLUtil::ToInt( t, ival ) ) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; -} - - -XMLError XMLElement::QueryUnsignedText( unsigned* uval ) const -{ - if ( FirstChild() && FirstChild()->ToText() ) { - const char* t = FirstChild()->ToText()->Value(); - if ( XMLUtil::ToUnsigned( t, uval ) ) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; -} - - -XMLError XMLElement::QueryBoolText( bool* bval ) const -{ - if ( FirstChild() && FirstChild()->ToText() ) { - const char* t = FirstChild()->ToText()->Value(); - if ( XMLUtil::ToBool( t, bval ) ) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; -} - - -XMLError XMLElement::QueryDoubleText( double* dval ) const -{ - if ( FirstChild() && FirstChild()->ToText() ) { - const char* t = FirstChild()->ToText()->Value(); - if ( XMLUtil::ToDouble( t, dval ) ) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; -} - - -XMLError XMLElement::QueryFloatText( float* fval ) const -{ - if ( FirstChild() && FirstChild()->ToText() ) { - const char* t = FirstChild()->ToText()->Value(); - if ( XMLUtil::ToFloat( t, fval ) ) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; -} - - - -XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name ) -{ - XMLAttribute* last = 0; - XMLAttribute* attrib = 0; - for( attrib = _rootAttribute; - attrib; - last = attrib, attrib = attrib->_next ) { - if ( XMLUtil::StringEqual( attrib->Name(), name ) ) { - break; - } - } - if ( !attrib ) { - attrib = new (_document->_attributePool.Alloc() ) XMLAttribute(); - attrib->_memPool = &_document->_attributePool; - if ( last ) { - last->_next = attrib; - } - else { - _rootAttribute = attrib; - } - attrib->SetName( name ); - attrib->_memPool->SetTracked(); // always created and linked. - } - return attrib; -} - - -void XMLElement::DeleteAttribute( const char* name ) -{ - XMLAttribute* prev = 0; - for( XMLAttribute* a=_rootAttribute; a; a=a->_next ) { - if ( XMLUtil::StringEqual( name, a->Name() ) ) { - if ( prev ) { - prev->_next = a->_next; - } - else { - _rootAttribute = a->_next; - } - DELETE_ATTRIBUTE( a ); - break; - } - prev = a; - } -} - - -char* XMLElement::ParseAttributes( char* p ) -{ - const char* start = p; - XMLAttribute* prevAttribute = 0; - - // Read the attributes. - while( p ) { - p = XMLUtil::SkipWhiteSpace( p ); - if ( !p || !(*p) ) { - _document->SetError( XML_ERROR_PARSING_ELEMENT, start, Name() ); - return 0; - } - - // attribute. - if (XMLUtil::IsNameStartChar( *p ) ) { - XMLAttribute* attrib = new (_document->_attributePool.Alloc() ) XMLAttribute(); - attrib->_memPool = &_document->_attributePool; - attrib->_memPool->SetTracked(); - - p = attrib->ParseDeep( p, _document->ProcessEntities() ); - if ( !p || Attribute( attrib->Name() ) ) { - DELETE_ATTRIBUTE( attrib ); - _document->SetError( XML_ERROR_PARSING_ATTRIBUTE, start, p ); - return 0; - } - // There is a minor bug here: if the attribute in the source xml - // document is duplicated, it will not be detected and the - // attribute will be doubly added. However, tracking the 'prevAttribute' - // avoids re-scanning the attribute list. Preferring performance for - // now, may reconsider in the future. - if ( prevAttribute ) { - prevAttribute->_next = attrib; - } - else { - _rootAttribute = attrib; - } - prevAttribute = attrib; - } - // end of the tag - else if ( *p == '/' && *(p+1) == '>' ) { - _closingType = CLOSED; - return p+2; // done; sealed element. - } - // end of the tag - else if ( *p == '>' ) { - ++p; - break; - } - else { - _document->SetError( XML_ERROR_PARSING_ELEMENT, start, p ); - return 0; - } - } - return p; -} - - -// -// <ele></ele> -// <ele>foo<b>bar</b></ele> -// -char* XMLElement::ParseDeep( char* p, StrPair* strPair ) -{ - // Read the element name. - p = XMLUtil::SkipWhiteSpace( p ); - if ( !p ) { - return 0; - } - - // The closing element is the </element> form. It is - // parsed just like a regular element then deleted from - // the DOM. - if ( *p == '/' ) { - _closingType = CLOSING; - ++p; - } - - p = _value.ParseName( p ); - if ( _value.Empty() ) { - return 0; - } - - p = ParseAttributes( p ); - if ( !p || !*p || _closingType ) { - return p; - } - - p = XMLNode::ParseDeep( p, strPair ); - return p; -} - - - -XMLNode* XMLElement::ShallowClone( XMLDocument* doc ) const -{ - if ( !doc ) { - doc = _document; - } - XMLElement* element = doc->NewElement( Value() ); // fixme: this will always allocate memory. Intern? - for( const XMLAttribute* a=FirstAttribute(); a; a=a->Next() ) { - element->SetAttribute( a->Name(), a->Value() ); // fixme: this will always allocate memory. Intern? - } - return element; -} - - -bool XMLElement::ShallowEqual( const XMLNode* compare ) const -{ - const XMLElement* other = compare->ToElement(); - if ( other && XMLUtil::StringEqual( other->Value(), Value() )) { - - const XMLAttribute* a=FirstAttribute(); - const XMLAttribute* b=other->FirstAttribute(); - - while ( a && b ) { - if ( !XMLUtil::StringEqual( a->Value(), b->Value() ) ) { - return false; - } - a = a->Next(); - b = b->Next(); - } - if ( a || b ) { - // different count - return false; - } - return true; - } - return false; -} - - -bool XMLElement::Accept( XMLVisitor* visitor ) const -{ - if ( visitor->VisitEnter( *this, _rootAttribute ) ) { - for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() ) { - if ( !node->Accept( visitor ) ) { - break; - } - } - } - return visitor->VisitExit( *this ); -} - - -// --------- XMLDocument ----------- // -XMLDocument::XMLDocument( bool processEntities, Whitespace whitespace ) : - XMLNode( 0 ), - _writeBOM( false ), - _processEntities( processEntities ), - _errorID( XML_NO_ERROR ), - _whitespace( whitespace ), - _errorStr1( 0 ), - _errorStr2( 0 ), - _charBuffer( 0 ) -{ - _document = this; // avoid warning about 'this' in initializer list -} - - -XMLDocument::~XMLDocument() -{ - DeleteChildren(); - delete [] _charBuffer; - -#if 0 - _textPool.Trace( "text" ); - _elementPool.Trace( "element" ); - _commentPool.Trace( "comment" ); - _attributePool.Trace( "attribute" ); -#endif - -#ifdef DEBUG - if ( Error() == false ) { - TIXMLASSERT( _elementPool.CurrentAllocs() == _elementPool.Untracked() ); - TIXMLASSERT( _attributePool.CurrentAllocs() == _attributePool.Untracked() ); - TIXMLASSERT( _textPool.CurrentAllocs() == _textPool.Untracked() ); - TIXMLASSERT( _commentPool.CurrentAllocs() == _commentPool.Untracked() ); - } -#endif -} - - -void XMLDocument::Clear() -{ - DeleteChildren(); - - _errorID = XML_NO_ERROR; - _errorStr1 = 0; - _errorStr2 = 0; - - delete [] _charBuffer; - _charBuffer = 0; -} - - -XMLElement* XMLDocument::NewElement( const char* name ) -{ - XMLElement* ele = new (_elementPool.Alloc()) XMLElement( this ); - ele->_memPool = &_elementPool; - ele->SetName( name ); - return ele; -} - - -XMLComment* XMLDocument::NewComment( const char* str ) -{ - XMLComment* comment = new (_commentPool.Alloc()) XMLComment( this ); - comment->_memPool = &_commentPool; - comment->SetValue( str ); - return comment; -} - - -XMLText* XMLDocument::NewText( const char* str ) -{ - XMLText* text = new (_textPool.Alloc()) XMLText( this ); - text->_memPool = &_textPool; - text->SetValue( str ); - return text; -} - - -XMLDeclaration* XMLDocument::NewDeclaration( const char* str ) -{ - XMLDeclaration* dec = new (_commentPool.Alloc()) XMLDeclaration( this ); - dec->_memPool = &_commentPool; - dec->SetValue( str ? str : "xml version=\"1.0\" encoding=\"UTF-8\"" ); - return dec; -} - - -XMLUnknown* XMLDocument::NewUnknown( const char* str ) -{ - XMLUnknown* unk = new (_commentPool.Alloc()) XMLUnknown( this ); - unk->_memPool = &_commentPool; - unk->SetValue( str ); - return unk; -} - - -XMLError XMLDocument::LoadFile( const char* filename ) -{ - Clear(); - FILE* fp = 0; - -#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) - errno_t err = fopen_s(&fp, filename, "rb" ); - if ( !fp || err) { -#else - fp = fopen( filename, "rb" ); - if ( !fp) { -#endif - SetError( XML_ERROR_FILE_NOT_FOUND, filename, 0 ); - return _errorID; - } - LoadFile( fp ); - fclose( fp ); - return _errorID; -} - - -XMLError XMLDocument::LoadFile( FILE* fp ) -{ - Clear(); - - fseek( fp, 0, SEEK_SET ); - fgetc( fp ); - if ( ferror( fp ) != 0 ) { - SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); - return _errorID; - } - - fseek( fp, 0, SEEK_END ); - size_t size = ftell( fp ); - fseek( fp, 0, SEEK_SET ); - - if ( size == 0 ) { - SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); - return _errorID; - } - - _charBuffer = new char[size+1]; - size_t read = fread( _charBuffer, 1, size, fp ); - if ( read != size ) { - SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); - return _errorID; - } - - _charBuffer[size] = 0; - - const char* p = _charBuffer; - p = XMLUtil::SkipWhiteSpace( p ); - p = XMLUtil::ReadBOM( p, &_writeBOM ); - if ( !p || !*p ) { - SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); - return _errorID; - } - - ParseDeep( _charBuffer + (p-_charBuffer), 0 ); - return _errorID; -} - - -XMLError XMLDocument::SaveFile( const char* filename, bool compact ) -{ - FILE* fp = 0; -#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) - errno_t err = fopen_s(&fp, filename, "w" ); - if ( !fp || err) { -#else - fp = fopen( filename, "w" ); - if ( !fp) { -#endif - SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, filename, 0 ); - return _errorID; - } - SaveFile(fp, compact); - fclose( fp ); - return _errorID; -} - - -XMLError XMLDocument::SaveFile( FILE* fp, bool compact ) -{ - XMLPrinter stream( fp, compact ); - Print( &stream ); - return _errorID; -} - - -XMLError XMLDocument::Parse( const char* p, size_t len ) -{ - const char* start = p; - Clear(); - - if ( len == 0 || !p || !*p ) { - SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); - return _errorID; - } - if ( len == (size_t)(-1) ) { - len = strlen( p ); - } - _charBuffer = new char[ len+1 ]; - memcpy( _charBuffer, p, len ); - _charBuffer[len] = 0; - - p = XMLUtil::SkipWhiteSpace( p ); - p = XMLUtil::ReadBOM( p, &_writeBOM ); - if ( !p || !*p ) { - SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); - return _errorID; - } - - ptrdiff_t delta = p - start; // skip initial whitespace, BOM, etc. - ParseDeep( _charBuffer+delta, 0 ); - return _errorID; -} - - -void XMLDocument::Print( XMLPrinter* streamer ) const -{ - XMLPrinter stdStreamer( stdout ); - if ( !streamer ) { - streamer = &stdStreamer; - } - Accept( streamer ); -} - - -void XMLDocument::SetError( XMLError error, const char* str1, const char* str2 ) -{ - _errorID = error; - _errorStr1 = str1; - _errorStr2 = str2; -} - - -void XMLDocument::PrintError() const -{ - if ( _errorID ) { - static const int LEN = 20; - char buf1[LEN] = { 0 }; - char buf2[LEN] = { 0 }; - - if ( _errorStr1 ) { - TIXML_SNPRINTF( buf1, LEN, "%s", _errorStr1 ); - } - if ( _errorStr2 ) { - TIXML_SNPRINTF( buf2, LEN, "%s", _errorStr2 ); - } - - printf( "XMLDocument error id=%d str1=%s str2=%s\n", - _errorID, buf1, buf2 ); - } -} - - -XMLPrinter::XMLPrinter( FILE* file, bool compact, int depth ) : - _elementJustOpened( false ), - _firstElement( true ), - _fp( file ), - _depth( depth ), - _textDepth( -1 ), - _processEntities( true ), - _compactMode( compact ) -{ - for( int i=0; i<ENTITY_RANGE; ++i ) { - _entityFlag[i] = false; - _restrictedEntityFlag[i] = false; - } - for( int i=0; i<NUM_ENTITIES; ++i ) { - TIXMLASSERT( entities[i].value < ENTITY_RANGE ); - if ( entities[i].value < ENTITY_RANGE ) { - _entityFlag[ (int)entities[i].value ] = true; - } - } - _restrictedEntityFlag[(int)'&'] = true; - _restrictedEntityFlag[(int)'<'] = true; - _restrictedEntityFlag[(int)'>'] = true; // not required, but consistency is nice - _buffer.Push( 0 ); -} - - -void XMLPrinter::Print( const char* format, ... ) -{ - va_list va; - va_start( va, format ); - - if ( _fp ) { - vfprintf( _fp, format, va ); - } - else { -#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) - int len = _vscprintf( format, va ); -#else - int len = vsnprintf( 0, 0, format, va ); -#endif - // Close out and re-start the va-args - va_end( va ); - va_start( va, format ); - char* p = _buffer.PushArr( len ) - 1; // back up over the null terminator. -#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) - vsnprintf_s( p, len+1, _TRUNCATE, format, va ); -#else - vsnprintf( p, len+1, format, va ); -#endif - } - va_end( va ); -} - - -void XMLPrinter::PrintSpace( int depth ) -{ - for( int i=0; i<depth; ++i ) { - Print( " " ); - } -} - - -void XMLPrinter::PrintString( const char* p, bool restricted ) -{ - // Look for runs of bytes between entities to print. - const char* q = p; - const bool* flag = restricted ? _restrictedEntityFlag : _entityFlag; - - if ( _processEntities ) { - while ( *q ) { - // Remember, char is sometimes signed. (How many times has that bitten me?) - if ( *q > 0 && *q < ENTITY_RANGE ) { - // Check for entities. If one is found, flush - // the stream up until the entity, write the - // entity, and keep looking. - if ( flag[(unsigned)(*q)] ) { - while ( p < q ) { - Print( "%c", *p ); - ++p; - } - for( int i=0; i<NUM_ENTITIES; ++i ) { - if ( entities[i].value == *q ) { - Print( "&%s;", entities[i].pattern ); - break; - } - } - ++p; - } - } - ++q; - } - } - // Flush the remaining string. This will be the entire - // string if an entity wasn't found. - if ( !_processEntities || (q-p > 0) ) { - Print( "%s", p ); - } -} - - -void XMLPrinter::PushHeader( bool writeBOM, bool writeDec ) -{ - if ( writeBOM ) { - static const unsigned char bom[] = { TIXML_UTF_LEAD_0, TIXML_UTF_LEAD_1, TIXML_UTF_LEAD_2, 0 }; - Print( "%s", bom ); - } - if ( writeDec ) { - PushDeclaration( "xml version=\"1.0\"" ); - } -} - - -void XMLPrinter::OpenElement( const char* name, bool compactMode ) -{ - if ( _elementJustOpened ) { - SealElement(); - } - _stack.Push( name ); - - if ( _textDepth < 0 && !_firstElement && !compactMode ) { - Print( "\n" ); - } - if ( !compactMode ) { - PrintSpace( _depth ); - } - - Print( "<%s", name ); - _elementJustOpened = true; - _firstElement = false; - ++_depth; -} - - -void XMLPrinter::PushAttribute( const char* name, const char* value ) -{ - TIXMLASSERT( _elementJustOpened ); - Print( " %s=\"", name ); - PrintString( value, false ); - Print( "\"" ); -} - - -void XMLPrinter::PushAttribute( const char* name, int v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - PushAttribute( name, buf ); -} - - -void XMLPrinter::PushAttribute( const char* name, unsigned v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - PushAttribute( name, buf ); -} - - -void XMLPrinter::PushAttribute( const char* name, bool v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - PushAttribute( name, buf ); -} - - -void XMLPrinter::PushAttribute( const char* name, double v ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - PushAttribute( name, buf ); -} - - -void XMLPrinter::CloseElement( bool compactMode ) -{ - --_depth; - const char* name = _stack.Pop(); - - if ( _elementJustOpened ) { - Print( "/>" ); - } - else { - if ( _textDepth < 0 && !compactMode) { - Print( "\n" ); - PrintSpace( _depth ); - } - Print( "</%s>", name ); - } - - if ( _textDepth == _depth ) { - _textDepth = -1; - } - if ( _depth == 0 && !compactMode) { - Print( "\n" ); - } - _elementJustOpened = false; -} - - -void XMLPrinter::SealElement() -{ - _elementJustOpened = false; - Print( ">" ); -} - - -void XMLPrinter::PushText( const char* text, bool cdata ) -{ - _textDepth = _depth-1; - - if ( _elementJustOpened ) { - SealElement(); - } - if ( cdata ) { - Print( "<![CDATA[" ); - Print( "%s", text ); - Print( "]]>" ); - } - else { - PrintString( text, true ); - } -} - -void XMLPrinter::PushText( int value ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); -} - - -void XMLPrinter::PushText( unsigned value ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); -} - - -void XMLPrinter::PushText( bool value ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); -} - - -void XMLPrinter::PushText( float value ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); -} - - -void XMLPrinter::PushText( double value ) -{ - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); -} - - -void XMLPrinter::PushComment( const char* comment ) -{ - if ( _elementJustOpened ) { - SealElement(); - } - if ( _textDepth < 0 && !_firstElement && !_compactMode) { - Print( "\n" ); - PrintSpace( _depth ); - } - _firstElement = false; - Print( "<!--%s-->", comment ); -} - - -void XMLPrinter::PushDeclaration( const char* value ) -{ - if ( _elementJustOpened ) { - SealElement(); - } - if ( _textDepth < 0 && !_firstElement && !_compactMode) { - Print( "\n" ); - PrintSpace( _depth ); - } - _firstElement = false; - Print( "<?%s?>", value ); -} - - -void XMLPrinter::PushUnknown( const char* value ) -{ - if ( _elementJustOpened ) { - SealElement(); - } - if ( _textDepth < 0 && !_firstElement && !_compactMode) { - Print( "\n" ); - PrintSpace( _depth ); - } - _firstElement = false; - Print( "<!%s>", value ); -} - - -bool XMLPrinter::VisitEnter( const XMLDocument& doc ) -{ - _processEntities = doc.ProcessEntities(); - if ( doc.HasBOM() ) { - PushHeader( true, false ); - } - return true; -} - - -bool XMLPrinter::VisitEnter( const XMLElement& element, const XMLAttribute* attribute ) -{ - const XMLElement* parentElem = element.Parent()->ToElement(); - bool compactMode = parentElem ? CompactMode(*parentElem) : _compactMode; - OpenElement( element.Name(), compactMode ); - while ( attribute ) { - PushAttribute( attribute->Name(), attribute->Value() ); - attribute = attribute->Next(); - } - return true; -} - - -bool XMLPrinter::VisitExit( const XMLElement& element ) -{ - CloseElement( CompactMode(element) ); - return true; -} - - -bool XMLPrinter::Visit( const XMLText& text ) -{ - PushText( text.Value(), text.CData() ); - return true; -} - - -bool XMLPrinter::Visit( const XMLComment& comment ) -{ - PushComment( comment.Value() ); - return true; -} - -bool XMLPrinter::Visit( const XMLDeclaration& declaration ) -{ - PushDeclaration( declaration.Value() ); - return true; -} - - -bool XMLPrinter::Visit( const XMLUnknown& unknown ) -{ - PushUnknown( unknown.Value() ); - return true; -} - -} // namespace tinyxml2 - diff --git a/external/tinyxml/tinyxml2.h b/external/tinyxml/tinyxml2.h deleted file mode 100644 index 75bf810f..00000000 --- a/external/tinyxml/tinyxml2.h +++ /dev/null @@ -1,2076 +0,0 @@ -/* -Original code by Lee Thomason (www.grinninglizard.com) - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - -#ifndef TINYXML2_INCLUDED -#define TINYXML2_INCLUDED - -#if defined(ANDROID_NDK) || defined(__BORLANDC__) -# include <ctype.h> -# include <limits.h> -# include <stdio.h> -# include <stdlib.h> -# include <string.h> -# include <stdarg.h> -#else -# include <cctype> -# include <climits> -# include <cstdio> -# include <cstdlib> -# include <cstring> -# include <cstdarg> -#endif - -/* - TODO: intern strings instead of allocation. -*/ -/* - gcc: - g++ -Wall -DDEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe - - Formatting, Artistic Style: - AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h -*/ - -#if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__) -# ifndef DEBUG -# define DEBUG -# endif -#endif - -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable: 4251) -#endif - -#ifdef _WIN32 -# ifdef TINYXML2_EXPORT -# define TINYXML2_LIB __declspec(dllexport) -# elif defined(TINYXML2_IMPORT) -# define TINYXML2_LIB __declspec(dllimport) -# else -# define TINYXML2_LIB -# endif -#else -# define TINYXML2_LIB -#endif - - -#if defined(DEBUG) -# if defined(_MSC_VER) -# define TIXMLASSERT( x ) if ( !(x)) { __debugbreak(); } //if ( !(x)) WinDebugBreak() -# elif defined (ANDROID_NDK) -# include <android/log.h> -# define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); } -# else -# include <assert.h> -# define TIXMLASSERT assert -# endif -# else -# define TIXMLASSERT( x ) {} -#endif - - -#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) -// Microsoft visual studio, version 2005 and higher. -/*int _snprintf_s( - char *buffer, - size_t sizeOfBuffer, - size_t count, - const char *format [, - argument] ... -);*/ -inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... ) -{ - va_list va; - va_start( va, format ); - int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va ); - va_end( va ); - return result; -} -#define TIXML_SSCANF sscanf_s -#else -// GCC version 3 and higher -//#warning( "Using sn* functions." ) -#define TIXML_SNPRINTF snprintf -#define TIXML_SSCANF sscanf -#endif - -/* Versioning, past 1.0.14: - http://semver.org/ -*/ -static const int TIXML2_MAJOR_VERSION = 2; -static const int TIXML2_MINOR_VERSION = 1; -static const int TIXML2_PATCH_VERSION = 0; - -namespace tinyxml2 -{ -class XMLDocument; -class XMLElement; -class XMLAttribute; -class XMLComment; -class XMLText; -class XMLDeclaration; -class XMLUnknown; -class XMLPrinter; - -/* - A class that wraps strings. Normally stores the start and end - pointers into the XML file itself, and will apply normalization - and entity translation if actually read. Can also store (and memory - manage) a traditional char[] -*/ -class StrPair -{ -public: - enum { - NEEDS_ENTITY_PROCESSING = 0x01, - NEEDS_NEWLINE_NORMALIZATION = 0x02, - COLLAPSE_WHITESPACE = 0x04, - - TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, - TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, - ATTRIBUTE_NAME = 0, - ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, - ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, - COMMENT = NEEDS_NEWLINE_NORMALIZATION - }; - - StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {} - ~StrPair(); - - void Set( char* start, char* end, int flags ) { - Reset(); - _start = start; - _end = end; - _flags = flags | NEEDS_FLUSH; - } - - const char* GetStr(); - - bool Empty() const { - return _start == _end; - } - - void SetInternedStr( const char* str ) { - Reset(); - _start = const_cast<char*>(str); - } - - void SetStr( const char* str, int flags=0 ); - - char* ParseText( char* in, const char* endTag, int strFlags ); - char* ParseName( char* in ); - -private: - void Reset(); - void CollapseWhitespace(); - - enum { - NEEDS_FLUSH = 0x100, - NEEDS_DELETE = 0x200 - }; - - // After parsing, if *_end != 0, it can be set to zero. - int _flags; - char* _start; - char* _end; -}; - - -/* - A dynamic array of Plain Old Data. Doesn't support constructors, etc. - Has a small initial memory pool, so that low or no usage will not - cause a call to new/delete -*/ -template <class T, int INIT> -class DynArray -{ -public: - DynArray< T, INIT >() { - _mem = _pool; - _allocated = INIT; - _size = 0; - } - - ~DynArray() { - if ( _mem != _pool ) { - delete [] _mem; - } - } - - void Clear() { - _size = 0; - } - - void Push( T t ) { - EnsureCapacity( _size+1 ); - _mem[_size++] = t; - } - - T* PushArr( int count ) { - EnsureCapacity( _size+count ); - T* ret = &_mem[_size]; - _size += count; - return ret; - } - - T Pop() { - return _mem[--_size]; - } - - void PopArr( int count ) { - TIXMLASSERT( _size >= count ); - _size -= count; - } - - bool Empty() const { - return _size == 0; - } - - T& operator[](int i) { - TIXMLASSERT( i>= 0 && i < _size ); - return _mem[i]; - } - - const T& operator[](int i) const { - TIXMLASSERT( i>= 0 && i < _size ); - return _mem[i]; - } - - const T& PeekTop() const { - TIXMLASSERT( _size > 0 ); - return _mem[ _size - 1]; - } - - int Size() const { - return _size; - } - - int Capacity() const { - return _allocated; - } - - const T* Mem() const { - return _mem; - } - - T* Mem() { - return _mem; - } - -private: - void EnsureCapacity( int cap ) { - if ( cap > _allocated ) { - int newAllocated = cap * 2; - T* newMem = new T[newAllocated]; - memcpy( newMem, _mem, sizeof(T)*_size ); // warning: not using constructors, only works for PODs - if ( _mem != _pool ) { - delete [] _mem; - } - _mem = newMem; - _allocated = newAllocated; - } - } - - T* _mem; - T _pool[INIT]; - int _allocated; // objects allocated - int _size; // number objects in use -}; - - -/* - Parent virtual class of a pool for fast allocation - and deallocation of objects. -*/ -class MemPool -{ -public: - MemPool() {} - virtual ~MemPool() {} - - virtual int ItemSize() const = 0; - virtual void* Alloc() = 0; - virtual void Free( void* ) = 0; - virtual void SetTracked() = 0; -}; - - -/* - Template child class to create pools of the correct type. -*/ -template< int SIZE > -class MemPoolT : public MemPool -{ -public: - MemPoolT() : _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {} - ~MemPoolT() { - // Delete the blocks. - for( int i=0; i<_blockPtrs.Size(); ++i ) { - delete _blockPtrs[i]; - } - } - - virtual int ItemSize() const { - return SIZE; - } - int CurrentAllocs() const { - return _currentAllocs; - } - - virtual void* Alloc() { - if ( !_root ) { - // Need a new block. - Block* block = new Block(); - _blockPtrs.Push( block ); - - for( int i=0; i<COUNT-1; ++i ) { - block->chunk[i].next = &block->chunk[i+1]; - } - block->chunk[COUNT-1].next = 0; - _root = block->chunk; - } - void* result = _root; - _root = _root->next; - - ++_currentAllocs; - if ( _currentAllocs > _maxAllocs ) { - _maxAllocs = _currentAllocs; - } - _nAllocs++; - _nUntracked++; - return result; - } - virtual void Free( void* mem ) { - if ( !mem ) { - return; - } - --_currentAllocs; - Chunk* chunk = (Chunk*)mem; -#ifdef DEBUG - memset( chunk, 0xfe, sizeof(Chunk) ); -#endif - chunk->next = _root; - _root = chunk; - } - void Trace( const char* name ) { - printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n", - name, _maxAllocs, _maxAllocs*SIZE/1024, _currentAllocs, SIZE, _nAllocs, _blockPtrs.Size() ); - } - - void SetTracked() { - _nUntracked--; - } - - int Untracked() const { - return _nUntracked; - } - - // This number is perf sensitive. 4k seems like a good tradeoff on my machine. - // The test file is large, 170k. - // Release: VS2010 gcc(no opt) - // 1k: 4000 - // 2k: 4000 - // 4k: 3900 21000 - // 16k: 5200 - // 32k: 4300 - // 64k: 4000 21000 - enum { COUNT = (4*1024)/SIZE }; // Some compilers do not accept to use COUNT in private part if COUNT is private - -private: - union Chunk { - Chunk* next; - char mem[SIZE]; - }; - struct Block { - Chunk chunk[COUNT]; - }; - DynArray< Block*, 10 > _blockPtrs; - Chunk* _root; - - int _currentAllocs; - int _nAllocs; - int _maxAllocs; - int _nUntracked; -}; - - - -/** - Implements the interface to the "Visitor pattern" (see the Accept() method.) - If you call the Accept() method, it requires being passed a XMLVisitor - class to handle callbacks. For nodes that contain other nodes (Document, Element) - you will get called with a VisitEnter/VisitExit pair. Nodes that are always leafs - are simply called with Visit(). - - If you return 'true' from a Visit method, recursive parsing will continue. If you return - false, <b>no children of this node or its siblings</b> will be visited. - - All flavors of Visit methods have a default implementation that returns 'true' (continue - visiting). You need to only override methods that are interesting to you. - - Generally Accept() is called on the XMLDocument, although all nodes support visiting. - - You should never change the document from a callback. - - @sa XMLNode::Accept() -*/ -class TINYXML2_LIB XMLVisitor -{ -public: - virtual ~XMLVisitor() {} - - /// Visit a document. - virtual bool VisitEnter( const XMLDocument& /*doc*/ ) { - return true; - } - /// Visit a document. - virtual bool VisitExit( const XMLDocument& /*doc*/ ) { - return true; - } - - /// Visit an element. - virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ ) { - return true; - } - /// Visit an element. - virtual bool VisitExit( const XMLElement& /*element*/ ) { - return true; - } - - /// Visit a declaration. - virtual bool Visit( const XMLDeclaration& /*declaration*/ ) { - return true; - } - /// Visit a text node. - virtual bool Visit( const XMLText& /*text*/ ) { - return true; - } - /// Visit a comment node. - virtual bool Visit( const XMLComment& /*comment*/ ) { - return true; - } - /// Visit an unknown node. - virtual bool Visit( const XMLUnknown& /*unknown*/ ) { - return true; - } -}; - - -/* - Utility functionality. -*/ -class XMLUtil -{ -public: - // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't - // correct, but simple, and usually works. - static const char* SkipWhiteSpace( const char* p ) { - while( !IsUTF8Continuation(*p) && isspace( *reinterpret_cast<const unsigned char*>(p) ) ) { - ++p; - } - return p; - } - static char* SkipWhiteSpace( char* p ) { - while( !IsUTF8Continuation(*p) && isspace( *reinterpret_cast<unsigned char*>(p) ) ) { - ++p; - } - return p; - } - static bool IsWhiteSpace( char p ) { - return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) ); - } - - inline static bool IsNameStartChar( unsigned char ch ) { - return ( ( ch < 128 ) ? isalpha( ch ) : 1 ) - || ch == ':' - || ch == '_'; - } - - inline static bool IsNameChar( unsigned char ch ) { - return IsNameStartChar( ch ) - || isdigit( ch ) - || ch == '.' - || ch == '-'; - } - - inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) { - int n = 0; - if ( p == q ) { - return true; - } - while( *p && *q && *p == *q && n<nChar ) { - ++p; - ++q; - ++n; - } - if ( (n == nChar) || ( *p == 0 && *q == 0 ) ) { - return true; - } - return false; - } - - inline static int IsUTF8Continuation( const char p ) { - return p & 0x80; - } - - static const char* ReadBOM( const char* p, bool* hasBOM ); - // p is the starting location, - // the UTF-8 value of the entity will be placed in value, and length filled in. - static const char* GetCharacterRef( const char* p, char* value, int* length ); - static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); - - // converts primitive types to strings - static void ToStr( int v, char* buffer, int bufferSize ); - static void ToStr( unsigned v, char* buffer, int bufferSize ); - static void ToStr( bool v, char* buffer, int bufferSize ); - static void ToStr( float v, char* buffer, int bufferSize ); - static void ToStr( double v, char* buffer, int bufferSize ); - - // converts strings to primitive types - static bool ToInt( const char* str, int* value ); - static bool ToUnsigned( const char* str, unsigned* value ); - static bool ToBool( const char* str, bool* value ); - static bool ToFloat( const char* str, float* value ); - static bool ToDouble( const char* str, double* value ); -}; - - -/** XMLNode is a base class for every object that is in the - XML Document Object Model (DOM), except XMLAttributes. - Nodes have siblings, a parent, and children which can - be navigated. A node is always in a XMLDocument. - The type of a XMLNode can be queried, and it can - be cast to its more defined type. - - A XMLDocument allocates memory for all its Nodes. - When the XMLDocument gets deleted, all its Nodes - will also be deleted. - - @verbatim - A Document can contain: Element (container or leaf) - Comment (leaf) - Unknown (leaf) - Declaration( leaf ) - - An Element can contain: Element (container or leaf) - Text (leaf) - Attributes (not on tree) - Comment (leaf) - Unknown (leaf) - - @endverbatim -*/ -class TINYXML2_LIB XMLNode -{ - friend class XMLDocument; - friend class XMLElement; -public: - - /// Get the XMLDocument that owns this XMLNode. - const XMLDocument* GetDocument() const { - return _document; - } - /// Get the XMLDocument that owns this XMLNode. - XMLDocument* GetDocument() { - return _document; - } - - /// Safely cast to an Element, or null. - virtual XMLElement* ToElement() { - return 0; - } - /// Safely cast to Text, or null. - virtual XMLText* ToText() { - return 0; - } - /// Safely cast to a Comment, or null. - virtual XMLComment* ToComment() { - return 0; - } - /// Safely cast to a Document, or null. - virtual XMLDocument* ToDocument() { - return 0; - } - /// Safely cast to a Declaration, or null. - virtual XMLDeclaration* ToDeclaration() { - return 0; - } - /// Safely cast to an Unknown, or null. - virtual XMLUnknown* ToUnknown() { - return 0; - } - - virtual const XMLElement* ToElement() const { - return 0; - } - virtual const XMLText* ToText() const { - return 0; - } - virtual const XMLComment* ToComment() const { - return 0; - } - virtual const XMLDocument* ToDocument() const { - return 0; - } - virtual const XMLDeclaration* ToDeclaration() const { - return 0; - } - virtual const XMLUnknown* ToUnknown() const { - return 0; - } - - /** The meaning of 'value' changes for the specific type. - @verbatim - Document: empty - Element: name of the element - Comment: the comment text - Unknown: the tag contents - Text: the text string - @endverbatim - */ - const char* Value() const; - - /** Set the Value of an XML node. - @sa Value() - */ - void SetValue( const char* val, bool staticMem=false ); - - /// Get the parent of this node on the DOM. - const XMLNode* Parent() const { - return _parent; - } - - XMLNode* Parent() { - return _parent; - } - - /// Returns true if this node has no children. - bool NoChildren() const { - return !_firstChild; - } - - /// Get the first child node, or null if none exists. - const XMLNode* FirstChild() const { - return _firstChild; - } - - XMLNode* FirstChild() { - return _firstChild; - } - - /** Get the first child element, or optionally the first child - element with the specified name. - */ - const XMLElement* FirstChildElement( const char* value=0 ) const; - - XMLElement* FirstChildElement( const char* value=0 ) { - return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( value )); - } - - /// Get the last child node, or null if none exists. - const XMLNode* LastChild() const { - return _lastChild; - } - - XMLNode* LastChild() { - return const_cast<XMLNode*>(const_cast<const XMLNode*>(this)->LastChild() ); - } - - /** Get the last child element or optionally the last child - element with the specified name. - */ - const XMLElement* LastChildElement( const char* value=0 ) const; - - XMLElement* LastChildElement( const char* value=0 ) { - return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(value) ); - } - - /// Get the previous (left) sibling node of this node. - const XMLNode* PreviousSibling() const { - return _prev; - } - - XMLNode* PreviousSibling() { - return _prev; - } - - /// Get the previous (left) sibling element of this node, with an optionally supplied name. - const XMLElement* PreviousSiblingElement( const char* value=0 ) const ; - - XMLElement* PreviousSiblingElement( const char* value=0 ) { - return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( value ) ); - } - - /// Get the next (right) sibling node of this node. - const XMLNode* NextSibling() const { - return _next; - } - - XMLNode* NextSibling() { - return _next; - } - - /// Get the next (right) sibling element of this node, with an optionally supplied name. - const XMLElement* NextSiblingElement( const char* value=0 ) const; - - XMLElement* NextSiblingElement( const char* value=0 ) { - return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( value ) ); - } - - /** - Add a child node as the last (right) child. - If the child node is already part of the document, - it is moved from its old location to the new location. - Returns the addThis argument or 0 if the node does not - belong to the same document. - */ - XMLNode* InsertEndChild( XMLNode* addThis ); - - XMLNode* LinkEndChild( XMLNode* addThis ) { - return InsertEndChild( addThis ); - } - /** - Add a child node as the first (left) child. - If the child node is already part of the document, - it is moved from its old location to the new location. - Returns the addThis argument or 0 if the node does not - belong to the same document. - */ - XMLNode* InsertFirstChild( XMLNode* addThis ); - /** - Add a node after the specified child node. - If the child node is already part of the document, - it is moved from its old location to the new location. - Returns the addThis argument or 0 if the afterThis node - is not a child of this node, or if the node does not - belong to the same document. - */ - XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis ); - - /** - Delete all the children of this node. - */ - void DeleteChildren(); - - /** - Delete a child of this node. - */ - void DeleteChild( XMLNode* node ); - - /** - Make a copy of this node, but not its children. - You may pass in a Document pointer that will be - the owner of the new Node. If the 'document' is - null, then the node returned will be allocated - from the current Document. (this->GetDocument()) - - Note: if called on a XMLDocument, this will return null. - */ - virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0; - - /** - Test if 2 nodes are the same, but don't test children. - The 2 nodes do not need to be in the same Document. - - Note: if called on a XMLDocument, this will return false. - */ - virtual bool ShallowEqual( const XMLNode* compare ) const = 0; - - /** Accept a hierarchical visit of the nodes in the TinyXML-2 DOM. Every node in the - XML tree will be conditionally visited and the host will be called back - via the XMLVisitor interface. - - This is essentially a SAX interface for TinyXML-2. (Note however it doesn't re-parse - the XML for the callbacks, so the performance of TinyXML-2 is unchanged by using this - interface versus any other.) - - The interface has been based on ideas from: - - - http://www.saxproject.org/ - - http://c2.com/cgi/wiki?HierarchicalVisitorPattern - - Which are both good references for "visiting". - - An example of using Accept(): - @verbatim - XMLPrinter printer; - tinyxmlDoc.Accept( &printer ); - const char* xmlcstr = printer.CStr(); - @endverbatim - */ - virtual bool Accept( XMLVisitor* visitor ) const = 0; - - // internal - virtual char* ParseDeep( char*, StrPair* ); - -protected: - XMLNode( XMLDocument* ); - virtual ~XMLNode(); - XMLNode( const XMLNode& ); // not supported - XMLNode& operator=( const XMLNode& ); // not supported - - XMLDocument* _document; - XMLNode* _parent; - mutable StrPair _value; - - XMLNode* _firstChild; - XMLNode* _lastChild; - - XMLNode* _prev; - XMLNode* _next; - -private: - MemPool* _memPool; - void Unlink( XMLNode* child ); -}; - - -/** XML text. - - Note that a text node can have child element nodes, for example: - @verbatim - <root>This is <b>bold</b></root> - @endverbatim - - A text node can have 2 ways to output the next. "normal" output - and CDATA. It will default to the mode it was parsed from the XML file and - you generally want to leave it alone, but you can change the output mode with - SetCData() and query it with CData(). -*/ -class TINYXML2_LIB XMLText : public XMLNode -{ - friend class XMLBase; - friend class XMLDocument; -public: - virtual bool Accept( XMLVisitor* visitor ) const; - - virtual XMLText* ToText() { - return this; - } - virtual const XMLText* ToText() const { - return this; - } - - /// Declare whether this should be CDATA or standard text. - void SetCData( bool isCData ) { - _isCData = isCData; - } - /// Returns true if this is a CDATA text element. - bool CData() const { - return _isCData; - } - - char* ParseDeep( char*, StrPair* endTag ); - virtual XMLNode* ShallowClone( XMLDocument* document ) const; - virtual bool ShallowEqual( const XMLNode* compare ) const; - -protected: - XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {} - virtual ~XMLText() {} - XMLText( const XMLText& ); // not supported - XMLText& operator=( const XMLText& ); // not supported - -private: - bool _isCData; -}; - - -/** An XML Comment. */ -class TINYXML2_LIB XMLComment : public XMLNode -{ - friend class XMLDocument; -public: - virtual XMLComment* ToComment() { - return this; - } - virtual const XMLComment* ToComment() const { - return this; - } - - virtual bool Accept( XMLVisitor* visitor ) const; - - char* ParseDeep( char*, StrPair* endTag ); - virtual XMLNode* ShallowClone( XMLDocument* document ) const; - virtual bool ShallowEqual( const XMLNode* compare ) const; - -protected: - XMLComment( XMLDocument* doc ); - virtual ~XMLComment(); - XMLComment( const XMLComment& ); // not supported - XMLComment& operator=( const XMLComment& ); // not supported - -private: -}; - - -/** In correct XML the declaration is the first entry in the file. - @verbatim - <?xml version="1.0" standalone="yes"?> - @endverbatim - - TinyXML-2 will happily read or write files without a declaration, - however. - - The text of the declaration isn't interpreted. It is parsed - and written as a string. -*/ -class TINYXML2_LIB XMLDeclaration : public XMLNode -{ - friend class XMLDocument; -public: - virtual XMLDeclaration* ToDeclaration() { - return this; - } - virtual const XMLDeclaration* ToDeclaration() const { - return this; - } - - virtual bool Accept( XMLVisitor* visitor ) const; - - char* ParseDeep( char*, StrPair* endTag ); - virtual XMLNode* ShallowClone( XMLDocument* document ) const; - virtual bool ShallowEqual( const XMLNode* compare ) const; - -protected: - XMLDeclaration( XMLDocument* doc ); - virtual ~XMLDeclaration(); - XMLDeclaration( const XMLDeclaration& ); // not supported - XMLDeclaration& operator=( const XMLDeclaration& ); // not supported -}; - - -/** Any tag that TinyXML-2 doesn't recognize is saved as an - unknown. It is a tag of text, but should not be modified. - It will be written back to the XML, unchanged, when the file - is saved. - - DTD tags get thrown into XMLUnknowns. -*/ -class TINYXML2_LIB XMLUnknown : public XMLNode -{ - friend class XMLDocument; -public: - virtual XMLUnknown* ToUnknown() { - return this; - } - virtual const XMLUnknown* ToUnknown() const { - return this; - } - - virtual bool Accept( XMLVisitor* visitor ) const; - - char* ParseDeep( char*, StrPair* endTag ); - virtual XMLNode* ShallowClone( XMLDocument* document ) const; - virtual bool ShallowEqual( const XMLNode* compare ) const; - -protected: - XMLUnknown( XMLDocument* doc ); - virtual ~XMLUnknown(); - XMLUnknown( const XMLUnknown& ); // not supported - XMLUnknown& operator=( const XMLUnknown& ); // not supported -}; - - -enum XMLError { - XML_NO_ERROR = 0, - XML_SUCCESS = 0, - - XML_NO_ATTRIBUTE, - XML_WRONG_ATTRIBUTE_TYPE, - - XML_ERROR_FILE_NOT_FOUND, - XML_ERROR_FILE_COULD_NOT_BE_OPENED, - XML_ERROR_FILE_READ_ERROR, - XML_ERROR_ELEMENT_MISMATCH, - XML_ERROR_PARSING_ELEMENT, - XML_ERROR_PARSING_ATTRIBUTE, - XML_ERROR_IDENTIFYING_TAG, - XML_ERROR_PARSING_TEXT, - XML_ERROR_PARSING_CDATA, - XML_ERROR_PARSING_COMMENT, - XML_ERROR_PARSING_DECLARATION, - XML_ERROR_PARSING_UNKNOWN, - XML_ERROR_EMPTY_DOCUMENT, - XML_ERROR_MISMATCHED_ELEMENT, - XML_ERROR_PARSING, - - XML_CAN_NOT_CONVERT_TEXT, - XML_NO_TEXT_NODE -}; - - -/** An attribute is a name-value pair. Elements have an arbitrary - number of attributes, each with a unique name. - - @note The attributes are not XMLNodes. You may only query the - Next() attribute in a list. -*/ -class TINYXML2_LIB XMLAttribute -{ - friend class XMLElement; -public: - /// The name of the attribute. - const char* Name() const; - - /// The value of the attribute. - const char* Value() const; - - /// The next attribute in the list. - const XMLAttribute* Next() const { - return _next; - } - - /** IntValue interprets the attribute as an integer, and returns the value. - If the value isn't an integer, 0 will be returned. There is no error checking; - use QueryIntValue() if you need error checking. - */ - int IntValue() const { - int i=0; - QueryIntValue( &i ); - return i; - } - /// Query as an unsigned integer. See IntValue() - unsigned UnsignedValue() const { - unsigned i=0; - QueryUnsignedValue( &i ); - return i; - } - /// Query as a boolean. See IntValue() - bool BoolValue() const { - bool b=false; - QueryBoolValue( &b ); - return b; - } - /// Query as a double. See IntValue() - double DoubleValue() const { - double d=0; - QueryDoubleValue( &d ); - return d; - } - /// Query as a float. See IntValue() - float FloatValue() const { - float f=0; - QueryFloatValue( &f ); - return f; - } - - /** QueryIntValue interprets the attribute as an integer, and returns the value - in the provided parameter. The function will return XML_NO_ERROR on success, - and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful. - */ - XMLError QueryIntValue( int* value ) const; - /// See QueryIntValue - XMLError QueryUnsignedValue( unsigned int* value ) const; - /// See QueryIntValue - XMLError QueryBoolValue( bool* value ) const; - /// See QueryIntValue - XMLError QueryDoubleValue( double* value ) const; - /// See QueryIntValue - XMLError QueryFloatValue( float* value ) const; - - /// Set the attribute to a string value. - void SetAttribute( const char* value ); - /// Set the attribute to value. - void SetAttribute( int value ); - /// Set the attribute to value. - void SetAttribute( unsigned value ); - /// Set the attribute to value. - void SetAttribute( bool value ); - /// Set the attribute to value. - void SetAttribute( double value ); - /// Set the attribute to value. - void SetAttribute( float value ); - -private: - enum { BUF_SIZE = 200 }; - - XMLAttribute() : _next( 0 ), _memPool( 0 ) {} - virtual ~XMLAttribute() {} - - XMLAttribute( const XMLAttribute& ); // not supported - void operator=( const XMLAttribute& ); // not supported - void SetName( const char* name ); - - char* ParseDeep( char* p, bool processEntities ); - - mutable StrPair _name; - mutable StrPair _value; - XMLAttribute* _next; - MemPool* _memPool; -}; - - -/** The element is a container class. It has a value, the element name, - and can contain other elements, text, comments, and unknowns. - Elements also contain an arbitrary number of attributes. -*/ -class TINYXML2_LIB XMLElement : public XMLNode -{ - friend class XMLBase; - friend class XMLDocument; -public: - /// Get the name of an element (which is the Value() of the node.) - const char* Name() const { - return Value(); - } - /// Set the name of the element. - void SetName( const char* str, bool staticMem=false ) { - SetValue( str, staticMem ); - } - - virtual XMLElement* ToElement() { - return this; - } - virtual const XMLElement* ToElement() const { - return this; - } - virtual bool Accept( XMLVisitor* visitor ) const; - - /** Given an attribute name, Attribute() returns the value - for the attribute of that name, or null if none - exists. For example: - - @verbatim - const char* value = ele->Attribute( "foo" ); - @endverbatim - - The 'value' parameter is normally null. However, if specified, - the attribute will only be returned if the 'name' and 'value' - match. This allow you to write code: - - @verbatim - if ( ele->Attribute( "foo", "bar" ) ) callFooIsBar(); - @endverbatim - - rather than: - @verbatim - if ( ele->Attribute( "foo" ) ) { - if ( strcmp( ele->Attribute( "foo" ), "bar" ) == 0 ) callFooIsBar(); - } - @endverbatim - */ - const char* Attribute( const char* name, const char* value=0 ) const; - - /** Given an attribute name, IntAttribute() returns the value - of the attribute interpreted as an integer. 0 will be - returned if there is an error. For a method with error - checking, see QueryIntAttribute() - */ - int IntAttribute( const char* name ) const { - int i=0; - QueryIntAttribute( name, &i ); - return i; - } - /// See IntAttribute() - unsigned UnsignedAttribute( const char* name ) const { - unsigned i=0; - QueryUnsignedAttribute( name, &i ); - return i; - } - /// See IntAttribute() - bool BoolAttribute( const char* name ) const { - bool b=false; - QueryBoolAttribute( name, &b ); - return b; - } - /// See IntAttribute() - double DoubleAttribute( const char* name ) const { - double d=0; - QueryDoubleAttribute( name, &d ); - return d; - } - /// See IntAttribute() - float FloatAttribute( const char* name ) const { - float f=0; - QueryFloatAttribute( name, &f ); - return f; - } - - /** Given an attribute name, QueryIntAttribute() returns - XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion - can't be performed, or XML_NO_ATTRIBUTE if the attribute - doesn't exist. If successful, the result of the conversion - will be written to 'value'. If not successful, nothing will - be written to 'value'. This allows you to provide default - value: - - @verbatim - int value = 10; - QueryIntAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10 - @endverbatim - */ - XMLError QueryIntAttribute( const char* name, int* value ) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return XML_NO_ATTRIBUTE; - } - return a->QueryIntValue( value ); - } - /// See QueryIntAttribute() - XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return XML_NO_ATTRIBUTE; - } - return a->QueryUnsignedValue( value ); - } - /// See QueryIntAttribute() - XMLError QueryBoolAttribute( const char* name, bool* value ) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return XML_NO_ATTRIBUTE; - } - return a->QueryBoolValue( value ); - } - /// See QueryIntAttribute() - XMLError QueryDoubleAttribute( const char* name, double* value ) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return XML_NO_ATTRIBUTE; - } - return a->QueryDoubleValue( value ); - } - /// See QueryIntAttribute() - XMLError QueryFloatAttribute( const char* name, float* value ) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return XML_NO_ATTRIBUTE; - } - return a->QueryFloatValue( value ); - } - - - /** Given an attribute name, QueryAttribute() returns - XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion - can't be performed, or XML_NO_ATTRIBUTE if the attribute - doesn't exist. It is overloaded for the primitive types, - and is a generally more convenient replacement of - QueryIntAttribute() and related functions. - - If successful, the result of the conversion - will be written to 'value'. If not successful, nothing will - be written to 'value'. This allows you to provide default - value: - - @verbatim - int value = 10; - QueryAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10 - @endverbatim - */ - int QueryAttribute( const char* name, int* value ) const { - return QueryIntAttribute( name, value ); - } - - int QueryAttribute( const char* name, unsigned int* value ) const { - return QueryUnsignedAttribute( name, value ); - } - - int QueryAttribute( const char* name, bool* value ) const { - return QueryBoolAttribute( name, value ); - } - - int QueryAttribute( const char* name, double* value ) const { - return QueryDoubleAttribute( name, value ); - } - - int QueryAttribute( const char* name, float* value ) const { - return QueryFloatAttribute( name, value ); - } - - /// Sets the named attribute to value. - void SetAttribute( const char* name, const char* value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - /// Sets the named attribute to value. - void SetAttribute( const char* name, int value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - /// Sets the named attribute to value. - void SetAttribute( const char* name, unsigned value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - /// Sets the named attribute to value. - void SetAttribute( const char* name, bool value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - /// Sets the named attribute to value. - void SetAttribute( const char* name, double value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - /// Sets the named attribute to value. - void SetAttribute( const char* name, float value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - - /** - Delete an attribute. - */ - void DeleteAttribute( const char* name ); - - /// Return the first attribute in the list. - const XMLAttribute* FirstAttribute() const { - return _rootAttribute; - } - /// Query a specific attribute in the list. - const XMLAttribute* FindAttribute( const char* name ) const; - - /** Convenience function for easy access to the text inside an element. Although easy - and concise, GetText() is limited compared to getting the XMLText child - and accessing it directly. - - If the first child of 'this' is a XMLText, the GetText() - returns the character string of the Text node, else null is returned. - - This is a convenient method for getting the text of simple contained text: - @verbatim - <foo>This is text</foo> - const char* str = fooElement->GetText(); - @endverbatim - - 'str' will be a pointer to "This is text". - - Note that this function can be misleading. If the element foo was created from - this XML: - @verbatim - <foo><b>This is text</b></foo> - @endverbatim - - then the value of str would be null. The first child node isn't a text node, it is - another element. From this XML: - @verbatim - <foo>This is <b>text</b></foo> - @endverbatim - GetText() will return "This is ". - */ - const char* GetText() const; - - /** Convenience function for easy access to the text inside an element. Although easy - and concise, SetText() is limited compared to creating an XMLText child - and mutating it directly. - - If the first child of 'this' is a XMLText, SetText() sets its value to - the given string, otherwise it will create a first child that is an XMLText. - - This is a convenient method for setting the text of simple contained text: - @verbatim - <foo>This is text</foo> - fooElement->SetText( "Hullaballoo!" ); - <foo>Hullaballoo!</foo> - @endverbatim - - Note that this function can be misleading. If the element foo was created from - this XML: - @verbatim - <foo><b>This is text</b></foo> - @endverbatim - - then it will not change "This is text", but rather prefix it with a text element: - @verbatim - <foo>Hullaballoo!<b>This is text</b></foo> - @endverbatim - - For this XML: - @verbatim - <foo /> - @endverbatim - SetText() will generate - @verbatim - <foo>Hullaballoo!</foo> - @endverbatim - */ - void SetText( const char* inText ); - /// Convenience method for setting text inside and element. See SetText() for important limitations. - void SetText( int value ); - /// Convenience method for setting text inside and element. See SetText() for important limitations. - void SetText( unsigned value ); - /// Convenience method for setting text inside and element. See SetText() for important limitations. - void SetText( bool value ); - /// Convenience method for setting text inside and element. See SetText() for important limitations. - void SetText( double value ); - /// Convenience method for setting text inside and element. See SetText() for important limitations. - void SetText( float value ); - - /** - Convenience method to query the value of a child text node. This is probably best - shown by example. Given you have a document is this form: - @verbatim - <point> - <x>1</x> - <y>1.4</y> - </point> - @endverbatim - - The QueryIntText() and similar functions provide a safe and easier way to get to the - "value" of x and y. - - @verbatim - int x = 0; - float y = 0; // types of x and y are contrived for example - const XMLElement* xElement = pointElement->FirstChildElement( "x" ); - const XMLElement* yElement = pointElement->FirstChildElement( "y" ); - xElement->QueryIntText( &x ); - yElement->QueryFloatText( &y ); - @endverbatim - - @returns XML_SUCCESS (0) on success, XML_CAN_NOT_CONVERT_TEXT if the text cannot be converted - to the requested type, and XML_NO_TEXT_NODE if there is no child text to query. - - */ - XMLError QueryIntText( int* ival ) const; - /// See QueryIntText() - XMLError QueryUnsignedText( unsigned* uval ) const; - /// See QueryIntText() - XMLError QueryBoolText( bool* bval ) const; - /// See QueryIntText() - XMLError QueryDoubleText( double* dval ) const; - /// See QueryIntText() - XMLError QueryFloatText( float* fval ) const; - - // internal: - enum { - OPEN, // <foo> - CLOSED, // <foo/> - CLOSING // </foo> - }; - int ClosingType() const { - return _closingType; - } - char* ParseDeep( char* p, StrPair* endTag ); - virtual XMLNode* ShallowClone( XMLDocument* document ) const; - virtual bool ShallowEqual( const XMLNode* compare ) const; - -private: - XMLElement( XMLDocument* doc ); - virtual ~XMLElement(); - XMLElement( const XMLElement& ); // not supported - void operator=( const XMLElement& ); // not supported - - XMLAttribute* FindAttribute( const char* name ); - XMLAttribute* FindOrCreateAttribute( const char* name ); - //void LinkAttribute( XMLAttribute* attrib ); - char* ParseAttributes( char* p ); - - enum { BUF_SIZE = 200 }; - int _closingType; - // The attribute list is ordered; there is no 'lastAttribute' - // because the list needs to be scanned for dupes before adding - // a new attribute. - XMLAttribute* _rootAttribute; -}; - - -enum Whitespace { - PRESERVE_WHITESPACE, - COLLAPSE_WHITESPACE -}; - - -/** A Document binds together all the functionality. - It can be saved, loaded, and printed to the screen. - All Nodes are connected and allocated to a Document. - If the Document is deleted, all its Nodes are also deleted. -*/ -class TINYXML2_LIB XMLDocument : public XMLNode -{ - friend class XMLElement; -public: - /// constructor - XMLDocument( bool processEntities = true, Whitespace = PRESERVE_WHITESPACE ); - ~XMLDocument(); - - virtual XMLDocument* ToDocument() { - return this; - } - virtual const XMLDocument* ToDocument() const { - return this; - } - - /** - Parse an XML file from a character string. - Returns XML_NO_ERROR (0) on success, or - an errorID. - - You may optionally pass in the 'nBytes', which is - the number of bytes which will be parsed. If not - specified, TinyXML-2 will assume 'xml' points to a - null terminated string. - */ - XMLError Parse( const char* xml, size_t nBytes=(size_t)(-1) ); - - /** - Load an XML file from disk. - Returns XML_NO_ERROR (0) on success, or - an errorID. - */ - XMLError LoadFile( const char* filename ); - - /** - Load an XML file from disk. You are responsible - for providing and closing the FILE*. - - Returns XML_NO_ERROR (0) on success, or - an errorID. - */ - XMLError LoadFile( FILE* ); - - /** - Save the XML file to disk. - Returns XML_NO_ERROR (0) on success, or - an errorID. - */ - XMLError SaveFile( const char* filename, bool compact = false ); - - /** - Save the XML file to disk. You are responsible - for providing and closing the FILE*. - - Returns XML_NO_ERROR (0) on success, or - an errorID. - */ - XMLError SaveFile( FILE* fp, bool compact = false ); - - bool ProcessEntities() const { - return _processEntities; - } - Whitespace WhitespaceMode() const { - return _whitespace; - } - - /** - Returns true if this document has a leading Byte Order Mark of UTF8. - */ - bool HasBOM() const { - return _writeBOM; - } - /** Sets whether to write the BOM when writing the file. - */ - void SetBOM( bool useBOM ) { - _writeBOM = useBOM; - } - - /** Return the root element of DOM. Equivalent to FirstChildElement(). - To get the first node, use FirstChild(). - */ - XMLElement* RootElement() { - return FirstChildElement(); - } - const XMLElement* RootElement() const { - return FirstChildElement(); - } - - /** Print the Document. If the Printer is not provided, it will - print to stdout. If you provide Printer, this can print to a file: - @verbatim - XMLPrinter printer( fp ); - doc.Print( &printer ); - @endverbatim - - Or you can use a printer to print to memory: - @verbatim - XMLPrinter printer; - doc.Print( &printer ); - // printer.CStr() has a const char* to the XML - @endverbatim - */ - void Print( XMLPrinter* streamer=0 ) const; - virtual bool Accept( XMLVisitor* visitor ) const; - - /** - Create a new Element associated with - this Document. The memory for the Element - is managed by the Document. - */ - XMLElement* NewElement( const char* name ); - /** - Create a new Comment associated with - this Document. The memory for the Comment - is managed by the Document. - */ - XMLComment* NewComment( const char* comment ); - /** - Create a new Text associated with - this Document. The memory for the Text - is managed by the Document. - */ - XMLText* NewText( const char* text ); - /** - Create a new Declaration associated with - this Document. The memory for the object - is managed by the Document. - - If the 'text' param is null, the standard - declaration is used.: - @verbatim - <?xml version="1.0" encoding="UTF-8"?> - @endverbatim - */ - XMLDeclaration* NewDeclaration( const char* text=0 ); - /** - Create a new Unknown associated with - this Document. The memory for the object - is managed by the Document. - */ - XMLUnknown* NewUnknown( const char* text ); - - /** - Delete a node associated with this document. - It will be unlinked from the DOM. - */ - void DeleteNode( XMLNode* node ) { - node->_parent->DeleteChild( node ); - } - - void SetError( XMLError error, const char* str1, const char* str2 ); - - /// Return true if there was an error parsing the document. - bool Error() const { - return _errorID != XML_NO_ERROR; - } - /// Return the errorID. - XMLError ErrorID() const { - return _errorID; - } - /// Return a possibly helpful diagnostic location or string. - const char* GetErrorStr1() const { - return _errorStr1; - } - /// Return a possibly helpful secondary diagnostic location or string. - const char* GetErrorStr2() const { - return _errorStr2; - } - /// If there is an error, print it to stdout. - void PrintError() const; - - /// Clear the document, resetting it to the initial state. - void Clear(); - - // internal - char* Identify( char* p, XMLNode** node ); - - virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const { - return 0; - } - virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const { - return false; - } - -private: - XMLDocument( const XMLDocument& ); // not supported - void operator=( const XMLDocument& ); // not supported - - bool _writeBOM; - bool _processEntities; - XMLError _errorID; - Whitespace _whitespace; - const char* _errorStr1; - const char* _errorStr2; - char* _charBuffer; - - MemPoolT< sizeof(XMLElement) > _elementPool; - MemPoolT< sizeof(XMLAttribute) > _attributePool; - MemPoolT< sizeof(XMLText) > _textPool; - MemPoolT< sizeof(XMLComment) > _commentPool; -}; - - -/** - A XMLHandle is a class that wraps a node pointer with null checks; this is - an incredibly useful thing. Note that XMLHandle is not part of the TinyXML-2 - DOM structure. It is a separate utility class. - - Take an example: - @verbatim - <Document> - <Element attributeA = "valueA"> - <Child attributeB = "value1" /> - <Child attributeB = "value2" /> - </Element> - </Document> - @endverbatim - - Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very - easy to write a *lot* of code that looks like: - - @verbatim - XMLElement* root = document.FirstChildElement( "Document" ); - if ( root ) - { - XMLElement* element = root->FirstChildElement( "Element" ); - if ( element ) - { - XMLElement* child = element->FirstChildElement( "Child" ); - if ( child ) - { - XMLElement* child2 = child->NextSiblingElement( "Child" ); - if ( child2 ) - { - // Finally do something useful. - @endverbatim - - And that doesn't even cover "else" cases. XMLHandle addresses the verbosity - of such code. A XMLHandle checks for null pointers so it is perfectly safe - and correct to use: - - @verbatim - XMLHandle docHandle( &document ); - XMLElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild().NextSibling().ToElement(); - if ( child2 ) - { - // do something useful - @endverbatim - - Which is MUCH more concise and useful. - - It is also safe to copy handles - internally they are nothing more than node pointers. - @verbatim - XMLHandle handleCopy = handle; - @endverbatim - - See also XMLConstHandle, which is the same as XMLHandle, but operates on const objects. -*/ -class TINYXML2_LIB XMLHandle -{ -public: - /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. - XMLHandle( XMLNode* node ) { - _node = node; - } - /// Create a handle from a node. - XMLHandle( XMLNode& node ) { - _node = &node; - } - /// Copy constructor - XMLHandle( const XMLHandle& ref ) { - _node = ref._node; - } - /// Assignment - XMLHandle& operator=( const XMLHandle& ref ) { - _node = ref._node; - return *this; - } - - /// Get the first child of this handle. - XMLHandle FirstChild() { - return XMLHandle( _node ? _node->FirstChild() : 0 ); - } - /// Get the first child element of this handle. - XMLHandle FirstChildElement( const char* value=0 ) { - return XMLHandle( _node ? _node->FirstChildElement( value ) : 0 ); - } - /// Get the last child of this handle. - XMLHandle LastChild() { - return XMLHandle( _node ? _node->LastChild() : 0 ); - } - /// Get the last child element of this handle. - XMLHandle LastChildElement( const char* _value=0 ) { - return XMLHandle( _node ? _node->LastChildElement( _value ) : 0 ); - } - /// Get the previous sibling of this handle. - XMLHandle PreviousSibling() { - return XMLHandle( _node ? _node->PreviousSibling() : 0 ); - } - /// Get the previous sibling element of this handle. - XMLHandle PreviousSiblingElement( const char* _value=0 ) { - return XMLHandle( _node ? _node->PreviousSiblingElement( _value ) : 0 ); - } - /// Get the next sibling of this handle. - XMLHandle NextSibling() { - return XMLHandle( _node ? _node->NextSibling() : 0 ); - } - /// Get the next sibling element of this handle. - XMLHandle NextSiblingElement( const char* _value=0 ) { - return XMLHandle( _node ? _node->NextSiblingElement( _value ) : 0 ); - } - - /// Safe cast to XMLNode. This can return null. - XMLNode* ToNode() { - return _node; - } - /// Safe cast to XMLElement. This can return null. - XMLElement* ToElement() { - return ( ( _node && _node->ToElement() ) ? _node->ToElement() : 0 ); - } - /// Safe cast to XMLText. This can return null. - XMLText* ToText() { - return ( ( _node && _node->ToText() ) ? _node->ToText() : 0 ); - } - /// Safe cast to XMLUnknown. This can return null. - XMLUnknown* ToUnknown() { - return ( ( _node && _node->ToUnknown() ) ? _node->ToUnknown() : 0 ); - } - /// Safe cast to XMLDeclaration. This can return null. - XMLDeclaration* ToDeclaration() { - return ( ( _node && _node->ToDeclaration() ) ? _node->ToDeclaration() : 0 ); - } - -private: - XMLNode* _node; -}; - - -/** - A variant of the XMLHandle class for working with const XMLNodes and Documents. It is the - same in all regards, except for the 'const' qualifiers. See XMLHandle for API. -*/ -class TINYXML2_LIB XMLConstHandle -{ -public: - XMLConstHandle( const XMLNode* node ) { - _node = node; - } - XMLConstHandle( const XMLNode& node ) { - _node = &node; - } - XMLConstHandle( const XMLConstHandle& ref ) { - _node = ref._node; - } - - XMLConstHandle& operator=( const XMLConstHandle& ref ) { - _node = ref._node; - return *this; - } - - const XMLConstHandle FirstChild() const { - return XMLConstHandle( _node ? _node->FirstChild() : 0 ); - } - const XMLConstHandle FirstChildElement( const char* value=0 ) const { - return XMLConstHandle( _node ? _node->FirstChildElement( value ) : 0 ); - } - const XMLConstHandle LastChild() const { - return XMLConstHandle( _node ? _node->LastChild() : 0 ); - } - const XMLConstHandle LastChildElement( const char* _value=0 ) const { - return XMLConstHandle( _node ? _node->LastChildElement( _value ) : 0 ); - } - const XMLConstHandle PreviousSibling() const { - return XMLConstHandle( _node ? _node->PreviousSibling() : 0 ); - } - const XMLConstHandle PreviousSiblingElement( const char* _value=0 ) const { - return XMLConstHandle( _node ? _node->PreviousSiblingElement( _value ) : 0 ); - } - const XMLConstHandle NextSibling() const { - return XMLConstHandle( _node ? _node->NextSibling() : 0 ); - } - const XMLConstHandle NextSiblingElement( const char* _value=0 ) const { - return XMLConstHandle( _node ? _node->NextSiblingElement( _value ) : 0 ); - } - - - const XMLNode* ToNode() const { - return _node; - } - const XMLElement* ToElement() const { - return ( ( _node && _node->ToElement() ) ? _node->ToElement() : 0 ); - } - const XMLText* ToText() const { - return ( ( _node && _node->ToText() ) ? _node->ToText() : 0 ); - } - const XMLUnknown* ToUnknown() const { - return ( ( _node && _node->ToUnknown() ) ? _node->ToUnknown() : 0 ); - } - const XMLDeclaration* ToDeclaration() const { - return ( ( _node && _node->ToDeclaration() ) ? _node->ToDeclaration() : 0 ); - } - -private: - const XMLNode* _node; -}; - - -/** - Printing functionality. The XMLPrinter gives you more - options than the XMLDocument::Print() method. - - It can: - -# Print to memory. - -# Print to a file you provide. - -# Print XML without a XMLDocument. - - Print to Memory - - @verbatim - XMLPrinter printer; - doc.Print( &printer ); - SomeFunction( printer.CStr() ); - @endverbatim - - Print to a File - - You provide the file pointer. - @verbatim - XMLPrinter printer( fp ); - doc.Print( &printer ); - @endverbatim - - Print without a XMLDocument - - When loading, an XML parser is very useful. However, sometimes - when saving, it just gets in the way. The code is often set up - for streaming, and constructing the DOM is just overhead. - - The Printer supports the streaming case. The following code - prints out a trivially simple XML file without ever creating - an XML document. - - @verbatim - XMLPrinter printer( fp ); - printer.OpenElement( "foo" ); - printer.PushAttribute( "foo", "bar" ); - printer.CloseElement(); - @endverbatim -*/ -class TINYXML2_LIB XMLPrinter : public XMLVisitor -{ -public: - /** Construct the printer. If the FILE* is specified, - this will print to the FILE. Else it will print - to memory, and the result is available in CStr(). - If 'compact' is set to true, then output is created - with only required whitespace and newlines. - */ - XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 ); - virtual ~XMLPrinter() {} - - /** If streaming, write the BOM and declaration. */ - void PushHeader( bool writeBOM, bool writeDeclaration ); - /** If streaming, start writing an element. - The element must be closed with CloseElement() - */ - void OpenElement( const char* name, bool compactMode=false ); - /// If streaming, add an attribute to an open element. - void PushAttribute( const char* name, const char* value ); - void PushAttribute( const char* name, int value ); - void PushAttribute( const char* name, unsigned value ); - void PushAttribute( const char* name, bool value ); - void PushAttribute( const char* name, double value ); - /// If streaming, close the Element. - virtual void CloseElement( bool compactMode=false ); - - /// Add a text node. - void PushText( const char* text, bool cdata=false ); - /// Add a text node from an integer. - void PushText( int value ); - /// Add a text node from an unsigned. - void PushText( unsigned value ); - /// Add a text node from a bool. - void PushText( bool value ); - /// Add a text node from a float. - void PushText( float value ); - /// Add a text node from a double. - void PushText( double value ); - - /// Add a comment - void PushComment( const char* comment ); - - void PushDeclaration( const char* value ); - void PushUnknown( const char* value ); - - virtual bool VisitEnter( const XMLDocument& /*doc*/ ); - virtual bool VisitExit( const XMLDocument& /*doc*/ ) { - return true; - } - - virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute ); - virtual bool VisitExit( const XMLElement& element ); - - virtual bool Visit( const XMLText& text ); - virtual bool Visit( const XMLComment& comment ); - virtual bool Visit( const XMLDeclaration& declaration ); - virtual bool Visit( const XMLUnknown& unknown ); - - /** - If in print to memory mode, return a pointer to - the XML file in memory. - */ - const char* CStr() const { - return _buffer.Mem(); - } - /** - If in print to memory mode, return the size - of the XML file in memory. (Note the size returned - includes the terminating null.) - */ - int CStrSize() const { - return _buffer.Size(); - } - /** - If in print to memory mode, reset the buffer to the - beginning. - */ - void ClearBuffer() { - _buffer.Clear(); - _buffer.Push(0); - } - -protected: - virtual bool CompactMode( const XMLElement& ) { return _compactMode; } - - /** Prints out the space before an element. You may override to change - the space and tabs used. A PrintSpace() override should call Print(). - */ - virtual void PrintSpace( int depth ); - void Print( const char* format, ... ); - - void SealElement(); - bool _elementJustOpened; - DynArray< const char*, 10 > _stack; - -private: - void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities. - - bool _firstElement; - FILE* _fp; - int _depth; - int _textDepth; - bool _processEntities; - bool _compactMode; - - enum { - ENTITY_RANGE = 64, - BUF_SIZE = 200 - }; - bool _entityFlag[ENTITY_RANGE]; - bool _restrictedEntityFlag[ENTITY_RANGE]; - - DynArray< char, 20 > _buffer; -#ifdef _MSC_VER - DynArray< char, 20 > _accumulator; -#endif -}; - - -} // tinyxml2 - -#if defined(_MSC_VER) -# pragma warning(pop) -#endif - -#endif // TINYXML2_INCLUDED diff --git a/external/xgetopt/XGetopt.cpp b/external/xgetopt/XGetopt.cpp deleted file mode 100644 index 66c59eea..00000000 --- a/external/xgetopt/XGetopt.cpp +++ /dev/null @@ -1,219 +0,0 @@ -// XGetopt.cpp Version 1.2 -// -// Author: Hans Dietrich -// hdietrich2@hotmail.com -// -// Description: -// XGetopt.cpp implements getopt(), a function to parse command lines. -// -// History -// Version 1.2 - 2003 May 17 -// - Added Unicode support -// -// Version 1.1 - 2002 March 10 -// - Added example to XGetopt.cpp module header -// -// This software is released into the public domain. -// You are free to use it in any way you like. -// -// This software is provided "as is" with no expressed -// or implied warranty. I accept no liability for any -// damage or loss of business that this software may cause. -// -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// if you are using precompiled headers then include this line: -//#include "stdafx.h" -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// if you are not using precompiled headers then include these lines: -#include <windows.h> -#include <stdio.h> -//#include <tchar.h> -/////////////////////////////////////////////////////////////////////////////// - - -#include "XGetopt.h" - - -/////////////////////////////////////////////////////////////////////////////// -// -// X G e t o p t . c p p -// -// -// NAME -// getopt -- parse command line options -// -// SYNOPSIS -// int getopt(int argc, TCHAR *argv[], TCHAR *optstring) -// -// extern TCHAR *optarg; -// extern int optind; -// -// DESCRIPTION -// The getopt() function parses the command line arguments. Its -// arguments argc and argv are the argument count and array as -// passed into the application on program invocation. In the case -// of Visual C++ programs, argc and argv are available via the -// variables __argc and __argv (double underscores), respectively. -// getopt returns the next option letter in argv that matches a -// letter in optstring. (Note: Unicode programs should use -// __targv instead of __argv. Also, all character and string -// literals should be enclosed in _T( ) ). -// -// optstring is a string of recognized option letters; if a letter -// is followed by a colon, the option is expected to have an argument -// that may or may not be separated from it by white space. optarg -// is set to point to the start of the option argument on return from -// getopt. -// -// Option letters may be combined, e.g., "-ab" is equivalent to -// "-a -b". Option letters are case sensitive. -// -// getopt places in the external variable optind the argv index -// of the next argument to be processed. optind is initialized -// to 0 before the first call to getopt. -// -// When all options have been processed (i.e., up to the first -// non-option argument), getopt returns EOF, optarg will point -// to the argument, and optind will be set to the argv index of -// the argument. If there are no non-option arguments, optarg -// will be set to NULL. -// -// The special option "--" may be used to delimit the end of the -// options; EOF will be returned, and "--" (and everything after it) -// will be skipped. -// -// RETURN VALUE -// For option letters contained in the string optstring, getopt -// will return the option letter. getopt returns a question mark (?) -// when it encounters an option letter not included in optstring. -// EOF is returned when processing is finished. -// -// BUGS -// 1) Long options are not supported. -// 2) The GNU double-colon extension is not supported. -// 3) The environment variable POSIXLY_CORRECT is not supported. -// 4) The + syntax is not supported. -// 5) The automatic permutation of arguments is not supported. -// 6) This implementation of getopt() returns EOF if an error is -// encountered, instead of -1 as the latest standard requires. -// -// EXAMPLE -// BOOL CMyApp::ProcessCommandLine(int argc, TCHAR *argv[]) -// { -// int c; -// -// while ((c = getopt(argc, argv, _T("aBn:"))) != EOF) -// { -// switch (c) -// { -// case _T('a'): -// TRACE(_T("option a\n")); -// // -// // set some flag here -// // -// break; -// -// case _T('B'): -// TRACE( _T("option B\n")); -// // -// // set some other flag here -// // -// break; -// -// case _T('n'): -// TRACE(_T("option n: value=%d\n"), atoi(optarg)); -// // -// // do something with value here -// // -// break; -// -// case _T('?'): -// TRACE(_T("ERROR: illegal option %s\n"), argv[optind-1]); -// return FALSE; -// break; -// -// default: -// TRACE(_T("WARNING: no handler for option %c\n"), c); -// return FALSE; -// break; -// } -// } -// // -// // check for non-option args here -// // -// return TRUE; -// } -// -/////////////////////////////////////////////////////////////////////////////// - -char *optarg; // global argument pointer -int optind = 0; // global argv index - -int getopt(int argc, char *argv[], char *optstring) -{ - static char *next = NULL; - if (optind == 0) - next = NULL; - - optarg = NULL; - - if (next == NULL || *next == _T('\0')) - { - if (optind == 0) - optind++; - - if (optind >= argc || argv[optind][0] != _T('-') || argv[optind][1] == _T('\0')) - { - optarg = NULL; - if (optind < argc) - optarg = argv[optind]; - return EOF; - } - - if (_tcscmp(argv[optind], _T("--")) == 0) - { - optind++; - optarg = NULL; - if (optind < argc) - optarg = argv[optind]; - return EOF; - } - - next = argv[optind]; - next++; // skip past - - optind++; - } - - char c = *next++; - char *cp = _tcschr(optstring, c); - - if (cp == NULL || c == _T(':')) - return _T('?'); - - cp++; - if (*cp == _T(':')) - { - if (*next != _T('\0')) - { - optarg = next; - next = NULL; - } - else if (optind < argc) - { - optarg = argv[optind]; - optind++; - } - else - { - return _T('?'); - } - } - - return c; -} diff --git a/external/xgetopt/XGetopt.h b/external/xgetopt/XGetopt.h deleted file mode 100644 index fa6f6ad1..00000000 --- a/external/xgetopt/XGetopt.h +++ /dev/null @@ -1,23 +0,0 @@ -// XGetopt.h Version 1.2 -// -// Author: Hans Dietrich -// hdietrich2@hotmail.com -// -// This software is released into the public domain. -// You are free to use it in any way you like. -// -// This software is provided "as is" with no expressed -// or implied warranty. I accept no liability for any -// damage or loss of business that this software may cause. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef XGETOPT_H -#define XGETOPT_H - -extern int optind, opterr; -extern char *optarg; - -int getopt(int argc, char *argv[], char *optstring); - -#endif //XGETOPT_H diff --git a/hsolve/CMakeLists.txt b/hsolve/CMakeLists.txt index 427efb30..f3d6c4eb 100644 --- a/hsolve/CMakeLists.txt +++ b/hsolve/CMakeLists.txt @@ -1,8 +1,9 @@ -cmake_minimum_required(VERSION 2.6) -include_directories(../basecode ../utility ../kinetics ../external/debug) +cmake_minimum_required(VERSION 2.8) +include( ${CMAKE_CURRENT_SOURCE_DIR}/../CheckCXXCompiler.cmake) add_library(hsolve HSolveStruct.cpp HinesMatrix.cpp + Cell.cpp HSolvePassive.cpp RateLookup.cpp HSolveActive.cpp diff --git a/hsolve/Cell.cpp b/hsolve/Cell.cpp index 6a6eeb8d..ac811584 100644 --- a/hsolve/Cell.cpp +++ b/hsolve/Cell.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "../shell/Shell.h" #include "Cell.h" @@ -273,7 +273,7 @@ Id Cell::findCompt( Id cell ) } else { - dump("TODO", "TODO: Commented out code. "); + moose::showWarn( "TODO: Commented out code. "); Id curr = child.back(); #if 0 /* ----- #if 0 : If0Label_1 ----- */ @@ -286,7 +286,6 @@ Id Cell::findCompt( Id cell ) } #endif /* ----- #if 0 : If0Label_1 ----- */ - cstack.push_back( children( curr ) ); } } @@ -297,11 +296,10 @@ Id Cell::findCompt( Id cell ) void Cell::setupSolver( Id cell, Id seed ) const { Id solver = Id::nextId(); - dump("FIXME" - , "Using 0 for parentMsgIndex in function call Shell::innerCreate" + moose::showWarn( + "FIXME: Using 0 for parentMsgIndex in function call Shell::innerCreate" "0 in first and third argument to NodeBalance. " "I am not sure if I should be doing this here in this function." - " -- Dilawar" ); NodeBalance nb(0, MooseBlockBalance, 0); shell_->innerCreate("HSolve", cell, solver, solverName_, nb, 0); diff --git a/hsolve/HSolve.cpp b/hsolve/HSolve.cpp index 7f3cc36b..5d04a777 100644 --- a/hsolve/HSolve.cpp +++ b/hsolve/HSolve.cpp @@ -9,7 +9,7 @@ #include "../basecode/header.h" #include "../basecode/global.h" -#include "ElementValueFinfo.h" +#include "../basecode/ElementValueFinfo.h" #include "HSolveStruct.h" #include "HinesMatrix.h" #include "HSolvePassive.h" diff --git a/hsolve/HSolveActive.cpp b/hsolve/HSolveActive.cpp index ebc62b34..662c4cc8 100644 --- a/hsolve/HSolveActive.cpp +++ b/hsolve/HSolveActive.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include <queue> #include "HSolveStruct.h" #include "HinesMatrix.h" @@ -92,7 +92,8 @@ void HSolveActive::updateMatrix() if ( HJ_.size() != 0 ) memcpy( &HJ_[ 0 ], &HJCopy_[ 0 ], sizeof( double ) * HJ_.size() ); - double GkSum, GkEkSum; vector< CurrentStruct >::iterator icurrent = current_.begin(); + double GkSum, GkEkSum; + vector< CurrentStruct >::iterator icurrent = current_.begin(); vector< currentVecIter >::iterator iboundary = currentBoundary_.begin(); vector< double >::iterator ihs = HS_.begin(); vector< double >::iterator iv = V_.begin(); @@ -232,7 +233,7 @@ void HSolveActive::advanceChannels( double dt ) LookupRow vRow; LookupRow dRow; - double C1, C2; + double C1 = 0.0, C2 = 0.0; for ( iv = V_.begin(); iv != V_.end(); ++iv ) { @@ -258,7 +259,7 @@ void HSolveActive::advanceChannels( double dt ) for ( ; ichan < chanBoundary; ++ichan ) { - caTable_.row( *iextca, dRow ); + caTable_.row( *iextca, dRow ); if ( ichan->Xpower_ > 0.0 ) { @@ -288,7 +289,7 @@ void HSolveActive::advanceChannels( double dt ) double temp = 1.0 + dt / 2.0 * C2; *istate = ( *istate * ( 2.0 - temp ) + dt * C1 ) / temp; -} + } ++icolumn, ++istate; } @@ -301,14 +302,13 @@ void HSolveActive::advanceChannels( double dt ) caTable_.lookup( *icolumn, *caRow, C1, C2 ); } - else if (*iextca >0) - - { - caTable_.lookup( *icolumn, dRow, C1, C2 ); - } - else + else if (*iextca >0) + { + caTable_.lookup( *icolumn, dRow, C1, C2 ); + } + else { - vTable_.lookup( *icolumn, vRow, C1, C2 ); + vTable_.lookup( *icolumn, vRow, C1, C2 ); } @@ -325,7 +325,7 @@ void HSolveActive::advanceChannels( double dt ) ++icolumn, ++istate, ++icarow; } - ++iextca; + ++iextca; } ++ichannelcount, ++icacount; @@ -356,22 +356,24 @@ void HSolveActive::sendValues( ProcPtr info ) { vector< unsigned int >::iterator i; - for ( i = outVm_.begin(); i != outVm_.end(); ++i ) { + for ( i = outVm_.begin(); i != outVm_.end(); ++i ) + { Compartment::VmOut()->send( //~ ZombieCompartment::VmOut()->send( compartmentId_[ *i ].eref(), V_[ *i ] ); - } + } - for ( i = outIk_.begin(); i != outIk_.end(); ++i ){ + for ( i = outIk_.begin(); i != outIk_.end(); ++i ) + { unsigned int comptIndex = chan2compt_[ *i ]; assert( comptIndex < V_.size() ); ChanBase::IkOut()->send(channelId_[*i].eref(), - (current_[ *i ].Ek - V_[ comptIndex ]) * current_[ *i ].Gk); + (current_[ *i ].Ek - V_[ comptIndex ]) * current_[ *i ].Gk); } diff --git a/hsolve/HSolveInterface.cpp b/hsolve/HSolveInterface.cpp index 5a8e8e3c..548646dd 100644 --- a/hsolve/HSolveInterface.cpp +++ b/hsolve/HSolveInterface.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "HSolveStruct.h" #include "HinesMatrix.h" #include "HSolvePassive.h" diff --git a/hsolve/HSolveStruct.cpp b/hsolve/HSolveStruct.cpp index 11daa9e5..ce40817c 100644 --- a/hsolve/HSolveStruct.cpp +++ b/hsolve/HSolveStruct.cpp @@ -8,7 +8,7 @@ **********************************************************************/ #include <cmath> -#include "header.h" +#include "../basecode/header.h" #include "../biophysics/SpikeGen.h" #include "HSolveStruct.h" diff --git a/hsolve/HinesMatrix.cpp b/hsolve/HinesMatrix.cpp index 47b12009..66d51dbf 100644 --- a/hsolve/HinesMatrix.cpp +++ b/hsolve/HinesMatrix.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "HinesMatrix.h" #include <sstream> #include <iomanip> diff --git a/hsolve/ZombieCaConc.cpp b/hsolve/ZombieCaConc.cpp index e7d18d2c..5e55f5bc 100644 --- a/hsolve/ZombieCaConc.cpp +++ b/hsolve/ZombieCaConc.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "../biophysics/CaConcBase.h" #include "HinesMatrix.h" diff --git a/hsolve/ZombieCompartment.h b/hsolve/ZombieCompartment.h index 507b602c..e4ef5ca4 100644 --- a/hsolve/ZombieCompartment.h +++ b/hsolve/ZombieCompartment.h @@ -11,10 +11,10 @@ #ifndef _ZOMBIE_COMPARTMENT_H #define _ZOMBIE_COMPARTMENT_H -#include "global.h" +#include "../basecode/global.h" -#include "header.h" -#include "ElementValueFinfo.h" +#include "../basecode/header.h" +#include "../basecode/ElementValueFinfo.h" #include "../utility/print_function.hpp" #include "../biophysics/CompartmentBase.h" #include "../biophysics/Compartment.h" diff --git a/hsolve/ZombieHHChannel.h b/hsolve/ZombieHHChannel.h index 756a2eaa..98bdf41c 100644 --- a/hsolve/ZombieHHChannel.h +++ b/hsolve/ZombieHHChannel.h @@ -29,8 +29,8 @@ * respectively. */ -#include "header.h" -#include "ElementValueFinfo.h" +#include "../basecode/header.h" +#include "../basecode/ElementValueFinfo.h" #include "HinesMatrix.h" #include "HSolveStruct.h" #include "HSolvePassive.h" diff --git a/intfire/AdExIF.cpp b/intfire/AdExIF.cpp index f9fddfa5..8b714bd4 100644 --- a/intfire/AdExIF.cpp +++ b/intfire/AdExIF.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" diff --git a/intfire/AdThreshIF.cpp b/intfire/AdThreshIF.cpp index 064f4511..a5805460 100644 --- a/intfire/AdThreshIF.cpp +++ b/intfire/AdThreshIF.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" diff --git a/intfire/CMakeLists.txt b/intfire/CMakeLists.txt index 06435a8e..5bbddab9 100644 --- a/intfire/CMakeLists.txt +++ b/intfire/CMakeLists.txt @@ -1,5 +1,4 @@ cmake_minimum_required(VERSION 2.8) -include_directories(../basecode) -add_definitions( -std=c++11 ) +include( ${CMAKE_CURRENT_SOURCE_DIR}/../CheckCXXCompiler.cmake) file(GLOB SRC *.cpp) add_library(intfire ${SRC}) diff --git a/intfire/ExIF.cpp b/intfire/ExIF.cpp index dcde4431..65c1db04 100644 --- a/intfire/ExIF.cpp +++ b/intfire/ExIF.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" diff --git a/intfire/IzhIF.cpp b/intfire/IzhIF.cpp index 6359727e..15ce57ae 100644 --- a/intfire/IzhIF.cpp +++ b/intfire/IzhIF.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" diff --git a/intfire/QIF.cpp b/intfire/QIF.cpp index 62e4a85f..c3c4850f 100644 --- a/intfire/QIF.cpp +++ b/intfire/QIF.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" diff --git a/intfire/testIntFire.cpp b/intfire/testIntFire.cpp index ed1a15bb..9e9ddf90 100644 --- a/intfire/testIntFire.cpp +++ b/intfire/testIntFire.cpp @@ -8,7 +8,7 @@ **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "../shell/Shell.h" #include "../biophysics/CompartmentBase.h" #include "../biophysics/Compartment.h" diff --git a/kinetics/CMakeLists.txt b/kinetics/CMakeLists.txt index b836312c..cdd8315d 100644 --- a/kinetics/CMakeLists.txt +++ b/kinetics/CMakeLists.txt @@ -1,20 +1,20 @@ -include_directories(../msg) -include_directories(../basecode ../utility) +cmake_minimum_required(VERSION 2.8) +include( ${CMAKE_CURRENT_SOURCE_DIR}/../CheckCXXCompiler.cmake) add_library(kinetics - PoolBase.cpp - Pool.cpp - BufPool.cpp - ReacBase.cpp - Reac.cpp - EnzBase.cpp - CplxEnzBase.cpp - Enz.cpp - MMenz.cpp - Species.cpp - ConcChan.cpp - ReadKkit.cpp - WriteKkit.cpp - ReadCspace.cpp - lookupVolumeFromMesh.cpp - testKinetics.cpp - ) + PoolBase.cpp + Pool.cpp + BufPool.cpp + ReacBase.cpp + Reac.cpp + EnzBase.cpp + CplxEnzBase.cpp + Enz.cpp + MMenz.cpp + Species.cpp + ConcChan.cpp + ReadKkit.cpp + WriteKkit.cpp + ReadCspace.cpp + lookupVolumeFromMesh.cpp + testKinetics.cpp + ) diff --git a/kinetics/ConcChan.cpp b/kinetics/ConcChan.cpp index 62170845..6edc7431 100644 --- a/kinetics/ConcChan.cpp +++ b/kinetics/ConcChan.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "ConcChan.h" static SrcFinfo2< double, double > *inPoolOut() { diff --git a/kinetics/CplxEnzBase.cpp b/kinetics/CplxEnzBase.cpp index 361f672f..36e23591 100644 --- a/kinetics/CplxEnzBase.cpp +++ b/kinetics/CplxEnzBase.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 "EnzBase.h" #include "CplxEnzBase.h" diff --git a/kinetics/Enz.cpp b/kinetics/Enz.cpp index f41d109a..358ab906 100644 --- a/kinetics/Enz.cpp +++ b/kinetics/Enz.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 "EnzBase.h" #include "CplxEnzBase.h" diff --git a/kinetics/EnzBase.cpp b/kinetics/EnzBase.cpp index 0812374c..68982016 100644 --- a/kinetics/EnzBase.cpp +++ b/kinetics/EnzBase.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 "EnzBase.h" diff --git a/kinetics/MMenz.cpp b/kinetics/MMenz.cpp index cd03b00f..af24152e 100644 --- a/kinetics/MMenz.cpp +++ b/kinetics/MMenz.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 "EnzBase.h" #include "MMenz.h" diff --git a/kinetics/PoolBase.cpp b/kinetics/PoolBase.cpp index b00153f4..bff5f026 100644 --- a/kinetics/PoolBase.cpp +++ b/kinetics/PoolBase.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" diff --git a/kinetics/Reac.cpp b/kinetics/Reac.cpp index 7e3bc72d..02de9aed 100644 --- a/kinetics/Reac.cpp +++ b/kinetics/Reac.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 "ReacBase.h" #include "Reac.h" diff --git a/kinetics/ReacBase.cpp b/kinetics/ReacBase.cpp index 0d3273d1..2ce128bd 100644 --- a/kinetics/ReacBase.cpp +++ b/kinetics/ReacBase.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 "ReacBase.h" diff --git a/kinetics/ReadCspace.cpp b/kinetics/ReadCspace.cpp index 86b1f3f0..ac60d9e4 100644 --- a/kinetics/ReadCspace.cpp +++ b/kinetics/ReadCspace.cpp @@ -8,7 +8,7 @@ **********************************************************************/ #include <fstream> -#include "header.h" +#include "../basecode/header.h" #include "../shell/Shell.h" #define DO_CSPACE_DEBUG 0 diff --git a/kinetics/ReadKkit.cpp b/kinetics/ReadKkit.cpp index 1a2e0776..01254b62 100644 --- a/kinetics/ReadKkit.cpp +++ b/kinetics/ReadKkit.cpp @@ -11,7 +11,7 @@ #include <iomanip> #include <fstream> -#include "header.h" +#include "../basecode/header.h" #include "../utility/utility.h" #include "PoolBase.h" #include "Pool.h" @@ -1195,6 +1195,7 @@ Id ReadKkit::buildChan( const vector< string >& args ) assert( chan != Id() ); string chanPath = clean.substr( 10 ); chanIds_[ chanPath ] = chan; + Id info = buildInfo( chan, chanMap_, args ); return chan; } diff --git a/kinetics/Species.cpp b/kinetics/Species.cpp index 1d579f9f..8229f752 100644 --- a/kinetics/Species.cpp +++ b/kinetics/Species.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "Species.h" static SrcFinfo1< double > *molWtOut() { diff --git a/kinetics/WriteKkit.cpp b/kinetics/WriteKkit.cpp index 3c3bc890..00917878 100644 --- a/kinetics/WriteKkit.cpp +++ b/kinetics/WriteKkit.cpp @@ -12,7 +12,7 @@ #include "../shell/Wildcard.h" -#include "header.h" +#include "../basecode/header.h" #include "../utility/utility.h" #include "PoolBase.h" diff --git a/kinetics/lookupVolumeFromMesh.cpp b/kinetics/lookupVolumeFromMesh.cpp index 84f9ebf9..e0457b6b 100644 --- a/kinetics/lookupVolumeFromMesh.cpp +++ b/kinetics/lookupVolumeFromMesh.cpp @@ -7,13 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" -/* -#include "../mesh/VoxelJunction.h" -#include "../mesh/MeshEntry.h" -#include "../mesh/Boundary.h" -#include "../mesh/ChemCompt.h" -*/ +#include "../basecode/header.h" #include "lookupVolumeFromMesh.h" // Utility function: return the compartment in which the specified diff --git a/kinetics/testKinetics.cpp b/kinetics/testKinetics.cpp index b63e099c..b1252a22 100644 --- a/kinetics/testKinetics.cpp +++ b/kinetics/testKinetics.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "../shell/Shell.h" #include "ReadKkit.h" #include "ReadCspace.h" diff --git a/ksolve/CMakeLists.txt b/ksolve/CMakeLists.txt index f86c69c0..f5124aab 100644 --- a/ksolve/CMakeLists.txt +++ b/ksolve/CMakeLists.txt @@ -1,10 +1,19 @@ cmake_minimum_required(VERSION 2.8) include(CheckIncludeFileCXX) +include( ${CMAKE_CURRENT_SOURCE_DIR}/../CheckCXXCompiler.cmake) + +if(WITH_BOOST) + find_package(Boost REQUIRED COMPONENTS thread) + add_definitions( -DUSE_BOOST_ASYNC ) + if("${CMAKE_BUILD_TYPE}" STREQUAL "Release") + add_definitions( -UBOOST_UBLAS_TYPE_CHECK ) + else() + add_definitions( -DBOOST_UBLAS_TYPE_CHECK ) + endif() + set(WITH_BOOST_ODE ON) + include_directories( ${Boost_INCLUDE_DIRS} ) +endif() -include_directories(../builtins ../basecode ../utility ../kinetics) -include_directories(../ ) -include_directories(../mesh) -include_directories(../external/muparser/include ) IF(WITH_BOOST_ODE) check_include_file_cxx( ${Boost_INCLUDE_DIRS}/boost/numeric/odeint.hpp ODEINT_EXISTS) @@ -18,30 +27,24 @@ elseif(WITH_GSL) include_directories( ${GSL_INCLUDE_DIRS} ) endif(WITH_BOOST_ODE) -if(WITH_BOOST) - find_package(Boost REQUIRED COMPONENTS thread) - add_definitions( -DUSE_BOOST_ASYNC ) - include_directories( ${Boost_INCLUDE_DIRS} ) -endif() - set(KSOLVE_SRCS - KinSparseMatrix.cpp - ZombiePool.cpp - ZombieFunction.cpp - ZombieBufPool.cpp - ZombieReac.cpp - ZombieEnz.cpp - ZombieMMenz.cpp - VoxelPoolsBase.cpp - VoxelPools.cpp - GssaVoxelPools.cpp - RateTerm.cpp - FuncTerm.cpp - Stoich.cpp - Ksolve.cpp - Gsolve.cpp - ZombiePoolInterface.cpp - testKsolve.cpp + KinSparseMatrix.cpp + ZombiePool.cpp + ZombieFunction.cpp + ZombieBufPool.cpp + ZombieReac.cpp + ZombieEnz.cpp + ZombieMMenz.cpp + VoxelPoolsBase.cpp + VoxelPools.cpp + GssaVoxelPools.cpp + RateTerm.cpp + FuncTerm.cpp + Stoich.cpp + Ksolve.cpp + Gsolve.cpp + ZombiePoolInterface.cpp + testKsolve.cpp ) if(WITH_GSL) diff --git a/ksolve/FuncTerm.cpp b/ksolve/FuncTerm.cpp index 1ca12021..c8690071 100644 --- a/ksolve/FuncTerm.cpp +++ b/ksolve/FuncTerm.cpp @@ -23,7 +23,7 @@ #include <sstream> using namespace std; -#include "muParser.h" +#include "../external/muparser/include/muParser.h" #include "FuncTerm.h" #include "../utility/numutil.h" diff --git a/ksolve/FuncTerm.h b/ksolve/FuncTerm.h index ccf2dcd1..fe735278 100644 --- a/ksolve/FuncTerm.h +++ b/ksolve/FuncTerm.h @@ -10,7 +10,7 @@ #ifndef _FUNC_TERM_H #define _FUNC_TERM_H -#include "muParser.h" +#include "../external/muparser/include/muParser.h" class FuncTerm { diff --git a/ksolve/Gsolve.cpp b/ksolve/Gsolve.cpp index d99dd12a..332005a6 100644 --- a/ksolve/Gsolve.cpp +++ b/ksolve/Gsolve.cpp @@ -18,7 +18,7 @@ #include "RateTerm.h" #include "FuncTerm.h" #include "FuncRateTerm.h" -#include "SparseMatrix.h" +#include "../basecode/SparseMatrix.h" #include "KinSparseMatrix.h" #include "GssaSystem.h" #include "Stoich.h" diff --git a/ksolve/Gsolve.h b/ksolve/Gsolve.h index 4b09049c..7eb1275c 100644 --- a/ksolve/Gsolve.h +++ b/ksolve/Gsolve.h @@ -162,8 +162,6 @@ private: /// Flag: True if atot should be updated every clock tick bool useClockedUpdate_; - - double t1_; }; #endif // _GSOLVE_H diff --git a/ksolve/GssaVoxelPools.cpp b/ksolve/GssaVoxelPools.cpp index ae725120..a12d693e 100644 --- a/ksolve/GssaVoxelPools.cpp +++ b/ksolve/GssaVoxelPools.cpp @@ -7,14 +7,12 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#ifdef ENABLE_CPP11 -#include <memory> -#endif - -#include "header.h" +#include "../basecode/header.h" +#include "../basecode/global.h" +#include "../randnum/RNG.h" #include "RateTerm.h" #include "FuncTerm.h" -#include "SparseMatrix.h" +#include "../basecode/SparseMatrix.h" #include "KinSparseMatrix.h" #include "VoxelPoolsBase.h" #include "../mesh/VoxelJunction.h" @@ -23,8 +21,6 @@ #include "Stoich.h" #include "GssaSystem.h" #include "GssaVoxelPools.h" -#include "../randnum/RNG.h" -#include "../basecode/global.h" /** * The SAFETY_FACTOR Protects against the total propensity exceeding diff --git a/ksolve/KinSparseMatrix.cpp b/ksolve/KinSparseMatrix.cpp index 1b1c1d31..0ff7676b 100644 --- a/ksolve/KinSparseMatrix.cpp +++ b/ksolve/KinSparseMatrix.cpp @@ -14,8 +14,8 @@ #include <iostream> #include <cassert> #include <cmath> -#include "SparseMatrix.h" -#include "utility/numutil.h" +#include "../basecode/SparseMatrix.h" +#include "../utility/numutil.h" #include "KinSparseMatrix.h" using namespace std; diff --git a/ksolve/Ksolve.cpp b/ksolve/Ksolve.cpp index 2277e5ff..a072b4c0 100644 --- a/ksolve/Ksolve.cpp +++ b/ksolve/Ksolve.cpp @@ -235,11 +235,7 @@ static const Cinfo* ksolveCinfo = Ksolve::initCinfo(); Ksolve::Ksolve() : -#if USE_GSL method_( "rk5" ), -#elif USE_BOOST_ODE - method_( "rk5a" ), -#endif epsAbs_( 1e-7 ), epsRel_( 1e-7 ), numThreads_( 1 ), @@ -248,19 +244,12 @@ Ksolve::Ksolve() dsolve_(), dsolvePtr_( 0 ) { + ; } Ksolve::~Ksolve() { -#if 0 - char* p = getenv( "MOOSE_SHOW_SOLVER_PERF" ); - if( p != NULL ) - { - cout << "Info: Ksolve (+Dsolve) took " << totalTime_ << " seconds and took " << numSteps_ - << " steps." << endl; - - } -#endif + ; } ////////////////////////////////////////////////////////////// @@ -378,6 +367,7 @@ void Ksolve::setStoich( Id stoich ) assert( stoich.element()->cinfo()->isA( "Stoich" ) ); stoich_ = stoich; stoichPtr_ = reinterpret_cast< Stoich* >( stoich.eref().data() ); + if ( !isBuilt_ ) { OdeSystem ode; @@ -386,6 +376,7 @@ void Ksolve::setStoich( Id stoich ) // ode.initStepSize = getEstimatedDt(); ode.initStepSize = 0.01; // This will be overridden at reinit. ode.method = method_; + #ifdef USE_GSL ode.gslSys.dimension = stoichPtr_->getNumAllPools(); if ( ode.gslSys.dimension == 0 ) @@ -416,6 +407,7 @@ void Ksolve::setStoich( Id stoich ) #endif isBuilt_ = true; } + } Id Ksolve::getDsolve() const diff --git a/ksolve/NonlinearSystem.h b/ksolve/NonlinearSystem.h index 5792f287..e2ea270f 100644 --- a/ksolve/NonlinearSystem.h +++ b/ksolve/NonlinearSystem.h @@ -31,8 +31,6 @@ #include <boost/numeric/ublas/lu.hpp> #include <boost/numeric/ublas/vector.hpp> #include <boost/numeric/ublas/io.hpp> - - #include "VoxelPools.h" using namespace std; @@ -46,10 +44,10 @@ typedef ublas::matrix<value_type> matrix_type; class ReacInfo { public: - int rank; - int num_reacs; + size_t rank; + size_t num_reacs; size_t num_mols; - int nIter; + size_t nIter; double convergenceCriterion; double* T; VoxelPools* pool; @@ -60,8 +58,10 @@ class ReacInfo /* Matrix inversion routine. - Uses lu_factorize and lu_substitute in uBLAS to invert a matrix */ - template<class T> + * Uses lu_factorize and lu_substitute in uBLAS to invert a matrix + */ + +template<class T> bool inverse(const ublas::matrix<T>& input, ublas::matrix<T>& inverse) { using namespace boost::numeric::ublas; @@ -73,6 +73,7 @@ bool inverse(const ublas::matrix<T>& input, ublas::matrix<T>& inverse) // perform LU-factorization int res = lu_factorize(A,pm); + if( res != 0 ) return false; // create identity matrix of "inverse" @@ -103,14 +104,19 @@ public: x1.resize( size_, 0); ri.nVec.resize( size_ ); - dx_ = sqrt( numeric_limits<double>::epsilon() ); + + // Find machine epsilon to decide on dx. Machine eps is typically 2.22045e-16 on 64 bit machines/intel. + // Square root of this value is a very good value. The values matches with GSL solver nicely. + // Making this value too small or too big gonna cause error in blas methods especially when + // computing inverse. + // Gnu-GSL uses GSL_SQRT_DBL_EPSILON which is 1.4901161193847656e-08 + // dx_ = 1.4901161193847656e-08; + dx_ = std::sqrt( numeric_limits<double>::epsilon() ); } - vector_type compute_at(const vector_type& x) + bool compute_at(const vector_type& x, vector_type& result) { - vector_type result( size_ ); - system(x, result); - return result; + return system(x, result); } int apply( ) @@ -118,22 +124,51 @@ public: return system(x_, f_); } - int compute_jacobians( const vector_type& x, bool compute_inverse = true ) + int compute_jacobians( const vector_type& x, bool compute_inverse = false ) { for( size_t i = 0; i < size_; i++) + { + // This trick I leart by looking at GSL implmentation. + double dx = dx_ * std::fabs(x[i]); + if( dx == 0 ) + dx = dx_; + for( size_t j = 0; j < size_; j++) { vector_type temp = x; - temp[j] += dx_; - J_(i, j) = (compute_at(temp)[i] - compute_at(x)[i]) / dx_; + temp[j] += dx; + vector_type res1, res2; + auto r1 = compute_at(temp, res1); + auto r2 = compute_at(x, res2); + + if( 0 == r1 && 0 == r2 ) + { + J_(i, j) = (res1[i] - res2[i]) / dx; + if( std::isnan(J_(i,j)) || std::isinf(J_(i,j)) ) + { + /* Try increasing dx */ + J_.clear(); + return -1; + } + } + else + { + J_.clear(); + return -1; + } } + } - // is_jacobian_valid_ = true; - // Keep the inverted J_ ready - //if(is_jacobian_valid_ and compute_inverse ) if( compute_inverse ) - inverse( J_, invJ_ ); - + { + try { + inverse( J_, invJ_ ); + } catch ( exception & e ) { + J_.clear(); + invJ_.clear(); + return -1; + } + } return 0; } @@ -147,9 +182,15 @@ public: init[i] = x[i]; x_ = init; - apply(); - - compute_jacobians( init ); + if( 0 == apply() ) + { + if( 0 != compute_jacobians( init ) ) + { + return; + } + } + else + return; } string to_string( ) @@ -167,22 +208,16 @@ public: int system( const vector_type& x, vector_type& f ) { - int num_consv = ri.num_mols - ri.rank; + size_t num_consv = ri.num_mols - ri.rank; for ( size_t i = 0; i < ri.num_mols; ++i ) { double temp = x[i] * x[i] ; -#if 0 // if overflow - if ( std::isnan( temp ) or std::isinf( temp ) ) - { - cerr << "Failed: "; - for( auto v : ri.nVec ) cerr << v << ", "; - cerr << endl; + if ( std::isnan( temp ) || std::isinf( temp ) ) return -1; - } -#endif - ri.nVec[i] = temp; + else + ri.nVec[i] = temp; } vector< double > vels; @@ -192,21 +227,21 @@ public: // y = Nr . v // Note that Nr is row-echelon: diagonal and above. - for ( int i = 0; i < ri.rank; ++i ) + f.resize( ri.rank + num_consv); + for ( size_t i = 0; i < ri.rank; ++i ) { double temp = 0; - for ( int j = i; j < ri.num_reacs; ++j ) + for ( size_t j = i; j < ri.num_reacs; ++j ) temp += ri.Nr(i, j ) * vels[j]; f[i] = temp ; } // dT = gamma.S - T - for ( int i = 0; i < num_consv; ++i ) + for ( size_t i = 0; i < num_consv; ++i ) { double dT = - ri.T[i]; for ( size_t j = 0; j < ri.num_mols; ++j ) dT += ri.gamma(i, j) * x[j] * x[j]; - f[ i + ri.rank] = dT ; } return 0; @@ -222,99 +257,42 @@ public: * @return If successful, return true. Check the variable `x_` at * which the system f_ is close to zero (within the tolerance). */ - bool find_roots_gnewton( double tolerance = 1e-7 , size_t max_iter = 50) + bool find_roots_gnewton( double tolerance, size_t max_iter) { - //tolerance = sqrt( numeric_limits<double>::epsilon() ); double norm2OfDiff = 1.0; size_t iter = 0; - int status = apply(); + if(0 != apply() ) + return false; - while( ublas::norm_2(f_) >= tolerance ) + while( ublas::norm_2(f_) > tolerance ) { iter += 1; - compute_jacobians( x_, true ); + ri.nIter = iter; + + if( 0 != compute_jacobians( x_, true ) ) + { + J_.clear(); + invJ_.clear(); + return false; + } + vector_type correction = ublas::prod( invJ_, f_ ); x_ -= correction; // If could not compute the value of system successfully. - status = apply(); - if( 0 != status ) + if( 0 != apply() ) + { + x_.clear(); return false; + } if( iter >= max_iter ) break; } - - ri.nIter = iter; - - if( iter >= max_iter ) - return false; - return true; } - /** - * @brief Compute the slope of function in given dimension. - * - * @param which_dimen The index of dimension. - * - * @return Slope. - */ - value_type slope( unsigned int which_dimen ) - { - vector_type x = x_; - x[which_dimen] += dx_; - // x1 and x2 holds the f_ of system at x_ and x (which is x + - // some step) - system( x_, x1 ); - system( x, x2 ); - return ublas::norm_2( (x2 - x1)/dx_ ); - } - - - /** - * @brief Makes the first guess. After this call the Newton method. - */ - void correction_step( ) - { - // Get the jacobian at current point. Notice that in this method, we - // don't have to compute inverse of jacobian - - vector_type direction( size_ ); - - // Now take the largest step possible such that the value of system at - // (x_ - step ) is lower than the value of system as x_. - vector_type nextState( size_ ); - - apply(); - - unsigned int i = 0; - - double factor = 1e-2; - while( true ) - { - i += 1; - compute_jacobians( x_, false ); - // Make a move in either side of direction. In whichever direction - // the function decreases. - direction = ublas::prod( J_, f_ ); - nextState = x_ - factor * direction; - if( ublas::norm_2( compute_at( nextState ) ) >= ublas::norm_2(compute_at(x_))) - factor = factor / 2.0; - else - { - cerr << "Correction term applied "; - x_ = nextState; - apply(); - break; - } - - if ( i > 20 ) - break; - } - } - public: const size_t size_; diff --git a/ksolve/OdeSystem.h b/ksolve/OdeSystem.h index 6a3ede6d..511513b5 100644 --- a/ksolve/OdeSystem.h +++ b/ksolve/OdeSystem.h @@ -26,15 +26,16 @@ class OdeSystem { {;} std::string method; - // GSL stuff + + double initStepSize; + double epsAbs; // Absolute error + double epsRel; // Relative error #ifdef USE_GSL + // GSL stuff gsl_odeiv2_system gslSys; const gsl_odeiv2_step_type* gslStep; #endif - double initStepSize; - double epsAbs; // Absolute error - double epsRel; // Relative error #if USE_BOOST_ODE size_t dimension; diff --git a/ksolve/RateTerm.cpp b/ksolve/RateTerm.cpp index 53250711..66f6ae33 100644 --- a/ksolve/RateTerm.cpp +++ b/ksolve/RateTerm.cpp @@ -12,9 +12,9 @@ #include <vector> #include <algorithm> #include <cassert> -using namespace std; -#include "header.h" +#include "../basecode/header.h" #include "RateTerm.h" +using namespace std; const double RateTerm::EPSILON = 1.0e-6; diff --git a/ksolve/SteadyStateBoost.cpp b/ksolve/SteadyStateBoost.cpp index a96439ba..98b67154 100644 --- a/ksolve/SteadyStateBoost.cpp +++ b/ksolve/SteadyStateBoost.cpp @@ -85,27 +85,6 @@ struct reac_info const Cinfo* SteadyState::initCinfo() { - /** - * This picks up the entire Stoich data structure - static Finfo* gslShared[] = - { - new SrcFinfo( "reinitSrc", Ftype0() ), - new DestFinfo( "assignStoich", - Ftype1< void* >(), - RFCAST( &SteadyState::assignStoichFunc ) - ), - new DestFinfo( "setMolN", - Ftype2< double, unsigned int >(), - RFCAST( &SteadyState::setMolN ) - ), - new SrcFinfo( "requestYsrc", Ftype0() ), - new DestFinfo( "assignY", - Ftype1< double* >(), - RFCAST( &SteadyState::assignY ) - ), - }; - */ - /** * These are the fields of the SteadyState class */ @@ -207,59 +186,59 @@ const Cinfo* SteadyState::initCinfo() // MsgDest definitions /////////////////////////////////////////////////////// static DestFinfo setupMatrix( "setupMatrix", - "This function initializes and rebuilds the matrices used " - "in the calculation.", - new OpFunc0< SteadyState >(&SteadyState::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 ) - ); + "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 ) - ); + "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 ) - ); + "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 ) - ); + "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 + &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 }; @@ -278,7 +257,7 @@ const Cinfo* SteadyState::initCinfo() "Note that the method finds unstable as well as stable fixed " "points.\n " "The SteadyState class also provides a utility function " - "*randomInit()* to " + "*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 " @@ -368,12 +347,10 @@ void SteadyState::setStoich( Id value ) 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 ); + double vol = LookupField< unsigned int, double >::get(stoichPtr->getCompartment(), "oneVoxelVolume", 0 ); pool_.setVolume( vol ); - pool_.setStoich( stoichPtr, 0 ); - pool_.updateAllRateTerms( stoichPtr->getRateTerms(), - stoichPtr->getNumCoreRates() ); + pool_.setStoich( stoichPtr, nullptr ); + pool_.updateAllRateTerms( stoichPtr->getRateTerms(), stoichPtr->getNumCoreRates() ); isInitialized_ = 1; } @@ -513,9 +490,9 @@ void SteadyState::showMatrices() return; } int numConsv = numVarPools_ - rank_; - cout << "Totals: "; + cout << "Totals: "; for ( int i = 0; i < numConsv; ++i ) - cout << total_[i] << " "; + cout << total_[i] << " "; cout << endl; cout << "gamma " << gamma_ << endl; cout << "Nr " << Nr_ << endl; @@ -549,9 +526,7 @@ void SteadyState::setupSSmatrix() { double x = 0; if ( j == colIndex[k] && k < rowStart[i+1] ) - { x = entry[k++]; - } N(i,j) = x; LU_(i,j) = x; } @@ -586,6 +561,7 @@ void SteadyState::setupSSmatrix() total_.assign( nConsv, 0.0 ); Id ksolve = Field< Id >::get( stoich_, "ksolve" ); + vector< double > nVec = LookupField< unsigned int, vector< double > >::get( ksolve,"nVec", 0 ); @@ -614,7 +590,7 @@ void SteadyState::classifyState( const double* T ) 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 ); + s->getKsolve(), "nVec", 0 ); for ( unsigned int i = 0; i < numVarPools_; ++i ) tot += nVec[i]; @@ -625,14 +601,14 @@ void SteadyState::classifyState( const double* T ) for ( unsigned int i = 0; i < numVarPools_; ++i ) { double orig = nVec[i]; - if ( std::isnan( orig ) or std::isinf( orig ) ) + if ( std::isnan( orig ) || std::isinf( orig ) ) { cout << "Warning: SteadyState::classifyState: orig=nan\n"; solutionStatus_ = 2; // Steady state OK, eig failed J.clear(); return; } - if ( std::isnan( tot ) or std::isinf( tot )) + if ( std::isnan( tot ) || std::isinf( tot )) { cout << "Warning: SteadyState::classifyState: tot=nan\n"; solutionStatus_ = 2; // Steady state OK, eig failed @@ -647,74 +623,73 @@ void SteadyState::classifyState( const double* T ) // Assign the rates for each mol. for ( unsigned int j = 0; j < numVarPools_; ++j ) { - if( std::isnan( yprime[j] ) or std::isinf( yprime[j] ) ) + if( std::isnan( yprime[j] ) || std::isinf( yprime[j] ) ) { - cout << "Warning: Overflow/underflow. Can't continue " << endl; solutionStatus_ = 2; + J.clear(); return; } J(i, j) = yprime[j]; } - } - // Jacobian is now ready. Find eigenvalues. - ublas::vector< std::complex< double > > eigenVec ( J.size1() ); + // Jacobian is now ready. Find eigenvalues. + ublas::vector< std::complex< double > > eigenVec ( J.size1() ); - ublas::matrix< std::complex<double>, ublas::column_major >* vl, *vr; - vl = NULL; vr = NULL; + ublas::matrix< std::complex<double>, ublas::column_major >* vl, *vr; + vl = NULL; vr = NULL; - /*----------------------------------------------------------------------------- - * INFO: Calling lapack routine geev to compute eigen vector of matrix J. - * - * Argument 3 and 4 are left- and right-eigenvectors. Since we do not need - * them, they are set to NULL. Argument 2 holds eigen-vector and result is - * copied to it (output ). - *-----------------------------------------------------------------------------*/ - int status = lapack::geev( J, eigenVec, vl, vr, lapack::optimal_workspace() ); + /*----------------------------------------------------------------------------- + * INFO: Calling lapack routine geev to compute eigen vector of matrix J. + * + * Argument 3 and 4 are left- and right-eigenvectors. Since we do not need + * them, they are set to NULL. Argument 2 holds eigen-vector and result is + * copied to it (output ). + *-----------------------------------------------------------------------------*/ + int status = lapack::geev( J, eigenVec, vl, vr, lapack::optimal_workspace() ); - eigenvalues_.clear(); - eigenvalues_.resize( numVarPools_, 0.0 ); - if ( status != 0 ) - { - 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 ) + eigenvalues_.clear(); + eigenvalues_.resize( numVarPools_, 0.0 ); + if ( status != 0 ) + { + 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. { - std::complex<value_type> z = eigenVec[ i ]; - double r = z.real(); - 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. + nNegEigenvalues_ = 0; + nPosEigenvalues_ = 0; + for ( unsigned int i = 0; i < numVarPools_; ++i ) + { + std::complex<value_type> z = eigenVec[ i ]; + double r = z.real(); + 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 } - 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 } } static bool isSolutionValid( const vector< double >& x ) { - for( size_t i = 0; i < x.size(); i++ ) + for( auto &v : x ) { - double v = x[i]; - if ( std::isnan( v ) or std::isinf( v ) ) + if ( std::isnan( v ) || std::isinf( v ) ) { cout << "Warning: SteadyState iteration gave nan/inf concs\n"; return false; @@ -728,6 +703,19 @@ static bool isSolutionValid( const vector< double >& x ) return true; } +static bool isSolutionPositive( const vector< double >& x ) +{ + for( auto &v : x ) + { + if( v < 0.0 ) + { + cout << "Warning: SteadyState iteration gave negative concs" << endl; + return false; + } + } + return true; +} + /** * The settle function computes the steady state nearest the initial * conditions. @@ -798,7 +786,7 @@ void SteadyState::settle( bool forceSetup ) int status = 1; // Find roots . If successful, set status to 0. - if( ss->find_roots_gnewton( ) ) + if( ss->find_roots_gnewton( convergenceCriterion_, maxIter_ ) ) status = 0; if ( status == 0 && isSolutionValid( ss->ri.nVec ) ) diff --git a/ksolve/SteadyStateGsl.cpp b/ksolve/SteadyStateGsl.cpp index 295b5256..eaec6d07 100644 --- a/ksolve/SteadyStateGsl.cpp +++ b/ksolve/SteadyStateGsl.cpp @@ -87,20 +87,20 @@ 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 ) - ), + 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 ) + ), }; */ @@ -205,61 +205,61 @@ const Cinfo* SteadyState::initCinfo() // MsgDest definitions /////////////////////////////////////////////////////// static DestFinfo setupMatrix( "setupMatrix", - "This function initializes and rebuilds the matrices used " - "in the calculation.", - new OpFunc0< SteadyState >(&SteadyState::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 ) - ); + "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 ) - ); + "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 ) - ); + "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 ) - ); + "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 - - + &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[] = @@ -276,7 +276,7 @@ const Cinfo* SteadyState::initCinfo() "Note that the method finds unstable as well as stable fixed " "points.\n " "The SteadyState class also provides a utility function " - "*randomInit()* to " + "*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 " @@ -316,7 +316,6 @@ static const Cinfo* steadyStateCinfo = SteadyState::initCinfo(); /////////////////////////////////////////////////// // Class function definitions /////////////////////////////////////////////////// - SteadyState::SteadyState() : nIter_( 0 ), @@ -382,9 +381,9 @@ void SteadyState::setStoich( Id value ) double vol = LookupField< unsigned int, double >::get( stoichPtr->getCompartment(), "oneVoxelVolume", 0 ); pool_.setVolume( vol ); - pool_.setStoich( stoichPtr, 0 ); - pool_.updateAllRateTerms( stoichPtr->getRateTerms(), - stoichPtr->getNumCoreRates() ); + + pool_.setStoich( stoichPtr, nullptr ); + pool_.updateAllRateTerms( stoichPtr->getRateTerms(), stoichPtr->getNumCoreRates() ); isInitialized_ = 1; } @@ -548,9 +547,9 @@ void SteadyState::showMatrices() return; } int numConsv = numVarPools_ - rank_; - cout << "Totals: "; + cout << "Totals: "; for ( int i = 0; i < numConsv; ++i ) - cout << total_[i] << " "; + cout << total_[i] << " "; cout << endl; #ifdef USE_GSL print_gsl_mat( gamma_, "gamma" ); @@ -584,7 +583,7 @@ void SteadyState::setupSSmatrix() { gsl_matrix_set (LU_, i, i + nReacs_, 1 ); unsigned int k = rowStart[i]; - // cout << endl << i << ": "; + // cout << endl << i << ": "; for ( unsigned int j = 0; j < nReacs_; ++j ) { double x = 0; @@ -592,7 +591,7 @@ void SteadyState::setupSSmatrix() { x = entry[k++]; } - // cout << " " << x; + // cout << " " << x; gsl_matrix_set (N, i, j, x); gsl_matrix_set (LU_, i, j, x ); } @@ -637,10 +636,10 @@ void SteadyState::setupSSmatrix() /* cout << "S = ("; for ( unsigned int j = 0; j < numVarPools_; ++j ) - cout << s_->S()[ j ] << ", "; + cout << s_->S()[ j ] << ", "; cout << "), Sinit = ( "; for ( unsigned int j = 0; j < numVarPools_; ++j ) - cout << s_->Sinit()[ j ] << ", "; + cout << s_->Sinit()[ j ] << ", "; cout << ")\n"; */ Id ksolve = Field< Id >::get( stoich_, "ksolve" ); @@ -936,13 +935,9 @@ int ss_func( const gsl_vector* x, void* params, gsl_vector* f ) { 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 ); diff --git a/ksolve/Stoich.cpp b/ksolve/Stoich.cpp index 3cd9d902..62959a2a 100644 --- a/ksolve/Stoich.cpp +++ b/ksolve/Stoich.cpp @@ -7,16 +7,16 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" -#include "ElementValueFinfo.h" -#include "PoolBase.h" -#include "ReacBase.h" -#include "EnzBase.h" -#include "CplxEnzBase.h" +#include "../basecode/header.h" +#include "../basecode/ElementValueFinfo.h" +#include "../kinetics/PoolBase.h" +#include "../kinetics/ReacBase.h" +#include "../kinetics/EnzBase.h" +#include "../kinetics/CplxEnzBase.h" #include "FuncTerm.h" #include "RateTerm.h" #include "FuncRateTerm.h" -#include "SparseMatrix.h" +#include "../basecode/SparseMatrix.h" #include "KinSparseMatrix.h" #include "VoxelPoolsBase.h" #include "../mesh/VoxelJunction.h" @@ -26,7 +26,7 @@ #include "../builtins/Function.h" #include "ZombieFunction.h" #include "Stoich.h" -#include "lookupVolumeFromMesh.h" +#include "../kinetics/lookupVolumeFromMesh.h" #include "../scheduling/Clock.h" #include "../shell/Shell.h" #include "../shell/Wildcard.h" diff --git a/ksolve/VoxelPools.cpp b/ksolve/VoxelPools.cpp index ea575304..dd797fd3 100644 --- a/ksolve/VoxelPools.cpp +++ b/ksolve/VoxelPools.cpp @@ -1,12 +1,13 @@ -/********************************************************************** -** This program is part of 'MOOSE', the -** Messaging Object Oriented Simulation Environment. -** Copyright (C) 2003-2010 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. -**********************************************************************/ -#include "header.h" +/* +* This program is part of 'MOOSE', the +* Messaging Object Oriented Simulation Environment. +* Copyright (C) 2003-2010 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. +*/ + +#include "../basecode/header.h" #ifdef USE_GSL #include <gsl/gsl_errno.h> @@ -22,7 +23,7 @@ using namespace boost::numeric; #include "VoxelPools.h" #include "RateTerm.h" #include "FuncTerm.h" -#include "SparseMatrix.h" +#include "../basecode/SparseMatrix.h" #include "KinSparseMatrix.h" #include "../mesh/VoxelJunction.h" #include "XferInfo.h" @@ -66,9 +67,12 @@ void VoxelPools::reinit( double dt ) void VoxelPools::setStoich( Stoich* s, const OdeSystem* ode ) { stoichPtr_ = s; - absTol_ = ode->epsAbs; - relTol_ = ode->epsRel; - method_ = ode->method; + if( ode ) + { + epsAbs_ = ode->epsAbs; + epsRel_ = ode->epsRel; + method_ = ode->method; + } #ifdef USE_GSL if ( ode ) @@ -77,10 +81,9 @@ void VoxelPools::setStoich( Stoich* s, const OdeSystem* ode ) if ( driver_ ) gsl_odeiv2_driver_free( driver_ ); - driver_ = gsl_odeiv2_driver_alloc_y_new( - &sys_, ode->gslStep, ode->initStepSize, - ode->epsAbs, ode->epsRel - ); + driver_ = gsl_odeiv2_driver_alloc_y_new( &sys_, ode->gslStep + , ode->initStepSize, ode->epsAbs, ode->epsRel + ); } #endif VoxelPoolsBase::reinit(); @@ -89,6 +92,7 @@ void VoxelPools::setStoich( Stoich* s, const OdeSystem* ode ) 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 ) @@ -135,114 +139,50 @@ void VoxelPools::advance( const ProcInfo* p ) * user should provide the stepping size when using fixed dt. This feature * can be incredibly useful on large system. */ - const double fixedDt = 0.1; - if( method_ == "rk2" ) - odeint::integrate_const( rk_midpoint_stepper_type_() - , [this](const vector_type_& dy, vector_type_& dydt, const double t) { - VoxelPools::evalRates(this, dy, dydt ); - } - , Svec() - , p->currTime - p->dt, p->currTime, std::min( p->dt, fixedDt ) + // Variout stepper times are listed here: + // https://www.boost.org/doc/libs/1_68_0/libs/numeric/odeint/doc/html/boost_numeric_odeint/odeint_in_detail/steppers.html#boost_numeric_odeint.odeint_in_detail.steppers.explicit_steppers + + // Describe system to be used in boost solver calls. + auto sys = [this](const vector_type_& dy, vector_type_& dydt, const double t) { + VoxelPools::evalRates(this, dy, dydt); }; + + // This is usually the default method. It works well in practice. Tested + // with steady-state solver. Closest to GSL rk5 . + if( method_ == "rk5" || method_ == "gsl" || method_ == "boost" ) + odeint::integrate_adaptive( + make_dense_output( epsAbs_, epsRel_, odeint::runge_kutta_dopri5<vector_type_>() ) + , sys , Svec() , p->currTime - p->dt , p->currTime , p->dt ); + else if( method_ == "rk5a" || method_ == "adaptive" ) + odeint::integrate_adaptive( odeint::make_controlled<rk_dopri_stepper_type_>( epsAbs_, epsRel_ ) + , sys , Svec() , p->currTime - p->dt , p->currTime, p->dt ); + else if( method_ == "rk2" ) + odeint::integrate_const( rk_midpoint_stepper_type_() + , sys, Svec(), p->currTime - p->dt, p->currTime, p->dt); else if( method_ == "rk4" ) odeint::integrate_const( rk4_stepper_type_() - , [this](const vector_type_& dy, vector_type_& dydt, const double t) { - VoxelPools::evalRates(this, dy, dydt ); - } - , Svec() - , p->currTime - p->dt, p->currTime, std::min( p->dt, fixedDt ) - ); - else if( method_ == "rk5") - odeint::integrate_const( rk_karp_stepper_type_() - , [this](const vector_type_& dy, vector_type_& dydt, const double t) { - VoxelPools::evalRates(this, dy, dydt ); - } - , Svec() - , p->currTime - p->dt, p->currTime, std::min( p->dt, fixedDt ) - ); - else if( method_ == "rk5a") - odeint::integrate_adaptive( - odeint::make_controlled<rk_karp_stepper_type_>( absTol_, relTol_ ) - , [this](const vector_type_& dy, vector_type_& dydt, const double t) { - VoxelPools::evalRates(this, dy, dydt ); - } - , Svec() - , p->currTime - p->dt - , p->currTime - , p->dt - ); + , sys, Svec(), p->currTime - p->dt, p->currTime, p->dt ); else if ("rk54" == method_ ) odeint::integrate_const( rk_karp_stepper_type_() - , [this](const vector_type_& dy, vector_type_& dydt, const double t) { - VoxelPools::evalRates(this, dy, dydt ); - } - , Svec() - , p->currTime - p->dt, p->currTime, std::min( p->dt, fixedDt ) - ); - else if ("rk54a" == method_ ) - odeint::integrate_adaptive( - odeint::make_controlled<rk_karp_stepper_type_>( absTol_, relTol_ ) - , [this](const vector_type_& dy, vector_type_& dydt, const double t) { - VoxelPools::evalRates(this, dy, dydt ); - } - , Svec() - , p->currTime - p->dt - , p->currTime - , p->dt - ); - else if ("rk5" == method_ ) - odeint::integrate_const( rk_dopri_stepper_type_() - , [this](const vector_type_& dy, vector_type_& dydt, const double t) { - VoxelPools::evalRates(this, dy, dydt ); - } - , Svec() - , p->currTime - p->dt - , p->currTime - , std::min( p->dt, fixedDt ) - ); - else if ("rk5a" == method_ ) - odeint::integrate_adaptive( - odeint::make_controlled<rk_dopri_stepper_type_>( absTol_, relTol_ ) - , [this](const vector_type_& dy, vector_type_& dydt, const double t) { - VoxelPools::evalRates(this, dy, dydt ); - } - , Svec() - , p->currTime - p->dt - , p->currTime - , p->dt - ); + , sys , Svec() , p->currTime - p->dt, p->currTime, p->dt); + else if ("rkck" == method_ ) + odeint::integrate_adaptive( odeint::make_controlled<rk_karp_stepper_type_>( epsAbs_, epsRel_ ) + , sys, Svec(), p->currTime - p->dt, p->currTime, p->dt); else if( method_ == "rk8" ) odeint::integrate_const( rk_felhberg_stepper_type_() - , [this](const vector_type_& dy, vector_type_& dydt, const double t) { - VoxelPools::evalRates(this, dy, dydt ); - } - , Svec() - , p->currTime - p->dt, p->currTime, std::min( p->dt, fixedDt ) - ); + , sys, Svec(), p->currTime - p->dt, p->currTime, p->dt); else if( method_ == "rk8a" ) - odeint::integrate_adaptive( - odeint::make_controlled<rk_felhberg_stepper_type_>( absTol_, relTol_ ) - , [this](const vector_type_& dy, vector_type_& dydt, const double t) { - VoxelPools::evalRates(this, dy, dydt ); - } - , Svec() - , p->currTime - p->dt - , p->currTime - , p->dt - ); - + odeint::integrate_adaptive( rk_felhberg_stepper_type_() + , sys, Svec(), p->currTime - p->dt, p->currTime, p->dt); else - odeint::integrate_adaptive( - odeint::make_controlled<rk_karp_stepper_type_>( absTol_, relTol_ ) - , [this](const vector_type_& dy, vector_type_& dydt, const double t) { - VoxelPools::evalRates(this, dy, dydt ); - } - , Svec() - , p->currTime - p->dt - , p->currTime - , p->dt + { + cerr << "Ksolve: Unknow method " << method_ << ", using default!" << endl; + odeint::integrate_const( + make_dense_output( epsAbs_, epsRel_, odeint::runge_kutta_dopri5<vector_type_>() ) + , sys , Svec() , p->currTime - p->dt , p->currTime , p->dt ); + } #endif if ( !stoichPtr_->getAllowNegative() ) // clean out negatives @@ -272,17 +212,6 @@ int VoxelPools::gslFunc( double t, const double* y, double *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 @@ -353,8 +282,7 @@ void VoxelPools::updateRates( const double* s, double* yprime ) const 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() == 0 || N.nRows() == stoichPtr_->getNumAllPools() ); assert( N.nColumns() == rates_.size() ); for ( vector< RateTerm* >::const_iterator diff --git a/ksolve/VoxelPools.h b/ksolve/VoxelPools.h index a39b151c..04c5bb8c 100644 --- a/ksolve/VoxelPools.h +++ b/ksolve/VoxelPools.h @@ -99,8 +99,8 @@ private: gsl_odeiv2_system sys_; #endif - double absTol_; - double relTol_; + double epsAbs_; + double epsRel_; string method_; }; diff --git a/ksolve/VoxelPoolsBase.cpp b/ksolve/VoxelPoolsBase.cpp index f0261245..6a35f477 100644 --- a/ksolve/VoxelPoolsBase.cpp +++ b/ksolve/VoxelPoolsBase.cpp @@ -6,15 +6,14 @@ ** 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 "VoxelPoolsBase.h" #include "../mesh/VoxelJunction.h" #include "XferInfo.h" #include "ZombiePoolInterface.h" #include "RateTerm.h" #include "FuncTerm.h" -#include "SparseMatrix.h" +#include "../basecode/SparseMatrix.h" #include "KinSparseMatrix.h" #include "Stoich.h" diff --git a/ksolve/ZombieBufPool.cpp b/ksolve/ZombieBufPool.cpp index 82665529..a0fb2df5 100644 --- a/ksolve/ZombieBufPool.cpp +++ b/ksolve/ZombieBufPool.cpp @@ -6,15 +6,15 @@ ** GNU Lesser General Public License version 2.1 ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" -#include "PoolBase.h" +#include "../basecode/header.h" +#include "../kinetics/PoolBase.h" #include "VoxelPoolsBase.h" #include "../mesh/VoxelJunction.h" #include "XferInfo.h" #include "ZombiePoolInterface.h" #include "ZombiePool.h" #include "ZombieBufPool.h" -#include "lookupVolumeFromMesh.h" +#include "../kinetics/lookupVolumeFromMesh.h" // Entirely derived from ZombiePool. Only the zombification routines differ. const Cinfo* ZombieBufPool::initCinfo() diff --git a/ksolve/ZombieEnz.cpp b/ksolve/ZombieEnz.cpp index e73c27ac..4c06cf0e 100644 --- a/ksolve/ZombieEnz.cpp +++ b/ksolve/ZombieEnz.cpp @@ -6,12 +6,11 @@ ** GNU Lesser General Public License version 2.1 ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" - -#include "lookupVolumeFromMesh.h" +#include "../basecode/header.h" +#include "../kinetics/lookupVolumeFromMesh.h" #include "RateTerm.h" #include "FuncTerm.h" -#include "SparseMatrix.h" +#include "../basecode/SparseMatrix.h" #include "KinSparseMatrix.h" #include "VoxelPoolsBase.h" #include "../mesh/VoxelJunction.h" @@ -19,8 +18,8 @@ #include "ZombiePoolInterface.h" #include "Stoich.h" -#include "EnzBase.h" -#include "CplxEnzBase.h" +#include "../kinetics/EnzBase.h" +#include "../kinetics/CplxEnzBase.h" #include "ZombieEnz.h" #define EPSILON 1e-15 diff --git a/ksolve/ZombieFunction.cpp b/ksolve/ZombieFunction.cpp index 9e184961..48a21899 100644 --- a/ksolve/ZombieFunction.cpp +++ b/ksolve/ZombieFunction.cpp @@ -7,19 +7,19 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" -#include "ElementValueFinfo.h" +#include "../basecode/header.h" +#include "../basecode/ElementValueFinfo.h" -#include "Variable.h" -#include "Function.h" +#include "../builtins/Variable.h" +#include "../builtins/Function.h" #include "ZombieFunction.h" #include "FuncTerm.h" #include "RateTerm.h" -#include "SparseMatrix.h" +#include "../basecode/SparseMatrix.h" #include "KinSparseMatrix.h" #include "VoxelPoolsBase.h" -#include "VoxelJunction.h" +#include "../mesh/VoxelJunction.h" #include "XferInfo.h" #include "ZombiePoolInterface.h" #include "Stoich.h" diff --git a/ksolve/ZombieMMenz.cpp b/ksolve/ZombieMMenz.cpp index dc400897..0eeaef1a 100644 --- a/ksolve/ZombieMMenz.cpp +++ b/ksolve/ZombieMMenz.cpp @@ -6,12 +6,11 @@ ** GNU Lesser General Public License version 2.1 ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" - -#include "lookupVolumeFromMesh.h" +#include "../basecode/header.h" +#include "../kinetics/lookupVolumeFromMesh.h" #include "RateTerm.h" #include "FuncTerm.h" -#include "SparseMatrix.h" +#include "../basecode/SparseMatrix.h" #include "KinSparseMatrix.h" #include "VoxelPoolsBase.h" #include "../mesh/VoxelJunction.h" @@ -19,7 +18,7 @@ #include "ZombiePoolInterface.h" #include "Stoich.h" -#include "EnzBase.h" +#include "../kinetics/EnzBase.h" #include "ZombieMMenz.h" #define EPSILON 1e-15 diff --git a/ksolve/ZombiePool.cpp b/ksolve/ZombiePool.cpp index 6d612c83..b1e3af86 100644 --- a/ksolve/ZombiePool.cpp +++ b/ksolve/ZombiePool.cpp @@ -7,14 +7,14 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" -#include "PoolBase.h" +#include "../basecode/header.h" +#include "../kinetics/PoolBase.h" #include "VoxelPoolsBase.h" #include "../mesh/VoxelJunction.h" #include "XferInfo.h" #include "ZombiePoolInterface.h" #include "ZombiePool.h" -#include "lookupVolumeFromMesh.h" +#include "../kinetics/lookupVolumeFromMesh.h" #define EPSILON 1e-15 diff --git a/ksolve/ZombiePoolInterface.cpp b/ksolve/ZombiePoolInterface.cpp index 1df99ae2..62a50f9f 100644 --- a/ksolve/ZombiePoolInterface.cpp +++ b/ksolve/ZombiePoolInterface.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" diff --git a/ksolve/ZombieReac.cpp b/ksolve/ZombieReac.cpp index c12f30b8..55a00887 100644 --- a/ksolve/ZombieReac.cpp +++ b/ksolve/ZombieReac.cpp @@ -7,12 +7,12 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" -#include "ReacBase.h" -#include "lookupVolumeFromMesh.h" +#include "../basecode/header.h" +#include "../kinetics/ReacBase.h" +#include "../kinetics/lookupVolumeFromMesh.h" #include "RateTerm.h" #include "FuncTerm.h" -#include "SparseMatrix.h" +#include "../basecode/SparseMatrix.h" #include "KinSparseMatrix.h" #include "VoxelPoolsBase.h" #include "../mesh/VoxelJunction.h" diff --git a/ksolve/testKsolve.cpp b/ksolve/testKsolve.cpp index 6f0275ff..64ae8db7 100644 --- a/ksolve/testKsolve.cpp +++ b/ksolve/testKsolve.cpp @@ -6,12 +6,11 @@ ** 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 "../shell/Shell.h" #include "RateTerm.h" -#include "muParser.h" #include "FuncTerm.h" -#include "SparseMatrix.h" +#include "../basecode/SparseMatrix.h" #include "KinSparseMatrix.h" #include "VoxelPoolsBase.h" #include "../mesh/VoxelJunction.h" @@ -19,6 +18,8 @@ #include "ZombiePoolInterface.h" #include "Stoich.h" +#include "../external/muparser/include/muParser.h" + /** * Tab controlled by table * A + Tab <===> B diff --git a/mesh/CMakeLists.txt b/mesh/CMakeLists.txt index a04e31dd..bbeb98c3 100644 --- a/mesh/CMakeLists.txt +++ b/mesh/CMakeLists.txt @@ -1,6 +1,5 @@ -include_directories(../msg) -include_directories(../basecode) -include_directories(../utility) +cmake_minimum_required(VERSION 2.8) +include( ${CMAKE_CURRENT_SOURCE_DIR}/../CheckCXXCompiler.cmake) add_library(mesh ChemCompt.cpp MeshCompt.cpp @@ -13,6 +12,6 @@ add_library(mesh SpineEntry.cpp SpineMesh.cpp PsdMesh.cpp - EndoMesh.cpp + EndoMesh.cpp testMesh.cpp ) diff --git a/mesh/ChemCompt.cpp b/mesh/ChemCompt.cpp index 1d2b3f7f..b8961f1d 100644 --- a/mesh/ChemCompt.cpp +++ b/mesh/ChemCompt.cpp @@ -7,9 +7,9 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" -#include "ElementValueFinfo.h" -#include "LookupElementValueFinfo.h" +#include "../basecode/header.h" +#include "../basecode/ElementValueFinfo.h" +#include "../basecode/LookupElementValueFinfo.h" #include "Boundary.h" #include "MeshEntry.h" #include "ChemCompt.h" diff --git a/mesh/CubeMesh.cpp b/mesh/CubeMesh.cpp index 728c69ba..d5050743 100644 --- a/mesh/CubeMesh.cpp +++ b/mesh/CubeMesh.cpp @@ -7,9 +7,9 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" -#include "SparseMatrix.h" -#include "ElementValueFinfo.h" +#include "../basecode/header.h" +#include "../basecode/SparseMatrix.h" +#include "../basecode/ElementValueFinfo.h" #include "Boundary.h" #include "MeshEntry.h" #include "VoxelJunction.h" diff --git a/mesh/CylBase.cpp b/mesh/CylBase.cpp index a4d8d6bb..209977db 100644 --- a/mesh/CylBase.cpp +++ b/mesh/CylBase.cpp @@ -6,12 +6,9 @@ ** GNU Lesser General Public License version 2.1 ** See the file COPYING.LIB for the full notice. **********************************************************************/ -//#include <vector> -//#include <cassert> -//using namespace std; -#include "header.h" -#include "SparseMatrix.h" -// #include "ElementValueFinfo.h" + +#include "../basecode/header.h" +#include "../basecode/SparseMatrix.h" #include "Boundary.h" #include "MeshEntry.h" #include "VoxelJunction.h" diff --git a/mesh/CylMesh.cpp b/mesh/CylMesh.cpp index 9fc8352e..e0057529 100644 --- a/mesh/CylMesh.cpp +++ b/mesh/CylMesh.cpp @@ -7,9 +7,9 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" -#include "SparseMatrix.h" -#include "ElementValueFinfo.h" +#include "../basecode/header.h" +#include "../basecode/SparseMatrix.h" +#include "../basecode/ElementValueFinfo.h" #include "../utility/Vec.h" #include "Boundary.h" #include "MeshEntry.h" diff --git a/mesh/EndoMesh.cpp b/mesh/EndoMesh.cpp index 33c13bdb..e1e21dfd 100644 --- a/mesh/EndoMesh.cpp +++ b/mesh/EndoMesh.cpp @@ -7,9 +7,9 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" -#include "SparseMatrix.h" -#include "ElementValueFinfo.h" +#include "../basecode/header.h" +#include "../basecode/SparseMatrix.h" +#include "../basecode/ElementValueFinfo.h" #include "../utility/Vec.h" #include "Boundary.h" #include "MeshEntry.h" @@ -23,6 +23,9 @@ #include "NeuroMesh.h" #include "EndoMesh.h" #include "../utility/numutil.h" + +static CubeMesh defaultParent; + const Cinfo* EndoMesh::initCinfo() { ////////////////////////////////////////////////////////////// @@ -137,7 +140,7 @@ static const Cinfo* endoMeshCinfo = EndoMesh::initCinfo(); ////////////////////////////////////////////////////////////////// EndoMesh::EndoMesh() : - parent_( 0 ), + parent_( &defaultParent ), rPower_( 1.0 / 3.0 ), rScale_( 0.5 ), aPower_( 0.5 ), @@ -263,7 +266,7 @@ unsigned int EndoMesh::getMeshDimensions( unsigned int fid ) const /// Virtual function to return # of spatial dimensions of mesh unsigned int EndoMesh::innerGetDimensions() const { - return 1; + return 3; } /// Virtual function to return volume of mesh Entry. double EndoMesh::getMeshEntryVolume( unsigned int fid ) const diff --git a/mesh/MeshCompt.cpp b/mesh/MeshCompt.cpp index 5b46bd6a..8e4186d3 100644 --- a/mesh/MeshCompt.cpp +++ b/mesh/MeshCompt.cpp @@ -7,8 +7,8 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" -#include "SparseMatrix.h" +#include "../basecode/header.h" +#include "../basecode/SparseMatrix.h" #include "VoxelJunction.h" #include "Boundary.h" // #include "Stencil.h" diff --git a/mesh/MeshEntry.cpp b/mesh/MeshEntry.cpp index 88d95b75..3388e3fa 100644 --- a/mesh/MeshEntry.cpp +++ b/mesh/MeshEntry.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 "MeshEntry.h" #include "Boundary.h" // #include "Stencil.h" diff --git a/mesh/NeuroMesh.cpp b/mesh/NeuroMesh.cpp index cb0ccc56..5e5e82f4 100644 --- a/mesh/NeuroMesh.cpp +++ b/mesh/NeuroMesh.cpp @@ -7,12 +7,10 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include <cctype> -#include "header.h" -#include "SparseMatrix.h" +#include "../basecode/header.h" +#include "../basecode/SparseMatrix.h" +#include "../basecode/ElementValueFinfo.h" #include "../utility/Vec.h" - -#include "ElementValueFinfo.h" #include "Boundary.h" #include "MeshEntry.h" #include "ChemCompt.h" diff --git a/mesh/NeuroNode.cpp b/mesh/NeuroNode.cpp index 9610227b..0cfc583d 100644 --- a/mesh/NeuroNode.cpp +++ b/mesh/NeuroNode.cpp @@ -7,8 +7,8 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" -#include "SparseMatrix.h" +#include "../basecode/header.h" +#include "../basecode/SparseMatrix.h" #include "Boundary.h" #include "MeshEntry.h" #include "VoxelJunction.h" diff --git a/mesh/PsdMesh.cpp b/mesh/PsdMesh.cpp index da23aebb..75e8e2ed 100644 --- a/mesh/PsdMesh.cpp +++ b/mesh/PsdMesh.cpp @@ -7,12 +7,10 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include <cctype> -#include "header.h" -#include "SparseMatrix.h" +#include "../basecode/header.h" +#include "../basecode/SparseMatrix.h" +#include "../basecode/ElementValueFinfo.h" #include "../utility/Vec.h" - -#include "ElementValueFinfo.h" #include "Boundary.h" #include "MeshEntry.h" #include "ChemCompt.h" diff --git a/mesh/SpineEntry.cpp b/mesh/SpineEntry.cpp index c2d01652..f9e3a918 100644 --- a/mesh/SpineEntry.cpp +++ b/mesh/SpineEntry.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "Boundary.h" #include "MeshEntry.h" #include "VoxelJunction.h" diff --git a/mesh/SpineMesh.cpp b/mesh/SpineMesh.cpp index 4fca0872..a14dfbc2 100644 --- a/mesh/SpineMesh.cpp +++ b/mesh/SpineMesh.cpp @@ -7,12 +7,10 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include <cctype> -#include "header.h" -#include "SparseMatrix.h" +#include "../basecode/header.h" +#include "../basecode/SparseMatrix.h" +#include "../basecode/ElementValueFinfo.h" #include "../utility/Vec.h" - -#include "ElementValueFinfo.h" #include "Boundary.h" #include "MeshEntry.h" #include "ChemCompt.h" diff --git a/mesh/testMesh.cpp b/mesh/testMesh.cpp index 2ab6f067..0446a8f0 100644 --- a/mesh/testMesh.cpp +++ b/mesh/testMesh.cpp @@ -7,19 +7,17 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" -#include "SparseMatrix.h" +#include "../basecode/header.h" +#include "../basecode/SparseMatrix.h" #include "../shell/Shell.h" #include "Boundary.h" #include "MeshEntry.h" -// #include "Stencil.h" #include "ChemCompt.h" #include "MeshCompt.h" #include "CubeMesh.h" #include "CylBase.h" #include "NeuroNode.h" -#include "SparseMatrix.h" -// #include "NeuroStencil.h" +#include "../basecode/SparseMatrix.h" #include "NeuroMesh.h" #include "../utility/Vec.h" #include "CylMesh.h" diff --git a/mpi/CMakeLists.txt b/mpi/CMakeLists.txt index a3617266..02006208 100644 --- a/mpi/CMakeLists.txt +++ b/mpi/CMakeLists.txt @@ -1,4 +1,5 @@ -include_directories(../msg ../basecode) +cmake_minimum_required(VERSION 2.8) +include( ${CMAKE_CURRENT_SOURCE_DIR}/../CheckCXXCompiler.cmake) IF(USE_MPI) find_package(MPI REQUIRED) include_directories(MPI_INCLUDE_PATH) diff --git a/mpi/PostMaster.cpp b/mpi/PostMaster.cpp index 194fdfd4..85760dc2 100644 --- a/mpi/PostMaster.cpp +++ b/mpi/PostMaster.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "PostMaster.h" #include "../shell/Shell.h" diff --git a/msg/CMakeLists.txt b/msg/CMakeLists.txt index 9b5d6bc3..d7209e19 100644 --- a/msg/CMakeLists.txt +++ b/msg/CMakeLists.txt @@ -1,4 +1,5 @@ -include_directories(../basecode) +cmake_minimum_required(VERSION 2.8) +include( ${CMAKE_CURRENT_SOURCE_DIR}/../CheckCXXCompiler.cmake) add_library(msg Msg.cpp DiagonalMsg.cpp diff --git a/msg/DiagonalMsg.cpp b/msg/DiagonalMsg.cpp index cc1fa542..4ff6d581 100644 --- a/msg/DiagonalMsg.cpp +++ b/msg/DiagonalMsg.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "DiagonalMsg.h" // Static field declaration diff --git a/msg/Msg.cpp b/msg/Msg.cpp index 5d5a3a79..f2603652 100644 --- a/msg/Msg.cpp +++ b/msg/Msg.cpp @@ -7,16 +7,16 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "SingleMsg.h" #include "DiagonalMsg.h" #include "OneToOneMsg.h" #include "OneToOneDataIndexMsg.h" #include "OneToAllMsg.h" -#include "SparseMatrix.h" +#include "../basecode/SparseMatrix.h" #include "SparseMsg.h" #include "../shell/Shell.h" // For the myNode() and numNodes() definitions -#include "MsgElement.h" +#include "../basecode/MsgElement.h" #include "../shell/Shell.h" diff --git a/msg/OneToAllMsg.cpp b/msg/OneToAllMsg.cpp index 262e0494..96cd8208 100644 --- a/msg/OneToAllMsg.cpp +++ b/msg/OneToAllMsg.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "OneToAllMsg.h" // Initializing static variables diff --git a/msg/OneToOneDataIndexMsg.cpp b/msg/OneToOneDataIndexMsg.cpp index d26f82e9..42b20da1 100644 --- a/msg/OneToOneDataIndexMsg.cpp +++ b/msg/OneToOneDataIndexMsg.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "OneToOneDataIndexMsg.h" // Initializing static variables diff --git a/msg/OneToOneMsg.cpp b/msg/OneToOneMsg.cpp index e1625eae..d36720dd 100644 --- a/msg/OneToOneMsg.cpp +++ b/msg/OneToOneMsg.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "OneToOneMsg.h" // Initializing static variables diff --git a/msg/SingleMsg.cpp b/msg/SingleMsg.cpp index c8ba6f00..fd02beb3 100644 --- a/msg/SingleMsg.cpp +++ b/msg/SingleMsg.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "SingleMsg.h" // Initializing static variables diff --git a/msg/testMsg.cpp b/msg/testMsg.cpp index 90d7fae5..a8fa0f6d 100644 --- a/msg/testMsg.cpp +++ b/msg/testMsg.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "../builtins/Arith.h" #include "../shell/Shell.h" diff --git a/pymoose/CMakeLists.txt b/pymoose/CMakeLists.txt index 3c69dacd..22f4613e 100644 --- a/pymoose/CMakeLists.txt +++ b/pymoose/CMakeLists.txt @@ -1,77 +1,98 @@ cmake_minimum_required(VERSION 2.8) +include( ${CMAKE_CURRENT_SOURCE_DIR}/../CheckCXXCompiler.cmake) -set(PYMOOSE_SRCS - moosemodule.cpp - vec.cpp - mfield.cpp - pymooseinit.cpp - melement.cpp - PyRun.cpp - test_moosemodule.cpp - ) - -# Build _moose.so in source directory and them copy everything to -# current binary directory using cmake. -add_library( _moose MODULE ${PYMOOSE_SRCS} ) -set(PYMOOSE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/python/moose") +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake_modules/") find_package(PythonInterp REQUIRED) + +# Find Numpy +find_package(NumPy REQUIRED) +include_directories(${NUMPY_INCLUDE_DIRS}) +add_definitions( -std=c++11 ) +add_definitions(-DUSE_NUMPY) +add_definitions(-DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION) + +# set module extensiton. default is .so. Also check ../python/setup.cmake.py execute_process( COMMAND ${PYTHON_EXECUTABLE} -c - "import importlib.machinery +"import importlib.machinery print(importlib.machinery.EXTENSION_SUFFIXES[-1])" OUTPUT_VARIABLE PYTHON_SO_EXTENSION OUTPUT_STRIP_TRAILING_WHITESPACE ) if(NOT PYTHON_SO_EXTENSION) + message(STATUS "Python so ext could not be determined. Using default .so") set(PYTHON_SO_EXTENSION ".so") endif() -message( STATUS "Python so extension ${PYTHON_SO_EXTENSION}" ) +message(STATUS "Python so extension ${PYTHON_SO_EXTENSION}" ) -find_package(NumPy REQUIRED) -include_directories(${NUMPY_INCLUDE_DIRS}) -add_definitions(-DUSE_NUMPY) +# TARGET +set(PYMOOSE_SRCS + moosemodule.cpp + vec.cpp + mfield.cpp + pymooseinit.cpp + melement.cpp + PyRun.cpp + test_moosemodule.cpp + ) -add_definitions(-DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION) +# Build python module in source directory and them copy everything to +# current binary directory using cmake. +add_library( _moose MODULE ${PYMOOSE_SRCS} ) +set(PYMOOSE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../python/moose") +message(STATUS "Python module will be saved to ${PYMOOSE_OUTPUT_DIRECTORY}" ) # make sure the Python.h is found. -find_package( PythonLibs REQUIRED) -include_directories( ${PYTHON_INCLUDE_DIRS} ) +find_package( PythonLibs) +if(PYTHON_INCLUDE_DIRS) + include_directories( ${PYTHON_INCLUDE_DIRS} ) +else() + # Use python executable to find include paths. For building wheel, we are + # stuck with cmake-2.8 with which PythonLibs module might fail. + message( STATUS "Using ${PYTHON_EXECUTABLE}-config to find Python.h" ) + 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}" + ) -#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}" ) +endif() +# Remove prefix lib from python module. +if(NOT(PYTHON_SO_EXTENSION STREQUAL "")) + set_target_properties(_moose PROPERTIES SUFFIX ${PYTHON_SO_EXTENSION}) +endif() set_target_properties(_moose PROPERTIES - COMPILE_DEFINITIONS "PYMOOSE" - COMPILE_FLAGS "${PYTHON_INCLUDE_FLAGS}" LIBRARY_OUTPUT_DIRECTORY ${PYMOOSE_OUTPUT_DIRECTORY} PREFIX "" SUFFIX ${PYTHON_SO_EXTENSION} ) -if(NOT(PYTHON_SO_EXTENSION STREQUAL "")) - set_target_properties(_moose PROPERTIES - SUFFIX ${PYTHON_SO_EXTENSION}) -endif() - # see issue #80 -if(HDF5_LIBRARY_DIRS) +if(HDF5_FOUND AND WITH_NSDF) set_target_properties( _moose PROPERTIES LINK_FLAGS "-L${HDF5_LIBRARY_DIRS}" ) endif() -if(MACOSX) +if(APPLE) set(CMAKE_MODULE_LINKER_FLAGS "-undefined dynamic_lookup") message(STATUS "ADDING some linker flags ${CMAKE_EXE_LINKER_FLAGS}") -endif(MACOSX) +endif(APPLE) + +# cmake --help-policy CMP0042 +if(APPLE) + set_target_properties( _moose PROPERTIES MACOSX_RPATH OFF) +endif(APPLE) -if(MACOSX) +if(APPLE) target_link_libraries( _moose "-Wl,-all_load" ${MOOSE_LIBRARIES} @@ -80,7 +101,7 @@ if(MACOSX) target_link_libraries(_moose ${SYSTEM_SHARED_LIBS} ) -else(MACOSX) +else(APPLE) target_link_libraries(_moose "-Wl,--whole-archive" ${MOOSE_LIBRARIES} @@ -88,7 +109,7 @@ else(MACOSX) "-Wl,--no-whole-archive" ${SYSTEM_SHARED_LIBS} ) -endif(MACOSX) +endif(APPLE) add_custom_command(TARGET _moose POST_BUILD COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --cyan "MOOSE python extention is successfully built. Now " diff --git a/pymoose/moosemodule.cpp b/pymoose/moosemodule.cpp index fe702125..5e811d02 100644 --- a/pymoose/moosemodule.cpp +++ b/pymoose/moosemodule.cpp @@ -36,9 +36,9 @@ #include "../utility/utility.h" #include "../shell/Shell.h" #include "../shell/Wildcard.h" +#include "../basecode/global.h" #include "moosemodule.h" -#include "global.h" using namespace std; diff --git a/pymoose/pymooseinit.cpp b/pymoose/pymooseinit.cpp index 29200a67..add0fee1 100644 --- a/pymoose/pymooseinit.cpp +++ b/pymoose/pymooseinit.cpp @@ -7,28 +7,23 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" -#ifndef WIN32 -#include <sys/time.h> -#else +#include "../basecode/header.h" #include <time.h> -#endif #include <math.h> #include <queue> -#ifdef WIN32 -#include "../external/xgetopt/XGetopt.h" -#else #include <unistd.h> // for getopt -#endif #include "../scheduling/Clock.h" -#include "DiagonalMsg.h" -#include "SparseMatrix.h" -#include "SparseMsg.h" +#include "../msg/DiagonalMsg.h" +#include "../basecode/SparseMatrix.h" +#include "../msg/SparseMsg.h" #include "../mpi/PostMaster.h" + #ifdef USE_MPI #include <mpi.h> #endif + #include "../shell/Shell.h" + #ifdef MACOSX #include <sys/sysctl.h> #endif // MACOSX diff --git a/python/moose/OrderedDict.py b/python/moose/OrderedDict.py index cf7e1716..3f217842 100644 --- a/python/moose/OrderedDict.py +++ b/python/moose/OrderedDict.py @@ -14,7 +14,6 @@ try: except ImportError: pass - class OrderedDict(dict): 'Dictionary that remembers insertion order' # An inherited dict maps keys to values. diff --git a/python/moose/SBML/readSBML.py b/python/moose/SBML/readSBML.py index d9b0e90f..f8e74f7e 100644 --- a/python/moose/SBML/readSBML.py +++ b/python/moose/SBML/readSBML.py @@ -13,10 +13,11 @@ ** copyright (C) 2003-2017 Upinder S. Bhalla. and NCBS Created : Thu May 13 10:19:00 2016(+0530) Version -Last-Updated: Fri May 21 11:21:00 2018(+0530) +Last-Updated: Fri Oct 26 11:21:00 2018(+0530) By:HarshaRani **********************************************************************/ 2018 +Oct 26: - validator can be switchedoff by passing validate="off" while readSBML files May 18: - cleanedup and connected cplx pool to correct parent enzyme Jan 6: - only if valid model exists, then printing the no of compartment,pool,reaction etc - at reaction level a check made to see if path exist while creating a new reaction @@ -77,7 +78,7 @@ try: except ImportError: pass -def mooseReadSBML(filepath, loadpath, solver="ee"): +def mooseReadSBML(filepath, loadpath, solver="ee",validate="on"): """Load SBML model """ global foundLibSBML_ @@ -100,7 +101,10 @@ def mooseReadSBML(filepath, loadpath, solver="ee"): filep = open(filepath, "r") document = libsbml.readSBML(filepath) tobecontinue = False - tobecontinue = validateModel(document) + if validate == "on": + tobecontinue = validateModel(document) + else: + tobecontinue = True if tobecontinue: level = document.getLevel() version = document.getVersion() diff --git a/python/moose/SBML/validation.py b/python/moose/SBML/validation.py index e9670fa1..48facdf0 100644 --- a/python/moose/SBML/validation.py +++ b/python/moose/SBML/validation.py @@ -112,5 +112,6 @@ def validateModel(sbmlDoc): # consistencyMessages) if __name__ == '__main__': + import libsbml sbmlDoc = libsbml.readSBML('00001-sbml-l3v1.xml') validateModel(sbmlDoc) diff --git a/python/moose/SBML/writeSBML.py b/python/moose/SBML/writeSBML.py index 8124611b..a3d898d4 100644 --- a/python/moose/SBML/writeSBML.py +++ b/python/moose/SBML/writeSBML.py @@ -18,8 +18,11 @@ Last-Updated: Mon 30 Apr 15:10:00 2018(+0530) **********************************************************************/ /**************************** 2018 +Oct 16: CylMesh's comparment volume is written, but zeroth volex details are populated +Oct 13: CylMesh are written to SBML with annotation field and only zeroth element/voxel (incase of cylMesh) of moose object is written +Oct 1 : corrected the spell of CyclMesh-->CylMesh, negating the yaxis for kkit is removed Apr 30: indentation corrected while writting annotation for enzymecomplex -Jan 6: for Product_formation_, k3 units depends on noofSub, prd was passed which is fixed +Jan 6 : for Product_formation_, k3 units depends on noofSub, prd was passed which is fixed 2017 Dec 15: If model path exists is checked Enz cplx is written only if enz,cplx,sub, prd exist, a clean check is made @@ -32,17 +35,12 @@ Aug 3 : Added recalculatecoordinates,cleanup in groupName ''' import sys import re +import os import moose from moose.SBML.validation import validateModel from moose.chemUtil.chemConnectUtil import * from moose.chemUtil.graphUtils import * - -# ToDo: -# Table should be written -# boundary condition for buffer pool having assignment statment constant -# shd be false - foundLibSBML_ = False try: from libsbml import * @@ -78,10 +76,12 @@ def mooseWriteSBML(modelpath, filename, sceneitems={}): if not moose.exists(modelpath): return False, "Path doesn't exist" elif moose.exists(modelpath): - mObj = moose.wildcardFind(moose.element(modelpath).path+'/##[ISA=PoolBase]'+','+ - moose.element(modelpath).path+'/##[ISA=ReacBase]'+','+ - moose.element(modelpath).path+'/##[ISA=EnzBase]'+','+ - moose.element(modelpath).path+'/##[ISA=StimulusTable]') + checkCompt = moose.wildcardFind(modelpath+'/##[0][ISA=ChemCompt]') + + mObj = moose.wildcardFind(moose.element(modelpath).path+'/##[0][ISA=PoolBase]'+','+ + moose.element(modelpath).path+'/##[0][ISA=ReacBase]'+','+ + moose.element(modelpath).path+'/##[0][ISA=EnzBase]'+','+ + moose.element(modelpath).path+'/##[0][ISA=StimulusTable]') for p in mObj: if not isinstance(moose.element(p.parent),moose.CplxEnzBase): if moose.exists(p.path+'/info'): @@ -107,7 +107,7 @@ def mooseWriteSBML(modelpath, filename, sceneitems={}): cremodel_.setLengthUnits("length") neutralNotes = "" - specieslist = moose.wildcardFind(modelpath + '/##[ISA=PoolBase]') + specieslist = moose.wildcardFind(modelpath + '/##[0][ISA=PoolBase]') if specieslist: neutralPath = getGroupinfo(specieslist[0]) if moose.exists(neutralPath.path + '/info'): @@ -122,18 +122,24 @@ def mooseWriteSBML(modelpath, filename, sceneitems={}): srcdesConnection = {} writeUnits(cremodel_) + modelAnno = writeSimulationAnnotation(modelpath) if modelAnno: cremodel_.setAnnotation(modelAnno) groupInfo = {} + compartexist, groupInfo = writeCompt(modelpath, cremodel_) + if compartexist == True: species = writeSpecies( modelpath,cremodel_,sbmlDoc,sceneitems,groupInfo) if species: writeFunc(modelpath, cremodel_) reacGroup = {} + writeReac(modelpath, cremodel_, sceneitems,groupInfo) + writeEnz(modelpath, cremodel_, sceneitems,groupInfo) + if groupInfo: for key,value in groupInfo.items(): mplugin = cremodel_.getPlugin("groups") @@ -157,6 +163,7 @@ def mooseWriteSBML(modelpath, filename, sceneitems={}): for values in value: member = group.createMember() member.setIdRef(values) + consistencyMessages = "" SBMLok = validateModel(sbmlDoc) if (SBMLok): @@ -170,13 +177,9 @@ def mooseWriteSBML(modelpath, filename, sceneitems={}): return -1, consistencyMessages else: return False, "Atleast one compartment should exist to write SBML" - -def calPrime(x): - prime = int((20 * (float(x - cmin) / float(cmax - cmin))) - 10) - return prime - + def writeEnz(modelpath, cremodel_, sceneitems,groupInfo): - for enz in moose.wildcardFind(modelpath + '/##[ISA=EnzBase]'): + for enz in moose.wildcardFind(modelpath + '/##[0][ISA=EnzBase]'): enzannoexist = False enzGpnCorCol = " " cleanEnzname = convertSpecialChar(enz.name) @@ -639,7 +642,7 @@ def listofname(reacSub, mobjEnz): def writeReac(modelpath, cremodel_, sceneitems,reacGroup): - for reac in moose.wildcardFind(modelpath + '/##[ISA=ReacBase]'): + for reac in moose.wildcardFind(modelpath + '/##[0][ISA=ReacBase]'): reacSub = reac.neighbors["sub"] reacPrd = reac.neighbors["prd"] if (len(reacSub) != 0 and len(reacPrd) != 0): @@ -772,7 +775,7 @@ def writeReac(modelpath, cremodel_, sceneitems,reacGroup): def writeFunc(modelpath, cremodel_): - funcs = moose.wildcardFind(modelpath + '/##[ISA=Function]') + funcs = moose.wildcardFind(modelpath + '/##[0][ISA=Function]') # if func: foundFunc = False for func in funcs: @@ -833,7 +836,7 @@ def getGroupinfo(element): # if /modelpath/Compartment/Group/Group1/Pool, then I check and get Group1 # And /modelpath is also a NeutralObject,I stop till I find Compartment - while not mooseIsInstance(element, ["Neutral", "CubeMesh", "CyclMesh"]): + while not mooseIsInstance(element, ["Neutral", "CubeMesh", "CylMesh"]): element = element.parent return element @@ -845,7 +848,7 @@ def idBeginWith(name): return changedName def findGroup_compt(melement): - while not (mooseIsInstance(melement, ["Neutral","CubeMesh", "CyclMesh"])): + while not (mooseIsInstance(melement, ["Neutral","CubeMesh", "CylMesh"])): melement = melement.parent return melement @@ -874,7 +877,7 @@ def convertSpecialChar(str1): def writeSpecies(modelpath, cremodel_, sbmlDoc, sceneitems,speGroup): # getting all the species - for spe in moose.wildcardFind(modelpath + '/##[ISA=PoolBase]'): + for spe in moose.wildcardFind(modelpath + '/##[0][ISA=PoolBase]'): sName = convertSpecialChar(spe.name) comptVec = findCompartment(spe) speciannoexist = False @@ -986,14 +989,25 @@ def writeSpecies(modelpath, cremodel_, sbmlDoc, sceneitems,speGroup): def writeCompt(modelpath, cremodel_): # getting all the compartments - compts = moose.wildcardFind(modelpath + '/##[ISA=ChemCompt]') + compts = moose.wildcardFind(modelpath + '/##[0][ISA=ChemCompt]') groupInfo = {} for compt in compts: + comptAnno = "" comptName = convertSpecialChar(compt.name) # converting m3 to litre - size = compt.volume * pow(10, 3) + if isinstance(compt,moose.CylMesh): + size = (compt.volume/compt.numDiffCompts)*pow(10,3) + comptAnno = "<moose:CompartmentAnnotation><moose:Mesh>" + \ + str(compt.className) + "</moose:Mesh>\n" + \ + "<moose:numDiffCompts>" + \ + str(compt.numDiffCompts)+ "</moose:numDiffCompts>\n" + \ + "</moose:CompartmentAnnotation>" + else: + size = compt.volume * pow(10, 3) ndim = compt.numDimensions c1 = cremodel_.createCompartment() + if comptAnno: + c1.setAnnotation(comptAnno) c1.setId(str(idBeginWith(comptName + "_" + str(compt.getId().value) + @@ -1002,11 +1016,12 @@ def writeCompt(modelpath, cremodel_): "_"))) c1.setName(comptName) c1.setConstant(True) - c1.setSize(size) + c1.setSize(compt.volume*pow(10,3)) + #c1.setSize(size) c1.setSpatialDimensions(ndim) c1.setUnits('volume') #For each compartment get groups information along - for grp in moose.wildcardFind(compt.path+'/##[TYPE=Neutral]'): + for grp in moose.wildcardFind(compt.path+'/##[0][TYPE=Neutral]'): grp_cmpt = findGroup_compt(grp.parent) try: value = groupInfo[moose.element(grp)] @@ -1020,6 +1035,7 @@ def writeCompt(modelpath, cremodel_): else: return False,groupInfo # write Simulation runtime,simdt,plotdt + def writeSimulationAnnotation(modelpath): modelAnno = "" plots = "" @@ -1036,7 +1052,8 @@ def writeSimulationAnnotation(modelpath): modelAnno = modelAnno + "<moose:plotdt> " + \ str(mooseclock.dts[18]) + " </moose:plotdt>\n" plots = "" - graphs = moose.wildcardFind(modelpath + "/##[TYPE=Table2]") + graphs = moose.wildcardFind(modelpath + "/##[0][TYPE=Table2]") + for gphs in range(0, len(graphs)): gpath = graphs[gphs].neighbors['requestOut'] if len(gpath) != 0: @@ -1044,7 +1061,7 @@ def writeSimulationAnnotation(modelpath): ori = q.path name = convertSpecialChar(q.name) graphSpefound = False - while not(isinstance(moose.element(q), moose.CubeMesh)): + while not(isinstance(moose.element(q), moose.CubeMesh) or isinstance(moose.element(q),moose.CylMesh)): q = q.parent graphSpefound = True if graphSpefound: @@ -1055,17 +1072,12 @@ def writeSimulationAnnotation(modelpath): else: plots = plots + "; "+ori[ori.find(q.name)-1:len(ori)] #plots = plots + "; /" + q.name + '/' + name + if plots != " ": modelAnno = modelAnno + "<moose:plots> " + plots + "</moose:plots>\n" modelAnno = modelAnno + "</moose:ModelAnnotation>" return modelAnno -def xyPosition(objInfo,xory): - try: - return(float(moose.element(objInfo).getField(xory))) - except ValueError: - return (float(0)) - def recalculatecoordinates(modelpath, mObjlist,xcord,ycord): positionInfoExist = not(len(np.nonzero(xcord)[0]) == 0 \ and len(np.nonzero(ycord)[0]) == 0) @@ -1081,7 +1093,7 @@ def recalculatecoordinates(modelpath, mObjlist,xcord,ycord): objInfo = merts.path+'/info' if moose.exists(objInfo): Ix = defaultsceneWidth * ((xyPosition(objInfo,'x')-xmin)/(xmax-xmin)) - Iy = defaultsceneHeight * ((ymin-xyPosition(objInfo,'y'))/(ymax-ymin)) + Iy = defaultsceneHeight * ((xyPosition(objInfo,'y')-ymin)/(ymax-ymin)) moose.element(objInfo).x = Ix moose.element(objInfo).y = Iy diff --git a/python/moose/__init__.py b/python/moose/__init__.py index ceec0ffd..407b6950 100644 --- a/python/moose/__init__.py +++ b/python/moose/__init__.py @@ -1,8 +1,13 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, division, print_function -# Bring moose.py functions into global namespace. - +# Bring everything from moose.py to global namespace. from moose.moose import * -__version__ = version( ) +# Bring everything from c++ module to global namespace. Not everything is +# imported by the pervios import statement. +from moose._moose import * + +# create a shorthand for version() call here. +__version__ = version() + diff --git a/python/moose/chemMerge/merge.py b/python/moose/chemMerge/merge.py index d3d80058..6b37ae44 100644 --- a/python/moose/chemMerge/merge.py +++ b/python/moose/chemMerge/merge.py @@ -714,17 +714,7 @@ def checkexist(spList,objB,objA): return allexist -def findCompartment(element): - while not mooseIsInstance(element,["CubeMesh","CyclMesh"]): - element = element.parent - return element - -def mooseIsInstance(element, classNames): - return moose.element(element).__class__.__name__ in classNames - - if __name__ == "__main__": - try: sys.argv[1] except IndexError: diff --git a/python/moose/chemUtil/chemConnectUtil.py b/python/moose/chemUtil/chemConnectUtil.py index f4cbccbc..bbb18ed5 100644 --- a/python/moose/chemUtil/chemConnectUtil.py +++ b/python/moose/chemUtil/chemConnectUtil.py @@ -1,8 +1,6 @@ # -*- coding: utf-8 -*- """ ChemconnectUtil.py Some of the command function are written """ -#Created : Friday May 27 12:19:00 2016(+0530) - __author__ = "Harsha Rani" __copyright__ = "Copyright 2017, Harsha Rani and NCBS Bangalore" __credits__ = ["NCBS Bangalore"] @@ -13,16 +11,14 @@ __email__ = "hrani@ncbs.res.in" __status__ = "Development" __updated__ = "Aug 8 2017" -#Aug 8 : added findCompartment function here - import moose import numpy as np def xyPosition(objInfo,xory): try: - return(float(moose.element(objInfo).getField(xory))) - except ValueError: - return (float(0)) + return float(moose.element(objInfo).getField(xory)) + except ValueError as e: + return float(0) def setupMeshObj(modelRoot): ''' Setup compartment and its members pool,reaction,enz cplx under self.meshEntry dictionaries \ @@ -94,9 +90,6 @@ def setupMeshObj(modelRoot): ymax = max(ycord) return meshEntry,xmin,xmax,ymin,ymax,positionInfoExist,listOfitems -def sizeHint(self): - return QtCore.QSize(800,400) - def getxyCord(xcord,ycord,list1,listOfitems): for item in list1: # if isinstance(item,Function): @@ -200,7 +193,7 @@ def countitems(mitems,objtype): def findCompartment(element): if element.path == '/': return moose.element('/') - elif mooseIsInstance(element, ["CubeMesh", "CyclMesh"]): + elif mooseIsInstance(element, ["CubeMesh", "CylMesh"]): return (element) else: return findCompartment(moose.element(element.parent)) diff --git a/python/moose/fixXreacs.py b/python/moose/fixXreacs.py index de7bec63..7009390f 100644 --- a/python/moose/fixXreacs.py +++ b/python/moose/fixXreacs.py @@ -1,3 +1,6 @@ +# -*- coding: utf-8 -*- +from __future__ import print_function, division, absolute_import + #################################################################### # fixXreacs.py # The program is meant to take a model and reconfigure any cross-compartment @@ -10,17 +13,16 @@ # This program carries no warranty whatsoever. #################################################################### - import sys -import moose +import moose._moose as _moose msgSeparator = "_xMsg_" def findCompt( elm ): - elm = moose.element( elm ) + elm = _moose.element( elm ) pa = elm.parent while pa.path != '/': - if moose.Neutral(pa).isA[ 'ChemCompt' ]: + if _moose.Neutral(pa).isA[ 'ChemCompt' ]: return pa.path pa = pa.parent print( 'Error: No compartment parent found for ' + elm.path ) @@ -31,7 +33,7 @@ def checkEqual(lst): return not lst or lst.count(lst[0]) == len(lst) def findXreacs( basepath, reacType ): - reacs = moose.wildcardFind( basepath + '/##[ISA=' + reacType + 'Base]' ) + reacs = _moose.wildcardFind( basepath + '/##[ISA=' + reacType + 'Base]' ) ret = [] for i in reacs: reacc = findCompt( i ) @@ -48,38 +50,38 @@ def findXreacs( basepath, reacType ): return ret def removeEnzFromPool( pool ): - kids = moose.wildcardFind( pool.path + "/#" ) + kids = _moose.wildcardFind( pool.path + "/#" ) for i in kids: if i.isA[ 'EnzBase' ]: - moose.delete( i ) + _moose.delete( i ) elif i.isA[ 'Function' ]: - moose.delete( i ) + _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 ) + 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 + #_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 ) + 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 = _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 ) + _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 ) + enze = _moose.element( enz ) # kcat and k2 are indept of volume, just time^-1 km = enze.numKm proxify( enz, enzc, direction, pool, poolc ) @@ -88,7 +90,7 @@ def enzProxify( enz, enzc, direction, pool, poolc ): def reacProxify( reac, reacc, direction, pool, poolc ): if reacc == poolc: return - reac_elm = moose.element( reac ) + reac_elm = _moose.element( reac ) kf = reac_elm.numKf kb = reac_elm.numKb proxify( reac, reacc, direction, pool, poolc ) @@ -106,26 +108,26 @@ def identifyMsg( src, srcOut, dest ): def disconnectReactant( reacOrEnz, reactant, duppool ): outMsgs = reacOrEnz.msgOut infoPath = duppool.path + '/info' - if moose.exists( infoPath ): - info = moose.element( infoPath ) + if _moose.exists( infoPath ): + info = _moose.element( infoPath ) else: - info = moose.Annotator( infoPath ) + info = _moose.Annotator( infoPath ) - #moose.le( reactant ) + #_moose.le( reactant ) notes = "" - #moose.showmsg( reacOrEnz ) + #_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 ) + _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 ) + _moose.delete( i ) #print "MSGS to rebuild:", notes info.notes += notes @@ -152,7 +154,7 @@ def fixXreacs( basepath ): def getOldRates( msgs ): if len( msgs ) > 1 : m1 = msgs[1].split( msgSeparator )[0] - elm = moose.element( m1.split( ' ' )[0] ) + elm = _moose.element( m1.split( ' ' )[0] ) if elm.isA[ 'ReacBase' ]: return [elm.numKf, elm.numKb] elif elm.isA[ 'EnzBase' ]: @@ -164,7 +166,7 @@ def restoreOldRates( oldRates, msgs ): #print oldRates, msgs if len( msgs ) > 1 : m1 = msgs[1].split( msgSeparator )[0] - elm = moose.element( m1.split( ' ' )[0] ) + elm = _moose.element( m1.split( ' ' )[0] ) if elm.isA[ 'ReacBase' ]: elm.numKf = oldRates[0] elm.numKb = oldRates[1] @@ -174,20 +176,20 @@ def restoreOldRates( oldRates, msgs ): def restoreXreacs( basepath ): - proxyInfo = moose.wildcardFind( basepath + "/##/#_xfer_#/info" ) + 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 ) + _moose.delete( i.parent ) for j in msgs[1:]: 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] ) + #_moose.showfield( args[0] ) + _moose.connect( args[0], args[1], args[2], args[3] ) #print( "Reconnecting {}".format( args ) ) - #moose.showfield( args[0] ) + #_moose.showfield( args[0] ) restoreOldRates( oldRates, msgs ) diff --git a/python/moose/genesis/writeKkit.py b/python/moose/genesis/writeKkit.py index f6bba42b..c03a77aa 100644 --- a/python/moose/genesis/writeKkit.py +++ b/python/moose/genesis/writeKkit.py @@ -9,8 +9,11 @@ __version__ = "1.0.0" __maintainer__ = "Harsha Rani" __email__ = "hrani@ncbs.res.in" __status__ = "Development" -__updated__ = "Aug 8 2017" +__updated__ = "Oct 23 2018" +# 2018 +# Oct 16: Channels are written back to genesis +# only zeroth element is taken for written back to genesis, this is true for CubeMesh and CylMesh # 2017 # Aug 8 : All the moose object which doesn't have compartment are not written. Error message are appended @@ -69,7 +72,7 @@ def mooseWriteKkit( modelpath, filename, sceneitems={}): cmin, xmin, ymin = 0, 0, 0 cmax, xmax, ymax = 1, 1, 1 - compt = moose.wildcardFind(modelpath+'/##[ISA=ChemCompt]') + compt = moose.wildcardFind(modelpath+'/##[0][ISA=ChemCompt]') maxVol = estimateDefaultVol(compt) positionInfoExist = True if compt: @@ -108,16 +111,19 @@ def mooseWriteKkit( modelpath, filename, sceneitems={}): enzList,error = writeEnz(modelpath,f,sceneitems) errors = errors+error - error = writeSumtotal(modelpath,f) + chanList, error = writeConcChan(modelpath,f,sceneitems) errors = errors+error error = writeStimulus(modelpath,f) errors = errors+error + error = writeSumtotal(modelpath,f) + errors = errors+error + #writeSumtotal(modelpath,f) f.write("simundump xgraph /graphs/conc1 0 0 99 0.001 0.999 0\n" "simundump xgraph /graphs/conc2 0 0 100 0 1 0\n") - tgraphs = moose.wildcardFind(modelpath+'/##[ISA=Table2]') + tgraphs = moose.wildcardFind(modelpath+'/##[0][ISA=Table2]') first, second = " ", " " if tgraphs: first,second = writeplot(tgraphs,f) @@ -133,6 +139,7 @@ def mooseWriteKkit( modelpath, filename, sceneitems={}): "simundump xtext /file/notes 0 1\n") storeReacMsg(reacList,f) storeEnzMsg(enzList,f) + storeChanMsg(chanList,f) if tgraphs: storePlotMsgs(tgraphs,f) writeFooter1(f) @@ -171,7 +178,7 @@ def calPrime(x): def storeCplxEnzMsgs( enz, f ): for sub in enz.neighbors["subOut"]: - s = "addmsg /kinetics/" + trimPath( sub ) + " /kinetics/" + trimPath(enz) + " SUBSTRATE n \n"; + s = "addmsg /kinetics/" + trimPath( moose.element(sub) ) + " /kinetics/" + trimPath(enz) + " SUBSTRATE n \n"; s = s+ "addmsg /kinetics/" + trimPath( enz ) + " /kinetics/" + trimPath( sub ) + " REAC sA B \n"; f.write(s) for prd in enz.neighbors["prd"]: @@ -206,9 +213,72 @@ def storeEnzMsg( enzList, f): else: storeCplxEnzMsgs( enz, f ) +def storeChanMsg(chanList,f): + for channel in chanList: + for chanOL in channel.neighbors['out']: + eo = "addmsg /kinetics/" + trimPath(moose.element(channel)) + " /kinetics/" + trimPath(moose.element(chanOL))+ " REAC B A \n"; + eo = eo +"addmsg /kinetics/" + trimPath(moose.element(chanOL)) + " /kinetics/"+trimPath(moose.element(channel))+" PRODUCT n vol \n"; + f.write(eo) + + for chanIL in channel.neighbors['in']: + ei = "addmsg /kinetics/" + trimPath(moose.element(channel)) + " /kinetics/" + trimPath(moose.element(chanIL))+ " REAC A B \n"; + ei = ei +"addmsg /kinetics/" + trimPath(moose.element(chanIL)) + " /kinetics/"+trimPath(moose.element(channel))+" SUBSTRATE n vol \n"; + f.write(ei) + + for chanSNC in channel.neighbors['setNumChan']: + cff = "addmsg /kinetics/"+trimPath(moose.element(chanSNC))+ " /kinetics/"+trimPath(moose.element(channel))+ " NUMCHAN n \n" + f.write(cff) + +def writeConcChan(modelpath,f,sceneitems): + error = "" + concChanList = moose.wildcardFind(modelpath+'/##[0][ISA=ConcChan]') + for cChan in concChanList: + if findCompartment(cChan) == moose.element('/'): + error = error + " \n "+cChan.path+ " doesn't have compartment ignored to write to genesis" + else: + x = random.randrange(0,10) + y = random.randrange(0,10) + textcolor = "" + color = "" + if len(moose.element(cChan).neighbors['setNumChan']) == 1: + chanParent = moose.element(moose.element(cChan).neighbors['setNumChan'][0]) + + if not (isinstance(chanParent,moose.PoolBase)): + print(" raise exception Channel doesn't have pool as parent %s",moose.element(cChan).path) + return False,"raise exception Channel doesn't have pool as parent" + else: + vol = chanParent.volume * NA * 1e-3; + + cinfo = cChan.path+'/info' + if moose.exists(cinfo): + x = moose.Annotator(cinfo).getField('x') + y = moose.Annotator(cinfo).getField('y') + #x = sceneitems[cChan]['x'] + #y = sceneitems[cChan]['y'] + color = moose.Annotator(cinfo).getField('color') + color = getColorCheck(color,GENESIS_COLOR_SEQUENCE) + + textcolor = moose.Annotator(cinfo).getField('textColor') + textcolor = getColorCheck(textcolor,GENESIS_COLOR_SEQUENCE) + else: + error = error + "\n x and y co-ordinates are not specified for `" + cChan.name+ "` zero will be assigned \n " + if color == "" or color == " ": + color = getRandColor() + if textcolor == "" or textcolor == " ": + textcolor = getRandColor() + f.write("simundump kchan /kinetics/" + trimPath(cChan)+ " " + str(int(1)) + " " + str(cChan.permeability)+ " " + + str(int(0)) + " " + + str(int(0)) + " " + + str(int(0)) + " " + + str(int(0)) + " " + + str("") + " " + + str(textcolor) + " " + str(color) + " \"\"" + + " " + str(int(x)) + " " + str(int(y)) + " "+str(int(0))+"\n") + + return concChanList,error def writeEnz( modelpath,f,sceneitems): error = "" - enzList = moose.wildcardFind(modelpath+'/##[ISA=EnzBase]') + enzList = moose.wildcardFind(modelpath+'/##[0][ISA=EnzBase]') for enz in enzList: if findCompartment(enz) == moose.element('/'): error = error + " \n "+enz.path+ " doesn't have compartment ignored to write to genesis" @@ -313,7 +383,7 @@ def storeReacMsg(reacList,f): def writeReac(modelpath,f,sceneitems): error = "" - reacList = moose.wildcardFind(modelpath+'/##[ISA=ReacBase]') + reacList = moose.wildcardFind(modelpath+'/##[0][ISA=ReacBase]') for reac in reacList: if findCompartment(reac) == moose.element('/'): error = error + " \n "+reac.path+ " doesn't have compartment ignored to write to genesis" @@ -385,7 +455,7 @@ def trimPath(mobj): def writeSumtotal( modelpath,f): error = "" - funclist = moose.wildcardFind(modelpath+'/##[ISA=Function]') + funclist = moose.wildcardFind(modelpath+'/##[0][ISA=Function]') s = "" for func in funclist: fInfound = True @@ -420,7 +490,7 @@ def writeSumtotal( modelpath,f): def writeStimulus(modelpath,f): error = "" - if len(moose.wildcardFind(modelpath+'/##[ISA=StimulusTable]')): + if len(moose.wildcardFind(modelpath+'/##[0][ISA=StimulusTable]')): error = error +'\n StimulusTable is not written into genesis. This is in Todo List' return error @@ -501,7 +571,8 @@ def writePool(modelpath,f,volIndex,sceneitems): error = "" color = "" textcolor = "" - for p in moose.wildcardFind(modelpath+'/##[ISA=PoolBase]'): + + for p in moose.wildcardFind(modelpath+'/##[0][ISA=PoolBase]'): if findCompartment(p) == moose.element('/'): error = error + " \n "+p.path+ " doesn't have compartment ignored to write to genesis" else: @@ -541,9 +612,8 @@ def writePool(modelpath,f,volIndex,sceneitems): color = getColorCheck(color,GENESIS_COLOR_SEQUENCE) textcolor = moose.Annotator(pinfo).getField('textColor') textcolor = getColorCheck(textcolor,GENESIS_COLOR_SEQUENCE) - - - geometryName = volIndex[p.volume] + poolsCmpt = findCompartment(p) + geometryName = volIndex[float(poolsCmpt.volume)] volume = p.volume * NA * 1e-3 if color == "" or color == " ": color = getRandColor() @@ -616,6 +686,10 @@ def writeCompartment(modelpath,compts,f): l = len(compts) geometry = "" for compt in compts: + # if isinstance(compt,moose.CylMesh): + # print " 1 " + # size = (compt.volume/compt.numDiffCompts) + # else: size = compt.volume ndim = compt.numDimensions vecIndex = l-i-1 @@ -624,17 +698,18 @@ def writeCompartment(modelpath,compts,f): y = ymax+1 if vecIndex > 0: geometry = geometry+"simundump geometry /kinetics" + "/geometry[" + str(vecIndex) +"] 0 " + str(size) + " " + str(ndim) + " sphere " +" \"\" white black "+ str(int(x)) + " " +str(int(y)) +" 0\n"; - volIndex[size] = "/geometry["+str(vecIndex)+"]" + volIndex[float(size)] = "/geometry["+str(vecIndex)+"]" else: + geometry = geometry+"simundump geometry /kinetics" + "/geometry 0 " + str(size) + " " + str(ndim) + " sphere " +" \"\" white black " + str(int(x)) + " "+str(int(y))+ " 0\n"; - volIndex[size] = "/geometry" - f.write(geometry) + volIndex[float(size)] = "/geometry" + f.write(geometry) writeGroup(modelpath,f) return volIndex def writeGroup(modelpath,f): ignore = ["graphs","moregraphs","geometry","groups","conc1","conc2","conc3","conc4","model","data","graph_0","graph_1","graph_2","graph_3","graph_4","graph_5"] - for g in moose.wildcardFind(modelpath+'/##[TYPE=Neutral]'): + for g in moose.wildcardFind(modelpath+'/##[0][TYPE=Neutral]'): if not g.name in ignore: if trimPath(g) != None: x = xmin+1 @@ -705,12 +780,12 @@ def writeNotes(modelpath,f): notes = "" #items = moose.wildcardFind(modelpath+"/##[ISA=ChemCompt],/##[ISA=ReacBase],/##[ISA=PoolBase],/##[ISA=EnzBase],/##[ISA=Function],/##[ISA=StimulusTable]") items = [] - items = moose.wildcardFind(modelpath+"/##[ISA=ChemCompt]") +\ - moose.wildcardFind(modelpath+"/##[ISA=PoolBase]") +\ - moose.wildcardFind(modelpath+"/##[ISA=ReacBase]") +\ - moose.wildcardFind(modelpath+"/##[ISA=EnzBase]") +\ - moose.wildcardFind(modelpath+"/##[ISA=Function]") +\ - moose.wildcardFind(modelpath+"/##[ISA=StimulusTable]") + items = moose.wildcardFind(modelpath+"/##[0][ISA=ChemCompt]") +\ + moose.wildcardFind(modelpath+"/##[0][ISA=PoolBase]") +\ + moose.wildcardFind(modelpath+"/##[0][ISA=ReacBase]") +\ + moose.wildcardFind(modelpath+"/##[0][ISA=EnzBase]") +\ + moose.wildcardFind(modelpath+"/##[0][ISA=Function]") +\ + moose.wildcardFind(modelpath+"/##[0][ISA=StimulusTable]") for item in items: if moose.exists(item.path+'/info'): info = item.path+'/info' @@ -741,4 +816,4 @@ if __name__ == "__main__": if written: print(" file written to ",output) else: - print(" could be written to kkit format") + print(" could be written to kkit format") \ No newline at end of file diff --git a/python/moose/hdfutil.py b/python/moose/hdfutil.py index 3d1fd80a..bae19268 100644 --- a/python/moose/hdfutil.py +++ b/python/moose/hdfutil.py @@ -84,12 +84,12 @@ # # Code: -from __future__ import print_function +from __future__ import print_function, division, absolute_import try: from future_builtins import zip except ImportError: pass -from . import moose as moose__ +import moose import numpy as np import h5py as h5 import time @@ -123,8 +123,8 @@ def get_rec_dtype(em): if em.className in dtype_table: dtype = dtype_table[em.className] else: - print('Creating entries for class:', obj.className) - fielddict = moose__.getFieldDict(obj.className, 'valueFinfo') + print('Creating entries for class:', em.className) + fielddict = moose.getFieldDict(em.className, 'valueFinfo') print(fielddict) # If we do not have the type of this field in cpp-np data @@ -137,8 +137,8 @@ def get_rec_dtype(em): fields = [(fieldname, cpptonp[ftype]) # [('path', 'S1024')] for fieldname, ftype in sorted(fielddict.items()) if ftype in cpptonp] - dtype_table[obj.className] = np.dtype(fields) - return dtype_table[obj.className] + dtype_table[em.className] = np.dtype(fields) + return dtype_table[em.className] def save_dataset(classname, rec, dtype, hdfnode): """Saves the data from rec into dataset""" @@ -211,15 +211,15 @@ def loadtree(hdfnode, moosenode): shape = dims[path] em = moose.vec(rpath, shape, classname) wfields = {} - for cinfo in moose__.element('/classes').children: + for cinfo in moose.element('/classes').children: cname = cinfo[0].name - wfields[cname] = [f[len('set_'):] for f in moose__.getFieldNames(cname, 'destFinfo') + wfields[cname] = [f[len('set_'):] for f in moose.getFieldNames(cname, 'destFinfo') if f.startswith('set_') and f not in ['set_this', 'set_name', 'set_lastDimension', 'set_runTime'] and not f.startswith('set_num_')] for key in hdfnode['/elements']: dset = hdfnode['/elements/'][key][:] fieldnames = dset.dtype.names for ii in range(len(dset)): - obj = moose__.element(dset['path'][ii][len(basepath):]) + obj = moose.element(dset['path'][ii][len(basepath):]) for f in wfields[obj.className]: obj.setField(f, dset[f][ii]) @@ -244,7 +244,7 @@ def savestate(filename=None): class_count_dict = {} class_array_dict = {} objcount = 0 - for obj in moose__.wildcardFind("/##"): + for obj in moose.wildcardFind("/##"): if obj.path.startswith('/Msg') or obj.path.startswith('/class') or obj.className == 'Table' or obj.className == 'TableEntry': continue print('Processing:', obj.path, obj.className) @@ -257,7 +257,7 @@ def savestate(filename=None): # If we do not yet have dataset for this class, create one and keep it in dict if obj.className not in class_dataset_dict: print('Creating entries for class:', obj.className) - fielddict = moose__.getFieldDict(obj.className, 'valueFinfo') + fielddict = moose.getFieldDict(obj.className, 'valueFinfo') print(fielddict) keys = sorted(fielddict) fields = [] # [('path', 'S1024')] @@ -280,7 +280,7 @@ def savestate(filename=None): for f in ds.dtype.names: print('getting field:', f) entry.getField(f) - fields = [f.path if isinstance(f, moose__.vec) or isinstance(f, moose__.element) else f for f in fields] + fields = [f.path if isinstance(f, moose.vec) or isinstance(f, moose.element) else f for f in fields] class_array_dict[obj.className].append(fields) # print 'fields:' # print fields @@ -305,9 +305,9 @@ def savestate(filename=None): def restorestate(filename): wfields = {} - for cinfo in moose__.element('/classes').children: + for cinfo in moose.element('/classes').children: cname = cinfo[0].name - wfields[cname] = [f[len('set_'):] for f in moose__.getFieldNames(cname, 'destFinfo') + wfields[cname] = [f[len('set_'):] for f in moose.getFieldNames(cname, 'destFinfo') if f.startswith('set_') and f not in ['set_this', 'set_name', 'set_lastDimension', 'set_runTime'] and not f.startswith('set_num_')] with h5.File(filename, 'r') as fd: typeinfo = fd['/metadata/typeinfo'][:] @@ -318,12 +318,12 @@ def restorestate(filename): sorted_paths = sorted(typeinfo['path'], key=lambda x: x.count('/')) for path in sorted_paths: name = path.rpartition('/')[-1].partition('[')[0] - moose__.vec(parentdict[path] + '/' + name, eval(dimsdict[path]), classdict[path]) + moose.vec(parentdict[path] + '/' + name, eval(dimsdict[path]), classdict[path]) for key in fd['/elements']: dset = fd['/elements/'][key][:] fieldnames = dset.dtype.names for ii in range(len(dset)): - obj = moose__.element(dset['path'][ii]) + obj = moose.element(dset['path'][ii]) for f in wfields[obj.className]: obj.setField(f, dset[f][ii]) diff --git a/python/moose/moose.py b/python/moose/moose.py index b9acb706..a55bc7be 100644 --- a/python/moose/moose.py +++ b/python/moose/moose.py @@ -4,18 +4,20 @@ from __future__ import print_function, division, absolute_import # Author: Subhasis Ray # Maintainer: Dilawar Singh, Harsha Rani, Upi Bhalla -from __future__ import print_function, division, absolute_import - -from contextlib import closing import warnings import pydoc -from io import StringIO -from os.path import splitext import moose import moose.utils as mu +from io import StringIO +from os.path import splitext +from contextlib import closing -sbmlImport_, sbmlError_ = True, '' +# Import function from C++ module into moose namespace. +# from moose._moose import * +import moose._moose as _moose +# sbml import. +sbmlImport_, sbmlError_ = True, '' try: import moose.SBML.readSBML as _readSBML import moose.SBML.writeSBML as _writeSBML @@ -29,10 +31,10 @@ try: import moose.neuroml2 as _neuroml2 except Exception as e: nml2Import_ = False - nml2ImportError_ = '\n'.join( [ + nml2ImportError_ = ' '.join( [ "NML2 support is disabled because `libneuroml` and " - , "`pyneuroml` modules are not found." - , " pip install pyneuroml libneuroml " + , "`pyneuroml` modules are not found.\n" + , " $ pip install pyneuroml libneuroml \n" , " should fix it." , " Actual error: %s " % e ] ) @@ -58,16 +60,6 @@ except Exception as e: mergechemImport_ = False mergechemError_ = '%s' % 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: @@ -98,8 +90,10 @@ def loadModel(filename, target,method=None): chemError_ = _chemUtil.add_Delete_ChemicalSolver.mooseAddChemSolver(target,method) return ret +# Version def version( ): - return VERSION + # Show user version. + return moose._moose.VERSION # Tests from moose.moose_test import test @@ -128,7 +122,7 @@ known_types = ['void', 'melement'] + sequence_types # SBML related functions. -def mooseReadSBML(filepath, loadpath, solver='ee'): +def mooseReadSBML(filepath, loadpath, solver='ee',validate="on"): """Load SBML model. keyword arguments: \n @@ -140,7 +134,7 @@ def mooseReadSBML(filepath, loadpath, solver='ee'): """ global sbmlImport_ if sbmlImport_: - return _readSBML.mooseReadSBML( filepath, loadpath, solver ) + return _readSBML.mooseReadSBML( filepath, loadpath, solver,validate ) else: print( sbmlError_ ) return False @@ -228,35 +222,31 @@ def mergeChemModel(src, des): return False # NML2 reader and writer function. -def mooseReadNML2( modelpath ): - """Read NeuroML model (version 2). - +def mooseReadNML2( modelpath, verbose = False ): + """Read NeuroML model (version 2) and return reader object. """ global nml2Import_ - if nml2Import_: - reader = _neuroml2.NML2Reader( ) - reader.read( modelpath ) - return reader - else: - mu.info( nml2ImportError_ ) - mu.warn( "Could not load NML2 support. Doing nothing" ) - return False + if not nml2Import_: + mu.warn( nml2ImportError_ ) + raise RuntimeError( "Could not load NML2 support." ) + + reader = _neuroml2.NML2Reader( verbose = verbose ) + reader.read( modelpath ) + return reader def mooseWriteNML2( outfile ): - mu.warn( "Writing to NML2 is not supported yet" ) + raise NotImplementedError( "Writing to NML2 is not supported yet" ) ################################################################ # Wrappers for global functions ################################################################ - - def pwe(): """Print present working element. Convenience function for GENESIS users. If you want to retrieve the element in stead of printing the path, use moose.getCwe() """ - pwe_ = moose.getCwe() + pwe_ = _moose.getCwe() print(pwe_.getPath()) return pwe_ @@ -277,19 +267,19 @@ def le(el=None): """ if el is None: - el = getCwe() + el = _moose.getCwe() elif isinstance(el, str): - if not exists(el): + if not _moose.exists(el): raise ValueError('no such element') - el = element(el) - elif isinstance(el, vec): + el = _moose.element(el) + elif isinstance(el, _moose.vec): el = el[0] print('Elements under', el.path) for ch in el.children: print(ch.path) return [child.path for child in el.children] -ce = setCwe # ce is a GENESIS shorthand for change element. +ce = _moose.setCwe # ce is a GENESIS shorthand for change element. def syncDataHandler(target): @@ -313,10 +303,10 @@ def syncDataHandler(target): raise NotImplementedError('The implementation is not working for IntFire - goes to invalid objects. \ First fix that issue with SynBase or something in that line.') if isinstance(target, str): - if not moose.exists(target): + if not _moose.exists(target): raise ValueError('%s: element does not exist.' % (target)) - target = vec(target) - moose.syncDataHandler(target) + target = _moose.vec(target) + _moose.syncDataHandler(target) def showfield(el, field='*', showtype=False): @@ -341,11 +331,11 @@ def showfield(el, field='*', showtype=False): """ if isinstance(el, str): - if not exists(el): + if not _moose.exists(el): raise ValueError('no such element') - el = element(el) + el = _moose.element(el) if field == '*': - value_field_dict = getFieldDict(el.className, 'valueFinfo') + value_field_dict = _moose.getFieldDict(el.className, 'valueFinfo') max_type_len = max(len(dtype) for dtype in value_field_dict.values()) max_field_len = max(len(dtype) for dtype in value_field_dict.keys()) print('\n[', el.path, ']') @@ -401,7 +391,7 @@ def listmsg(el): connections of `el`. """ - obj = element(el) + obj = _moose.element(el) ret = [] for msg in obj.inMsg: ret.append(msg) @@ -423,7 +413,7 @@ def showmsg(el): None """ - obj = element(el) + obj = _moose.element(el) print('INCOMING:') for msg in obj.msgIn: print( @@ -471,7 +461,7 @@ def getfielddoc(tokens, indent=''): fieldname = tokens[1] while True: try: - classelement = moose.element('/classes/' + classname) + classelement = _moose.element('/classes/' + classname) for finfo in classelement.children: for fieldelement in finfo: baseinfo = '' @@ -530,12 +520,13 @@ def getmoosedoc(tokens, inherited=False): """ indent = ' ' - with closing(StringIO()) as docstring: + docstring = StringIO() + with closing(docstring): if not tokens: return "" try: - class_element = moose.element('/classes/%s' % (tokens[0])) - except ValueError: + class_element = _moose.element('/classes/%s' % (tokens[0])) + except ValueError as e: raise NameError('name \'%s\' not defined.' % (tokens[0])) if len(tokens) > 1: docstring.write(toUnicode(getfielddoc(tokens))) @@ -543,14 +534,14 @@ def getmoosedoc(tokens, inherited=False): docstring.write(toUnicode('%s\n' % (class_element.docs))) append_finfodocs(tokens[0], docstring, indent) if inherited: - mro = eval('moose.%s' % (tokens[0])).mro() + mro = eval('_moose.%s' % (tokens[0])).mro() for class_ in mro[1:]: - if class_ == moose.melement: + if class_ == _moose.melement: break docstring.write(toUnicode( '\n\n#Inherited from %s#\n' % (class_.__name__))) append_finfodocs(class_.__name__, docstring, indent) - if class_ == moose.Neutral: # Neutral is the toplevel moose class + if class_ == _moose.Neutral: # Neutral is the toplevel moose class break return docstring.getvalue() @@ -558,13 +549,13 @@ def getmoosedoc(tokens, inherited=False): def append_finfodocs(classname, docstring, indent): """Append list of finfos in class name to docstring""" try: - class_element = moose.element('/classes/%s' % (classname)) + class_element = _moose.element('/classes/%s' % (classname)) except ValueError: raise NameError('class \'%s\' not defined.' % (classname)) for ftype, rname in finfotypes: docstring.write(toUnicode('\n*%s*\n' % (rname.capitalize()))) try: - finfo = moose.element('%s/%s' % (class_element.path, ftype)) + finfo = _moose.element('%s/%s' % (class_element.path, ftype)) for field in finfo.vec: docstring.write(toUnicode( '%s%s: %s\n' % (indent, field.fieldName, field.type))) @@ -625,7 +616,7 @@ def doc(arg, inherited=True, paged=True): tokens = tokens[1:] elif isinstance(arg, type): tokens = [arg.__name__] - elif isinstance(arg, melement) or isinstance(arg, vec): + elif isinstance(arg, _moose.melement) or isinstance(arg, _moose.vec): text = '%s: %s\n\n' % (arg.path, arg.className) tokens = [arg.className] if tokens: diff --git a/python/moose/moose_test.py b/python/moose/moose_test.py index eeab9f94..362a590e 100644 --- a/python/moose/moose_test.py +++ b/python/moose/moose_test.py @@ -29,9 +29,7 @@ import time logging.basicConfig( level=logging.DEBUG, format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s', - datefmt='%m-%d %H:%M', - filename='tests.log', - filemode='w' + datefmt='%m-%d %H:%M' ) console = logging.StreamHandler() console.setLevel(logging.WARNING) @@ -182,7 +180,7 @@ def test_all( timeout, **kwargs ): _logger.info( 'Total %d valid tests found' % len( scripts ) ) total_ = len( scripts ) for i, s in enumerate( scripts ): - _logger.info( 'Running test : %s' % s ) + _logger.info( 'Running test (timeout=%s) : %s' % (timeout,s)) run_test(i, s, timeout, **kwargs ) diff --git a/python/moose/neuroml/ChannelML.py b/python/moose/neuroml/ChannelML.py index d658bddf..73ded19c 100644 --- a/python/moose/neuroml/ChannelML.py +++ b/python/moose/neuroml/ChannelML.py @@ -13,16 +13,16 @@ readChannelMLFromFile(...) to load a standalone ChannelML file (synapse/channel) readChannelML(...) / readSynapseML to load from an xml.etree xml element (could be part of a larger NeuroML file). """ -from __future__ import print_function +from __future__ import print_function, division from xml.etree import cElementTree as ET import string -import os, sys +import os +import sys import math - import moose from moose.neuroml import utils -from moose import utils as moose_utils -from moose import print_utils as pu +import moose.utils as mu +import moose.print_utils as pu class ChannelML(): @@ -402,7 +402,7 @@ class ChannelML(): def make_cml_function(self, element, fn_name, concdep=None): fn_type = element.attrib['expr_form'] if fn_type in ['exponential','sigmoid','exp_linear']: - fn = self.make_function( fn_name, fn_type, rate=float(element.attrib['rate']),\ + self.make_function( fn_name, fn_type, rate=float(element.attrib['rate']),\ midpoint=float(element.attrib['midpoint']), scale=float(element.attrib['scale'] ) ) elif fn_type == 'generic': ## OOPS! These expressions should be in SI units, since I converted to SI @@ -415,7 +415,7 @@ class ChannelML(): else: ca_name = ','+concdep.attrib['variable_name'] # Ca dependence expr_string = expr_string.replace( 'alpha', 'self.alpha(v'+ca_name+')') expr_string = expr_string.replace( 'beta', 'self.beta(v'+ca_name+')') - fn = self.make_function( fn_name, fn_type, expr_string=expr_string, concdep=concdep ) + self.make_function( fn_name, fn_type, expr_string=expr_string, concdep=concdep ) else: pu.fatal("Unsupported function type %s "% fn_type) sys.exit() @@ -465,11 +465,13 @@ class ChannelML(): val = eval(alternativeFalse,{"__builtins__":None},allowed_locals) else: val = eval(expr_str,{"__builtins__" : None},allowed_locals) - if fn_name == 'tau': return val/self.q10factor - else: return val - + if fn_name == 'tau': + return val/self.q10factor + else: + return val fn.__name__ = fn_name setattr(self.__class__, fn.__name__, fn) + return None def make_new_synapse(syn_name, postcomp, syn_name_full, nml_params): @@ -483,7 +485,7 @@ def make_new_synapse(syn_name, postcomp, syn_name_full, nml_params): else: raise IOError( 'For mechanism {0}: files {1} not found under {2}.'.format( - mechanismname, model_filename, self.model_dir + syn_name, model_filename, nml_params['model_dir'] ) ) ## deep copies the library SynChan and SynHandler @@ -497,7 +499,7 @@ def make_new_synapse(syn_name, postcomp, syn_name_full, nml_params): ## connect the SimpleSynHandler or the STDPSynHandler to the SynChan (double exp) moose.connect( synhandler, 'activationOut', syn, 'activation' ) # mgblock connections if required - childmgblock = moose_utils.get_child_Mstring(syn,'mgblockStr') + childmgblock = mu.get_child_Mstring(syn,'mgblockStr') #### connect the post compartment to the synapse if childmgblock.value=='True': # If NMDA synapse based on mgblock, connect to mgblock mgblock = moose.Mg_block(syn.path+'/mgblock') diff --git a/python/moose/neuroml/MorphML.py b/python/moose/neuroml/MorphML.py index b89f76e9..57b983cf 100644 --- a/python/moose/neuroml/MorphML.py +++ b/python/moose/neuroml/MorphML.py @@ -259,15 +259,18 @@ class MorphML(): if cableid in self.intFireCableIds: mechanismname = self.intFireCableIds[cableid] if mechanismname is not None: # this cableid is an intfire - ## create LIF (subclass of Compartment) and set to default values + # create LIF (subclass of Compartment) and set to default values moosecomp = moose.LIF(moosecomppath) - moosechannel = moose.Neutral('/library/'+mechanismname) + mname = '/library/' + mechanismname + moosechannel = moose.element(mname) if moose.exists(mname) else moose.Neutral(mname) + # Mstring values are 'string'; make sure to convert them to + # float else it will seg-fault with python3+ moosechannelval = moose.Mstring(moosechannel.path+'/vReset') - moosecomp.vReset = moosechannelval.value + moosecomp.vReset = float(moosechannelval.value) moosechannelval = moose.Mstring(moosechannel.path+'/thresh') - moosecomp.thresh = moosechannelval.value + moosecomp.thresh = float( moosechannelval.value ) moosechannelval = moose.Mstring(moosechannel.path+'/refracT') - moosecomp.refractoryPeriod = moosechannelval.value + moosecomp.refractoryPeriod = eval(moosechannelval.value) ## refracG is currently not supported by moose.LIF ## when you implement it, check if refracG or g_refrac ## is a conductance density or a conductance, I think the former diff --git a/python/moose/neuroml/NetworkML.py b/python/moose/neuroml/NetworkML.py index b400ce23..a2b9d030 100644 --- a/python/moose/neuroml/NetworkML.py +++ b/python/moose/neuroml/NetworkML.py @@ -179,7 +179,7 @@ class NetworkML(): model_filenames = (cellname+'.xml', cellname+'.morph.xml') success = False for model_filename in model_filenames: - model_path = find_first_file(model_filename,self.model_dir) + model_path = find_first_file(model_filename, self.model_dir) if model_path is not None: cellDict = mmlR.readMorphMLFromFile(model_path, self.params) success = True @@ -267,7 +267,7 @@ class NetworkML(): else: raise IOError( 'For mechanism {0}: files {1} not found under {2}.'.format( - mechanismname, model_filename, self.model_dir + syn_name, model_filename, self.model_dir ) ) weight = float(syn_props.attrib['weight']) diff --git a/python/moose/neuroml/NeuroML.py b/python/moose/neuroml/NeuroML.py index e558f443..e63fbb4e 100644 --- a/python/moose/neuroml/NeuroML.py +++ b/python/moose/neuroml/NeuroML.py @@ -1,8 +1,12 @@ # -*- coding: utf-8 -*- -## Description: class NeuroML for loading NeuroML from single file into MOOSE -## Version 1.0 by Aditya Gilra, NCBS, Bangalore, India, 2011 for serial MOOSE -## Version 1.5 by Niraj Dudani, NCBS, Bangalore, India, 2012, ported to parallel MOOSE -## Version 1.6 by Aditya Gilra, NCBS, Bangalore, India, 2012, further changes for parallel MOOSE +from __future__ import print_function, division + +# Description: class NeuroML for loading NeuroML from single file into MOOSE +# Version 1.0 by Aditya Gilra, NCBS, Bangalore, India, 2011 for serial MOOSE +# Version 1.5 by Niraj Dudani, NCBS, Bangalore, India, 2012, ported to parallel MOOSE +# Version 1.6 by Aditya Gilra, NCBS, Bangalore, India, 2012, further changes for parallel MOOSE +# Maintainer: Dilawar Singh, dilawars@ncbs.res.in +# - python3 related fixes. """ NeuroML.py is the preferred interface to read NeuroML files. @@ -15,7 +19,8 @@ readNeuroMLFromFile(...) to load NeuroML from a file: OR -(b) the file could have only L3 (network) with L2 (channels/synapses) and L1 (cells) spread over multiple files; +(b) the file could have only L3 (network) with L2 (channels/synapses) and L1 +(cells) spread over multiple files; these multiple files should be in the same or lower-level directory named as <chan/syn_name>.xml or <cell_name>.xml or <cell_name>.morph.xml (essentially as generated by neuroConstruct's export). @@ -44,9 +49,8 @@ In [2]: import moose.neuroml In [3]: moose.neuroml.loadNeuroML_L123('Generated.net.xml') """ -from __future__ import print_function import moose -from moose.utils import * +import moose.utils as mu from xml.etree import cElementTree as ET from moose.neuroml.ChannelML import ChannelML from moose.neuroml.MorphML import MorphML @@ -57,32 +61,27 @@ from moose.neuroml.utils import * import sys from os import path -import logging -console = logging.StreamHandler() -console.setLevel(logging.INFO) -formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') -console.setFormatter(formatter) -_logger = logging.getLogger('moose.nml.neuroml') -_logger.addHandler(console) - - class NeuroML(): def __init__(self): pass - def readNeuroMLFromFile(self,filename,params={},cellsDict={}): + def readNeuroMLFromFile(self, filename, params={}, cellsDict={}): """ For the format of params required to tweak what cells are loaded, refer to the doc string of NetworkML.readNetworkMLFromFile(). Returns (populationDict,projectionDict), see doc string of NetworkML.readNetworkML() for details. """ - _logger.info("Loading neuroml file %s " % filename) + mu.info("Loading neuroml file %s " % filename) moose.Neutral('/library') # creates /library in MOOSE tree; elif present, wraps tree = ET.parse(filename) root_element = tree.getroot() - self.model_dir = path.dirname( path.abspath( filename ) ) + + # if model_path is given in params, use it else use the directory of NML + # as model_dir. + self.model_dir = params.get('model_dir', path.dirname(path.abspath(filename))) + if 'lengthUnits' in list(root_element.attrib.keys()): self.lengthUnits = root_element.attrib['lengthUnits'] else: @@ -110,14 +109,14 @@ class NeuroML(): self.temperature = float(tag.find('.//{'+meta_ns+'}value').text) self.temperature_default = False if self.temperature_default: - _logger.info("Using default temperature of %s degree Celsius" % self.temperature) + mu.info("Using default temperature of %s degree Celsius" % self.temperature) self.nml_params = { 'temperature':self.temperature, 'model_dir':self.model_dir, } - _logger.debug("Loading channels and synapses into MOOSE /library ...") + mu.debug("Loading channels and synapses into MOOSE /library ...") cmlR = ChannelML(self.nml_params) for channels in root_element.findall('.//{'+neuroml_ns+'}channels'): self.channelUnits = channels.attrib['units'] @@ -131,7 +130,7 @@ class NeuroML(): for ionConc in channels.findall('.//{'+cml_ns+'}ion_concentration'): cmlR.readIonConcML(ionConc,units=self.channelUnits) - _logger.debug("Loading cell definitions into MOOSE /library ...") + mu.debug("Loading cell definitions into MOOSE /library ...") mmlR = MorphML(self.nml_params) self.cellsDict = cellsDict for cells in root_element.findall('.//{'+neuroml_ns+'}cells'): @@ -145,7 +144,7 @@ class NeuroML(): and root_element.find('.//{'+nml_ns+'}populations') is None: return (self.cellsDict,'no populations (L3 NetworkML) found.') else: - _logger.debug("Loading individual cells into MOOSE root ... ") + mu.debug("Loading individual cells into MOOSE root ... ") nmlR = NetworkML(self.nml_params) return nmlR.readNetworkML(root_element,self.cellsDict,\ params=params,lengthUnits=self.lengthUnits) @@ -163,6 +162,6 @@ def loadNeuroML_L123(filename): if __name__ == "__main__": if len(sys.argv)<2: - _logger.error("You need to specify the neuroml filename.") + mu.error("You need to specify the neuroml filename.") sys.exit(1) print(loadNeuroML_L123(sys.argv[1])) diff --git a/python/moose/neuroml2/converter.py b/python/moose/neuroml2/converter.py deleted file mode 100644 index 37dc7307..00000000 --- a/python/moose/neuroml2/converter.py +++ /dev/null @@ -1,207 +0,0 @@ -# -*- coding: utf-8 -*- -# converter.py --- -# -# Filename: mtoneuroml.py -# Description: -# Author: -# Maintainer: -# Created: Mon Apr 22 12:15:23 2013 (+0530) -# Version: -# Last-Updated: Wed Jul 10 16:36:14 2013 (+0530) -# By: subha -# Update #: 819 -# URL: -# Keywords: -# Compatibility: -# -# - -# Commentary: -# -# Utility for converting a MOOSE model into NeuroML2. This uses Python -# libNeuroML. -# -# - -# Change log: -# -# Tue May 21 16:58:03 IST 2013 - Subha moved the code for function -# fitting to hhfit.py. - -# -# -# 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. -# -# - -# Code: - -#!!!!! TODO: unit conversion !!!! - -try: - from future_builtins import zip -except ImportError: - pass -import traceback -import warnings -from collections import deque -import numpy as np -from scipy.optimize import curve_fit -from matplotlib import pyplot as plt - -import moose -from moose.utils import autoposition -import neuroml -import hhfit - - -def convert_morphology(root, positions='auto'): - """Convert moose neuron morphology contained under `root` into a - NeuroML object. The id of the return object is - {root.name}_morphology. Each segment object gets the numeric value - of the moose id of the object. The name of the segments are same - as the corresponding moose compartment. - - Parameters - ---------- - root : a moose element containing a single cell model. - - positions : string - flag to indicate if the positions of the end points of the - compartments are explicitly available in the compartments or - should be automatically generated. Possible values: - - `auto` - automatically generate z coordinates using length of the - compartments. - - `explicit` - model has explicit coordinates for all compartments. - - Return - ------ - a neuroml.Morphology instance. - - """ - if positions == 'auto': - queue = deque([autoposition(root)]) - elif positions == 'explicit': - compartments = moose.wildcardFind('%s/##[TYPE=Compartment]' % (root.path)) - queue = deque([compartment for compartment in map(moose.element, compartments) - if len(compartment.neighbours['axial']) == 0]) - if len(queue) != 1: - raise Exception('There must be one and only one top level compartment. Found %d' % (len(topcomp_list))) - else: - raise Exception('allowed values for keyword argument positions=`auto` or `explicit`') - comp_seg = {} - parent = None - while len(queue) > 0: - compartment = queue.popleft() - proximal = neuroml.Point3DWithDiam(x=compartment.x0, - y=compartment.y0, - z=compartment.z0, - diameter=compartment.diameter) - distal = neuroml.Point3DWithDiam(x=compartment.x, - y=compartment.y, - z=compartment.z, - diameter=compartment.diameter) - plist = list(map(moose.element, compartment.neighbours['axial'])) - try: - parent = neuroml.SegmentParent(segments=comp_seg[moose.element(plist[0])].id) - except (KeyError, IndexError) as e: - parent = None - segment = neuroml.Segment(id=compartment.id_.value, - proximal=proximal, - distal=distal, - parent=parent) - # TODO: For the time being using numerical value of the moose - # id for neuroml id.This needs to be updated for handling - # array elements - segment.name = compartment.name - comp_seg[compartment] = segment - queue.extend([comp for comp in map(moose.element, compartment.neighbours['raxial'])]) - morph = neuroml.Morphology(id='%s_morphology' % (root.name)) - morph.segments.extend(comp_seg.values()) - return morph - - -def define_vdep_rate(fn, name): - """Define new component type with generic expressions for voltage - dependent rate. - - """ - ctype = neuroml.ComponentType(name) - # This is going to be ugly ... - - - -def convert_hhgate(gate): - """Convert a MOOSE gate into GateHHRates in NeuroML""" - hh_rates = neuroml.GateHHRates(id=gate.id_.value, name=gate.name) - alpha = gate.tableA.copy() - beta = gate.tableB - alpha - vrange = np.linspace(gate.min, gate.max, len(alpha)) - afn, ap = hhfit.find_ratefn(vrange, alpha) - bfn, bp = hhfit.find_ratefn(vrange, beta) - if afn is None: - raise Exception('could not find a fitting function for `alpha`') - if bfn is None: - raise Exception('could not find a fitting function for `alpha`') - afn_type = fn_rate_map[afn] - afn_component_type = None - if afn_type is None: - afn_type, afn_component_type = define_component_type(afn) - hh_rates.forward_rate = neuroml.HHRate(type=afn_type, - midpoint='%gmV' % (ap[2]), - scale='%gmV' % (ap[1]), - rate='%gper_ms' % (ap[0])) - bfn_type = fn_rate_map[bfn] - bfn_component_type = None - if bfn_type is None: - bfn_type, bfn_component_type = define_component_type(bfn) - hh_rates.reverse_rate = neuroml.HHRate(type=bfn_type, - midpoint='%gmV' % (bp[2]), - scale='%gmV' % (bp[1]), - rate='%gper_ms' % (bp[0])) - return hh_rates, afn_component_type, bfn_component_type - - -def convert_hhchannel(channel): - """Convert a moose HHChannel object into a neuroml element. - - TODO: need to check useConcentration option for Ca2+ and V - dependent gates. How to handle generic expressions??? - - """ - nml_channel = neuroml.IonChannel(id=channel.id_.value, - name=channel.name, - type='ionChannelHH', - conductance=channel.Gbar) - if channel.Xpower > 0: - hh_rate_x = convert_hhgate(channel.gateX[0]) - hh_rate_x.instances = channel.Xpower - nml_channel.gate.append(hh_rate_x) - if channel.Ypower > 0: - hh_rate_y = convert_hhgate(channel.gateY[0]) - hh_rate_y.instances = channel.Ypower - nml_channel.gate.append(hh_rate_y) - if channel.Zpower > 0: - hh_rate_z = convert_hhgate(channel.gateZ[0]) - hh_rate_y.instances = channel.Zpower - nml_channel.gate.append(hh_rate_z) - return nml_channel - - -# -# converter.py ends here diff --git a/python/moose/neuroml2/hhfit.py b/python/moose/neuroml2/hhfit.py index c4eb3391..e82effda 100644 --- a/python/moose/neuroml2/hhfit.py +++ b/python/moose/neuroml2/hhfit.py @@ -133,7 +133,7 @@ def double_exp(x, a, k1, x1, k2, x2, y0=0): ret = np.zeros(len(x)) try: ret = a / (np.exp(k1 * (x - x1)) + np.exp(k2 * (x - x2))) + y0 - except RuntimeWaring as e: + except RuntimeWarning as e: traceback.print_exc() return ret diff --git a/python/moose/neuroml2/reader.py b/python/moose/neuroml2/reader.py index 1fdf4fc1..2f2e2d85 100644 --- a/python/moose/neuroml2/reader.py +++ b/python/moose/neuroml2/reader.py @@ -1,4 +1,6 @@ # -*- coding: utf-8 -*- +from __future__ import print_function, division, absolute_import + # reader.py --- # # Filename: reader.py @@ -9,50 +11,12 @@ # Version: # Last-Updated: 15 Jan 2018, pgleeson # 16 Jan 2018, dilawar, python3 compatible imports. -# -# 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. -# -# - -# Code: -"""Implementation of reader for NeuroML 2 models. - +# +"""Implementation of reader for NeuroML 2 models. TODO: handle morphologies of more than one segment... - """ -from __future__ import print_function, division, absolute_import - try: from future_builtins import zip, map except ImportError: @@ -64,12 +28,17 @@ import math import numpy as np import neuroml as nml from pyneuroml import pynml - import moose import moose.utils as mu - from .units import SI -from . import hhfit + + +def _unique( ls ): + res = [ ] + for l in ls: + if l not in res: + res.append( l ) + return res def sarea(comp): """ @@ -116,15 +85,13 @@ def setEk(comp, erev): def getSegments(nmlcell, component, sg_to_segments): """Get the list of segments the `component` is applied to""" sg = component.segment_groups - #seg = component.segment if sg is None: - segments = nmlcell.morphology.segments - elif sg == 'all': # Special case + segments = nmlcell.morphology.segments + elif sg == 'all': segments = [seg for seglist in sg_to_segments.values() for seg in seglist] else: segments = sg_to_segments[sg] - - return list(set(segments)) + return _unique(segments) class NML2Reader(object): @@ -148,10 +115,10 @@ class NML2Reader(object): self.filename = None self.nml_to_moose = {} # NeuroML object to MOOSE object self.moose_to_nml = {} # Moose object to NeuroML object - self.proto_cells = {} # map id to prototype cell in moose - self.proto_chans = {} # map id to prototype channels in moose - self.proto_pools = {} # map id to prototype pools (Ca2+, Mg2+) - self.includes = {} # Included files mapped to other readers + self.proto_cells = {} # map id to prototype cell in moose + self.proto_chans = {} # map id to prototype channels in moose + self.proto_pools = {} # map id to prototype pools (Ca2+, Mg2+) + self.includes = {} # Included files mapped to other readers self.lib = moose.Neutral('/library') self.id_to_ionChannel = {} self._cell_to_sg = {} # nml cell to dict - the dict maps segment groups to segments @@ -160,6 +127,7 @@ class NML2Reader(object): self.pop_to_cell_type = {} self.seg_id_to_comp_name = {} self.paths_to_chan_elements = {} + self.network = None def read(self, filename, symmetric=True): filename = os.path.realpath( filename ) @@ -172,9 +140,9 @@ class NML2Reader(object): if len(self.doc.networks)>=1: self.network = self.doc.networks[0] - moose.celsius = self._getTemperature() + self.importConcentrationModels(self.doc) self.importIonChannels(self.doc) self.importInputs(self.doc) @@ -189,20 +157,26 @@ class NML2Reader(object): mu.info("Read all from %s"%filename) def _getTemperature(self): - if self.network.type=="networkWithTemperature": - return SI(self.network.temperature) - else: - return 0 # Why not, if there's no temp dependence in nml..? + if self.network is not None: + if self.network.type=="networkWithTemperature": + return SI(self.network.temperature) + else: + # Why not, if there's no temp dependence in nml..? + return 0 + return SI('25') def getCellInPopulation(self, pop_id, index): return self.cells_in_populations[pop_id][index] def getComp(self, pop_id, cellIndex, segId): - return moose.element('%s/%s/%s/%s' % (self.lib.path, pop_id, cellIndex, self.seg_id_to_comp_name[self.pop_to_cell_type[pop_id]][segId])) + return moose.element('%s/%s/%s/%s' % ( self.lib.path, pop_id, cellIndex + , self.seg_id_to_comp_name[self.pop_to_cell_type[pop_id]][segId]) + ) def createPopulations(self): for pop in self.network.populations: - mpop = moose.Neutral('%s/%s' % (self.lib.path, pop.id)) + ep = '%s/%s' % (self.lib.path, pop.id) + mpop = moose.element(ep) if moose.exists(ep) else moose.Neutral(ep) self.cells_in_populations[pop.id] ={} for i in range(pop.size): mu.info("Creating %s/%s instances of %s under %s"%(i,pop.size,pop.component, mpop)) @@ -228,12 +202,15 @@ class NML2Reader(object): for il in self.network.input_lists: for ii in il.input: input = self.getInput(il.component) - moose.connect(input, 'output', self.getComp(il.populations,ii.get_target_cell_id(),ii.get_segment_id()), 'injectMsg') + moose.connect(input, 'output' + , self.getComp(il.populations,ii.get_target_cell__hash(),ii.get_segment__hash()) + , 'injectMsg') def createCellPrototype(self, cell, symmetric=True): """To be completed - create the morphology, channels in prototype""" - nrn = moose.Neuron('%s/%s' % (self.lib.path, cell.id)) + ep = '%s/%s' % (self.lib.path, cell.id) + nrn = moose.element(ep) if moose.exists(ep) else moose.Neuron(ep) self.proto_cells[cell.id] = nrn self.nml_to_moose[cell] = nrn self.moose_to_nml[nrn] = cell @@ -262,11 +239,13 @@ class NML2Reader(object): self.seg_id_to_comp_name[nmlcell.id]={} for seg in segments: if seg.name is not None: - id_to_comp[seg.id] = compclass('%s/%s' % (cellpath, seg.name)) + ep = '%s/%s' % (cellpath, seg.name) + id_to_comp[seg.id] = moose.element(ep) if moose.exists(ep) else compclass(ep) self.seg_id_to_comp_name[nmlcell.id][seg.id] = seg.name else: name = 'comp_%s'%seg.id - id_to_comp[seg.id] = compclass('%s/%s' % (cellpath, name)) + ep = '%s/%s' % (cellpath, name) + id_to_comp[seg.id] = moose.element(ep) if moose.exists(ep) else compclass(ep) self.seg_id_to_comp_name[nmlcell.id][seg.id] = name # Now assign the positions and connect up axial resistance if not symmetric: @@ -286,13 +265,15 @@ class NML2Reader(object): if parent: p0 = parent.distal else: - raise Exception('No proximal point and no parent segment for segment: name=%s, id=%s' % (segment.name, segment.id)) - comp.x0, comp.y0, comp.z0 = (x * self.lunit for x in map(float, (p0.x, p0.y, p0.z))) + raise Exception( + 'No proximal point and no parent segment for segment:'+\ + 'name=%s, id=%s' % (segment.name, segment.id) + ) + comp.x0, comp.y0, comp.z0 = (x*self.lunit for x in map(float, (p0.x, p0.y, p0.z))) p1 = segment.distal - comp.x, comp.y, comp.z = (x * self.lunit for x in map(float, (p1.x, p1.y, p1.z))) - comp.length = np.sqrt((comp.x - comp.x0)**2 - + (comp.y - comp.y0)**2 - + (comp.z - comp.z0)**2) + comp.x, comp.y, comp.z = (x*self.lunit for x in map(float, (p1.x, p1.y, p1.z))) + comp.length = np.sqrt((comp.x-comp.x0)**2+(comp.y-comp.y0)**2+(comp.z-comp.z0)**2) + # This can pose problem with moose where both ends of # compartment have same diameter. We are averaging the two # - may be splitting the compartment into two is better? @@ -377,10 +358,15 @@ class NML2Reader(object): proto_pool = innerReader.proto_pools[species.concentrationModel] break if not proto_pool: - raise Exception('No prototype pool for %s referred to by %s' % (species.concentration_model, species.id)) - pool_id = moose.copy(proto_pool, comp, species.id) + raise Exception('No prototype pool for %s referred to by %s' % ( + species.concentration_model, species.id) + ) + pool_id = moose.copy(proto_pool, compartment, species.id) pool = moose.element(pool_id) - pool.B = pool.B / (np.pi * compartment.length * (0.5 * compartment.diameter + pool.thickness) * (0.5 * compartment.diameter - pool.thickness)) + pool.B = pool.B / (np.pi * compartment.length * ( + 0.5 * compartment.diameter + pool.thickness) * + (0.5 * compartment.diameter - pool.thickness) + ) return pool def importAxialResistance(self, nmlcell, intracellularProperties): @@ -399,26 +385,27 @@ class NML2Reader(object): return False - rate_fn_map = { - 'HHExpRate': hhfit.exponential2, - 'HHSigmoidRate': hhfit.sigmoid2, - 'HHSigmoidVariable': hhfit.sigmoid2, - 'HHExpLinearRate': hhfit.linoid2 } - def calculateRateFn(self, ratefn, vmin, vmax, tablen=3000, vShift='0mV'): """Returns A / B table from ngate.""" + from . import hhfit + rate_fn_map = { + 'HHExpRate': hhfit.exponential2, + 'HHSigmoidRate': hhfit.sigmoid2, + 'HHSigmoidVariable': hhfit.sigmoid2, + 'HHExpLinearRate': hhfit.linoid2 } + tab = np.linspace(vmin, vmax, tablen) if self._is_standard_nml_rate(ratefn): midpoint, rate, scale = map(SI, (ratefn.midpoint, ratefn.rate, ratefn.scale)) - return self.rate_fn_map[ratefn.type](tab, rate, scale, midpoint) + return rate_fn_map[ratefn.type](tab, rate, scale, midpoint) else: for ct in self.doc.ComponentType: if ratefn.type == ct.name: mu.info("Using %s to evaluate rate"%ct.name) rate = [] for v in tab: - vals = pynml.evaluate_component(ct,req_variables={'v':'%sV'%v,'vShift':vShift,'temperature':self._getTemperature()}) - '''mu.info vals''' + req_vars = {'v':'%sV'%v,'vShift':vShift,'temperature':self._getTemperature()} + vals = pynml.evaluate_component(ct, req_variables = req_vars) if 'x' in vals: rate.append(vals['x']) if 't' in vals: @@ -427,6 +414,9 @@ class NML2Reader(object): rate.append(vals['r']) return np.array(rate) + print( "[WARN ] Could not determine rate: %s %s %s" %(ratefn.type,vmin,vmax)) + return np.array([]) + def importChannelsToCell(self, nmlcell, moosecell, membrane_properties): sg_to_segments = self._cell_to_sg[nmlcell] for chdens in membrane_properties.channel_densities + membrane_properties.channel_density_v_shifts: @@ -436,11 +426,13 @@ class NML2Reader(object): try: ionChannel = self.id_to_ionChannel[chdens.ion_channel] except KeyError: - mu.info('No channel with id', chdens.ion_channel) + mu.info('No channel with id: %s' % chdens.ion_channel) continue if self.verbose: - mu.info('Setting density of channel %s in %s to %s; erev=%s (passive: %s)'%(chdens.id, segments, condDensity,erev,self.isPassiveChan(ionChannel))) + mu.info('Setting density of channel %s in %s to %s; erev=%s (passive: %s)'%( + chdens.id, segments, condDensity,erev,self.isPassiveChan(ionChannel)) + ) if self.isPassiveChan(ionChannel): for seg in segments: @@ -483,32 +475,6 @@ class NML2Reader(object): moose.connect(chan, 'channel', comp, 'channel') return chan - ''' - def importIncludes(self, doc): - for include in doc.include: - if self.verbose: - mu.info(self.filename, 'Loading include', include) - error = None - inner = NML2Reader(self.verbose) - paths = [include.href, os.path.join(os.path.dirname(self.filename), include.href)] - for path in paths: - try: - inner.read(path) - if self.verbose: - mu.info(self.filename, 'Loaded', path, '... OK') - except IOError as e: - error = e - else: - self.includes[include.href] = inner - self.id_to_ionChannel.update(inner.id_to_ionChannel) - self.nml_to_moose.update(inner.nml_to_moose) - self.moose_to_nml.update(inner.moose_to_nml) - error = None - break - if error: - mu.info(self.filename, 'Last exception:', error) - raise IOError('Could not read any of the locations: %s' % (paths))''' - def _is_standard_nml_rate(self, rate): return rate.type=='HHExpLinearRate' \ or rate.type=='HHExpRate' or \ @@ -517,11 +483,12 @@ class NML2Reader(object): def createHHChannel(self, chan, vmin=-150e-3, vmax=100e-3, vdivs=5000): mchan = moose.HHChannel('%s/%s' % (self.lib.path, chan.id)) - mgates = map(moose.element, (mchan.gateX, mchan.gateY, mchan.gateZ)) - assert(len(chan.gate_hh_rates) <= 3) # We handle only up to 3 gates in HHCHannel + mgates = [moose.element(x) for x in [mchan.gateX, mchan.gateY, mchan.gateZ]] + assert len(chan.gate_hh_rates)<=3, "We handle only up to 3 gates in HHCHannel" if self.verbose: mu.info('== Creating channel: %s (%s) -> %s (%s)'%(chan.id, chan.gate_hh_rates, mchan, mgates)) + all_gates = chan.gates + chan.gate_hh_rates for ngate, mgate in zip(all_gates,mgates): if mgate.name.endswith('X'): @@ -543,27 +510,32 @@ class NML2Reader(object): # refering to tau_inf and m_inf?? fwd = ngate.forward_rate rev = ngate.reverse_rate - self.paths_to_chan_elements['%s/%s'%(chan.id,ngate.id)] = '%s/%s'%(chan.id,mgate.name) - q10_scale = 1 if ngate.q10_settings: if ngate.q10_settings.type == 'q10Fixed': q10_scale= float(ngate.q10_settings.fixed_q10) elif ngate.q10_settings.type == 'q10ExpTemp': - q10_scale = math.pow(float(ngate.q10_settings.q10_factor),(self._getTemperature()- SI(ngate.q10_settings.experimental_temp))/10) - #mu.info('Q10: %s; %s; %s; %s'%(ngate.q10_settings.q10_factor, self._getTemperature(),SI(ngate.q10_settings.experimental_temp),q10_scale)) + q10_scale = math.pow( float(ngate.q10_settings.q10_factor) + , (self._getTemperature()- SI(ngate.q10_settings.experimental_temp))/10 + ) else: - raise Exception('Unknown Q10 scaling type %s: %s'%(ngate.q10_settings.type,ngate.q10_settings)) + raise Exception('Unknown Q10 scaling type %s: %s'%( + ngate.q10_settings.type,ngate.q10_settings) + ) if self.verbose: - mu.info(' === Gate: %s; %s; %s; %s; %s; scale=%s'%(ngate.id, mgate.path, mchan.Xpower, fwd, rev, q10_scale)) + mu.info(' === Gate: %s; %s; %s; %s; %s; scale=%s'% ( + ngate.id, mgate.path, mchan.Xpower, fwd, rev, q10_scale) + ) if (fwd is not None) and (rev is not None): alpha = self.calculateRateFn(fwd, vmin, vmax, vdivs) beta = self.calculateRateFn(rev, vmin, vmax, vdivs) + mgate.tableA = q10_scale * (alpha) mgate.tableB = q10_scale * (alpha + beta) + # Assuming the meaning of the elements in GateHHTauInf ... if hasattr(ngate,'time_course') and hasattr(ngate,'steady_state') \ and (ngate.time_course is not None) and (ngate.steady_state is not None): @@ -577,26 +549,36 @@ class NML2Reader(object): if hasattr(ngate,'steady_state') and (ngate.time_course is None) and (ngate.steady_state is not None): inf = ngate.steady_state tau = 1 / (alpha + beta) - if (inf is not None): + if inf is not None: inf = self.calculateRateFn(inf, vmin, vmax, vdivs) - mgate.tableA = q10_scale * (inf / tau) - mgate.tableB = q10_scale * (1 / tau) + if len(inf) > 0: + mgate.tableA = q10_scale * (inf / tau) + mgate.tableB = q10_scale * (1 / tau) if self.verbose: - mu.info(self.filename, '== Created', mchan.path, 'for', chan.id) + mu.info('%s: Created %s for %s'%(self.filename,mchan.path,chan.id)) return mchan def createPassiveChannel(self, chan): - mchan = moose.Leakage('%s/%s' % (self.lib.path, chan.id)) + epath = '%s/%s' % (self.lib.path, chan.id) + if moose.exists( epath ): + mchan = moose.element(epath) + else: + mchan = moose.Leakage(epath) if self.verbose: - mu.info(self.filename, 'Created', mchan.path, 'for', chan.id) + mu.info('%s: Created %s for %s'%(self.filename,mchan.path,chan.id)) return mchan def importInputs(self, doc): - minputs = moose.Neutral('%s/inputs' % (self.lib.path)) - for pg_nml in doc.pulse_generators: + epath = '%s/inputs' % (self.lib.path) + if moose.exists( epath ): + minputs = moose.element( epath ) + else: + minputs = moose.Neutral( epath ) - pg = moose.PulseGen('%s/%s' % (minputs.path, pg_nml.id)) + for pg_nml in doc.pulse_generators: + epath = '%s/%s' % (minputs.path, pg_nml.id) + pg = moose.element(epath) if moose.exists(epath) else moose.PulseGen(epath) pg.firstDelay = SI(pg_nml.delay) pg.firstWidth = SI(pg_nml.duration) pg.firstLevel = SI(pg_nml.amplitude) @@ -605,7 +587,7 @@ class NML2Reader(object): def importIonChannels(self, doc, vmin=-150e-3, vmax=100e-3, vdivs=5000): if self.verbose: - mu.info(self.filename, 'Importing the ion channels') + mu.info('%s: Importing the ion channels' % self.filename ) for chan in doc.ion_channel+doc.ion_channel_hhs: if chan.type == 'ionChannelHH': @@ -619,11 +601,12 @@ class NML2Reader(object): self.nml_to_moose[chan] = mchan self.proto_chans[chan.id] = mchan if self.verbose: - mu.info(self.filename, 'Created ion channel', mchan.path, 'for', chan.type, chan.id) + mu.info( self.filename + ': Created ion channel %s for %s %s'%( + mchan.path, chan.type, chan.id)) def importConcentrationModels(self, doc): for concModel in doc.decaying_pool_concentration_models: - proto = self.createDecayingPoolConcentrationModel(concModel) + self.createDecayingPoolConcentrationModel(concModel) def createDecayingPoolConcentrationModel(self, concModel): """Create prototype for concentration model""" @@ -632,21 +615,13 @@ class NML2Reader(object): else: name = concModel.id ca = moose.CaConc('%s/%s' % (self.lib.path, id)) - mu.info('11111', concModel.restingConc) - mu.info('2222', concModel.decayConstant) - mu.info('33333', concModel.shellThickness) - ca.CaBasal = SI(concModel.restingConc) ca.tau = SI(concModel.decayConstant) ca.thick = SI(concModel.shellThickness) - ca.B = 5.2e-6 # B = 5.2e-6/(Ad) where A is the area of the shell and d is thickness - must divide by shell volume when copying + ca.B = 5.2e-6 # B = 5.2e-6/(Ad) where A is the area of the + # shell and d is thickness - must divide by + # shell volume when copying self.proto_pools[concModel.id] = ca self.nml_to_moose[concModel.id] = ca self.moose_to_nml[ca] = concModel - logger.debug('Created moose element: %s for nml conc %s' % (ca.path, concModel.id)) - - - - -# -# reader.py ends here + mu.debug('Created moose element: %s for nml conc %s' % (ca.path, concModel.id)) diff --git a/python/moose/neuroml2/run_cell.py b/python/moose/neuroml2/run_cell.py index a95e2a29..81d535f1 100644 --- a/python/moose/neuroml2/run_cell.py +++ b/python/moose/neuroml2/run_cell.py @@ -43,6 +43,7 @@ # Code: import moose +import moose.utils as mu import sys from reader import NML2Reader import numpy as np @@ -76,16 +77,10 @@ def run(nogui): plotdt = 1e-4 simtime = 150e-3 - if (1): - #moose.showmsg( '/clock' ) - for i in range(8): - moose.setClock( i, simdt ) - moose.setClock( 8, plotdt ) - moose.reinit() - else: - utils.resetSim([model.path, data.path], simdt, plotdt, simmethod='ee') - moose.showmsg( '/clock' ) - + for i in range(8): + moose.setClock( i, simdt ) + moose.setClock( 8, plotdt ) + moose.reinit() moose.start(simtime) print("Finished simulation!") @@ -113,4 +108,4 @@ if __name__ == '__main__': nogui = '-nogui' in sys.argv - run(nogui) \ No newline at end of file + run(nogui) diff --git a/python/moose/neuroml2/run_hhcell.py b/python/moose/neuroml2/run_hhcell.py index 61e18afc..fb92841d 100644 --- a/python/moose/neuroml2/run_hhcell.py +++ b/python/moose/neuroml2/run_hhcell.py @@ -120,15 +120,11 @@ def run(nogui): simdt = 1e-6 plotdt = 1e-4 simtime = 300e-3 - if (1): - #moose.showmsg( '/clock' ) - for i in range(8): - moose.setClock( i, simdt ) - moose.setClock( 8, plotdt ) - moose.reinit() - else: - utils.resetSim([model.path, data.path], simdt, plotdt, simmethod='ee') - moose.showmsg( '/clock' ) + #moose.showmsg( '/clock' ) + for i in range(8): + moose.setClock( i, simdt ) + moose.setClock( 8, plotdt ) + moose.reinit() moose.start(simtime) print("Finished simulation!") @@ -164,4 +160,4 @@ if __name__ == '__main__': nogui = '-nogui' in sys.argv run(nogui) - \ No newline at end of file + diff --git a/python/moose/plot_utils.py b/python/moose/plot_utils.py index 9b309e46..a680dbbe 100644 --- a/python/moose/plot_utils.py +++ b/python/moose/plot_utils.py @@ -1,7 +1,4 @@ # -*- coding: utf-8 -*- -# -# plot_utils.py: Some utility function for plotting data in moose. - from __future__ import print_function, division, absolute_import __author__ = "Dilawar Singh" @@ -225,7 +222,7 @@ def saveRecords(records, xvec = None, **kwargs): for k in records: try: yvec = records[k].vector - except AtrributeError as e: + except AttributeError as e: yevc = records[k] yvecs.append(yvec) xvec = np.linspace(0, clock.currentTime, len(yvecs[0])) @@ -287,7 +284,7 @@ def plotRecords(records, xvec = None, **kwargs): plt.close( ) -def plotTables( regex = '.*', **kwargs ): +def plotTablesByRegex( regex = '.*', **kwargs ): """plotTables Plot all moose.Table/moose.Table2 matching given regex. By default plot all tables. Table names must be unique. Table name are used as legend. diff --git a/python/moose/utils.py b/python/moose/utils.py index 8dbec98a..64fdee8b 100644 --- a/python/moose/utils.py +++ b/python/moose/utils.py @@ -82,15 +82,17 @@ def readtable(table, filename, separator=None): line_no = 0 for line in in_file: line_no = line_no + 1 - tokens = split(line, separator) - if len(token) is 0: + tokens = line.split(separator) + if len(tokens) is 0: continue - elif len(token) == 1: - table[ii] = float(token[0]) - elif len(token) == 2: - table[int(token[0])] = float(token[1]) + elif len(tokens) == 1: + table[ii] = float(tokens[0]) + elif len(tokens) == 2: + table[int(tokens[0])] = float(tokens[1]) else: - print("pymoose.readTable(", table, ",", filename, ",", separator, ") - line#", line_no, " does not fit.") + print("pymoose.readTable(", table, ",", filename, ",", separator + , ") - line#", line_no, " does not fit." + ) def getfields(moose_object): """Returns a dictionary of the fields and values in this object.""" @@ -310,8 +312,9 @@ def autoposition(root): compartments = moose.wildcardFind('%s/##[TYPE=Compartment]' % (root.path)) stack = [compartment for compartment in map(moose.element, compartments) if len(compartment.neighbors['axial']) == 0] - if len(stack) != 1: - raise Exception('There must be one and only one top level compartment. Found %d' % (len(topcomp_list))) + + assert len(stack) == 1, 'There must be one and only one top level\ + compartment. Found %d' % len(stack) ret = stack[0] while len(stack) > 0: comp = stack.pop() diff --git a/python/rdesigneur/rdesigneur.py b/python/rdesigneur/rdesigneur.py index 568bac94..6ad93d02 100644 --- a/python/rdesigneur/rdesigneur.py +++ b/python/rdesigneur/rdesigneur.py @@ -73,6 +73,7 @@ class rdesigneur: combineSegments = True, stealCellFromLibrary = False, verbose = True, + benchmark = False, 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, @@ -96,8 +97,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 @@ -110,6 +111,7 @@ class rdesigneur: self.combineSegments = combineSegments self.stealCellFromLibrary = stealCellFromLibrary self.verbose = verbose + self.benchmark = benchmark self.addSomaChemCompt = addSomaChemCompt self.addEndoChemCompt = addEndoChemCompt self.diffusionLength= diffusionLength @@ -138,11 +140,16 @@ 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 = [] @@ -166,11 +173,13 @@ class rdesigneur: ################################################################ def _printModelStats( self ): - print("\n\tRdesigneur: Elec model has", + if not self.verbose: + return + print("\nRdesigneur: Elec model has", self.elecid.numCompartments, "compartments and", self.elecid.numSpines, "spines on", len( self.cellPortionElist ), "compartments.") - if hasattr( self , 'chemid' ): + if hasattr( self , 'chemid') and len( self.chemDistrib ) > 0: dmstoich = moose.element( self.dendCompt.path + '/stoich' ) print("\tChem part of model has the following compartments: ") for j in moose.wildcardFind( '/model/chem/##[ISA=ChemCompt]'): @@ -184,17 +193,15 @@ class rdesigneur: return self.model = moose.Neutral( modelPath ) self.modelPath = modelPath - print( "[INFO ] rdesigneur: Building model. " ) funcs = [ self.installCellFromProtos, self.buildPassiveDistrib , self.buildChanDistrib, self.buildSpineDistrib, self.buildChemDistrib , self._configureSolvers, self.buildAdaptors, self._buildStims , self._buildPlots, self._buildMoogli, self._configureHSolve - , self._configureClocks, self._printModelStats, self._savePlots + , self._configureClocks, self._printModelStats ] for i, _func in enumerate( funcs ): - if self.verbose: + if self.benchmark: print( " + (%d/%d) executing %25s"%(i, len(funcs), _func.__name__), end=' ' ) - sys.stdout.flush() t0 = time.time() try: _func( ) @@ -203,11 +210,12 @@ class rdesigneur: moose.delete( self.model ) return t = time.time() - t0 - if self.verbose: + if self.benchmark: msg = r' ... DONE' if t > 1: msg += ' %.3f sec' % t print( msg ) + sys.stdout.flush() def installCellFromProtos( self ): if self.stealCellFromLibrary: @@ -303,7 +311,7 @@ class rdesigneur: protoName = protoVec[0][6:] if self.isKnownClassOrFile( protoName, knownClasses ): try: - getAttr( moose, protoName )( '/library/' + protoVec[1] ) + getattr( moose, protoName )( '/library/' + protoVec[1] ) except AttributeError: raise BuildError( protoType + "Proto: Moose class '" \ + protoVec[0] + "' not found." ) @@ -391,7 +399,7 @@ class rdesigneur: period = name.rfind( '.' ) slash = name.rfind( '/' ) if ( slash >= period ): - raise BuildError( "chanProto: bad filename:" + i[0] ) + raise BuildError( "chanProto: bad filename:" + name ) if ( slash < 0 ): return name[:period] else: @@ -433,7 +441,7 @@ class rdesigneur: for i in range( len(args) ): parms[i] = args[i] if parms[6] <= 0: - return _self.buildElecSoma( parms[:4] ) + return self.buildElecSoma( parms[:4] ) cell = moose.Neuron( '/library/' + parms[1] ) prev = buildCompt( cell, 'soma', dia = args[2], dx = args[3] ) dx = parms[5]/parms[6] @@ -463,10 +471,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 @@ -486,6 +494,12 @@ class rdesigneur: # Expression can use p, g, L, len, dia, maxP, maxG, maxL. temp = [] for i in self.passiveDistrib: + # Handle legacy format of ['.', path, field, expr [field expr]] + if (len( i ) < 3) or (i[0] != '.' and len(i) %2 != 1): + raise BuildError( "buildPassiveDistrib: Need 3 + N*2 arguments as (path field expr [field expr]...), have {}".format( len(i) ) ) + + if not(( len(i) % 2 ) != 1 and i[0] == '.' ): + temp.append( '.' ) temp.extend( i ) temp.extend( [""] ) self.elecid.passiveDistribution = temp @@ -608,18 +622,17 @@ 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] in ['CaConcBase', 'ChanBase', 'NMDAChan', 'VClamp']: - objList = self._collapseElistToPathAndClass( comptList, plotSpec[2], kf[0] ) + objList = self._collapseElistToPathAndClass( comptList, plotSpec.relpath, kf[0] ) return objList, kf[1] - elif field in [ 'n', 'conc', 'volume']: - path = plotSpec[2] + path = plotSpec.relpath pos = path.find( '/' ) if pos == -1: # Assume it is in the dend compartment. path = 'dend/' + path @@ -640,13 +653,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( "Warn: Rdesigneur::_parseComptField: unknown Object: '%s'" % plotSpec[2] ) + print( "Warning: Rdesigneur::_parseComptField: unknown Object: '", plotSpec.relpath, "'" ) #print "############", chemCompt, len(objList), kf[1] return objList, kf[1] @@ -678,7 +691,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 ) @@ -686,26 +699,26 @@ class rdesigneur: assert( plotField == plotField2 ) plotObj3 = plotObj + plotObj2 numPlots = sum( q != dummy for q in plotObj3 ) - if numPlots == 0: - return - - tabname = graphs.path + '/plot' + str(k) - scale = knownFields[i[3]][2] - units = knownFields[i[3]][3] - ymin = i[6] if len(i) > 7 else 0 - ymax = i[7] if len(i) > 7 else 0 - if len( i ) > 5 and i[5] == 'wave': - self.wavePlotNames.append( [ tabname, i[4], k, scale, units, i[3], ymin, ymax ] ) - else: - self.plotNames.append( [ tabname, i[4], k, scale, units, i[3], ymin, ymax ] ) - k += 1 - if i[3] in [ 'n', 'conc', 'volume', 'Gbar' ]: - tabs = moose.Table2( tabname, numPlots ) - else: - tabs = moose.Table( tabname, numPlots ) - if i[3] == 'spikeTime': - tabs.vec.threshold = -0.02 # Threshold for classifying Vm as a spike. - tabs.vec.useSpikeMode = True # spike detect mode on + #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.field][2] + units = knownFields[i.field][3] + if i.mode == 'wave': + self.wavePlotNames.append( [ tabname, i.title, k, scale, units, i ] ) + 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.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.field == 'spikeTime': + tabs.vec.threshold = -0.02 # Threshold for classifying Vm as a spike. + tabs.vec.useSpikeMode = True # spike detect mode on vtabs = moose.vec( tabs ) q = 0 @@ -731,8 +744,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 ) @@ -740,13 +753,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 ) ) @@ -815,10 +821,15 @@ rdesigneur.rmoogli.updateMoogliViewer() plt.title( i[1] ) plt.xlabel( "position (voxels)" ) plt.ylabel( i[4] ) - mn = np.min(vpts) - mx = np.max(vpts) - if mn/mx < 0.3: - mn = 0 + plotinfo = i[5] + if plotinfo.ymin == plotinfo.ymax: + mn = np.min(vpts) + mx = np.max(vpts) + if mn/mx < 0.3: + mn = 0 + else: + mn = plotinfo.ymin + mx = plotinfo.ymax 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' ) @@ -847,134 +858,13 @@ rdesigneur.rmoogli.updateMoogliViewer() Email address: sarthaks442@gmail.com Heavily modified by U.S. Bhalla ''' - - def _savePlots( self ): - if self.verbose: - print( 'rdesigneur: Saving plots ...', end = ' ' ) - sys.stdout.flush() - - 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] in [ 'n', 'conc', 'volume', '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 - - if self.verbose: - print( ' ... DONE.' ) - - 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: @@ -987,36 +877,33 @@ 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) @@ -1024,42 +911,25 @@ rdesigneur.rmoogli.updateMoogliViewer() 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("Save format not known") - 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 @@ -1078,19 +948,19 @@ rdesigneur.rmoogli.updateMoogliViewer() } stims = moose.Neutral( self.modelPath + '/stims' ) k = 0 - # Stimlist = [path, geomExpr, relPath, field, expr_string] + # rstim class has {elecpath, geom_expr, relpath, field, expr} 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: @@ -1103,7 +973,7 @@ rdesigneur.rmoogli.updateMoogliViewer() funcname = stims.path + '/stim' + str(k) k += 1 func = moose.Function( funcname ) - func.expr = i[4] + func.expr = i.expr #if i[3] == 'vclamp': # Hack to clean up initial condition func.doEvalAtReinit = 1 for q in stimObj3: @@ -1141,8 +1011,7 @@ rdesigneur.rmoogli.updateMoogliViewer() ################################################################ def validateFromMemory( self, epath, cpath ): - ret = self.validateChem() - return ret + return self.validateChem() ################################################################# # assumes ePath is the parent element of the electrical model, @@ -1194,11 +1063,11 @@ rdesigneur.rmoogli.updateMoogliViewer() self._buildNeuroMesh() - self._configureSolvers() for i in self.adaptorList: - print(i) - self._buildAdaptor( i[0],i[1],i[2],i[3],i[4],i[5],i[6] ) + # print(i) + assert len(i) >= 8 + self._buildAdaptor( i[0],i[1],i[2],i[3],i[4],i[5],i[6],i[7] ) ################################################################ @@ -1328,6 +1197,8 @@ rdesigneur.rmoogli.updateMoogliViewer() if len( comptlist ) == 0: raise BuildError( "validateChem: no compartment on: " + cpath ) + return True + ''' if len( comptlist ) == 1: return; @@ -1454,7 +1325,7 @@ rdesigneur.rmoogli.updateMoogliViewer() ################################################################# def _configureSolvers( self ) : - if not hasattr( self, 'chemid' ): + if not hasattr( self, 'chemid' ) or len( self.chemDistrib ) == 0: return if not hasattr( self, 'dendCompt' ): raise BuildError( "configureSolvers: no chem meshes defined." ) @@ -1619,3 +1490,95 @@ rdesigneur.rmoogli.updateMoogliViewer() for j in range( i[1], i[2] ): 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( "{0}, {1}, {2}, {3}, {4}".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 920caaba..cade7920 100644 --- a/python/rdesigneur/rdesigneurProtos.py +++ b/python/rdesigneur/rdesigneurProtos.py @@ -49,13 +49,17 @@ import moose import math from moose import utils -EREST_ACT = -0.060 -ECA = 0.080 -EK = -0.075 -SOMA_A = 3.32e-9 -per_ms = 1e3 -PI = 3.14159265359 +EREST_ACT = -0.060 +EREST_ACT_HH = -0.070 # A different value is used for the HH squid params +ECA = 0.080 +EK = -0.075 +SOMA_A = 3.32e-9 +per_ms = 1e3 +PI = 3.14159265359 FaradayConst = 96485.3365 # Coulomb/mol +#CA_SCALE = 25000 # Ratio of Traub units to mM. 250::0.01 +CA_SCALE = 1.0 # I have now set sensible ranges in the KCA and KAHP + def make_HH_Na(name = 'HH_Na', parent='/library', vmin=-110e-3, vmax=50e-3, vdivs=3000): @@ -68,7 +72,7 @@ def make_HH_Na(name = 'HH_Na', parent='/library', vmin=-110e-3, vmax=50e-3, vdiv na.Ek = 50e-3 na.Xpower = 3 na.Ypower = 1 - v = np.linspace(vmin, vmax, vdivs+1) - EREST_ACT + v = np.linspace(vmin, vmax, vdivs+1) - EREST_ACT_HH m_alpha = per_ms * (25 - v * 1e3) / (10 * (np.exp((25 - v * 1e3) / 10) - 1)) m_beta = per_ms * 4 * np.exp(- v * 1e3/ 18) m_gate = moose.element('%s/gateX' % (na.path)) @@ -97,7 +101,7 @@ def make_HH_K(name = 'HH_K', parent='/library', vmin=-120e-3, vmax=40e-3, vdivs= k = moose.HHChannel('%s/%s' % (parent, name)) k.Ek = -77e-3 k.Xpower = 4 - v = np.linspace(vmin, vmax, vdivs+1) - EREST_ACT + v = np.linspace(vmin, vmax, vdivs+1) - EREST_ACT_HH n_alpha = per_ms * (10 - v * 1e3)/(100 * (np.exp((10 - v * 1e3)/10) - 1)) n_beta = per_ms * 0.125 * np.exp(- v * 1e3 / 80) n_gate = moose.element('%s/gateX' % (k.path)) @@ -310,13 +314,17 @@ def make_Ca_conc( name ): # this was specified here in make_Ca_conc. #======================================================================== -# Tabulated Ca-dependent K AHP Channel +# Tabulated Ca-dependent K AHP Channel: Traub 1991 #======================================================================== # This is a tabchannel which gets the calcium concentration from Ca_conc # in order to calculate the activation of its Z gate. It is set up much # like the Ca channel, except that the A and B tables have values which are # functions of concentration, instead of voltage. +# Traub's original equation is min(0.2e-4 Xi, 0.01) which suggests a max +# of 500 for the Xi (calcium) in his system. For dendritic calcium say 10uM +# or 0.01 mM. Elsewhere we estimate that the ratio of Traub units to mM is +# 250:0.01. Using this ratio, we should have xmax = 0.02. def make_K_AHP( name ): if moose.exists( '/library/' + name ): @@ -330,7 +338,7 @@ def make_K_AHP( name ): K_AHP.Zpower = 1 zgate = moose.element( K_AHP.path + '/gateZ' ) - xmax = 500.0 + xmax = 0.02 # 20 micromolar. zgate.min = 0 zgate.max = xmax zgate.divs = 3000 @@ -339,7 +347,7 @@ def make_K_AHP( name ): dx = (zgate.max - zgate.min)/zgate.divs x = zgate.min for i in range( zgate.divs + 1 ): - zA[i] = min( 0.02 * CA_SCALE * x, 10 ) + zA[i] = min( 250.00 * CA_SCALE * x, 10 ) zB[i] = 1.0 x = x + dx @@ -403,13 +411,14 @@ def make_K_C( name ): xgate.tableB = xB # Create a table for the function of concentration, allowing a -# concentration range of 0 to 200, with 3000 divisions. This is done +# concentration range of 0 to 100 uM, with 3000 divisions. This is done # using the Z gate, which can receive a CONCEN message. By using # the "instant" flag, the A and B tables are evaluated as lookup tables, # rather than being used in a differential equation. zgate = moose.element( K_C.path + '/gateZ' ) zgate.min = 0.0 - xmax = 150.0 + xmax = 0.02 # Max Ca conc is likely to be 100 uM even in spine, but + # based on estimates above let's keep it at 20uM. zgate.max = xmax zgate.divs = 3000 zA = np.zeros( (zgate.divs + 1), dtype=float) @@ -418,8 +427,8 @@ def make_K_C( name ): x = zgate.min #CaScale = 100000.0 / 250.0e-3 for i in range( zgate.divs + 1 ): - zA[i] = min( 1000.0, x * CA_SCALE / (250 * xmax ) ) - zB[i] = 1000.0 + zA[i] = min( 1.0, x * CA_SCALE / xmax) + zB[i] = 1.0 x += dx zgate.tableA = zA zgate.tableB = zB @@ -449,6 +458,39 @@ def make_glu( name ): sh.synapse[0].weight = 1 return glu +#======================================================================== +# NMDAChan: NMDA receptor +#======================================================================== + +def make_NMDA( name ): + if moose.exists( '/library/' + name ): + return + NMDA = moose.NMDAChan( '/library/' + name ) + NMDA.Ek = 0.0 + NMDA.tau1 = 20.0e-3 + NMDA.tau2 = 20.0e-3 + NMDA.Gbar = 5 * SOMA_A + NMDA.CMg = 1.2 # [Mg]ext in mM + NMDA.KMg_A = 1.0/0.28 + NMDA.KMg_B = 1.0/62 + NMDA.temperature = 300 # Temperature in Kelvin. + NMDA.extCa = 1.5 # [Ca]ext in mM + NMDA.intCa = 0.00008 # [Ca]int in mM + NMDA.intCaScale = 1 # Scale factor from elec Ca units to mM + NMDA.intCaOffset = 0.00008 # Basal [Ca]int in mM + NMDA.condFraction = 0.02 # Fraction of conductance due to Ca + + addmsg1 = moose.Mstring( NMDA.path + '/addmsg1' ) + addmsg1.value = '. ICaOut ../Ca_conc current' + addmsg2 = moose.Mstring( NMDA.path + '/addmsg2' ) + addmsg2.value = '../Ca_conc concOut . assignIntCa' + + sh = moose.SimpleSynHandler( NMDA.path + '/sh' ) + moose.connect( sh, 'activationOut', NMDA, 'activation' ) + sh.numSynapses = 1 + sh.synapse[0].weight = 1 + return NMDA + #======================================================================== # SynChan: GABA receptor #======================================================================== diff --git a/python/rdesigneur/rmoogli.py b/python/rdesigneur/rmoogli.py index 16317b56..f673dad7 100644 --- a/python/rdesigneur/rmoogli.py +++ b/python/rdesigneur/rmoogli.py @@ -29,7 +29,7 @@ def makeMoogli( rd, mooObj, args, fieldInfo ): else: ymin = fieldInfo[4] ymax = fieldInfo[5] - print( "fieldinfo = {}, ymin = {}, ymax = {}".format( fieldInfo, ymin, ymax )) + #print( "fieldinfo = {}, ymin = {}, ymax = {}".format( fieldInfo, ymin, ymax )) viewer = moogul.MooView() if mooField == 'n' or mooField == 'conc': diff --git a/python/setup.cmake.py b/python/setup.cmake.py index d74a5242..c7254b40 100644 --- a/python/setup.cmake.py +++ b/python/setup.cmake.py @@ -27,20 +27,21 @@ from distutils.core import setup script_dir = os.path.dirname( os.path.abspath( __file__ ) ) # Version file must be available. It MUST be written by cmake. Or create -# manually. +# it manually before running this script. with open( os.path.join( script_dir, 'VERSION'), 'r' ) as f: version = f.read( ) print( 'Got %s from VERSION file' % version ) - -# importlib is available only for python3. +# importlib is available only for python3. Since we build wheels, prefer .so +# extension. This way a wheel built by any python3.x will work with any python3. suffix = '.so' try: import importlib.machinery - suffix = importlib.machinery.EXTENSION_SUFFIXES[0].split('.')[-1] + suffix = importlib.machinery.EXTENSION_SUFFIXES[-1] except Exception as e: print( '[WARN] Failed to determine importlib suffix' ) suffix = '.so' +print( '[INFO] Suffix for python SO: %s' % suffix ) setup( name = 'pymoose', @@ -54,9 +55,9 @@ setup( packages = [ 'rdesigneur', 'moose' , 'moose.SBML', 'moose.genesis' , 'moose.neuroml', 'moose.neuroml2' - , 'moose.chemUtil', 'moose.chemMerge' + , 'moose.chemUtil', 'moose.chemMerge' ], - install_requires = [ 'python-libsbml', 'numpy' ], + install_requires = [ 'numpy' ], package_dir = { 'moose' : 'moose', 'rdesigneur' : 'rdesigneur' }, package_data = { 'moose' : ['_moose' + suffix, 'neuroml2/schema/NeuroMLCoreDimensions.xml'] }, ) diff --git a/scheduling/CMakeLists.txt b/scheduling/CMakeLists.txt index 52917a41..1d60f72f 100644 --- a/scheduling/CMakeLists.txt +++ b/scheduling/CMakeLists.txt @@ -1,5 +1,6 @@ +cmake_minimum_required(VERSION 2.8) +include( ${CMAKE_CURRENT_SOURCE_DIR}/../CheckCXXCompiler.cmake) file(GLOB scheduling_SRC "*.cpp" ) - if(NOTIFY_PROGRESS) add_definitions("-DNOTIFY_PROGRESS") endif(NOTIFY_PROGRESS) @@ -9,7 +10,4 @@ if(PARALLELIZED_CLOCK) add_definitions( -DPARALLELIZE_CLOCK_USING_CPP11_ASYNC ) endif(PARALLELIZED_CLOCK) -include_directories(../msg) -include_directories(../basecode) - add_library(scheduling ${scheduling_SRC}) diff --git a/scheduling/testScheduling.cpp b/scheduling/testScheduling.cpp index 197bce0c..d904fb16 100644 --- a/scheduling/testScheduling.cpp +++ b/scheduling/testScheduling.cpp @@ -7,13 +7,13 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "testScheduling.h" #include "Clock.h" -#include "SparseMatrix.h" -#include "SparseMsg.h" -#include "SingleMsg.h" +#include "../basecode/SparseMatrix.h" +#include "../msg/SparseMsg.h" +#include "../msg/SingleMsg.h" #include "../builtins/Arith.h" #include "../shell/Shell.h" diff --git a/setup.py b/setup.py deleted file mode 100755 index 4d9d8284..00000000 --- a/setup.py +++ /dev/null @@ -1,172 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import print_function - -"""setup.py: This -NOT COMPLETE. -scripts prepare MOOSE for PyPI. - -Last modified: Mon Jul 28, 2014 12:52AM - -""" - -__author__ = "Dilawar Singh" -__copyright__ = "Copyright 2013, 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" - -import os -import sys -import shutil - -from setuptools import setup -from distutils.core import Command, Extension -from distutils.command.install import install as _install -from distutils.command.build import build as _build -from distutils.command.build_py import build_py as _build_py - - -import distutils.spawn as ds - -build_dir = 'buildMooseUsingCmake' -if not os.path.isdir(build_dir): - os.makedirs(build_dir) - -class BuildCommand(_build): - """This command builds """ - user_options = _build.user_options + [] - - def initialize_options(self): - self.cwd = os.getcwd() - self.build_base = '/tmp' - self.build_temp = '/tmp' - self.build_lib = '/tmp' - self.new_dir = os.path.join(os.path.split(__file__)[0], build_dir) - - def finalize_options(self): - pass - - def get_source_files(self): - return [] - - def run(self): - print("++ Building MOOSE") - os.chdir(self.new_dir) - try: - ds.spawn(['cmake', '..' ]) - ds.spawn(['make', '_moose']) - except ds.DistutilsExecError as e: - print("Can't build MOOSE") - print(e) - os.chdir(self.cwd) - sys.exit(-1) - os.chdir(self.cwd) - -class InstallCommand(_install): - user_options = _install.user_options + [ - ('single-version-externally-managed', None, '') - ] - - def initialize_options(self): - _install.initialize_options(self) - self.cwd = os.getcwd() - self.single_version_externally_managed = False - self.record = None - self.build_lib = None - - def finalize_options(self): - _install.finalize_options(self) - - def run(self): - self.new_dir = os.path.join(os.path.split(__file__)[0], build_dir) - os.chdir(self.new_dir) - try: - ds.spawn(['cmake', '..' ]) - ds.spawn(['make', '_moose']) - except ds.DistutilsExecError as e: - print("Can't build MOOSE") - print(e) - os.chdir(self.cwd) - sys.exit(-1) - os.chdir(self.cwd) - - print("++ Installing PyMOOSE") - self.new_dir = os.path.join(os.path.split(__file__)[0], 'python') - os.chdir(self.new_dir) - try: - ds.spawn(["python", "setup.cmake.py", "install"]) - except ds.DistutilsExecError as e: - print("Can't install PyMOOSE") - print(e) - os.chdir(self.cwd) - sys.exit(-1) - os.chdir(self.cwd) - -class BuildPyCommand(_build_py): - """Build PyMoose for distribution""" - user_options = _build_py.user_options + [ - ( 'build_lib', None, 'Build library' ) - ] - - def initialize_options(self): - self.data_files = [] - self.build_lib = '/tmp' - self.cwd = os.getcwd() - self.compiler = None - self.new_dir = os.path.join(os.path.split(__file__)[0], 'python') - - def finalize_options(self): - pass - - def run(self): - pass - -## -# @brief FUnction to read a file. -# -# @param fname Name of the file. -# -# @return A string content of the file. -def read(fname): - return open(os.path.join(os.path.dirname(__file__), fname)).read() - -name = 'moose' -version = '3.0' -description = ( - 'MOOSE is the Multiscale Object-Oriented Simulation Environment. ' - 'It is the base and numerical core for large, detailed simulations ' - 'including Computational Neuroscience and Systems Biology.' ) -url = 'http://moose.ncbs.res.in/' - - -setup( - name = name - , version = version - , author = "Upinder Bhalla et. al." - , author_email = "bhalla@ncbs.res.in" - , maintainer = 'Dilawar Singh' - , maintainer_email = 'dilawars@ncbs.res.in' - , description = description - , license = "LGPL" - , url = url - , long_description = read('./README.md') - , ext_modules = [ - Extension('_moose', [ '*' ]) - ] - , cmdclass = { - 'install' : InstallCommand - , 'build_py' : BuildPyCommand - , 'build_ext' : BuildCommand - } - , require = [ 'python-qt4' ] - , keywords = "neural simulation" - , classifiers=[ - 'Intended Audience :: Science/Research', - 'Operating System :: Linux', - 'Programming Language :: Python', - 'Programming Language :: C++', - ] - ) diff --git a/shell/CMakeLists.txt b/shell/CMakeLists.txt index 5d5c661e..f77084a6 100644 --- a/shell/CMakeLists.txt +++ b/shell/CMakeLists.txt @@ -1,16 +1,26 @@ -include_directories(../basecode ../msg ) +cmake_minimum_required(VERSION 2.8) +include( ${CMAKE_CURRENT_SOURCE_DIR}/../CheckCXXCompiler.cmake) if(LIBSBML_FOUND) add_definitions(-DUSE_SBML) endif() add_library(shell - Shell.cpp - ShellCopy.cpp - ShellThreads.cpp - LoadModels.cpp - SaveModels.cpp - Neutral.cpp - Wildcard.cpp - testShell.cpp + Shell.cpp + ShellCopy.cpp + ShellThreads.cpp + LoadModels.cpp + SaveModels.cpp + Neutral.cpp + Wildcard.cpp + testShell.cpp ) + +## version is set by top-level script ../CMakeLists.txt . +#if(NOT MOOSE_VERSION) +# set(MOOSE_VERSION "undefined") +#endif() +# +#set_target_properties(shell +# PROPERTIES COMPILE_FLAGS ${COMPILE_FLAGS} -DMOOSE_VERSION=\"${MOOSE_VERSION}\" +# ) diff --git a/shell/LoadModels.cpp b/shell/LoadModels.cpp index 6d1bc04e..0dbe00f0 100644 --- a/shell/LoadModels.cpp +++ b/shell/LoadModels.cpp @@ -8,7 +8,7 @@ **********************************************************************/ #include <fstream> -#include "header.h" +#include "../basecode/header.h" #include "Shell.h" #include "../utility/strutil.h" #include "../utility/Vec.h" diff --git a/shell/Neutral.cpp b/shell/Neutral.cpp index 9b5a2ecf..314ece6c 100644 --- a/shell/Neutral.cpp +++ b/shell/Neutral.cpp @@ -7,10 +7,10 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" -#include "Dinfo.h" -#include "ElementValueFinfo.h" -#include "LookupElementValueFinfo.h" +#include "../basecode/header.h" +#include "../basecode/Dinfo.h" +#include "../basecode/ElementValueFinfo.h" +#include "../basecode/LookupElementValueFinfo.h" #include "Shell.h" const Cinfo* Neutral::initCinfo() diff --git a/shell/SaveModels.cpp b/shell/SaveModels.cpp index a252b3f3..c5c0a295 100644 --- a/shell/SaveModels.cpp +++ b/shell/SaveModels.cpp @@ -8,7 +8,7 @@ **********************************************************************/ #include <fstream> -#include "header.h" +#include "../basecode/header.h" #include "Shell.h" // Defined in kinetics/WriteKkit.cpp diff --git a/shell/Shell.cpp b/shell/Shell.cpp index e4b29463..aa7cc983 100644 --- a/shell/Shell.cpp +++ b/shell/Shell.cpp @@ -10,19 +10,18 @@ #include <string> #include <algorithm> -using namespace std; +#include "../basecode/header.h" +#include "../basecode/global.h" +#include "../basecode/Dinfo.h" +#include "../basecode/SparseMatrix.h" +#include "../msg/SingleMsg.h" +#include "../msg/DiagonalMsg.h" +#include "../msg/OneToOneMsg.h" +#include "../msg/OneToAllMsg.h" +#include "../msg/SparseMsg.h" -#include "header.h" -#include "global.h" -#include "SingleMsg.h" -#include "DiagonalMsg.h" -#include "OneToOneMsg.h" -#include "OneToAllMsg.h" -#include "SparseMatrix.h" -#include "SparseMsg.h" #include "Shell.h" -#include "Dinfo.h" #include "Wildcard.h" // Want to separate out this search path into the Makefile options @@ -609,7 +608,8 @@ ObjId Shell::doFind( const string& path ) const string Shell::doVersion() { - return MOOSE_VERSION; + string v = MOOSE_VERSION; + return v; } void Shell::setCwe( ObjId val ) diff --git a/shell/Shell.h b/shell/Shell.h index 1b2a7f45..40c36b3c 100644 --- a/shell/Shell.h +++ b/shell/Shell.h @@ -11,10 +11,8 @@ #define _SHELL_H #include <string> - using namespace std; - class DestFinfo; enum AssignmentType { SINGLE, VECTOR, REPEAT }; diff --git a/shell/ShellCopy.cpp b/shell/ShellCopy.cpp index 3788c474..a0eb29d8 100644 --- a/shell/ShellCopy.cpp +++ b/shell/ShellCopy.cpp @@ -7,8 +7,8 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" -#include "OneToAllMsg.h" +#include "../basecode/header.h" +#include "../msg/OneToAllMsg.h" #include "Shell.h" #include "../scheduling/Clock.h" diff --git a/shell/ShellThreads.cpp b/shell/ShellThreads.cpp index 76e3d027..03efacd2 100644 --- a/shell/ShellThreads.cpp +++ b/shell/ShellThreads.cpp @@ -14,9 +14,9 @@ #ifdef USE_MPI #include <mpi.h> #endif -#include "header.h" +#include "../basecode/header.h" #include "Shell.h" -#include "Dinfo.h" +#include "../basecode/Dinfo.h" #define USE_NODES 1 diff --git a/shell/Wildcard.cpp b/shell/Wildcard.cpp index 0ce0567a..9031759a 100644 --- a/shell/Wildcard.cpp +++ b/shell/Wildcard.cpp @@ -7,12 +7,10 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" -#include <stdio.h> +#include "../basecode/header.h" #include "Neutral.h" #include "Shell.h" #include "Wildcard.h" -// #define NOINDEX (UINT_MAX - 2) static int wildcardRelativeFind( ObjId start, const vector< string >& path, unsigned int depth, vector< ObjId >& ret ); diff --git a/shell/testShell.cpp b/shell/testShell.cpp index 6a5e8d2a..4fe322e6 100644 --- a/shell/testShell.cpp +++ b/shell/testShell.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "Shell.h" #ifdef USE_MPI #include <mpi.h> @@ -16,10 +16,10 @@ #include "../scheduling/testScheduling.h" #include "../builtins/Arith.h" -#include "SparseMatrix.h" -#include "SparseMsg.h" -#include "SingleMsg.h" -#include "OneToAllMsg.h" +#include "../basecode/SparseMatrix.h" +#include "../msg/SparseMsg.h" +#include "../msg/SingleMsg.h" +#include "../msg/OneToAllMsg.h" #include "Wildcard.h" const bool TEST_WARNING = false; diff --git a/signeur/Adaptor.cpp b/signeur/Adaptor.cpp index 91b2764e..48c11a8a 100644 --- a/signeur/Adaptor.cpp +++ b/signeur/Adaptor.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "Adaptor.h" /** diff --git a/signeur/CMakeLists.txt b/signeur/CMakeLists.txt index 4479310f..09083dcf 100644 --- a/signeur/CMakeLists.txt +++ b/signeur/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 2.6) -include_directories(../basecode ../utility ../kinetics) +cmake_minimum_required(VERSION 2.8) +include( ${CMAKE_CURRENT_SOURCE_DIR}/../CheckCXXCompiler.cmake) add_library(signeur Adaptor.cpp testSigNeur.cpp diff --git a/synapse/CMakeLists.txt b/synapse/CMakeLists.txt index f122eb4e..35c7f098 100644 --- a/synapse/CMakeLists.txt +++ b/synapse/CMakeLists.txt @@ -1,7 +1,5 @@ cmake_minimum_required(VERSION 2.8) - -include_directories( ../basecode ../utility ../kinetics) -include_directories( ../external/muparser/include/ ) +include( ${CMAKE_CURRENT_SOURCE_DIR}/../CheckCXXCompiler.cmake) set( SYNAPSE_SRCS GraupnerBrunel2012CaPlasticitySynHandler.cpp diff --git a/synapse/STDPSynHandler.cpp b/synapse/STDPSynHandler.cpp index a414913b..f7edf824 100644 --- a/synapse/STDPSynHandler.cpp +++ b/synapse/STDPSynHandler.cpp @@ -8,7 +8,7 @@ **********************************************************************/ #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" diff --git a/synapse/STDPSynapse.cpp b/synapse/STDPSynapse.cpp index 211c60ba..8a59e894 100644 --- a/synapse/STDPSynapse.cpp +++ b/synapse/STDPSynapse.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "SynHandlerBase.h" #include "Synapse.h" #include "STDPSynapse.h" diff --git a/synapse/SeqSynHandler.cpp b/synapse/SeqSynHandler.cpp index cb8bb0b6..7a0056dd 100644 --- a/synapse/SeqSynHandler.cpp +++ b/synapse/SeqSynHandler.cpp @@ -8,14 +8,14 @@ **********************************************************************/ #include <queue> -#include "global.h" -#include "header.h" +#include "../basecode/global.h" +#include "../basecode/header.h" #include "Synapse.h" #include "SynEvent.h" #include "SynHandlerBase.h" #include "RollingMatrix.h" #include "SeqSynHandler.h" -#include "muParser.h" +#include "../external/muparser/include/muParser.h" const Cinfo* SeqSynHandler::initCinfo() { diff --git a/synapse/SimpleSynHandler.cpp b/synapse/SimpleSynHandler.cpp index 51100cd2..4d6828bb 100644 --- a/synapse/SimpleSynHandler.cpp +++ b/synapse/SimpleSynHandler.cpp @@ -8,7 +8,7 @@ **********************************************************************/ #include <queue> -#include "header.h" +#include "../basecode/header.h" #include "Synapse.h" #include "SynEvent.h" #include "SynHandlerBase.h" diff --git a/synapse/SynHandlerBase.cpp b/synapse/SynHandlerBase.cpp index 6c325145..a7bffb04 100644 --- a/synapse/SynHandlerBase.cpp +++ b/synapse/SynHandlerBase.cpp @@ -7,7 +7,7 @@ ** See the file COPYING.LIB for the full notice. **********************************************************************/ -#include "header.h" +#include "../basecode/header.h" #include "Synapse.h" #include "SynHandlerBase.h" diff --git a/synapse/Synapse.cpp b/synapse/Synapse.cpp index 30c97b1b..6089a2a8 100644 --- a/synapse/Synapse.cpp +++ b/synapse/Synapse.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 "SynHandlerBase.h" #include "Synapse.h" diff --git a/tests/python/Rallpacks/moose_vs_neuron/rallpack3/moose_sim.py b/tests/python/Rallpacks/moose_vs_neuron/rallpack3/moose_sim.py index 0045db3a..476e1c63 100644 --- a/tests/python/Rallpacks/moose_vs_neuron/rallpack3/moose_sim.py +++ b/tests/python/Rallpacks/moose_vs_neuron/rallpack3/moose_sim.py @@ -123,16 +123,6 @@ def behaH(A, B, V0, v): ''' return (A * np.exp((v-V0)/B) + 1) -def createChannel(species, path, **kwargs): - """Create a channel """ - if species == 'na': - return sodiumChannel( path, **kwargs) - elif species == 'ca': - channel.Xpower = 4 - else: - utils.dump("FATAL", "Unsupported channel type: {}".format(species)) - raise RuntimeError("Unsupported species of chanel") - def create_na_chan(parent='/library', name='na', vmin=-110e-3, vmax=50e-3, vdivs=3000): """Create a Hodhkin-Huxley Na channel under `parent`. diff --git a/tests/python/abstrModelEqns9.py b/tests/python/abstrModelEqns9.py index 208632e5..5745ff87 100644 --- a/tests/python/abstrModelEqns9.py +++ b/tests/python/abstrModelEqns9.py @@ -89,7 +89,7 @@ def makeChemProto( name, Aexpr, Bexpr, params ): return compt -def makeBis( args ): +def makeBis( args = None ): params = { 'k0a':0.1, # Constant 'k1a':-5.0, # Coeff for A @@ -124,7 +124,7 @@ def makeBis( args ): params ) return params -def makeFHN( args ): +def makeFHN( args = None ): params = { 'k_t':2.5, # Time-const. 'k_a':0.7, # Coeff1 @@ -160,7 +160,7 @@ def makeFHN( args ): return params -def makeNegFB( args ): +def makeNegFB( args = None ): params = { 'k1a':-0.1, # Coeff for decay of A, slow. 'k2a':-0.2, # Coeff for turnoff of A by B, medium. @@ -193,7 +193,7 @@ def makeNegFB( args ): return params # Was negFF2 in earlier versions of abstrModelEqns -def makeNegFF( args ): +def makeNegFF( args = None ): params = { 'k1a':-0.1, # Coeff for decay of A, slow. 'k2a':-0.01, # Coeff for turnoff of A by B, medium. @@ -237,5 +237,3 @@ if __name__ == '__main__': makeNegFB() print("Making Negative Feedforward models") makeNegFF() - - diff --git a/tests/python/chem_models/19085.cspace b/tests/python/chem_models/19085.cspace new file mode 100644 index 00000000..1d2cf355 --- /dev/null +++ b/tests/python/chem_models/19085.cspace @@ -0,0 +1 @@ +M101: |DabX|Jbca| 5.59269 0.0157641 0.172865 0.361005 4.72728 1.08558 0.0982933 \ No newline at end of file diff --git a/tests/python/testXchan1.py b/tests/python/testXchan1.py index c62f1427..d93b1b3e 100644 --- a/tests/python/testXchan1.py +++ b/tests/python/testXchan1.py @@ -27,8 +27,6 @@ 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 moose.fixXreacs as fixXreacs diff --git a/tests/python/testXdiff1.py b/tests/python/testXdiff1.py index 71b30993..0cec22d9 100644 --- a/tests/python/testXdiff1.py +++ b/tests/python/testXdiff1.py @@ -27,8 +27,6 @@ import math import numpy as np -import matplotlib.pyplot as plt -import matplotlib.image as mpimg import moose import moose.fixXreacs as fixXreacs diff --git a/tests/python/testXenz1.py b/tests/python/testXenz1.py index 80071aa5..75234a11 100644 --- a/tests/python/testXenz1.py +++ b/tests/python/testXenz1.py @@ -17,8 +17,6 @@ import math import numpy as np -import matplotlib.pyplot as plt -import matplotlib.image as mpimg import moose import moose.fixXreacs as fixXreacs diff --git a/tests/python/testXreacs2.py b/tests/python/testXreacs2.py index 1d5bed33..cee4e6b4 100644 --- a/tests/python/testXreacs2.py +++ b/tests/python/testXreacs2.py @@ -1,7 +1,5 @@ # -*- 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 diff --git a/tests/python/testXreacs3.py b/tests/python/testXreacs3.py index fa99656f..a4d68029 100644 --- a/tests/python/testXreacs3.py +++ b/tests/python/testXreacs3.py @@ -22,8 +22,6 @@ import math import numpy as np -import matplotlib.pyplot as plt -import matplotlib.image as mpimg import moose import moose.fixXreacs as fixXreacs diff --git a/tests/python/testXreacs4.py b/tests/python/testXreacs4.py index d618e05c..ceb36096 100644 --- a/tests/python/testXreacs4.py +++ b/tests/python/testXreacs4.py @@ -11,8 +11,6 @@ import math import numpy as np -import matplotlib.pyplot as plt -import matplotlib.image as mpimg import moose import moose.fixXreacs as fixXreacs diff --git a/tests/python/testXreacs4a.py b/tests/python/testXreacs4a.py index 482c0dba..79f98ba6 100644 --- a/tests/python/testXreacs4a.py +++ b/tests/python/testXreacs4a.py @@ -11,8 +11,6 @@ import math import numpy as np -import matplotlib.pyplot as plt -import matplotlib.image as mpimg import moose import moose.fixXreacs as fixXreacs diff --git a/tests/python/testXreacs5.py b/tests/python/testXreacs5.py index 7012dd96..f011381e 100644 --- a/tests/python/testXreacs5.py +++ b/tests/python/testXreacs5.py @@ -11,8 +11,6 @@ import math import numpy as np -import matplotlib.pyplot as plt -import matplotlib.image as mpimg import moose import moose.fixXreacs as fixXreacs diff --git a/tests/python/testXreacs5a.py b/tests/python/testXreacs5a.py index 3d552f34..45e32743 100644 --- a/tests/python/testXreacs5a.py +++ b/tests/python/testXreacs5a.py @@ -11,8 +11,6 @@ import math import numpy as np -import matplotlib.pyplot as plt -import matplotlib.image as mpimg import moose import moose.fixXreacs as fixXreacs diff --git a/tests/python/testXreacs6.py b/tests/python/testXreacs6.py index 75bd905b..e491253d 100644 --- a/tests/python/testXreacs6.py +++ b/tests/python/testXreacs6.py @@ -11,8 +11,6 @@ import math import numpy as np -import matplotlib.pyplot as plt -import matplotlib.image as mpimg import moose import moose.fixXreacs as fixXreacs diff --git a/tests/python/testXreacs7.py b/tests/python/testXreacs7.py index 73008321..bb7d79a1 100644 --- a/tests/python/testXreacs7.py +++ b/tests/python/testXreacs7.py @@ -13,8 +13,6 @@ import math import numpy as np -import matplotlib.pyplot as plt -import matplotlib.image as mpimg import moose import moose.fixXreacs as fixXreacs diff --git a/tests/python/testXreacs8.py b/tests/python/testXreacs8.py index 0ae0dba9..bf5d28ed 100644 --- a/tests/python/testXreacs8.py +++ b/tests/python/testXreacs8.py @@ -22,8 +22,6 @@ import math import numpy as np -import matplotlib.pyplot as plt -import matplotlib.image as mpimg import moose import moose.fixXreacs as fixXreacs diff --git a/tests/python/test_GraupnerBrunel2012_STDPfromCaPlasticity.py b/tests/python/test_GraupnerBrunel2012_STDPfromCaPlasticity.py index 73aa8c9e..b01a3408 100644 --- a/tests/python/test_GraupnerBrunel2012_STDPfromCaPlasticity.py +++ b/tests/python/test_GraupnerBrunel2012_STDPfromCaPlasticity.py @@ -8,8 +8,6 @@ # 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 diff --git a/tests/python/test_Xchan1.py b/tests/python/test_Xchan1.py index af555663..d1eb3511 100644 --- a/tests/python/test_Xchan1.py +++ b/tests/python/test_Xchan1.py @@ -63,7 +63,7 @@ def makeModel(): 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 + chan.permeability = 0.1 * chanPool.volume * 6.022e23 *0.001 / chanPool.nInit ##################################################################### fixXreacs.fixXreacs( '/model' ) diff --git a/tests/python/test_Xreacs2.py b/tests/python/test_Xreacs2.py index 4089501c..2fb36cfb 100644 --- a/tests/python/test_Xreacs2.py +++ b/tests/python/test_Xreacs2.py @@ -7,7 +7,8 @@ import moose.fixXreacs as fixXreacs def countCrossings( plot, thresh ): vec = moose.element( plot ).vector - #print (vec[:-1] < thresh) + print( vec ) + # print (vec[:-1] <= thresh) return sum( (vec[:-1] < thresh) * (vec[1:] >= thresh ) ) def main( standalone = False ): @@ -43,7 +44,8 @@ def main( standalone = False ): 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 ) + nCrossings = countCrossings( '/model/graphs/conc2/M.Co', 0.001 ) + assert( nCrossings == 4 ), "Expected 4, got %d" % nCrossings moose.delete( '/model' ) # Run the 'main' if this script is executed standalone. diff --git a/tests/python/test_dose_response.py b/tests/python/test_dose_response.py new file mode 100644 index 00000000..4a897301 --- /dev/null +++ b/tests/python/test_dose_response.py @@ -0,0 +1,116 @@ +# -*- coding: utf-8 -*- +from __future__ import print_function, division + +## Makes and plots the dose response curve for bistable models +## Author: Sahil Moza +## June 26, 2014 +## Update: +## Friday 14 September 2018 05:48:42 PM IST +## Tunrned into a light-weight test by Dilawar Singh + +import os +import sys +import moose +import numpy as np + +sdir_ = os.path.dirname( os.path.realpath( __file__ ) ) +vals_ = [ ] + +def setupSteadyState(simdt,plotDt): + + ksolve = moose.Ksolve( '/model/kinetics/ksolve' ) + stoich = moose.Stoich( '/model/kinetics/stoich' ) + stoich.compartment = moose.element('/model/kinetics') + stoich.ksolve = ksolve + stoich.path = "/model/kinetics/##" + state = moose.SteadyState( '/model/kinetics/state' ) + moose.reinit() + state.stoich = stoich + state.showMatrices() + state.convergenceCriterion = 1e-8 + return ksolve, state + +def parseModelName(fileName): + pos1=fileName.rfind('/') + pos2=fileName.rfind('.') + directory=fileName[:pos1] + prefix=fileName[pos1+1:pos2] + suffix=fileName[pos2+1:len(fileName)] + return directory, prefix, suffix + +# Solve for the steady state +def getState( ksolve, state, vol): + scale = 1.0 / ( vol * 6.022e23 ) + moose.reinit() + state.randomInit() # Removing random initial condition to systematically make Dose reponse curves. + moose.start( 2.0 ) # Run the model for 2 seconds. + a = moose.element( '/model/kinetics/a' ).conc + vals_.append( a ) + state.settle() + + vector = [] + a = moose.element( '/model/kinetics/a' ).conc + for x in ksolve.nVec[0]: + vector.append( x * scale) + failedSteadyState = any([np.isnan(x) for x in vector]) + if not (failedSteadyState): + return state.stateType, state.solutionStatus, a, vector + + +def main(): + # Setup parameters for simulation and plotting + simdt= 1e-2 + plotDt= 1 + + # Factors to change in the dose concentration in log scale + factorExponent = 10 ## Base: ten raised to some power. + factorBegin = -10 + factorEnd = 11 + factorStepsize = 2 + factorScale = 10.0 ## To scale up or down the factors + + # Load Model and set up the steady state solver. + # model = sys.argv[1] # To load model from a file. + model = os.path.join( sdir_, 'chem_models/19085.cspace' ) + modelPath, modelName, modelType = parseModelName(model) + outputDir = modelPath + + modelId = moose.loadModel(model, 'model', 'ee') + dosePath = '/model/kinetics/b/DabX' # The dose entity + + ksolve, state = setupSteadyState( simdt, plotDt) + vol = moose.element( '/model/kinetics' ).volume + iterInit = 100 + solutionVector = [] + factorArr = [] + + enz = moose.element(dosePath) + init = float(enz.kcat) # Dose parameter + + # Change Dose here to . + for factor in range(factorBegin, factorEnd, factorStepsize ): + scale = factorExponent ** (factor/factorScale) + enz.kcat = init * scale + print( "scale={:.3f}\tkcat={:.3f}".format( scale, enz.kcat) ) + for num in range(iterInit): + stateType, solStatus, a, vector = getState( ksolve, state, vol) + if solStatus == 0: + #solutionVector.append(vector[0]/sum(vector)) + solutionVector.append(a) + factorArr.append(scale) + + expected = (0.001411, 0.00092559) + got = ( np.mean(vals_), np.std(vals_) ) + assert np.isclose(got, expected, atol=1e-4).all(), "Got %s, expected %s" % (got, expected) + print( '[TEST1] Passed. Concentration of a is same' ) + + joint = np.array([factorArr, solutionVector]) + joint = joint[:,joint[1,:].argsort()] + got = np.mean( joint ), np.std( joint ) + expected = (1.2247, 2.46) + # Close upto 2 decimal place is good enough. + assert np.isclose(got, expected, atol=1e-2).all(), "Got %s, expected %s" % (got, expected) + print( joint ) + +if __name__ == '__main__': + main() diff --git a/tests/python/test_kkit.py b/tests/python/test_kkit.py index 0b7c3758..e4b0336b 100644 --- a/tests/python/test_kkit.py +++ b/tests/python/test_kkit.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - import numpy import sys import os diff --git a/tests/python/test_moose_attribs.py b/tests/python/test_moose_attribs.py new file mode 100644 index 00000000..4d3d9770 --- /dev/null +++ b/tests/python/test_moose_attribs.py @@ -0,0 +1,67 @@ +"""test_moose_attribs.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 moose + +attribs = ['AdExIF', 'AdThreshIF', 'Adaptor', 'Annotator', 'Arith', 'BufPool', + 'CaConc', 'CaConcBase', 'ChanBase', 'ChemCompt', 'Cinfo', 'Clock', + 'Compartment', 'CompartmentBase', 'ConcChan', 'CplxEnzBase', 'CubeMesh', + 'CylMesh', 'DestField', 'DiagonalMsg', 'DifBuffer', 'DifBufferBase', + 'DifShell', 'DifShellBase', 'DiffAmp', 'Dsolve', 'ElementField', + 'EndoMesh', 'Enz', 'EnzBase', 'ExIF', 'Finfo', 'Func', 'Function', + 'GapJunction', 'GraupnerBrunel2012CaPlasticitySynHandler', 'Group', + 'Gsolve', 'HHChannel', 'HHChannel2D', 'HHChannelBase', 'HHGate', + 'HHGate2D', 'HSolve', 'INFINITE', 'IntFire', 'IntFireBase', 'Interpol', + 'Interpol2D', 'IzhIF', 'IzhikevichNrn', 'Ksolve', 'LIF', 'Leakage', + 'LookupField', 'MMPump', 'MMenz', 'MarkovChannel' , + # 'MarkovGslSolver', # This is GSL specific. + 'MarkovRateTable', 'MarkovSolver', 'MarkovSolverBase', 'MeshEntry', + 'MgBlock', 'Msg', 'Mstring', 'NMDAChan', 'Nernst', 'NeuroMesh', + 'Neuron', 'Neutral', 'OneToAllMsg', 'OneToOneDataIndexMsg', + 'OneToOneMsg', 'PIDController', 'Pool', 'PoolBase', + 'PostMaster', 'PsdMesh', 'PulseGen', 'PyRun', 'QIF', 'RC', 'RandSpike', + 'Reac', 'ReacBase', 'SBML', 'STDPSynHandler', 'STDPSynapse', + 'SeqSynHandler', 'Shell', 'SimpleSynHandler', 'SingleMsg', 'SparseMsg', + 'Species', 'SpikeGen', 'SpikeStats', 'Spine', 'SpineMesh', 'Stats', + 'SteadyState', 'StimulusTable', 'Stoich', 'Streamer', 'StringIO', + 'SymCompartment', 'SynChan', 'SynHandlerBase', 'Synapse', 'Table', + 'Table2', 'TableBase', 'TimeTable', 'VClamp', 'VERSION', 'Variable', + 'VectorTable', 'ZombieBufPool', 'ZombieCaConc', 'ZombieCompartment', + 'ZombieEnz', 'ZombieFunction', 'ZombieHHChannel', 'ZombieMMenz', + 'ZombiePool', 'ZombieReac', '_moose', + 'append_finfodocs', 'ce', 'chemMerge', + 'chemUtil', 'closing', 'connect', 'copy', 'delete', 'division', 'doc', + 'element', 'exists', 'finfotypes', 'fixXreacs', 'genesis', 'getCwe', + 'getField', 'getFieldDict', 'getFieldNames', 'getfielddoc', + 'getmoosedoc', 'isRunning', + 'known_types', 'le', 'listmsg', 'loadModel', 'melement', + 'mergeChemModel', 'moose', + 'mooseAddChemSolver', 'mooseDeleteChemSolver', 'mooseReadNML2', + 'mooseReadSBML', 'mooseWriteKkit', 'mooseWriteNML2', 'mooseWriteSBML', + 'moose_constants', 'moose_test', 'move', + 'nml2Import_', 'pager', 'print_utils', + 'pwe', 'pydoc', 'rand', 'reinit', + 'seed', 'sequence_types', 'setClock', 'setCwe', 'showfield', + 'showfields', 'showmsg', 'splitext', 'start', 'stop', 'syncDataHandler', + 'test', 'testSched', 'toUnicode', 'useClock', 'utils', 'vec', 'version', + 'warnings', 'wildcardFind'] + +def main(): + global attribs + for at in attribs: + assert hasattr( moose, at ), 'Attrib %s not found' % at + print( getattr(moose, at ) ) + +if __name__ == '__main__': + main() + diff --git a/tests/python/test_muparser.py b/tests/python/test_muparser.py index d5f92311..26480932 100644 --- a/tests/python/test_muparser.py +++ b/tests/python/test_muparser.py @@ -1,15 +1,10 @@ # -*- coding: utf-8 -*- - """test_muparser.py: - 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_neuroml2.py b/tests/python/test_neuroml2.py index 8460c092..d1b34ea3 100644 --- a/tests/python/test_neuroml2.py +++ b/tests/python/test_neuroml2.py @@ -6,6 +6,18 @@ from __future__ import absolute_import, print_function, division +# check if neuroml working properly. +# NOTE: This script does not work with python3 +# See https://github.com/NeuroML/NeuroML2/issues/116 . If this bug is fixed then +# remove this code block. +import neuroml as nml +a = nml.nml.nml.IonChannel() +try: + b = {a : 1 } +except TypeError as e: + print( 'Failed due to https://github.com/NeuroML/NeuroML2/issues/116' ) + quit( 0 ) + import moose import moose.utils as mu import sys @@ -14,6 +26,7 @@ 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' ) diff --git a/tests/python/test_rdesigneur.py b/tests/python/test_rdesigneur.py index f53ac93f..2972a3c0 100644 --- a/tests/python/test_rdesigneur.py +++ b/tests/python/test_rdesigneur.py @@ -11,8 +11,6 @@ __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_rdesigneur_random_syn_input.py b/tests/python/test_rdesigneur_random_syn_input.py new file mode 100644 index 00000000..07c3ccb3 --- /dev/null +++ b/tests/python/test_rdesigneur_random_syn_input.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +from __future__ import print_function, division + +# This example demonstrates random (Poisson) synaptic input to a cell. +# Copyright (C) Upinder S. Bhalla NCBS 2018 +# Released under the terms of the GNU Public License V3. No warranty. +# Changelog: +# Thursday 20 September 2018 09:53:27 AM IST +# - Turned into a test script. Dilawar Singh <dilawars@ncbs.res.in> + +import moose +import numpy as np + +moose.seed( 100 ) + +try: + import matplotlib +except Exception as e: + print( "[INFO ] matplotlib is not found. This test wont run." ) + quit() + +import rdesigneur as rd + +rdes = rd.rdesigneur( + cellProto = [['somaProto', 'soma', 20e-6, 200e-6]], + chanProto = [['make_glu()', 'glu']], + chanDistrib = [['glu', 'soma', 'Gbar', '1' ]], + stimList = [['soma', '0.5', 'glu', 'randsyn', '50' ]], + # Deliver stimulus to glu synapse on soma, at mean 50 Hz Poisson. + plotList = [['soma', '1', '.', 'Vm', 'Soma membrane potential']] +) +rdes.buildModel() +moose.reinit() +moose.start( 0.3 ) +tables = moose.wildcardFind( '/##[TYPE=Table]' ) +res = [ ] +for t in tables: + y = t.vector + u, s = np.mean(y), np.std(y) + res.append( (u,s) ) + + +# Got these values from version compiled on Sep 20, 2018 with moose.seed set to +# 100. +expected = [(-0.051218660048699974, 0.01028490481294165)] +assert np.isclose( expected, res, atol=1e-5).all(), "Expected %s, got %s" %(expected,res) diff --git a/tests/python/test_steady_state_solver.py b/tests/python/test_steady_state_solver.py new file mode 100644 index 00000000..fd3e13e1 --- /dev/null +++ b/tests/python/test_steady_state_solver.py @@ -0,0 +1,152 @@ +# -*- coding: utf-8 -*- +from __future__ import print_function, division + +# This program is part of 'MOOSE', the +# Messaging Object Oriented Simulation Environment. +# Copyright (C) 2013 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. +# Monday 17 September 2018 01:49:30 PM IST +# - Converted to a test script + +import math +import numpy as np +import moose +print( "[INFO ] Using moose from %s" % moose.__file__ ) + +def main(): + compartment = makeModel() + ksolve = moose.Ksolve( '/model/compartment/ksolve' ) + stoich = moose.Stoich( '/model/compartment/stoich' ) + stoich.compartment = compartment + stoich.ksolve = ksolve + stoich.path = "/model/compartment/##" + state = moose.SteadyState( '/model/compartment/state' ) + + moose.reinit() + state.stoich = stoich + state.convergenceCriterion = 1e-6 + moose.seed( 111 ) # Used when generating the samples in state space + + b = moose.element( '/model/compartment/b' ) + a = moose.element( '/model/compartment/a' ) + c = moose.element( '/model/compartment/c' ) + a.concInit = 0.1 + deltaA = 0.002 + num = 150 + avec = [] + bvec = [] + moose.reinit() + + # Now go up. + for i in range( 0, num ): + moose.start( 1.0 ) # Run the model for 1 seconds. + state.settle() # This function finds the steady states. + avec.append( a.conc ) + bvec.append( b.conc ) + a.concInit += deltaA + + aa, bb = avec, bvec + got = np.mean(aa), np.std(aa) + expected = 0.24899, 0.08660 + assert np.isclose(got, expected, atol = 1e-4).all(), "Got %s, expected %s" % (got, expected) + print( "[INFO ] Test 1 PASSED" ) + + + # Now go down. + avec = [] + bvec = [] + for i in range( 0, num ): + moose.start( 1.0 ) # Run the model for 1 seconds. + state.settle() # This function finds the steady states. + avec.append( a.conc ) + bvec.append( b.conc ) + a.concInit -= deltaA + + aa, bb = avec, bvec + got = np.mean(aa), np.std(aa) + expected = 0.251, 0.0866 + assert np.isclose(got, expected, atol = 1e-4).all(), "Got %s, expected %s" % (got, expected) + print( "[INFO ] Test 2 PASSED" ) + + # Now aim for the middle. We do this by judiciously choosing a + # start point that should be closer to the unstable fixed point. + avec = [] + bvec = [] + a.concInit = 0.28 + b.conc = 0.15 + for i in range( 0, 65 ): + moose.start( 1.0 ) # Run the model for 1 seconds. + state.settle() # This function finds the steady states. + avec.append( a.conc ) + bvec.append( b.conc ) + a.concInit -= deltaA + + aa, bb = avec, bvec + got = np.mean(aa), np.std(aa) + expected = 0.216, 0.03752 + assert np.isclose(got, expected, atol = 1e-4).all(), "Got %s, expected %s" % (got, expected) + print( "[INFO ] Test 3 PASSED" ) + quit() + +def makeModel(): + """ This function creates a bistable reaction system using explicit + MOOSE calls rather than load from a file. + The reaction is:: + + a ---b---> 2b # b catalyzes a to form more of b. + 2b ---c---> a # c catalyzes b to form a. + a <======> 2b # a interconverts to b. + + """ + # create container for model + model = moose.Neutral( 'model' ) + compartment = moose.CubeMesh( '/model/compartment' ) + compartment.volume = 1e-15 + # the mesh is created automatically by the compartment + mesh = moose.element( '/model/compartment/mesh' ) + + # create molecules and reactions + a = moose.BufPool( '/model/compartment/a' ) + b = moose.Pool( '/model/compartment/b' ) + c = moose.Pool( '/model/compartment/c' ) + enz1 = moose.Enz( '/model/compartment/b/enz1' ) + enz2 = moose.Enz( '/model/compartment/c/enz2' ) + cplx1 = moose.Pool( '/model/compartment/b/enz1/cplx' ) + cplx2 = moose.Pool( '/model/compartment/c/enz2/cplx' ) + reac = moose.Reac( '/model/compartment/reac' ) + + # connect them up for reactions + moose.connect( enz1, 'sub', a, 'reac' ) + moose.connect( enz1, 'prd', b, 'reac' ) + moose.connect( enz1, 'prd', b, 'reac' ) # Note 2 molecules of b. + moose.connect( enz1, 'enz', b, 'reac' ) + moose.connect( enz1, 'cplx', cplx1, 'reac' ) + + moose.connect( enz2, 'sub', b, 'reac' ) + moose.connect( enz2, 'sub', b, 'reac' ) # Note 2 molecules of b. + moose.connect( enz2, 'prd', a, 'reac' ) + moose.connect( enz2, 'enz', c, 'reac' ) + moose.connect( enz2, 'cplx', cplx2, 'reac' ) + + moose.connect( reac, 'sub', a, 'reac' ) + moose.connect( reac, 'prd', b, 'reac' ) + moose.connect( reac, 'prd', b, 'reac' ) # Note 2 order in b. + + # Assign parameters + a.concInit = 1 + b.concInit = 0 + c.concInit = 0.01 + enz1.kcat = 0.4 + enz1.Km = 4 + enz2.kcat = 0.6 + enz2.Km = 0.01 + reac.Kf = 0.001 + reac.Kb = 0.01 + + return compartment + +# Run the 'main' if this script is executed standalone. +if __name__ == '__main__': + main() diff --git a/tests/python/testdisabled_dose_response.py b/tests/python/testdisabled_dose_response.py new file mode 100644 index 00000000..a840565a --- /dev/null +++ b/tests/python/testdisabled_dose_response.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- +## Makes and plots the dose response curve for bistable models +## Author: Sahil Moza +## June 26, 2014 +## Update: +## Friday 14 September 2018 05:48:42 PM IST +## Tunrned into a light-weight test by Dilawar Singh + +import os +import sys +import moose +import numpy as np + +sdir_ = os.path.dirname( os.path.realpath( __file__ ) ) + +def setupSteadyState(simdt,plotDt): + + ksolve = moose.Ksolve( '/model/kinetics/ksolve' ) + stoich = moose.Stoich( '/model/kinetics/stoich' ) + stoich.compartment = moose.element('/model/kinetics') + stoich.ksolve = ksolve + stoich.path = "/model/kinetics/##" + state = moose.SteadyState( '/model/kinetics/state' ) + moose.reinit() + state.stoich = stoich + state.showMatrices() + state.convergenceCriterion = 1e-8 + return ksolve, state + +def parseModelName(fileName): + pos1=fileName.rfind('/') + pos2=fileName.rfind('.') + directory=fileName[:pos1] + prefix=fileName[pos1+1:pos2] + suffix=fileName[pos2+1:len(fileName)] + return directory, prefix, suffix + +# Solve for the steady state +def getState( ksolve, state, vol): + scale = 1.0 / ( vol * 6.022e23 ) + moose.reinit() + state.randomInit() # Removing random initial condition to systematically make Dose reponse curves. + moose.start( 2.0 ) # Run the model for 2 seconds. + state.settle() + + vector = [] + a = moose.element( '/model/kinetics/a' ).conc + for x in ksolve.nVec[0]: + vector.append( x * scale) + failedSteadyState = any([np.isnan(x) for x in vector]) + if not (failedSteadyState): + return state.stateType, state.solutionStatus, a, vector + + +def main(): + # Setup parameters for simulation and plotting + simdt= 1e-2 + plotDt= 1 + + # Factors to change in the dose concentration in log scale + factorExponent = 10 ## Base: ten raised to some power. + factorBegin = -10 + factorEnd = 11 + factorStepsize = 2 + factorScale = 10.0 ## To scale up or down the factors + + # Load Model and set up the steady state solver. + # model = sys.argv[1] # To load model from a file. + model = os.path.join( sdir_, 'chem_models/19085.cspace' ) + modelPath, modelName, modelType = parseModelName(model) + outputDir = modelPath + + modelId = moose.loadModel(model, 'model', 'ee') + dosePath = '/model/kinetics/b/DabX' # The dose entity + + ksolve, state = setupSteadyState( simdt, plotDt) + vol = moose.element( '/model/kinetics' ).volume + iterInit = 100 + solutionVector = [] + factorArr = [] + + enz = moose.element(dosePath) + init = float(enz.kcat) # Dose parameter + + # Change Dose here to . + for factor in range(factorBegin, factorEnd, factorStepsize ): + scale = factorExponent ** (factor/factorScale) + enz.kcat = init * scale + print( "scale={:.3f}\tkcat={:.3f}".format( scale, enz.kcat) ) + for num in range(iterInit): + stateType, solStatus, a, vector = getState( ksolve, state, vol) + if solStatus == 0: + #solutionVector.append(vector[0]/sum(vector)) + solutionVector.append(a) + factorArr.append(scale) + + joint = np.array([factorArr, solutionVector]) + joint = joint[:,joint[1,:].argsort()] + got = np.mean( joint ), np.std( joint ) + expected = (1.2247, 2.46) + # Close upto 2 decimal place is good enough. + assert np.isclose(got, expected, atol=1e-2).all(), "Got %s, expected %s" % (got, expected) + print( joint ) + +if __name__ == '__main__': + main() diff --git a/utility/Annotator.cpp b/utility/Annotator.cpp index 8dca2186..4f1c51bd 100644 --- a/utility/Annotator.cpp +++ b/utility/Annotator.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" #include "Annotator.h" const Cinfo* Annotator::initCinfo() diff --git a/utility/CMakeLists.txt b/utility/CMakeLists.txt index 67e180ed..5fcd5cee 100644 --- a/utility/CMakeLists.txt +++ b/utility/CMakeLists.txt @@ -1,3 +1,6 @@ +cmake_minimum_required(VERSION 2.8) +include( ${CMAKE_CURRENT_SOURCE_DIR}/../CheckCXXCompiler.cmake) + IF(WITH_BOOST) include(CheckIncludeFiles) check_include_files( ${Boost_INCLUDE_DIRS}/boost/random/random_device.hpp @@ -5,8 +8,6 @@ check_include_files( ${Boost_INCLUDE_DIRS}/boost/random/random_device.hpp ) endif(WITH_BOOST) -include_directories(../msg) -include_directories(../basecode) add_library(utility strutil.cpp types.cpp diff --git a/utility/cnpy.hpp b/utility/cnpy.hpp index afbc0e71..b7148beb 100644 --- a/utility/cnpy.hpp +++ b/utility/cnpy.hpp @@ -38,7 +38,7 @@ #include <stdint.h> -#include "global.h" +#include "../basecode/global.h" #include "../utility/print_function.hpp" diff --git a/utility/print_function.hpp b/utility/print_function.hpp index 4b984d7c..c2cf0c7f 100644 --- a/utility/print_function.hpp +++ b/utility/print_function.hpp @@ -226,14 +226,13 @@ namespace moose { moose::__dump__(msg, moose::warning ); } - inline void showDebug( const string msg ) - { + inline void showDebug( const string msg ) + { #ifdef DISABLE_DEBUG - #else - moose::__dump__(msg, moose::debug ); + moose::__dump__(msg, moose::debug ); #endif - } + } inline void showError( string msg ) { diff --git a/wheels/Dockerfile b/wheels/Dockerfile deleted file mode 100644 index cec973ab..00000000 --- a/wheels/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -FROM quay.io/pypa/manylinux1_x86_64 -MAINTAINER Dilawar Singh <dilawar.s.rajput@gmail.com> - -# If you are behind proxy, uncomment the following lines with appropriate -# values. Otherwise comment them out. -ENV http_proxy http://proxy.ncbs.res.in:3128 -ENV https_proxy http://proxy.ncbs.res.in:3128 -ENV PATH=/usr/local/bin:$PATH - -RUN yum update -RUN yum install -y cmake28 && ln -sf /usr/bin/cmake28 /usr/bin/cmake -RUN yum install -y wget -RUN if [ ! -f /usr/local/lib/libgsl.a ]; then \ - wget --no-check-certificate ftp://ftp.gnu.org/gnu/gsl/gsl-2.4.tar.gz && \ - tar xvf gsl-2.4.tar.gz && cd gsl-2.4 && ./configure && make -j2 && \ - make install && cd; fi -RUN ./build_wheels.sh diff --git a/wheels/build_wheels.sh b/wheels/build_wheels.sh deleted file mode 100755 index 5509ea85..00000000 --- a/wheels/build_wheels.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash -set -e -set -x - -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - -MOOSE_SOURCE_DIR=/tmp/moose-core -# Clone git or update. -if [ ! -d $MOOSE_SOURCE_DIR ]; then - git clone -b wheels https://github.com/BhallaLab/moose-core --depth 10 $MOOSE_SOURCE_DIR -else - cd $MOOSE_SOURCE_DIR && git pull && git merge master -X theirs && cd - -fi - -# Try to link statically. -GSL_STATIC_LIBS="/usr/local/lib/libgsl.a;/usr/local/lib/libgslcblas.a" -CMAKE=/usr/bin/cmake28 - -WHEELHOUSE=$HOME/wheelhouse -mkdir -p $WHEELHOUSE -for PYDIR in /opt/python/cp27-cp27m/ /opt/python/cp34-cp34m/ /opt/python/cp36-cp36m/; do - PYVER=$(basename $PYDIR) - mkdir -p $PYVER - ( - cd $PYVER - echo "Building using $PYDIR in $PYVER" - PYTHON=$(ls $PYDIR/bin/python?.?) - $PYTHON -m pip install numpy - $CMAKE -DPYTHON_EXECUTABLE=$PYTHON \ - -DGSL_STATIC_LIBRARIES=$GSL_STATIC_LIBS \ - -DMOOSE_VERSION="3.2rc1" ${MOOSE_SOURCE_DIR} - make -j4 - - # Now build bdist_wheel - cd python - cp setup.cmake.py setup.py - $PYDIR/bin/pip wheel . -w $WHEELHOUSE - ) -done - -# now check the wheels. -for whl in $WHEELHOUSE/*.whl; do - #auditwheel repair "$whl" -w $WHEELHOUSE - auditwheel show "$whl" -done -ls -lh $WHEELHOUSE/*.whl -- GitLab