From 6d651b6013e1093a1cdb2541bb8615bbc3a66021 Mon Sep 17 00:00:00 2001
From: Dilawar Singh <dilawars@ncbs.res.in>
Date: Wed, 28 Feb 2018 13:30:40 +0530
Subject: [PATCH] Squashed 'moose-core/' changes from 0c33b2c333..49d5b3ef6b
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

49d5b3ef6b Merge pull request #255 from dilawar/master
f498d7c6a4 Merge branch 'master' of github.com:dilawar/moose-core
c09dd9936f Cut down on unneccessary looping. It is logically equivalent to original block.
aab34e125d Merge branch 'master' into master
3568083113 replace has_key with python3 compatible statement.
026d0a39b1 updated pre-commit config.
b811def3bd Merge branch 'master' of github.com:BhallaLab/moose-core
5bc1e1410a Merge pull request #254 from upibhalla/master
b08b888f56 Merge branch 'master' of https://github.com/BhallaLab/moose-core
945fb6b961 Added funcDt to rdesigneur arguments, set sensible defaults
760f554966 Update Function.cpp
8e9bcb58ac Merge pull request #253 from upibhalla/master
2f8dc9fcfe Merge branch 'master' of https://github.com/BhallaLab/moose-core
b55e1a74ea Update to Synapse to permit set/get access to addSpike. Cascaded onto all SynHandlers. Update to rdesigneur to permit fullscreen display of Moogli.
6eca687a68 Added deploy section in travis. Deploy on PyPi. Needs to add script t… (#251)
c8f9101621 Fixed cmake error on osx when not compiled in debug mode. Affect only >=cmake-3.6
f6ab07d0ef Update README.md
0d3f850fe5 Update README.md
cc94e3bd61 Set VERSION_MOOSE only
948406bc17 Marked as release candidate 3.2.0rc1.
b675c4d1bf Fixed build failure due to newline in output variable.
bf8d39351e Add git hash to version.
d95e58650f Python wheel for pymoose (#250)
edbb4ce966 Fixing VERSION; MOOSE_VERSION; project name is moose-core.
e245ef6a4d call project moose-core.
9061927ca7 Build GSL with fPIC.
230466ff32 updated dockerfile. Added missing gsl library.
69bc228b34 rename to pymoose.
41ef965e75 Heredocs are not supported in docker.
f370b4aa19 Docker file has the script inline.
b8b9679943 Time to merge into master branch.
9c7241f1bd Wheels are built. Now use manylinux docker file to build them.
c439f55046 Build in manylinux environment.
108f71809d Wheel is created.
d08ddf290f removed file.
9d654b4cba no need to link with PYTHON_LIBS.

git-subtree-dir: moose-core
git-subtree-split: 49d5b3ef6b585ff1c64734f447ac08cd67d9996a
---
 .pre-commit-config.yaml                       |   3 +-
 .travis.yml                                   |  52 +++--
 .travis/deploy_pypi.sh                        |  22 ++
 CMakeLists.txt                                |  63 +++---
 Jenkinsfile                                   |  15 --
 README.md                                     |  18 +-
 builtins/Function.cpp                         |  52 ++---
 cmake_modules/GetGitRevisionDescription.cmake | 168 +++++++++++++++
 .../GetGitRevisionDescription.cmake.in        |  41 ++++
 cmake_moose_cpack.cmake                       |   4 +-
 pymoose/CMakeLists.txt                        |   2 +-
 python/moose/SBML/readSBML.py                 |   7 +-
 python/rdesigneur/rdesigneur.py               |  17 +-
 python/rdesigneur/rmoogli.py                  |   7 +-
 python/setup.cmake.py                         |  21 +-
 scripts/setup.py => setup.py                  |   4 +-
 setup_/__init__.py                            | 203 ------------------
 ...aupnerBrunel2012CaPlasticitySynHandler.cpp |   9 +
 ...GraupnerBrunel2012CaPlasticitySynHandler.h |   1 +
 synapse/STDPSynHandler.cpp                    |   7 +
 synapse/STDPSynHandler.h                      |   1 +
 synapse/SeqSynHandler.cpp                     |   7 +
 synapse/SeqSynHandler.h                       |   1 +
 synapse/SimpleSynHandler.cpp                  |   7 +
 synapse/SimpleSynHandler.h                    |   1 +
 synapse/SynHandlerBase.h                      |   1 +
 synapse/Synapse.cpp                           |  14 ++
 synapse/Synapse.h                             |   1 +
 wheels/Dockerfile                             |  17 ++
 wheels/build_wheels.sh                        |  46 ++++
 30 files changed, 493 insertions(+), 319 deletions(-)
 create mode 100755 .travis/deploy_pypi.sh
 delete mode 100644 Jenkinsfile
 create mode 100644 cmake_modules/GetGitRevisionDescription.cmake
 create mode 100644 cmake_modules/GetGitRevisionDescription.cmake.in
 rename scripts/setup.py => setup.py (97%)
 delete mode 100644 setup_/__init__.py
 create mode 100644 wheels/Dockerfile
 create mode 100755 wheels/build_wheels.sh

diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 5eccd7a7..f8aa18ad 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,5 +1,6 @@
+repos:
 -   repo: https://github.com/pre-commit/pre-commit-hooks
-    sha: v0.8.0
+    sha: v1.2.1
     hooks:
     - id: check-added-large-files
     - id: check-ast
diff --git a/.travis.yml b/.travis.yml
index f38c78cc..d1de05b8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,31 +1,37 @@
 language: cpp
-dist: trusty
 sudo: required
 group: edge
 
-os:
-    - linux
-    - osx
+services: 
+    - docker
 
+os:
+- linux
+- osx
 notifications:
-    email:
-        recipients:
-            - bhalla@ncbs.res.in
-            - dilawar.s.rajput@gmail.com
-            - hrani@ncbs.res.in
-        on_success: change
-        on_failure: always
-
-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
+  email:
+    recipients:
+    - bhalla@ncbs.res.in
+    - dilawar.s.rajput@gmail.com
+    - hrani@ncbs.res.in
+    on_success: change
+    on_failure: always
 
+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:
-    - # checking if any python3 incompatible file is in the source tree.
-    - python2 -m compileall -q .
-    - if type python3 > /dev/null; then python3 -m compileall -q . ; fi
-    - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./.travis/travis_build_osx.sh; fi
-    - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./.travis/travis_build_linux.sh; fi
-    - set +e
+- 
+- python2 -m compileall -q .
+- if type python3 > /dev/null; then python3 -m compileall -q . ; fi
+- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./.travis/travis_build_osx.sh; fi
+- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./.travis/travis_build_linux.sh; fi
+- set +e
+
+deploy:
+  on: tags
+  provider: script
+  script: ./.travis/deploy_pypi.sh
diff --git a/.travis/deploy_pypi.sh b/.travis/deploy_pypi.sh
new file mode 100755
index 00000000..ed7c978d
--- /dev/null
+++ b/.travis/deploy_pypi.sh
@@ -0,0 +1,22 @@
+#!/bin/bash -
+#===============================================================================
+#
+#          FILE: deploy_pypi.sh
+#
+#         USAGE: ./deploy_pypi.sh
+#
+#   DESCRIPTION:  Build docker image and deploy on PyPI.
+#
+#       OPTIONS: ---
+#  REQUIREMENTS: ---
+#          BUGS: ---
+#         NOTES: ---
+#        AUTHOR: Dilawar Singh (), dilawars@ncbs.res.in
+#  ORGANIZATION: NCBS Bangalore
+#       CREATED: Sunday 04 February 2018 11:46:32  IST
+#      REVISION:  ---
+#===============================================================================
+set -o nounset                                  # Treat unset variables as an error
+
+git clone https://github.com/BhallaLab/pymoose-wheels
+cd pymoose-wheels && docker build -t bhallalab/wheels .
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4daf30d9..a73455b2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,7 @@
 set(CMAKE_LEGACY_CYGWIN_WIN32 0)
 cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
-project(MOOSE)
+
+project(moose-core)
 
 if(COMMAND cmake_policy)
     cmake_policy(SET CMP0003 NEW)
@@ -15,18 +16,28 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules")
 include(CheckCXXCompiler.cmake)
 include(CheckIncludeFileCXX)
 include(FindPkgConfig)
-include(GetRevision)
+
+# getgit revision number
+find_program( GIT_EXEC git )
+if(GIT_EXEC)
+    execute_process(COMMAND ${GIT_EXEC} rev-parse --short HEAD 
+        OUTPUT_VARIABLE GIT_HEAD
+        OUTPUT_STRIP_TRAILING_WHITESPACE
+        )
+endif()
 
 # If from command line, version info is not passed, use the git to generate a
 # version file. If GIT fails, use the previous known version.
-set(MOOSE_VERSION 3.2-git)
-add_definitions( -DMOOSE_VERSION="${MOOSE_VERSION}")
-message( STATUS "MOOSE Version ${MOOSE_VERSION}" )
+if(NOT VERSION_MOOSE)
+    set(VERSION_MOOSE "3.2.0rc1-${GIT_HEAD}")
+endif( )
+add_definitions( -DMOOSE_VERSION="${VERSION_MOOSE}")
+message( STATUS "MOOSE Version ${VERSION_MOOSE}" )
 
-# Write VERSION to a file VERSION so that setup.py can use it.
-set(VERSION_FILE ${CMAKE_CURRENT_SOURCE_DIR}/VERSION)
-message(STATUS "+ Writing ${MOOSE_VERSION} to ${VERSION_FILE}" )
-file(WRITE ${VERSION_FILE} ${MOOSE_VERSION} )
+# Write VERSION to a file VERSION so that setup.cmake.py can use it.
+set(VERSION_FILE ${CMAKE_CURRENT_SOURCE_DIR}/python/VERSION)
+message(STATUS "+ Writing ${VERSION_MOOSE} to ${VERSION_FILE}" )
+file(WRITE ${VERSION_FILE} ${VERSION_MOOSE} )
 
 # This snippet is from LLVM project.
 # Sanity check our source directory to make sure that we are not trying to
@@ -267,19 +278,24 @@ endif(WITH_BOOST)
 # these two types because of --whole-archive option. See
 # BhallaLab/moose-core#66,
 if(WITH_GSL)
-    message(STATUS "Using gsl libraries: ${GSL_LIBRARIES}")
-    foreach(GSL_LIB ${GSL_LIBRARIES} )
-        if(GSL_LIB)
-            get_filename_component( GSL_LIB_EXT ${GSL_LIB} EXT )
-            if(GSL_LIB_EXT)
-                if(GSL_LIB_EXT STREQUAL ".a" )
-                    list(APPEND STATIC_LIBRARIES ${GSL_LIB})
-                else()
-                    list(APPEND SYSTEM_SHARED_LIBS ${GSL_LIB})
-                endif( )
-            endif( )
-        endif( )
-    endforeach( )
+    if(GSL_STATIC_LIBRARIES)
+       message( STATUS "Using static libraries ${GSL_STATIC_LIBRARIES}" )
+       list(APPEND STATIC_LIBRARIES ${GSL_STATIC_LIBRARIES})
+    else( )
+       message(STATUS "Using gsl libraries: ${GSL_LIBRARIES}")
+       foreach(GSL_LIB ${GSL_LIBRARIES} )
+           if(GSL_LIB)
+               get_filename_component( GSL_LIB_EXT ${GSL_LIB} EXT )
+               if(GSL_LIB_EXT)
+                   if(GSL_LIB_EXT STREQUAL ".a" )
+                       list(APPEND STATIC_LIBRARIES ${GSL_LIB})
+                   else()
+                       list(APPEND SYSTEM_SHARED_LIBS ${GSL_LIB})
+                   endif( )
+               endif( )
+           endif( )
+       endforeach( )
+   endif( )
 endif()
 
 if(WITH_MPI)
@@ -373,6 +389,7 @@ if(DEBUG)
     endif( WITH_BOOST )
 endif()
 
+
 ######################### BUILD PYMOOSE ########################################
 add_subdirectory( pymoose )
 
@@ -431,8 +448,6 @@ if(${CMAKE_BUILD_TOOL} MATCHES "make")
 endif()
 
 
-
-
 ############################ CTEST ######################################
 include( CTest )
 # If CTEST_OUTPUT_ON_FAILURE environment variable is set, the output is printed
diff --git a/Jenkinsfile b/Jenkinsfile
deleted file mode 100644
index 2b8f686e..00000000
--- a/Jenkinsfile
+++ /dev/null
@@ -1,15 +0,0 @@
-pipeline {
-    agent any 
-    stages {
-        stage('Build') { 
-            steps { 
-                sh 'mkdir -p _build && cd _build && cmake .. && make -j4' 
-            }
-        }
-        stage('Test'){
-            steps {
-                sh 'cd _build && ctest --output-on-failure'
-            }
-        }
-    }
-}
diff --git a/README.md b/README.md
index 90d19144..dd8e6362 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,18 @@
-[![Build Status - master](https://travis-ci.org/BhallaLab/moose-core.svg?branch=master)](https://travis-ci.org/BhallaLab/moose-core)
+[![Build Status - master](https://travis-ci.org/BhallaLab/moose-core.svg?branch=master)](https://travis-ci.org/BhallaLab/moose-core) | [![PyPI version](https://badge.fury.io/py/pymoose.svg)](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. For more details about MOOSE simulator, see https://github.com/BhallaLab/moose/blob/master/README.md
+C++ codebase and python interface called `pymoose`. For more details about MOOSE simulator, visit https://moose.ncbs.res.in .
 
-This repository is sufficient for using MOOSE as a python module. If you just want to build moose python module, follow instructions given here at https://github.com/BhallaLab/moose-core/blob/master/INSTALL.md .
+# Download and Install
+
+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.  
+
+# Build 
+
+To build `pymoose`, follow instructions given here at https://github.com/BhallaLab/moose-core/blob/master/INSTALL.md 
diff --git a/builtins/Function.cpp b/builtins/Function.cpp
index 54224b27..79413c1b 100644
--- a/builtins/Function.cpp
+++ b/builtins/Function.cpp
@@ -150,7 +150,7 @@ const Cinfo * Function::initCinfo()
         "log2        1       logarithm to the base 2\n"
         "log10       1       logarithm to the base 10\n"
         "log         1       logarithm to the base 10\n"
-        "ln  1       logarithm to base e (2.71828...)\n"
+        "ln  	     1       logarithm to base e (2.71828...)\n"
         "exp         1       e raised to the power of x\n"
         "sqrt        1       square root of a value\n"
         "sign        1       sign function -1 if x<0; 1 if x>0\n"
@@ -166,32 +166,34 @@ const Cinfo * Function::initCinfo()
         "                    if seed = -1, a 'random' seed is created using either\n"
         "                    by random_device or by reading system clock\n"
         "\nOperators\n"
-        "Op  meaning         priority\n"
-        "=   assignment     -1\n"
-        "&&  logical and     1\n"
-        "||  logical or      2\n"
-        "<=  less or equal   4\n"
-        ">=  greater or equal        4\n"
-        "!=  not equal       4\n"
-        "==  equal   4\n"
-        ">   greater than    4\n"
-        "<   less than       4\n"
-        "+   addition        5\n"
-        "-   subtraction     5\n"
-        "*   multiplication  6\n"
-        "/   division        6\n"
-        "^   raise x to the power of y       7\n"
-        "%   floating point modulo         7\n"
+        "Op  meaning         		priority\n"
+        "=   assignment     		-1\n"
+        "&&  logical and     		1\n"
+        "||  logical or      		2\n"
+        "<=  less or equal   		4\n"
+        ">=  greater or equal  		4\n"
+        "!=  not equal         		4\n"
+        "==  equal   			4\n"
+        ">   greater than    		4\n"
+        "<   less than       		4\n"
+        "+   addition        		5\n"
+        "-   subtraction     		5\n"
+        "*   multiplication  		6\n"
+        "/   division        		6\n"
+        "^   raise x to the power of y  7\n"
+        "%   floating point modulo      7\n"
         "\n"
-        "?:  if then else operator   C++ style syntax\n",
+        "?:  if then else operator   	C++ style syntax\n",
         &Function::setExpr,
-        &Function::getExpr);
+        &Function::getExpr
+    );
 
     static ValueFinfo< Function, unsigned int > numVars(
         "numVars",
         "Number of variables used by Function.",
         &Function::setNumVar,
-        &Function::getNumVar);
+        &Function::getNumVar
+    );
 
     static FieldElementFinfo< Function, Variable > inputs(
         "x",
@@ -199,7 +201,8 @@ const Cinfo * Function::initCinfo()
         Variable::initCinfo(),
         &Function::getVar,
         &Function::setNumVar,
-        &Function::getNumVar);
+        &Function::getNumVar
+    );
 
     static LookupValueFinfo < Function, string, double > constants(
         "c",
@@ -229,10 +232,7 @@ const Cinfo * Function::initCinfo()
     static DestFinfo reinit( "reinit",
                              "Handles reinit call.",
                              new ProcOpFunc< Function >( &Function::reinit ) );
-    static Finfo* processShared[] =
-            {
-		&process, &reinit
-            };
+    static Finfo* processShared[] = { &process, &reinit };
 
     static SharedFinfo proc( "proc",
                              "This is a shared message to receive Process messages "
@@ -382,7 +382,7 @@ Function::Function(const Function& rhs): _numVar(rhs._numVar),
 
 Function& Function::operator=(const Function rhs)
 {
-	static Eref er;
+    static Eref er;
     _clearBuffer();
     _mode = rhs._mode;
     _lastValue = rhs._lastValue;
diff --git a/cmake_modules/GetGitRevisionDescription.cmake b/cmake_modules/GetGitRevisionDescription.cmake
new file mode 100644
index 00000000..8ab03bc5
--- /dev/null
+++ b/cmake_modules/GetGitRevisionDescription.cmake
@@ -0,0 +1,168 @@
+# - Returns a version string from Git
+#
+# These functions force a re-configure on each git commit so that you can
+# trust the values of the variables in your build system.
+#
+#  get_git_head_revision(<refspecvar> <hashvar> [<additional arguments to git describe> ...])
+#
+# Returns the refspec and sha hash of the current head revision
+#
+#  git_describe(<var> [<additional arguments to git describe> ...])
+#
+# Returns the results of git describe on the source tree, and adjusting
+# the output so that it tests false if an error occurs.
+#
+#  git_get_exact_tag(<var> [<additional arguments to git describe> ...])
+#
+# Returns the results of git describe --exact-match on the source tree,
+# and adjusting the output so that it tests false if there was no exact
+# matching tag.
+#
+#  git_local_changes(<var>)
+#
+# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes.
+# Uses the return code of "git diff-index --quiet HEAD --".
+# Does not regard untracked files.
+#
+# Requires CMake 2.6 or newer (uses the 'function' command)
+#
+# Original Author:
+# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
+# http://academic.cleardefinition.com
+# Iowa State University HCI Graduate Program/VRAC
+#
+# Copyright Iowa State University 2009-2010.
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+if(__get_git_revision_description)
+	return()
+endif()
+set(__get_git_revision_description YES)
+
+# We must run the following at "include" time, not at function call time,
+# to find the path to this module rather than the path to a calling list file
+get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
+
+function(get_git_head_revision _refspecvar _hashvar)
+	set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+	set(GIT_DIR "${GIT_PARENT_DIR}/.git")
+	while(NOT EXISTS "${GIT_DIR}")	# .git dir not found, search parent directories
+		set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}")
+		get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH)
+		if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT)
+			# We have reached the root directory, we are not in git
+			set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
+			set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
+			return()
+		endif()
+		set(GIT_DIR "${GIT_PARENT_DIR}/.git")
+	endwhile()
+	# check if this is a submodule
+	if(NOT IS_DIRECTORY ${GIT_DIR})
+		file(READ ${GIT_DIR} submodule)
+		string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule})
+		get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)
+		get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE)
+	endif()
+	set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
+	if(NOT EXISTS "${GIT_DATA}")
+		file(MAKE_DIRECTORY "${GIT_DATA}")
+	endif()
+
+	if(NOT EXISTS "${GIT_DIR}/HEAD")
+		return()
+	endif()
+	set(HEAD_FILE "${GIT_DATA}/HEAD")
+	configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY)
+
+	configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
+		"${GIT_DATA}/grabRef.cmake"
+		@ONLY)
+	include("${GIT_DATA}/grabRef.cmake")
+
+	set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE)
+	set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE)
+endfunction()
+
+function(git_describe _var)
+	if(NOT GIT_FOUND)
+		find_package(Git QUIET)
+	endif()
+	get_git_head_revision(refspec hash)
+	if(NOT GIT_FOUND)
+		set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
+		return()
+	endif()
+	if(NOT hash)
+		set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
+		return()
+	endif()
+
+	# TODO sanitize
+	#if((${ARGN}" MATCHES "&&") OR
+	#	(ARGN MATCHES "||") OR
+	#	(ARGN MATCHES "\\;"))
+	#	message("Please report the following error to the project!")
+	#	message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
+	#endif()
+
+	#message(STATUS "Arguments to execute_process: ${ARGN}")
+
+	execute_process(COMMAND
+		"${GIT_EXECUTABLE}"
+		describe
+		${hash}
+		${ARGN}
+		WORKING_DIRECTORY
+		"${CMAKE_CURRENT_SOURCE_DIR}"
+		RESULT_VARIABLE
+		res
+		OUTPUT_VARIABLE
+		out
+		ERROR_QUIET
+		OUTPUT_STRIP_TRAILING_WHITESPACE)
+	if(NOT res EQUAL 0)
+		set(out "${out}-${res}-NOTFOUND")
+	endif()
+
+	set(${_var} "${out}" PARENT_SCOPE)
+endfunction()
+
+function(git_get_exact_tag _var)
+	git_describe(out --exact-match ${ARGN})
+	set(${_var} "${out}" PARENT_SCOPE)
+endfunction()
+
+function(git_local_changes _var)
+	if(NOT GIT_FOUND)
+		find_package(Git QUIET)
+	endif()
+	get_git_head_revision(refspec hash)
+	if(NOT GIT_FOUND)
+		set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
+		return()
+	endif()
+	if(NOT hash)
+		set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
+		return()
+	endif()
+
+	execute_process(COMMAND
+		"${GIT_EXECUTABLE}"
+		diff-index --quiet HEAD --
+		WORKING_DIRECTORY
+		"${CMAKE_CURRENT_SOURCE_DIR}"
+		RESULT_VARIABLE
+		res
+		OUTPUT_VARIABLE
+		out
+		ERROR_QUIET
+		OUTPUT_STRIP_TRAILING_WHITESPACE)
+	if(res EQUAL 0)
+		set(${_var} "CLEAN" PARENT_SCOPE)
+	else()
+		set(${_var} "DIRTY" PARENT_SCOPE)
+	endif()
+endfunction()
diff --git a/cmake_modules/GetGitRevisionDescription.cmake.in b/cmake_modules/GetGitRevisionDescription.cmake.in
new file mode 100644
index 00000000..6d8b708e
--- /dev/null
+++ b/cmake_modules/GetGitRevisionDescription.cmake.in
@@ -0,0 +1,41 @@
+#
+# Internal file for GetGitRevisionDescription.cmake
+#
+# Requires CMake 2.6 or newer (uses the 'function' command)
+#
+# Original Author:
+# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
+# http://academic.cleardefinition.com
+# Iowa State University HCI Graduate Program/VRAC
+#
+# Copyright Iowa State University 2009-2010.
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+
+set(HEAD_HASH)
+
+file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
+
+string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
+if(HEAD_CONTENTS MATCHES "ref")
+	# named branch
+	string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
+	if(EXISTS "@GIT_DIR@/${HEAD_REF}")
+		configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
+	else()
+		configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY)
+		file(READ "@GIT_DATA@/packed-refs" PACKED_REFS)
+		if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}")
+			set(HEAD_HASH "${CMAKE_MATCH_1}")
+		endif()
+	endif()
+else()
+	# detached HEAD
+	configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
+endif()
+
+if(NOT HEAD_HASH)
+	file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
+	string(STRIP "${HEAD_HASH}" HEAD_HASH)
+endif()
diff --git a/cmake_moose_cpack.cmake b/cmake_moose_cpack.cmake
index 985c3fc4..05e7f114 100644
--- a/cmake_moose_cpack.cmake
+++ b/cmake_moose_cpack.cmake
@@ -58,7 +58,9 @@ if(APPLE)
     SET(BUNDLE_NAME ${CMAKE_PROJECT_NAME})
     SET(CPACK_BUNDLE_NAME ${BUNDLE_NAME})
 
