about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--INSTALL.md23
-rw-r--r--Makefile38
-rw-r--r--example/demo.txt22
-rwxr-xr-xrun_tests.sh6
-rwxr-xr-xtest/test_suite.sh54
6 files changed, 123 insertions, 25 deletions
diff --git a/.gitignore b/.gitignore
index 108e607..5088ec4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,9 +2,12 @@
 *.tar.gz
 src/Eigen
 example/output
+test/output
+./output
 doc/manual.aux
 doc/manual.bbl
 doc/manual.blg
 doc/manual.log
 doc/manual.out
-doc/manual.toc
\ No newline at end of file
+doc/manual.toc
+contrib/
diff --git a/INSTALL.md b/INSTALL.md
index f6eb0c0..e4da6ff 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -47,4 +47,25 @@ Install listed dependencies and run
 if you get an Eigen error you may need to override the include
 path. E.g. on GNU Guix with shared libs this may work
 
-    make EIGEN_INCLUDE_PATH=~/.guix-profile/include/eigen3 FORCE_DYNAMIC=1
+    make EIGEN_INCLUDE_PATH=~/.guix-profile/include/eigen3 FORCE_DYNAMIC=1 WITH_OPENBLAS=1
+
+to run GEMMA tests
+
+    make check
+
+## Run tests
+
+GEMMA uses the shunit2 test framework (version 2.0) and can be found
+[here](https://github.com/genenetwork/shunit2)
+
+In the source tree:
+
+    git clone https://github.com/genenetwork/shunit2 contrib/shunit2
+
+and run
+
+    make check
+
+or
+
+    ./run_tests.sh
diff --git a/Makefile b/Makefile
index 0f25d88..72994be 100644
--- a/Makefile
+++ b/Makefile
@@ -10,11 +10,13 @@
 # Set this variable to either LNX or MAC
 SYS = LNX
 # Leave blank after "=" to disable; put "= 1" to enable
-WITH_LAPACK = 1
+SHOW_COMPILER_WARNINGS   =
+WITH_LAPACK     = 1
+WITH_OPENBLAS   =
 NO_INTEL_COMPAT =
-FORCE_32BIT =
-FORCE_DYNAMIC =
-DIST_NAME = gemma-0.97
+FORCE_32BIT     =
+FORCE_DYNAMIC   =
+DIST_NAME       = gemma-0.97
 
 # --------------------------------------------------------------------
 # Edit below this line with caution
@@ -28,12 +30,16 @@ SRC_DIR  = ./src
 
 CPP = g++
 
-CPPFLAGS = -Wall -Weffc++ -O3 -std=gnu++11 -I$(EIGEN_INCLUDE_PATH)
+CPPFLAGS = -O3 -std=gnu++11 -isystem$(EIGEN_INCLUDE_PATH)
+
+ifdef SHOW_COMPILER_WARNINGS
+  CPPFLAGS += -Wall
+endif
 
 ifdef FORCE_DYNAMIC
-LIBS = -lgsl -lgslcblas -lblas -pthread -lz
+  LIBS = -lgsl -lgslcblas -pthread -lz
 else
-LIBS = -lgsl -lgslcblas -pthread -lz
+  LIBS = -lgsl -lgslcblas -pthread -lz
 endif
 
 OUTPUT = $(BIN_DIR)/gemma
@@ -45,6 +51,8 @@ HDR =
 # Detailed libary paths, D for dynamic and S for static
 
 LIBS_LNX_D_LAPACK = -llapack
+LIBS_LNX_D_BLAS = -lblas
+LIBS_LNX_D_OPENBLAS = -lopenblas
 LIBS_MAC_D_LAPACK = -framework Veclib
 LIBS_LNX_S_LAPACK = /usr/lib/lapack/liblapack.a -lgfortran  /usr/lib/atlas-base/libatlas.a /usr/lib/libblas/libblas.a -Wl,--allow-multiple-definition
 
@@ -56,11 +64,14 @@ ifdef WITH_LAPACK
 ifeq ($(SYS), MAC)
   LIBS += $(LIBS_MAC_D_LAPACK)
 else
-ifdef FORCE_DYNAMIC
-  LIBS += $(LIBS_LNX_D_LAPACK)
-else
-  LIBS += $(LIBS_LNX_S_LAPACK)
-endif
+  ifdef FORCE_DYNAMIC
+    ifdef WITH_OPENBLAS
+      LIBS += $(LIBS_LNX_D_OPENBLAS)
+    else
+      LIBS += $(LIBS_LNX_D_BLAS)
+    endif
+    LIBS += $(LIBS_LNX_D_LAPACK)
+  endif
 endif
   SOURCES += $(SRC_DIR)/lapack.cpp
   HDR += $(SRC_DIR)/lapack.h
@@ -95,6 +106,9 @@ $(OBJS) : $(HDR)
 	$(CPP) $(CPPFLAGS) $(HEADERS) -c $*.cpp -o $*.o
 .SUFFIXES : .cpp .c .o $(SUFFIXES)
 
+check: all
+	cd test && ./test_suite.sh | tee ../test.log
+	grep -q 'success rate: 100%' test.log
 
 clean:
 	rm -rf ${SRC_DIR}/*.o ${SRC_DIR}/*~ *~ $(OUTPUT)
diff --git a/example/demo.txt b/example/demo.txt
index 80c5c95..c8082b9 100644
--- a/example/demo.txt
+++ b/example/demo.txt
@@ -67,17 +67,17 @@ chr	rs	ps	n_miss	allele1	allele0	af	beta_1	beta_2	Vbeta_1_1	Vbeta_1_2	Vbeta_2_2
 1	rs13475700	4098402	0	A	C	0.128	-6.727883e-02	1.685363e-01	5.597160e-03	-1.366799e-04	7.574216e-03	1.060482e-01
 
 # The log file also contains Vg and Ve estimates and their standard errors
-## REMLE estimate for Vg in the null model: 
-1.39398	
--0.226714	2.08168	
-## se(Vg): 
-0.156661	
-0.136319	0.235858	
-## REMLE estimate for Ve in the null model: 
-0.348882	
-0.0490525	0.414433	
-## se(Ve): 
-0.0206226	
+## REMLE estimate for Vg in the null model:
+1.39398
+-0.226714	2.08168
+## se(Vg):
+0.156661
+0.136319	0.235858
+## REMLE estimate for Ve in the null model:
+0.348882
+0.0490525	0.414433
+## se(Ve):
+0.0206226
 0.0166233	0.0266869
 
 # Since there are individuals with partially missing phenotypes, one can impute these missing values before association tests
diff --git a/run_tests.sh b/run_tests.sh
new file mode 100755
index 0000000..181f687
--- /dev/null
+++ b/run_tests.sh
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+
+# download shunit2 in order to run tests (see INSTALL.md)
+
+cd test
+./test_suite.sh | tee /dev/stderr | grep -q 'success rate: 100%'
diff --git a/test/test_suite.sh b/test/test_suite.sh
new file mode 100755
index 0000000..f1a1c6f
--- /dev/null
+++ b/test/test_suite.sh
@@ -0,0 +1,54 @@
+#!/usr/bin/env bash
+
+gemma=../bin/gemma
+
+testCenteredRelatednessMatrixK() {
+    $gemma -g ../example/mouse_hs1940.geno.txt.gz -p ../example/mouse_hs1940.pheno.txt \
+           -a ../example/mouse_hs1940.anno.txt -gk -o mouse_hs1940
+    assertEquals 0 $?
+    grep "total computation time" < output/mouse_hs1940.log.txt
+    assertEquals 0 $?
+    assertEquals "3763600" `wc -w < output/mouse_hs1940.cXX.txt`
+    # assertEquals "15f680c" `md5sum < output/mouse_hs1940.cXX.txt | head -c 7`
+    assertEquals "0.335" `head -c 5 output/mouse_hs1940.cXX.txt`
+    # FIXME: The following test fails in the Guix build system (https://github.com/xiangzhou/GEMMA/issues/55)
+    assertEquals "29.691" `awk '{s+=substr($1,0,6)}END{print s}' output/mouse_hs1940.cXX.txt`
+}
+
+testUnivariateLinearMixedModel() {
+    $gemma -g ../example/mouse_hs1940.geno.txt.gz -p ../example/mouse_hs1940.pheno.txt -n 1 \
+           -a ../example/mouse_hs1940.anno.txt -k ./output/mouse_hs1940.cXX.txt -lmm \
+           -o mouse_hs1940_CD8_lmm
+    assertEquals 0 $?
+    grep "total computation time" < output/mouse_hs1940_CD8_lmm.log.txt
+    assertEquals 0 $?
+    assertEquals "118459" `wc -w < output/mouse_hs1940_CD8_lmm.assoc.txt`
+    assertEquals "92047" `awk '{s+=substr($1,0,6)}END{print s}' output/mouse_hs1940_CD8_lmm.assoc.txt`
+}
+
+testMultivariateLinearMixedModel() {
+    $gemma -g ../example/mouse_hs1940.geno.txt.gz -p ../example/mouse_hs1940.pheno.txt \
+           -n 1 6 -a ../example/mouse_hs1940.anno.txt -k ./output/mouse_hs1940.cXX.txt \
+           -lmm -o mouse_hs1940_CD8MCH_lmm
+    assertEquals 0 $?
+    grep "total computation time" < output/mouse_hs1940_CD8MCH_lmm.log.txt
+    assertEquals 0 $?
+
+    outfn=output/mouse_hs1940_CD8MCH_lmm.assoc.txt
+    assertEquals "139867" `wc -w < $outfn`
+    assertEquals "92079" `awk '{s+=substr($1,0,6)}END{print s}' $outfn`
+}
+
+shunit2=`which shunit2`
+if [ -e "../contrib/shunit2/source/2.0/src/shell/shunit2" ]; then
+    echo try to run the locally installed shunit2
+    . ../contrib/shunit2/source/2.0/src/shell/shunit2
+elif [ -e "../shunit2-2.0.3/src/shell/shunit2" ]; then
+    echo try to run the older locally installed shunit2
+    . ../shunit2-2.0.3/src/shell/shunit2
+elif [ -x "$shunit2" ]; then
+    echo run system shunit2
+    . $shunit2
+else
+    echo "Can not find shunit2 - see INSTALL.md"
+fi