diff --git a/CMakeLists.txt b/CMakeLists.txt index 62c167a698d58d3ed8470ef14d430eebc156e0f1..2760ff05d598d7a7693c156d32a37bfde9240d11 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,16 +88,25 @@ else() set(use_external_modcc ON BOOL) endif() -# whether to attempt to use nrniv to build validation data +# Validation data generation + +# destination directory for generated data +set(VALIDATION_DATA_DIR "${CMAKE_SOURCE_DIR}/validation/data" CACHE PATH "location of generated validation data") + +# Whether to build validation data at all +set(BUILD_VALIDATION_DATA ON CACHE BOOL "generate validation data") + +# Whether to attempt to use nrniv to build validation data # (if we find nrniv, do) find_program(NRNIV_BIN nrniv) if(NRNIV_BIN STREQUAL "NRNIV_BIN-NOTFOUND") - message(STATUS "nrniv not found; will not automatically build validation data sets") - set(BUILD_VALIDATION_DATA FALSE) + message(STATUS "nrniv not found; will not automatically build NEURON validation data sets") + set(BUILD_NRN_VALIDATION_DATA FALSE) else() - set(BUILD_VALIDATION_DATA TRUE) + set(BUILD_NRN_VALIDATION_DATA TRUE) endif() + include_directories(${CMAKE_SOURCE_DIR}/tclap/include) include_directories(${CMAKE_SOURCE_DIR}/vector) include_directories(${CMAKE_SOURCE_DIR}/include) @@ -109,12 +118,17 @@ if( "${WITH_TBB}" STREQUAL "ON" ) include_directories(${TBB_INCLUDE_DIRS}) endif() +# only include validation data if flag is set +if(BUILD_VALIDATION_DATA) + add_subdirectory(validation) +endif() + # only compile modcc if it is not provided externally if(use_external_modcc) add_subdirectory(modcc) endif() + add_subdirectory(mechanisms) -add_subdirectory(nrn) add_subdirectory(src) add_subdirectory(tests) add_subdirectory(miniapp) diff --git a/nrn/CMakeLists.txt b/nrn/CMakeLists.txt deleted file mode 100644 index 28325c091cea5aec8b0666ac46ba6503e82cdc9a..0000000000000000000000000000000000000000 --- a/nrn/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -# The validation scripts to run (without .py extension) - -set(validations - ball_and_stick - ball_and_3stick - ball_and_taper - simple_exp_synapse - simple_exp2_synapse - soma) - -# Only try and make validation sets if we can find nrniv -if(BUILD_VALIDATION_DATA) - set(common "${CMAKE_CURRENT_SOURCE_DIR}/nrn_validation.py") - foreach(v ${validations}) - set(out "${CMAKE_SOURCE_DIR}/data/validation/neuron_${v}.json") - set(src "${CMAKE_CURRENT_SOURCE_DIR}/${v}.py") - add_custom_command( - OUTPUT "${out}" - DEPENDS "${src}" "${common}" - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - COMMAND ${NRNIV_BIN} -nobanner -python ${src} > ${out}) - list(APPEND all_neuron_validation "${out}") - endforeach() - add_custom_target(validation_data DEPENDS ${all_neuron_validation}) -endif() - diff --git a/tests/validation/CMakeLists.txt b/tests/validation/CMakeLists.txt index 5f61ecc32af9c2083cc69f3945bf8bc8d58417db..a38ae3e23291aff01b8955d3717c63144f1bf940 100644 --- a/tests/validation/CMakeLists.txt +++ b/tests/validation/CMakeLists.txt @@ -12,8 +12,9 @@ set(VALIDATION_SOURCES validate.cpp ) -add_definitions("-DDATADIR=\"${CMAKE_SOURCE_DIR}/data\"") - +if(VALIDATION_DATA_DIR) + add_definitions("-DDATADIR=\"${VALIDATION_DATA_DIR}\"") +endif() add_executable(validate.exe ${VALIDATION_SOURCES} ${HEADERS}) set(TARGETS validate.exe) @@ -36,7 +37,7 @@ foreach(target ${TARGETS}) RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests" ) - if (BUILD_VALIDATION_DATA) + if(BUILD_VALIDATION_DATA) add_dependencies(${target} validation_data) endif() endforeach() diff --git a/validation/CMakeLists.txt b/validation/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..8566b787dcaf71fd08cb291ac21f1a3ed6e7383c --- /dev/null +++ b/validation/CMakeLists.txt @@ -0,0 +1,49 @@ +# Validation data generation + +add_custom_target(validation_data) + +# Helper function because ffs CMake. + +function(make_unique_target_name name path) + # try and make a broadly human readable target name if possible. + string(REGEX REPLACE ".*/" "" leaf "${path}") + string(REGEX REPLACE "[^a-zA-Z0-9_.+-]" "_" canon "${leaf}") + + # check against reserved names, of which of course there is no documented list + if(canon MATCHES "^(all|test|clean|help)$") + set(canon "${canon}_") + endif() + while((TARGET "${canon}")) + set(canon "${canon}_") + endwhile() + set("${name}" "${canon}" PARENT_SCOPE) +endfunction() + +# Helper function to add a data generation script that writes to standard output. +# e.g.: +# add_validation_data(OUTPUT foo_model.json DEPENDS foo_model.py common.py COMMAND python foo_model.py) + +include(CMakeParseArguments) +function(add_validation_data) + cmake_parse_arguments(ADD_VALIDATION_DATA "" "OUTPUT" "DEPENDS;COMMAND" ${ARGN}) + set(out "${VALIDATION_DATA_DIR}/${ADD_VALIDATION_DATA_OUTPUT}") + string(REGEX REPLACE "([^;]+)" "${CMAKE_CURRENT_SOURCE_DIR}/\\1" deps "${ADD_VALIDATION_DATA_DEPENDS}") + add_custom_command( + OUTPUT "${out}" + DEPENDS ${deps} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + COMMAND ${ADD_VALIDATION_DATA_COMMAND} > "${out}") + + # Cmake, why can't we just write add_dependencies(validation_data "${out}")?! + make_unique_target_name(ffs_cmake "${out}") + add_custom_target("${ffs_cmake}" DEPENDS "${out}") + add_dependencies(validation_data "${ffs_cmake}") +endfunction() + + +if(BUILD_NRN_VALIDATION_DATA) + add_subdirectory(ref/neuron) +endif() + +add_subdirectory(ref/numeric) + diff --git a/validation/README.md b/validation/README.md new file mode 100644 index 0000000000000000000000000000000000000000..2357501d57fbe0101a05b1ef077c60eafde22a16 --- /dev/null +++ b/validation/README.md @@ -0,0 +1,22 @@ +# Validation data and generation + +## Sub-directory organization + +`validation/data` + ~ Generated validation data + +`validation/ref` + ~ Reference models + +`validation/ref/neuron` + ~ NEURON-based reference models, run with `nrniv -python` + +`validation/ref/numeric` + ~ Direct numerical and analytic models + +## Data generation + +Data is generated via the `validation_data` CMake target, which is +a prerequisite for the `validation.exe` test executable. + + diff --git a/data/validation/.keep b/validation/data/.keep similarity index 100% rename from data/validation/.keep rename to validation/data/.keep diff --git a/validation/ref/neuron/CMakeLists.txt b/validation/ref/neuron/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..570d3f7234b2fab135b97dde9462884caa23523e --- /dev/null +++ b/validation/ref/neuron/CMakeLists.txt @@ -0,0 +1,18 @@ +# note: function add_validation_data defined in validation/CMakeLists.txt + +set(models + ball_and_stick + ball_and_3stick + ball_and_taper + simple_exp_synapse + simple_exp2_synapse + soma) + +foreach(model ${models}) + set(script "${model}.py") + add_validation_data( + OUTPUT "neuron_${model}.json" + DEPENDS "${script}" "nrn_validation.py" + COMMAND ${NRNIV_BIN} -nobanner -python "${script}") +endforeach() + diff --git a/nrn/ball_and_3stick.py b/validation/ref/neuron/ball_and_3stick.py similarity index 100% rename from nrn/ball_and_3stick.py rename to validation/ref/neuron/ball_and_3stick.py diff --git a/nrn/ball_and_stick.py b/validation/ref/neuron/ball_and_stick.py similarity index 100% rename from nrn/ball_and_stick.py rename to validation/ref/neuron/ball_and_stick.py diff --git a/nrn/ball_and_taper.py b/validation/ref/neuron/ball_and_taper.py similarity index 100% rename from nrn/ball_and_taper.py rename to validation/ref/neuron/ball_and_taper.py diff --git a/nrn/generate_validation.sh b/validation/ref/neuron/generate_validation.sh similarity index 100% rename from nrn/generate_validation.sh rename to validation/ref/neuron/generate_validation.sh diff --git a/nrn/nrn_validation.py b/validation/ref/neuron/nrn_validation.py similarity index 100% rename from nrn/nrn_validation.py rename to validation/ref/neuron/nrn_validation.py diff --git a/nrn/simple_exp2_synapse.py b/validation/ref/neuron/simple_exp2_synapse.py similarity index 100% rename from nrn/simple_exp2_synapse.py rename to validation/ref/neuron/simple_exp2_synapse.py diff --git a/nrn/simple_exp_synapse.py b/validation/ref/neuron/simple_exp_synapse.py similarity index 100% rename from nrn/simple_exp_synapse.py rename to validation/ref/neuron/simple_exp_synapse.py diff --git a/nrn/soma.py b/validation/ref/neuron/soma.py similarity index 100% rename from nrn/soma.py rename to validation/ref/neuron/soma.py diff --git a/validation/ref/numeric/CMakeLists.txt b/validation/ref/numeric/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..a697439f0f8681efa9f0a0016d023e1897e7684c --- /dev/null +++ b/validation/ref/numeric/CMakeLists.txt @@ -0,0 +1,4 @@ +# note: function add_validation_data defined in validation/CMakeLists.txt + +# placeholder +add_validation_data(OUTPUT foo.out DEPENDS foo.sh COMMAND bash foo.sh) diff --git a/scripts/PassiveCable.jl b/validation/ref/numeric/PassiveCable.jl similarity index 100% rename from scripts/PassiveCable.jl rename to validation/ref/numeric/PassiveCable.jl diff --git a/validation/ref/numeric/foo.sh b/validation/ref/numeric/foo.sh new file mode 100644 index 0000000000000000000000000000000000000000..cdf28307542429d80a65e980af6fe4f44a3d99bd --- /dev/null +++ b/validation/ref/numeric/foo.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +echo "woop woop" + diff --git a/tests/validation/hh_soma.jl b/validation/ref/numeric/hh_soma.jl similarity index 100% rename from tests/validation/hh_soma.jl rename to validation/ref/numeric/hh_soma.jl