-    SET_TARGET_PROPERTIES(moose.bin PROPERTIES MACOSX_BUNDLE TRUE)
+    if(DEBUG)
+        SET_TARGET_PROPERTIES(moose.bin PROPERTIES MACOSX_BUNDLE TRUE)
+    endif(DEBUG)
     SET_TARGET_PROPERTIES(_moose PROPERTIES MACOSX_BUNDLE TRUE)
 
 endif(APPLE)
diff --git a/pymoose/CMakeLists.txt b/pymoose/CMakeLists.txt
index d7c5c3c9..713ade07 100644
--- a/pymoose/CMakeLists.txt
+++ b/pymoose/CMakeLists.txt
@@ -76,7 +76,7 @@ ELSE(MACOSX)
         ${MOOSE_LIBRARIES}
         ${STATIC_LIBRARIES}
         "-Wl,--no-whole-archive"
-        ${PYTHON_LIBRARIES}
+        # ${PYTHON_LIBRARIES}
         ${SYSTEM_SHARED_LIBS}
         )
 endif(MACOSX)
diff --git a/python/moose/SBML/readSBML.py b/python/moose/SBML/readSBML.py
index ff7b7dbc..06de82bc 100644
--- a/python/moose/SBML/readSBML.py
+++ b/python/moose/SBML/readSBML.py
@@ -970,7 +970,7 @@ def createRules(model, specInfoMap, globparameterIdValue):
         if (rule.isAssignment()):
             rule_variable = rule.getVariable()
         
-            if specInfoMap.has_key(rule_variable):
+            if rule_variable in specInfoMap:
                 #In assignment rule only if pool exist, then that is conveted to moose as 
                 # this can be used as summation of pool's, P1+P2+P3 etc 
                 rule_variable = parentSp = str(idBeginWith(rule_variable))
@@ -993,10 +993,9 @@ def createRules(model, specInfoMap, globparameterIdValue):
                     if found:
                         allPools = True
                         for i in ruleMemlist:
-                            if specInfoMap.has_key(i):
-                                pass
-                            else:
+                            if i not in specInfoMap:
                                 allPools = False
+                                break
                         if allPools:
                             #only if addition then summation works, only then I create a function in moose
                             # which is need to get the summation's output to a pool
diff --git a/python/rdesigneur/rdesigneur.py b/python/rdesigneur/rdesigneur.py
index 8665281d..30906a25 100644
--- a/python/rdesigneur/rdesigneur.py
+++ b/python/rdesigneur/rdesigneur.py
@@ -80,6 +80,8 @@ class rdesigneur:
             elecDt= 50e-6,          # Same default as from MOOSE
             chemPlotDt = 1.0,       # Same default as from MOOSE
             elecPlotDt = 0.1e-3,    # Same default as from MOOSE
+            funcDt = 0.1e-3,        # Used when turnOffElec is False.
+                                    # Otherwise system uses chemDt.
             cellProto = [],
             spineProto = [],
             chanProto = [],
@@ -113,6 +115,7 @@ class rdesigneur:
         self.diffDt= diffDt
         self.elecDt= elecDt
         self.elecPlotDt= elecPlotDt
+        self.funcDt= funcDt
         self.chemPlotDt= chemPlotDt
 
         self.cellProtoList = cellProto
@@ -640,8 +643,8 @@ class rdesigneur:
     ################################################################
     # Here we display the plots and moogli
     ################################################################
-    def displayMoogli( self, moogliDt, runtime, rotation = math.pi/500.0):
-        rmoogli.displayMoogli( self, moogliDt, runtime, rotation )
+    def displayMoogli( self, moogliDt, runtime, rotation = math.pi/500.0, fullscreen = False):
+        rmoogli.displayMoogli( self, moogliDt, runtime, rotation, fullscreen )
 
     def display( self ):
         import matplotlib.pyplot as plt
@@ -925,12 +928,14 @@ class rdesigneur:
             elecPlotDt = self.elecPlotDt
         diffDt = self.diffDt
         chemDt = self.chemDt
-        for i in range( 0, 9 ):
+        for i in range( 0, 9 ):     # Assign elec family of clocks
             moose.setClock( i, elecDt )
-        moose.setClock( 8, elecPlotDt )
-        moose.setClock( 10, diffDt )
-        for i in range( 11, 18 ):
+        moose.setClock( 8, elecPlotDt ) 
+        moose.setClock( 10, diffDt )# Assign diffusion clock.
+        for i in range( 11, 18 ):   # Assign the chem family of clocks.
             moose.setClock( i, chemDt )
+        if not self.turnOffElec:    # Assign the Function clock
+            moose.setClock( 12, self.funcDt )
         moose.setClock( 18, self.chemPlotDt )
         hsolve = moose.HSolve( self.elecid.path + '/hsolve' )
         hsolve.dt = elecDt
diff --git a/python/rdesigneur/rmoogli.py b/python/rdesigneur/rmoogli.py
index bd4ad979..fcb1a120 100644
--- a/python/rdesigneur/rmoogli.py
+++ b/python/rdesigneur/rmoogli.py
@@ -157,7 +157,7 @@ def makeMoogli( rd, mooObj, moogliEntry, fieldInfo ):
     viewer.attach_view(view)
     return viewer
 
-def displayMoogli( rd, _dt, _runtime, _rotation ):
+def displayMoogli( rd, _dt, _runtime, _rotation, fullscreen = False ):
     if not hasMoogli:
         return None
     global runtime
@@ -167,7 +167,10 @@ def displayMoogli( rd, _dt, _runtime, _rotation ):
     moogliDt = _dt
     rotation = _rotation
     for i in rd.moogNames:
-        i.show()
+        if fullscreen:
+            i.showMaximized()
+        else:
+            i.show()
         i.start()
     #viewer.showMaximized()
     #viewer.show()
diff --git a/python/setup.cmake.py b/python/setup.cmake.py
index 8cd9faf1..ebce9069 100644
--- a/python/setup.cmake.py
+++ b/python/setup.cmake.py
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 
 """setup.py:
-Script to install python targets. 
+Script to install python targets.
 
 NOTE: This script is to be called by CMake. Not intended to be used standalone.
 
@@ -19,12 +19,17 @@ __status__           = "Development"
 import os
 import sys
 
-from distutils.core import setup
+try:
+	from setuptools import setup
+except Exception as e:
+	from distutils.core import setup
+
 script_dir = os.path.dirname( os.path.abspath( __file__ ) )
-version = '3.2.git'
+version = '3.2pre1'
+
 
 try:
-    with open( os.path.join( script_dir, '..', '..', 'VERSION'), 'r' ) as f:
+    with open( os.path.join( script_dir, 'VERSION'), 'r' ) as f:
         version = f.read( )
 except Exception as e:
     print( 'Failed to read VERSION %s' % e )
@@ -38,9 +43,9 @@ except Exception as e:
     suffix = '.so'
 
 setup(
-        name='moose',
+        name='pymoose',
         version=version,
-        description='MOOSE python scripting module.',
+        description='Python scripting interface of MOOSE Simulator (https://moose.ncbs.res.in)',
         author='MOOSERes',
         author_email='bhalla@ncbs.res.in',
         maintainer='Dilawar Singh',
@@ -56,9 +61,9 @@ setup(
             , 'moose.chemUtil'
             , 'moose.chemMerge'
             ],
+	install_requires = [ 'python-libsbml', 'numpy' ],
         package_dir = {
-            'moose' : 'moose'
-            , 'rdesigneur' : 'rdesigneur'
+            'moose' : 'moose', 'rdesigneur' : 'rdesigneur'
             },
         package_data = { 'moose' : ['_moose' + suffix, 'neuroml2/schema/NeuroMLCoreDimensions.xml'] },
     )
diff --git a/scripts/setup.py b/setup.py
similarity index 97%
rename from scripts/setup.py
rename to setup.py
index 746ba5a0..f7eec4a3 100755
--- a/scripts/setup.py
+++ b/setup.py
@@ -95,7 +95,7 @@ class InstallCommand(_install):
         self.new_dir = os.path.join(os.path.split(__file__)[0], 'python')
         os.chdir(self.new_dir)
         try:
-            ds.spawn(["python", "setup.py", "install"])
+            ds.spawn(["python", "setup.cmake.py", "install"])
         except ds.DistutilsExecError as e:
             print("Can't install PyMOOSE")
             print(e)
@@ -150,7 +150,7 @@ setup(
         , description = description
         , license = "LGPL"
         , url = url
-        , long_description = read('README')
+        , long_description = read('./README.md')
         , ext_modules = [
             Extension('_moose', [ '*' ])
             ]
diff --git a/setup_/__init__.py b/setup_/__init__.py
deleted file mode 100644
index 50aca64a..00000000
--- a/setup_/__init__.py
+++ /dev/null
@@ -1,203 +0,0 @@
-# -*- coding: utf-8 -*-
-sources = [
-	'basecode/consts.cpp',
-	'basecode/Element.cpp',
-	'basecode/Qinfo.cpp',
-	'basecode/DataHandler.cpp',
-	'basecode/ZeroDimHandler.cpp',
-	'basecode/ZeroDimParallelHandler.cpp',
-	'basecode/BlockHandler.cpp',
-	'basecode/OneDimHandler.cpp',
-	'basecode/TwoDimHandler.cpp',
-	'basecode/AnyDimHandler.cpp',
-	'basecode/DataHandlerWrapper.cpp',
-	'basecode/FieldDataHandlerBase.cpp',
-	'basecode/MsgDataHandler.cpp',
-	'basecode/ZombieHandler.cpp',
-	'basecode/Eref.cpp',
-	'basecode/Finfo.cpp',
-	'basecode/DestFinfo.cpp',
-	'basecode/Cinfo.cpp',
-	'basecode/SrcFinfo.cpp',
-	'basecode/ValueFinfo.cpp',
-	'basecode/SharedFinfo.cpp',
-	'basecode/FieldElementFinfo.cpp',
-	'basecode/Id.cpp',
-	'basecode/ObjId.cpp',
-	'basecode/DataId.cpp',
-	'basecode/SetGet.cpp',
-	'basecode/OpFunc.cpp',
-	'basecode/FieldOpFunc.cpp',
-	'basecode/SparseMatrix.cpp',
-	'basecode/PrepackedBuffer.cpp',
-	'basecode/FuncBarrier.cpp',
-	'basecode/doubleEq.cpp',
-	'basecode/ReduceBase.cpp',
-	'basecode/main.cpp',
-	'basecode/testAsync.cpp',
-
-	'biophysics/SynBase.cpp',
-	'biophysics/IntFire.cpp',
-	'biophysics/IzhikevichNrn.cpp',
-	'biophysics/LeakyIaF.cpp',
-	'biophysics/Synapse.cpp',
-	'biophysics/Compartment.cpp',
-	'biophysics/SymCompartment.cpp',
-	'biophysics/ChanBase.cpp',
-	'biophysics/SynChanBase.cpp',
-	'biophysics/HHChannel.cpp',
-	'biophysics/HHGate.cpp',
-	'biophysics/SynChan.cpp',
-	'biophysics/SpikeGen.cpp',
-	'biophysics/CaConc.cpp',
-	'biophysics/Nernst.cpp',
-	'biophysics/GHK.cpp',
-	'biophysics/NMDAChan.cpp',
-	'biophysics/HHGate2D.cpp',
-	'biophysics/HHChannel2D.cpp',
-	'biophysics/MgBlock.cpp',
-	'biophysics/VectorTable.cpp',
-	'biophysics/MarkovRateTable.cpp',
-	'biophysics/MarkovChannel.cpp',
-	'biophysics/MarkovGslSolver.cpp',
-	'biophysics/MatrixOps.cpp',
-	'biophysics/MarkovSolverBase.cpp',
-	'biophysics/MarkovSolver.cpp',
-	'biophysics/ReadCell.cpp',
-	'biophysics/testBiophysics.cpp',
-
-	'builtins/Arith.cpp',
-	'builtins/Group.cpp',
-	'builtins/Mdouble.cpp',
-	'builtins/Mstring.cpp',
-	'builtins/TableBase.cpp',
-	'builtins/TableEntry.cpp',
-	'builtins/Table.cpp',
-	'builtins/StimulusTable.cpp',
-	'builtins/Stats.cpp',
-	'builtins/Interpol2D.cpp',
-	'builtins/HDF5WriterBase.cpp',
-	'builtins/HDF5DataWriter.cpp',
-	'builtins/testBuiltins.cpp',
-
-	'device/PulseGen.cpp',
-	'device/DiffAmp.cpp',
-	'device/PIDController.cpp',
-	'device/RC.cpp',
-
-	'geom/Geometry.cpp',
-	'geom/Surface.cpp',
-	'geom/Panel.cpp',
-	'geom/CylPanel.cpp',
-	'geom/SpherePanel.cpp',
-	'geom/HemispherePanel.cpp',
-	'geom/DiskPanel.cpp',
-	'geom/RectPanel.cpp',
-	'geom/TriPanel.cpp',
-	'geom/testGeom.cpp',
-
-	'hsolve/HSolveStruct.cpp',
-	'hsolve/HinesMatrix.cpp',
-	'hsolve/HSolvePassive.cpp',
-	'hsolve/RateLookup.cpp',
-	'hsolve/HSolveActive.cpp',
-	'hsolve/HSolveActiveSetup.cpp',
-	'hsolve/HSolveInterface.cpp',
-	'hsolve/HSolve.cpp',
-	'hsolve/HSolveUtils.cpp',
-	'hsolve/testHSolve.cpp',
-	'hsolve/ZombieCompartment.cpp',
-	'hsolve/ZombieCaConc.cpp',
-	'hsolve/ZombieHHChannel.cpp',
-
-	'kinetics/PoolBase.cpp',
-	'kinetics/Pool.cpp',
-	'kinetics/BufPool.cpp',
-	'kinetics/FuncPool.cpp',
-	'kinetics/Reac.cpp',
-	'kinetics/Enz.cpp',
-	'kinetics/MMenz.cpp',
-	'kinetics/Species.cpp',
-	'kinetics/ReadKkit.cpp',
-	'kinetics/ReadCspace.cpp',
-	'kinetics/MathFunc.cpp',
-	'kinetics/SumFunc.cpp',
-	'kinetics/lookupSizeFromMesh.cpp',
-	'kinetics/testKinetics.cpp',
-
-	'ksolve/Port.cpp',
-	'ksolve/Stoich.cpp',
-	'ksolve/KinSparseMatrix.cpp',
-	'ksolve/ZombiePool.cpp',
-	'ksolve/ZombieBufPool.cpp',
-	'ksolve/ZombieFuncPool.cpp',
-	'ksolve/ZombieReac.cpp',
-	'ksolve/ZombieEnz.cpp',
-	'ksolve/ZombieMMenz.cpp',
-	'ksolve/ZombieSumFunc.cpp',
-	'ksolve/RateTerm.cpp',
-	'ksolve/FuncTerm.cpp',
-	'ksolve/GssaStoich.cpp',
-	'ksolve/testKsolve.cpp',
-
-	'manager/SimManager.cpp',
-	'manager/testSimManager.cpp',
-
-	'mesh/ChemMesh.cpp',
-	'mesh/MeshEntry.cpp',
-	'mesh/CylMesh.cpp',
-	'mesh/CubeMesh.cpp',
-	'mesh/Boundary.cpp',
-	'mesh/Stencil.cpp',
-	'mesh/testMesh.cpp',
-
-	'msg/Msg.cpp',
-	'msg/DiagonalMsg.cpp',
-	'msg/OneToAllMsg.cpp',
-	'msg/OneToOneMsg.cpp',
-	'msg/SingleMsg.cpp',
-	'msg/SparseMsg.cpp',
-	'msg/ReduceMsg.cpp',
-	'msg/testMsg.cpp',
-
-	'pymoose/moosemodule.cpp',
-
-	'randnum/mt19937ar.cpp',
-
-	'regressionTests/regressionTest.cpp',
-	'regressionTests/rtTable.cpp',
-	'regressionTests/rtReadKkit.cpp',
-	'regressionTests/rtHHnetwork.cpp',
-	'regressionTests/rtReacDiff.cpp',
-	'regressionTests/perfTestMarkovSolver.cpp',
-	'regressionTests/benchmarkTests.cpp',
-
-	'scheduling/Clock.cpp',
-	'scheduling/Tick.cpp',
-	'scheduling/TickMgr.cpp',
-	'scheduling/testScheduling.cpp',
-
-	'shell/Shell.cpp',
-	'shell/ShellCopy.cpp',
-	'shell/ShellSetGet.cpp',
-	'shell/ShellThreads.cpp',
-	'shell/ProcessLoop.cpp',
-	'shell/LoadModels.cpp',
-	'shell/Neutral.cpp',
-	'shell/Wildcard.cpp',
-	'shell/testShell.cpp',
-
-	#~ 'smol/SmolSim.cpp',
-	#~ 'smol/SmolPool.cpp',
-	#~ 'smol/SmolMol.cpp',
-	#~ 'smol/SmolReac.cpp',
-	#~ 'smol/SmolEnz.cpp',
-	#~ 'smol/SmolMMenz.cpp',
-	#~ 'smol/testSmol.cpp',
-
-	'utility/strutil.cpp',
-	'utility/types.cpp',
-	'utility/setupenv.cpp',
-	'utility/numutil.cpp',
-	'utility/Annotator.cpp',
-]
diff --git a/synapse/GraupnerBrunel2012CaPlasticitySynHandler.cpp b/synapse/GraupnerBrunel2012CaPlasticitySynHandler.cpp
index 6734a574..835dc72b 100644
--- a/synapse/GraupnerBrunel2012CaPlasticitySynHandler.cpp
+++ b/synapse/GraupnerBrunel2012CaPlasticitySynHandler.cpp
@@ -305,6 +305,15 @@ void GraupnerBrunel2012CaPlasticitySynHandler::addSpike(
 	delayDPreEvents_.push( PreSynEvent( index, time+delayD_, weight ) );
 }
 
+double GraupnerBrunel2012CaPlasticitySynHandler::getTopSpike( 
+				unsigned int index ) const
+{
+	if ( events_.empty() )
+		return 0.0;
+	return events_.top().time;
+}
+
+
 void GraupnerBrunel2012CaPlasticitySynHandler::addPostSpike( const Eref& e, double time )
 {
 	postEvents_.push( PostSynEvent( time ) );
diff --git a/synapse/GraupnerBrunel2012CaPlasticitySynHandler.h b/synapse/GraupnerBrunel2012CaPlasticitySynHandler.h
index 2c305559..f7888602 100644
--- a/synapse/GraupnerBrunel2012CaPlasticitySynHandler.h
+++ b/synapse/GraupnerBrunel2012CaPlasticitySynHandler.h
@@ -95,6 +95,7 @@ class GraupnerBrunel2012CaPlasticitySynHandler: public SynHandlerBase
 		unsigned int addSynapse();
 		void dropSynapse( unsigned int droppedSynNumber );
 		void addSpike( unsigned int index, double time, double weight );
+		double getTopSpike( unsigned int index ) const;
 		////////////////////////////////////////////////////////////////
 		void addPostSpike( const Eref& e, double time );
 
diff --git a/synapse/STDPSynHandler.cpp b/synapse/STDPSynHandler.cpp
index 372e6d66..a414913b 100644
--- a/synapse/STDPSynHandler.cpp
+++ b/synapse/STDPSynHandler.cpp
@@ -190,6 +190,13 @@ void STDPSynHandler::addSpike(
 	events_.push( PreSynEvent( index, time, weight ) );
 }
 
+double STDPSynHandler::getTopSpike( unsigned int index ) const
+{
+	if ( events_.empty() )
+		return 0.0;
+	return events_.top().time;
+}
+
 void STDPSynHandler::addPostSpike( const Eref& e, double time )
 {
 	postEvents_.push( PostSynEvent( time ) );
diff --git a/synapse/STDPSynHandler.h b/synapse/STDPSynHandler.h
index 947db5f1..c0f1446e 100644
--- a/synapse/STDPSynHandler.h
+++ b/synapse/STDPSynHandler.h
@@ -77,6 +77,7 @@ class STDPSynHandler: public SynHandlerBase
 		unsigned int addSynapse();
 		void dropSynapse( unsigned int droppedSynNumber );
 		void addSpike( unsigned int index, double time, double weight );
+		double getTopSpike( unsigned int index ) const;
 		////////////////////////////////////////////////////////////////
 		void addPostSpike( const Eref& e, double time );
 
diff --git a/synapse/SeqSynHandler.cpp b/synapse/SeqSynHandler.cpp
index 0f29f3d4..cb8bb0b6 100644
--- a/synapse/SeqSynHandler.cpp
+++ b/synapse/SeqSynHandler.cpp
@@ -513,6 +513,13 @@ void SeqSynHandler::addSpike(unsigned int index, double time, double weight)
 	latestSpikes_[ synapseOrder_[index] ] += weight;
 }
 
+double SeqSynHandler::getTopSpike( unsigned int index ) const
+{
+	if ( events_.empty() )
+		return 0.0;
+	return events_.top().time;
+}
+
 unsigned int SeqSynHandler::addSynapse()
 {
 	unsigned int newSynIndex = synapses_.size();
diff --git a/synapse/SeqSynHandler.h b/synapse/SeqSynHandler.h
index 58ede36a..97b4800f 100644
--- a/synapse/SeqSynHandler.h
+++ b/synapse/SeqSynHandler.h
@@ -44,6 +44,7 @@ class SeqSynHandler: public SynHandlerBase
 		unsigned int addSynapse();
 		void dropSynapse( unsigned int droppedSynNumber );
 		void addSpike( unsigned int index, double time, double weight );
+		double getTopSpike( unsigned int index ) const;
 		////////////////////////////////////////////////////////////////
 		// New fields.
 		////////////////////////////////////////////////////////////////
diff --git a/synapse/SimpleSynHandler.cpp b/synapse/SimpleSynHandler.cpp
index b1323cb1..51100cd2 100644
--- a/synapse/SimpleSynHandler.cpp
+++ b/synapse/SimpleSynHandler.cpp
@@ -104,6 +104,13 @@ void SimpleSynHandler::addSpike(
 	events_.push( SynEvent( time, weight ) );
 }
 
+double SimpleSynHandler::getTopSpike( unsigned int index ) const
+{
+	if ( events_.empty() )
+		return 0.0;
+	return events_.top().time;
+}
+
 void SimpleSynHandler::vProcess( const Eref& e, ProcPtr p )
 {
 	double activation = 0.0;
diff --git a/synapse/SimpleSynHandler.h b/synapse/SimpleSynHandler.h
index 9b3138bf..22ee6c90 100644
--- a/synapse/SimpleSynHandler.h
+++ b/synapse/SimpleSynHandler.h
@@ -61,6 +61,7 @@ class SimpleSynHandler: public SynHandlerBase
 		unsigned int addSynapse();
 		void dropSynapse( unsigned int droppedSynNumber );
 		void addSpike( unsigned int index, double time, double weight );
+		double getTopSpike( unsigned int index ) const;
 		////////////////////////////////////////////////////////////////
 		static const Cinfo* initCinfo();
 	private:
diff --git a/synapse/SynHandlerBase.h b/synapse/SynHandlerBase.h
index 660da06d..e3b3a383 100644
--- a/synapse/SynHandlerBase.h
+++ b/synapse/SynHandlerBase.h
@@ -79,6 +79,7 @@ class SynHandlerBase
 		 */
 		virtual void addSpike(
 			unsigned int index, double time, double weight ) = 0;
+		virtual double getTopSpike( unsigned int index ) const = 0;
 		////////////////////////////////////////////////////////////////
 		// Virtual func definitions for fields.
 		////////////////////////////////////////////////////////////////
diff --git a/synapse/Synapse.cpp b/synapse/Synapse.cpp
index 17aa5a0d..30c97b1b 100644
--- a/synapse/Synapse.cpp
+++ b/synapse/Synapse.cpp
@@ -8,6 +8,7 @@
 **********************************************************************/
 
 #include "header.h"
+#include "ElementValueFinfo.h"
 #include "SynHandlerBase.h"
 #include "Synapse.h"
 
@@ -26,6 +27,13 @@ const Cinfo* Synapse::initCinfo()
 			&Synapse::setDelay,
 			&Synapse::getDelay
 		);
+		static ElementValueFinfo< Synapse, double > spikeTime(
+			"spikeTime",
+			"Value field interface to add spike (by assignment) and to "
+			"read the value of the spike on top of the queue.",
+			&Synapse::addSpike,
+			&Synapse::getTopSpike
+		);
 
 		static DestFinfo addSpike( "addSpike",
 			"Handles arriving spike messages, inserts into event queue.",
@@ -34,6 +42,7 @@ const Cinfo* Synapse::initCinfo()
 	static Finfo* synapseFinfos[] = {
 		&weight,		// Field
 		&delay,			// Field
+		&spikeTime,		// ElementField
 		&addSpike,		// DestFinfo
 	};
 
@@ -103,6 +112,11 @@ void Synapse::addSpike( const Eref& e, double time )
 	handler_->addSpike( e.fieldIndex(), time + delay_, weight_ );
 }
 
+double Synapse::getTopSpike( const Eref& e ) const
+{
+	return handler_->getTopSpike( e.fieldIndex() );
+}
+
 /////////////////////////////////////////////////////////////
 // Callbacks for message add/drop
 /////////////////////////////////////////////////////////////
diff --git a/synapse/Synapse.h b/synapse/Synapse.h
index 12e5915d..4ac1593c 100644
--- a/synapse/Synapse.h
+++ b/synapse/Synapse.h
@@ -26,6 +26,7 @@ class Synapse
 		double getDelay() const;
 
 		void addSpike( const Eref& e, double time );
+		double getTopSpike( const Eref& e ) const;
 
 		void setHandler( SynHandlerBase* h );
 
diff --git a/wheels/Dockerfile b/wheels/Dockerfile
new file mode 100644
index 00000000..cec973ab
--- /dev/null
+++ b/wheels/Dockerfile
@@ -0,0 +1,17 @@
+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
new file mode 100755
index 00000000..5509ea85
--- /dev/null
+++ b/wheels/build_wheels.sh
@@ -0,0 +1,46 @@
+#!/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